Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=cedbfa72420100... Commit: cedbfa724201007cbdbc205e9b115b83540c9e3b Parent: 77602315f5d8803d9d00b2379ab1ceb9da16df93 Author: Jan Pokorn�� jpokorny@redhat.com AuthorDate: Tue Feb 28 02:31:58 2017 +0100 Committer: Jan Pokorn�� jpokorny@redhat.com CommitterDate: Tue Feb 28 02:31:58 2017 +0100
fedorahosted.org discontinued
Signed-off-by: Jan Pokorn�� jpokorny@redhat.com --- Makefile | 179 - README | 3 + ccs/Makefile | 50 - ccs/bin/Makefile | 28 - ccs/ccs_test/Makefile | 50 - ccs/ccs_test/ccs_test.c | 195 - ccs/ccs_tool/Makefile | 43 - ccs/ccs_tool/ccs_tool.c | 125 - ccs/ccs_tool/editconf.c | 1275 - ccs/ccs_tool/editconf.h | 20 - ccs/ccs_tool/old_parser.c | 700 - ccs/ccs_tool/old_parser.h | 64 - ccs/ccs_tool/update.c | 308 - ccs/ccs_tool/update.h | 18 - ccs/ccs_tool/upgrade.c | 269 - ccs/ccs_tool/upgrade.h | 18 - ccs/common/log.c | 23 - ccs/common/log.h | 98 - ccs/config/copyright.cf | 22 - ccs/configure | 166 - ccs/daemon/Makefile | 46 - ccs/daemon/ccsd.c | 909 - ccs/daemon/cluster_mgr.c | 433 - ccs/daemon/cluster_mgr.h | 17 - ccs/daemon/cnx_mgr.c | 1391 - ccs/daemon/cnx_mgr.h | 19 - ccs/daemon/globals.c | 30 - ccs/daemon/globals.h | 35 - ccs/daemon/misc.c | 159 - ccs/daemon/misc.h | 30 - ccs/include/comm_headers.h | 59 - ccs/include/debug.h | 24 - ccs/init.d/Makefile | 30 - ccs/init.d/ccsd | 92 - ccs/lib/Makefile | 51 - ccs/lib/ccs.h | 24 - ccs/lib/libccs.c | 625 - ccs/make/defines.mk.input | 33 - ccs/make/release.mk.input | 15 - ccs/man/Makefile | 30 - ccs/man/ccs.7 | 50 - ccs/man/ccs_test.8 | 140 - ccs/man/ccs_tool.8 | 219 - ccs/man/ccsd.8 | 69 - ccs/man/cluster.conf.5 | 184 - ccs/scripts/uninstall.pl | 84 - cman-kernel/Makefile | 14 - cman-kernel/configure | 174 - cman-kernel/make/defines.mk.input | 41 - cman-kernel/make/release.mk.input | 15 - cman-kernel/patches/2.6.9/00001.patch | 227 - cman-kernel/scripts/uninstall.pl | 84 - cman-kernel/src/Makefile | 75 - cman-kernel/src/cnxman-private.h | 442 - cman-kernel/src/cnxman-socket.h | 245 - cman-kernel/src/cnxman.c | 4399 --- cman-kernel/src/cnxman.h | 87 - cman-kernel/src/config.c | 51 - cman-kernel/src/config.h | 33 - cman-kernel/src/kjoin.c | 238 - cman-kernel/src/membership.c | 3376 --- cman-kernel/src/proc.c | 562 - cman-kernel/src/service.h | 102 - cman-kernel/src/sm.h | 109 - cman-kernel/src/sm_barrier.c | 239 - cman-kernel/src/sm_barrier.h | 29 - cman-kernel/src/sm_control.c | 156 - cman-kernel/src/sm_control.h | 22 - cman-kernel/src/sm_daemon.c | 114 - cman-kernel/src/sm_daemon.h | 32 - cman-kernel/src/sm_internal.h | 232 - cman-kernel/src/sm_joinleave.c | 1293 - cman-kernel/src/sm_joinleave.h | 23 - cman-kernel/src/sm_membership.c | 701 - cman-kernel/src/sm_membership.h | 20 - cman-kernel/src/sm_message.c | 884 - cman-kernel/src/sm_message.h | 34 - cman-kernel/src/sm_misc.c | 454 - cman-kernel/src/sm_misc.h | 29 - cman-kernel/src/sm_recover.c | 577 - cman-kernel/src/sm_recover.h | 24 - cman-kernel/src/sm_services.c | 420 - cman-kernel/src/sm_services.h | 20 - cman-kernel/src/sm_user.c | 569 - cman-kernel/src/sm_user.h | 21 - cman/Makefile | 45 - cman/bin/Makefile | 28 - cman/cman_tool/Makefile | 62 - cman/cman_tool/cman_tool.h | 108 - cman/cman_tool/join.c | 413 - cman/cman_tool/join_ccs.c | 539 - cman/cman_tool/main.c | 831 - cman/config/copyright.cf | 22 - cman/configure | 166 - cman/init.d/Makefile | 30 - cman/init.d/cman | 224 - cman/init.d/qdiskd | 76 - cman/lib/Makefile | 74 - cman/lib/libcman.c | 503 - cman/lib/libcman.h | 165 - cman/make/defines.mk.input | 39 - cman/make/flags.mk | 13 - cman/make/release.mk.input | 15 - cman/man/Makefile | 27 - cman/man/cman.5 | 114 - cman/man/cman_tool.8 | 306 - cman/man/mkqdisk.8 | 28 - cman/man/qdisk.5 | 461 - cman/man/qdiskd.8 | 25 - cman/qdisk/Makefile | 59 - cman/qdisk/README | 1 - cman/qdisk/bitmap.c | 107 - cman/qdisk/clulog.c | 291 - cman/qdisk/clulog.h | 161 - cman/qdisk/crc32.c | 125 - cman/qdisk/daemon_init.c | 238 - cman/qdisk/disk.c | 798 - cman/qdisk/disk.h | 302 - cman/qdisk/disk_util.c | 344 - cman/qdisk/gettid.c | 24 - cman/qdisk/gettid.h | 7 - cman/qdisk/iostate.c | 142 - cman/qdisk/iostate.h | 17 - cman/qdisk/main.c | 1664 -- cman/qdisk/mkqdisk.c | 93 - cman/qdisk/platform.h | 59 - cman/qdisk/proc.c | 156 - cman/qdisk/score.c | 490 - cman/qdisk/score.h | 69 - cman/scripts/cman.init | 69 - cman/scripts/uninstall.pl | 84 - cman/tests/Makefile | 36 - cman/tests/client.c | 156 - cman/tests/libtest.c | 96 - cman/tests/msgtest.c | 175 - cman/tests/qwait.c | 67 - cman/tests/sysman.c | 73 - cman/tests/sysmand.c | 542 - cman/tests/user_service.c | 298 - cmirror-kernel/Makefile | 14 - cmirror-kernel/README | 10 - cmirror-kernel/TODO | 50 - cmirror-kernel/configure | 174 - cmirror-kernel/make/defines.mk.input | 41 - cmirror-kernel/make/release.mk.input | 15 - cmirror-kernel/scripts/uninstall.pl | 84 - cmirror-kernel/src/Makefile | 46 - cmirror-kernel/src/dm-cmirror-client.c | 1559 - cmirror-kernel/src/dm-cmirror-cman.c | 101 - cmirror-kernel/src/dm-cmirror-cman.h | 21 - cmirror-kernel/src/dm-cmirror-common.h | 182 - cmirror-kernel/src/dm-cmirror-server.c | 1480 - cmirror-kernel/src/dm-cmirror-server.h | 18 - cmirror-kernel/src/dm-cmirror-xfr.c | 50 - cmirror-kernel/src/dm-cmirror-xfr.h | 66 - cmirror-kernel/src/dm-log.h | 154 - configure | 49 - csnap/Makefile | 65 - csnap/README | 67 - csnap/agent.c | 359 - csnap/buffer.c | 256 - csnap/buffer.h | 59 - csnap/buffertest.c | 15 - csnap/create.c | 58 - csnap/csnap.c | 2264 -- csnap/csnap.h | 44 - csnap/devpoke.c | 55 - csnap/devspam.c | 83 - csnap/doc/cluster.snapshot.design.html | 1467 - csnap/doc/csnap.ps | 2994 -- csnap/list.h | 64 - csnap/patches/csnap-2.6.7-2.4.26 | 195 - csnap/patches/csnap-2.6.8.1 | 1321 - csnap/sock.h | 55 - csnap/testclient.c | 185 - csnap/trace.h | 7 - dlm-kernel/Makefile | 14 - dlm-kernel/configure | 174 - dlm-kernel/make/defines.mk.input | 41 - dlm-kernel/make/release.mk.input | 15 - dlm-kernel/patches/2.6.9/00001.patch | 62 - dlm-kernel/scripts/uninstall.pl | 84 - dlm-kernel/src/Makefile | 76 - dlm-kernel/src/ast.c | 652 - dlm-kernel/src/ast.h | 31 - dlm-kernel/src/config.c | 163 - dlm-kernel/src/config.h | 36 - dlm-kernel/src/device.c | 1374 - dlm-kernel/src/device.h | 19 - dlm-kernel/src/dir.c | 471 - dlm-kernel/src/dir.h | 33 - dlm-kernel/src/dlm.h | 421 - dlm-kernel/src/dlm_device.h | 105 - dlm-kernel/src/dlm_internal.h | 626 - dlm-kernel/src/lkb.c | 187 - dlm-kernel/src/lkb.h | 23 - dlm-kernel/src/locking.c | 1583 - dlm-kernel/src/locking.h | 33 - dlm-kernel/src/lockqueue.c | 1342 - dlm-kernel/src/lockqueue.h | 30 - dlm-kernel/src/lockspace.c | 760 - dlm-kernel/src/lockspace.h | 29 - dlm-kernel/src/lowcomms.c | 1447 - dlm-kernel/src/lowcomms.h | 34 - dlm-kernel/src/main.c | 93 - dlm-kernel/src/memory.c | 238 - dlm-kernel/src/memory.h | 32 - dlm-kernel/src/midcomms.c | 380 - dlm-kernel/src/midcomms.h | 24 - dlm-kernel/src/nodes.c | 366 - dlm-kernel/src/nodes.h | 27 - dlm-kernel/src/proc.c | 683 - dlm-kernel/src/queries.c | 713 - dlm-kernel/src/queries.h | 20 - dlm-kernel/src/rebuild.c | 1291 - dlm-kernel/src/rebuild.h | 22 - dlm-kernel/src/reccomms.c | 430 - dlm-kernel/src/reccomms.h | 36 - dlm-kernel/src/recover.c | 701 - dlm-kernel/src/recover.h | 34 - dlm-kernel/src/recoverd.c | 718 - dlm-kernel/src/recoverd.h | 23 - dlm-kernel/src/rsb.c | 471 - dlm-kernel/src/rsb.h | 35 - dlm-kernel/src/util.c | 183 - dlm-kernel/src/util.h | 24 - dlm/Makefile | 39 - dlm/configure | 166 - dlm/doc/example.c | 53 - dlm/doc/libdlm.txt | 533 - dlm/doc/user-dlm-overview.txt | 325 - dlm/lib/Makefile | 99 - dlm/lib/dlm32.c | 231 - dlm/lib/libdlm.c | 1118 - dlm/lib/libdlm.h | 297 - dlm/make/defines.mk.input | 39 - dlm/make/flags.mk | 15 - dlm/make/release.mk.input | 15 - dlm/man/Makefile | 34 - dlm/man/dlm_cleanup.3 | 1 - dlm/man/dlm_close_lockspace.3 | 1 - dlm/man/dlm_create_lockspace.3 | 81 - dlm/man/dlm_dispatch.3 | 1 - dlm/man/dlm_get_fd.3 | 1 - dlm/man/dlm_lock.3 | 205 - dlm/man/dlm_lock_wait.3 | 1 - dlm/man/dlm_ls_lock.3 | 1 - dlm/man/dlm_ls_lock_wait.3 | 1 - dlm/man/dlm_ls_pthread_init.3 | 1 - dlm/man/dlm_ls_query.3 | 1 - dlm/man/dlm_ls_query_wait.3 | 1 - dlm/man/dlm_ls_unlock.3 | 1 - dlm/man/dlm_ls_unlock_wait.3 | 1 - dlm/man/dlm_open_lockspace.3 | 1 - dlm/man/dlm_pthread_init.3 | 1 - dlm/man/dlm_query.3 | 196 - dlm/man/dlm_query_wait.3 | 1 - dlm/man/dlm_release_lockspace.3 | 1 - dlm/man/dlm_unlock.3 | 89 - dlm/man/dlm_unlock_wait.3 | 1 - dlm/man/libdlm.3 | 101 - dlm/scripts/51-dlm.rules | 3 - dlm/scripts/uninstall.pl | 84 - dlm/tests/locktest/lockrange.c | 453 - dlm/tests/locktest/locktest.c | 536 - dlm/tests/locktest/timelocks.c | 241 - dlm/tests/usertest/Makefile | 46 - dlm/tests/usertest/asttest.c | 264 - dlm/tests/usertest/dlmtest.c | 288 - dlm/tests/usertest/lstest.c | 326 - dlm/tests/usertest/lvb.c | 233 - dlm/tests/usertest/pingtest.c | 340 - dlm/tool/Makefile | 40 - dlm/tool/main.c | 426 - doc/min-gfs.txt | 159 - fence/Makefile | 39 - fence/agents/Makefile | 101 - fence/agents/apc/Makefile | 35 - fence/agents/apc/README | 47 - fence/agents/apc/fence_apc.pl | 474 - fence/agents/apc/fence_apc.py | 218 - fence/agents/apc/fence_apc_snmp.py | 463 - fence/agents/apc/powernet369.mib |31109 -------------------- fence/agents/apc_snmp/Makefile | 43 - fence/agents/apc_snmp/README_SNMP | 47 - fence/agents/apc_snmp/fence_apc_snmp.py | 469 - fence/agents/apc_snmp/powernet369.mib |31109 -------------------- fence/agents/baytech/Makefile | 37 - fence/agents/baytech/fence_baytech.pl | 685 - fence/agents/baytech/fence_baytech.py | 283 - fence/agents/bladecenter/Makefile | 35 - fence/agents/bladecenter/fence_bladecenter.pl | 332 - fence/agents/bladecenter/fence_bladecenter.py | 98 - fence/agents/brocade/Makefile | 37 - fence/agents/brocade/fence_brocade.pl | 266 - fence/agents/bullpap/Makefile | 37 - fence/agents/bullpap/fence_bullpap.pl | 369 - fence/agents/cpint/Makefile | 37 - fence/agents/cpint/fence_cpint.pl | 147 - fence/agents/drac/Makefile | 48 - fence/agents/drac/fence_drac.pl | 668 - fence/agents/drac/fence_drac5.py | 104 - fence/agents/drac/test_drac.sh | 83 - fence/agents/egenera/Makefile | 38 - fence/agents/egenera/fence_egenera.pl | 442 - fence/agents/eps/Makefile | 38 - fence/agents/eps/fence_eps.py | 108 - fence/agents/ibmblade/Makefile | 37 - fence/agents/ibmblade/fence_ibmblade.pl | 277 - fence/agents/ilo/Makefile | 35 - fence/agents/ilo/fence_ilo.pl | 659 - fence/agents/ilo/fence_ilo.py | 109 - fence/agents/ipmilan/Makefile | 37 - fence/agents/ipmilan/expect.c | 361 - fence/agents/ipmilan/expect.h | 68 - fence/agents/ipmilan/ipmilan.c | 1237 - fence/agents/lib/Makefile | 48 - fence/agents/lib/fencing.py.py | 492 - fence/agents/lib/telnet_ssl.py | 72 - fence/agents/lpar/Makefile | 35 - fence/agents/lpar/fence_lpar.py | 132 - fence/agents/manual/Makefile | 41 - fence/agents/manual/ack.c | 156 - fence/agents/manual/manual.c | 329 - fence/agents/mcdata/Makefile | 37 - fence/agents/mcdata/fence_mcdata.pl | 305 - fence/agents/rackswitch/Makefile | 40 - fence/agents/rackswitch/do_rack.c | 748 - fence/agents/rackswitch/do_rack.h | 31 - fence/agents/rps10/Makefile | 37 - fence/agents/rps10/rps10.c | 540 - fence/agents/rsa/Makefile | 35 - fence/agents/rsa/fence_rsa.py | 75 - fence/agents/rsb/Makefile | 35 - fence/agents/rsb/fence_rsb.py | 387 - fence/agents/sanbox2/Makefile | 37 - fence/agents/sanbox2/fence_sanbox2.py | 123 - fence/agents/scsi/Makefile | 48 - fence/agents/scsi/fence_scsi.pl | 401 - fence/agents/scsi/fence_scsi_test.pl | 252 - fence/agents/scsi/scsi_reserve | 303 - fence/agents/vixel/Makefile | 37 - fence/agents/vixel/fence_vixel.pl | 228 - fence/agents/wti/Makefile | 36 - fence/agents/wti/fence_wti.pl | 384 - fence/agents/wti/fence_wti.py | 135 - fence/agents/xcat/Makefile | 32 - fence/agents/xcat/fence_xcat.pl | 199 - fence/agents/xvm/Makefile | 59 - fence/agents/xvm/README | 182 - fence/agents/xvm/TODO | 33 - fence/agents/xvm/debug.c | 35 - fence/agents/xvm/debug.h | 31 - fence/agents/xvm/fence_xvm.c | 368 - fence/agents/xvm/ip_lookup.c | 322 - fence/agents/xvm/ip_lookup.h | 40 - fence/agents/xvm/mcast.c | 373 - fence/agents/xvm/mcast.h | 32 - fence/agents/xvm/options.c | 637 - fence/agents/xvm/options.h | 70 - fence/agents/xvm/simple_auth.c | 411 - fence/agents/xvm/simple_auth.h | 35 - fence/agents/xvm/tcp.c | 300 - fence/agents/xvm/tcp.h | 27 - fence/agents/xvm/xvm.h | 76 - fence/agents/zvm/Makefile | 37 - fence/agents/zvm/fence_zvm.pl | 357 - fence/bin/Makefile | 87 - fence/config/copyright.cf | 22 - fence/configure | 166 - fence/fence_node/Makefile | 48 - fence/fence_node/fence_node.c | 120 - fence/fence_tool/Makefile | 58 - fence/fence_tool/fence_tool.c | 553 - fence/fenced/Makefile | 56 - fence/fenced/agent.c | 347 - fence/fenced/fd.h | 181 - fence/fenced/main.c | 696 - fence/fenced/recover.c | 657 - fence/include/list.h | 325 - fence/init.d/Makefile | 30 - fence/init.d/fenced | 139 - fence/make/defines.mk.input | 34 - fence/make/release.mk.input | 15 - fence/man/Makefile | 51 - fence/man/fence.8 | 73 - fence/man/fence_ack_manual.8 | 43 - fence/man/fence_apc.8 | 105 - fence/man/fence_baytech.8 | 89 - fence/man/fence_bladecenter.8 | 102 - fence/man/fence_brocade.8 | 89 - fence/man/fence_bullpap.8 | 78 - fence/man/fence_cpint.8 | 59 - fence/man/fence_drac.8 | 103 - fence/man/fence_egenera.8 | 77 - fence/man/fence_eps.8 | 106 - fence/man/fence_ibmblade.8 | 68 - fence/man/fence_ilo.8 | 101 - fence/man/fence_ipmilan.8 | 101 - fence/man/fence_manual.8 | 56 - fence/man/fence_mcdata.8 | 89 - fence/man/fence_node.8 | 43 - fence/man/fence_rackswitch.8 | 75 - fence/man/fence_rib.8 | 17 - fence/man/fence_rsa.8 | 76 - fence/man/fence_rsb.8 | 81 - fence/man/fence_sanbox2.8 | 89 - fence/man/fence_scsi.8 | 109 - fence/man/fence_tool.8 | 64 - fence/man/fence_vixel.8 | 77 - fence/man/fence_wti.8 | 90 - fence/man/fence_xcat.8 | 64 - fence/man/fence_xvm.8 | 142 - fence/man/fence_zvm.8 | 69 - fence/man/fenced.8 | 141 - fence/scripts/define2var | 71 - fence/scripts/uninstall.pl | 84 - gfs-kernel/Makefile | 14 - gfs-kernel/configure | 174 - gfs-kernel/make/defines.mk.input | 41 - gfs-kernel/make/release.mk.input | 15 - gfs-kernel/patches/2.6.9/00001.patch | 65 - gfs-kernel/patches/2.6.9/00002.patch | 106 - gfs-kernel/patches/2.6.9/00003.patch | 46 - gfs-kernel/patches/2.6.9/00004.patch | 46 - gfs-kernel/patches/2.6.9/00005.patch | 61 - gfs-kernel/scripts/uninstall.pl | 84 - gfs-kernel/src/Makefile | 50 - gfs-kernel/src/dlm/Makefile | 77 - gfs-kernel/src/dlm/group.c | 882 - gfs-kernel/src/dlm/lock.c | 766 - gfs-kernel/src/dlm/lock_dlm.h | 388 - gfs-kernel/src/dlm/main.c | 359 - gfs-kernel/src/dlm/mount.c | 589 - gfs-kernel/src/dlm/plock.c | 1269 - gfs-kernel/src/dlm/thread.c | 448 - gfs-kernel/src/gfs/Makefile | 109 - gfs-kernel/src/gfs/acl.c | 383 - gfs-kernel/src/gfs/acl.h | 46 - gfs-kernel/src/gfs/bits.c | 189 - gfs-kernel/src/gfs/bits.h | 32 - gfs-kernel/src/gfs/bmap.c | 1406 - gfs-kernel/src/gfs/bmap.h | 48 - gfs-kernel/src/gfs/daemon.c | 286 - gfs-kernel/src/gfs/daemon.h | 24 - gfs-kernel/src/gfs/diaper.c | 631 - gfs-kernel/src/gfs/diaper.h | 26 - gfs-kernel/src/gfs/dio.c | 1244 - gfs-kernel/src/gfs/dio.h | 195 - gfs-kernel/src/gfs/dir.c | 2420 -- gfs-kernel/src/gfs/dir.h | 55 - gfs-kernel/src/gfs/eaops.c | 314 - gfs-kernel/src/gfs/eaops.h | 35 - gfs-kernel/src/gfs/eattr.c | 2020 -- gfs-kernel/src/gfs/eattr.h | 107 - gfs-kernel/src/gfs/file.c | 458 - gfs-kernel/src/gfs/file.h | 55 - gfs-kernel/src/gfs/fixed_div64.h | 142 - gfs-kernel/src/gfs/format.h | 30 - gfs-kernel/src/gfs/gfs.h | 96 - gfs-kernel/src/gfs/gfs_ioctl.h | 33 - gfs-kernel/src/gfs/gfs_ondisk.h | 1915 -- gfs-kernel/src/gfs/glock.c | 3002 -- gfs-kernel/src/gfs/glock.h | 151 - gfs-kernel/src/gfs/glops.c | 671 - gfs-kernel/src/gfs/glops.h | 26 - gfs-kernel/src/gfs/incore.h | 1226 - gfs-kernel/src/gfs/inode.c | 2234 -- gfs-kernel/src/gfs/inode.h | 72 - gfs-kernel/src/gfs/ioctl.c | 1520 - gfs-kernel/src/gfs/ioctl.h | 19 - gfs-kernel/src/gfs/lm.c | 500 - gfs-kernel/src/gfs/lm.h | 46 - gfs-kernel/src/gfs/log.c | 1529 - gfs-kernel/src/gfs/log.h | 79 - gfs-kernel/src/gfs/lops.c | 1661 -- gfs-kernel/src/gfs/lops.h | 179 - gfs-kernel/src/gfs/lvb.c | 148 - gfs-kernel/src/gfs/lvb.h | 66 - gfs-kernel/src/gfs/main.c | 132 - gfs-kernel/src/gfs/mount.c | 156 - gfs-kernel/src/gfs/mount.h | 19 - gfs-kernel/src/gfs/ondisk.c | 28 - gfs-kernel/src/gfs/ops_address.c | 489 - gfs-kernel/src/gfs/ops_address.h | 19 - gfs-kernel/src/gfs/ops_dentry.c | 124 - gfs-kernel/src/gfs/ops_dentry.h | 19 - gfs-kernel/src/gfs/ops_export.c | 450 - gfs-kernel/src/gfs/ops_export.h | 19 - gfs-kernel/src/gfs/ops_file.c | 1879 -- gfs-kernel/src/gfs/ops_file.h | 20 - gfs-kernel/src/gfs/ops_fstype.c | 786 - gfs-kernel/src/gfs/ops_fstype.h | 22 - gfs-kernel/src/gfs/ops_inode.c | 1836 -- gfs-kernel/src/gfs/ops_inode.h | 22 - gfs-kernel/src/gfs/ops_super.c | 480 - gfs-kernel/src/gfs/ops_super.h | 19 - gfs-kernel/src/gfs/ops_vm.c | 238 - gfs-kernel/src/gfs/ops_vm.h | 20 - gfs-kernel/src/gfs/page.c | 279 - gfs-kernel/src/gfs/page.h | 26 - gfs-kernel/src/gfs/proc.c | 505 - gfs-kernel/src/gfs/proc.h | 27 - gfs-kernel/src/gfs/quota.c | 1152 - gfs-kernel/src/gfs/quota.h | 41 - gfs-kernel/src/gfs/recovery.c | 783 - gfs-kernel/src/gfs/recovery.h | 36 - gfs-kernel/src/gfs/rgrp.c | 2165 -- gfs-kernel/src/gfs/rgrp.h | 87 - gfs-kernel/src/gfs/super.c | 1287 - gfs-kernel/src/gfs/super.h | 68 - gfs-kernel/src/gfs/trans.c | 463 - gfs-kernel/src/gfs/trans.h | 37 - gfs-kernel/src/gfs/unlinked.c | 444 - gfs-kernel/src/gfs/unlinked.h | 32 - gfs-kernel/src/gfs/util.c | 584 - gfs-kernel/src/gfs/util.h | 343 - gfs-kernel/src/gulm/Makefile | 82 - gfs-kernel/src/gulm/gio_wiretypes.h | 486 - gfs-kernel/src/gulm/gulm.h | 256 - gfs-kernel/src/gulm/gulm_core.c | 259 - gfs-kernel/src/gulm/gulm_firstlock.c | 310 - gfs-kernel/src/gulm/gulm_fs.c | 782 - gfs-kernel/src/gulm/gulm_jid.c | 643 - gfs-kernel/src/gulm/gulm_lock_queue.c | 841 - gfs-kernel/src/gulm/gulm_lock_queue.h | 81 - gfs-kernel/src/gulm/gulm_log_msg_bits.h | 40 - gfs-kernel/src/gulm/gulm_lt.c | 1002 - gfs-kernel/src/gulm/gulm_main.c | 107 - gfs-kernel/src/gulm/gulm_plock.c | 321 - gfs-kernel/src/gulm/gulm_prints.h | 45 - gfs-kernel/src/gulm/gulm_recsig.c | 337 - gfs-kernel/src/gulm/handler.c | 343 - gfs-kernel/src/gulm/handler.h | 42 - gfs-kernel/src/gulm/lg_core.c | 669 - gfs-kernel/src/gulm/lg_lock.c | 785 - gfs-kernel/src/gulm/lg_main.c | 211 - gfs-kernel/src/gulm/lg_priv.h | 88 - gfs-kernel/src/gulm/libgulm.h | 199 - gfs-kernel/src/gulm/utils_tostr.c | 66 - gfs-kernel/src/gulm/utils_tostr.h | 17 - gfs-kernel/src/gulm/xdr.h | 98 - gfs-kernel/src/gulm/xdr_base.c | 907 - gfs-kernel/src/gulm/xdr_io.c | 169 - gfs-kernel/src/gulm/xdr_socket.c | 82 - gfs-kernel/src/harness/Makefile | 70 - gfs-kernel/src/harness/lm_interface.h | 247 - gfs-kernel/src/harness/main.c | 244 - gfs-kernel/src/nolock/Makefile | 67 - gfs-kernel/src/nolock/main.c | 358 - gfs/Makefile | 54 - gfs/bin/Makefile | 51 - gfs/config/copyright.cf | 22 - gfs/configure | 166 - gfs/gfs_debug/Makefile | 54 - gfs/gfs_debug/basic.c | 449 - gfs/gfs_debug/basic.h | 39 - gfs/gfs_debug/block_device.c | 130 - gfs/gfs_debug/block_device.h | 27 - gfs/gfs_debug/gfs_debug.h | 96 - gfs/gfs_debug/main.c | 192 - gfs/gfs_debug/ondisk.c | 26 - gfs/gfs_debug/readfile.c | 249 - gfs/gfs_debug/readfile.h | 27 - gfs/gfs_debug/util.c | 347 - gfs/gfs_debug/util.h | 42 - gfs/gfs_edit/Makefile | 49 - gfs/gfs_edit/gfshex.c | 356 - gfs/gfs_edit/gfshex.h | 23 - gfs/gfs_edit/hexedit.c | 827 - gfs/gfs_edit/hexedit.h | 193 - gfs/gfs_edit/ondisk.c | 24 - gfs/gfs_fsck/FEATURES | 25 - gfs/gfs_fsck/Makefile | 60 - gfs/gfs_fsck/TODO | 49 - gfs/gfs_fsck/bio.c | 181 - gfs/gfs_fsck/bio.h | 36 - gfs/gfs_fsck/bitmap.c | 130 - gfs/gfs_fsck/bitmap.h | 33 - gfs/gfs_fsck/block_list.c | 301 - gfs/gfs_fsck/block_list.h | 99 - gfs/gfs_fsck/eattr.c | 112 - gfs/gfs_fsck/eattr.h | 33 - gfs/gfs_fsck/file.c | 242 - gfs/gfs_fsck/file.h | 23 - gfs/gfs_fsck/fs_bits.c | 362 - gfs/gfs_fsck/fs_bits.h | 47 - gfs/gfs_fsck/fs_bmap.c | 542 - gfs/gfs_fsck/fs_bmap.h | 23 - gfs/gfs_fsck/fs_dir.c | 1687 -- gfs/gfs_fsck/fs_dir.h | 43 - gfs/gfs_fsck/fs_inode.c | 613 - gfs/gfs_fsck/fs_inode.h | 35 - gfs/gfs_fsck/fs_recovery.c | 89 - gfs/gfs_fsck/fs_recovery.h | 22 - gfs/gfs_fsck/fsck.h | 47 - gfs/gfs_fsck/fsck_incore.h | 151 - gfs/gfs_fsck/hash.c | 104 - gfs/gfs_fsck/hash.h | 20 - gfs/gfs_fsck/initialize.c | 441 - gfs/gfs_fsck/inode.c | 343 - gfs/gfs_fsck/inode.h | 25 - gfs/gfs_fsck/inode_hash.c | 87 - gfs/gfs_fsck/inode_hash.h | 20 - gfs/gfs_fsck/link.c | 107 - gfs/gfs_fsck/link.h | 22 - gfs/gfs_fsck/log.c | 155 - gfs/gfs_fsck/log.h | 99 - gfs/gfs_fsck/lost_n_found.c | 146 - gfs/gfs_fsck/lost_n_found.h | 21 - gfs/gfs_fsck/main.c | 289 - gfs/gfs_fsck/metawalk.c | 819 - gfs/gfs_fsck/metawalk.h | 77 - gfs/gfs_fsck/ondisk.c | 1355 - gfs/gfs_fsck/ondisk.h | 2058 -- gfs/gfs_fsck/pass1.c | 936 - gfs/gfs_fsck/pass1b.c | 534 - gfs/gfs_fsck/pass1c.c | 286 - gfs/gfs_fsck/pass2.c | 957 - gfs/gfs_fsck/pass3.c | 287 - gfs/gfs_fsck/pass4.c | 194 - gfs/gfs_fsck/pass5.c | 378 - gfs/gfs_fsck/rgrp.c | 637 - gfs/gfs_fsck/rgrp.h | 33 - gfs/gfs_fsck/super.c | 1290 - gfs/gfs_fsck/super.h | 24 - gfs/gfs_fsck/test_bitmap.c | 50 - gfs/gfs_fsck/test_block_list.c | 103 - gfs/gfs_fsck/util.c | 342 - gfs/gfs_fsck/util.h | 40 - gfs/gfs_grow/Makefile | 49 - gfs/gfs_grow/main.c | 970 - gfs/gfs_grow/ondisk.c | 26 - gfs/gfs_jadd/Makefile | 52 - gfs/gfs_jadd/main.c | 922 - gfs/gfs_jadd/ondisk.c | 26 - gfs/gfs_mkfs/Makefile | 57 - gfs/gfs_mkfs/device_geometry.c | 195 - gfs/gfs_mkfs/fs_geometry.c | 208 - gfs/gfs_mkfs/locking.c | 115 - gfs/gfs_mkfs/main.c | 407 - gfs/gfs_mkfs/mkfs_gfs.h | 192 - gfs/gfs_mkfs/ondisk.c | 26 - gfs/gfs_mkfs/structures.c | 1042 - gfs/gfs_quota/Makefile | 51 - gfs/gfs_quota/check.c | 646 - gfs/gfs_quota/gfs_quota.h | 107 - gfs/gfs_quota/layout.c | 613 - gfs/gfs_quota/main.c | 747 - gfs/gfs_quota/names.c | 97 - gfs/gfs_quota/ondisk.c | 26 - gfs/gfs_tool/Makefile | 54 - gfs/gfs_tool/counters.c | 215 - gfs/gfs_tool/decipher_lockstate_dump | 186 - gfs/gfs_tool/df.c | 275 - gfs/gfs_tool/gfs_tool.h | 103 - gfs/gfs_tool/layout.c | 855 - gfs/gfs_tool/main.c | 277 - gfs/gfs_tool/misc.c | 746 - gfs/gfs_tool/ondisk.c | 29 - gfs/gfs_tool/parse_lockdump | 172 - gfs/gfs_tool/sb.c | 166 - gfs/gfs_tool/tune.c | 148 - gfs/gfs_tool/util.c | 283 - gfs/include/global.h | 55 - gfs/include/linux_endian.h | 81 - gfs/include/osi_list.h | 97 - gfs/include/osi_user.h | 434 - gfs/init.d/Makefile | 30 - gfs/init.d/gfs | 98 - gfs/make/defines.mk.input | 33 - gfs/make/flags.mk | 14 - gfs/make/release.mk.input | 15 - gfs/man/Makefile | 36 - gfs/man/gfs.8 | 40 - gfs/man/gfs_fsck.8 | 62 - gfs/man/gfs_grow.8 | 66 - gfs/man/gfs_jadd.8 | 78 - gfs/man/gfs_mkfs.8 | 87 - gfs/man/gfs_mount.8 | 214 - gfs/man/gfs_quota.8 | 104 - gfs/man/gfs_tool.8 | 140 - gfs/scripts/uninstall.pl | 84 - gfs/tests/filecon2/Makefile | 31 - gfs/tests/filecon2/filecon2.h | 159 - gfs/tests/filecon2/filecon2_client.c | 854 - gfs/tests/filecon2/filecon2_server.c | 610 - gfs/tests/mmdd/Makefile | 29 - gfs/tests/mmdd/mmdd.c | 716 - gnbd-kernel/Makefile | 14 - gnbd-kernel/configure | 174 - gnbd-kernel/make/defines.mk.input | 41 - gnbd-kernel/make/release.mk.input | 15 - gnbd-kernel/patches/2.6.9/00001.patch | 26 - gnbd-kernel/scripts/uninstall.pl | 84 - gnbd-kernel/src/Makefile | 71 - gnbd-kernel/src/gnbd.c | 1054 - gnbd-kernel/src/gnbd.h | 103 - gnbd/COPYING | 340 - gnbd/Makefile | 36 - gnbd/bin/Makefile | 51 - gnbd/client/Makefile | 50 - gnbd/client/gnbd_monitor.c | 786 - gnbd/client/gnbd_monitor.h | 40 - gnbd/client/gnbd_recvd.c | 398 - gnbd/client/monitor_req.c | 157 - gnbd/config/copyright.cf | 22 - gnbd/configure | 166 - gnbd/include/global.h | 39 - gnbd/include/gnbd_endian.h | 79 - gnbd/make/defines.mk.input | 33 - gnbd/make/release.mk.input | 15 - gnbd/man/Makefile | 38 - gnbd/man/fence_gnbd.8 | 87 - gnbd/man/gnbd.8 | 43 - gnbd/man/gnbd_export.8 | 164 - gnbd/man/gnbd_import.8 | 174 - gnbd/man/gnbd_serv.8 | 74 - gnbd/scripts/find_executable | 20 - gnbd/scripts/linuxver | 79 - gnbd/scripts/uninstall.pl | 84 - gnbd/server/Makefile | 51 - gnbd/server/device.c | 388 - gnbd/server/device.h | 52 - gnbd/server/extern_req.c | 317 - gnbd/server/extern_req.h | 56 - gnbd/server/fence.c | 147 - gnbd/server/fence.h | 22 - gnbd/server/gnbd_clusterd.c | 91 - gnbd/server/gnbd_serv.c | 409 - gnbd/server/gnbd_server.h | 24 - gnbd/server/gserv.c | 631 - gnbd/server/gserv.h | 67 - gnbd/server/list.h | 95 - gnbd/server/local_req.c | 195 - gnbd/server/local_req.h | 57 - gnbd/tools/Makefile | 28 - gnbd/tools/fence_gnbd/Makefile | 36 - gnbd/tools/fence_gnbd/main.c | 340 - gnbd/tools/gnbd_export/Makefile | 41 - gnbd/tools/gnbd_export/gnbd_export.c | 864 - gnbd/tools/gnbd_export/gnbd_get_uid | 10 - gnbd/tools/gnbd_import/Makefile | 49 - gnbd/tools/gnbd_import/fence_return.h | 19 - gnbd/tools/gnbd_import/gnbd_import.c | 1346 - gnbd/utils/gnbd_utils.c | 424 - gnbd/utils/gnbd_utils.h | 115 - gnbd/utils/trans.c | 328 - gnbd/utils/trans.h | 40 - gulm/COPYING | 340 - gulm/Makefile | 149 - gulm/configure | 166 - gulm/glv/Makefile | 40 - gulm/glv/README | 31 - gulm/glv/glv.language | 79 - gulm/glv/glv.wireproto | 33 - gulm/glv/glvc.c | 341 - gulm/glv/glvd.c | 587 - gulm/glv/glvd.h | 66 - gulm/glv/glvd_parser.y | 565 - gulm/glv/glvd_scanner.l | 85 - gulm/glv/tests/anyflag.glv | 51 - gulm/glv/tests/basiclockconflict.glv | 40 - gulm/glv/tests/basiclvb.glv | 57 - gulm/glv/tests/basicranges.glv | 101 - gulm/glv/tests/basicsubid.glv | 36 - gulm/glv/tests/basicsubidconf.glv | 39 - gulm/glv/tests/basictest.glv | 35 - gulm/glv/tests/basicxmote.glv | 100 - gulm/glv/tests/mergecheck.glv | 16 - gulm/glv/tests/nocbflag.glv | 33 - gulm/glv/tests/onelock.glv | 8 - gulm/glv/tests/prioityflag.glv | 52 - gulm/glv/tests/rangeconflict.glv | 40 - gulm/glv/tests/shared2exlcusive.glv | 68 - gulm/init.d/Makefile | 30 - gulm/init.d/lock_gulmd | 408 - gulm/lib/Makefile | 26 - gulm/lib/exported_symbols.sym | 25 - gulm/lib/lg_core.c | 561 - gulm/lib/lg_lock.c | 543 - gulm/lib/lg_main.c | 169 - gulm/lib/lg_priv.h | 135 - gulm/lib/libgulm.h | 210 - gulm/lib/tests/Makefile | 37 - gulm/lib/tests/basic_lock_test.c | 380 - gulm/lib/tests/core_tests.c | 222 - gulm/make/defines.mk.input | 30 - gulm/make/release.mk.input | 15 - gulm/man/Makefile | 19 - gulm/man/gulm_tool.8 | 171 - gulm/man/lock_gulmd.5 | 140 - gulm/man/lock_gulmd.8 | 373 - gulm/scripts/uninstall.pl | 84 - gulm/src/LLi.h | 114 - gulm/src/Makefile | 29 - gulm/src/Qu.h | 34 - gulm/src/config_ccs.c | 212 - gulm/src/config_ccs.h | 18 - gulm/src/config_cmdline.c | 340 - gulm/src/config_gulm.h | 87 - gulm/src/config_main.c | 738 - gulm/src/config_priv.h | 31 - gulm/src/core.h | 17 - gulm/src/core_fence.c | 202 - gulm/src/core_io.c | 2133 -- gulm/src/core_main.c | 229 - gulm/src/core_nodelists.c | 1120 - gulm/src/core_priv.h | 82 - gulm/src/core_resources.c | 317 - gulm/src/gio_wiretypes.h | 486 - gulm/src/gulm_defines.h | 78 - gulm/src/gulm_log_msg_bits.h | 40 - gulm/src/gulm_tool.c | 869 - gulm/src/hash.c | 369 - gulm/src/hash.h | 34 - gulm/src/hashn.c | 248 - gulm/src/hashn.h | 33 - gulm/src/lock.h | 17 - gulm/src/lock_io.c | 2541 -- gulm/src/lock_main.c | 226 - gulm/src/lock_priv.h | 186 - gulm/src/lock_space.c | 3154 -- gulm/src/log.c | 259 - gulm/src/log.h | 58 - gulm/src/ltpx.h | 17 - gulm/src/ltpx_io.c | 2403 -- gulm/src/ltpx_main.c | 171 - gulm/src/ltpx_map.c | 313 - gulm/src/ltpx_priv.h | 55 - gulm/src/main_main.c | 279 - gulm/src/myio.c | 202 - gulm/src/myio.h | 28 - gulm/src/nodel.c | 133 - gulm/src/nodel.h | 22 - gulm/src/osi_endian.h | 116 - gulm/src/utils_crc.c | 98 - gulm/src/utils_crc.h | 18 - gulm/src/utils_dir.c | 111 - gulm/src/utils_dir.h | 19 - gulm/src/utils_ip.c | 251 - gulm/src/utils_ip.h | 33 - gulm/src/utils_tostr.c | 131 - gulm/src/utils_tostr.h | 22 - gulm/src/utils_verb_flags.c | 256 - gulm/src/utils_verb_flags.h | 18 - gulm/src/xdr.h | 99 - gulm/src/xdr_base.c | 823 - gulm/src/xdr_io.c | 176 - gulm/src/xdr_socket.c | 47 - iddev/Makefile | 26 - iddev/configure | 166 - iddev/include/global.h | 55 - iddev/include/osi_endian.h | 116 - iddev/lib/Makefile | 46 - iddev/lib/exported_symbols.sym | 2 - iddev/lib/iddev.c | 522 - iddev/lib/iddev.h | 46 - iddev/lib/identify_device.c | 83 - iddev/lib/size.c | 102 - iddev/make/defines.mk.input | 33 - iddev/make/release.mk.input | 15 - iddev/scripts/uninstall.pl | 84 - magma-plugins/Makefile | 38 - magma-plugins/cman/Makefile | 56 - magma-plugins/cman/cman-plugin.h | 12 - magma-plugins/cman/cman.c | 534 - magma-plugins/configure | 180 - magma-plugins/doc/COPYING | 851 - magma-plugins/dumb/Makefile | 42 - magma-plugins/dumb/dumb.c | 296 - magma-plugins/gulm/Makefile | 45 - magma-plugins/gulm/gulm-lock.c | 375 - magma-plugins/gulm/gulm-plugin.h | 44 - magma-plugins/gulm/gulm.c | 655 - magma-plugins/make/defines.mk.input | 35 - magma-plugins/make/release.mk.input | 15 - magma-plugins/scripts/uninstall.pl | 84 - magma-plugins/sm/Makefile | 55 - magma-plugins/sm/services.c | 324 - magma-plugins/sm/sm-plugin.h | 43 - magma-plugins/sm/sm.c | 990 - magma/Doxyfile | 187 - magma/Makefile | 33 - magma/configure | 180 - magma/doc/COPYING-libmagma | 851 - magma/doc/COPYING-libmagmamsg | 340 - magma/doc/TODO | 3 - magma/doc/magma.txt | 247 - magma/lib/Makefile | 119 - magma/lib/clist.c | 356 - magma/lib/clist.h | 37 - magma/lib/fdops.c | 193 - magma/lib/global.c | 606 - magma/lib/ip_lookup.c | 291 - magma/lib/ip_lookup.h | 27 - magma/lib/localinfo.c | 127 - magma/lib/magma-build.h | 251 - magma/lib/magma.h | 484 - magma/lib/magmamsg.h | 55 - magma/lib/memberlist.c | 527 - magma/lib/message.c | 922 - magma/lib/plugin.c | 779 - magma/make/defines.mk.input | 35 - magma/make/release.mk.input | 15 - magma/man/Makefile | 24 - magma/man/clu_connect.3 | 34 - magma/man/clu_disconnect.3 | 1 - magma/man/clu_get_event.3 | 39 - magma/man/magma_tool.8 | 98 - magma/scripts/uninstall.pl | 84 - magma/tests/Makefile | 55 - magma/tests/circleping.c | 250 - magma/tests/cluster_cmd.c | 482 - magma/tests/cptester.c | 108 - magma/tests/magma_tool.c | 484 - magma/tests/thread_test.c | 117 - rgmanager/AUTHORS | 13 - rgmanager/COPYING | 340 - rgmanager/ChangeLog | 312 - rgmanager/INSTALL | 7 - rgmanager/Makefile | 32 - rgmanager/NEWS | 1 - rgmanager/README | 359 - rgmanager/TODO | 22 - rgmanager/configure | 167 - rgmanager/errors.txt | 554 - rgmanager/event-script.txt | 311 - rgmanager/examples/cluster.conf | 106 - rgmanager/include/clulog.h | 161 - rgmanager/include/event.h | 147 - rgmanager/include/findproc.h | 29 - rgmanager/include/gettid.h | 7 - rgmanager/include/list.h | 94 - rgmanager/include/msgsimple.h | 65 - rgmanager/include/platform.h | 72 - rgmanager/include/pthread_dbg.h | 41 - rgmanager/include/res-ocf.h | 68 - rgmanager/include/resgroup.h | 260 - rgmanager/include/reslist.h | 243 - rgmanager/include/restart_counter.h | 32 - rgmanager/include/rg_locks.h | 52 - rgmanager/include/rg_queue.h | 65 - rgmanager/include/rmtab.h | 119 - rgmanager/include/sets.h | 39 - rgmanager/include/signals.h | 9 - rgmanager/include/vf.h | 187 - rgmanager/init.d/Makefile | 30 - rgmanager/init.d/rgmanager | 149 - rgmanager/make/defines.mk.input | 42 - rgmanager/make/release.mk.input | 15 - rgmanager/man/Makefile | 25 - rgmanager/man/cluarp.8 | 15 - rgmanager/man/clubufflush.8 | 13 - rgmanager/man/clufindhostname.8 | 22 - rgmanager/man/clulog.8 | 35 - rgmanager/man/clunfsops.8 | 14 - rgmanager/man/clurgmgrd.8 | 30 - rgmanager/man/clurmtabd.8 | 37 - rgmanager/man/clushutdown.8 | 13 - rgmanager/man/clustat.8 | 53 - rgmanager/man/clusvcadm.8 | 93 - rgmanager/scripts/uninstall.pl | 84 - rgmanager/src/Makefile | 43 - rgmanager/src/clulib/Makefile | 46 - rgmanager/src/clulib/alloc.c | 1225 - rgmanager/src/clulib/clulog.c | 320 - rgmanager/src/clulib/daemon_init.c | 236 - rgmanager/src/clulib/gettid.c | 24 - rgmanager/src/clulib/msgsimple.c | 163 - rgmanager/src/clulib/rg_strings.c | 179 - rgmanager/src/clulib/sets.c | 370 - rgmanager/src/clulib/signals.c | 86 - rgmanager/src/clulib/tmgr.c | 128 - rgmanager/src/clulib/vft.c | 1953 -- rgmanager/src/clulib/wrap_lock.c | 224 - rgmanager/src/daemons/Makefile | 83 - rgmanager/src/daemons/clurmtabd.c | 634 - rgmanager/src/daemons/clurmtabd_lib.c | 837 - rgmanager/src/daemons/event_config.c | 540 - rgmanager/src/daemons/fo_domain.c | 653 - rgmanager/src/daemons/groups.c | 1749 -- rgmanager/src/daemons/main.c | 982 - rgmanager/src/daemons/members.c | 164 - rgmanager/src/daemons/nodeevent.c | 99 - rgmanager/src/daemons/reslist.c | 886 - rgmanager/src/daemons/resrules.c | 1220 - rgmanager/src/daemons/restart_counter.c | 205 - rgmanager/src/daemons/restree.c | 1711 -- rgmanager/src/daemons/rg_event.c | 516 - rgmanager/src/daemons/rg_forward.c | 257 - rgmanager/src/daemons/rg_locks.c | 373 - rgmanager/src/daemons/rg_queue.c | 84 - rgmanager/src/daemons/rg_state.c | 1716 -- rgmanager/src/daemons/rg_thread.c | 648 - rgmanager/src/daemons/service_op.c | 218 - rgmanager/src/daemons/slang_event.c | 1290 - rgmanager/src/daemons/test.c | 405 - .../daemons/tests/delta-test001-test002.expected | 56 - .../daemons/tests/delta-test002-test003.expected | 70 - .../daemons/tests/delta-test003-test004.expected | 84 - .../daemons/tests/delta-test004-test005.expected | 95 - .../daemons/tests/delta-test005-test006.expected | 110 - .../daemons/tests/delta-test006-test007.expected | 110 - .../daemons/tests/delta-test007-test008.expected | 116 - .../daemons/tests/delta-test008-test009.expected | 135 - .../daemons/tests/delta-test009-test010.expected | 149 - .../daemons/tests/delta-test010-test011.expected | 232 - .../daemons/tests/delta-test011-test012.expected | 307 - .../daemons/tests/delta-test012-test013.expected | 316 - .../daemons/tests/delta-test013-test014.expected | 407 - .../daemons/tests/delta-test014-test015.expected | 494 - .../daemons/tests/delta-test015-test016.expected | 487 - .../daemons/tests/delta-test016-test017.expected | 535 - .../daemons/tests/delta-test017-test018.expected | 558 - rgmanager/src/daemons/tests/gentests.sh | 74 - rgmanager/src/daemons/tests/runtests.sh | 110 - rgmanager/src/daemons/tests/test001.conf | 7 - rgmanager/src/daemons/tests/test001.expected | 32 - rgmanager/src/daemons/tests/test001.start.expected | 3 - rgmanager/src/daemons/tests/test001.stop.expected | 3 - rgmanager/src/daemons/tests/test002.conf | 13 - rgmanager/src/daemons/tests/test002.expected | 32 - rgmanager/src/daemons/tests/test002.start.expected | 3 - rgmanager/src/daemons/tests/test002.stop.expected | 3 - rgmanager/src/daemons/tests/test003.conf | 14 - rgmanager/src/daemons/tests/test003.expected | 44 - rgmanager/src/daemons/tests/test003.start.expected | 4 - rgmanager/src/daemons/tests/test003.stop.expected | 4 - rgmanager/src/daemons/tests/test004.conf | 15 - rgmanager/src/daemons/tests/test004.expected | 44 - rgmanager/src/daemons/tests/test004.start.expected | 4 - rgmanager/src/daemons/tests/test004.stop.expected | 4 - rgmanager/src/daemons/tests/test005.conf | 16 - rgmanager/src/daemons/tests/test005.expected | 57 - rgmanager/src/daemons/tests/test005.start.expected | 5 - rgmanager/src/daemons/tests/test005.stop.expected | 5 - rgmanager/src/daemons/tests/test006.conf | 16 - rgmanager/src/daemons/tests/test006.expected | 57 - rgmanager/src/daemons/tests/test006.start.expected | 5 - rgmanager/src/daemons/tests/test006.stop.expected | 5 - rgmanager/src/daemons/tests/test007.conf | 17 - rgmanager/src/daemons/tests/test007.expected | 57 - rgmanager/src/daemons/tests/test007.start.expected | 5 - rgmanager/src/daemons/tests/test007.stop.expected | 5 - rgmanager/src/daemons/tests/test008.conf | 20 - rgmanager/src/daemons/tests/test008.expected | 67 - rgmanager/src/daemons/tests/test008.start.expected | 5 - rgmanager/src/daemons/tests/test008.stop.expected | 5 - rgmanager/src/daemons/tests/test009.conf | 19 - rgmanager/src/daemons/tests/test009.expected | 74 - rgmanager/src/daemons/tests/test009.start.expected | 6 - rgmanager/src/daemons/tests/test009.stop.expected | 6 - rgmanager/src/daemons/tests/test010.conf | 19 - rgmanager/src/daemons/tests/test010.expected | 83 - rgmanager/src/daemons/tests/test010.start.expected | 6 - rgmanager/src/daemons/tests/test010.stop.expected | 6 - rgmanager/src/daemons/tests/test011.conf | 38 - rgmanager/src/daemons/tests/test011.expected | 153 - rgmanager/src/daemons/tests/test011.start.expected | 9 - rgmanager/src/daemons/tests/test011.stop.expected | 9 - rgmanager/src/daemons/tests/test012.conf | 33 - rgmanager/src/daemons/tests/test012.expected | 160 - rgmanager/src/daemons/tests/test012.start.expected | 10 - rgmanager/src/daemons/tests/test012.stop.expected | 10 - rgmanager/src/daemons/tests/test013.conf | 34 - rgmanager/src/daemons/tests/test013.expected | 160 - rgmanager/src/daemons/tests/test013.start.expected | 10 - rgmanager/src/daemons/tests/test013.stop.expected | 10 - rgmanager/src/daemons/tests/test014.conf | 46 - rgmanager/src/daemons/tests/test014.expected | 247 - rgmanager/src/daemons/tests/test014.start.expected | 20 - rgmanager/src/daemons/tests/test014.stop.expected | 20 - rgmanager/src/daemons/tests/test015.conf | 51 - rgmanager/src/daemons/tests/test015.expected | 247 - rgmanager/src/daemons/tests/test015.start.expected | 20 - rgmanager/src/daemons/tests/test015.stop.expected | 20 - rgmanager/src/daemons/tests/test016.conf | 50 - rgmanager/src/daemons/tests/test016.expected | 248 - rgmanager/src/daemons/tests/test016.start.expected | 22 - rgmanager/src/daemons/tests/test016.stop.expected | 22 - rgmanager/src/daemons/tests/test017.conf | 68 - rgmanager/src/daemons/tests/test017.expected | 271 - rgmanager/src/daemons/tests/test017.start.expected | 22 - rgmanager/src/daemons/tests/test017.stop.expected | 22 - rgmanager/src/daemons/tests/test018.conf | 78 - rgmanager/src/daemons/tests/test018.expected | 291 - rgmanager/src/daemons/tests/test018.start.expected | 24 - rgmanager/src/daemons/tests/test018.stop.expected | 24 - rgmanager/src/daemons/tests/testlist | 4 - rgmanager/src/daemons/watchdog.c | 97 - rgmanager/src/resources/Makefile | 66 - rgmanager/src/resources/SAPDatabase | 698 - rgmanager/src/resources/SAPInstance | 406 - rgmanager/src/resources/apache.metadata | 95 - rgmanager/src/resources/apache.sh | 277 - rgmanager/src/resources/clusterfs.sh | 876 - rgmanager/src/resources/default_event_script.sl | 316 - rgmanager/src/resources/fs.sh | 1203 - rgmanager/src/resources/ip.sh | 967 - rgmanager/src/resources/lvm.metadata | 86 - rgmanager/src/resources/lvm.sh | 193 - rgmanager/src/resources/lvm_by_lv.sh | 365 - rgmanager/src/resources/lvm_by_vg.sh | 281 - rgmanager/src/resources/mysql.metadata | 96 - rgmanager/src/resources/mysql.sh | 205 - rgmanager/src/resources/named.metadata | 104 - rgmanager/src/resources/named.sh | 223 - rgmanager/src/resources/netfs.sh | 625 - rgmanager/src/resources/nfsclient.sh | 478 - rgmanager/src/resources/nfsexport.sh | 278 - rgmanager/src/resources/ocf-shellfuncs | 185 - rgmanager/src/resources/openldap.metadata | 98 - rgmanager/src/resources/openldap.sh | 240 - rgmanager/src/resources/oracledb.sh | 869 - rgmanager/src/resources/perlscript.pl | 37 - rgmanager/src/resources/postgres-8.metadata | 95 - rgmanager/src/resources/postgres-8.sh | 235 - rgmanager/src/resources/ra-api-1-modified.dtd | 66 - rgmanager/src/resources/samba.metadata | 89 - rgmanager/src/resources/samba.sh | 254 - rgmanager/src/resources/script.sh | 119 - rgmanager/src/resources/service.sh | 302 - rgmanager/src/resources/smb.sh | 768 - rgmanager/src/resources/svclib_nfslock | 278 - rgmanager/src/resources/tomcat-5.metadata | 104 - rgmanager/src/resources/tomcat-5.sh | 287 - rgmanager/src/resources/utils/config-utils.sh | 307 - .../src/resources/utils/httpd-parse-config.pl | 65 - rgmanager/src/resources/utils/member_util.sh | 97 - rgmanager/src/resources/utils/messages.sh | 272 - .../src/resources/utils/named-parse-config.pl | 26 - rgmanager/src/resources/utils/ra-skelet.sh | 95 - .../src/resources/utils/tomcat-parse-config.pl | 45 - rgmanager/src/utils/Makefile | 63 - rgmanager/src/utils/cluarp.c | 177 - rgmanager/src/utils/clubufflush.c | 142 - rgmanager/src/utils/clufindhostname.c | 81 - rgmanager/src/utils/clulog.c | 143 - rgmanager/src/utils/clunfslock.sh | 73 - rgmanager/src/utils/clunfsops.c | 242 - rgmanager/src/utils/clushutdown | 53 - rgmanager/src/utils/clustat.c | 827 - rgmanager/src/utils/clusvcadm.c | 436 - rgmanager/src/utils/syscall.h | 182 - rgmanager/tests/nfs-tests | 343 - scripts/latest_tag.pl | 23 - 1147 files changed, 3 insertions(+), 350738 deletions(-)
diff --git a/Makefile b/Makefile deleted file mode 100644 index 0a11da4..0000000 --- a/Makefile +++ /dev/null @@ -1,179 +0,0 @@ -############################################################################### -############################################################################### -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -# Order is important -LATEST_TAG=scripts/latest_tag.pl -BUILD_SRPMS=scripts/build_srpms.pl -BUILDDIR = $(shell pwd)/build -MAKELINE = sbindir=${BUILDDIR}/sbin libdir=${BUILDDIR}/lib mandir=${BUILDDIR}/man incdir=${BUILDDIR}/incdir module_dir=${BUILDDIR}/module sharedir=${BUILDDIR} slibdir=${BUILDDIR}/slib DESTDIR=${BUILDDIR} - - -all: - cd cman-kernel && ${MAKE} install ${MAKELINE} - cd dlm-kernel && ${MAKE} install ${MAKELINE} - cd gfs-kernel && ${MAKE} install ${MAKELINE} - cd gnbd-kernel && ${MAKE} install ${MAKELINE} - cd magma && ${MAKE} install ${MAKELINE} - cd ccs && ${MAKE} install ${MAKELINE} - cd cman && ${MAKE} install ${MAKELINE} - cd dlm && ${MAKE} install ${MAKELINE} - cd fence && ${MAKE} install ${MAKELINE} - cd iddev && ${MAKE} install ${MAKELINE} - cd gfs && ${MAKE} install ${MAKELINE} - cd gnbd && ${MAKE} install ${MAKELINE} - cd gulm && ${MAKE} install ${MAKELINE} - cd magma-plugins && ${MAKE} install ${MAKELINE} - cd rgmanager && ${MAKE} install ${MAKELINE} - -copytobin: - cd cman-kernel && ${MAKE} copytobin - cd dlm-kernel && ${MAKE} copytobin - cd gfs-kernel && ${MAKE} copytobin - cd gnbd-kernel && ${MAKE} copytobin - cd magma && ${MAKE} copytobin - cd ccs && ${MAKE} copytobin - cd cman && ${MAKE} copytobin - cd dlm && ${MAKE} copytobin - cd fence && ${MAKE} copytobin - cd iddev && ${MAKE} copytobin - cd gfs && ${MAKE} copytobin - cd gnbd && ${MAKE} copytobin - cd gulm && ${MAKE} copytobin - cd magma-plugins && ${MAKE} copytobin - cd rgmanager && ${MAKE} copytobin - -clean: - rm -f *tar.gz - rm -rf build - cd cman-kernel && ${MAKE} clean - cd dlm-kernel && ${MAKE} clean - cd gfs-kernel && ${MAKE} clean - cd gnbd-kernel && ${MAKE} clean - cd magma && ${MAKE} clean - cd ccs && ${MAKE} clean - cd cman && ${MAKE} clean - cd dlm && ${MAKE} clean - cd fence && ${MAKE} clean - cd iddev && ${MAKE} clean - cd gfs && ${MAKE} clean - cd gnbd && ${MAKE} clean - cd gulm && ${MAKE} clean - cd magma-plugins && ${MAKE} clean - cd rgmanager && ${MAKE} clean - -distclean: - cd cman-kernel && ${MAKE} distclean - cd dlm-kernel && ${MAKE} distclean - cd gfs-kernel && ${MAKE} distclean - cd gnbd-kernel && ${MAKE} distclean - cd magma && ${MAKE} distclean - cd ccs && ${MAKE} distclean - cd cman && ${MAKE} distclean - cd dlm && ${MAKE} distclean - cd fence && ${MAKE} distclean - cd iddev && ${MAKE} distclean - cd gfs && ${MAKE} distclean - cd gnbd && ${MAKE} distclean - cd gulm && ${MAKE} distclean - cd magma-plugins && ${MAKE} distclean - cd rgmanager && ${MAKE} distclean - -install: - cd cman-kernel && ${MAKE} install - cd dlm-kernel && ${MAKE} install - cd gfs-kernel && ${MAKE} install - cd gnbd-kernel && ${MAKE} install - cd magma && ${MAKE} install - cd ccs && ${MAKE} install - cd cman && ${MAKE} install - cd dlm && ${MAKE} install - cd fence && ${MAKE} install - cd iddev && ${MAKE} install - cd gfs && ${MAKE} install - cd gnbd && ${MAKE} install - cd gulm && ${MAKE} install - cd magma-plugins && ${MAKE} install - cd rgmanager && ${MAKE} install - -uninstall: - cd cman-kernel && ${MAKE} uninstall - cd dlm-kernel && ${MAKE} uninstall - cd gfs-kernel && ${MAKE} uninstall - cd gnbd-kernel && ${MAKE} uninstall - cd magma && ${MAKE} uninstall - cd ccs && ${MAKE} uninstall - cd cman && ${MAKE} uninstall - cd dlm && ${MAKE} uninstall - cd fence && ${MAKE} uninstall - cd iddev && ${MAKE} uninstall - cd gfs && ${MAKE} uninstall - cd gnbd && ${MAKE} uninstall - cd gulm && ${MAKE} uninstall - cd magma-plugins && ${MAKE} uninstall - cd rgmanager && ${MAKE} uninstall - -latest_tags: - ${LATEST_TAG} cman-kernel - ${LATEST_TAG} dlm-kernel - ${LATEST_TAG} gfs-kernel - ${LATEST_TAG} gnbd-kernel - ${LATEST_TAG} magma - ${LATEST_TAG} ccs - ${LATEST_TAG} cman - ${LATEST_TAG} dlm - ${LATEST_TAG} fence - ${LATEST_TAG} iddev - ${LATEST_TAG} gfs - ${LATEST_TAG} gnbd - ${LATEST_TAG} gulm - ${LATEST_TAG} magma-plugins - ${LATEST_TAG} rgmanager - echo "Beware, your directories are now in sync with their last tag." > TAG - -setrelease: - for i in `ls */make/release.mk.input`; do ${EDITOR} $$i; done - -.PHONY: srpms - -srpms: - $(BUILD_SRPMS) - -tarballs: TAG - make -s COMPONENT=cman-kernel RELEASE_FILE=cman-kernel/make/release.mk.input tarball - make -s COMPONENT=dlm-kernel RELEASE_FILE=dlm-kernel/make/release.mk.input tarball - make -s COMPONENT=gfs-kernel RELEASE_FILE=gfs-kernel/make/release.mk.input tarball - make -s COMPONENT=gnbd-kernel RELEASE_FILE=gnbd-kernel/make/release.mk.input tarball - make -s COMPONENT=magma RELEASE_FILE=magma/make/release.mk.input tarball - make -s COMPONENT=ccs RELEASE_FILE=ccs/make/release.mk.input tarball - make -s COMPONENT=cman RELEASE_FILE=cman/make/release.mk.input tarball - make -s COMPONENT=dlm RELEASE_FILE=dlm/make/release.mk.input tarball - make -s COMPONENT=fence RELEASE_FILE=fence/make/release.mk.input tarball - make -s COMPONENT=iddev RELEASE_FILE=iddev/make/release.mk.input tarball - make -s COMPONENT=gfs RELEASE_FILE=gfs/make/release.mk.input tarball - make -s COMPONENT=gnbd RELEASE_FILE=gnbd/make/release.mk.input tarball - make -s COMPONENT=gulm RELEASE_FILE=gulm/make/release.mk.input tarball - make -s COMPONENT=magma-plugins RELEASE_FILE=magma-plugins/make/release.mk.input tarball - make -s COMPONENT=rgmanager RELEASE_FILE=rgmanager/make/release.mk.input tarball - -ifdef RELEASE_FILE -include ${RELEASE_FILE} -endif - -ifneq (${RELEASE_MAJOR}, DEVEL) -tarball: - cp -r ${COMPONENT} ${COMPONENT}-${RELEASE_MAJOR}.${RELEASE_MINOR} - rm -rf `find ${COMPONENT}-${RELEASE_MAJOR}.${RELEASE_MINOR} -name CVS`; - tar -zcvf ${COMPONENT}-${RELEASE_MAJOR}.${RELEASE_MINOR}.tar.gz \ - ${COMPONENT}-${RELEASE_MAJOR}.${RELEASE_MINOR} - rm -rf ${COMPONENT}-${RELEASE_MAJOR}.${RELEASE_MINOR} -else -tarball: - echo "${COMPONENT}:: Version number not set." -endif diff --git a/README b/README new file mode 100644 index 0000000..ded30cd --- /dev/null +++ b/README @@ -0,0 +1,3 @@ +DISCONTINUED ON FEDORAHOSTED.ORG + +New home: https://pagure.io/linux-cluster/cluster diff --git a/ccs/Makefile b/ccs/Makefile deleted file mode 100644 index e3cab56..0000000 --- a/ccs/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd daemon && ${MAKE} all - cd lib && ${MAKE} all - cd ccs_test && ${MAKE} all - cd ccs_tool && ${MAKE} all - -copytobin: - cd daemon && ${MAKE} copytobin - cd lib && ${MAKE} copytobin - cd ccs_test && ${MAKE} copytobin - cd ccs_tool && ${MAKE} copytobin - -clean: - cd bin && ${MAKE} clean - cd daemon && ${MAKE} clean - cd lib && ${MAKE} clean - cd ccs_test && ${MAKE} clean - cd ccs_tool && ${MAKE} clean - rm -f *~ - -distclean: clean - rm -f make/defines.mk - -install: - cd daemon && ${MAKE} install - cd lib && ${MAKE} install - cd ccs_test && ${MAKE} install - cd ccs_tool && ${MAKE} install - cd man && ${MAKE} install - cd init.d && ${MAKE} install - -uninstall: - cd daemon && ${MAKE} uninstall - cd lib && ${MAKE} uninstall - cd ccs_test && ${MAKE} uninstall - cd ccs_tool && ${MAKE} uninstall - cd man && ${MAKE} uninstall - cd init.d && ${MAKE} uninstall diff --git a/ccs/bin/Makefile b/ccs/bin/Makefile deleted file mode 100644 index 1181df2..0000000 --- a/ccs/bin/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -all: - cd .. && ${MAKE} copytobin - -clean: - rm -f *~ *.o ccs_test ccsd - -install: - cd .. && ${MAKE} install - -uninstall: - cd .. && ${MAKE} uninstall diff --git a/ccs/ccs_test/Makefile b/ccs/ccs_test/Makefile deleted file mode 100644 index 22c9979..0000000 --- a/ccs/ccs_test/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -ccs_libdir=${top_srcdir}/lib -INCLUDE+= -I. -I${top_srcdir}/include -I${ccs_libdir} -I${top_srcdir}/config - -ifeq ($(DEBUG),y) -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DDEBUG -g \ - -DCCS_RELEASE_NAME="${RELEASE}" -else -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DCCS_RELEASE_NAME="${RELEASE}" -endif - -LDFLAGS+= -L${ccs_libdir} -LOADLIBES+= -lccs - -all: ccs_test - -copytobin: all - cp ccs_test ${top_srcdir}/bin - -ccs_test: ccs_test.c ${ccs_libdir}/libccs.a - ${CC} ${CFLAGS} ${INCLUDE} ccs_test.c ${LDFLAGS} ${LOADLIBES} ${LDLIBS}-o $@ - -${ccs_libdir}/libccs.a: - cd ${ccs_libdir} && ${MAKE} libccs.a - -install: ccs_test - install -d ${sbindir} - install ccs_test ${sbindir} - -uninstall: - ${UNINSTALL} ccs_test ${sbindir} - -clean: - rm -rf *.o ccs_test *~ diff --git a/ccs/ccs_test/ccs_test.c b/ccs/ccs_test/ccs_test.c deleted file mode 100644 index 912e703..0000000 --- a/ccs/ccs_test/ccs_test.c +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> - -#include "ccs.h" - -#include "copyright.cf" - -static void print_usage(FILE *stream); - -int main(int argc, char *argv[]){ - int desc=0; - int i=0; - int error = 0; - int force = 0, blocking = 0; - char *str=NULL, *str2=NULL; - char *cluster_name = NULL; - - if(argc <= 1){ - print_usage(stderr); - exit(EXIT_FAILURE); - } - - for(i=1; i < argc; i++){ - if(!strcmp(argv[i], "-h")){ - print_usage(stdout); - exit(EXIT_SUCCESS); - } - if(!strcmp(argv[i], "-V")){ - printf("%s %s (built %s %s)\n", argv[0], CCS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - } - } - - if(!strcmp(argv[1], "connect")){ - for(i=2; i < argc; i++){ - if(!strcmp(argv[i], "force")){ - printf("Force is set.\n"); - force = 1; - } else if(!strcmp(argv[i], "block")){ - printf("Blocking is set.\n"); - blocking = 1; - } else { - cluster_name = argv[i]; - printf("Setting cluster name to %s\n", cluster_name); - } - } - if(blocking && !force){ - fprintf(stderr, "Blocking can only be used with "force".\n"); - exit(EXIT_FAILURE); - } - if(force){ - desc = ccs_force_connect(cluster_name, blocking); - } else { - if(cluster_name){ - fprintf(stderr, "A cluster name can only be specified when using 'force'.\n"); - exit(EXIT_FAILURE); - } - desc = ccs_connect(); - } - if(desc < 0){ - fprintf(stderr, "ccs_connect failed: %s\n", strerror(-desc)); - exit(EXIT_FAILURE); - } else { - printf("Connect successful.\n"); - printf(" Connection descriptor = %d\n", desc); - } - } - else if(!strcmp(argv[1], "disconnect")){ - if(argc < 3){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - desc = atoi(argv[2]); - if((error = ccs_disconnect(desc))){ - fprintf(stderr, "ccs_disconnect failed: %s\n", strerror(-error)); - exit(EXIT_FAILURE); - } else { - printf("Disconnect successful.\n"); - } - } - else if(!strcmp(argv[1], "get")){ - if(argc < 4){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - desc = atoi(argv[2]); - if((error = ccs_get(desc, argv[3], &str))){ - fprintf(stderr, "ccs_get failed: %s\n", strerror(-error)); - exit(EXIT_FAILURE); - } else { - printf("Get successful.\n"); - printf(" Value = <%s>\n", str); - if(str)free(str); - } - } - else if(!strcmp(argv[1], "get_list")){ - if(argc < 4){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - desc = atoi(argv[2]); - if((error = ccs_get_list(desc, argv[3], &str))){ - fprintf(stderr, "ccs_get failed: %s\n", strerror(-error)); - exit(EXIT_FAILURE); - } else { - printf("Get successful.\n"); - printf(" Value = <%s>\n", str); - if(str)free(str); - } - } - else if(!strcmp(argv[1], "set")){ - if(argc < 5){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - desc = atoi(argv[2]); - if((error = ccs_set(desc, argv[3], argv[4]))){ - fprintf(stderr, "ccs_set failed: %s\n", strerror(-error)); - exit(EXIT_FAILURE); - } else { - printf("Set successful.\n"); - } - } - else if(!strcmp(argv[1], "get_state")){ - if(argc < 3){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - desc = atoi(argv[2]); - if((error = ccs_get_state(desc, &str, &str2))){ - fprintf(stderr, "ccs_get_state failed: %s\n", strerror(-error)); - exit(EXIT_FAILURE); - } else { - printf("Get state successful.\n"); - printf(" Current working path: %s\n", str); - printf(" Previous query : %s\n", str2); - if(str) free(str); - if(str2) free(str2); - } - } - else if(!strcmp(argv[1], "set_state")){ - if(argc < 4){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - desc = atoi(argv[2]); - if((error = ccs_set_state(desc, argv[3], 0))){ - fprintf(stderr, "ccs_set_state failed: %s\n", strerror(-error)); - exit(EXIT_FAILURE); - } else { - printf("Set state successful.\n"); - } - } else { - fprintf(stderr, "Unknown command: %s\n", argv[1]); - exit(EXIT_FAILURE); - } - - exit(EXIT_SUCCESS); -} - - -static void print_usage(FILE *stream){ - fprintf(stream, - "Usage:\n" - "\n" - "ccs_test [Options] <Command>\n" - "\n" - "Options:\n" - " -h Print usage.\n" - " -V Print version information.\n" - "\n" - "Commands:\n" - " connect <force> <block> Connect to CCS and return connection descriptor.\n" - " disconnect <desc> Disconnect from CCS.\n" - " get <desc> <request> Get a value from CCS.\n" - " get_list <desc> <request> Get a value from CCS.\n" - " set <desc> <path> <val> Set a value in CCS.\n" - " get_state <desc> Get the state in the connection.\n" - " set_state <desc> <ncwp> Set the current working path.\n" - ); -} diff --git a/ccs/ccs_tool/Makefile b/ccs/ccs_tool/Makefile deleted file mode 100644 index 4976b2f..0000000 --- a/ccs/ccs_tool/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2005 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl -include ${top_srcdir}/make/defines.mk - -ccs_libdir=${top_srcdir}/lib -INCLUDE= -I. -I${top_srcdir}/config -I${top_srcdir}/include -I${ccs_libdir} -I${incdir} - -ifeq ($(DEBUG),y) -CFLAGS+= -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DDEBUG -g \ - `xml2-config --cflags` -DCCS_RELEASE_NAME="${RELEASE}" -else -CFLAGS+= -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \ - `xml2-config --cflags` -DCCS_RELEASE_NAME="${RELEASE}" -endif - -LDFLAGS+= -L${ccs_libdir} `xml2-config --libs` -L${libdir} -LOADLIBES+= -lccs -lmagma -lmagmamsg -ldl - -all: ccs_tool - -ccs_tool: ccs_tool.c update.c upgrade.c old_parser.c editconf.c - ${CC} ${CFLAGS} ${INCLUDE} -o $@ $^ ${LDFLAGS} ${LOADLIBES} - -clean: - rm -f *.o ccs_tool *~ - -install: all - install -d ${sbindir} - install ccs_tool ${sbindir} - -uninstall: - ${UNINSTALL} ccs_tool ${sbindir} diff --git a/ccs/ccs_tool/ccs_tool.c b/ccs/ccs_tool/ccs_tool.c deleted file mode 100644 index dc54146..0000000 --- a/ccs/ccs_tool/ccs_tool.c +++ /dev/null @@ -1,125 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <getopt.h> -#include <string.h> - -#include "copyright.cf" -#include "update.h" -#include "upgrade.h" -#include "editconf.h" - -static void print_usage(FILE *stream); - -int main(int argc, char *argv[]) -{ - optind = 1; - - if (argc < 2 || !strcmp(argv[optind], "-h")) { - print_usage(stdout); - exit(EXIT_SUCCESS); - } - if (!strcmp(argv[optind], "-V")) { - printf("%s %s (built %s %s)\n", argv[0], CCS_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - } - - if(optind < argc){ - if(!strcmp(argv[optind], "help")){ - print_usage(stdout); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "update")){ - if(optind+1 >= argc){ - fprintf(stderr, "Too few arguments.\n" - "Try 'ccs_tool help' for help.\n"); - exit(EXIT_FAILURE); - } - if(update(argv[optind+1])){ - fprintf(stderr, "\nFailed to update config file.\n"); - exit(EXIT_FAILURE); - } - printf("\nUpdate complete.\n"); - } - else if(!strcmp(argv[optind], "upgrade")){ - if(optind+1 >= argc){ - fprintf(stderr, "Too few arguments.\n" - "Try 'ccs_tool help' for help.\n"); - exit(EXIT_FAILURE); - } - if(upgrade(argv[optind+1])){ - fprintf(stderr, "\nFailed to upgrade CCS configuration information.\n"); - exit(EXIT_FAILURE); - } - } - - else if(!strcmp(argv[optind], "addnode")){ - add_node(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "delnode")){ - del_node(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "addfence")){ - add_fence(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "delfence")){ - del_fence(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "lsnode")){ - list_nodes(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "lsfence")){ - list_fences(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "create")){ - create_skeleton(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[optind], "addnodeids")){ - add_nodeids(argc-1, argv+1); - exit(EXIT_SUCCESS); - } - - else { - fprintf(stderr, "Unknown command, %s.\n" - "Try 'ccs_tool help' for help.\n", argv[optind]); - exit(EXIT_FAILURE); - } - } else { - fprintf(stderr, "Too few arguments.\n" - "Try 'ccs_tool help' for help.\n"); - exit(EXIT_FAILURE); - } - exit(EXIT_SUCCESS); -} - -static void print_usage(FILE *stream){ - fprintf(stream, - "Usage::\n" - " ccs_tool [options] <command>\n" - "\n" - "Options:\n" - " -h Print this usage and exit.\n" - " -V Print version information and exit.\n" - "\n" - "Commands:\n" - " help Print this usage and exit.\n" - " update <xml file> Tells ccsd to upgrade to new config file.\n" - " upgrade <location> Upgrade old CCS format to new xml format.\n" - " addnode <node> Add a node\n" - " delnode <node> Delete a node\n" - " lsnode List nodes\n" - " lsfence List fence devices\n" - " addfence <fencedev> Add a new fence device\n" - " delfence <fencedev> Delete a fence device\n" - " create Create a skeleton config file\n" - " addnodeids Assign node ID numbers to all nodes\n" - "\n"); -} diff --git a/ccs/ccs_tool/editconf.c b/ccs/ccs_tool/editconf.c deleted file mode 100644 index b076a00..0000000 --- a/ccs/ccs_tool/editconf.c +++ /dev/null @@ -1,1275 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/stat.h> -#include <getopt.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> - -#include <libxml/tree.h> - -#include "update.h" - -#define MAX_NODES 256 -#define DEFAULT_CONFIG_FILE "/etc/cluster/cluster.conf" -char *prog_name = "ccs_tool"; - -#define die(fmt, args...) \ -do { \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt "\n", ##args); \ - exit(EXIT_FAILURE); \ -} while (0) - - -struct option_info -{ - char *name; - char *votes; - char *nodeid; - char *mcast_if; - char *mcast_addr; - char *fence_type; - char *configfile; - char *outputfile; - int do_delete; - int tell_ccsd; - int force_ccsd; -}; - -static void config_usage(int rw) -{ - fprintf(stderr, " -c --configfile Name of configuration file (/etc/cluster/cluster.conf)\n"); - if (rw) - { - fprintf(stderr, " -o --outputfile Name of output file (defaults to same as --configfile)\n"); - fprintf(stderr, " -C --no_ccs Don't tell CCSD about this change\n"); - fprintf(stderr, " (default: run "ccs_tool update" if file is updated in place)\n"); - fprintf(stderr, " -F --force_ccs Force "ccs_tool update" even if input & output files differ\n"); - } -} - -static void help_usage(void) -{ - fprintf(stderr, " -h --help Display this help text\n"); -} - -static void list_usage(const char *name) -{ - fprintf(stderr, "Usage: %s %s [options]\n", prog_name, name); - fprintf(stderr, " -v --verbose Print all properties of the item\n"); - config_usage(0); - help_usage(); - - exit(0); -} - -static void create_usage(const char *name) -{ - fprintf(stderr, "Usage: %s %s [-2] <clustername>\n", prog_name, name); - fprintf(stderr, " -2 Create a 2-node cman cluster config file\n"); - config_usage(0); - help_usage(); - fprintf(stderr, "\n" - "Note that "create" on its own will not create a valid configuration file.\n" - "Fence agents and nodes will need to be added to it before handing it over\n" - "to ccsd.\n" - "\n" - "eg:\n" - " ccs_tool create MyCluster\n" - " ccs_tool addfence apc fence_apc ipaddr=apc.domain.net user=apc password=apc\n" - " ccs_tool addnode node1 -v 1 -f apc port=1\n" - " ccs_tool addnode node2 -v 1 -f apc port=2\n" - " ccs_tool addnode node3 -v 1 -f apc port=3\n" - " ccs_tool addnode node4 -v 1 -f apc port=4\n" - "\n"); - - exit(0); -} - -static void addfence_usage(const char *name) -{ - fprintf(stderr, "Usage: %s %s [options] <name> <agent> [param=value]\n", prog_name, name); - config_usage(1); - help_usage(); - - exit(0); -} - -static void delfence_usage(const char *name) -{ - fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name); - config_usage(1); - help_usage(); - fprintf(stderr, "\n"); - fprintf(stderr, "%s will allow you to remove a fence device that is in use by nodes.\n", name); - fprintf(stderr, "This is to allow changes to be made, but be aware that it may produce an\n"); - fprintf(stderr, "invalid configuration file if you don't add it back in again.\n"); - - exit(0); -} - -static void delnode_usage(const char *name) -{ - fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name); - config_usage(1); - help_usage(); - - exit(0); -} - -static void addnodeid_usage(const char *name) -{ - fprintf(stderr, "Add node IDs to all nodes in the config file that don't have them.\n"); - fprintf(stderr, "Nodes with IDs will not be afftected, so you can run this as many times\n"); - fprintf(stderr, "as you like without doing any harm.\n"); - fprintf(stderr, "It will optionally add a multicast address to the cluster config too.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name); - fprintf(stderr, " -n --nodeid Nodeid to start with (default 1)\n"); - fprintf(stderr, " -m --multicast Set or change the multicast address\n"); - fprintf(stderr, " -v --verbose Print nodeids that are assigned\n"); - config_usage(1); - help_usage(); - - exit(0); -} - -static void addnode_usage(const char *name) -{ - fprintf(stderr, "Usage: %s %s [options] <nodename> [<fencearg>=<value>]...\n", prog_name, name); - fprintf(stderr, " -v --votes Number of votes for this node\n"); - fprintf(stderr, " -n --nodeid Nodeid (optional)\n"); - fprintf(stderr, " -i --interface Interface name (needed if multicast is used)\n"); - fprintf(stderr, " -m --multicast Multicast address (only needed for first node in a cman\n"); - fprintf(stderr, " multicast cluster)\n"); - fprintf(stderr, " -f --fence_type Type of fencing to use\n"); - config_usage(1); - help_usage(); - - fprintf(stderr, "\n"); - fprintf(stderr, "Examples:\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Add a new node to default configuration file:\n"); - fprintf(stderr, " %s %s -v 1 -f manual ipaddr=newnode\n", prog_name, name); - fprintf(stderr, "\n"); - fprintf(stderr, "Add a new node and dump config file to stdout rather than save it\n"); - fprintf(stderr, " %s %s -v 1 -f apc -i eth0 -o - newnode.temp.net port=1\n", prog_name, name); - - exit(0); -} - -/* Is it really ? - * Actually, we don't check that this is a valid multicast address(!), - * merely that it is a valid IP[46] address. - */ -static int valid_mcast_addr(char *mcast) -{ - struct addrinfo *ainfo; - struct addrinfo ahints; - int ret; - - memset(&ahints, 0, sizeof(ahints)); - - ret = getaddrinfo(mcast, NULL, &ahints, &ainfo); - if (ret) { - freeaddrinfo(ainfo); - return 0; - } - return 1; -} - -static void save_file(xmlDoc *doc, struct option_info *ninfo) -{ - char tmpfile[strlen(ninfo->outputfile)+5]; - char oldfile[strlen(ninfo->outputfile)+5]; - int using_stdout = 0; - mode_t old_mode; - int ret; - - old_mode = umask(026); - - if (strcmp(ninfo->outputfile, "-") == 0) - using_stdout = 1; - - /* - * Save it to a temp file before moving the old one out of the way - */ - if (!using_stdout) - { - snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", ninfo->outputfile); - snprintf(oldfile, sizeof(oldfile), "%s.old", ninfo->outputfile); - } - else - { - strcpy(tmpfile, ninfo->outputfile); - } - - xmlKeepBlanksDefault(0); - ret = xmlSaveFormatFile(tmpfile, doc, 1); - if (ret == -1) - die("Error writing new config file %s", ninfo->outputfile); - - if (!using_stdout) - { - if (rename(ninfo->outputfile, oldfile) == -1 && errno != ENOENT) - die("Can't move old config file out of the way\n"); - - if (rename(tmpfile, ninfo->outputfile)) - { - perror("Error renaming new file to its real filename"); - - /* Drat, that failed, try to put the old one back */ - if (rename(oldfile, ninfo->outputfile)) - die("Can't move old config fileback in place - clean up after me please\n"); - } - } - - /* Try to tell ccsd if needed */ - if ((strcmp(ninfo->configfile, ninfo->outputfile) == 0 && ninfo->tell_ccsd) || - ninfo->force_ccsd) - { - printf("running ccs_tool update...\n"); - update(ninfo->outputfile); - } - - /* free the document */ - xmlFreeDoc(doc); - - umask(old_mode); -} - -static void validate_int_arg(char argopt, char *arg) -{ - char *tmp; - int val; - - val = strtol(arg, &tmp, 10); - if (tmp == arg || tmp != arg + strlen(arg)) - die("argument to %c (%s) is not an integer", argopt, arg); - - if (val < 0) - die("argument to %c cannot be negative", argopt); -} - -/* Get the config_version string from the file */ -static xmlChar *find_version(xmlNode *root) -{ - if (xmlHasProp(root, BAD_CAST "config_version")) - { - xmlChar *ver; - - ver = xmlGetProp(root, BAD_CAST "config_version"); - return ver; - } - return NULL; -} - -/* Get the cluster name string from the file */ -static xmlChar *cluster_name(xmlNode *root) -{ - if (xmlHasProp(root, BAD_CAST "name")) - { - xmlChar *ver; - - ver = xmlGetProp(root, BAD_CAST "name"); - return ver; - } - return NULL; -} - -static void increment_version(xmlNode *root_element) -{ - int ver; - unsigned char *version_string; - char newver[32]; - - /* Increment version */ - version_string = find_version(root_element); - if (!version_string) - die("Can't find "config_version" in config file\n"); - - ver = atoi((char *)version_string); - snprintf(newver, sizeof(newver), "%d", ++ver); - xmlSetProp(root_element, BAD_CAST "config_version", BAD_CAST newver); -} - -static xmlNode *findnode(xmlNode *root, char *name) -{ - xmlNode *cur_node; - - for (cur_node = root->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, name)==0) - { - return cur_node; - } - } - return NULL; -} - -/* Return the fence type name (& node) for a cluster node */ -static xmlChar *get_fence_type(xmlNode *clusternode, xmlNode **fencenode) -{ - xmlNode *f; - - f = findnode(clusternode, "fence"); - if (f) - { - f = findnode(f, "method"); - if (f) - { - f = findnode(f, "device"); - *fencenode = f; - return xmlGetProp(f, BAD_CAST "name"); - } - } - return NULL; -} - -/* Check the fence type exists under <fencedevices> */ -static xmlNode *valid_fence_type(xmlNode *root, char *fencetype) -{ - xmlNode *devs; - xmlNode *cur_node; - - devs = findnode(root, "fencedevices"); - if (!devs) - return NULL; - - for (cur_node = devs->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0) - { - xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name"); - if (strcmp((char *)name, fencetype) == 0) - return cur_node; - } - } - return NULL; -} - -/* Check the nodeid is not already in use by another node */ -static xmlNode *get_by_nodeid(xmlNode *root, int nodeid) -{ - xmlNode *cnodes; - xmlNode *cur_node; - - cnodes = findnode(root, "clusternodes"); - if (!cnodes) - return NULL; - - for (cur_node = cnodes->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0) - { - xmlChar *idstring = xmlGetProp(cur_node, BAD_CAST "nodeid"); - if (idstring && atoi((char *)idstring) == nodeid) - return cur_node; - } - } - return NULL; -} - - -/* Get the multicast address (if present) from the first node. - * If one has it, they all must. - * Note that if there are no nodes in the config file then - * we return the command-line multicast address (which may also be NULL!) - */ -static xmlChar *find_multicast_addr(xmlNode *clusternodes, struct option_info *ninfo) -{ - xmlChar *mc_addr = NULL; - - xmlNode *clnode = findnode(clusternodes, "clusternode"); - if (clnode) - { - xmlNode *mcast = findnode(clnode, "multicast"); - if (mcast) - { - mc_addr = xmlGetProp(mcast, BAD_CAST "addr"); - } - } - else - mc_addr = (xmlChar *)ninfo->mcast_addr; - return mc_addr; -} - -static xmlChar *get_mcast_if(xmlNode *clusternode) -{ - xmlChar *mc_if = NULL; - - xmlNode *mcast = findnode(clusternode, "multicast"); - if (mcast) - { - mc_if = xmlGetProp(mcast, BAD_CAST "interface"); - } - return mc_if; -} - - -static xmlNode *find_node(xmlNode *clusternodes, char *nodename) -{ - xmlNode *cur_node; - - for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0) - { - xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name"); - if (strcmp((char *)name, nodename) == 0) - return cur_node; - } - } - return NULL; -} - -/* Print name=value pairs for a (n XML) node. - * "ignore" is a string to ignore if present as a property (probably already printed on the main line) - */ -static void print_properties(xmlNode *node, char *prefix, char *ignore) -{ - xmlAttr *attr; - int done_prefix = 0; - - for (attr = node->properties; attr; attr = attr->next) - { - /* Don't print "name=" */ - if (strcmp((char *)attr->name, "name") && - strcmp((char *)attr->name, ignore) ) - { - if (!done_prefix) - { - done_prefix = 1; - printf("%s", prefix); - } - printf(" %s=%s", attr->name, xmlGetProp(node, attr->name)); - } - } - if (done_prefix) - printf("\n"); -} - -/* Add name=value pairs from the commandline as properties to a node */ -static void add_fence_args(xmlNode *fencenode, int argc, char **argv, int optind) -{ - int i; - - for (i = optind; i<argc; i++) - { - char *prop; - char *value; - char *equals; - - prop = strdup(argv[i]); - equals = strchr(prop, '='); - if (!equals) - die("option '%s' is not opt=value pair\n", prop); - - value = equals+1; - *equals = '\0'; - - /* "name" is used for the fence type itself, so this is just - * to protect the user from their own stupidity - */ - if (strcmp(prop, "name") == 0) - die("Can't use "name" as a fence argument name\n"); - - xmlSetProp(fencenode, BAD_CAST prop, BAD_CAST value); - free(prop); - } -} - -static void add_clusternode(xmlNode *root_element, struct option_info *ninfo, - int argc, char **argv, int optind) -{ - xmlNode *clusternodes; - xmlNode *newnode; - xmlNode *newfence; - xmlNode *newfencemethod; - xmlNode *newfencedevice; - xmlChar *multicast_addr; - - clusternodes = findnode(root_element, "clusternodes"); - if (!clusternodes) - die("Can't find "clusternodes" in %s\n", ninfo->configfile); - - /* Don't allow duplicate node names */ - if (find_node(clusternodes, ninfo->name)) - die("node %s already exists in %s\n", ninfo->name, ninfo->configfile); - - /* Check for duplicate node ID */ - if (ninfo->nodeid && get_by_nodeid(root_element, atoi((char *)ninfo->nodeid))) - die("nodeid %s already in use\n", ninfo->nodeid); - - /* Don't allow random fence types */ - if (!valid_fence_type(root_element, ninfo->fence_type)) - die("fence type '%s' not known\n", ninfo->fence_type); - - /* - * Check for a multicast line on the first node. If it's there then - * the user must have supplied an interface on the command-line. - */ - multicast_addr = find_multicast_addr(clusternodes, ninfo); - if (multicast_addr && !ninfo->mcast_if) - die("no interface specified, but cluster.conf uses multicast\n"); - - /* We could ignore this, but I'd rather point out the user's mistake */ - if (!multicast_addr && ninfo->mcast_if) - die("interface was specified, but cluster.conf is not set up for multicast\n"); - - /* Add the new node */ - newnode = xmlNewNode(NULL, BAD_CAST "clusternode"); - xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name); - xmlSetProp(newnode, BAD_CAST "votes", BAD_CAST ninfo->votes); - if (ninfo->nodeid) - xmlSetProp(newnode, BAD_CAST "nodeid", BAD_CAST ninfo->nodeid); - xmlAddChild(clusternodes, newnode); - - if (multicast_addr) - { - xmlNode *mcastnode; - - mcastnode = xmlNewNode(NULL, BAD_CAST "multicast"); - xmlSetProp(mcastnode, BAD_CAST "addr", multicast_addr); - xmlSetProp(mcastnode, BAD_CAST "interface", BAD_CAST ninfo->mcast_if); - xmlAddChild(newnode, mcastnode); - } - - /* Add the fence attributes */ - newfence = xmlNewNode(NULL, BAD_CAST "fence"); - newfencemethod = xmlNewNode(NULL, BAD_CAST "method"); - xmlSetProp(newfencemethod, BAD_CAST "name", BAD_CAST "single"); - - newfencedevice = xmlNewNode(NULL, BAD_CAST "device"); - xmlSetProp(newfencedevice, BAD_CAST "name", BAD_CAST ninfo->fence_type); - - /* Add name=value options */ - add_fence_args(newfencedevice, argc, argv, optind+1); - - xmlAddChild(newnode, newfence); - xmlAddChild(newfence, newfencemethod); - xmlAddChild(newfencemethod, newfencedevice); -} - -static xmlDoc *open_configfile(struct option_info *ninfo) -{ - xmlDoc *doc; - - /* Init libxml */ - xmlInitParser(); - LIBXML_TEST_VERSION; - - if (!ninfo->configfile) - ninfo->configfile = DEFAULT_CONFIG_FILE; - if (!ninfo->outputfile) - ninfo->outputfile = ninfo->configfile; - - /* Load XML document */ - doc = xmlParseFile(ninfo->configfile); - if (doc == NULL) - die("Error: unable to parse cluster.conf file\n"); - - return doc; - -} - -static void del_clusternode(xmlNode *root_element, struct option_info *ninfo) -{ - xmlNode *clusternodes; - xmlNode *oldnode; - - clusternodes = findnode(root_element, "clusternodes"); - if (!clusternodes) - { - fprintf(stderr, "Can't find "clusternodes" in %s\n", ninfo->configfile); - exit(1); - } - - oldnode = find_node(clusternodes, ninfo->name); - if (!oldnode) - { - fprintf(stderr, "node %s does not exist in %s\n", ninfo->name, ninfo->configfile); - exit(1); - } - - xmlUnlinkNode(oldnode); -} - -struct option addnode_options[] = -{ - { "votes", required_argument, NULL, 'v'}, - { "nodeid", required_argument, NULL, 'n'}, - { "interface", required_argument, NULL, 'i'}, - { "multicast", required_argument, NULL, 'm'}, - { "fence_type", required_argument, NULL, 'f'}, - { "outputfile", required_argument, NULL, 'o'}, - { "configfile", required_argument, NULL, 'c'}, - { "no_ccs", no_argument, NULL, 'C'}, - { "force_ccs", no_argument, NULL, 'F'}, - { NULL, 0, NULL, 0 }, -}; - -struct option delnode_options[] = -{ - { "outputfile", required_argument, NULL, 'o'}, - { "configfile", required_argument, NULL, 'c'}, - { "no_ccs", no_argument, NULL, 'C'}, - { "force_ccs", no_argument, NULL, 'F'}, - { NULL, 0, NULL, 0 }, -}; - -struct option addfence_options[] = -{ - { "outputfile", required_argument, NULL, 'o'}, - { "configfile", required_argument, NULL, 'c'}, - { "no_ccs", no_argument, NULL, 'C'}, - { "force_ccs", no_argument, NULL, 'F'}, - { NULL, 0, NULL, 0 }, -}; - -struct option addnodeid_options[] = -{ - { "outputfile", required_argument, NULL, 'o'}, - { "configfile", required_argument, NULL, 'c'}, - { "multicast", required_argument, NULL, 'm'}, - { "nodeid", no_argument, NULL, 'n'}, - { "verbose", no_argument, NULL, 'v'}, - { NULL, 0, NULL, 0 }, -}; - -struct option list_options[] = -{ - { "configfile", required_argument, NULL, 'c'}, - { "verbose", no_argument, NULL, 'v'}, - { NULL, 0, NULL, 0 }, -}; - -static int next_nodeid(int startid, int *nodeids, int nodecount) -{ - int i; - int nextid = startid; - -retry: - for (i=0; i<nodecount; i++) - { - if (nodeids[i] == nextid) - { - nextid++; - goto retry; - } - } - - return nextid; -} - -void add_nodeids(int argc, char **argv) -{ - struct option_info ninfo; - unsigned char *nodenames[MAX_NODES]; - xmlDoc *doc; - xmlNode *root_element; - xmlNode *clusternodes; - xmlNode *cur_node; - int verbose = 0; - int opt; - int i; - int nodenumbers[MAX_NODES]; - int nodeidx; - int totalnodes; - int nextid; - - memset(nodenames, 0, sizeof(nodenames)); - memset(nodenumbers, 0, sizeof(nodenumbers)); - memset(&ninfo, 0, sizeof(ninfo)); - ninfo.nodeid = "1"; - - while ( (opt = getopt_long(argc, argv, "n:o:c:m:vh?", addnodeid_options, NULL)) != EOF) - { - switch(opt) - { - case 'n': - validate_int_arg(opt, optarg); - ninfo.nodeid = strdup(optarg); - break; - - case 'c': - ninfo.configfile = strdup(optarg); - break; - - case 'o': - ninfo.outputfile = strdup(optarg); - break; - - case 'm': - if (!valid_mcast_addr(optarg)) { - fprintf(stderr, "%s is not a valid multicast address\n", optarg); - return; - } - ninfo.mcast_addr = strdup(optarg); - break; - - case 'v': - verbose++; - break; - - case '?': - default: - addnodeid_usage(argv[0]); - } - } - - doc = open_configfile(&ninfo); - - root_element = xmlDocGetRootElement(doc); - - increment_version(root_element); - - /* Get a list of nodes that /do/ have nodeids so we don't generate - any duplicates */ - nodeidx=0; - clusternodes = findnode(root_element, "clusternodes"); - if (!clusternodes) - die("Can't find "clusternodes" in %s\n", ninfo.configfile); - - - for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0) - { - xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name"); - xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid"); - nodenames[nodeidx] = name; - if (nodeid) - nodenumbers[nodeidx] = atoi((char*)nodeid); - nodeidx++; - } - } - totalnodes = nodeidx; - - /* Loop round nodes adding nodeIDs where they don't exist. */ - nextid = next_nodeid(atoi(ninfo.nodeid), nodenumbers, totalnodes); - for (i=0; i<totalnodes; i++) - { - if (nodenumbers[i] == 0) - { - nodenumbers[i] = nextid; - nextid = next_nodeid(nextid, nodenumbers, totalnodes); - if (verbose) - fprintf(stderr, "Node %s now has id %d\n", nodenames[i], nodenumbers[i]); - } - } - - /* Now write them into the tree */ - nodeidx = 0; - for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0) - { - char tmp[80]; - xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name"); - - assert(strcmp((char*)nodenames[nodeidx], (char*)name) == 0); - - sprintf(tmp, "%d", nodenumbers[nodeidx]); - xmlSetProp(cur_node, BAD_CAST "nodeid", BAD_CAST tmp); - nodeidx++; - } - } - - - /* Write it out */ - save_file(doc, &ninfo); - - /* Shutdown libxml */ - xmlCleanupParser(); -} - -void add_node(int argc, char **argv) -{ - struct option_info ninfo; - int opt; - xmlDoc *doc; - xmlNode *root_element; - - memset(&ninfo, 0, sizeof(ninfo)); - ninfo.tell_ccsd = 1; - - while ( (opt = getopt_long(argc, argv, "v:n:i:m:f:o:c:CFh?", addnode_options, NULL)) != EOF) - { - switch(opt) - { - case 'v': - validate_int_arg(opt, optarg); - ninfo.votes = optarg; - break; - - case 'n': - validate_int_arg(opt, optarg); - ninfo.nodeid = optarg; - break; - - case 'i': - ninfo.mcast_if = strdup(optarg); - break; - - case 'm': - ninfo.mcast_addr = strdup(optarg); - break; - - case 'f': - ninfo.fence_type = strdup(optarg); - break; - - case 'c': - ninfo.configfile = strdup(optarg); - break; - - case 'o': - ninfo.outputfile = strdup(optarg); - break; - - case 'C': - ninfo.tell_ccsd = 0; - break; - - case 'F': - ninfo.force_ccsd = 1; - break; - - case '?': - default: - addnode_usage(argv[0]); - } - } - - /* Get node name parameter */ - if (optind < argc) - ninfo.name = strdup(argv[optind]); - else - addnode_usage(argv[0]); - - if (!ninfo.fence_type || !ninfo.votes) - addnode_usage(argv[0]); - - - doc = open_configfile(&ninfo); - - root_element = xmlDocGetRootElement(doc); - - increment_version(root_element); - - add_clusternode(root_element, &ninfo, argc, argv, optind); - - /* Write it out */ - save_file(doc, &ninfo); - /* Shutdown libxml */ - xmlCleanupParser(); - -} - -void del_node(int argc, char **argv) -{ - struct option_info ninfo; - int opt; - xmlDoc *doc; - xmlNode *root_element; - - memset(&ninfo, 0, sizeof(ninfo)); - ninfo.tell_ccsd = 1; - - while ( (opt = getopt_long(argc, argv, "o:c:CFh?", delnode_options, NULL)) != EOF) - { - switch(opt) - { - case 'c': - ninfo.configfile = strdup(optarg); - break; - - case 'o': - ninfo.outputfile = strdup(optarg); - break; - - case 'C': - ninfo.tell_ccsd = 0; - break; - - case 'F': - ninfo.force_ccsd = 1; - break; - - case '?': - default: - delnode_usage(argv[0]); - } - } - - /* Get node name parameter */ - if (optind < argc) - ninfo.name = strdup(argv[optind]); - else - delnode_usage(argv[0]); - - doc = open_configfile(&ninfo); - - root_element = xmlDocGetRootElement(doc); - - increment_version(root_element); - - del_clusternode(root_element, &ninfo); - - /* Write it out */ - save_file(doc, &ninfo); -} - -void list_nodes(int argc, char **argv) -{ - xmlNode *cur_node; - xmlNode *root_element; - xmlNode *clusternodes; - xmlNode *fencenode = NULL; - xmlDocPtr doc; - xmlChar *mcast; - struct option_info ninfo; - int opt; - int verbose = 0; - - memset(&ninfo, 0, sizeof(ninfo)); - - while ( (opt = getopt_long(argc, argv, "c:vh?", list_options, NULL)) != EOF) - { - switch(opt) - { - case 'c': - ninfo.configfile = strdup(optarg); - break; - case 'v': - verbose++; - break; - case '?': - default: - list_usage(argv[0]); - } - } - doc = open_configfile(&ninfo); - - root_element = xmlDocGetRootElement(doc); - - clusternodes = findnode(root_element, "clusternodes"); - if (!clusternodes) - die("Can't find "clusternodes" in %s\n", ninfo.configfile); - - printf("\nCluster name: %s, config_version: %s\n\n", - (char *)cluster_name(root_element), - (char *)find_version(root_element)); - - mcast = find_multicast_addr(clusternodes, &ninfo); - if (mcast) - printf("Multicast address for cluster: %s\n\n", mcast); - - printf("Nodename Votes Nodeid Iface Fencetype\n"); - for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0) - { - xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name"); - xmlChar *votes = xmlGetProp(cur_node, BAD_CAST "votes"); - xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid"); - xmlChar *ftype = get_fence_type(cur_node, &fencenode); - xmlChar *mc_if = get_mcast_if(cur_node); - - printf("%-32s %3d %-3s %-5s %s\n", name, votes?atoi((char *)votes):1, - nodeid?nodeid:(xmlChar *)"", - mc_if?mc_if:(xmlChar *)"", - ftype?ftype:(xmlChar *)""); - if (verbose) - { - print_properties(cur_node, " Node properties: ", "votes"); - print_properties(fencenode, " Fence properties: ", "agent"); - } - - } - } -} - -void create_skeleton(int argc, char **argv) -{ - xmlNode *root_element; - xmlNode *fencedevices; - xmlNode *clusternodes; - xmlNode *rm; - xmlNode *rm1; - xmlNode *rm2; - xmlDocPtr doc; - char *clustername; - struct option_info ninfo; - struct stat st; - int twonode = 0; - int opt; - - memset(&ninfo, 0, sizeof(ninfo)); - - while ( (opt = getopt_long(argc, argv, "c:2h?", list_options, NULL)) != EOF) - { - switch(opt) - { - case 'c': - ninfo.outputfile = strdup(optarg); - break; - - case '2': - twonode = 1; - break; - - case '?': - default: - create_usage(argv[0]); - } - } - if (!ninfo.outputfile) - ninfo.outputfile = DEFAULT_CONFIG_FILE; - ninfo.configfile = "-"; - - if (argc - optind < 1) - create_usage(argv[0]); - - clustername = argv[optind]; - - if (stat(ninfo.outputfile, &st) == 0) - die("%s already exists", ninfo.outputfile); - - /* Init libxml */ - xmlInitParser(); - LIBXML_TEST_VERSION; - - doc = xmlNewDoc(BAD_CAST "1.0"); - root_element = xmlNewNode(NULL, BAD_CAST "cluster"); - xmlDocSetRootElement(doc, root_element); - - xmlSetProp(root_element, BAD_CAST "name", BAD_CAST clustername); - xmlSetProp(root_element, BAD_CAST "config_version", BAD_CAST "1"); - - /* Generate extra bits for a 2node cman cluster */ - if (twonode) { - - xmlNode *cman = xmlNewNode(NULL, BAD_CAST "cman"); - xmlSetProp(cman, BAD_CAST "two_node", BAD_CAST "1"); - xmlSetProp(cman, BAD_CAST "expected_votes", BAD_CAST "1"); - xmlAddChild(root_element, cman); - } - - clusternodes = xmlNewNode(NULL, BAD_CAST "clusternodes"); - fencedevices = xmlNewNode(NULL, BAD_CAST "fencedevices"); - rm = xmlNewNode(NULL, BAD_CAST "rm"); - rm1 = xmlNewNode(NULL, BAD_CAST "failoverdomains"); - - xmlAddChild(root_element, clusternodes); - xmlAddChild(root_element, fencedevices); - xmlAddChild(root_element, rm); - - /* Create empty resource manager sections to keep GUI happy */ - rm2 = xmlNewNode(NULL, BAD_CAST "resources"); - xmlAddChild(rm, rm1); - xmlAddChild(rm, rm2); - - save_file(doc, &ninfo); - -} - -void add_fence(int argc, char **argv) -{ - xmlNode *root_element; - xmlNode *fencedevices; - xmlNode *fencenode = NULL; - xmlDocPtr doc; - char *fencename; - char *agentname; - struct option_info ninfo; - int opt; - - memset(&ninfo, 0, sizeof(ninfo)); - ninfo.tell_ccsd = 1; - - while ( (opt = getopt_long(argc, argv, "c:o:CFh?", list_options, NULL)) != EOF) - { - switch(opt) - { - case 'c': - ninfo.configfile = strdup(optarg); - break; - case 'o': - ninfo.outputfile = strdup(optarg); - break; - - case 'C': - ninfo.tell_ccsd = 0; - break; - - case 'F': - ninfo.force_ccsd = 1; - break; - - case '?': - default: - addfence_usage(argv[0]); - } - } - - if (argc - optind < 2) - addfence_usage(argv[0]); - - doc = open_configfile(&ninfo); - root_element = xmlDocGetRootElement(doc); - - increment_version(root_element); - - fencedevices = findnode(root_element, "fencedevices"); - if (!fencedevices) - die("Can't find "fencedevices" %s\n", ninfo.configfile); - - /* First param is the fence name - check it doesn't already exist */ - fencename = argv[optind++]; - - if (valid_fence_type(root_element, fencename)) - die("fence type %s already exists\n", fencename); - - agentname = argv[optind++]; - - /* Add it */ - fencenode = xmlNewNode(NULL, BAD_CAST "fencedevice"); - xmlSetProp(fencenode, BAD_CAST "name", BAD_CAST fencename); - xmlSetProp(fencenode, BAD_CAST "agent", BAD_CAST agentname); - - /* Add name=value options */ - add_fence_args(fencenode, argc, argv, optind); - - xmlAddChild(fencedevices, fencenode); - - save_file(doc, &ninfo); -} - -void del_fence(int argc, char **argv) -{ - xmlNode *root_element; - xmlNode *fencedevices; - xmlNode *fencenode; - xmlDocPtr doc; - char *fencename; - struct option_info ninfo; - int opt; - - memset(&ninfo, 0, sizeof(ninfo)); - ninfo.tell_ccsd = 1; - - while ( (opt = getopt_long(argc, argv, "c:o:CFhv?", list_options, NULL)) != EOF) - { - switch(opt) - { - case 'c': - ninfo.configfile = strdup(optarg); - break; - case 'o': - ninfo.outputfile = strdup(optarg); - break; - - case 'C': - ninfo.tell_ccsd = 0; - break; - - case 'F': - ninfo.force_ccsd = 1; - break; - - case '?': - default: - delfence_usage(argv[0]); - } - } - - if (argc - optind < 1) - delfence_usage(argv[0]); - - fencename = argv[optind]; - - doc = open_configfile(&ninfo); - root_element = xmlDocGetRootElement(doc); - increment_version(root_element); - - fencedevices = findnode(root_element, "fencedevices"); - if (!fencedevices) - die("Can't find "fencedevices" in %s\n", ninfo.configfile); - - fencenode = valid_fence_type(root_element, fencename); - if (!fencenode) - die("fence type %s does not exist\n", fencename); - - xmlUnlinkNode(fencenode); - - save_file(doc, &ninfo); -} - -void list_fences(int argc, char **argv) -{ - xmlNode *cur_node; - xmlNode *root_element; - xmlNode *fencedevices; - xmlDocPtr doc; - struct option_info ninfo; - int opt; - int verbose=0; - - memset(&ninfo, 0, sizeof(ninfo)); - - while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF) - { - switch(opt) - { - case 'c': - ninfo.configfile = strdup(optarg); - break; - case 'v': - verbose++; - break; - case '?': - default: - list_usage(argv[0]); - } - } - doc = open_configfile(&ninfo); - root_element = xmlDocGetRootElement(doc); - - fencedevices = findnode(root_element, "fencedevices"); - if (!fencedevices) - die("Can't find "fencedevices" in %s\n", ninfo.configfile); - - - printf("Name Agent\n"); - for (cur_node = fencedevices->children; cur_node; cur_node = cur_node->next) - { - if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0) - { - xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name"); - xmlChar *agent = xmlGetProp(cur_node, BAD_CAST "agent"); - - printf("%-16s %s\n", name, agent); - if (verbose) - print_properties(cur_node, " Properties: ", "agent"); - } - } -} - diff --git a/ccs/ccs_tool/editconf.h b/ccs/ccs_tool/editconf.h deleted file mode 100644 index 66cb574..0000000 --- a/ccs/ccs_tool/editconf.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -void add_node(int argc, char **argv); -void add_nodeids(int argc, char **argv); -void add_fence(int argc, char **argv); -void del_node(int argc, char **argv); -void del_fence(int argc, char **argv); -void list_nodes(int argc, char **argv); -void list_fences(int argc, char **argv); -void create_skeleton(int argc, char **argv); diff --git a/ccs/ccs_tool/old_parser.c b/ccs/ccs_tool/old_parser.c deleted file mode 100644 index 51d9526..0000000 --- a/ccs/ccs_tool/old_parser.c +++ /dev/null @@ -1,700 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <unistd.h> -#include <sys/types.h> -#include "old_parser.h" - -enum { - TOK_INT, - TOK_FLOAT, - TOK_STRING, - TOK_EQ, - TOK_SECTION_B, - TOK_SECTION_E, - TOK_ARRAY_B, - TOK_ARRAY_E, - TOK_IDENTIFIER, - TOK_COMMA, - TOK_EOF -}; - - -typedef struct parser { - const char *data; /* data and data limits */ - const char *db, *de; - - int t; /* token limits and type */ - const char *tb, *te; - - int line; /* line we're on */ -} parser_t; - - -static void _get_token(struct parser *p); -static void _eat_space(struct parser *p); -static ccs_node_t *_file(struct parser *p); -static ccs_node_t *_section(struct parser *p); -static ccs_value_t *_value(struct parser *p); -static ccs_value_t *_type(struct parser *p); -static int _match_aux(struct parser *p, int t); -static ccs_value_t *_create_value(void); -static ccs_node_t *_create_node(void); -static char *_dup_tok(struct parser *p); - - -#define match(t) do {\ - if (!_match_aux(p, (t))) {\ - fprintf(stderr, \ - "Parse error at line %d: unexpected token\n", p->line); \ - return 0;\ - } \ -} while(0); - - -static void free_ccs_value(ccs_value_t *cv){ - if(cv->next) - free_ccs_value(cv->next); - if(cv->type == CCS_STRING && cv->v.str) - free(cv->v.str); - free(cv); -} - -void free_ccs_node(ccs_node_t *cn){ - ccs_node_t *tmp, *sib_end; - - for(tmp = cn; tmp->sib; tmp = tmp->sib); - sib_end = tmp; - - for(tmp = cn; tmp; tmp = tmp->sib){ - if(tmp->child){ - sib_end->sib = tmp->child; - tmp->child = NULL; - while(sib_end->sib){ - sib_end = sib_end->sib; - } - } - } - - while(cn){ - tmp = cn; - cn = cn->sib; - if(tmp->v){ - free_ccs_value(tmp->v); - } - if(tmp->key){ - free(tmp->key); - } - free(tmp); - } -} - -static int isidchar(char c){ - if ( (c >= 'a' && c <= 'z') || /* [a-z] */ - (c >= 'A' && c <= 'Z') || /* [A-Z] */ - (c >= '0' && c <= '9') || /* [0-9] */ - (c == '_' ) || - (c == '$' ) || - (c == '-' ) || - (c == '.' ) ) - return 1; - else - return 0; -} - -static void _get_token(struct parser *p){ - int number_valid = 1; - - p->tb = p->te; - _eat_space(p); - if (p->tb == p->de){ - p->t = TOK_EOF; - return; - } - - p->t = TOK_INT; /* fudge so the fall through for - floats works */ - switch (*p->te) { - case '{': - p->t = TOK_SECTION_B; - p->te++; - break; - - case '}': - p->t = TOK_SECTION_E; - p->te++; - break; - - case '[': - p->t = TOK_ARRAY_B; - p->te++; - break; - - case ']': - p->t = TOK_ARRAY_E; - p->te++; - break; - - case ',': - p->t = TOK_COMMA; - p->te++; - break; - - case '=': - p->t = TOK_EQ; - p->te++; - break; - - case '"': - p->t = TOK_STRING; - p->te++; - while ((p->te != p->de) && (*p->te != '"')) { - /* $ is reserved */ - if (*p->te == '$') - { - /* set token to EOF due to parse error */ - p->t = TOK_EOF; - break; - } - - if ((*p->te == '\') && (p->te + 1 != p->de)) - p->te++; - p->te++; - } - - if (p->te != p->de) - p->te++; - break; - - case ''': - p->t = TOK_STRING; - p->te++; - while ((p->te != p->de) && (*p->te != ''')) { - p->te++; - } - - if (p->te != p->de) - p->te++; - break; - - case '.': - p->t = TOK_FLOAT; - case '-': - case '+': - number_valid = 0; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - p->te++; - while (p->te != p->de) { - if (*p->te == '.') { - if (p->t == TOK_FLOAT) - break; - p->t = TOK_FLOAT; - } else if (!isdigit((int) *p->te)){ - break; - } - number_valid = 1; - p->te++; - } - if (!number_valid){ - p->t = TOK_EOF; - } else if(!isidchar(*p->te)){ - break; - } - default: - - - /* NOTE: at this point, [-.0-9] have already been checked. This means - * that valid identifiers can begin with [$_a-zA-Z] */ - if (isidchar(*p->te)) - { - p->t = TOK_IDENTIFIER; - while ((p->te != p->de) && !isspace(*p->te) && - (isidchar(*p->te)) && (*p->te != '#') && (*p->te != '=')) - p->te++; - }else - p->t = TOK_EOF; - - break; - } -} - - -static void _eat_space(struct parser *p){ - while (p->tb != p->de) { - if (*p->te == '#') { - while ((p->te != p->de) && (*p->te != '\n')) - p->te++; - /* p->line++; - since != \n, the \n will be picked up by else if */ - } - - else if (isspace(*p->te)) { - while ((p->te != p->de) && isspace(*p->te)) { - if (*p->te == '\n') - p->line++; - p->te++; - } - } - - else - return; - - p->tb = p->te; - } -} - - -static ccs_node_t *_file(struct parser *p){ - ccs_node_t *root = NULL, *n, *l = NULL; - - while (p->t != TOK_EOF) { - if (!(n = _section(p))) { - return 0; - } - - if (!root) - root = n; - else - l->sib = n; - l = n; - } - return root; -} - - -static ccs_node_t *_section(struct parser *p){ - /* IDENTIFIER '{' VALUE* '}' */ - ccs_node_t *root, *n, *l = NULL; - - if (!(root = _create_node())) { - return 0; - } - - if (!(root->key = _dup_tok(p))) { - free_ccs_node(root); - return 0; - } - - match(TOK_IDENTIFIER); - - if (p->t == TOK_SECTION_B) { - match(TOK_SECTION_B); - while (p->t != TOK_SECTION_E) { - if (!(n = _section(p))) { - free_ccs_node(root); - return 0; - } - - if (!root->child) - root->child = n; - else - l->sib = n; - l = n; - } - match(TOK_SECTION_E); - } else { - match(TOK_EQ); - if (!(root->v = _value(p))) { - free_ccs_node(root); - return 0; - } - } - - return root; -} - - -static ccs_value_t *_value(struct parser *p){ - /* '[' TYPE* ']' | TYPE */ - ccs_value_t *h = 0, *l, *ll = 0; - if (p->t == TOK_ARRAY_B) { - match(TOK_ARRAY_B); - while (p->t != TOK_ARRAY_E) { - if (!(l = _type(p))) { - return 0; - } - - if (!h) - h = l; - else - ll->next = l; - ll = l; - - if (p->t == TOK_COMMA) - match(TOK_COMMA); - } - match(TOK_ARRAY_E); - } else - h = _type(p); - - return h; -} - - -static ccs_value_t *_type(struct parser *p){ - /* [0-9]+ | [0-9]*.[0-9]* | ".*" */ - ccs_value_t *v; - - if(!(v = _create_value())){ - return NULL; - } - - switch (p->t) { - case TOK_INT: - v->type = CCS_INT; - v->v.i = strtol(p->tb, 0, 0); /* FIXME: check error */ - match(TOK_INT); - break; - -#ifndef __KERNEL__ - case TOK_FLOAT: - v->type = CCS_FLOAT; - v->v.r = strtod(p->tb, 0); /* FIXME: check error */ - match(TOK_FLOAT); - break; -#endif - - case TOK_STRING: - v->type = CCS_STRING; - - p->tb++, p->te--; /* strip double-quotes */ - if (!(v->v.str = _dup_tok(p))) { - free_ccs_value(v); - return NULL; - } else { - char *tmp; - /* strip 's */ - while((tmp = strstr(v->v.str, "\"))){ - strcpy(tmp, tmp+1); - } - } - p->te++; - match(TOK_STRING); - break; - - default: - fprintf(stderr, "Error on line %d\n", p->line); - free_ccs_value(v); - return NULL; - } - return v; -} - - -static int _match_aux(struct parser *p, int t){ - if (p->t != t){ - return 0; - } - _get_token(p); - - return 1; -} - - -static ccs_value_t *_create_value(void){ - ccs_value_t *v = (ccs_value_t *)malloc(sizeof(ccs_value_t)); - if(v){ - memset(v, 0, sizeof(ccs_value_t)); - return v; - } - return NULL; -} - - -static ccs_node_t *_create_node(void){ - ccs_node_t *n = (ccs_node_t *)malloc(sizeof(ccs_node_t)); - if(n){ - memset(n, 0, sizeof(ccs_node_t)); - return n; - } - return NULL; -} - - -static char *_dup_tok(struct parser *p){ - int len = p->te - p->tb; - char *str = (char *)malloc(len + 1); - if (!str) { - return NULL; - } - strncpy(str, p->tb, len); - str[len] = '\0'; - return str; -} - - -static int get_ccs_file(int fd, char **file_data, char *filename){ - int error = 0; - int size; - char *data=NULL; - char *beginning, *end; - char search_str[128]; - - if((size = lseek(fd, 0, SEEK_END)) < 0){ - fprintf(stderr, "Unable to seek to end of archive: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - - if(lseek(fd, 0, SEEK_SET) < 0){ - fprintf(stderr, "Bad lseek on archive: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - - size++; - data = malloc(size); - memset(data, 0, size); - size--; - - if(read(fd, data, size) != size){ - fprintf(stderr, "Unable to read entire archive.\n"); - error = -EIO; - goto fail; - } - - sprintf(search_str, "#nigeb=%s mtime=", filename); - beginning = strstr(data, search_str); - if(!beginning){ - fprintf(stderr, "Unable to find %s in the archive.\n", filename); - error = -ENOENT; - goto fail; - } - beginning = strstr(beginning, "\n"); - if(!beginning){ - fprintf(stderr, "Unable to find %s in the archive.\n", filename); - error = -ENOENT; - goto fail; - } - beginning++; /* skip newline */ - - sprintf(search_str, "#dne=%s", filename); - end = strstr(beginning, search_str); - if(!end){ - fprintf(stderr, "Unable to find the end of %s in the archive.\n", filename); - error = -ENOENT; - goto fail; - } - - size = end - beginning; - - *file_data = malloc(size+1); - if(!file_data){ - fprintf(stderr, "Unable to allocate memory for CCS file.\n"); - error = -ENOMEM; - goto fail; - } - memset(*file_data, 0, size+1); - - memcpy(*file_data, beginning, size); - - fail: - if(data) free(data); - return error; -} - - -static int parse_filedata(ccs_node_t **cn, char *filedata){ - int error=0; - parser_t p; - - memset(&p, 0, sizeof(p)); - if(!filedata){ - error = -ENODATA; - goto fail; - } - p.db = p.data = filedata; - p.line =1; - p.de = (char *)(filedata + strlen(filedata)); - - p.tb = p.te = p.db; - _get_token(&p); - if(!(*cn = _file(&p))){ - error = -EPARSE; - } - - fail: - return error; -} - - -/* - * parse_ccs_file - * @cf: - * - * Returns: 0 on success, -EXXX on error - */ -int parse_ccs_file(int fd, ccs_node_t **cn, char *filename){ - int error; - char *file_data = NULL; - - error = get_ccs_file(fd, &file_data, filename); - if(error < 0){ - goto fail; - } - /* This is where the magic happens */ - error = parse_filedata(cn, file_data); - - fail: - if(file_data) free(file_data); - return error; -} - - -static int _tok_match(const char *str, const char *b, const char *e) -{ - while (*str && (b != e)) { - if (*str++ != *b++) - return 0; - } - - return !(*str || (b != e)); -} - - -ccs_node_t *find_ccs_node(ccs_node_t *cn, - const char *path, - char sep){ - const char *e; - while (cn) { - /* trim any leading slashes */ - while (*path && (*path == sep)) - path++; - - /* find the end of this segment */ - for (e = path; *e && (*e != sep); e++) ; - - /* hunt for the node */ - while (cn) { - if (_tok_match(cn->key, path, e)) - break; - - cn = cn->sib; - } - - if (cn && *e) - cn = cn->child; - else - break; /* don't move into the last node */ - - path = e; - } - - return cn; -} - - -const char *find_ccs_str(ccs_node_t *cn, - const char *path, - char sep, - const char *fail){ - ccs_node_t *n = find_ccs_node(cn, path, sep); - - if (n && n->v && n->v->type == CCS_STRING) { - return n->v->v.str; - } - - return fail; -} - - -int find_ccs_int(ccs_node_t *cn, - const char *path, - char sep, - int fail){ - ccs_node_t *n = find_ccs_node(cn, path, sep); - - if (n && n->v && n->v->type == CCS_INT) { - return n->v->v.i; - } - - return fail; -} - -#ifndef __KERNEL__ -float find_ccs_float(ccs_node_t *cn, - const char *path, - char sep, - float fail){ - ccs_node_t *n = find_ccs_node(cn, path, sep); - - if (n && n->v && n->v->type == CCS_FLOAT) { - return n->v->v.r; - } - - return fail; -} -#endif - -static int _str_in_array(const char *str, const char *values[]){ - int i; - - for (i = 0; values[i]; i++){ - if (!strcasecmp(str, values[i])) - return 1; - } - return 0; -} - - -static int _str_to_bool(const char *str, int fail){ - static const char *_true_values[] = { "y", "yes", "on", "true", NULL }; - static const char *_false_values[] = { "n", "no", "off", "false", NULL }; - - if (_str_in_array(str, _true_values)) - return 1; - - if (_str_in_array(str, _false_values)) - return 0; - - return fail; -} - -int find_ccs_bool(ccs_node_t *cn, - const char *path, - char sep, - int fail){ - ccs_node_t *n = find_ccs_node(cn, path, sep); - ccs_value_t *v; - - if (!n) - return fail; - - v = n->v; - - if(!v) - return fail; - - switch (v->type) { - case CCS_INT: - return v->v.i ? 1 : 0; - - case CCS_STRING: - return _str_to_bool(v->v.str, fail); - } - - return fail; -} diff --git a/ccs/ccs_tool/old_parser.h b/ccs/ccs_tool/old_parser.h deleted file mode 100644 index 275dcd7..0000000 --- a/ccs/ccs_tool/old_parser.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __OLD_PARSER_H__ -#define __OLD_PARSER_H__ - -/* A special error number for CCS. This error indicates that there was ** -** an error while parsing data. This number should not collide with ** -** other Linux error numbers, however, if someone has a better errno in ** -** mind, please let me know............................................ */ -#define EPARSE 2050 - -enum { - CCS_STRING, - CCS_FLOAT, - CCS_INT, -}; - - -typedef struct ccs_value { - int type; - union { - int i; - float r; - char *str; - } v; - struct ccs_value *next; /* for arrays */ -} ccs_value_t; - -typedef struct ccs_node_s{ - char *key; - struct ccs_node_s *sib, *child; - struct ccs_value *v; -} ccs_node_t; - - -void free_ccs_node(ccs_node_t *cn); - -int parse_ccs_file(int fd, ccs_node_t **cn, char *filename); - -ccs_node_t *find_ccs_node(ccs_node_t *cn, - const char *path, - char seperator); - -const char *find_ccs_str(ccs_node_t *cn, - const char *path, - char sep, - const char *fail); - -int find_ccs_int(ccs_node_t *cn, - const char *path, - char sep, - int fail); - -#ifndef __KERNEL__ -float find_ccs_float(ccs_node_t *cn, - const char *path, - char sep, - float fail); -#endif - -int find_ccs_bool(ccs_node_t *cn, - const char *path, - char sep, - int fail); - -#endif /* __OLD_PARSER_H__ */ diff --git a/ccs/ccs_tool/update.c b/ccs/ccs_tool/update.c deleted file mode 100644 index bfc059e..0000000 --- a/ccs/ccs_tool/update.c +++ /dev/null @@ -1,308 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <ctype.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -#include "comm_headers.h" - -#include "ccs.h" -#include "magma.h" -#include "magmamsg.h" - -int cluster_base_port = 50008; - -static int get_doc_version(xmlDocPtr ldoc){ - int i; - int error = 0; - xmlXPathObjectPtr obj = NULL; - xmlXPathContextPtr ctx = NULL; - xmlNodePtr node = NULL; - - ctx = xmlXPathNewContext(ldoc); - if(!ctx){ - fprintf(stderr, "Unable to create new XPath context.\n"); - error = -EIO; /* ATTENTION -- what should this be? */ - goto fail; - } - - obj = xmlXPathEvalExpression("//cluster/@config_version", ctx); - if(!obj || !obj->nodesetval || (obj->nodesetval->nodeNr != 1)){ - fprintf(stderr, "Error while retrieving config_version.\n"); - error = -ENODATA; - goto fail; - } - - node = obj->nodesetval->nodeTab[0]; - if(node->type != XML_ATTRIBUTE_NODE){ - fprintf(stderr, "Object returned is not of attribute type.\n"); - error = -ENODATA; - goto fail; - } - - if(!node->children->content || !strlen(node->children->content)){ - error = -ENODATA; - goto fail; - } - - for(i=0; i < strlen(node->children->content); i++){ - if(!isdigit(node->children->content[i])){ - fprintf(stderr, "config_version is not a valid integer.\n"); - error = -EINVAL; - goto fail; - } - } - error = atoi(node->children->content); - - fail: - if(ctx){ - xmlXPathFreeContext(ctx); - } - if(obj){ - xmlXPathFreeObject(obj); - } - return error; -} - -int update(char *location){ - uint64_t nid; - int error = 0; - int i, fd; - int cluster_fd = -1; - char true_location[256]; - xmlDocPtr doc = NULL; - char *mem_doc = NULL; - int doc_size = 0; - char *buffer = NULL; - comm_header_t *ch = NULL, rch; - cluster_member_list_t *membership = NULL; - int desc; - char *v1_str,*v3_str; - int v1, v2, v3; - - if(location[0] != '/'){ - memset(true_location, 0, 256); - if(!getcwd(true_location, 256)){ - fprintf(stderr, "Unable to get the current working directory.\n"); - return -errno; - } - true_location[strlen(true_location)] = '/'; - strncpy(true_location+strlen(true_location), location, 256-strlen(true_location)); - } else { - strncpy(true_location, location, 256); - } - - desc = ccs_connect(); - if(desc < 0){ - fprintf(stderr, "Unable to connect to the CCS daemon: %s\n", strerror(-desc)); - return desc; - } - - if((error = ccs_get(desc, "//@config_version", &v1_str))){ - fprintf(stderr, "Unable to get current config_version: %s\n", strerror(-error)); - ccs_disconnect(desc); - return error; - } - ccs_disconnect(desc); - - for(i=0; i < strlen(v1_str); i++){ - if(!isdigit(v1_str[i])){ - fprintf(stderr, "config_version is not a valid integer.\n"); - free(v1_str); - return -EINVAL; - } - } - v1 = atoi(v1_str); - free(v1_str); - - doc = xmlParseFile(true_location); - if(!doc){ - fprintf(stderr, "Unable to parse %s\n", true_location); - return -EINVAL; - } - v2 = get_doc_version(doc); - if(v2 < 0){ - fprintf(stderr, "Unable to get the config_version from %s\n", - location); - xmlFreeDoc(doc); - return -EINVAL; - } - if(v2 <= v1){ - fprintf(stderr, - "Proposed updated config file does not have greater version number.\n" - " Current config_version :: %d\n" - " Proposed config_version:: %d\n", v1, v2); - xmlFreeDoc(doc); - return -EINVAL; - } - - xmlDocDumpFormatMemory(doc, (xmlChar **)&mem_doc, &doc_size, 0); - if(!mem_doc){ - fprintf(stderr, "Unable to allocate memory for update document.\n"); - xmlFreeDoc(doc); - return -ENOMEM; - } - xmlFreeDoc(doc); - - buffer = malloc(doc_size + sizeof(comm_header_t)); - if(!buffer){ - fprintf(stderr, "Unable to allocate memory for transfer buffer.\n"); - free(mem_doc); - return -ENOMEM; - } - memset(buffer, 0, (doc_size + sizeof(comm_header_t))); - ch = (comm_header_t *)buffer; - memcpy(buffer+sizeof(comm_header_t), mem_doc, doc_size); - free(mem_doc); - - ch->comm_type = COMM_UPDATE; - ch->comm_flags= COMM_UPDATE_NOTICE; - ch->comm_payload_size = doc_size; - - cluster_fd = clu_connect(NULL, 0); - if(cluster_fd < 0){ - fprintf(stderr, "Unable to connect to cluster infrastructure.\n"); - if((errno == ENOENT) || (errno == ELIBACC)){ - fprintf(stderr, "Hint: The magma plugins can not be found.\n"); - } - - return cluster_fd; - } - - if(!(clu_quorum_status(NULL) & QF_QUORATE)){ - fprintf(stderr, "Unable to honor update request. Cluster is not quorate.\n"); - return -EPERM; - } - - membership = clu_member_list(NULL); - msg_update(membership); - clu_local_nodeid(NULL, &nid); - msg_set_nodeid(nid); - memb_resolve_list(membership, NULL); - - - swab_header(ch); - - for(i=0; i < membership->cml_count; i++){ - fd = msg_open(membership->cml_members[i].cm_id, cluster_base_port, 0, 5); - - if(fd < 0){ - fprintf(stderr, "Unable to open connection to %s: %s\n", - membership->cml_members[i].cm_name, strerror(errno)); - free(buffer); - cml_free(membership); - return -errno; - } - - error = msg_send(fd, buffer, sizeof(comm_header_t) + doc_size); - if(error < 0){ - fprintf(stderr, "Unable to send msg to %s: %s\n", - membership->cml_members[i].cm_name, strerror(errno)); - msg_close(fd); - free(buffer); - cml_free(membership); - return -errno; - } - - error = msg_receive_timeout(fd, &rch, sizeof(comm_header_t), 5); - swab_header(&rch); - if(error < 0){ - fprintf(stderr, "Failed to receive COMM_UPDATE_NOTICE_ACK from %s.\n", - membership->cml_members[i].cm_name); - fprintf(stderr, "Hint: Check the log on %s for reason.\n", - membership->cml_members[i].cm_name); - msg_close(fd); - free(buffer); - cml_free(membership); - return -errno; - } - msg_close(fd); - } - - swab_header(ch); - - ch->comm_flags = COMM_UPDATE_COMMIT; - - swab_header(ch); - - for(i=0; i < membership->cml_count; i++){ - fd = msg_open(membership->cml_members[i].cm_id, cluster_base_port, 0, 5); - if(fd < 0){ - fprintf(stderr, "Unable to open connection to %s: %s\n", - membership->cml_members[i].cm_name, strerror(errno)); - free(buffer); - cml_free(membership); - return -errno; - } - error = msg_send(fd, buffer, sizeof(comm_header_t)); - if(error < 0){ - fprintf(stderr, "Unable to send msg to %s: %s\n", - membership->cml_members[i].cm_name, strerror(errno)); - msg_close(fd); - free(buffer); - cml_free(membership); - return -errno; - } - error = msg_receive_timeout(fd, &rch, sizeof(comm_header_t), 5); - swab_header(&rch); - if(error < 0){ - fprintf(stderr, "Failed to receive COMM_UPDATE_COMMIT_ACK from %s.\n", - membership->cml_members[i].cm_name); - fprintf(stderr, "Hint: Check the log on %s for reason.\n", - membership->cml_members[i].cm_name); - msg_close(fd); - free(buffer); - cml_free(membership); - return -errno; - } - msg_close(fd); - error = 0; - } - - free(buffer); - cml_free(membership); - - /* If we can't connect here, it doesn't mean the update failed ** - ** It means that we simply can't report the change in version */ - desc = ccs_connect(); - if(desc < 0){ - fprintf(stderr, "Unable to connect to the CCS daemon: %s\n", strerror(-desc)); - return 0; - } - - if((error = ccs_get(desc, "//@config_version", &v3_str))){ - ccs_disconnect(desc); - return 0; - } - v3 = atoi(v3_str); - free(v3_str); - ccs_disconnect(desc); - - if(v2 == v3){ - printf("Config file updated from version %d to %d\n", v1, v2); - } else { - fprintf(stderr, "Warning:: Simultaneous update requests detected.\n" - " You have lost the race.\n" - " Old config version :: %d\n" - " Proposed config version :: %d\n" - " Winning config version :: %d\n\n" - "Check /etc/cluster/cluster.conf to ensure it contains the desired contents.\n", v1, v2, v3); - return -EAGAIN; - } - return 0; -} diff --git a/ccs/ccs_tool/update.h b/ccs/ccs_tool/update.h deleted file mode 100644 index 19fd7cb..0000000 --- a/ccs/ccs_tool/update.h +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UPDATE_DOT_H__ -#define __UPDATE_DOT_H__ - -int update(char *location); - -#endif /* __UPDATE_DOT_H__ */ diff --git a/ccs/ccs_tool/upgrade.c b/ccs/ccs_tool/upgrade.c deleted file mode 100644 index ac90735..0000000 --- a/ccs/ccs_tool/upgrade.c +++ /dev/null @@ -1,269 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> - -#include <endian.h> -#include <byteswap.h> - -#include "old_parser.h" - -#define DEFAULT_BBS 16384 /* default basic block size */ - - -static int upgrade_file_archive(char *location); -static int upgrade_device_archive(char *location); - -int upgrade(char *location){ - struct stat stat_buf; - - if(stat(location, &stat_buf)){ - fprintf(stderr, "Unable to stat %s: %s\n", location, strerror(errno)); - return -errno; - } - - if(S_ISBLK(stat_buf.st_mode)){ - return upgrade_device_archive(location); - } else { - return upgrade_file_archive(location); - } -} - -static int _upgrade_file_archive(int fd){ - int error = 0; - ccs_node_t *cluster_cn = NULL; - ccs_node_t *fence_cn = NULL; - ccs_node_t *nodes_cn = NULL; - ccs_node_t *tmp_cn; - - if((error = parse_ccs_file(fd, &cluster_cn, "cluster.ccs"))){ - return error; - } - - if((error = parse_ccs_file(fd, &nodes_cn, "nodes.ccs"))){ - return error; - } - - if((error = parse_ccs_file(fd, &fence_cn, "fence.ccs"))){ - return error; - } - - tmp_cn = find_ccs_node(cluster_cn, "cluster/name", '/'); - if(!tmp_cn || !tmp_cn->v){ - fprintf(stderr, "Unable to find cluster name.\n"); - error = -EINVAL; - goto fail; - } - - printf("<cluster name="%s" config_version="1">\n", tmp_cn->v->v.str); - - /* No cman on upgrade - printf("\n<cman>\n"); - printf("</cman>\n"); - */ - - tmp_cn = find_ccs_node(cluster_cn, "cluster/lock_gulm/servers", '/'); - printf("\n<gulm>\n"); - if(tmp_cn && tmp_cn->v){ - ccs_value_t *server; - for(server = tmp_cn->v; server; server = server->next) - printf(" <lockserver name="%s"/>\n", server->v.str); - } - printf("</gulm>\n"); - - printf("\n<clusternodes>\n"); - - for(tmp_cn = nodes_cn->child; tmp_cn; tmp_cn = tmp_cn->sib){ - ccs_node_t *fence, *method, *device, *params; - - printf("\n <clusternode name="%s" votes="1">\n", tmp_cn->key); - for(fence = tmp_cn->child; fence; fence = fence->sib){ - if(!strcmp(fence->key, "fence")){ - printf(" <fence>\n"); - for(method = fence->child; method; method = method->sib){ - printf(" <method name="%s">\n", method->key); - for(device = method->child; device; device=device->sib){ - printf(" <device name="%s"", device->key); - for(params = device->child; params; params = params->sib){ - if (params->v->type == CCS_STRING) - printf(" %s="%s"", params->key, params->v->v.str); - else if (params->v->type == CCS_INT) - printf(" %s="%d"", params->key, params->v->v.i); - else if (params->v->type == CCS_FLOAT) - printf(" %s=[DECIMAL NOT CONVERTED]", params->key); - else - printf(" %s=[BAD TYPE CONVERSION]", params->key); - } - printf("/>\n"); - } - printf(" </method>\n"); - } - printf(" </fence>\n"); - } - } - printf(" </clusternode>\n"); - } - - printf("\n</clusternodes>\n"); - - printf("\n<fencedevices>\n"); - for(tmp_cn = fence_cn->child; tmp_cn; tmp_cn = tmp_cn->sib){ - ccs_node_t *params; - - printf(" <fencedevice name="%s"", tmp_cn->key); - for(params = tmp_cn->child; params; params = params->sib){ - printf(" %s="%s"", params->key, params->v->v.str); - } - printf("/>\n"); - } - - printf("\n</fencedevices>\n"); - - printf("</cluster>\n"); - - fail: - if(cluster_cn) free_ccs_node(cluster_cn); - if(fence_cn) free_ccs_node(fence_cn); - if(nodes_cn) free_ccs_node(nodes_cn); - return error; -} - -static int upgrade_file_archive(char *location){ - int error = 0; - int fd=-1; - - if((fd = open(location, O_RDONLY)) < 0){ - fprintf(stderr, "Unable to open %s: %s\n", location, strerror(errno)); - error = -errno; - goto fail; - } - - error = _upgrade_file_archive(fd); - - fail: - if(fd >= 0) close(fd); - return error; -} - - -#define CCS_DH_MAGIC 0x122473 - -/* CCS Device Header */ -typedef struct ccs_dh_s { - u_int32_t dh_magic; - u_int32_t dh_format; - u_int32_t dh_generation; - u_int32_t dh_active; - u_int32_t dh_size; /* Size of archive on disk */ - u_int32_t dh_maxsize; - char dh_reserved[64]; -} ccs_dh_t; - -static void ccs_dh_in(ccs_dh_t *dh, char *buf){ - ccs_dh_t *tmp = (ccs_dh_t *)buf; - -#if __BYTE_ORDER == __BIG_ENDIAN - dh->dh_magic = tmp->dh_magic; - dh->dh_active = tmp->dh_active; - dh->dh_size = tmp->dh_size; - dh->dh_maxsize = tmp->dh_maxsize; -#else - dh->dh_magic = bswap_32(tmp->dh_magic); - dh->dh_active = bswap_32(tmp->dh_active); - dh->dh_size = bswap_32(tmp->dh_size); - dh->dh_maxsize = bswap_32(tmp->dh_maxsize); -#endif -} - -static int upgrade_device_archive(char *location){ - int error = 0; - int dev_fd=-1, tmp_fd=-1; - char tmp_file[128]; - char *buffer = NULL; - ccs_dh_t dev_header; - - if(posix_memalign((void **)&buffer, DEFAULT_BBS, DEFAULT_BBS)){ - fprintf(stderr, "Unable to allocate aligned memory.\n"); - return -ENOMEM; - } - - if((dev_fd = open(location, O_RDONLY | O_DIRECT)) < 0){ - fprintf(stderr, "Unable to open %s: %s\n", location, strerror(errno)); - error = -errno; - goto fail; - } - - if(read(dev_fd, buffer, DEFAULT_BBS) < DEFAULT_BBS){ - fprintf(stderr, "Unable to read %s: %s\n", location, strerror(errno)); - error = -errno; - goto fail; - } - - ccs_dh_in(&dev_header, buffer); - if(dev_header.dh_magic == CCS_DH_MAGIC){ - if(!dev_header.dh_active){ - if(lseek(dev_fd, dev_header.dh_maxsize, SEEK_SET)< 0){ - fprintf(stderr, "Unable to lseek in %s: %s\n", location, strerror(errno)); - error = -errno; - goto fail; - } - } - } else { - fprintf(stderr, "The specified device does not contain a CCS archive.\n"); - error = -EINVAL; - goto fail; - } - - memset(tmp_file, 0, 128); - sprintf(tmp_file, "/tmp/ccs_tool_tmp_XXXXXX"); - - tmp_fd = mkstemp(tmp_file); - if(tmp_fd < 0){ - fprintf(stderr, "Unable to create temporary archive: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - unlink(tmp_file); - - while(dev_header.dh_size){ - int write_size; - if(read(dev_fd, buffer, DEFAULT_BBS) < DEFAULT_BBS){ - fprintf(stderr, "Bad read on %s: %s.\n", location, strerror(errno)); - error = -errno; - goto fail; - } - write_size = (dev_header.dh_size < DEFAULT_BBS) ? - dev_header.dh_size : DEFAULT_BBS; - if(write(tmp_fd, buffer, write_size) < write_size){ - fprintf(stderr, "Unable to write to temporary archive: %s.\n", strerror(errno)); - error = -errno; - goto fail; - } - dev_header.dh_size -= write_size; - } - lseek(tmp_fd, 0, SEEK_SET); - - error = _upgrade_file_archive(tmp_fd); - - fail: - if(buffer) free(buffer); - if(dev_fd >= 0) close(dev_fd); - if(tmp_fd >= 0) close(tmp_fd); - return error; -} - diff --git a/ccs/ccs_tool/upgrade.h b/ccs/ccs_tool/upgrade.h deleted file mode 100644 index 6b3253a..0000000 --- a/ccs/ccs_tool/upgrade.h +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UPGRADE_DOT_H__ -#define __UPGRADE_DOT_H__ - -int upgrade(char *location); - -#endif /* __UPGRADE_DOT_H__ */ diff --git a/ccs/common/log.c b/ccs/common/log.c deleted file mode 100644 index a9c70f1..0000000 --- a/ccs/common/log.c +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <syslog.h> - -int log_is_open = 0; - -void log_open(const char *ident, int option, int facility){ - openlog(ident, option, facility); - log_is_open = 1; -} - -void log_close(void){ - log_is_open = 0; -} diff --git a/ccs/common/log.h b/ccs/common/log.h deleted file mode 100644 index 113319a..0000000 --- a/ccs/common/log.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __LOG_H__ -#define __LOG_H__ - -#include <syslog.h> - -extern int log_is_open; - -void log_open(const char *ident, int option, int facility); -void log_close(void); - -/* Note, messages will always be sent to syslog, but userland programs ** -** will have to close stdout, stderr if they don't want messages ** -** printed to the controling terminal (as all good daemon's should). */ - -#ifdef DEBUG -#define log_dbg(fmt, args...) { \ - if(log_is_open){ \ - syslog(LOG_DEBUG, "[%s:%d] " fmt , __FILE__ , __LINE__ , ## args ); \ - }else { \ - fprintf(stdout, "[%s:%d] " fmt , __FILE__ , __LINE__ , ## args ); \ - } \ -} -#else -#define log_dbg(fmt, args...) -#endif - -#define log_msg(fmt, args...) {\ - if(log_is_open){ \ - syslog(LOG_NOTICE, fmt, ## args); \ - }else { \ - fprintf(stdout, fmt , ## args ); \ - } \ -} - -#ifdef DEBUG -#define log_err(fmt, args...){ \ - if(log_is_open){ \ - syslog(LOG_ERR, "[%s:%d] " fmt , __FILE__ , __LINE__ , ## args ); \ - }else { \ - fprintf(stderr, "[%s:%d] ", __FILE__ , __LINE__); \ - fprintf(stderr, fmt, ## args ); \ - } \ -} -#else -#define log_err(fmt, args...){ \ - if(log_is_open){ \ - syslog(LOG_ERR, fmt, ## args ); \ - }else { \ - fprintf(stderr, fmt, ## args ); \ - } \ -} -#endif - - -#ifdef DEBUG -#define log_sys_err(fmt, args...){ \ - if(log_is_open){ \ - syslog(LOG_ERR, "[%s:%d] " fmt ": %m\n" , __FILE__ , __LINE__ , ## args ); \ - }else { \ - fprintf(stderr, "[%s:%d] ", __FILE__ , __LINE__); \ - fprintf(stderr, fmt ": " , ## args ); \ - perror(NULL); \ - } \ -} -#else -#define log_sys_err(fmt, args...){ \ - if(log_is_open){ \ - syslog(LOG_ERR, fmt ": %m\n" , ## args ); \ - }else { \ - fprintf(stderr, fmt ": " , ## args ); \ - perror(NULL); \ - } \ -} -#endif - -#define die(ext, fmt, args...) { \ - if(log_is_open){ \ - syslog(LOG_ERR, "In %s, at %d (%s) death by:\n" fmt , __FILE__ , \ - __LINE__ , CCS_RELEASE_NAME , ## args ); exit(ext); \ - }else { \ - fprintf(stderr, "In %s, at %d (%s) death by:\n" fmt , __FILE__ , \ - __LINE__ , CCS_RELEASE_NAME , ## args ); exit(ext); \ - } \ -} - - -#endif /* __LOG_H__ */ diff --git a/ccs/config/copyright.cf b/ccs/config/copyright.cf deleted file mode 100644 index 8847c05..0000000 --- a/ccs/config/copyright.cf +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) Red Hat, Inc. 2004 All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __COPYRIGHT_DOT_CF__ -#define __COPYRIGHT_DOT_CF__ - -#define REDHAT_COPYRIGHT ("Copyright (C) Red Hat, Inc. 2004 All rights reserved.") - -#endif /* __COPYRIGHT_DOT_CF__ */ - - - diff --git a/ccs/configure b/ccs/configure deleted file mode 100755 index dd4d532..0000000 --- a/ccs/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/ccs/daemon/Makefile b/ccs/daemon/Makefile deleted file mode 100644 index 75057e1..0000000 --- a/ccs/daemon/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -INCLUDE= -I. -I../include -I../common -I${top_srcdir}/config -I${incdir} - -ifeq ($(DEBUG),y) -CFLAGS+= -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DDEBUG -g \ - `xml2-config --cflags` -DCCS_RELEASE_NAME="${RELEASE}" -else -CFLAGS+= -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \ - `xml2-config --cflags` -DCCS_RELEASE_NAME="${RELEASE}" -endif - -LDFLAGS+= -L${libdir} `xml2-config --libs` -lpthread -lmagma -lmagmamsg -ldl - -all: ccsd - -copytobin: all - cp ccsd ${top_srcdir}/bin - -ccsd: ccsd.c cnx_mgr.c cluster_mgr.c misc.c ../common/log.c globals.c - ${CC} ${CFLAGS} ${INCLUDE} -o $@ $^ ${LDFLAGS} - -install: ccsd - install -d ${sbindir} - install ccsd ${sbindir} - -uninstall: - ${UNINSTALL} ccsd ${sbindir} - -clean: - rm -rf *.o ccsd *~ diff --git a/ccs/daemon/ccsd.c b/ccs/daemon/ccsd.c deleted file mode 100644 index 9dbd05c..0000000 --- a/ccs/daemon/ccsd.c +++ /dev/null @@ -1,909 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <libxml/parser.h> - -#include "log.h" -#include "debug.h" -#include "cnx_mgr.h" -#include "cluster_mgr.h" -#include "globals.h" -#include "comm_headers.h" - -#include "copyright.cf" - -static int exit_now=0; -static unsigned int flags=0; -static sigset_t signal_mask; -static int signal_received = 0; -#define FLAG_NODAEMON 1 - -static char *parse_cli_args(int argc, char *argv[]); -static int check_cluster_conf(void); -static void daemonize(void); -static void print_start_msg(char *msg); -static int join_group(int sfd, int loopback, int port); -static int setup_local_socket(int backlog); -static inline void process_signals(void); - -int main(int argc, char *argv[]){ - int i,error=0; - int trueint = 1; - int sfds[3] = {-1,-1,-1}, afd; - struct sockaddr_storage addr; - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; - int addr_size=0; - fd_set rset, tmp_set; - char *msg; - - msg = parse_cli_args(argc, argv); - - if(check_cluster_conf()){ - /* check_cluster_conf will print out errors if there are any */ - exit(EXIT_FAILURE); - } - - daemonize(); - - print_start_msg(msg); - - if(msg){ - free(msg); - } - - if(start_cluster_monitor_thread()){ - log_err("Unable to create thread.\n"); - exit(EXIT_FAILURE); - } - - memset(&addr, 0, sizeof(struct sockaddr_storage)); - - /** Setup the socket to communicate with the CCS library **/ - if(IPv6 && (sfds[0] = socket(PF_INET6, SOCK_STREAM, 0)) < 0){ - if(IPv6 == -1){ - log_dbg("Unable to create IPv6 socket:: %s\n", strerror(errno)); - IPv6=0; - } else { - log_sys_err("Unable to create IPv6 socket"); - exit(EXIT_FAILURE); - } - } else { - /* IPv6 is no longer optional for ccsd - IPv6 = (IPv6)? 1: 0; - */ - } - - log_dbg("Using %s\n", IPv6?"IPv6":"IPv4"); - - if(!IPv6 && (sfds[0] = socket(PF_INET, SOCK_STREAM, 0)) < 0){ - log_sys_err("Unable to create IPv4 socket"); - exit(EXIT_FAILURE); - } - - if(setsockopt(sfds[0], SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int))){ - log_sys_err("Unable to set socket option"); - exit(EXIT_FAILURE); - } - - if(IPv6){ - addr_size = sizeof(struct sockaddr_in6); - addr6->sin6_family = AF_INET6; - addr6->sin6_addr = in6addr_loopback; - addr6->sin6_port = htons(frontend_port); - } else { - addr_size = sizeof(struct sockaddr_in); - addr4->sin_family = AF_INET; - /* addr4->sin_addr.s_addr = INADDR_LOOPBACK; */ - inet_aton("127.0.0.1", (struct in_addr *)&(addr4->sin_addr.s_addr)); - addr4->sin_port = htons(frontend_port); - } - - if(bind(sfds[0], (struct sockaddr *)&addr, addr_size) < 0){ - log_sys_err("Unable to bind socket"); - close(sfds[0]); - exit(EXIT_FAILURE); - } - - listen(sfds[0], 5); - - - /** Setup the socket to communicate with the CCS library **/ - sfds[1] = socket((IPv6)? PF_INET6: PF_INET, SOCK_DGRAM, 0); - if(sfds[1] < 0){ - log_sys_err("Socket creation failed"); - exit(EXIT_FAILURE); - } else { - int trueint = 1; - if(setsockopt(sfds[1], SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int))){ - log_sys_err("Unable to set socket option"); - exit(EXIT_FAILURE); - } - } - - if(IPv6){ - addr6->sin6_family = AF_INET6; - addr6->sin6_addr = in6addr_any; - addr6->sin6_port = htons(backend_port); - } else { - addr4->sin_family = AF_INET; - addr4->sin_addr.s_addr = INADDR_ANY; - addr4->sin_port = htons(backend_port); - } - - if(bind(sfds[1], (struct sockaddr *)&addr, addr_size) < 0){ - log_sys_err("Unable to bind socket"); - close(sfds[1]); - return -errno; - } - - if(IPv6 || multicast_address){ - if(join_group(sfds[1], 1, backend_port)){ - log_err("Unable to join multicast group.\n"); - exit(EXIT_FAILURE); - } - } - - listen(sfds[1], 5); - - /* Set up the unix (local) socket for CCS lib comms */ - sfds[2] = setup_local_socket(SOMAXCONN); - - FD_ZERO(&rset); - FD_SET(sfds[0], &rset); - FD_SET(sfds[1], &rset); - if (sfds[2] >= 0) - FD_SET(sfds[2], &rset); - - while(1){ - int len = addr_size; - - process_signals(); - - tmp_set = rset; - - if((select(FD_SETSIZE, &tmp_set, NULL,NULL,NULL) < 0)){ - if(errno != EINTR){ - log_sys_err("Select failed"); - } - continue; - } - - for(i=0; i<3; i++){ - if(sfds[i] < 0 || !FD_ISSET(sfds[i], &tmp_set)){ - continue; - } - if(i == 0){ - uint16_t port; - log_dbg("NORMAL CCS REQUEST.\n"); - afd = accept(sfds[i], (struct sockaddr *)&addr, &len); - if(afd < 0){ - log_sys_err("Unable to accept connection"); - continue; - } - - port = (IPv6) ? addr6->sin6_port : addr4->sin_port; - - log_dbg("Connection requested from port %u.\n", ntohs(port)); - - if(ntohs(port) > 1024){ - log_err("Refusing connection from port > 1024: port = %d", ntohs(port)); - close(afd); - continue; - } - if((error = process_request(afd))){ - log_err("Error while processing request: %s\n", strerror(-error)); - } - close(afd); - } else if (i == 2) { - log_dbg("NORMAL CCS REQUEST.\n"); - afd = accept(sfds[i], NULL, NULL); - if(afd < 0){ - log_sys_err("Unable to accept connection"); - continue; - } - - log_dbg("Connection requested from local socket\n"); - - if((error = process_request(afd))){ - log_err("Error while processing request: %s\n", strerror(-error)); - } - close(afd); - } else { - log_dbg("BROADCAST REQUEST.\n"); - if((error = process_broadcast(sfds[i]))){ - log_err("Error while processing broadcast: %s\n", strerror(-error)); - } - } - } - } - exit(EXIT_SUCCESS); -} - - -/** - * print_usage - print usage information - * @stream: open file stream to print to - * - */ -static void print_usage(FILE *stream){ - ENTER("print_usage"); - fprintf(stream, - "Usage:\n" - "\n" - "ccsd [Options]\n" - "\n" - "Options:\n" - " -4 Use IPv4 only.\n" - " -6 Use IPv6 only.\n" - " -I Use IP for everything (disables local sockets)\n" - " -h Help.\n" - " -m <addr> Specify multicast address ("default" ok).\n" - " -n No Daemon. Run in the foreground.\n" - /* " -p <file> Specify the location of the pid file.\n"*/ - " -t <ttl> Multicast threshold (aka Time to Live) value.\n" - " -P [bcf]:# Specify various port numbers.\n" - " -V Print version information.\n" - ); - EXIT("print_usage"); -} - - -static int is_multicast_addr(char *addr_string){ - int rtn = 0; - struct sockaddr_storage addr; - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; - - ENTER("is_multicast_addr"); - - if(inet_pton(AF_INET6, addr_string, &(addr6->sin6_addr)) > 0){ - if(IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)){ - rtn = AF_INET6; - } - } else if(inet_pton(AF_INET, addr_string, &(addr4->sin_addr)) > 0){ - if(IN_MULTICAST(ntohl(addr4->sin_addr.s_addr))){ - rtn = AF_INET; - } - } - EXIT("is_multicast_addr"); - return rtn; -} - - -/** - * parse_cli_args - * @argc: - * @argv: - * - * This function parses the command line arguments and sets the - * appropriate flags in the global 'flags' variable. Additionally, - * it sets the global 'config_file_location'. This function - * will either succeed or cause the program to exit. - * - * Returns: string (or NULL) describing changes, exit(EXIT_FAILURE) on error - */ -static char *parse_cli_args(int argc, char *argv[]){ - int c, error=0; - int buff_size=512; - char buff[buff_size]; - int buff_index=0; - - ENTER("parse_cli_args"); - - config_file_location = strdup(DEFAULT_CONFIG_LOCATION); - lockfile_location = strdup(DEFAULT_CCSD_LOCKFILE); - - if(!config_file_location || !lockfile_location){ - fprintf(stderr, "Insufficient memory.\n"); - error = -ENOMEM; - goto fail; - } - - memset(buff, 0, buff_size); - - while((c = getopt(argc, argv, "46Icdf:hlm:nP:t:sV")) != -1){ - switch(c){ - case '4': - if(IPv6 == 1){ - fprintf(stderr, - "Setting protocol to IPv4 conflicts with previous protocol choice.\n"); - error = -EINVAL; - goto fail; - } - IPv6=0; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " IP Protocol:: IPv4 only\n"); - break; - case '6': - if(IPv6 == 0){ - fprintf(stderr, - "Setting protocol to IPv6 conflicts with previous protocol choice.\n"); - error = -EINVAL; - goto fail; - } - IPv6=1; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " IP Protocol:: IPv6 only\n"); - break; - case 'I': - if (use_local) { - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Communication:: Local sockets disabled\n"); - } - use_local = 0; - break; - case 'c': - fprintf(stderr, "The '-c' option is depricated.\n" - "Try '-h' for help.\n"); - error = -EINVAL; - goto fail; - case 'd': /* might be usable for upgrade */ - fprintf(stderr, "The '-d' option is depricated.\n" - "Try '-h' for help.\n"); - error = -EINVAL; - goto fail; - case 'f': /* might be usable for upgrade */ - free(config_file_location); - config_file_location = optarg; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Config file location:: %s\n", optarg); - break; - case 'h': - print_usage(stdout); - exit(EXIT_SUCCESS); - case 'l': - fprintf(stderr, "The '-l' option is depricated.\n" - "Try '-h' for help.\n"); - error = -EINVAL; - goto fail; - case 'm': - if(strcmp("default", optarg)){ - int type = is_multicast_addr(optarg); - if((IPv6 == 1) && (type != AF_INET6)){ - fprintf(stderr, "%s is not a valid IPv6 multicast address.\n", optarg); - error = -EINVAL; - goto fail; - } else if((IPv6 == 0) && (type != AF_INET)){ - fprintf(stderr, "%s is not a valid IPv4 multicast address.\n", optarg); - error = -EINVAL; - goto fail; - } else if(type == 0){ - fprintf(stderr, "%s is not a valid multicast address.\n", optarg); - error = -EINVAL; - goto fail; - } else { - IPv6 = (type == AF_INET6)? 1: 0; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " IP Protocol:: %s only*\n", - (IPv6)? "IPv6" : "IPv4"); - } - } - multicast_address = optarg; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Multicast (%s):: SET\n", optarg); - break; - case 'n': - flags |= FLAG_NODAEMON; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " No Daemon:: SET\n"); - break; - case 'p': - free(lockfile_location); - lockfile_location = optarg; - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Lock file location:: %s\n", optarg); - break; - case 'P': - if(optarg[1] != ':'){ - fprintf(stderr, "Bad argument to '-P' option.\n" - "Try '-h' for help.\n"); - error = -EINVAL; - goto fail; - } - switch(optarg[0]){ - case 'b': /* backend port number */ - backend_port = atoi(optarg+2); - if(backend_port < 1024){ - fprintf(stderr, "Bad backend port number.\n"); - error = -EINVAL; - goto fail; - } - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Backend Port:: %d\n", backend_port); - break; - case 'c': /* cluster base port number */ - cluster_base_port = atoi(optarg+2); - if(cluster_base_port < 1024){ - fprintf(stderr, "Bad cluster base port number.\n"); - error = -EINVAL; - goto fail; - } - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Cluster base port:: %d\n", cluster_base_port); - break; - case 'f': /* frontend port number */ - frontend_port = atoi(optarg+2); - if(frontend_port < 1024){ - fprintf(stderr, "Bad frontend port number.\n"); - error = -EINVAL; - goto fail; - } - buff_index += snprintf(buff+buff_index, buff_size-buff_index, - " Frontend Port:: %d\n", frontend_port); - break; - default: - fprintf(stderr, "Bad argument to '-P' option.\n" - "Try '-h' for help.\n"); - error = -EINVAL; - goto fail; - } - break; - case 's': - fprintf(stderr, "The '-s' option is depricated.\n" - "Try '-h' for help.\n"); - error = -EINVAL; - goto fail; - case 't': - ttl = atoi(optarg); - break; - case 'V': - printf("%s %s (built %s %s)\n", argv[0], CCS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - default: - print_usage(stderr); - error = -EINVAL; - goto fail; - } - } - - fail: - EXIT("parse_cli_args"); - - if(error){ - exit(EXIT_FAILURE); - } - if(strlen(buff)){ - return(strdup(buff)); - } else { - return NULL; - } -} - - -/* - * check_cluster_conf - check validity of local copy of cluster.conf - * - * This function tries to parse the xml doc at 'config_file_location'. - * If it fails, it gives instructions to the user. - * - * Returns: 0 on success, -1 on failure - */ -static int check_cluster_conf(void){ - struct stat stat_buf; - xmlDocPtr doc = NULL; - - if(!stat(config_file_location, &stat_buf)){ - doc = xmlParseFile(config_file_location); - if(!doc){ - log_err("\nUnable to parse %s.\n", config_file_location); - return -1; - } - xmlFreeDoc(doc); - } else { - /* - * no cluster.conf file. - * We used to simply return 0 here and let go fetch a random - * conf file from the network. This worked well in environments - * that had only one cluster in broadcast range, but it has - * caused to much confusion when there is more than one cluster. - * Additionally, our docs and manuals tell users to copy the - * file to each node anyway. - * - * In the event that there is a cluster.conf file, ccs will - * still ensure that it has the most up-to-date copy of the - * file in relation to the other nodes in the quorate cluster. - */ - log_err("%s: file not found.\n" - "Please ensure an initial copy of this file is present on all cluster nodes.\n", - config_file_location); - return -1; - } - - return 0; -} - - -/** - * create_lockfile - create and lock a lock file - * @lockfile: location of lock file - * - * Returns: 0 on success, -1 otherwise - */ -static int create_lockfile(char *lockfile){ - int fd, error=0; - struct stat stat_buf; - struct flock lock; - char buffer[50]; - - ENTER("create_lockfile"); - - if(!strncmp(lockfile, "/var/run/cluster/", 17)){ - if(stat("/var/run/cluster", &stat_buf)){ - if(mkdir("/var/run/cluster", S_IRWXU)){ - log_sys_err("Cannot create lockfile directory"); - error = -errno; - goto fail; - } - } else if(!S_ISDIR(stat_buf.st_mode)){ - log_err("/var/run/cluster is not a directory.\n" - "Cannot create lockfile.\n"); - error = -ENOTDIR; - goto fail; - } - } - - if((fd = open(lockfile, O_CREAT | O_WRONLY, - (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0){ - log_sys_err("Cannot create lockfile"); - error = -errno; - goto fail; - } - - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - if (fcntl(fd, F_SETLK, &lock) < 0) { - close(fd); - log_err("The ccsd process is already running.\n"); - error = -errno; - goto fail; - } - - if (ftruncate(fd, 0) < 0) { - close(fd); - error = -errno; - goto fail; - } - - sprintf(buffer, "%d\n", getpid()); - - if(write(fd, buffer, strlen(buffer)) < strlen(buffer)){ - close(fd); - unlink(lockfile); - error = -errno; - goto fail; - } - - fail: - EXIT("create_lockfile"); - - /* leave fd open - rely on exit to close it */ - if(error){ - return error; - } else { - return 0; - } -} - - -/** - * parent_exit_handler: exit the parent - * @sig: the signal - * - */ -static void parent_exit_handler(int sig){ - ENTER("parent_exit_handler"); - exit_now=1; - EXIT("parent_exit_handler"); -} - - -/** - * sig_handler - * @sig - * - * This handles signals which the daemon might receive. - */ -static void sig_handler(int sig){ - sigaddset(&signal_mask, sig); - ++signal_received; -} - -static void process_signal(int sig){ - int err; - - ENTER("sig_handler"); - - switch(sig) { - case SIGINT: - log_msg("Stopping ccsd, SIGINT received.\n"); - err = EXIT_SUCCESS; - break; - case SIGQUIT: - log_msg("Stopping ccsd, SIGQUIT received.\n"); - err = EXIT_SUCCESS; - break; - case SIGTERM: - log_msg("Stopping ccsd, SIGTERM received.\n"); - err = EXIT_SUCCESS; - break; - case SIGHUP: - log_msg("SIGHUP received.\n"); - log_msg("Use ccs_tool for updates.\n"); - return; - break; - default: - log_err("Stopping ccsd, unknown signal %d received.\n", sig); - err = EXIT_FAILURE; - } - - EXIT("sig_handler"); - exit(err); -} - - -static inline void process_signals(void) -{ - int x; - - if (!signal_received) - return; - - signal_received = 0; - - for (x = 1; x < _NSIG; x++) { - if (sigismember(&signal_mask, x)) { - sigdelset(&signal_mask, x); - process_signal(x); - } - } -} - - -/** - * daemonize - * - * This function will do the following: - * - daemonize, if required - * - set up the lockfile - * - set up logging - * - set up signal handlers - * It will cause the program to exit if there is a failure. - */ -static void daemonize(void){ - int error=0; - int pid; - - ENTER("daemonize"); - - if(flags & FLAG_NODAEMON){ - log_dbg("Entering non-daemon mode.\n"); - if((error = create_lockfile(lockfile_location))){ - goto fail; - } - } else { - log_dbg("Entering daemon mode.\n"); - - signal(SIGTERM, &parent_exit_handler); - - pid = fork(); - - if(pid < 0){ - fprintf(stderr, "Unable to fork().\n"); - error = pid; - goto fail; - } - - if(pid){ - int status; - while(!waitpid(pid, &status, WNOHANG) && !exit_now); - if(exit_now) - exit(EXIT_SUCCESS); - - switch(WEXITSTATUS(status)){ - case EXIT_MAGMA_PLUGINS: - fprintf(stderr, "Failed to connect to cluster manager.\n" - "Hint: Magma plugins are not in the right spot.\n"); - break; - case EXIT_CLUSTER_FAIL: - fprintf(stderr, "Failed to connect to cluster manager.\n"); - break; - case EXIT_LOCKFILE: - fprintf(stderr, "Failed to create lockfile.\n"); - fprintf(stderr, "Hint: ccsd is already running.\n"); - break; - } - exit(EXIT_FAILURE); - } - ppid = getppid(); - setsid(); - chdir("/"); - umask(0); - - close(0); close(1); close(2); - open("/dev/null", O_RDONLY); /* reopen stdin */ - open("/dev/null", O_WRONLY); /* reopen stdout */ - open("/dev/null", O_WRONLY); /* reopen stderr */ - - log_open("ccsd", LOG_PID, LOG_DAEMON); - - if((error = create_lockfile(lockfile_location))){ - exit(EXIT_LOCKFILE); - } - - /* hold off on shutting down parent. Let cluster_communicator do it ** - ** after if figures out if it can use magma or not.................. ** - ** kill(getppid(), SIGTERM); */ - } - - signal(SIGINT, &sig_handler); - signal(SIGQUIT, &sig_handler); - signal(SIGTERM, &sig_handler); - signal(SIGHUP, &sig_handler); - signal(SIGPIPE, SIG_IGN); - sigemptyset(&signal_mask); - signal_received = 0; - - fail: - EXIT("daemonize"); - - if(error){ - exit(EXIT_FAILURE); - } -} - - -/** - * print_start_msg - * - */ -static void print_start_msg(char *msg){ - /* We want the start message to print every time */ - log_msg("Starting ccsd %s:\n", CCS_RELEASE_NAME); - log_msg(" Built: "__DATE__" "__TIME__"\n"); - log_msg(" %s\n", REDHAT_COPYRIGHT); - if(msg){ - log_msg("%s\n", msg); - } -} - - -static int join_group(int sfd, int loopback, int port){ - int error = 0; - char *addr_string; - struct sockaddr_storage addr; - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; - - ENTER("join_group"); - - if(IPv6){ - if(!multicast_address || !strcmp("default", multicast_address)){ - addr_string = "ff02::3:1"; - } else { - addr_string = multicast_address; - } - inet_pton(AF_INET6, addr_string, &(addr6->sin6_addr)); - addr6->sin6_family = AF_INET6; - addr6->sin6_port = htons(port); - } else { - if(!strcmp("default", multicast_address)){ - addr_string = "224.0.2.5"; - } else { - addr_string = multicast_address; - } - inet_pton(AF_INET, addr_string, &(addr4->sin_addr)); - addr4->sin_family = AF_INET; - addr4->sin_port = htons(port); - } - - if(addr.ss_family == AF_INET){ - struct ip_mreq mreq; - - mreq.imr_multiaddr.s_addr = addr4->sin_addr.s_addr; - mreq.imr_interface.s_addr = INADDR_ANY; - - if(setsockopt(sfd, IPPROTO_IP, IP_MULTICAST_LOOP, - &loopback, sizeof(loopback)) < 0){ - log_err("Unable to %s loopback.\n", loopback?"SET":"UNSET"); - error = -errno; - goto fail; - } - if(setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (const void *)&mreq, sizeof(mreq)) < 0){ - log_err("Unable to add to membership.\n"); - error = -errno; - goto fail; - } - } else if(addr.ss_family == AF_INET6){ - struct ipv6_mreq mreq; - - memcpy(&mreq.ipv6mr_multiaddr, &(addr6->sin6_addr), sizeof(struct in6_addr)); - - mreq.ipv6mr_interface = 0; - - if(setsockopt(sfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, - &loopback, sizeof(loopback)) < 0){ - log_err("Unable to %s loopback.\n", loopback?"SET":"UNSET"); - error = -errno; - goto fail; - } - if(setsockopt(sfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, - (const void *)&mreq, sizeof(mreq)) < 0){ - log_err("Unable to add to membership: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - } else { - log_err("Unknown address family.\n"); - error = -EINVAL; - } - fail: - EXIT("join_group"); - return 0; -} - -int setup_local_socket(int backlog) -{ - int sock = -1; - struct sockaddr_un su; - mode_t om; - - ENTER("setup_local_socket"); - if (use_local == 0) - goto fail; - - sock = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) - goto fail; - - /* This is ours ;) */ - unlink(COMM_LOCAL_SOCKET); - om = umask(077); - su.sun_family = PF_LOCAL; - snprintf(su.sun_path, sizeof(su.sun_path), COMM_LOCAL_SOCKET); - - if (bind(sock, &su, sizeof(su)) < 0) { - umask(om); - goto fail; - } - umask(om); - - if (listen(sock, backlog) < 0) - goto fail; - - log_dbg("Set up local socket on %s\n", su.sun_path); - EXIT("setup_local_socket"); - return sock; -fail: - if (sock >= 0) - close(sock); - EXIT("setup_local_socket"); - return -1; -} diff --git a/ccs/daemon/cluster_mgr.c b/ccs/daemon/cluster_mgr.c deleted file mode 100644 index 220b03b..0000000 --- a/ccs/daemon/cluster_mgr.c +++ /dev/null @@ -1,433 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <libxml/parser.h> - -#include "comm_headers.h" -#include "log.h" -#include "debug.h" -#include "misc.h" -#include "globals.h" - -#include "magma.h" -#include "magmamsg.h" - -static cluster_member_list_t *membership = NULL; - -static int check_update_doc(xmlDocPtr tmp_doc){ - int error = 0; - char *str1 = NULL; - char *str2 = NULL; - - ENTER("check_update_doc"); - - if(!(str1 = get_cluster_name(tmp_doc))){ - log_err("Unable to get cluster name from new config file.\n"); - error = -EINVAL; - goto fail; - } - - if(master_doc && master_doc->od_doc && - !(str2 = get_cluster_name(master_doc->od_doc))){ - log_dbg("Unable to get cluster name from current master doc.\n"); - } - - if(str2 && strcmp(str1, str2)){ - log_err("Cluster names for current and update configs do not match.\n"); - log_err(" Current cluster name:: <%s>\n", str2); - log_err(" Proposed update name:: <%s>\n", str1); - error = -EINVAL; - goto fail; - } - - if(master_doc && master_doc->od_doc && - (get_doc_version(tmp_doc) <= get_doc_version(master_doc->od_doc))){ - log_err("Proposed updated config file does not have greater version number.\n"); - log_err(" Current config_version :: %d\n", - get_doc_version(master_doc->od_doc)); - log_err(" Proposed config_version:: %d\n", - get_doc_version(tmp_doc)); - error = -EINVAL; - } - - fail: - if(str1){ - free(str1); - } - if(str2){ - free(str2); - } - EXIT("check_update_doc"); - return error; -} - - -static int handle_cluster_message(int fd){ - int error = 0; - int afd= -1; - mode_t old_mode; - FILE *fp = NULL; - int unlock=0; - char *buffer = NULL; - xmlDocPtr tmp_doc = NULL; - comm_header_t ch; - uint64_t nodeid; - static uint64_t master_node=0; - - ENTER("handle_cluster_message"); - - log_dbg("Cluster message on socket: %d\n", fd); - if((afd = msg_accept(fd, 1, &nodeid)) < 0){ - log_sys_err("Failed to accept connection.\n"); - goto fail; - } - - log_dbg("Accept socket: %d\n", afd); - - error = msg_peek(afd, &ch, sizeof(comm_header_t)); - if(error < 0){ - log_sys_err("Failed to receive message from %s\n", - memb_id_to_name(membership,nodeid)); - goto fail; - } - - log_dbg("Message (%d bytes) received from %s\n", error, - memb_id_to_name(membership,nodeid)); - swab_header(&ch); - if(ch.comm_type != COMM_UPDATE){ - log_err("Unexpected communication type (%d)... ignoring.\n", - ch.comm_type); - error = -EINVAL; - goto fail; - } - - if(ch.comm_flags == COMM_UPDATE_NOTICE){ - buffer = malloc(ch.comm_payload_size + sizeof(comm_header_t)); - if(!buffer){ - log_err("Unable to allocate space to perform update.\n"); - error = -ENOMEM; - goto fail; - } - - log_dbg("Updated config size:: %d\n", ch.comm_payload_size); - - error = msg_receive_timeout(afd, buffer, - ch.comm_payload_size+sizeof(comm_header_t), 5); - - if(error < 0){ - log_sys_err("Unable to retrieve updated config"); - goto fail; - } - - pthread_mutex_lock(&update_lock); - unlock=1; - log_dbg("Got lock 0\n"); - - tmp_doc = xmlParseMemory(buffer+sizeof(comm_header_t), ch.comm_payload_size); - if(!tmp_doc){ - log_err("Unable to parse updated config file.\n"); - /* ATTENTION -- need better error code */ - error = -EIO; - goto fail; - } - - if((error = check_update_doc(tmp_doc)) < 0){ - goto fail; - } - - old_mode = umask(026); - fp = fopen("/etc/cluster/cluster.conf-update", "w"); - umask(old_mode); - if(!fp){ - log_sys_err("Unable to open /etc/cluster/cluster.conf-update"); - error = -errno; - goto fail; - } - - if(xmlDocDump(fp, tmp_doc) < 0){ - log_sys_err("Unable to write /etc/cluster/cluster.conf-update"); - goto fail; - } - - log_dbg("Upload of new config file from %s complete.\n", - memb_id_to_name(membership,nodeid)); - - ch.comm_payload_size = 0; - ch.comm_flags = COMM_UPDATE_NOTICE_ACK; - log_dbg("Sending COMM_UPDATE_NOTICE_ACK.\n"); - swab_header(&ch); - if((error = msg_send(afd, &ch, sizeof(comm_header_t))) < 0){ - log_sys_err("Unable to send COMM_UPDATE_NOTICE_ACK.\n"); - goto fail; - } - master_node = nodeid; - error = 0; - } else if(ch.comm_flags == COMM_UPDATE_COMMIT){ - error = msg_receive_timeout(afd, &ch, sizeof(comm_header_t), 5); - - if(master_node != nodeid){ - log_err("COMM_UPDATE_COMMIT received from node other than initiator.\n"); - log_err("Hint: There may be multiple updates happening at once.\n"); - error = -EPERM; - goto fail; - } - - pthread_mutex_lock(&update_lock); - unlock = 1; - log_dbg("Got lock 1\n"); - - tmp_doc = xmlParseFile("/etc/cluster/cluster.conf-update"); - if(!tmp_doc){ - log_err("Unable to parse updated config file.\n"); - /* ATTENTION -- need better error code */ - error = -EIO; - goto fail; - } - - if((error = check_update_doc(tmp_doc)) < 0){ - goto fail; - } - - old_mode = umask(026); - fp = fopen("/etc/cluster/.cluster.conf", "w"); - umask(old_mode); - - if(!fp){ - log_sys_err("Unable to open /etc/cluster/.cluster.conf"); - error = -errno; - goto fail; - } - - if(xmlDocDump(fp, tmp_doc) < 0){ - log_sys_err("Unable to write /etc/cluster/.cluster.conf"); - goto fail; - } - - rename("/etc/cluster/cluster.conf-update", "/etc/cluster/cluster.conf"); - update_required=1; - ch.comm_flags = COMM_UPDATE_COMMIT_ACK; - log_dbg("Sending COMM_UPDATE_COMMIT_ACK.\n"); - swab_header(&ch); - if((error = msg_send(afd, &ch, sizeof(comm_header_t))) < 0){ - log_sys_err("Unable to send COMM_UPDATE_NOTICE_ACK.\n"); - goto fail; - } - error = 0; - } - - fail: - if(fp){ - fclose(fp); - } - if(afd >= 0){ - msg_close(afd); - } - if(buffer){ - free(buffer); - } - if(tmp_doc){ - xmlFreeDoc(tmp_doc); - } - if(unlock){ - pthread_mutex_unlock(&update_lock); - } - EXIT("handle_cluster_message"); - return error; -} - - - - -/** - * handle_cluster_event - * @fd: fd returned from clu_connect - * - * Returns: 0 on success, -1 on shutdown event - */ -static int handle_cluster_event(int fd){ - ENTER("handle_cluster_event"); - - switch(clu_get_event(fd)) { - case CE_NULL: - log_dbg("-E- Spurious wakeup\n"); - break; - case CE_SUSPEND: - log_dbg("*E* Suspend activities\n"); - break; - case CE_MEMB_CHANGE: - log_dbg("*E* Membership change\n"); - break; - case CE_QUORATE: - log_dbg("*E* Quorum formed\n"); - log_msg("Cluster is quorate. Allowing connections.\n"); - quorate = 1; - break; - case CE_INQUORATE: - log_dbg("*E* Quorum dissolved\n"); - quorate = 0; - break; - case CE_SHUTDOWN: - log_dbg("*E* Node shutdown\n"); - quorate = 0; - clu_disconnect(fd); - EXIT("handle_cluster_event"); - return -1; - default: - log_dbg("-E- Unknown cluster event\n"); - } - cml_free(membership); - membership = clu_member_list(NULL); - memb_resolve_list(membership, NULL); - msg_update(membership); - - EXIT("handle_cluster_event"); - return 0; -} - - -static void cluster_communicator(void){ - uint64_t nid; - int cluster_fd = -1; - int listen_fds[2], listeners; - int warn_user = 0; - int fd; - int error; - fd_set rset; - int max_fds, n; - - ENTER("cluster_communicator"); - - if ((listeners = msg_listen(cluster_base_port, 0, listen_fds, 2)) <= 0) { - log_err("Unable to setup update listener socket.\n"); - exit(EXIT_FAILURE); - } - - for(n=0; n < listeners; n++){ - log_dbg("Listener[%d] = %d\n", n, listen_fds[n]); - } - - restart: - while(cluster_fd < 0){ - cluster_fd = clu_connect(NULL, 0); - if(cluster_fd < 0){ - switch(errno){ - case ENOENT: - case ELIBACC: - log_err("Failed to connect to cluster manager.\n" - "Hint: Magma plugins are not in the right spot.\n"); - exit(EXIT_MAGMA_PLUGINS); - break; - case EINVAL: - log_err("Failed to connect to cluster manager.\n"); - exit(EXIT_CLUSTER_FAIL); - break; - case ESRCH: - default: - /* All fine, just haven't gotten ahold of the cluster mgr yet ** - ** at this point, we can tell the parent to exit */ - if(ppid){ - kill(ppid, SIGTERM); - ppid = 0; - } - } - warn_user++; - if(!(warn_user%30)){ - log_err("Unable to connect to cluster infrastructure after %d seconds.\n", - warn_user); - } - sleep(1); - } - } - if(ppid){ - kill(ppid, SIGTERM); - ppid = 0; - } - - log_dbg("cluster_fd = %d\n", cluster_fd); - - log_msg("Connected to cluster infrastruture via: %s\n", clu_plugin_version()); - - quorate = (clu_quorum_status(NULL) & QF_QUORATE); - log_msg("Initial status:: %s\n", (quorate)? "Quorate" : "Inquorate"); - - membership = clu_member_list(NULL); - msg_update(membership); - clu_local_nodeid(NULL, &nid); - msg_set_nodeid(nid); - memb_resolve_list(membership, NULL); - - while(1) { - FD_ZERO(&rset); - max_fds = msg_fill_fdset(&rset, MSG_ALL, MSGP_ALL); - log_dbg("Waiting for cluster event.\n"); - n = select(max_fds+1, &rset, NULL, NULL, NULL); - - if(n < 0){ - log_sys_err("Select failed"); - continue; - } - log_dbg("There are %d cluster messages waiting.\n", n); - - while(n){ - log_dbg("There are %d messages remaining.\n", n); - fd = msg_next_fd(&rset); - if(fd == -1) { break; } - n--; - if(fd == cluster_fd){ - if(handle_cluster_event(fd)){ - cluster_fd = -1; - log_err("Cluster manager shutdown. Attemping to reconnect...\n"); - goto restart; - } - } else { - if((error = handle_cluster_message(fd)) < 0){ - log_err("Error while responding to cluster message: %s\n", strerror(-error)); - } - } - } - } - - EXIT("cluster_communicator"); -} - -int start_cluster_monitor_thread(void){ - int error = 0; - pthread_t thread; - - ENTER("start_cluster_monitor_thread"); - - pthread_mutex_init(&update_lock, NULL); - - error = pthread_create(&thread, NULL, (void *)cluster_communicator, NULL); - if(error){ - log_err("Failed to create thread: %s\n", strerror(-error)); - goto fail; - } - pthread_detach(thread); - - - fail: - EXIT("start_cluster_monitor_thread"); - return error; -} - diff --git a/ccs/daemon/cluster_mgr.h b/ccs/daemon/cluster_mgr.h deleted file mode 100644 index 1c838b4..0000000 --- a/ccs/daemon/cluster_mgr.h +++ /dev/null @@ -1,17 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __CLUSTER_MGR_DOT_H__ -#define __CLUSTER_MGR_DOT_H__ - -int start_cluster_monitor_thread(void); - -#endif /* __CLUSTER_MGR_DOT_H__ */ diff --git a/ccs/daemon/cnx_mgr.c b/ccs/daemon/cnx_mgr.c deleted file mode 100644 index 6789951..0000000 --- a/ccs/daemon/cnx_mgr.c +++ /dev/null @@ -1,1391 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <pthread.h> -#include <signal.h> -#include <unistd.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <time.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -#include "log.h" -#include "comm_headers.h" -#include "debug.h" -#include "misc.h" -#include "globals.h" - -/* Default descriptor expiration time, in seconds */ -#ifndef DEFAULT_EXPIRE -#define DEFAULT_EXPIRE 30 -#endif - -/* Maximum open connection count */ -#ifndef MAX_OPEN_CONNECTIONS -#define MAX_OPEN_CONNECTIONS 30 -#endif - -/* Conversion from descriptor to ocs index */ -#ifdef dindex -#undef dindex -#endif -#define dindex(x) ((x) % MAX_OPEN_CONNECTIONS) - - -static inline void _cleanup_descriptor(int desc); - -typedef struct open_connection_s { - char *oc_cwp; - char *oc_query; - open_doc_t *oc_odoc; - xmlXPathContextPtr oc_ctx; - int oc_index; - int oc_desc; - time_t oc_expire; -} open_connection_t; - -/* ATTENTION: need to lock on this if we start forking the daemon ** -** Also would need to create a shared memory area for open cnx's */ -static open_connection_t **ocs = NULL; -static int _descbase = 0; - - -static int _update_config(char *location){ - int error = 0; - int v1=0, v2=0; - open_doc_t *tmp_odoc = NULL; - xmlDocPtr tmp_doc = NULL; - - ENTER("_update_config"); - - tmp_doc = xmlParseFile(location); - if(!tmp_doc){ - log_err("Unable to parse %s\n", location); - error = -EINVAL; - goto fail; - } else if((v2 = get_doc_version(tmp_doc)) < 0){ - log_err("Unable to get config_version from cluster.conf.\n"); - error = v2; - goto fail; - } else if(master_doc && master_doc->od_doc){ - v1 = get_doc_version(master_doc->od_doc); - if(v1 >= v2){ - log_err("cluster.conf on-disk version is <= to in-memory version.\n"); - log_err(" On-disk version : %d\n", v2); - log_err(" In-memory version : %d\n", v1); - error = -EPERM; - goto fail; - } - } else { - v1 = 0; - } - - if(!(tmp_odoc = malloc(sizeof(open_doc_t)))){ - error = -ENOMEM; - goto fail; - } - memset(tmp_odoc, 0, sizeof(open_doc_t)); - - tmp_odoc->od_doc = tmp_doc; - - log_dbg("There are %d references open on version %d of the config file.\n", - (master_doc)?master_doc->od_refs:0, v1); - if(master_doc && !master_doc->od_refs){ - log_dbg("Freeing version %d\n", v1); - xmlFreeDoc(master_doc->od_doc); - free(master_doc); - master_doc = tmp_odoc; - } else { - master_doc = tmp_odoc; - } - - log_msg("Update of cluster.conf complete (version %d -> %d).\n", v1, v2); - fail: - if(tmp_odoc != master_doc){ - free(tmp_odoc); - } - if(tmp_doc != master_doc->od_doc){ - xmlFreeDoc(tmp_doc); - } - - - EXIT("_update_config"); - return error; -} - - -static int update_config(void){ - int error = 0; - ENTER("update_config"); - - /* If update_required is set, it means that there is still a pending ** - ** update. We need to pull this one in before doing anything else. */ - if(update_required){ - error = _update_config("/etc/cluster/.cluster.conf"); - update_required = 0; - if(error){ - log_err("Previous update could not be completed.\n"); - goto fail; - } - } - - fail: - EXIT("update_config"); - return error; -} - -/** - * broadcast_for_doc - * - * Returns: 0 on success, < 0 on error - */ -static int broadcast_for_doc(char *cluster_name, int blocking){ - int opt; - int error = 0; - int retry = 5; - int sfd = -1; - int trueint; - int v1, v2; - int write_to_disk = 0; - char *tmp_name = NULL; - struct sockaddr_storage addr, recv_addr; - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; - int addr_size = 0; - int len=sizeof(struct sockaddr_storage); - comm_header_t *ch = NULL; - char *bdoc = NULL; - fd_set rset; - struct timeval tv; - xmlDocPtr tmp_doc = NULL; - - ENTER("broadcast_for_doc"); - - try_again: - if(!master_doc){ - log_err("No master_doc!!!\n"); - exit(EXIT_FAILURE); - } - - if(quorate && !cluster_name){ - log_err("Node is part of quorate cluster, but the cluster name is unknown.\n"); - log_err(" Unable to validate remote config files. Refusing connection.\n"); - error = -ECONNREFUSED; - goto fail; - } - - ch = malloc(sizeof(comm_header_t)); - if(!ch){ - error = -ENOMEM; - goto fail; - } - memset(ch, 0, sizeof(comm_header_t)); - - if(IPv6 && (sfd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) <0){ - log_sys_err("Unable to create IPv6 socket"); - error = -errno; - goto fail; - } - - if(!IPv6 && ((sfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)){ - log_sys_err("Unable to create socket for broadcast"); - error = -errno; - goto fail; - } - - memset(&addr, 0, sizeof(struct sockaddr_storage)); - - trueint = 1; - if(IPv6){ - struct ipv6_mreq mreq; - - addr6->sin6_family = AF_INET6; - addr6->sin6_port = htons(backend_port); - - if(!multicast_address || !strcmp(multicast_address, "default")){ - log_dbg("Trying IPv6 multicast (default).\n"); - if(inet_pton(AF_INET6, "ff02::3:1", &(addr6->sin6_addr)) <= 0){ - log_sys_err("Unable to convert multicast address"); - error = -errno; - goto fail; - } - } else { - log_dbg("Trying IPv6 multicast (%s).\n", multicast_address); - if(inet_pton(AF_INET6, multicast_address, &(addr6->sin6_addr)) <= 0){ - log_sys_err("Unable to convert multicast address"); - error = -errno; - goto fail; - } - } - - memcpy(&mreq.ipv6mr_multiaddr, &(addr6->sin6_addr), sizeof(struct in6_addr)); - mreq.ipv6mr_interface = 0; - opt = 0; - - if(setsockopt(sfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, - &opt, sizeof(opt)) < 0){ - log_err("Unable to %s loopback.\n", opt?"SET":"UNSET"); - error = -errno; - goto fail; - } - } else { - addr4->sin_family = AF_INET; - addr4->sin_port = htons(backend_port); - if(!multicast_address){ - log_dbg("Trying IPv4 broadcast.\n"); - - addr4->sin_addr.s_addr = INADDR_BROADCAST; - if((error = setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &trueint, sizeof(int)))){ - log_sys_err("Unable to set socket options"); - error = -errno; - goto fail; - } else { - log_dbg(" Broadcast enabled.\n"); - } - } else { - if(!strcmp(multicast_address, "default")){ - log_dbg("Trying IPv4 multicast (default).\n"); - if(inet_pton(AF_INET, "224.0.2.5", &(addr4->sin_addr)) <= 0){ - log_sys_err("Unable to convert multicast address"); - error = -errno; - goto fail; - } - } else { - log_dbg("Trying IPv4 multicast (%s).\n", multicast_address); - if(inet_pton(AF_INET, multicast_address, &(addr4->sin_addr)) <= 0){ - log_sys_err("Unable to convert multicast address"); - error = -errno; - goto fail; - } - } - opt = 0; - setsockopt(sfd, IPPROTO_IP, IP_MULTICAST_LOOP, &opt, sizeof(opt)); - if(setsockopt(sfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0){ - log_sys_err("Unable to set multicast threshold.\n"); - } - } - } - addr_size = IPv6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in); - - FD_ZERO(&rset); - - do { - ch->comm_type = COMM_BROADCAST; - - log_dbg("Sending broadcast.\n"); - swab_header(ch); - - if(sendto(sfd, (char *)ch, sizeof(comm_header_t), 0, - (struct sockaddr *)&addr, addr_size) < 0){ - log_sys_err("Unable to perform sendto"); - if(retry > 0){ - retry--; - close(sfd); - free(ch); - sleep(2); - goto try_again; - } else { - error = -errno; - goto fail; - } - } - - srandom(getpid()); - FD_SET(sfd, &rset); - tv.tv_sec = 0; - - tv.tv_usec = 250000 + (random()%500000); - log_dbg("Select waiting %ld usec\n", tv.tv_usec); - while((error = select(sfd+1, &rset, NULL,NULL, &tv))){ - log_dbg("Select returns %d\n", error); - if(error < 0){ - log_sys_err("Select failed"); - error = -errno; - goto fail; - } - if(error){ - log_dbg("Checking broadcast response.\n"); - error = 0; - recvfrom(sfd, (char *)ch, sizeof(comm_header_t), MSG_PEEK, - (struct sockaddr *)&recv_addr, (socklen_t *)&len); - swab_header(ch); - if(!ch->comm_payload_size || ch->comm_error){ - /* clean out this reply by not using MSG_PEEK */ - recvfrom(sfd, (char *)ch, sizeof(comm_header_t), 0, - (struct sockaddr *)&recv_addr, (socklen_t *)&len); - error = -ENODATA; - FD_SET(sfd, &rset); - goto reset_timer; - } - bdoc = malloc(ch->comm_payload_size + sizeof(comm_header_t)); - if(!bdoc){ - error = -ENOMEM; - goto fail; - } - memset(bdoc, 0, ch->comm_payload_size + sizeof(comm_header_t)); - /* ATTENTION -- potential for incomplete package */ - recvfrom(sfd, bdoc, ch->comm_payload_size + sizeof(comm_header_t), - 0, (struct sockaddr *)&recv_addr, &len); - tmp_doc = xmlParseMemory(bdoc+sizeof(comm_header_t), - ch->comm_payload_size); - if(!tmp_doc){ - log_err("Unable to parse remote cluster.conf.\n"); - free(bdoc); bdoc = NULL; - goto reset_timer; - } - - tmp_name = get_cluster_name(tmp_doc); - log_dbg(" Given cluster name = %s\n", cluster_name); - log_dbg(" Remote cluster name= %s\n", tmp_name); - if(!tmp_name){ - log_err("Unable to find cluster name in remote cluster.conf.\n"); - free(bdoc); bdoc = NULL; - xmlFreeDoc(tmp_doc); tmp_doc = NULL; - goto reset_timer; - } else if(cluster_name && strcmp(cluster_name, tmp_name)){ - log_dbg("Remote and local cluster.conf have different cluster names.\n"); - log_dbg("Skipping...\n"); - free(tmp_name); tmp_name = NULL; - free(bdoc); bdoc = NULL; - xmlFreeDoc(tmp_doc); tmp_doc = NULL; - goto reset_timer; - } - free(tmp_name); tmp_name = NULL; - if(!master_doc->od_doc){ - if((v2 = get_doc_version(tmp_doc)) >= 0){ - log_msg("Remote copy of cluster.conf (version = %d) found.\n", v2); - master_doc->od_doc = tmp_doc; - tmp_doc = NULL; - write_to_disk = 1; - } - } else { - if(((v1 = get_doc_version(master_doc->od_doc)) >= 0) && - ((v2 = get_doc_version(tmp_doc)) >= 0)){ - if(ch->comm_flags & COMM_BROADCAST_FROM_QUORATE){ - log_msg("Remote copy of cluster.conf is from quorate node.\n"); - log_msg(" Local version # : %d\n", v1); - log_msg(" Remote version #: %d\n", v2); - if(v1 != v2){ - log_msg("Switching to remote copy.\n"); - } - if(master_doc->od_refs){ - open_doc_t *tmp_odoc; - if(!(tmp_odoc = malloc(sizeof(open_doc_t)))){ - error = -ENOMEM; - goto fail; - } - memset(tmp_odoc, 0, sizeof(open_doc_t)); - tmp_odoc->od_doc = tmp_doc; - master_doc = tmp_odoc; - } else { - xmlFreeDoc(master_doc->od_doc); - master_doc->od_doc = tmp_doc; - } - tmp_doc = NULL; - write_to_disk = 1; - goto out; - } else if(v2 > v1){ - log_msg("Remote copy of cluster.conf is newer than local copy.\n"); - log_msg(" Local version # : %d\n", v1); - log_msg(" Remote version #: %d\n", v2); - if(master_doc->od_refs){ - open_doc_t *tmp_odoc; - if(!(tmp_odoc = malloc(sizeof(open_doc_t)))){ - error = -ENOMEM; - goto fail; - } - memset(tmp_odoc, 0, sizeof(open_doc_t)); - tmp_odoc->od_doc = tmp_doc; - master_doc = tmp_odoc; - } else { - xmlFreeDoc(master_doc->od_doc); - master_doc->od_doc = tmp_doc; - } - tmp_doc = NULL; - write_to_disk = 1; - } - } else { - xmlFreeDoc(tmp_doc); - tmp_doc = NULL; - } - } - free(bdoc); bdoc = NULL; - } - FD_SET(sfd, &rset); - /* select will alter the timeout */ - reset_timer: - tv.tv_sec = 0; - tv.tv_usec = 250000 + (random()%500000); - log_dbg("Select waiting %ld usec\n", tv.tv_usec); - } - } while(blocking && !master_doc); - out: - if(error){ - goto fail; - } - - if(write_to_disk){ - struct stat stat_buf; - mode_t old_mode; - FILE *f; - /* We did not have a copy available or we found a newer one, so write it out */ - - /* ATTENTION -- its bad if we fail here, because we have an in-memory version ** - ** but it has not been written to disk....................................... */ - if(stat("/etc/cluster", &stat_buf)){ - if(mkdir("/etc/cluster", S_IRWXU | S_IRWXG)){ - log_sys_err("Unable to create directory /etc/cluster"); - error = -errno; - goto fail; - } - } else if(!S_ISDIR(stat_buf.st_mode)){ - log_err("/etc/cluster is not a directory.\n"); - error = -ENOTDIR; - goto fail; - } - - old_mode = umask(026); - f = fopen("/etc/cluster/cluster.conf", "w"); - umask(old_mode); - if(!f){ - log_sys_err("Unable to open /etc/cluster/cluster.conf"); - error = -errno; - goto fail; - } - if(xmlDocDump(f, master_doc->od_doc) < 0){ - error = -EIO; - fclose(f); - goto fail; - } - fclose(f); - } - - fail: - if(ch) free(ch); - if(bdoc) free(bdoc); - if(tmp_doc) xmlFreeDoc(tmp_doc); - if(sfd >= 0) close(sfd); - EXIT("broadcast_for_doc"); - return error; -} - -/** - * process_connect: process a connect request - * @afd: accepted socket connection - * @cluster_name: optional cluster name - * - * Returns: 0 on success, < 0 on error - */ -static int process_connect(comm_header_t *ch, char *cluster_name){ - int i=0, error = 0; - int bcast_needed = 0; - char *tmp_name = NULL; - time_t now; - - ENTER("process_connect"); - - ch->comm_payload_size = 0; - - log_dbg("Given cluster name is = %s\n", cluster_name); - - if(!ocs){ - /* this will never be freed - unless exit */ - ocs = malloc(sizeof(open_connection_t *)*MAX_OPEN_CONNECTIONS); - if(!ocs){ - error = -ENOMEM; - goto fail; - } - memset(ocs, 0, sizeof(open_connection_t *)*MAX_OPEN_CONNECTIONS); - } - - if(!quorate && !(ch->comm_flags & COMM_CONNECT_FORCE)){ - log_msg("Cluster is not quorate. Refusing connection.\n"); - error = -ECONNREFUSED; - goto fail; - } - - if(!master_doc){ - /* ATTENTION -- signal could come at any time. It may be better to ** - ** malloc to different var, then copy to master_doc when done */ - master_doc = malloc(sizeof(open_doc_t)); - if(!master_doc){ - error = -ENOMEM; - goto fail; - } - memset(master_doc, 0, sizeof(open_doc_t)); - } - - if(!master_doc->od_doc){ - master_doc->od_doc = xmlParseFile("/etc/cluster/cluster.conf"); - if(!master_doc->od_doc){ - log_msg("Unable to parse %s\n", "/etc/cluster/cluster.conf"); - log_msg("Searching cluster for valid copy.\n"); - } else if((error = get_doc_version(master_doc->od_doc)) < 0){ - log_err("Unable to get config_version from cluster.conf.\n"); - log_err("Discarding data and searching for valid copy.\n"); - xmlFreeDoc(master_doc->od_doc); - master_doc->od_doc = NULL; - } else if(!(tmp_name = get_cluster_name(master_doc->od_doc))){ - log_err("Unable to get cluster name from cluster.conf.\n"); - log_err("Discarding data and searching for valid copy.\n"); - xmlFreeDoc(master_doc->od_doc); - master_doc->od_doc = NULL; - } else if(cluster_name && strcmp(cluster_name, tmp_name)){ - log_err("Given cluster name does not match local cluster.conf.\n"); - log_err("Discarding data and searching for matching copy.\n"); - xmlFreeDoc(master_doc->od_doc); - master_doc->od_doc = NULL; - free(tmp_name); tmp_name = NULL; - } else { /* Either the names match, or a name wasn't specified. */ - log_msg("cluster.conf (cluster name = %s, version = %d) found.\n", - tmp_name, error); - /* We must check with the others to make sure this is valid. */ - } - bcast_needed = 1; - error = 0; - } else { - tmp_name = get_cluster_name(master_doc->od_doc); - - /* ATTENTION -- if not quorate, consider swapping out in-memory config ** - ** for the config of the name specified............................... */ - - if(cluster_name && strcmp(cluster_name, tmp_name)){ - log_err("Request for cluster.conf with cluster name, %s\n", cluster_name); - log_err(" However, a cluster.conf with cluster name, %s, is already loaded.\n", - tmp_name); - error = -EINVAL; - goto fail; - } - if(!quorate){ - bcast_needed = 1; - } - } - - if(cluster_name && !tmp_name){ - tmp_name = strdup(cluster_name); - if(!tmp_name){ - error = -ENOMEM; - goto fail; - } - } - - log_dbg("Blocking is %s.\n", - (ch->comm_flags & COMM_CONNECT_BLOCKING)? "SET": "UNSET"); - log_dbg("Flags = 0x%x\n", ch->comm_flags); - - /* Need to broadcast regardless (unless quorate) to check version # */ - if(bcast_needed){ - log_dbg("Broadcast is neccessary.\n"); - } - if(bcast_needed && - (error = broadcast_for_doc(tmp_name, ch->comm_flags & COMM_CONNECT_BLOCKING)) && - !master_doc->od_doc){ - log_err("Broadcast for config file failed: %s\n", strerror(-error)); - goto fail; - } - error = 0; - - if(!master_doc || !master_doc->od_doc){ - log_err("The appropriate config file could not be loaded.\n"); - error = -ENODATA; - goto fail; - } - - if(update_required){ - log_dbg("Update is required.\n"); - if((error = update_config())){ - log_err("Failed to update config file, required by cluster.\n"); - /* ATTENTION -- remove all open_doc_t's ? */ - goto fail; - } - } - - /* Locate the connection descriptor */ - now = time(NULL); - for(i=0; i < MAX_OPEN_CONNECTIONS; i++){ - if (!ocs[i]) - continue; - if (now >= ocs[i]->oc_expire) { - log_dbg("Recycling connection descriptor %d: Expired\n", - ocs[i]->oc_desc ); - _cleanup_descriptor(i); - } - } - - for(i=0; i < MAX_OPEN_CONNECTIONS; i++){ - if(!ocs[i]) - break; - } - - if(i >= MAX_OPEN_CONNECTIONS){ - error = -EAGAIN; - goto fail; - } - - ocs[i] = (open_connection_t *)malloc(sizeof(open_connection_t)); - if(!ocs[i]){ - error = -ENOMEM; - goto fail; - } - - memset(ocs[i], 0, sizeof(open_connection_t)); - - master_doc->od_refs++; - ocs[i]->oc_odoc = master_doc; - ocs[i]->oc_ctx = xmlXPathNewContext(ocs[i]->oc_odoc->od_doc); - ocs[i]->oc_expire = now + DEFAULT_EXPIRE; - - /* using error as a temp var */ - error = i + _descbase++ * MAX_OPEN_CONNECTIONS; - if (error > INT_MAX || error < 0) { - error = i; - _descbase = 0; - } - ocs[i]->oc_desc = error; - - /* reset error */ - error = 0; - - if(!ocs[i]->oc_ctx){ - ocs[i]->oc_odoc->od_refs--; - free(ocs[i]); - log_err("Error: unable to create new XPath context.\n"); - error = -EIO; /* ATTENTION -- what should this be? */ - goto fail; - } - - /* return desc to requestor */ - - fail: - if(master_doc && master_doc->od_doc == NULL){ - free(master_doc); - master_doc = NULL; - } - if(tmp_name){ - free(tmp_name); - } - if(error){ - ch->comm_error = error; - } else { - ch->comm_desc = ocs[i]->oc_desc; - } - EXIT("process_connect"); - return error; -} - - -static inline void -_cleanup_descriptor(int desc) -{ - open_doc_t *tmp_odoc; - - if(ocs[desc]->oc_ctx){ - xmlXPathFreeContext(ocs[desc]->oc_ctx); - } - if(ocs[desc]->oc_cwp){ - free(ocs[desc]->oc_cwp); - } - if(ocs[desc]->oc_query){ - free(ocs[desc]->oc_query); - } - tmp_odoc = ocs[desc]->oc_odoc; - if(tmp_odoc->od_refs < 1){ - log_err("Number of references on an open doc should never be < 1.\n"); - log_err("This is a fatal error. Exiting...\n"); - exit(EXIT_FAILURE); - } - if(tmp_odoc != master_doc && tmp_odoc->od_refs == 1){ - log_dbg("No more references on version %d of config file, freeing...\n", - get_doc_version(tmp_odoc->od_doc)); - xmlFreeDoc(tmp_odoc->od_doc); - free(tmp_odoc); - } else { - tmp_odoc->od_refs--; - } - - free(ocs[desc]); - ocs[desc] = NULL; -} - - -/** - * process_disconnect: close an open session - * @afd: accepted socket connection - * @desc: descriptor describing the open connection - * - * This fuction frees all memory associated with an open session. - * - * Returns: 0 on success, < 0 on error - */ -static int process_disconnect(comm_header_t *ch){ - int desc = dindex(ch->comm_desc); - int error=0; - ENTER("process_disconnect"); - - ch->comm_payload_size = 0; - - if(desc < 0){ - log_err("Invalid descriptor specified (%d).\n", desc); - log_err("Someone may be attempting something evil.\n"); - error = -EBADR; - goto fail; - } - - if(!ocs || !ocs[desc] || (ocs[desc]->oc_desc != ch->comm_desc)){ - /* send failure to requestor ? */ - log_err("Attempt to close an unopened CCS descriptor (%d).\n", - ch->comm_desc); - - error = -EBADR; - goto fail; - } else { - _cleanup_descriptor(desc); - } - - fail: - if(error){ - ch->comm_error = error; - } else { - ch->comm_desc = -1; - } - EXIT("process_disconnect"); - return error; -} - -/* - * _process_get - * @ch - * @payload - * - * This function runs the xml query. If the query is different from the - * previous query, it will always fill the payload with the first match. - * If the current query and the previous query are the same, it fills the - * payload with next match. If the last of all possible matches was - * returned by the previous query and the current query is the same, - * the payload will be filled with the 1st match and 1 will be returned - * as the result of the function. - * - * Returns: -EXXX on error, 1 if restarting list, 0 otherwise - */ -static int _process_get(comm_header_t *ch, char **payload){ - int error = 0, desc = dindex(ch->comm_desc); - xmlXPathObjectPtr obj = NULL; - char *query = NULL; - - ENTER("_process_get"); - if(!ch->comm_payload_size){ - log_err("process_get: payload size is zero.\n"); - error = -EINVAL; - goto fail; - } - - if(ch->comm_desc < 0){ - log_err("Invalid descriptor specified (%d).\n", ch->comm_desc); - log_err("Someone may be attempting something evil.\n"); - error = -EBADR; - goto fail; - } - - if(!ocs || !ocs[desc] || (ocs[desc]->oc_desc != ch->comm_desc)){ - log_err("process_get: Invalid connection descriptor received.\n"); - error = -EBADR; - goto fail; - } - - if(ocs[desc]->oc_query && !strcmp(*payload,ocs[desc]->oc_query)){ - ocs[desc]->oc_index++; - log_dbg("Index = %d\n",ocs[desc]->oc_index); - log_dbg(" Query = %s\n", *payload); - } else { - log_dbg("Index reset (new query).\n"); - log_dbg(" Query = %s\n", *payload); - ocs[desc]->oc_index = 0; - if(ocs[desc]->oc_query){ - free(ocs[desc]->oc_query); - } - ocs[desc]->oc_query = (char *)strdup(*payload); - } - - /* ATTENTION -- should path expansion go before index inc ? */ - if(((ch->comm_payload_size > 1) && - ((*payload)[0] == '/')) || - !ocs[desc]->oc_cwp){ - log_dbg("Query involves absolute path or cwp is not set.\n"); - query = (char *)strdup(*payload); - if(!query){ - error = -ENOMEM; - goto fail; - } - } else { - /* +2 because of NULL and '/' character */ - log_dbg("Query involves relative path.\n"); - query = malloc(strlen(*payload)+strlen(ocs[desc]->oc_cwp)+2); - if(!query){ - error = -ENOMEM; - goto fail; - } - sprintf(query, "%s/%s", ocs[desc]->oc_cwp, *payload); - } - - /* Bump expiration time */ - ocs[desc]->oc_expire = time(NULL) + DEFAULT_EXPIRE; - - obj = xmlXPathEvalExpression(query, ocs[desc]->oc_ctx); - if(obj){ - log_dbg("Obj type = %d (%s)\n", obj->type, (obj->type == 1)?"XPATH_NODESET":""); - log_dbg("Number of matches: %d\n", (obj->nodesetval)?obj->nodesetval->nodeNr:0); - if(obj->nodesetval && (obj->nodesetval->nodeNr > 0) ){ - xmlNodePtr node; - int size=0; - int nnv=0; /* name 'n' value */ - - if(ocs[desc]->oc_index >= obj->nodesetval->nodeNr){ - ocs[desc]->oc_index = 0; - error = 1; - log_dbg("Index reset to zero (end of list).\n"); - } - - node = obj->nodesetval->nodeTab[ocs[desc]->oc_index]; - - log_dbg("Node (%s) type = %d (%s)\n", node->name, node->type, - (node->type == 1)? "XML_ELEMENT_NODE": - (node->type == 2)? "XML_ATTRIBUTE_NODE":""); - - if(!node) { - log_dbg("No content found.\n"); - error = -ENODATA; - goto fail; - } - - if(((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*")) || - ((node->type == XML_ELEMENT_NODE) && strstr(query, "child::*"))){ - /* add on the trailing NULL and the '=' separator for a list of attrs - or an element node + CDATA*/ - if (node->children && node->children->content) - size = strlen(node->children->content)+strlen(node->name)+2; - else - size = strlen(node->name)+2; - nnv= 1; - } else { - if (node->children && node->children->content) { - size = strlen(node->children->content)+1; - } else { - error = -ENODATA; - goto fail; - } - } - - if(size <= ch->comm_payload_size){ /* do we already have enough space? */ - log_dbg("No extra space needed.\n"); - if(nnv){ - sprintf(*payload, "%s=%s", node->name, node->children ? - (char *)node->children->content:""); - } else { - sprintf(*payload, "%s", node->children ? node->children->content : - node->name); - } - - } else { - log_dbg("Extra space needed.\n"); - free(*payload); - *payload = (char *)malloc(size); - if(!*payload){ - error = -ENOMEM; - goto fail; - } - if(nnv){ - sprintf(*payload, "%s=%s", node->name, node->children ? - (char *)node->children->content:""); - } else { - sprintf(*payload, "%s", node->children ? node->children->content : - node->name); - } - } - log_dbg("Query results:: %s\n", *payload); - ch->comm_payload_size = size; - } else { - log_dbg("No nodes found.\n"); - ch->comm_payload_size = 0; - error = -ENODATA; - goto fail; - } - } else { - log_err("Error: unable to evaluate xpath query "%s"\n", *payload); - error = -EINVAL; - goto fail; - } - - fail: - if(obj){ - xmlXPathFreeObject(obj); - } - if(error < 0){ - ch->comm_error = error; - ch->comm_payload_size = 0; - } - if(query) { free(query); } - EXIT("_process_get"); - return error; -} - -static int process_get(comm_header_t *ch, char **payload){ - int error; - ENTER("process_get"); - - error = _process_get(ch, payload); - - EXIT("process_get"); - return (error < 0)? error: 0; -} - -static int process_get_list(comm_header_t *ch, char **payload){ - int error; - ENTER("process_get_list"); - - error = _process_get(ch, payload); - if(error){ - ch->comm_payload_size = 0; - if(ocs && ocs[dindex(ch->comm_desc)]) - ocs[dindex(ch->comm_desc)]->oc_index = -1; - } - - EXIT("process_get_list"); - return (error < 0)? error: 0; -} - -static int process_set(comm_header_t *ch, char *payload){ - int error = 0; - int desc = dindex(ch->comm_desc); - - ENTER("process_set"); - if(!ch->comm_payload_size){ - log_err("process_set: payload size is zero.\n"); - error = -EINVAL; - goto fail; - } - - if(ch->comm_desc < 0){ - log_err("Invalid descriptor specified (%d).\n", ch->comm_desc); - log_err("Someone may be attempting something evil.\n"); - error = -EBADR; - goto fail; - } - - if(!ocs || !ocs[desc] || (ocs[desc]->oc_desc != ch->comm_desc)){ - log_err("process_set: Invalid connection descriptor received.\n"); - error = -EBADR; - goto fail; - } - - error = -ENOSYS; - - fail: - free(payload); - ch->comm_payload_size = 0; - if(error){ - ch->comm_error = error; - } - EXIT("process_set"); - return error; -} - - -static int process_get_state(comm_header_t *ch, char **payload){ - int error = 0, desc = dindex(ch->comm_desc); - char *load = NULL; - - ENTER("process_get_state"); - if(ch->comm_payload_size){ - log_err("process_get_state: payload size is nonzero.\n"); - error = -EINVAL; - goto fail; - } - - if(ch->comm_desc < 0){ - log_err("Invalid descriptor specified (%d).\n", ch->comm_desc); - log_err("Someone may be attempting something evil.\n"); - error = -EBADR; - goto fail; - } - - if(!ocs || !ocs[desc] || (ocs[desc]->oc_desc != ch->comm_desc)){ - log_err("process_get_state: Invalid connection descriptor received.\n"); - error = -EBADR; - goto fail; - } - - if(ocs[desc]->oc_cwp && ocs[desc]->oc_query){ - int size = strlen(ocs[desc]->oc_cwp) + - strlen(ocs[desc]->oc_query) + 2; - log_dbg("Both cwp and query are set.\n"); - load = malloc(size); - if(!load){ - error = -ENOMEM; - goto fail; - } - strcpy(load, ocs[desc]->oc_cwp); - strcpy(load+strlen(ocs[desc]->oc_cwp)+1, ocs[desc]->oc_query); - ch->comm_payload_size = size; - } else if(ocs[desc]->oc_cwp){ - log_dbg("Only cwp is set.\n"); - load = (char *)strdup(ocs[desc]->oc_cwp); - if(!load){ - error = -ENOMEM; - goto fail; - } - ch->comm_payload_size = strlen(load)+1; - } else if(ocs[desc]->oc_query){ - int size = strlen(ocs[desc]->oc_query) + 2; - log_dbg("Only query is set.\n"); - load = malloc(size); - if(!load){ - error = -ENOMEM; - goto fail; - } - memset(load, 0, size); - strcpy(load+1, ocs[desc]->oc_query); - ch->comm_payload_size = size; - } - - ocs[desc]->oc_expire = time(NULL) + DEFAULT_EXPIRE; - *payload = load; - - fail: - if(error){ - if(load) { free(load); } - ch->comm_error = error; - ch->comm_payload_size = 0; - } - EXIT("process_get_state"); - return error; -} - - -static int process_set_state(comm_header_t *ch, char *payload){ - int error = 0, desc = dindex(ch->comm_desc); - - ENTER("process_set_state"); - if(!ch->comm_payload_size){ - log_err("process_set_state: payload size is zero.\n"); - error = -EINVAL; - goto fail; - } - - if(ch->comm_desc < 0){ - log_err("Invalid descriptor specified (%d).\n", ch->comm_desc); - log_err("Someone may be attempting something evil.\n"); - error = -EBADR; - goto fail; - } - - if(!ocs || !ocs[desc] || (ocs[desc]->oc_desc != ch->comm_desc)){ - log_err("process_set_state: Invalid connection descriptor received.\n"); - error = -EBADR; - goto fail; - } - - if(ocs[desc]->oc_cwp){ - free(ocs[desc]->oc_cwp); - ocs[desc]->oc_cwp = NULL; - } - - if((ch->comm_flags & COMM_SET_STATE_RESET_QUERY) && ocs[desc]->oc_query){ - free(ocs[desc]->oc_query); - ocs[desc]->oc_query = NULL; - } - - ocs[desc]->oc_expire = time(NULL) + DEFAULT_EXPIRE; - ocs[desc]->oc_cwp = (char *)strdup(payload); - - fail: - ch->comm_payload_size = 0; - if(error){ - ch->comm_error = error; - } - - EXIT("process_set_state"); - return error; -} - - -/** - * process_request - * @afd - * - * This function operates as a switch, passing the request to the - * appropriate function. - * - * Returns: 0 on success, < 0 on error - */ -int process_request(int afd){ - int error=0; - comm_header_t *ch = NULL, *tmp_ch; - char *payload = NULL; - - ENTER("process_request"); - - if(!(ch = (comm_header_t *)malloc(sizeof(comm_header_t)))){ - error = -ENOMEM; - goto fail; - } - - error = read(afd, ch, sizeof(comm_header_t)); - if(error < 0){ - log_sys_err("Unable to read comm_header_t"); - goto fail; - } else if(error < sizeof(comm_header_t)){ - log_err("Unable to read complete comm_header_t.\n"); - error = -EBADE; - goto fail; - } - - if(ch->comm_payload_size){ - if(!(payload = (char *)malloc(ch->comm_payload_size))){ - error = -ENOMEM; - goto fail; - } - error = read(afd, payload, ch->comm_payload_size); - if(error < 0){ - log_sys_err("Unable to read payload"); - goto fail; - } else if(error < ch->comm_payload_size){ - log_err("Unable to read complete payload.\n"); - error = -EBADE; - goto fail; - } - } - - switch(ch->comm_type){ - case COMM_CONNECT: - if((error = process_connect(ch, payload)) < 0){ - log_err("Error while processing connect: %s\n", strerror(-error)); - goto fail; - } - break; - case COMM_DISCONNECT: - if((error = process_disconnect(ch)) < 0){ - log_err("Error while processing disconnect: %s\n", strerror(-error)); - goto fail; - } - break; - case COMM_GET: - if((error = process_get(ch, &payload)) < 0){ - if(error != -ENODATA){ - log_err("Error while processing get: %s\n", strerror(-error)); - } - goto fail; - } - break; - case COMM_GET_LIST: - if((error = process_get_list(ch, &payload)) < 0){ - if(error != -ENODATA){ - log_err("Error while processing get: %s\n", strerror(-error)); - } - goto fail; - } - break; - case COMM_SET: - if((error = process_set(ch, payload)) < 0){ - log_err("Error while processing set: %s\n", strerror(-error)); - goto fail; - } - break; - case COMM_GET_STATE: - if((error = process_get_state(ch, &payload)) < 0){ - log_err("Error while processing get_state: %s\n", strerror(-error)); - goto fail; - } - break; - case COMM_SET_STATE: - if((error = process_set_state(ch, payload)) < 0){ - log_err("Error while processing set_state: %s\n", strerror(-error)); - goto fail; - } - break; - default: - log_err("Unknown connection request received.\n"); - error = -EINVAL; - ch->comm_error = error; - ch->comm_payload_size = 0; - } - - if(ch->comm_payload_size){ - log_dbg("Reallocating transfer buffer.\n"); - tmp_ch = (comm_header_t *) - realloc(ch,sizeof(comm_header_t)+ch->comm_payload_size); - - if(tmp_ch) { ch = tmp_ch; } else { - log_err("Not enough memory to complete request.\n"); - error = -ENOMEM; - goto fail; - } - memcpy((char *)ch+sizeof(comm_header_t), payload, ch->comm_payload_size); - } - - fail: - error = write(afd, ch, sizeof(comm_header_t)+ch->comm_payload_size); - if(error < 0) { - if (errno == EINTR) - goto fail; - if (errno == EPIPE) { - error = 0; - } else { - log_sys_err("Unable to write package back to sender"); - } - } else if(error < (sizeof(comm_header_t)+ch->comm_payload_size)){ - log_err("Unable to write complete package.\n"); - error = -EBADE; - goto fail; - } else { - error = 0; - } - - if(ch){ free(ch); } - if(payload){ free(payload); } - - EXIT("process_request"); - return error; -} - - -/** - * process_broadcast - * @sfd: the UDP socket - * - * Returns: 0 on success, < 0 on failure - */ -int process_broadcast(int sfd){ - int error = 0; - comm_header_t *ch = NULL; - char *payload = NULL; - char *buffer = NULL; - struct sockaddr_storage addr; - int len = sizeof(struct sockaddr_storage); /* value/result for recvfrom */ - int sendlen; - int discard = 0; - - ENTER("process_broadcast"); - - ch = malloc(sizeof(comm_header_t)); - if(!ch){ - error = -ENOMEM; - goto fail; - } - memset(ch, 0, sizeof(comm_header_t)); - memset(&addr, 0, sizeof(struct sockaddr_storage)); /* just to make sure */ - - log_dbg("Waiting to receive broadcast request.\n"); - if(recvfrom(sfd, ch, sizeof(comm_header_t), 0, (struct sockaddr *)&addr, &len) < 0){ - log_sys_err("Unable to perform recvfrom"); - error = -errno; - goto fail; - } - swab_header(ch); - - if(ch->comm_type != COMM_BROADCAST){ - /* Either someone is pinging this port, or there is an older version ** - ** of ccs trying to get bcast response. Either way, we should not ** - ** respond to them.................................................. */ - log_dbg("Received invalid request on broadcast port. %x\n",ch->comm_type); - error = -EINVAL; - goto fail; - } - - /* need to ignore my own broadcasts */ - - if(ch->comm_payload_size){ - /* cluster name was sent, need to read it */ - } - - if(!master_doc){ - discard = 1; - log_dbg("master_doc not loaded. Attempting to load it.\n"); - if(!(master_doc = malloc(sizeof(open_doc_t)))){ - error = -ENOMEM; - goto fail; - } - memset(master_doc, 0, sizeof(open_doc_t)); - master_doc->od_doc = xmlParseFile("/etc/cluster/cluster.conf"); - if(!master_doc->od_doc){ - free(master_doc); - master_doc = NULL; - log_err("Unable to parse %s.\n", "/etc/cluster/cluster.conf"); - error = -ENODATA; - goto fail; - } - log_dbg("master_doc found and loaded.\n"); - } else if(update_required){ - log_dbg("Update is required.\n"); - if((error = update_config())){ - log_err("Failed to update config file, required by cluster.\n"); - /* ATTENTION -- remove all open_doc_t's ? */ - goto fail; - } - } - - /* allocates space for the payload */ - xmlDocDumpFormatMemory(master_doc->od_doc, - (xmlChar **)&payload, - &(ch->comm_payload_size), - 0); - if(!ch->comm_payload_size){ - error = -ENOMEM; - log_err("Document dump to memory failed.\n"); - goto fail; - } - - buffer = malloc(ch->comm_payload_size + sizeof(comm_header_t)); - if(!buffer){ - error = -ENOMEM; - goto fail; - } - - if(quorate){ - ch->comm_flags |= COMM_BROADCAST_FROM_QUORATE; - } - - swab_header(ch); - memcpy(buffer, ch, sizeof(comm_header_t)); - swab_header(ch); /* Swab back to dip into ch for payload_size */ - memcpy(buffer+sizeof(comm_header_t), payload, ch->comm_payload_size); - - log_dbg("Sending cluster.conf (version %d)...\n", get_doc_version(master_doc->od_doc)); - sendlen = ch->comm_payload_size + sizeof(comm_header_t); - if(sendto(sfd, buffer, sendlen, 0, - (struct sockaddr *)&addr, (socklen_t)len) < 0){ - log_sys_err("Sendto failed"); - error = -errno; - } - - fail: - if(buffer) free(buffer); - if(payload) free(payload); - if(ch) free(ch); - if(discard){ - if(master_doc && master_doc->od_doc) - xmlFreeDoc(master_doc->od_doc); - if(master_doc) free(master_doc); - master_doc = NULL; - } - EXIT("process_broadcast"); - return error; -} diff --git a/ccs/daemon/cnx_mgr.h b/ccs/daemon/cnx_mgr.h deleted file mode 100644 index 3ca51a8..0000000 --- a/ccs/daemon/cnx_mgr.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __CNX_MGR_DOT_H__ -#define __CNX_MGR_DOT_H__ - -int process_request(int afd); -int process_broadcast(int sfd); - -#endif /* __CNX_MGR_DOT_H__ */ diff --git a/ccs/daemon/globals.c b/ccs/daemon/globals.c deleted file mode 100644 index a5e8205..0000000 --- a/ccs/daemon/globals.c +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> - -int ppid = 0; - -char *config_file_location = NULL; -char *lockfile_location = NULL; - -int frontend_port = 50006; -int backend_port = 50007; -int cluster_base_port = 50008; - -/* -1 = no preference, 0 = IPv4, 1 = IPv6 */ -int IPv6=-1; - -/* 1 = allow and use UNIX domain sockets for local ccs queries */ -int use_local = 1; - -char *multicast_address = NULL; -int ttl=1; diff --git a/ccs/daemon/globals.h b/ccs/daemon/globals.h deleted file mode 100644 index e25bab4..0000000 --- a/ccs/daemon/globals.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __GLOBALS_H__ -#define __GLOBALS_H__ - -#define DEFAULT_CONFIG_LOCATION "/etc/cluster/cluster.conf" -#define DEFAULT_CCSD_LOCKFILE "/var/run/cluster/ccsd.pid" - -#define EXIT_MAGMA_PLUGINS 2 /* Magma plugins are not available */ -#define EXIT_CLUSTER_FAIL 3 /* General failure to connect to cluster */ -#define EXIT_LOCKFILE 4 /* Failed to create lock file */ - -extern int ppid; - -extern char *config_file_location; -extern char *lockfile_location; - -extern int frontend_port; -extern int backend_port; -extern int cluster_base_port; - -extern int IPv6; -extern int use_local; -extern char *multicast_address; -extern int ttl; -#endif /* __GLOBALS_H__ */ diff --git a/ccs/daemon/misc.c b/ccs/daemon/misc.c deleted file mode 100644 index 46c9318..0000000 --- a/ccs/daemon/misc.c +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <pthread.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <libxml/parser.h> -#include <errno.h> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -#include "comm_headers.h" -#include "log.h" -#include "debug.h" -#include "misc.h" - -int quorate = 0; - -int update_required = 0; -pthread_mutex_t update_lock; - -open_doc_t *master_doc = NULL; - -int get_doc_version(xmlDocPtr ldoc){ - int i; - int error = 0; - xmlXPathObjectPtr obj = NULL; - xmlXPathContextPtr ctx = NULL; - xmlNodePtr node = NULL; - - ENTER("get_doc_version"); - - ctx = xmlXPathNewContext(ldoc); - if(!ctx){ - log_err("Error: unable to create new XPath context.\n"); - error = -EIO; /* ATTENTION -- what should this be? */ - goto fail; - } - - obj = xmlXPathEvalExpression("//cluster/@config_version", ctx); - if(!obj || !obj->nodesetval || (obj->nodesetval->nodeNr != 1)){ - log_err("Error while retrieving config_version.\n"); - error = -ENODATA; - goto fail; - } - - node = obj->nodesetval->nodeTab[0]; - if(node->type != XML_ATTRIBUTE_NODE){ - log_err("Object returned is not of attribute type.\n"); - error = -ENODATA; - goto fail; - } - - if(!node->children->content || !strlen(node->children->content)){ - log_dbg("No content found.\n"); - error = -ENODATA; - goto fail; - } - - for(i=0; i < strlen(node->children->content); i++){ - if(!isdigit(node->children->content[i])){ - log_err("config_version is not a valid integer.\n"); - error = -EINVAL; - goto fail; - } - } - error = atoi(node->children->content); - - fail: - if(ctx){ - xmlXPathFreeContext(ctx); - } - if(obj){ - xmlXPathFreeObject(obj); - } - EXIT("get_doc_version"); - return error; -} - - -/** - * get_cluster_name - * @ldoc: - * - * The caller must remember to free the string that is returned. - * - * Returns: NULL on failure, (char *) otherwise - */ -char *get_cluster_name(xmlDocPtr ldoc){ - int error = 0; - char *rtn = NULL; - xmlXPathObjectPtr obj = NULL; - xmlXPathContextPtr ctx = NULL; - xmlNodePtr node = NULL; - - ENTER("get_cluster_name"); - - ctx = xmlXPathNewContext(ldoc); - if(!ctx){ - log_err("Error: unable to create new XPath context.\n"); - error = -EIO; /* ATTENTION -- what should this be? */ - goto fail; - } - - obj = xmlXPathEvalExpression("//cluster/@name", ctx); - if(!obj || !obj->nodesetval || (obj->nodesetval->nodeNr != 1)){ - log_err("Error while retrieving config_version.\n"); - error = -ENODATA; - goto fail; - } - - node = obj->nodesetval->nodeTab[0]; - if(node->type != XML_ATTRIBUTE_NODE){ - log_err("Object returned is not of attribute type.\n"); - error = -ENODATA; - goto fail; - } - - if(!node->children->content || !strlen(node->children->content)){ - log_dbg("No content found.\n"); - error = -ENODATA; - goto fail; - } - - rtn = strdup(node->children->content); - - fail: - if(ctx){ - xmlXPathFreeContext(ctx); - } - if(obj){ - xmlXPathFreeObject(obj); - } - EXIT("get_cluster_name"); - return rtn; -} - - - diff --git a/ccs/daemon/misc.h b/ccs/daemon/misc.h deleted file mode 100644 index e730479..0000000 --- a/ccs/daemon/misc.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __MISC_H__ -#define __MISC_H__ - -typedef struct open_doc { - int od_refs; - xmlDocPtr od_doc; -} open_doc_t; - - -extern int quorate; -extern int update_required; -extern pthread_mutex_t update_lock; -extern open_doc_t *master_doc; - -char *get_cluster_name(xmlDocPtr ldoc); -int get_doc_version(xmlDocPtr ldoc); - - -#endif /* __MISC_H__ */ diff --git a/ccs/include/comm_headers.h b/ccs/include/comm_headers.h deleted file mode 100644 index 0e13ab1..0000000 --- a/ccs/include/comm_headers.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __COMM_HEADERS_DOT_H__ -#define __COMM_HEADERS_DOT_H__ - -#include <byteswap.h> - -/* Types of requests */ -#define COMM_CONNECT 1 -#define COMM_DISCONNECT 2 -#define COMM_GET 3 -#define COMM_GET_LIST 4 -#define COMM_SET 5 -#define COMM_GET_STATE 6 -#define COMM_SET_STATE 7 -#define COMM_BROADCAST 8 -#define COMM_UPDATE 9 - -/* Request flags */ -#define COMM_CONNECT_FORCE 1 -#define COMM_CONNECT_BLOCKING 2 -#define COMM_SET_STATE_RESET_QUERY 4 -#define COMM_BROADCAST_FROM_QUORATE 8 -#define COMM_UPDATE_NOTICE 16 -#define COMM_UPDATE_NOTICE_ACK 32 -#define COMM_UPDATE_COMMIT 64 -#define COMM_UPDATE_COMMIT_ACK 128 - -typedef struct comm_header_s { - int comm_type; - int comm_flags; /* flags that tune a particular type of operation */ - int comm_desc; - int comm_error; - int comm_payload_size; -} comm_header_t; - -#define COMM_LOCAL_SOCKET "/var/run/cluster/ccsd.sock" - -static inline void swab_header(comm_header_t *head) { -#if BYTE_ORDER == BIG_ENDIAN - head->comm_type = bswap_32(head->comm_type); - head->comm_flags = bswap_32(head->comm_flags); - head->comm_desc = bswap_32(head->comm_desc); - head->comm_error = bswap_32(head->comm_error); - head->comm_payload_size = bswap_32(head->comm_payload_size); -#endif -} - -#endif /* __COMM_HEADERS_DOT_H__ */ diff --git a/ccs/include/debug.h b/ccs/include/debug.h deleted file mode 100644 index 176ab48..0000000 --- a/ccs/include/debug.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DEBUG_DOT_H__ -#define __DEBUG_DOT_H__ - -#ifdef DEBUG -#define ENTER(x) log_dbg("Entering %s\n", x) -#define EXIT(x) log_dbg("Exiting %s\n", x) -#else -#define ENTER(x) -#define EXIT(x) -#endif - -#endif /* __DEBUG_DOT_H__ */ diff --git a/ccs/init.d/Makefile b/ccs/init.d/Makefile deleted file mode 100644 index 5e3b1f0..0000000 --- a/ccs/init.d/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= ccsd - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -copytobin: - -clean: - -install: - install -d ${DESTDIR}/etc/init.d - install ${TARGET} ${DESTDIR}/etc/init.d - -uninstall: - ${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d diff --git a/ccs/init.d/ccsd b/ccs/init.d/ccsd deleted file mode 100755 index 57705ab..0000000 --- a/ccs/init.d/ccsd +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -# -# ccsd start/stop ccsd -# -# chkconfig: 345 20 80 -# description: Starts and stops ccsd -# -# -### BEGIN INIT INFO -# Provides: -### END INIT INFO - -CCSD_OPTS= - -. /etc/init.d/functions -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - -LOCK_FILE="/var/lock/subsys/ccsd" - -start() -{ - echo -n "Starting ccsd:" - status ccsd &> /dev/null - if [ $? -ne 0 ] - then - action $"" ccsd $CCSD_OPTS - return $? - fi - success "start" - echo - return 0 -} - -stop() -{ - echo -n "Stopping ccsd:" - for sec in $(seq 1 10) - do - if pidof ccsd > /dev/null - then - # get the pid of ccsd from /var/run/cluster/ccsd.pid - # and break if the file is not there - [ -r /var/run/cluster/ccsd.pid ] || break - - pid=$(cat /var/run/cluster/ccsd.pid ) - kill $pid 2> /dev/null || break - - sleep 1 - else - success "shutdown" - echo - return 0 - fi - done - failure "shutdown" - echo - return 1 -} - -rtrn=1 - -# See how we were called. -case "$1" in - start) - start - rtrn=$? - [ $rtrn = 0 ] && touch $LOCK_FILE - ;; - - stop) - stop - rtrn=$? - [ $rtrn = 0 ] && rm -f $LOCK_FILE - ;; - - restart) - $0 stop - $0 start - rtrn=$? - ;; - - status) - status ccsd - rtrn=$? - ;; - - *) - echo $"Usage: $0 {start|stop|restart|status}" - ;; -esac - -exit $rtrn diff --git a/ccs/lib/Makefile b/ccs/lib/Makefile deleted file mode 100644 index 89570fa..0000000 --- a/ccs/lib/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -INCLUDE = -I../include -I../common - -ifeq ($(DEBUG),y) -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DDEBUG -g -else -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -endif - -all: libccs.a - -copytobin: all - -libccs.a: libccs.o log.o - ${AR} cr libccs.a libccs.o log.o - -libccs.o: libccs.c - ${CC} -c ${CFLAGS} ${INCLUDE} $^ - -log.o: ../common/log.c - ${CC} -c ${CFLAGS} ${INCLUDE} $^ - -install: libccs.a ccs.h - install -d ${libdir} - install -m644 libccs.a ${libdir} - install -d ${incdir} - install -m644 ccs.h ${incdir} - -uninstall: - ${UNINSTALL} libccs.a ${libdir} - ${UNINSTALL} ccs.h ${incdir} - rm -f /lib/libccs.a - -clean: - rm -rf *~ *.o libccs.a - diff --git a/ccs/lib/ccs.h b/ccs/lib/ccs.h deleted file mode 100644 index 36b5c6a..0000000 --- a/ccs/lib/ccs.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __CCS_DOT_H__ -#define __CCS_DOT_H__ - -int ccs_connect(void); -int ccs_force_connect(char const *cluster_name, int blocking); -int ccs_disconnect(int desc); -int ccs_get(int desc, const char *query, char **rtn); -int ccs_get_list(int desc, const char *query, char **rtn); -int ccs_set(int desc, const char *path, char *val); -int ccs_get_state(int desc, char **cw_path, char **prev_query); -int ccs_set_state(int desc, const char *cw_path, int reset_query); - -#endif /* __CCS_DOT_H__ */ diff --git a/ccs/lib/libccs.c b/ccs/lib/libccs.c deleted file mode 100644 index c8dbf04..0000000 --- a/ccs/lib/libccs.c +++ /dev/null @@ -1,625 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <stdlib.h> -#include <sys/types.h> -#include <unistd.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <errno.h> - -#include "log.h" /* Libraries should not print - so only use log_dbg */ -#include "debug.h" -#include "comm_headers.h" - -#include <stdio.h> - -static int fe_port = 50006; -static int comm_proto=-1; - -static int setup_interface_ipv6(int *sp, int port){ - int sock = -1; - int error = 0; - struct sockaddr_in6 addr; - int trueint = 1; - - ENTER("setup_interface_ipv6"); - memset(&addr, 0, sizeof(struct sockaddr_in6)); - - sock = socket(PF_INET6, SOCK_STREAM, 0); - if(sock < 0){ - error = -errno; - goto fail; - } - - if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int))){ - log_sys_err("Unable to set socket option SO_REUSEADDR"); - log_err("This may slow things down a bit.\n"); - } - - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(port); - addr.sin6_addr = in6addr_loopback; - - if(bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6))){ - log_dbg("Unable to (pre)bind to port %d: %s\n", port, strerror(errno)); - error = -errno; - goto fail; - } - - addr.sin6_family = AF_INET6; - addr.sin6_addr = in6addr_any; - addr.sin6_port = htons(fe_port); - error = connect(sock, (struct sockaddr *)&addr, - sizeof(struct sockaddr_in6)); - if(error < 0){ - log_dbg("Unable to connect to server: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - - *sp = sock; - EXIT("setup_interface_ipv6"); - return 0; - - fail: - if(sock >= 0){ - close(sock); - } - EXIT("setup_interface_ipv6"); - return error; -} - -static int setup_interface_ipv4(int *sp, int port){ - int sock = -1; - int error = 0; - struct sockaddr_in addr; - - ENTER("setup_interface_ipv4"); - - memset(&addr, 0, sizeof(struct sockaddr_in)); - sock = socket(PF_INET, SOCK_STREAM, 0); - if(sock < 0){ - error = -errno; - goto fail; - } - - addr.sin_family = AF_INET; - inet_aton("127.0.0.1", (struct in_addr *)&addr.sin_addr.s_addr); - addr.sin_port = htons(port); - - if(bindresvport(sock, &addr)){ - log_dbg("Unable to bindresvport: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(fe_port); - error = connect(sock, (struct sockaddr *)&addr, - sizeof(struct sockaddr_in)); - if(error < 0){ - log_dbg("Unable to connect to server: %s\n", strerror(errno)); - error = -errno; - goto fail; - } - - *sp = sock; - EXIT("setup_interface_ipv4"); - return 0; - - fail: - if(sock >= 0){ - close(sock); - } - EXIT("setup_interface_ipv4"); - return error; -} - - -int -setup_interface_local(int *sp) -{ - struct sockaddr_un sun; - int sock = -1, error = 0; - - ENTER("setup_interface_local"); - sun.sun_family = PF_LOCAL; - snprintf(sun.sun_path, sizeof(sun.sun_path), COMM_LOCAL_SOCKET); - - sock = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) { - error = errno; - goto fail; - } - - error = connect(sock, (struct sockaddr *)&sun, sizeof(sun)); - if (error < 0) { - error = errno; - goto fail; - } - - *sp = sock; - EXIT("setup_interface_local"); - return PF_LOCAL; - -fail: - if (sock >= 0){ - close(sock); - } - EXIT("setup_interface_local"); - return -error; -} - - -/** - * setup_interface - * @sp: pointer gets filled in with open socket - * - * This function (through helper functions) handles the details - * of creating and binding a socket followed be the connect. - * - * Returns: AF_INET | AF_INET6 on success, or -errno on error - */ -static int setup_interface(int *sp){ - int error=-1; - int res_port = IPPORT_RESERVED-1; - int timo=1; - int ipv4 = (comm_proto < 0) ? 1 : (comm_proto == PF_INET); - int ipv6 = (comm_proto < 0) ? 1 : (comm_proto == PF_INET6); - int local = (comm_proto < 0) ? 1 : (comm_proto == PF_LOCAL); - - ENTER("setup_interface"); - srandom(getpid()); - - /* Try to do a local connect first */ - if (local && !(error = setup_interface_local(sp))) - error = PF_LOCAL; - - if (error < 0) { - for(; res_port >= 512; res_port--){ - if (ipv6 && !(error = setup_interface_ipv6(sp, res_port))){ - error = PF_INET6; - break; - } else if (ipv4 && !(error = setup_interface_ipv4(sp, res_port))){ - error = PF_INET; - break; - } - if(error == -ECONNREFUSED){ - break; - } - - /* Connections could have colided, giving ECONNREFUSED, or ** - ** the port we are trying to bind to may already be in use ** - ** and since we don't want to collide again, wait a random ** - ** amount of time......................................... */ - timo = random(); - timo /= (RAND_MAX/4); - sleep(timo); - } - } - EXIT("setup_interface"); - return error; -} - - -/** - * do_request: send request an receive results - * @buffer: package to send - * - * This function does not interpret the contents of the package, except - * to check the 'comm_err' field. - * - * Returns: 0 on success, < 0 on error - */ -static int do_request(char *buffer){ - int error=0; - int sock=-1; - char *proto; - comm_header_t *ch = (comm_header_t *)buffer; - - ENTER("do_request"); - - if((error = setup_interface(&sock)) < 0){ - goto fail; - } - - /* In the future, we will only try the protocol that worked first */ - if (comm_proto < 0){ - if (error == AF_INET) { - proto = "IPv4"; - } else if (error == AF_INET6) { - proto = "IPv6"; - } else if (error == PF_LOCAL) { - proto = "Local Domain"; - } else { - proto = "Unknown"; - } - - comm_proto = error; - log_dbg("Protocol set to %s.\n", proto); - } - - error = write(sock, buffer, sizeof(comm_header_t)+ch->comm_payload_size); - if(error < 0){ - log_dbg("Write to socket failed.\n"); - goto fail; - } else if(error < (sizeof(comm_header_t)+ch->comm_payload_size)){ - log_dbg("Failed to write full package to socket.\n"); - error = -EBADE; - goto fail; - } - - /* ok to take in two passes ? */ - error = read(sock, buffer, sizeof(comm_header_t)); - if(error < 0){ - log_dbg("Read from socket failed.\n"); - goto fail; - } else if(error < sizeof(comm_header_t)){ - log_dbg("Failed to read complete comm_header_t.\n"); - error = -EBADE; - goto fail; - } else if(ch->comm_error){ - log_dbg("Server reports failure: %s\n", strerror(-ch->comm_error)); - error = ch->comm_error; - goto fail; - } else { - error = 0; - } - if(ch->comm_payload_size){ - error = read(sock, buffer+sizeof(comm_header_t), ch->comm_payload_size); - if(error < 0){ - log_dbg("Read from socket failed.\n"); - goto fail; - } else if(error < ch->comm_payload_size){ - log_dbg("Failed to read complete payload.\n"); - error = -EBADE; - goto fail; - } else { - error = 0; - } - } - fail: - if(sock >= 0) { close(sock); } - EXIT("do_request"); - return error; -} - - -/** -* _ccs_connect -* @cluster_name: name of the cluster (optional) -* @flags: blocking or force -* -* This function will return a descriptor on success that should be -* used with the other functions for proper operation. -* -* Returns: >= 0 on success, < 0 on error -*/ -int _ccs_connect(const char *cluster_name, int flags){ - int error = 0; - char *buffer = NULL; - comm_header_t *ch = NULL; - char *payload = NULL; - - ENTER("ccs_connect"); - - if(!(buffer = malloc(512))){ - error = -ENOMEM; - goto fail; - } - - memset(buffer, 0, 512); - ch = (comm_header_t *)buffer; - payload = (buffer + sizeof(comm_header_t)); - - ch->comm_type = COMM_CONNECT; - if(flags & COMM_CONNECT_BLOCKING){ - ch->comm_flags |= COMM_CONNECT_BLOCKING; - } - - if(flags & COMM_CONNECT_FORCE){ - ch->comm_flags |= COMM_CONNECT_FORCE; - } - - if(cluster_name){ - ch->comm_payload_size = strlen(cluster_name)+1; - if(ch->comm_payload_size > (512 - sizeof(comm_header_t))){ - error = -ENAMETOOLONG; - goto fail; - } - - strcpy(payload, cluster_name); /* already checked if it will fit */ - } - - if(!(error = do_request(buffer))){ - /* Not an error, just reusing the 'error' variable */ - error = ch->comm_desc; - } - - fail: - if(buffer) { free(buffer); } - EXIT("ccs_connect"); - return error; -} - - -/** - * ccs_connect - * - * This function will only allow a connection if the node is part of - * a quorate cluster. - * - * Returns: ccs_desc on success, < 0 on failure - */ -int ccs_connect(void){ - return _ccs_connect(NULL, 0); -} - - -/** - * ccs_force_connect - * - * This function will only allow a connection even if the node is not - * part of a quorate cluster. It will use the configuration file - * located in /etc/cluster/cluster.conf. If that file does not exist, - * a copy of the file will be broadcasted for. If blocking is specified, - * the broadcasts will be retried until a config file is located. Otherwise, - * the fuction will return an error if the initial broadcast is not successful. - * - * Returns: ccs_desc on success, < 0 on failure - */ -int ccs_force_connect(const char *cluster_name, int blocking){ - if(blocking){ - return _ccs_connect(cluster_name, COMM_CONNECT_FORCE | COMM_CONNECT_BLOCKING); - } else { - return _ccs_connect(cluster_name, COMM_CONNECT_FORCE); - } -} - - -/** - * ccs_disconnect - * @desc: the descriptor returned by ccs_connect - * - * This function frees all associated state kept with an open connection - * - * Returns: 0 on success, < 0 on error - */ -int ccs_disconnect(int desc){ - int error = 0; - char *buffer = NULL; - comm_header_t *ch = NULL; - char *payload = NULL; - - ENTER("ccs_disconnect"); - - if(!(buffer = malloc(512))){ - error = -ENOMEM; - goto fail; - } - - memset(buffer, 0, 512); - ch = (comm_header_t *)buffer; - payload = (buffer + sizeof(comm_header_t)); - - ch->comm_type = COMM_DISCONNECT; - ch->comm_desc = desc; - - error = do_request(buffer); - - fail: - if(buffer) { free(buffer); } - - EXIT("ccs_disconnect"); - return error; -} - - -/** - * _ccs_get - * @desc: - * @query: - * @rtn: value returned - * @list: 1 to operate in list fashion - * - * This function will allocate space for the value that is the result - * of the given query. It is the user's responsibility to ensure that - * the data returned is freed. - * - * Returns: 0 on success, < 0 on failure - */ -int _ccs_get(int desc, const char *query, char **rtn, int list){ - int error = 0; - char *buffer = NULL; - comm_header_t *ch = NULL; - char *payload = NULL; - - ENTER("_ccs_get"); - - if(!(buffer = malloc(512))){ - error = -ENOMEM; - goto fail; - } - - memset(buffer, 0, 512); - ch = (comm_header_t *)buffer; - payload = (buffer + sizeof(comm_header_t)); - - log_dbg("ccs_get list? %s\n", (list)?"YES":"NO"); - ch->comm_type = (list)?COMM_GET_LIST:COMM_GET; - ch->comm_desc = desc; - - ch->comm_payload_size = sprintf(payload, "%s", query)+1; - - error = do_request(buffer); - - if(!error){ - if(ch->comm_payload_size){ - *rtn = (char *)strdup(payload); - if(!*rtn){ error = -ENOMEM; } - } else { - *rtn = NULL; - } - } - - fail: - if(buffer) { free(buffer); } - - EXIT("_ccs_get"); - return error; -} - -int ccs_get(int desc, const char *query, char **rtn){ - return _ccs_get(desc, query, rtn, 0); -} - -int ccs_get_list(int desc, const char *query, char **rtn){ - return _ccs_get(desc, query, rtn, 1); -} - - -/** - * ccs_set: set an individual element's value in the config file. - * @desc: - * @path: - * @val: - * - * This function is used to update individual elements in a config file. - * It's effects are cluster wide. It only succeeds when the node is part - * of a quorate cluster. - * - * Note currently implemented. - * - * Returns: 0 on success, < 0 on failure - */ -int ccs_set(int desc, const char *path, char *val){ - ENTER("ccs_set"); - EXIT("ccs_set"); - return -ENOSYS; -} - - -/** - * ccs_get_state: return the stored state of the connection - * @desc: - * @cw_path: - * @prev_query: - * - * This function will return the current working path and the - * previous query. It is the user's responsibility to free - * both returned values. - * - * Returns: 0 on success, < 0 on failure - */ -int ccs_get_state(int desc, char **cw_path, char **prev_query){ - int error = 0; - char *buffer = NULL; - comm_header_t *ch = NULL; - char *payload = NULL; - - ENTER("ccs_get_state"); - - if(!(buffer = malloc(512))){ - error = -ENOMEM; - goto fail; - } - - *cw_path = *prev_query = NULL; - - memset(buffer, 0, 512); - ch = (comm_header_t *)buffer; - payload = (buffer + sizeof(comm_header_t)); - - ch->comm_type = COMM_GET_STATE; - ch->comm_desc = desc; - - error = do_request(buffer); - if(!error){ - *cw_path = (char *)strdup(payload); - if(!*cw_path){ - error = -ENOMEM; - goto fail; - } - *prev_query = (char *)strdup(payload+strlen(payload)+1); - if(!*prev_query){ - error = -ENOMEM; - free(*cw_path); - *cw_path = NULL; - goto fail; - } - } - - fail: - if(buffer) { free(buffer); } - - EXIT("ccs_get_state"); - return error; -} - - -/** - * ccs_set_state - * @desc: - * @cw_path: - * @reset_query: - * - * This function allows the user to specify a current working path, - * from which all later queries will be relative. It also allows the - * user to erase memory of the last query - useful if the user wanted - * to reset the index of a list to 0. - * - * Returns: 0 on success, < 0 on failure - */ -int ccs_set_state(int desc, const char *cw_path, int reset_query){ - int error = 0; - char *buffer = NULL; - comm_header_t *ch = NULL; - char *payload = NULL; - - ENTER("ccs_set_state"); - - if(!(buffer = malloc(512))){ - error = -ENOMEM; - goto fail; - } - - memset(buffer, 0, 512); - ch = (comm_header_t *)buffer; - payload = (buffer + sizeof(comm_header_t)); - - ch->comm_type = COMM_SET_STATE; - ch->comm_desc = desc; - - if(reset_query){ - ch->comm_flags |= COMM_SET_STATE_RESET_QUERY; - } - - if(strlen(cw_path)+1 > 512-sizeof(comm_header_t)){ - error = -ENAMETOOLONG; - goto fail; - } - - /* sprintf does not include trailing \0 */ - ch->comm_payload_size = sprintf(payload, "%s", cw_path) + 1; - - error = do_request(buffer); - - fail: - if(buffer) { free(buffer); } - - EXIT("ccs_set_state"); - return error; -} diff --git a/ccs/make/defines.mk.input b/ccs/make/defines.mk.input deleted file mode 100644 index 33522f9..0000000 --- a/ccs/make/defines.mk.input +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall -ggdb ${INCLUDE} diff --git a/ccs/make/release.mk.input b/ccs/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/ccs/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/ccs/man/Makefile b/ccs/man/Makefile deleted file mode 100644 index e9b8150..0000000 --- a/ccs/man/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -install: - install -d ${mandir}/man5 - install -d ${mandir}/man7 - install -d ${mandir}/man8 - install cluster.conf.5 ${mandir}/man5 - install ccs.7 ${mandir}/man7 - install ccsd.8 ccs_test.8 ccs_tool.8 ${mandir}/man8 - -uninstall: - ${UNINSTALL} cluster.conf.5 ${mandir}/man5 - ${UNINSTALL} ccs.7 ${mandir}/man7 - ${UNINSTALL} ccsd.8 ccs_test.8 ccs_tool.8 ${mandir}/man8 - diff --git a/ccs/man/ccs.7 b/ccs/man/ccs.7 deleted file mode 100644 index a31f86b..0000000 --- a/ccs/man/ccs.7 +++ /dev/null @@ -1,50 +0,0 @@ -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH ccs 7 - -.SH NAME -ccs - Cluster Configuration System - -.SH DESCRIPTION -A cluster environment that shares resources has information that is -essential to correct operation which must be available to -every node in the cluster. This information may include: -names of the nodes composing the cluster, I/O fencing methods, and -more. \fICCS\fP is the system that makes it possible for the nodes in a -cluster to retrieve the information they need. - -.SH OVERVIEW -The following is a generic description of the steps one should take to produce -a working CCS environment. - -.SS Step 1 -Choose a cluster name. It is important to determine -a name for the cluster before starting. The cluster name is what -binds a machine to specific resources that can only be shared by -machines that are members of the same cluster name. - -.SS Step 2 -Create the directory \fI/etc/cluster\fP. - -.SS Step 3 -Create the \fI/etc/cluster/cluster.conf\fP file, according to the -\fBcluster.conf(5)\fP man page, on one node in your cluster. - -.SS Step 4 -Start \fBccsd\fP and test the cluster.conf file by using \fBccs_test\fP. -If you haven't started a cluster manager yet, you should use the 'force' -option to \fBccs_test\fP - see the \fBccs_test(8)\fP man page for more info. - -If a failure occurs while parsing the config file, \fBccs_test\fP should -report "ccs_connect failed: No data available" and /var/log/messages -should report "Unable to parse /etc/cluster/cluster.conf". - -.SH FORMAT OF THE CCS FILE -See \fBcluster.conf(5)\fP - -.SH SEE ALSO -ccsd(8), ccs_tool(8), ccs_test(8), cluster.conf(5) diff --git a/ccs/man/ccs_test.8 b/ccs/man/ccs_test.8 deleted file mode 100644 index 1ffe9ea..0000000 --- a/ccs/man/ccs_test.8 +++ /dev/null @@ -1,140 +0,0 @@ -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH ccs_test 8 - -.SH NAME -ccs_test - The diagnostic tool for a running Cluster Configuration System. - -.SH SYNOPSIS -.B ccs_test -[\fBoptions\fP] -<\fBcommand\fP> - -.SH DESCRIPTION -\fBccs_test\fP is part of the Cluster Configuration System (CCS). It -is a diagnostic tool designed to validate the correct operation of a -running CCS system. It will communicate with the CCS daemon - \fBccsd\fP - -to obtain any information stored in the system. - -.SH OPTIONS -.TP -\fB-h\fP -Help. Print out the usage syntax and exit. -.TP -\fB-V\fP -Print the version information and exit. - -.SH COMMANDS -.TP -\fBconnect\fP \fI[force]\fP \fI[block]\fP \fI[cluster name]\fP -This command creates a connection to ccsd. It returns a descriptor, which -is used as an parameter to other commands. - -The 'force' key-word is used to establish a connection to ccsd in the -absence of a quorate cluster manager. - -The 'block' key-word is used (with the 'force' key-word) to tell ccsd to -keep broadcasting for a valid configuration file until one is found. - -The 'cluster name' is used (with the 'force' key-word) to specify that -only configuration files containing the given cluster name are valid -possibilities. - -.TP -\fBget\fP \fI<desc>\fP \fI<request>\fP -Get the results of a given request. The 'desc' is the number returned -from the \fBconnect\fP command. The 'request' is a valid Xpath request. - -If 'request' results in multiple matches, the first will be returned. -Subsequent calls with the same 'request' will result in the subsequent -matches. Once all the matches have been returned, a subsequent call -will begin again with the first result. - -.TP -\fBget_list\fP \fI<desc>\fP \fI<request>\fP -Similar to the \fBget\fP command. However, issuing subsequent calls -with the same 'request' will result in all matches being returned (one -at a time), then null, then starting over with the first result. - -.TP -\fBset\fP \fI<desc>\fP \fI<path>\fP \fI<value>\fP -Sets a particular 'path' to the given 'value'. Not yet implemented. - -.TP -\fBget_state\fP \fI<desc>\fP -Get the state associated with a given connection. - -.TP -\fBset_state\fP \fI<desc>\fP \fI<ncwp>\fP -Set the current working path (cwp) to 'ncwp' for a given connection. - -.SH EXAMPLES -.SS To connect to ccsd: - -> ccs_test connect - -Connect successful. - Connection descriptor = 0 - -Or, if the cluster is not yet quorate and the name of the cluster is 'mycluster': - -> ccs_test connect force block mycluster - -Connect successful. - Connection descriptor = 0 - -.SS To get the cluster name from ccsd: - -> ccs_test get 0 /cluster/@name - -Get successful. - Value = <mycluster> - -.SS To get the connection state: - -> ccs_test get_state 0 - -Get state successful. - Current working path: - Previous query : /cluster/@name - - -.SS To set the connection state: - -> ccs_test set_state 0 /cluster - -Set state successful. - - -.SS After setting the connection state, note the change: - -> ccs_test get_state 0 - -Get state successful. - Current working path: /cluster - Previous query : /cluster/@name - -.SS After setting the connection state, you can now query with an absolute or relative path: - -> ccs_test get 0 @name - -Get successful. - Value = <brassow> - -> ccs_test get 0 /cluster/@name - -Get successful. - Value = <brassow> - -.SS To disconnect: - -> ccs_test disconnect 0 - -Disconnect successful. - -.SH SEE ALSO -ccs(7), ccsd(8), cluster.conf(5) diff --git a/ccs/man/ccs_tool.8 b/ccs/man/ccs_tool.8 deleted file mode 100644 index a767699..0000000 --- a/ccs/man/ccs_tool.8 +++ /dev/null @@ -1,219 +0,0 @@ -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH ccs_tool 8 - -.SH NAME -ccs_tool - The tool used to make online updates of CCS config files. - -.SH SYNOPSIS -.B ccs_tool -[\fIOPTION\fR].. <\fBcommand\fP> - -.SH DESCRIPTION -\fBccs_tool\fP is part of the Cluster Configuration System (CCS). It -is used to make online updates of CCS config files. Additionally, it -can be used to upgrade old style (GFS <= 6.0) CCS archives to the new -xml format. - -.SH OPTIONS -.TP -\fB-h\fP -Help. Print out the usage. -.TP -\fB-V\fP -Print the version information. - -.SH COMMANDS -.TP -\fBaddfence\fP [\fIOPTION\fR].. <\fBname\fP> <\fBagent\fP> [\fIparam=value\fR].. -Add a new fencing agent to the cluster. - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-o --outputfile\fP -Name of output file (defaults to same as \fB--configfile\fP). - -\fB-C --no_ccs\fP -Don't tell CCSD about this change. -(default: run \fBccs_tool update\fP if file is updated in place) - -\fB-F --force_ccs\fP -Force \fBccs_tool update\fP even if input & output files differ. - -\fB-h --help\fP -Display this help text for \fBccs_tool addfence\fP. - -\fBExample:\fP - ccs_tool addfence apc fence_apc ipaddr=apc.domain.net user=apc password=apc -.TP - -\fBaddnode\fP [\fIOPTION\fR].. <\fBnodename\fP> [\fI<fencearg>=<value>\fR].. -Add a new node to the cluster. - -\fB-v --votes\fP -Number of votes for this node. - -\fB-n --nodeid\fP -Nodeid (optional) - -\fB-i --interface\fP -Interface name (needed if multicast is used) - -\fB-m --multicast\fP -Multicast address (only needed for first node in a cman multicast cluster) - -\fB-f --fence_type\fP -Type of fencing to use - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-o --outputfile\fP -Name of output file (defaults to same as \fB--configfile\fP). - -\fB-C --no_ccs\fP -Don't tell CCSD about this change. -(default: run \fBccs_tool update\fP if file is updated in place) - -\fB-F --force_ccs\fP -Force \fBccs_tool update\fP even if input & output files differ. - -\fB-h --help\fP -Display this help text for \fBccs_tool addnode\fP. - -\fBExamples:\fP - -Add a new node to default configuration file: - ccs_tool addnode -v 1 -f manual ipaddr=newnode - -Add a new node and dump config file to stdout rather than save it - ccs_tool addnode -v 1 -f apc -i eth0 -o - newnode.temp.net port=1 -.TP - -\fBcreate\fP [\fI-2\fR] <\fBclustername\fP> - -\fB-2\fP -Create a 2-node cman cluster config file. - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-h --help\fP -Display this help text for \fBccs_tool create\fP. - -Note that \fBcreate\fP on its own will not create a valid configuration file. -Fence agents and nodes will need to be added to it before handing it over -to ccsd. - -\fBExample\fP: - ccs_tool create MyCluster - ccs_tool addfence apc fence_apc ipaddr=apc.domain.net user=apc password=apc - ccs_tool addnode node1 -v 1 -f apc port=1 - ccs_tool addnode node2 -v 1 -f apc port=2 - ccs_tool addnode node3 -v 1 -f apc port=3 - ccs_tool addnode node4 -v 1 -f apc port=4 -.TP - -\fBdelfence\fP [\fIOPTION\fR].. <\fBfencename\fP> - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-o --outputfile\fP -Name of output file (defaults to same as \fB--configfile\fP). - -\fB-C --no_ccs\fP -Don't tell CCSD about this change. -(default: run \fBccs_tool update\fP if file is updated in place) - -\fB-F --force_ccs\fP -Force \fBccs_tool update\fP even if input & output files differ. - -\fB-h --help\fP -Display this help text for \fBccs_tool delfence\fP. - -\fBdelfence\fP will allow you to remove a fence device that is in use by nodes. -This is to allow changes to be made, but be aware that it may produce an -invalid configuration file if you don't add it back in again. -.TP - -\fBdelnode\fP [\fIOPTION\fR].. <\fBnodename\fP> - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-o --outputfile\fP -Name of output file (defaults to same as \fB--configfile\fP). - -\fB-C --no_ccs\fP -Don't tell CCSD about this change. -(default: run \fBccs_tool update\fP if file is updated in place) - -\fB-F --force_ccs\fP -Force \fBccs_tool upgdate\fP even if input & output files differ. - -\fB-h --help\fP -Display this help text for \fBccs_tool delnode\fP. -.TP - -\fBhelp\fP -Prints the usage help. Same as \fBccs_tool -h\fP. -.TP - -\fBlsfence\fP [\fIOPTION\fR].. - -\fB-v --verbose\fP -Print all properties of the item. - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-h --help\fP -Display this help text for \fBccs_tool lsfence\fP. -.TP - -\fBlsnode\fP [\fIOPTION\fR].. - -\fB-v --verbose\fP -Print all properties of the item. - -\fB-c --configfile\fP -Name of configuration file (/etc/cluster/cluster.conf). - -\fB-h --help\fP -Display this help text for \fBccs_tool lsnode\fP. - -.TP -\fBaddnodeids\fP -Adds node ID numbers to all the nodes in cluster.conf. In RHEL4, node IDs were optional -and assigned by cman when a node joined the cluster. In RHEL5 they must be pre-assigned -in cluster.conf. This command will not change any node IDs that are already set in -cluster.conf, it will simply add unique node ID numbers to nodes that do not already -have them. - -.TP -\fBupdate\fP \fI<xml file>\fP -This command is used to update the config file that ccsd is working with -while the cluster is operational (i.e. online). Run this on a single -machine to update all instances of ccsd across the cluster. - -If you are using 'cman' as your cluster manager, you will also need to -run \fBcman_tool version -r <new version number>\fP once the update is -complete. Failure to do so will result in new nodes (or nodes rejoining -after a failure) not being allowed -to join the working set due to version number mismatches. -.TP -\fBupgrade\fP \fI<location>\fP -This command is used to upgrade an old CCS format archive to the new -xml format. \fI<location>\fP is the location of the old archive, -which can be either a block device archive or a file archive. The -converted configuration will be printed to stdout. -.TP - -.SH SEE ALSO -ccs(7), ccsd(8), cluster.conf(5) diff --git a/ccs/man/ccsd.8 b/ccs/man/ccsd.8 deleted file mode 100644 index 8ec26c4..0000000 --- a/ccs/man/ccsd.8 +++ /dev/null @@ -1,69 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH ccsd 8 - -.SH NAME -ccsd - The daemon used to access CCS cluster configuration files. - -.SH SYNOPSIS -.B ccsd -[\fIOPTION\fR].. - -.SH DESCRIPTION -\fBccsd\fP is part of the Cluster Configuration System (CCS). It is the -daemon which accesses cluster the configuration file for other cluster -applications. It must be run on each node that wishes to join a cluster. - -.SH OPTIONS -.TP -\fB-4\fP -Use IPv4 for inter-node communication. By default, IPv6 is tried, then IPv4. -.TP -\fB-6\fP -Use IPv6 for inter-node communication. By default, IPv6 is tried, then IPv4. -.TP -\fB-I\fP -Force use of IP for local communication (disables use of UNIX domain sockets). -If set, \fBccsd\fP will use the specified inter-node communication protocol -(see the \fB-4\fP and \fB-6\fP options). If one is not specified, -IPv6 is tried, then IPv4. For backward compatibility, IP connections are -still allowed even when UNIX domain sockets are available. -.TP -\fB-h\fP -Help. Print out the usage syntax. -.TP -\fB-m <multicast address>\fP -Used to specify the multicast address. The keyword "default" can be used, -in which case "ff02::3:1" is used for IPv6 and "224.0.2.5" is used for IPv4. - -If you are using IPv4, the default action is to use broadcast. Specifying -this option will cause multicast to be used in that instance. -.TP -\fB-n\fP -No daemon. Run in the foreground. -.TP -\fB-P <port identifier>:<port number>\fP -You have the option of specifying the port numbers used by ccsd. The port -identifier is either: b, c, or f. "b" is the port which ccsd attempts to -communicate with ccsd processes on other machines, via broadcast/multicast, to -obtain or validate its config file (cluster.conf). This is known as the backend -port. "c" is the base port number of two consecutive ports used by ccsd -processes to communicate cluster membership information. This is known as the -cluster base port. "f" is the port number that listens for information requests -from the CCS library (or programs using it). This is known as the frontend port. - -So, to change the frontend port one might specify \fI-P f:60000\fP. -.TP -\fB-t <ttl>\fP -Set the multicast threshold (aka time to live). -.TP -\fB-V\fP -Print the version information. - -.SH SEE ALSO -ccs(7), ccs_tool(8), ccs_test(8), cluster.conf(5) diff --git a/ccs/man/cluster.conf.5 b/ccs/man/cluster.conf.5 deleted file mode 100644 index 76948b1..0000000 --- a/ccs/man/cluster.conf.5 +++ /dev/null @@ -1,184 +0,0 @@ -." -." Copyright 2001-2003 Sistina Software, Inc. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH cluster.conf 5 - -.SH NAME -cluster.conf - The configuration file for cluster products - -.SH DESCRIPTION -The \fBcluster.conf\fP file is located in the /etc/cluster directory. It -is the source of information used by the cluster products - accessed -indirectly through CCS (see \fBccs(7)\fP). This file contains all the -information needed for the cluster to operate, such as: what nodes compose -the cluster and how to I/O fence those nodes. There is generic information -which is applicable to all cluster infrastructures, as well as specific -information relevent for specific cluster products. - -This man page describes the generic contents of the \fBcluster.conf\fP file. -The product specific sections of \fBcluster.conf\fP are left to their -respective man pages. For example, after constructing the generic content, -a user would look at the \fBlock_gulmd(5)\fP man page for specific instructions -if using lock_gulmd as their lock server. Conversely, a user employing -\fBcman\fP and the \fBdlm\fP would look at \fBcman(5)\fP and \fBdlm(5)\fP for -further instruction. - -The \fBcluster.conf\fP file is an XML file. It has one encompasing section -in which everything is contained. That entity's name is \fIcluster\fP and it -has two manditory attributes: \fIname\fP and \fIconfig_version\fP. The -\fIname\fP attribute specifies the name of the cluster. It is important -that this name is unique from other clusters the user might set up. The -\fIconfig_version\fP attribute is a number used to identify the revision -level of the \fBcluster.conf\fP file. Given this information, your -\fBcluster.conf\fP file might look something like: - -<cluster name="alpha" config_version="1"> - -</cluster> - -A manditory subsection of \fIcluster\fP is \fIfencedevices\fP. It contains -all of the I/O fencing devices at the disposal of the cluster. The I/O -fencing devices are listed as entities designated as \fIfencedevice\fP and have -attributes that describe the particular fencing device. For example: - - <fencedevices> - <fencedevice name="apc" agent="fence_apc" - ipaddr="apc_1" login="apc" passwd="apc"/> - </fencedevices> - -Concerning the \fIfencedevice\fP entity, the \fIname\fP and \fIagent\fP attributes -must be specified for all I/O fence devices. The remaining attributes are -device specific and are used to specify the neccessary information to -access the device. The \fIname\fP attribute must be unique and is used to -reference the I/O fence device in other sections of the \fBcluster.conf\fP file. The \fIagent\fP attribute is used to specify the binary fence agent program used to communicate with the particular device. Your \fBcluster.conf\fP file might now look something like: - -<cluster name="alpha" config_version="1"> - <fencedevices> - <fencedevice name="apc" agent="fence_apc" - ipaddr="apc_1" login="apc" passwd="apc"/> - - <fencedevice name="brocade" agent="fence_brocade" - ipaddr="brocade_1" login="bro" passwd="bro"/> - - <!-- The WTI fence device requires no login name --> - <fencedevice name="wti" agent="fence_wti" - ipaddr="wti_1" passwd="wti"/> - - <fencedevice name="last_resort" agent="fence_manual"/> - </fencedevices> -</cluster> - -The final manditory subsection of \fIcluster\fP is \fIclusternodes\fP. It contains -the individual specification of all the machines (members) in the cluster. -Each machine has it's own section, \fIclusternode\fP, which has the \fIname\fP -attribute - this should be the name of the machine. The \fIclusternode\fP section -also contains the \fIfence\fP section. Not to be confused with \fIfencedevices\fP the \fIfence\fP section is used to specify all the possible "methods" for -fencing a particular machine, as well as the device used to perform that method -and the machine specific parameters neccessary. By example, the \fIclusternodes\fP -section may look as follows: - - <!-- This example only contains one machine --> - <clusternodes> - <clusternode name="nd01"> - <fence> - <!-- "power" method is tried before all others --> - <method name="power"> - <device name="apc" port="1:1"/> - </method> - <!-- If the "power" method fails, - try fencing through the "fabric" --> - <method name="fabric"> - <device name="brocade" port="1"/> - </method> - <!-- If all else fails, - make someone do it manually --> - <method name="human"> - <device name="last_resort" ipaddr="nd01"/> - </method> - </fence> - </clusternode> - </clusternodes> - -Putting it all together, a three node cluster's \fBcluster.conf\fP file -might look like: - - -<cluster name="example" config_version="1"> - <clusternodes> - <clusternode name="nd01"> - <fence> - <!-- "power" method is tried before all others --> - <method name="power"> - <device name="apc" port="1:1"/> - </method> - <!-- If the "power" method fails, - try fencing through the "fabric" --> - <method name="fabric"> - <device name="brocade" port="1"/> - </method> - <!-- If all else fails, - make someone do it manually --> - <method name="human"> - <device name="last_resort" ipaddr="nd01"/> - </method> - </fence> - </clusternode> - <clusternode name="nd02"> - <fence> - <!-- "power" method is tried before all others --> - <method name="power"> - <device name="apc" port="1:2"/> - </method> - <!-- If the "power" method fails, - try fencing through the "fabric" --> - <method name="fabric"> - <device name="brocade" port="2"/> - </method> - <!-- If all else fails, - make someone do it manually --> - <method name="human"> - <device name="last_resort" ipaddr="nd02"/> - </method> - </fence> - </clusternode> - <clusternode name="nd11"> - <fence> - <!-- "power" method is tried before all others --> - <method name="power"> - <!-- This machine has 2 power supplies --> - <device name="apc" port="2:1"/> - <device name="wti" port="1"/> - </method> - <!-- If the "power" method fails, - try fencing through the "fabric" --> - <method name="fabric"> - <device name="brocade" port="11"/> - </method> - <!-- If all else fails, - make someone do it manually --> - <method name="human"> - <device name="last_resort" ipaddr="nd11"/> - </method> - </fence> - </clusternode> - </clusternodes> - - <fencedevices> - <fencedevice name="apc" agent="fence_apc" - ipaddr="apc_1" login="apc" passwd="apc"/> - - <fencedevice name="brocade" agent="fence_brocade" - ipaddr="brocade_1" login="bro" passwd="bro"/> - - <!-- The WTI fence device requires no login name --> - <fencedevice name="wti" agent="fence_wti" - ipaddr="wti_1" passwd="wti"/> - - <fencedevice name="last_resort" agent="fence_manual"/> - </fencedevices> -</cluster> - -.SH SEE ALSO -ccs(7), ccs_tool(8), lock_gulmd(5), cman(5) - diff --git a/ccs/scripts/uninstall.pl b/ccs/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/ccs/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/cman-kernel/Makefile b/cman-kernel/Makefile deleted file mode 100644 index a1b0df5..0000000 --- a/cman-kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: - cd src && ${MAKE} all - -clean: - cd src && ${MAKE} clean - -install: - cd src && ${MAKE} install - -uninstall: - cd src && ${MAKE} uninstall - -distclean: clean - rm -f make/defines.mk \ No newline at end of file diff --git a/cman-kernel/configure b/cman-kernel/configure deleted file mode 100755 index 430d161..0000000 --- a/cman-kernel/configure +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$kernel_src) { - $kernel_src="/usr/src/linux-2.6"; -} -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -open VER, "<$kernel_src/include/linux/version.h" or die "Can't open $kernel_src/include/linux/version.h"; -while(<VER>){ - chomp; - if( $_ =~ /^#define\s*UTS_RELEASE\s*"(.*)"$/ ){ - $kernel_version = $1; - $module_dir = "${prefix}/lib/modules/$1/kernel"; - } -} - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@KERNEL_VERSION@/$kernel_version/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@MODULE_DIR@/$module_dir/; - $_ =~ s/@SBINDIR@/$sbindir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/cman-kernel/make/defines.mk.input b/cman-kernel/make/defines.mk.input deleted file mode 100644 index 0c2ea7a..0000000 --- a/cman-kernel/make/defines.mk.input +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -module_dir ?= ${DESTDIR}/@MODULE_DIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ -KERNEL_VERSION = @KERNEL_VERSION@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/cman-kernel/make/release.mk.input b/cman-kernel/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/cman-kernel/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/cman-kernel/patches/2.6.9/00001.patch b/cman-kernel/patches/2.6.9/00001.patch deleted file mode 100644 index dc8d8e8..0000000 --- a/cman-kernel/patches/2.6.9/00001.patch +++ /dev/null @@ -1,227 +0,0 @@ -diff -urN linux-orig/arch/alpha/Kconfig linux-orig2/arch/alpha/Kconfig ---- linux-orig/arch/alpha/Kconfig 2004-10-18 16:55:37.000000000 -0500 -+++ linux-orig2/arch/alpha/Kconfig 2004-10-22 11:29:33.507218717 -0500 -@@ -600,3 +600,4 @@ - - source "lib/Kconfig" - -+source "cluster/Kconfig" -diff -urN linux-orig/arch/arm/Kconfig linux-orig2/arch/arm/Kconfig ---- linux-orig/arch/arm/Kconfig 2004-10-18 16:54:31.000000000 -0500 -+++ linux-orig2/arch/arm/Kconfig 2004-10-22 11:30:56.358918506 -0500 -@@ -690,3 +690,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/arm26/Kconfig linux-orig2/arch/arm26/Kconfig ---- linux-orig/arch/arm26/Kconfig 2004-10-18 16:54:32.000000000 -0500 -+++ linux-orig2/arch/arm26/Kconfig 2004-10-22 11:29:33.531218341 -0500 -@@ -222,3 +222,4 @@ - - source "lib/Kconfig" - -+source "cluster/Kconfig" -diff -urN linux-orig/arch/cris/Kconfig linux-orig2/arch/cris/Kconfig ---- linux-orig/arch/cris/Kconfig 2004-10-18 16:55:07.000000000 -0500 -+++ linux-orig2/arch/cris/Kconfig 2004-10-22 11:31:11.965673644 -0500 -@@ -174,3 +174,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/i386/Kconfig linux-orig2/arch/i386/Kconfig ---- linux-orig/arch/i386/Kconfig 2004-10-18 16:53:22.000000000 -0500 -+++ linux-orig2/arch/i386/Kconfig 2004-10-22 11:29:33.533218309 -0500 -@@ -1194,6 +1194,8 @@ - - source "lib/Kconfig" - -+source "cluster/Kconfig" -+ - config X86_SMP - bool - depends on SMP && !X86_VOYAGER -diff -urN linux-orig/arch/ia64/Kconfig linux-orig2/arch/ia64/Kconfig ---- linux-orig/arch/ia64/Kconfig 2004-10-18 16:55:27.000000000 -0500 -+++ linux-orig2/arch/ia64/Kconfig 2004-10-22 11:29:33.534218294 -0500 -@@ -390,3 +390,5 @@ - source "security/Kconfig" - - source "crypto/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/m68k/Kconfig linux-orig2/arch/m68k/Kconfig ---- linux-orig/arch/m68k/Kconfig 2004-10-18 16:54:32.000000000 -0500 -+++ linux-orig2/arch/m68k/Kconfig 2004-10-22 11:31:38.187262279 -0500 -@@ -655,3 +655,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/mips/Kconfig linux-orig2/arch/mips/Kconfig ---- linux-orig/arch/mips/Kconfig 2004-10-18 16:54:08.000000000 -0500 -+++ linux-orig2/arch/mips/Kconfig 2004-10-22 11:29:33.541218184 -0500 -@@ -1563,3 +1563,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/parisc/Kconfig linux-orig2/arch/parisc/Kconfig ---- linux-orig/arch/parisc/Kconfig 2004-10-18 16:54:37.000000000 -0500 -+++ linux-orig2/arch/parisc/Kconfig 2004-10-22 11:31:57.146964867 -0500 -@@ -195,3 +195,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/ppc/Kconfig linux-orig2/arch/ppc/Kconfig ---- linux-orig/arch/ppc/Kconfig 2004-10-18 16:55:29.000000000 -0500 -+++ linux-orig2/arch/ppc/Kconfig 2004-10-22 11:29:33.550218043 -0500 -@@ -1231,3 +1231,5 @@ - source "security/Kconfig" - - source "crypto/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/ppc64/Kconfig linux-orig2/arch/ppc64/Kconfig ---- linux-orig/arch/ppc64/Kconfig 2004-10-18 16:54:31.000000000 -0500 -+++ linux-orig2/arch/ppc64/Kconfig 2004-10-22 11:32:11.150745212 -0500 -@@ -352,3 +352,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/s390/Kconfig linux-orig2/arch/s390/Kconfig ---- linux-orig/arch/s390/Kconfig 2004-10-18 16:53:51.000000000 -0500 -+++ linux-orig2/arch/s390/Kconfig 2004-10-22 11:32:31.175431141 -0500 -@@ -466,3 +466,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/sh/Kconfig linux-orig2/arch/sh/Kconfig ---- linux-orig/arch/sh/Kconfig 2004-10-18 16:55:29.000000000 -0500 -+++ linux-orig2/arch/sh/Kconfig 2004-10-22 11:32:47.169180310 -0500 -@@ -748,3 +748,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/sparc/Kconfig linux-orig2/arch/sparc/Kconfig ---- linux-orig/arch/sparc/Kconfig 2004-10-18 16:53:05.000000000 -0500 -+++ linux-orig2/arch/sparc/Kconfig 2004-10-22 11:33:06.891871022 -0500 -@@ -386,3 +386,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/sparc64/Kconfig linux-orig2/arch/sparc64/Kconfig ---- linux-orig/arch/sparc64/Kconfig 2004-10-18 16:55:06.000000000 -0500 -+++ linux-orig2/arch/sparc64/Kconfig 2004-10-22 11:33:19.290676599 -0500 -@@ -613,3 +613,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/arch/um/Kconfig linux-orig2/arch/um/Kconfig ---- linux-orig/arch/um/Kconfig 2004-10-18 16:54:08.000000000 -0500 -+++ linux-orig2/arch/um/Kconfig 2004-10-22 11:29:33.564217823 -0500 -@@ -225,6 +225,8 @@ - - source "lib/Kconfig" - -+source "cluster/Kconfig" -+ - menu "SCSI support" - depends on BROKEN - -diff -urN linux-orig/arch/x86_64/Kconfig linux-orig2/arch/x86_64/Kconfig ---- linux-orig/arch/x86_64/Kconfig 2004-10-18 16:54:55.000000000 -0500 -+++ linux-orig2/arch/x86_64/Kconfig 2004-10-22 11:33:37.130396876 -0500 -@@ -424,3 +424,5 @@ - source "crypto/Kconfig" - - source "lib/Kconfig" -+ -+source "cluster/Kconfig" -diff -urN linux-orig/cluster/cman/Makefile linux-orig2/cluster/cman/Makefile ---- linux-orig/cluster/cman/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux-orig2/cluster/cman/Makefile 2004-10-22 11:29:33.566217791 -0500 -@@ -0,0 +1,6 @@ -+cman-objs := cnxman.o config.o membership.o proc.o\ -+ sm_barrier.o sm_control.o sm_daemon.o sm_joinleave.o\ -+ sm_membership.o sm_message.o sm_misc.o sm_recover.o sm_services.o \ -+ sm_user.o -+ -+obj-$(CONFIG_CLUSTER) := cman.o -diff -urN linux-orig/cluster/Kconfig linux-orig2/cluster/Kconfig ---- linux-orig/cluster/Kconfig 1969-12-31 18:00:00.000000000 -0600 -+++ linux-orig2/cluster/Kconfig 2004-10-22 11:29:33.565217807 -0500 -@@ -0,0 +1,13 @@ -+menu "Cluster Support" -+ -+config CLUSTER -+ tristate "Cluster support" -+ ---help--- -+ Enable clustering support. This is not the high-performance clustering -+ made famous by beowulf. It is a high-availability cluster often using -+ shared storage. -+ The cluster manager is the heart(beat) of the cluster system. It is -+ needed by all the other components. It provides membership services -+ for those other subsystems. -+ -+endmenu -diff -urN linux-orig/cluster/Makefile linux-orig2/cluster/Makefile ---- linux-orig/cluster/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux-orig2/cluster/Makefile 2004-10-22 11:29:33.566217791 -0500 -@@ -0,0 +1,3 @@ -+obj-y := nocluster.o -+ -+obj-$(CONFIG_CLUSTER) += cman/ -diff -urN linux-orig/cluster/nocluster.c linux-orig2/cluster/nocluster.c ---- linux-orig/cluster/nocluster.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-orig2/cluster/nocluster.c 2004-10-22 11:29:33.567217776 -0500 -@@ -0,0 +1,20 @@ -+/* -+ * cluster/nocluster.c -+ * -+ * Copy from net/nonet.c -+ * Dummy functions to allow us to configure cluster support entirely -+ * out of the kernel. -+ * -+ * Distributed under the terms of the GNU GPL version 2. -+ * Copyright (c) Matthew Wilcox 2003 -+ */ -+ -+#include <linux/module.h> -+#include <linux/errno.h> -+#include <linux/fs.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+ -+void __init nocluster_init(void) -+{ -+} -diff -urN linux-orig/Makefile linux-orig2/Makefile ---- linux-orig/Makefile 2004-10-18 16:54:38.000000000 -0500 -+++ linux-orig2/Makefile 2004-10-22 11:29:33.507218717 -0500 -@@ -445,7 +445,7 @@ - - # Objects we will link into vmlinux / subdirs we need to visit - init-y := init/ --drivers-y := drivers/ sound/ -+drivers-y := drivers/ sound/ cluster/ - net-y := net/ - libs-y := lib/ - core-y := usr/ diff --git a/cman-kernel/scripts/uninstall.pl b/cman-kernel/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/cman-kernel/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/cman-kernel/src/Makefile b/cman-kernel/src/Makefile deleted file mode 100644 index 814aaa5..0000000 --- a/cman-kernel/src/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = .. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/linux-orig -linux_patched = ${top_srcdir}/linux-patched - -TARGET = cman.patch - -PWD := $(shell pwd) - -obj-m := cman.o -cman-objs := cnxman.o config.o membership.o proc.o \ - sm_barrier.o sm_control.o sm_daemon.o sm_joinleave.o\ - sm_membership.o sm_message.o sm_misc.o sm_recover.o sm_services.o \ - sm_user.o - -EXTRA_CFLAGS += -I$(obj) - -all: - rm -f cluster - ln -s . cluster - ${MAKE} -C ${KERNEL_SRC} M=${PWD} modules USING_KBUILD=yes - -install: all - install -d ${module_dir}/cluster - install cman.ko ${module_dir}/cluster - install -d ${incdir}/cluster - install cnxman.h cnxman-socket.h service.h ${incdir}/cluster - -uninstall: - ${UNINSTALL} cman.ko ${module_dir}/cluster - ${UNINSTALL} cnxman.h cnxman-socket.h service.h ${incdir}/cluster - - - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir} ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/cluster/cman - mkdir -p ${linux_patched}/include/cluster - cp *.[ch] ${linux_patched}/cluster/cman - mv ${linux_patched}/cluster/cman/cnxman.h ${linux_patched}/include/cluster - mv ${linux_patched}/cluster/cman/cnxman-socket.h ${linux_patched}/include/cluster - mv ${linux_patched}/cluster/cman/service.h ${linux_patched}/include/cluster - -clean: - rm -rf cluster *.ko *.o *.mod.c *~ .*o.cmd .tmp_versions - diff --git a/cman-kernel/src/cnxman-private.h b/cman-kernel/src/cnxman-private.h deleted file mode 100644 index 1e28f21..0000000 --- a/cman-kernel/src/cnxman-private.h +++ /dev/null @@ -1,442 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __CNXMAN_PRIVATE_H -#define __CNXMAN_PRIVATE_H - -/* Protocol Version triplet */ -#define CNXMAN_MAJOR_VERSION 5 -#define CNXMAN_MINOR_VERSION 0 -#define CNXMAN_PATCH_VERSION 1 - -#define CAP_CLUSTER CAP_SYS_ADMIN /* Capability needed to manage the - * cluster */ -#ifdef __KERNEL__ - -/* How we announce ourself in console events */ -#define CMAN_NAME "CMAN" - -/* One of these per AF_CLUSTER socket */ -struct cluster_sock { - /* WARNING: sk has to be the first member */ - struct sock sk; - - unsigned char port; /* Bound port or zero */ - int (*kernel_callback) (char *, int, char *, int, unsigned int); - void *service_data; -}; - -#define cluster_sk(__sk) ((struct cluster_sock *)__sk) - -/* We have one of these for each socket we use for communications */ -struct cl_comms_socket { - struct socket *sock; - int broadcast; /* This is a broadcast socket */ - int recv_only; /* This is the unicast receive end of a - * multicast socket */ - struct sockaddr_in6 saddr; /* Socket address, contains the sockaddr for - * the remote end(s) */ - int addr_len; /* Length of above */ - int number; /* Internal socket number, used to cycle around - * sockets in case of network errors */ - struct file *file; /* file pointer for user-passed in sockets */ - - wait_queue_t wait; - - struct cl_comms_socket *peer; - - /* The socket list */ - struct list_head list; - - /* On here when it has something to say */ - struct list_head active_list; - unsigned long active; -}; - -/* A client socket. We keep a list of these so we can notify clients of cluster - * events */ -struct cl_client_socket { - struct socket *sock; - struct list_head list; -}; - -/* This structure is tacked onto the start of a cluster message packet for our - * own nefarious purposes. */ -struct cl_protheader { - unsigned char tgtport; /* Target port number */ - unsigned char srcport; /* Source (originationg) port number */ - unsigned short seq; /* Packet sequence number, little-endian */ - unsigned short ack; /* Inline ACK */ - unsigned short cluster; /* Our cluster number, little-endian */ - unsigned int flags; - int srcid; /* Node ID of the sender */ - int tgtid; /* Node ID of the target or 0 for multicast - * messages */ -}; - -/* A cluster internal protocol message - port number 0 */ -struct cl_protmsg { - struct cl_protheader header; - unsigned char cmd; -}; - -/* A Cluster ACK message */ -struct cl_ackmsg { - struct cl_protheader header; - unsigned char cmd; /* Always CLUSTER_CMD_ACK */ - unsigned char remport; /* Remote port number the original message was - * for */ - unsigned char aflags; /* ACK flags 0=OK, 1=No listener */ - unsigned char pad; -}; - -/* A Cluster LISTENREQ/LISTENRESP message */ -struct cl_listenmsg { - unsigned char cmd; /* CLUSTER_CMD_LISTENRESP/REQ */ - unsigned char target_port; /* Port to probe */ - unsigned char listening; /* Always 0 for LISTENREQ */ - unsigned char pad; - unsigned short tag; /* PID of remote waiting process */ -}; - -/* A Cluster PORTCLOSED message */ -struct cl_closemsg { - unsigned char cmd; /* CLUSTER_CMD_PORTCLOSED */ - unsigned char port; -}; - -/* Structure of a newly dead node, passed from cnxman to kmembershipd */ -struct cl_new_dead_node { - struct list_head list; - struct cluster_node *node; -}; - -/* Subcommands for BARRIER message */ -#define BARRIER_REGISTER 1 -#define BARRIER_CHANGE 2 -#define BARRIER_WAIT 4 -#define BARRIER_COMPLETE 5 - -/* A Cluster BARRIER message */ -struct cl_barriermsg { - unsigned char cmd; /* CLUSTER_CMD_BARRIER */ - unsigned char subcmd; /* BARRIER sub command */ - unsigned short pad; - unsigned int flags; - unsigned int nodes; - char name[MAX_BARRIER_NAME_LEN]; -}; - -/* Membership services messages, the cl_protheader is added transparently */ -struct cl_mem_hello_msg { - unsigned char cmd; - unsigned char flags; - unsigned short members; /* Number of nodes in the cluster, - * little-endian */ - unsigned int generation; /* Current cluster generation number */ -}; - -struct cl_mem_endtrans_msg { - unsigned char cmd; - unsigned char pad1; - unsigned short pad2; - unsigned int quorum; - unsigned int total_votes; - unsigned int generation; /* Current cluster generation number */ - unsigned int new_node_id; /* If reason is a new node joining */ -}; - -/* ACK types for JOINACK message */ -#define JOINACK_TYPE_OK 1 /* You can join */ -#define JOINACK_TYPE_NAK 2 /* You can NOT join */ -#define JOINACK_TYPE_WAIT 3 /* Wait a bit longer - cluster is in transition - * already */ - -struct cl_mem_joinack_msg { - unsigned char cmd; - unsigned char acktype; -}; - -/* This is used by JOINREQ message */ -struct cl_mem_join_msg { - unsigned char cmd; - unsigned char votes; - unsigned short num_addr; /* Number of addresses for this node */ - unsigned int expected_votes; - unsigned int nodeid; /* node ID we want */ - unsigned int major_version; /* Not backwards compatible */ - unsigned int minor_version; /* Backwards compatible */ - unsigned int patch_version; /* Backwards/forwards compatible */ - unsigned int config_version; - unsigned int addr_len; /* length of node addresses */ - char clustername[16]; - /* Followed by <num_addr> addresses of `address_length` bytes and a - * NUL-terminated node name */ -}; - -/* State transition start reasons: */ -#define TRANS_NONE 0 /* No current transition */ -#define TRANS_NEWNODE 1 /* A new node is joining the cluster */ -#define TRANS_REMNODE 2 /* a node has left the cluster */ -#define TRANS_ANOTHERREMNODE 3 /* A node left the cluster while we were in - * transition */ -#define TRANS_NEWMASTER 4 /* We have had an election and I am the new - * master */ -#define TRANS_CHECK 5 /* A consistency check was called for */ -#define TRANS_RESTART 6 /* Transition restarted because of a previous - * timeout */ -#define TRANS_DEADMASTER 7 /* The master died during transition and I have - * taken over */ - -/* This is used to start a state transition */ -struct cl_mem_starttrans_msg { - unsigned char cmd; - unsigned char reason; /* Why a start transition was started - see - * above */ - unsigned char flags; - unsigned char votes; - unsigned int expected_votes; - unsigned int generation; /* Incremented for each STARTTRANS sent - */ - int nodeid; /* Node to be removed */ - unsigned short num_addrs; - /* If reason == TRANS_NEWNODE: Followed by <num_addr> addresses of - * `address_length` bytes and a NUL-terminated node name */ -}; - -struct cl_mem_startack_msg { - unsigned char cmd; - unsigned char reason; - unsigned short pad; - unsigned int generation; -}; - -/* Reconfigure a cluster parameter */ -struct cl_mem_reconfig_msg { - unsigned char cmd; - unsigned char param; - unsigned short pad; - unsigned int value; -}; - -/* Tell the cluster a node has died */ -struct cl_mem_nodedown_msg { - unsigned char cmd; - unsigned char reason; - unsigned short pad; - unsigned int nodeid; -}; - -/* Structure containing information about an outstanding listen request */ -struct cl_waiting_listen_request { - wait_queue_head_t waitq; - int result; - int waiting; - unsigned short tag; - int nodeid; - struct list_head list; -}; - -/* Messages from membership services */ -#define CLUSTER_MEM_JOINCONF 1 -#define CLUSTER_MEM_JOINREQ 2 -#define CLUSTER_MEM_LEAVE 3 -#define CLUSTER_MEM_HELLO 4 -#define CLUSTER_MEM_KILL 5 -#define CLUSTER_MEM_JOINACK 6 -#define CLUSTER_MEM_ENDTRANS 7 -#define CLUSTER_MEM_RECONFIG 8 -#define CLUSTER_MEM_MASTERVIEW 9 -#define CLUSTER_MEM_STARTTRANS 10 -#define CLUSTER_MEM_JOINREJ 11 -#define CLUSTER_MEM_VIEWACK 12 -#define CLUSTER_MEM_STARTACK 13 -#define CLUSTER_MEM_TRANSITION 14 -#define CLUSTER_MEM_NEWCLUSTER 15 -#define CLUSTER_MEM_CONFACK 16 -#define CLUSTER_MEM_NOMINATE 17 -#define CLUSTER_MEM_NODEDOWN 18 - -/* Flags in the HELLO message */ -#define HELLO_FLAG_MASTER 1 -#define HELLO_FLAG_QUORATE 2 - -/* Parameters for RECONFIG command */ -#define RECONFIG_PARAM_EXPECTED_VOTES 1 -#define RECONFIG_PARAM_NODE_VOTES 2 -#define RECONFIG_PARAM_CONFIG_VERSION 3 - -/* Data associated with an outgoing socket */ -struct cl_socket { - struct file *file; /* The real file */ - struct socket *socket; /* The real sock */ - int num_nodes; /* On this link */ - int retransmit_count; -}; - -/* There's one of these for each node in the cluster */ -struct cluster_node { - struct list_head list; - char *name; /* Node/host name of node */ - struct list_head addr_list; - int us; /* This node is us */ - unsigned int node_id; /* Unique node ID */ - nodestate_t state; - unsigned short last_seq_recv; - unsigned short last_ackneeded_seq_recv; - unsigned short last_seq_acked; - unsigned short last_seq_sent; - unsigned int votes; - unsigned int expected_votes; - unsigned int leave_reason; - unsigned int incarnation; /* Incremented each time a node joins - * the cluster */ - unsigned long last_hello; /* Jiffies */ - struct timeval join_time; -}; - -/* This is how we keep a list of user processes that are listening for cluster - * membership events */ -struct notify_struct { - struct list_head list; - pid_t pid; - int signal; -}; - -/* This is how we keep a list of kernel callbacks that are registered for - * cluster membership events */ -struct kernel_notify_struct { - struct list_head list; - void (*callback) (kcl_callback_reason, long arg); -}; - -/* A message waiting to be sent */ -struct queued_message { - struct list_head list; - - struct socket *socket; - struct sockaddr_cl addr; - int addr_len; - int msg_len; - unsigned char port; - unsigned int flags; - char msg_buffer[MAX_CLUSTER_MESSAGE]; -}; - -/* A barrier */ -struct cl_barrier { - struct list_head list; - - char name[MAX_BARRIER_NAME_LEN]; - unsigned int flags; - enum { BARRIER_STATE_WAITING, BARRIER_STATE_INACTIVE, - BARRIER_STATE_COMPLETE, BARRIER_STATE_DELETED } state; - unsigned int expected_nodes; - unsigned int registered_nodes; - atomic_t got_nodes; - atomic_t completed_nodes; - unsigned int inuse; - unsigned int waitsent; - unsigned int phase; /* Completion phase */ - unsigned int endreason; /* Reason we were woken, usually 0 */ - unsigned long timeout; /* In seconds */ - - void (*callback) (char *name, int status); - wait_queue_head_t waitq; - struct semaphore lock; /* To synch with cnxman messages */ - spinlock_t phase2_spinlock; /* Need to synchronise with timer - * interrupts */ - struct timer_list timer; -}; - -/* Cluster protocol commands sent to port 0 */ -#define CLUSTER_CMD_ACK 1 -#define CLUSTER_CMD_LISTENREQ 2 -#define CLUSTER_CMD_LISTENRESP 3 -#define CLUSTER_CMD_PORTCLOSED 4 -#define CLUSTER_CMD_BARRIER 5 - -extern struct cluster_node *find_node_by_addr(unsigned char *addr, - int addr_len); -extern struct cluster_node *find_node_by_nodeid(unsigned int id); -extern struct cluster_node *find_node_by_name(char *name); -extern void set_quorate(int); -extern void notify_kernel_listeners(kcl_callback_reason reason, long arg); -extern void notify_listeners(void); -extern void free_nodeid_array(void); -extern int send_reconfigure(int param, unsigned int value); -extern int calculate_quorum(int, int, int *); -extern void recalculate_quorum(int); -extern int send_leave(unsigned char); -extern int get_quorum(void); -extern void set_votes(int, int); -extern void kcl_wait_for_all_acks(void); -extern char *membership_state(char *, int); -extern char *leave_string(int reason); -extern void a_node_just_died(struct cluster_node *node); -extern void check_barrier_returns(void); -extern int in_transition(void); -extern void get_local_addresses(struct cluster_node *node); -extern int add_node_address(struct cluster_node *node, unsigned char *addr, int len); -extern void create_proc_entries(void); -extern void cleanup_proc_entries(void); -extern unsigned int get_highest_nodeid(void); -extern int allocate_nodeid_array(void); -extern void queue_oob_skb(struct socket *sock, int cmd); -extern int new_temp_nodeid(char *addr, int addrlen); -extern int get_addr_from_temp_nodeid(int nodeid, char *addr, int *addrlen); -extern void purge_temp_nodeids(void); -extern inline char *print_addr(unsigned char *addr, int len, char *buf) -{ - int i; - int ptr = 0; - - for (i = 0; i < len; i++) - ptr += sprintf(buf + ptr, "%02x ", addr[i]); - - return buf; -} - -#define MAX_ADDR_PRINTED_LEN (address_length*3 + 1) - -/* Debug enabling macros. Sorry about the C++ comments but they're easier to - * get rid of than C ones... */ - -// #define DEBUG_MEMB -// #define DEBUG_COMMS -// #define DEBUG_BARRIER - -/* Debug macros */ -#ifdef DEBUG_COMMS -#define P_COMMS(fmt, args...) printk(KERN_DEBUG "cman comms: " fmt, ## args) -#else -#define P_COMMS(fmt, args...) -#endif - -#ifdef DEBUG_BARRIER -#define P_BARRIER(fmt, args...) printk(KERN_DEBUG "cman barrier: " fmt, ## args) -#else -#define P_BARRIER(fmt, args...) -#endif - -#ifdef DEBUG_MEMB -#define P_MEMB(fmt, args...) printk(KERN_DEBUG "cman memb: " fmt, ## args) -#define C_MEMB(fmt, args...) printk(fmt, ## args) -#else -#define P_MEMB(fmt, args...) -#define C_MEMB(fmt, args...) -#endif - -#endif /* __KERNEL */ - -#endif diff --git a/cman-kernel/src/cnxman-socket.h b/cman-kernel/src/cnxman-socket.h deleted file mode 100644 index 9d34e86..0000000 --- a/cman-kernel/src/cnxman-socket.h +++ /dev/null @@ -1,245 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* CMAN socket interface header, - may be include by user or kernel code */ - -#ifndef __CNXMAN_SOCKET_H -#define __CNXMAN_SOCKET_H - -/* A currently unused number. TIPC also uses this number and you're unlikely - to be using both. - */ -#define AF_CLUSTER 30 -#define PF_CLUSTER AF_CLUSTER - -/* Protocol(socket) types */ -#define CLPROTO_MASTER 2 -#define CLPROTO_CLIENT 3 - -/* ioctls -- should register these properly */ -#define SIOCCLUSTER_NOTIFY _IOW('x', 0x01, int) -#define SIOCCLUSTER_REMOVENOTIFY _IO( 'x', 0x02) -#define SIOCCLUSTER_GETMEMBERS _IOR('x', 0x03, struct cl_cluster_nodelist) -#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int) -#define SIOCCLUSTER_ISQUORATE _IO( 'x', 0x05) -#define SIOCCLUSTER_ISLISTENING _IOW('x', 0x06, struct cl_listen_request) -#define SIOCCLUSTER_GETALLMEMBERS _IOR('x', 0x07, struct cl_cluster_nodelist) -#define SIOCCLUSTER_SET_VOTES _IOW('x', 0x08, int) -#define SIOCCLUSTER_GET_VERSION _IOR('x', 0x09, struct cl_version) -#define SIOCCLUSTER_SET_VERSION _IOW('x', 0x0a, struct cl_version) -#define SIOCCLUSTER_ISACTIVE _IO( 'x', 0x0b) -#define SIOCCLUSTER_KILLNODE _IOW('x', 0x0c, int) -#define SIOCCLUSTER_GET_JOINCOUNT _IO( 'x', 0x0d) -#define SIOCCLUSTER_SERVICE_REGISTER _IOW('x', 0x0e, char) -#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f) -#define SIOCCLUSTER_SERVICE_JOIN _IO( 'x', 0x10) -#define SIOCCLUSTER_SERVICE_LEAVE _IO( 'x', 0x20) -#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int) -#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int) -#define SIOCCLUSTER_SERVICE_GETEVENT _IOR('x', 0x50, struct cl_service_event) -#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist) -#define SIOCCLUSTER_SERVICE_GLOBALID _IOR('x', 0x70, uint32_t) -#define SIOCCLUSTER_SERVICE_SETLEVEL _IOR('x', 0x80, int) -#define SIOCCLUSTER_GETNODE _IOWR('x', 0x90, struct cl_cluster_node) -#define SIOCCLUSTER_GETCLUSTER _IOWR('x', 0x91, struct cl_cluster_info) -#define SIOCCLUSTER_BARRIER _IOW('x', 0x0a0, struct cl_barrier_info) -#define SIOCCLUSTER_QD_REGISTER _IOW('x', 0x0a1, struct cl_quorumdevice_info) -#define SIOCCLUSTER_QD_UNREGISTER _IO('x', 0x0a2) -#define SIOCCLUSTER_QD_POLL _IOW('x', 0x0a3, int) -#define SIOCCLUSTER_SET_CLUSTERID _IOW('x', 0x0a4, uint16_t) - -/* These were setsockopts */ -#define SIOCCLUSTER_PASS_SOCKET _IOW('x', 0x0b0, struct cl_passed_sock) -#define SIOCCLUSTER_SET_NODENAME _IOW('x', 0x0b1, char *) -#define SIOCCLUSTER_SET_NODEID _IOW('x', 0x0b2, int) -#define SIOCCLUSTER_JOIN_CLUSTER _IOW('x', 0x0b3, struct cl_join_cluster_info) -#define SIOCCLUSTER_LEAVE_CLUSTER _IOW('x', 0x0b4, int) - - -/* Maximum size of a cluster message */ -#define MAX_CLUSTER_MESSAGE 1500 -#define MAX_CLUSTER_MEMBER_NAME_LEN 255 -#define MAX_BARRIER_NAME_LEN 33 -#define MAX_SA_ADDR_LEN 12 -#define MAX_CLUSTER_NAME_LEN 16 - -/* Well-known cluster port numbers */ -#define CLUSTER_PORT_MEMBERSHIP 1 /* Mustn't block during cluster - * transitions! */ -#define CLUSTER_PORT_SERVICES 2 -#define CLUSTER_PORT_SYSMAN 10 /* Remote execution daemon */ -#define CLUSTER_PORT_CLVMD 11 /* Cluster LVM daemon */ -#define CLUSTER_PORT_SLM 12 /* LVM SLM (simple lock manager) */ - -/* Port numbers above this will be blocked when the cluster is inquorate or in - * transition */ -#define HIGH_PROTECTED_PORT 9 - -/* Reasons for leaving the cluster */ -#define CLUSTER_LEAVEFLAG_DOWN 0 /* Normal shutdown */ -#define CLUSTER_LEAVEFLAG_KILLED 1 -#define CLUSTER_LEAVEFLAG_PANIC 2 -#define CLUSTER_LEAVEFLAG_REMOVED 3 /* This one can reduce quorum */ -#define CLUSTER_LEAVEFLAG_REJECTED 4 /* Not allowed into the cluster in the - * first place */ -#define CLUSTER_LEAVEFLAG_INCONSISTENT 5 /* Our view of the cluster is - * in a minority */ -#define CLUSTER_LEAVEFLAG_DEAD 6 /* Discovered to be dead */ -#define CLUSTER_LEAVEFLAG_NORESPONSE 7 /* Didn't ACK message */ -#define CLUSTER_LEAVEFLAG_FORCE 0x10 /* Forced by command-line */ - -/* OOB messages sent to a local socket */ -#define CLUSTER_OOB_MSG_PORTCLOSED 1 -#define CLUSTER_OOB_MSG_STATECHANGE 2 -#define CLUSTER_OOB_MSG_SERVICEEVENT 3 - -/* Sendmsg flags, these are above the normal sendmsg flags so they don't - * interfere */ -#define MSG_NOACK 0x010000 /* Don't need an ACK for this message */ -#define MSG_QUEUE 0x020000 /* Queue the message for sending later */ -#define MSG_MULTICAST 0x080000 /* Message was sent to all nodes in the cluster - */ -#define MSG_ALLINT 0x100000 /* Send out of all interfaces */ -#define MSG_REPLYEXP 0x200000 /* Reply is expected */ -#define MSG_BCASTSELF 0x400000 /* Broadcast message also gets send to us */ - -typedef enum { NODESTATE_JOINING=1, NODESTATE_MEMBER, - NODESTATE_DEAD } nodestate_t; - - -struct sockaddr_cl { - unsigned short scl_family; - unsigned char scl_flags; - unsigned char scl_port; - int scl_nodeid; -}; - -/* - * This is how we pass the multicast & receive sockets into kernel space. - */ -struct cl_passed_sock { - int fd; /* FD of master socket to do multicast on */ - int number; /* Socket number, to match up recvonly & bcast - * sockets */ - int multicast; /* Is it multicast or receive ? */ -}; - -/* Cluster configuration info passed when we join the cluster */ -struct cl_join_cluster_info { - unsigned char votes; - unsigned int expected_votes; - unsigned int two_node; - unsigned int config_version; - - char cluster_name[17]; -}; - - -/* This is the structure, per node, returned from the membership ioctl */ -struct cl_cluster_node { - unsigned int size; - unsigned int node_id; - unsigned int us; - unsigned int leave_reason; - unsigned int incarnation; - nodestate_t state; - char name[MAX_CLUSTER_MEMBER_NAME_LEN]; - unsigned char votes; -}; - -/* The struct passed to the membership ioctls */ -struct cl_cluster_nodelist { - uint32_t max_members; - struct cl_cluster_node *nodes; -}; - -/* The struct passed to the quorum device register ioctl */ -struct cl_quorumdevice_info { - uint32_t votes; - char name[MAX_CLUSTER_MEMBER_NAME_LEN]; - -}; - -/* Structure passed to SIOCCLUSTER_ISLISTENING */ -struct cl_listen_request { - unsigned char port; - int nodeid; -}; - -/* A Cluster PORTCLOSED message - received by a local user as an OOB message */ -struct cl_portclosed_oob { - unsigned char cmd; /* CLUSTER_OOB_MSG_PORTCLOSED */ - unsigned char port; -}; - -/* Get all version numbers or set the config version */ -struct cl_version { - unsigned int major; - unsigned int minor; - unsigned int patch; - unsigned int config; -}; - -/* structure passed to barrier ioctls */ -struct cl_barrier_info { - char cmd; - char name[MAX_BARRIER_NAME_LEN]; - unsigned int flags; - unsigned long arg; -}; - -struct cl_cluster_info { - char name[MAX_CLUSTER_NAME_LEN+1]; - uint16_t number; -}; - -typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH, - SERVICE_EVENT_LEAVEDONE } service_event_t; - -typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE } - service_start_t; - -struct cl_service_event { - service_event_t type; - service_start_t start_type; - unsigned int event_id; - unsigned int last_stop; - unsigned int last_start; - unsigned int last_finish; - unsigned int node_count; -}; - - -/* Commands to the barrier ioctl */ -#define BARRIER_IOCTL_REGISTER 1 -#define BARRIER_IOCTL_CHANGE 2 -#define BARRIER_IOCTL_DELETE 3 -#define BARRIER_IOCTL_WAIT 4 - -/* Attributes of a barrier - bitmask */ -#define BARRIER_ATTR_AUTODELETE 1 -#define BARRIER_ATTR_MULTISTEP 2 -#define BARRIER_ATTR_MANUAL 4 -#define BARRIER_ATTR_ENABLED 8 -#define BARRIER_ATTR_CALLBACK 16 - -/* Attribute setting commands */ -#define BARRIER_SETATTR_AUTODELETE 1 -#define BARRIER_SETATTR_MULTISTEP 2 -#define BARRIER_SETATTR_ENABLED 3 -#define BARRIER_SETATTR_NODES 4 -#define BARRIER_SETATTR_CALLBACK 5 -#define BARRIER_SETATTR_TIMEOUT 6 - -#endif diff --git a/cman-kernel/src/cnxman.c b/cman-kernel/src/cnxman.c deleted file mode 100644 index f754ef1..0000000 --- a/cman-kernel/src/cnxman.c +++ /dev/null @@ -1,4399 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#define EXPORT_SYMTAB -#include <linux/init.h> -#include <linux/socket.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/file.h> -#include <linux/utsname.h> -#include <net/sock.h> -#include <linux/proc_fs.h> -#include <linux/poll.h> -#include <linux/module.h> -#include <linux/list.h> -#include <linux/uio.h> -#include <cluster/cnxman.h> -#include <cluster/service.h> - -#include "cnxman-private.h" -#include "sm_control.h" -#include "sm_user.h" -#include "config.h" - -#define CMAN_RELEASE_NAME "<CVS>" - -static void process_incoming_packet(struct cl_comms_socket *csock, - struct msghdr *msg, struct kvec *vec, int veclen, int len); -static int cl_sendack(struct cl_comms_socket *sock, unsigned short seq, - int addr_len, char *addr, unsigned char remport, - unsigned char flag); -static void send_listen_request(int nodeid, unsigned char port); -static void send_listen_response(struct cl_comms_socket *csock, int nodeid, - unsigned char port, unsigned short tag); -static void resend_last_message(void); -static void start_ack_timer(void); -static int send_queued_message(struct queued_message *qmsg); -static void send_port_close_oob(unsigned char port); -static void post_close_oob(unsigned char port, int nodeid); -static void process_barrier_msg(struct cl_barriermsg *msg, - struct cluster_node *node); -static struct cl_barrier *find_barrier(char *name); -static void tidy_barriers(void); -static void node_shutdown(void); -static void node_cleanup(void); -static int send_or_queue_message(struct socket *sock, void *buf, int len, struct sockaddr_cl *caddr, - unsigned int flags); -static struct cl_comms_socket *get_next_interface(struct cl_comms_socket *cur); -static struct cl_comms_socket *get_peer_interface(int if_num, int mcast); -static void check_for_unacked_nodes(void); -static void free_cluster_sockets(void); -static uint16_t generate_cluster_id(char *name); -static int is_valid_temp_nodeid(int nodeid); - -extern int start_membership_services(pid_t); -extern int kcl_leave_cluster(int remove); -extern int send_kill(int nodeid, int needack); -extern void cman_set_realtime(struct task_struct *tsk, int prio); - -static struct proto_ops cl_proto_ops; -static struct sock *master_sock; -static kmem_cache_t *cluster_sk_cachep; - -/* Pointer to the pseudo node that maintains quorum in a 2node system */ -struct cluster_node *quorum_device = NULL; - -/* Array of "ports" allocated. This is just a list of pointers to the sock that - * has this port bound. Speed is a major issue here so 1-2K of allocated - * storage is worth sacrificing. Port 0 is reserved for protocol messages */ -static struct sock *port_array[256]; -static struct semaphore port_array_lock; - -/* Our cluster name & number */ -uint16_t cluster_id; -char cluster_name[MAX_CLUSTER_NAME_LEN+1]; - -/* Two-node mode: causes cluster to remain quorate if one of two nodes fails. - * No more than two nodes are permitted to join the cluster. */ -unsigned short two_node; - -/* Cluster configuration version that must be the same among members. */ -unsigned int config_version; - -/* Reference counting for cluster applications */ -atomic_t use_count; - -/* Length of sockaddr address for our comms protocol */ -unsigned int address_length; - -/* Message sending */ -static unsigned short cur_seq; /* Last message sent */ -static unsigned int ack_count; /* Number of acks received for message - * 'cur_seq' */ -static unsigned int acks_expected; /* Number of acks we expect to receive */ -static struct semaphore send_lock; -static struct timer_list ack_timer; - -/* Saved packet information in case we need to resend it */ -static char saved_msg_buffer[MAX_CLUSTER_MESSAGE]; -static int saved_msg_len; -static int retry_count; - -/* Task variables */ -static pid_t kcluster_pid; -extern struct task_struct *membership_task; -extern spinlock_t membership_task_lock; -extern int quit_threads; - -wait_queue_head_t cnxman_waitq; - -/* Variables owned by membership services */ -extern int cluster_members; -extern struct list_head cluster_members_list; -extern struct semaphore cluster_members_lock; -extern int we_are_a_cluster_member; -extern int cluster_is_quorate; -extern struct cluster_node *us; -extern struct list_head new_dead_node_list; -extern spinlock_t new_dead_node_lock; -extern char nodename[]; -extern int wanted_nodeid; - -/* A list of processes listening for membership events */ -static struct list_head event_listener_list; -static struct semaphore event_listener_lock; - -/* A list of kernel callbacks listening for membership events */ -static struct list_head kernel_listener_list; -static struct semaphore kernel_listener_lock; - -/* A list of sockets we are listening on (and can transmit on...later) */ -static struct list_head socket_list; - -/* A list of all open cluster client sockets */ -static struct list_head client_socket_list; -static struct semaphore client_socket_lock; - -/* A list of all current barriers */ -static struct list_head barrier_list; -static struct semaphore barrier_list_lock; - -/* When a socket is read for reading it goes on this queue */ -static spinlock_t active_socket_lock; -static struct list_head active_socket_list; - -/* If the cnxman process is running and available for work */ -atomic_t cnxman_running; - -/* Fkags set by timers etc for the mainloop to detect and act upon */ -static unsigned long mainloop_flags; - -#define ACK_TIMEOUT 1 -#define RESEND_NEEDED 2 -#define TIDY_BARRIERS 3 -#define IN_SHUTDOWN 4 - -/* A queue of messages waiting to be sent. If kcl_sendmsg is called outside of - * process context then the messages get put in here */ -static struct list_head messages_list; -static struct semaphore messages_list_lock; - -static struct semaphore start_thread_sem; - -/* List of outstanding ISLISTENING requests */ -static struct list_head listenreq_list; -static struct semaphore listenreq_lock; - -/* Any sending requests wait on this queue if necessary (eg inquorate, waiting - * ACK) */ -static DECLARE_WAIT_QUEUE_HEAD(socket_waitq); - -/* Wait for thread to exit properly */ -struct completion cluster_thread_comp; -struct completion member_thread_comp; - -/* The resend delay to use, We increase this geometrically(word?) each time a - * send is delayed. in deci-seconds */ -static int resend_delay = 1; - -/* Highest numbered interface and the current default */ -static int num_interfaces; -static struct cl_comms_socket *current_interface = NULL; - -struct temp_node -{ - int nodeid; - char addr[sizeof(struct sockaddr_in6)]; - int addrlen; - struct list_head list; -}; -static struct list_head tempnode_list; -static struct semaphore tempnode_lock; - - -/* This is what's squirrelled away in skb->cb */ -struct cb_info -{ - int orig_nodeid; - char orig_port; - char oob; -}; - - -/* Wake up any processes that are waiting to send. This is usually called when - * all the ACKs have been gathered up or when a node has left the cluster - * unexpectedly and we reckon there are no more acks to collect */ -static void unjam(void) -{ - wake_up_interruptible(&socket_waitq); - wake_up_interruptible(&cnxman_waitq); -} - -/* Used by the data_ready routine to locate a connection given the socket */ -static inline struct cl_comms_socket *find_comms_by_sock(struct sock *sk) -{ - struct list_head *conlist; - - list_for_each(conlist, &socket_list) { - struct cl_comms_socket *clsock = - list_entry(conlist, struct cl_comms_socket, list); - if (clsock->sock->sk == sk) { - return clsock; - } - } - return NULL; -} - -/* Data available on socket */ -static void cnxman_data_ready(struct sock *sk, int count_unused) -{ - struct cl_comms_socket *clsock = find_comms_by_sock(sk); - - if (clsock == NULL) /* ASSERT ?? */ - return; - - /* If we're already on the list then don't do it again */ - if (test_and_set_bit(1, &clsock->active)) - return; - - spin_lock_irq(&active_socket_lock); - list_add(&clsock->active_list, &active_socket_list); - spin_unlock_irq(&active_socket_lock); - - wake_up_interruptible(&cnxman_waitq); -} - -static int receive_message(struct cl_comms_socket *csock, char *iobuf) -{ - struct msghdr msg; - struct kvec vec; - struct sockaddr_in6 sin; - int len; - - memset(&sin, 0, sizeof (sin)); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_name = &sin; - msg.msg_namelen = sizeof (sin); - msg.msg_flags = 0; - - vec.iov_len = MAX_CLUSTER_MESSAGE; - vec.iov_base = iobuf; - - len = kernel_recvmsg(csock->sock, &msg, - &vec, 1, MAX_CLUSTER_MESSAGE, MSG_DONTWAIT); - - vec.iov_base = iobuf; - vec.iov_len = MAX_CLUSTER_MESSAGE; - - if (len > 0) { - if (len > MAX_CLUSTER_MESSAGE) { - printk(KERN_CRIT CMAN_NAME - ": %d byte message far too big\n", len); - return 0; - } - process_incoming_packet(csock, &msg, &vec, 1, len); - } - else { - if (len != -EAGAIN) - printk(KERN_CRIT CMAN_NAME ": recvmsg failed: %d\n", - len); - } - return len; -} - -static int cluster_kthread(void *unused) -{ - int len; - char *iobuf; - struct list_head *socklist; - struct cl_comms_socket *csock; - wait_queue_t cnxman_waitq_head; - sigset_t tmpsig; - - daemonize("cman_comms"); - - /* Block everything but SIGKILL/SIGSTOP/SIGTERM */ - siginitset(&tmpsig, SIGKILL | SIGSTOP | SIGTERM); - sigprocmask(SIG_BLOCK, &tmpsig, NULL); - - /* This is the waitq we can wake the process up with */ - init_waitqueue_head(&cnxman_waitq); - init_waitqueue_entry(&cnxman_waitq_head, current); - add_wait_queue(&cnxman_waitq, &cnxman_waitq_head); - - cman_set_realtime(current, 1); - - /* Allow the sockets to start receiving */ - list_for_each(socklist, &socket_list) { - csock = list_entry(socklist, struct cl_comms_socket, list); - - clear_bit(1, &csock->active); - } - - iobuf = kmalloc(MAX_CLUSTER_MESSAGE, GFP_KERNEL); - if (!iobuf) { - printk(KERN_CRIT CMAN_NAME - ": Cannot allocate receive buffer for cluster comms\n"); - return -1; - } - - complete(&cluster_thread_comp); - - for (;;) { - struct list_head *temp; - - /* Wait for activity on any of the sockets */ - set_task_state(current, TASK_INTERRUPTIBLE); - - if (list_empty(&active_socket_list)) - schedule(); - set_task_state(current, TASK_RUNNING); - - if (quit_threads) - break; - - /* Now receive any messages waiting for us */ - spin_lock_irq(&active_socket_lock); - list_for_each_safe(socklist, temp, &active_socket_list) { - csock = - list_entry(socklist, struct cl_comms_socket, - active_list); - - list_del(&csock->active_list); - clear_bit(1, &csock->active); - - spin_unlock_irq(&active_socket_lock); - - do { - len = receive_message(csock, iobuf); - } - while (len > 0); - - spin_lock_irq(&active_socket_lock); - - if (len == 0) - break; /* EOF on socket */ - } - spin_unlock_irq(&active_socket_lock); - - if (test_and_clear_bit(ACK_TIMEOUT, &mainloop_flags)) { - check_for_unacked_nodes(); - } - - if (test_and_clear_bit(TIDY_BARRIERS, &mainloop_flags)) { - tidy_barriers(); - } - - /* Resend any unacked messages */ - if (test_and_clear_bit(RESEND_NEEDED, &mainloop_flags) - && acks_expected) { - resend_last_message(); - } - - /* Send any queued messages */ - if (acks_expected == 0) { - struct list_head *temp; - struct list_head *msglist; - - down(&messages_list_lock); - list_for_each_safe(msglist, temp, &messages_list) { - struct queued_message *qmsg = - list_entry(msglist, struct queued_message, - list); - int status = send_queued_message(qmsg); - - if (status >= 0) { - /* Suceeded, remove it from the queue */ - list_del(&qmsg->list); - kfree(qmsg); - } - /* Did it fail horribly ?? */ - if (status < 0 && status != -EAGAIN) { - printk(KERN_INFO CMAN_NAME - ": send_queued_message failed, error %d\n", - status); - list_del(&qmsg->list); - kfree(qmsg); - } - break; /* Only send one message at a time */ - } - up(&messages_list_lock); - } - - if (signal_pending(current)) - break; - } - P_COMMS("closing down\n"); - - set_bit(IN_SHUTDOWN, &mainloop_flags); - quit_threads = 1; /* force other thread to die too */ - - /* Wait for membership thread to finish, that way any - LEAVE message will get sent. */ - spin_lock(&membership_task_lock); - if (membership_task) { - wake_up_process(membership_task); - spin_unlock(&membership_task_lock); - wait_for_completion(&member_thread_comp); - } - else { - spin_unlock(&membership_task_lock); - } - - node_shutdown(); - - if (timer_pending(&ack_timer)) - del_timer(&ack_timer); - - node_cleanup(); - kfree(iobuf); - - complete(&cluster_thread_comp); - clear_bit(IN_SHUTDOWN, &mainloop_flags); - return 0; -} - -void notify_kernel_listeners(kcl_callback_reason reason, long arg) -{ - struct kernel_notify_struct *knotify; - struct list_head *proclist; - - down(&kernel_listener_lock); - list_for_each(proclist, &kernel_listener_list) { - knotify = - list_entry(proclist, struct kernel_notify_struct, list); - knotify->callback(reason, arg); - } - up(&kernel_listener_lock); -} - -static void check_for_unacked_nodes() -{ - struct list_head *nodelist; - struct list_head *temp; - struct cluster_node *node; - - clear_bit(RESEND_NEEDED, &mainloop_flags); - retry_count = 0; - - P_COMMS("Retry count exceeded -- looking for dead node\n"); - - /* Node did not ACK a message after <n> tries, remove it from the - * cluster */ - down(&cluster_members_lock); - list_for_each_safe(nodelist, temp, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - P_COMMS("checking node %s: last_acked = %d, last_seq_sent = %d\n", - node->name, node->last_seq_acked, node->last_seq_sent); - if (node->state != NODESTATE_DEAD && - node->last_seq_acked != node->last_seq_sent && !node->us) { - - /* Drop this lock or we can deadlock with membership */ - up(&cluster_members_lock); - - /* Start a state transition */ - node->leave_reason = CLUSTER_LEAVEFLAG_NORESPONSE; - a_node_just_died(node); - down(&cluster_members_lock); - } - } - up(&cluster_members_lock); - acks_expected = ack_count = 0; - unjam(); - return; -} - -static void ack_timer_fn(unsigned long arg) -{ - P_COMMS("%ld: ack_timer fired, retries=%d\n", jiffies, retry_count); - - /* Too many retries ? */ - if (++retry_count > cman_config.max_retries) { - set_bit(ACK_TIMEOUT, &mainloop_flags); - wake_up_interruptible(&cnxman_waitq); - } - else { - /* Resend last message */ - set_bit(RESEND_NEEDED, &mainloop_flags); - wake_up_interruptible(&cnxman_waitq); - } -} - -/* Called to resend a packet if sock_sendmsg was busy */ -static void short_timer_fn(unsigned long arg) -{ - P_COMMS("short_timer fired\n"); - - /* Resend last message */ - resend_delay <<= 1; - set_bit(RESEND_NEEDED, &mainloop_flags); - wake_up_interruptible(&cnxman_waitq); -} - -static void start_ack_timer() -{ - ack_timer.function = ack_timer_fn; - ack_timer.data = 0L; - mod_timer(&ack_timer, jiffies + HZ); -} - -static void start_short_timer(void) -{ - ack_timer.function = short_timer_fn; - ack_timer.data = 0L; - mod_timer(&ack_timer, jiffies + (resend_delay * HZ)); -} - - -static struct cl_waiting_listen_request *find_listen_request(unsigned short tag) -{ - struct list_head *llist; - struct cl_waiting_listen_request *listener; - - list_for_each(llist, &listenreq_list) { - listener = list_entry(llist, struct cl_waiting_listen_request, - list); - if (listener->tag == tag) { - return listener; - } - } - return NULL; -} - -static void process_ack(struct cluster_node *rem_node, unsigned short seq) -{ - if (rem_node && rem_node->state != NODESTATE_DEAD) { - /* This copes with duplicate acks from a multipathed - * host */ - if (rem_node->last_seq_acked != le16_to_cpu(seq)) { - rem_node->last_seq_acked = le16_to_cpu(seq); - - /* Got em all */ - if (++ack_count >= acks_expected) { - - /* Cancel the timer */ - del_timer(&ack_timer); - acks_expected = 0; - unjam(); - } - } - } -} - -static void process_cnxman_message(struct cl_comms_socket *csock, char *data, - int len, char *addr, int addrlen, - struct cluster_node *rem_node) -{ - struct cl_protmsg *msg = (struct cl_protmsg *) data; - struct cl_protheader *header = (struct cl_protheader *) data; - struct cl_ackmsg *ackmsg; - struct cl_listenmsg *listenmsg; - struct cl_closemsg *closemsg; - struct cl_barriermsg *barriermsg; - struct cl_waiting_listen_request *listen_request; - - P_COMMS("Message on port 0 is %d\n", msg->cmd); - switch (msg->cmd) { - case CLUSTER_CMD_ACK: - ackmsg = (struct cl_ackmsg *) data; - - if (rem_node && (ackmsg->aflags & 1)) { - if (net_ratelimit()) - printk(KERN_INFO CMAN_NAME - ": WARNING no listener for port %d on node %s\n", - ackmsg->remport, rem_node->name); - } - P_COMMS("Got ACK from %s. seq=%d (cur=%d)\n", - rem_node ? rem_node->name : "Unknown", - le16_to_cpu(ackmsg->header.ack), cur_seq); - - /* ACK processing has already happened */ - break; - - /* Return 1 if we have a listener on this port, 0 if not */ - case CLUSTER_CMD_LISTENREQ: - listenmsg = - (struct cl_listenmsg *) (data + - sizeof (struct cl_protheader)); - cl_sendack(csock, header->seq, addrlen, addr, header->tgtport, 0); - send_listen_response(csock, le32_to_cpu(header->srcid), - listenmsg->target_port, listenmsg->tag); - break; - - case CLUSTER_CMD_LISTENRESP: - /* Wake up process waiting for listen response */ - listenmsg = - (struct cl_listenmsg *) (data + - sizeof (struct cl_protheader)); - cl_sendack(csock, header->seq, addrlen, addr, header->tgtport, 0); - down(&listenreq_lock); - listen_request = find_listen_request(listenmsg->tag); - if (listen_request) { - listen_request->result = listenmsg->listening; - listen_request->waiting = 0; - wake_up_interruptible(&listen_request->waitq); - } - up(&listenreq_lock); - break; - - case CLUSTER_CMD_PORTCLOSED: - closemsg = - (struct cl_closemsg *) (data + - sizeof (struct cl_protheader)); - cl_sendack(csock, header->seq, addrlen, addr, header->tgtport, 0); - post_close_oob(closemsg->port, le32_to_cpu(header->srcid)); - break; - - case CLUSTER_CMD_BARRIER: - barriermsg = - (struct cl_barriermsg *) (data + - sizeof (struct cl_protheader)); - cl_sendack(csock, header->seq, addrlen, addr, header->tgtport, 0); - if (rem_node) - process_barrier_msg(barriermsg, rem_node); - break; - - default: - printk(KERN_ERR CMAN_NAME - ": Unknown protocol message %d received\n", msg->cmd); - break; - - } - return; -} - -static int valid_addr_for_node(struct cluster_node *node, char *addr) -{ - struct list_head *addrlist; - struct cluster_node_addr *nodeaddr; - - /* We don't compare the first two bytes of the address because it's - * the Address Family and always in native byte order...so it will - * not match if we have mixed big & little-endian machines in the cluster - */ - - list_for_each(addrlist, &node->addr_list) { - nodeaddr = list_entry(addrlist, struct cluster_node_addr, list); - - if (memcmp(nodeaddr->addr+2, addr+2, address_length-2) == 0) - return 1; /* TRUE */ - } - return 0; /* FALSE */ -} - -static void memcpy_fromkvec(void *data, struct kvec *vec, int len) -{ - while (len > 0) { - if (vec->iov_len) { - int copy = min_t(unsigned int, len, vec->iov_len); - memcpy(data, vec->iov_base, copy); - len -= copy; - data += copy; - vec->iov_base += copy; - vec->iov_len -= copy; - } - vec++; - } -} - -static int send_to_user_port(struct cl_comms_socket *csock, - struct cl_protheader *header, - struct msghdr *msg, - struct kvec *iov, int veclen, - int len) -{ - struct sk_buff *skb; - struct cb_info *cbinfo; - int err; - int flags = le32_to_cpu(header->flags); - - /* Get the port number and look for a listener */ - down(&port_array_lock); - if (port_array[header->tgtport]) { - struct cluster_sock *c = cluster_sk(port_array[header->tgtport]); - - /* ACK it */ - if (!(flags & MSG_NOACK) && !(flags & MSG_REPLYEXP)) { - - cl_sendack(csock, header->seq, msg->msg_namelen, - msg->msg_name, header->tgtport, 0); - } - - /* Call a callback if there is one */ - if (c->kernel_callback) { - up(&port_array_lock); - if (veclen == 1) { - c->kernel_callback(iov->iov_base, - iov->iov_len, - msg->msg_name, msg->msg_namelen, - le32_to_cpu(header->srcid)); - - } - else { /* Unroll iov, this Hardly ever Happens */ - char *data; - data = kmalloc(len, GFP_KERNEL); - if (!data) - return -ENOMEM; - - memcpy_fromkvec(data, iov, len); - c->kernel_callback(data, len, - msg->msg_name, msg->msg_namelen, - le32_to_cpu(header->srcid)); - kfree(data); - } - return len; - } - - /* Otherwise put it into an SKB and pass it onto the recvmsg - * mechanism */ - skb = alloc_skb(len, GFP_KERNEL); - if (!skb) { - up(&port_array_lock); - printk(KERN_INFO CMAN_NAME - ": Failed to allocate skb\n"); - return -ENOMEM; - } - - skb_put(skb, len); - memcpy_fromkvec(skb->data, iov, len); - - /* Put metadata into cb[] */ - cbinfo = (struct cb_info *)skb->cb; - cbinfo->orig_nodeid = le32_to_cpu(header->srcid); - cbinfo->orig_port = header->srcport; - cbinfo->oob = 0; - - if ((err = - sock_queue_rcv_skb(port_array[header->tgtport], skb)) < 0) { - - printk(KERN_INFO CMAN_NAME - ": Error queueing request to port %d: %d\n", - header->tgtport, err); - kfree_skb(skb); - - /* If the port was MEMBERSHIP then we have to die */ - if (header->tgtport == CLUSTER_PORT_MEMBERSHIP) { - up(&port_array_lock); - send_leave(CLUSTER_LEAVEFLAG_PANIC); - panic("membership stopped responding"); - } - } - up(&port_array_lock); - - } - else { - /* ACK it, but set the flag bit so remote end knows no-one - * caught it */ - if (!(flags & MSG_NOACK)) - cl_sendack(csock, header->seq, - msg->msg_namelen, msg->msg_name, - header->tgtport, 1); - - /* Nobody listening, drop it */ - up(&port_array_lock); - } - return len; -} - -/* NOTE: This routine knows (assumes!) that there is only one - iov element passed into it. */ -static void process_incoming_packet(struct cl_comms_socket *csock, - struct msghdr *msg, - struct kvec *vec, int veclen, int len) -{ - char *data = vec->iov_base; - char *addr = msg->msg_name; - int addrlen = msg->msg_namelen; - struct cl_protheader *header = (struct cl_protheader *) data; - int flags = le32_to_cpu(header->flags); - struct cluster_node *rem_node = - find_node_by_nodeid(le32_to_cpu(header->srcid)); - - P_COMMS("seen message, from %d for %d, sequence num = %d, rem_node=%p, state=%d\n", - le32_to_cpu(header->srcid), le32_to_cpu(header->tgtid), - le16_to_cpu(header->seq), rem_node, - rem_node ? rem_node->state : -1); - - /* If the remote end is being coy about its node ID then look it up by - * address */ - if (!rem_node && header->srcid == 0) { - rem_node = find_node_by_addr(addr, addrlen); - } - - /* If this node is an ex-member then treat it as unknown */ - if (rem_node && rem_node->state != NODESTATE_MEMBER - && rem_node->state != NODESTATE_JOINING) - rem_node = NULL; - - /* Ignore messages not for our cluster */ - if (le16_to_cpu(header->cluster) != cluster_id) { - P_COMMS("Dumping message - wrong cluster ID (us=%d, msg=%d)\n", - cluster_id, header->cluster); - goto incoming_finish; - } - - /* If the message is from us then just dump it */ - if (rem_node && rem_node->us) - goto incoming_finish; - - /* If we can't find the nodeid then check for our own messages the hard - * way - this only happens during joining */ - if (!rem_node) { - struct list_head *socklist; - struct cl_comms_socket *clsock; - - list_for_each(socklist, &socket_list) { - clsock = - list_entry(socklist, struct cl_comms_socket, list); - - if (clsock->recv_only) { - - if (memcmp(addr, &clsock->saddr, address_length) == 0) { - goto incoming_finish; - } - } - } - - } - - /* Ignore messages not for us */ - if (le32_to_cpu(header->tgtid) > 0 && us - && le32_to_cpu(header->tgtid) != us->node_id) { - goto incoming_finish; - } - - P_COMMS("got message, from %d for %d, sequence num = %d\n", - le32_to_cpu(header->srcid), le32_to_cpu(header->tgtid), - le16_to_cpu(header->seq)); - - if (header->ack && rem_node) { - process_ack(rem_node, header->ack); - } - - /* Have we received this message before ? If so just ignore it, it's a - * resend for someone else's benefit */ - if (!(flags & MSG_NOACK) && - rem_node && rem_node->last_ackneeded_seq_recv && - (short)((short)le16_to_cpu(header->seq) - (short)rem_node->last_ackneeded_seq_recv) <= 0) { - P_COMMS("Discarding message - seq = %d, last_seen = %d, last_acked_seen = %d\n", - header->seq, rem_node->last_seq_recv, rem_node->last_ackneeded_seq_recv); - /* Still need to ACK it though, in case it was the ACK that got - * lost */ - cl_sendack(csock, header->seq, addrlen, addr, header->tgtport, 0); - goto incoming_finish; - } - - /* Check that the message is from the node we think it is from */ - if (rem_node && !valid_addr_for_node(rem_node, addr)) { - return; - } - - /* If it's a new node then assign it a temporary node ID */ - if (!rem_node) - header->srcid = cpu_to_le32(new_temp_nodeid(addr, addrlen)); - - P_COMMS("Got message: flags = %x, port = %d, we_are_a_member = %d\n", - flags, header->tgtport, we_are_a_cluster_member); - - - /* If we are not part of the cluster then ignore multicast messages - * that need an ACK as we will confuse the sender who is only expecting - * ACKS from bona fide members */ - if ((flags & MSG_MULTICAST) && - !(flags & MSG_NOACK) && !we_are_a_cluster_member) { - P_COMMS - ("Discarding message - multicast and we are not a cluster member. port=%d flags=%x\n", - header->tgtport, flags); - goto incoming_finish; - } - - /* Save the sequence number of this message so we can ignore duplicates - * (above). Ignore ACKS(seq==0)! */ - if (rem_node && header->seq) { - rem_node->last_seq_recv = le16_to_cpu(header->seq); - if (!(flags & MSG_NOACK)) - rem_node->last_ackneeded_seq_recv = le16_to_cpu(header->seq); - } - - /* Is it a protocol message? */ - if (header->tgtport == 0) { - process_cnxman_message(csock, data, len, addr, addrlen, - rem_node); - goto incoming_finish; - } - - /* Skip past the header to the data */ - vec[0].iov_base = data + sizeof (struct cl_protheader); - vec[0].iov_len -= sizeof (struct cl_protheader); - len -= sizeof (struct cl_protheader); - - send_to_user_port(csock, header, msg, vec, veclen, len); - - incoming_finish: - return; -} - -static struct sock *cl_alloc_sock(struct socket *sock, int gfp) -{ - struct sock *sk; - struct cluster_sock *c; - - if ((sk = - sk_alloc(AF_CLUSTER, gfp, sizeof (struct cluster_sock), - cluster_sk_cachep)) == NULL) - goto no_sock; - - if (sock) { - sock->ops = &cl_proto_ops; - } - sock_init_data(sock, sk); - - sk->sk_destruct = NULL; - sk->sk_no_check = 1; - sk->sk_family = PF_CLUSTER; - sk->sk_allocation = gfp; - - c = cluster_sk(sk); - c->port = 0; - c->service_data = NULL; - - return sk; - no_sock: - return NULL; -} - -static int cl_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - struct cl_client_socket *csock; - struct list_head *socklist; - struct list_head *tmp; - - down(&client_socket_lock); - if (sk) { - /* Remove port allocations if it's a bound socket */ - struct cluster_sock *c = cluster_sk(sk); - - down(&port_array_lock); - if (c->port) { - port_array[c->port] = NULL; - } - up(&port_array_lock); - - /* Tell other nodes in the cluster that this listener is going - * away */ - if (atomic_read(&cnxman_running) && c->port) - send_port_close_oob(c->port); - - if (c->service_data) - sm_sock_release(sock); - - /* Master socket released ? */ - if (sk->sk_protocol == CLPROTO_MASTER) { - master_sock = NULL; - - /* If this socket is being freed and cnxman is not - * started then free all the comms sockets as either - * the userland "join" process has crashed or the - * join failed. - */ - if (!atomic_read(&cnxman_running)) { - quit_threads = 1; - free_cluster_sockets(); - } - } - - sock_orphan(sk); - sock_hold(sk); - lock_sock(sk); - release_sock(sk); - sock_put(sk); - sock_put(sk); - sock->sk = NULL; - } - - /* Remove it from the list of clients */ - list_for_each_safe(socklist, tmp, &client_socket_list) { - csock = list_entry(socklist, struct cl_client_socket, list); - - if (csock->sock == sock) { - list_del(&csock->list); - kfree(csock); - break; - } - } - up(&client_socket_lock); - - return 0; -} - -static int cl_create(struct socket *sock, int protocol) -{ - struct sock *sk; - - /* All are datagrams */ - if (sock->type != SOCK_DGRAM) - return -ESOCKTNOSUPPORT; - - if (protocol == CLPROTO_MASTER && !capable(CAP_CLUSTER)) - return -EPERM; - - /* Can only have one master socket */ - if (master_sock && protocol == CLPROTO_MASTER) - return -EBUSY; - - /* We are shutting down - please be patient */ - if (protocol == CLPROTO_MASTER && test_bit(IN_SHUTDOWN, &mainloop_flags)) - return -EBUSY; - - /* cnxman not running and a client was requested */ - if (!atomic_read(&cnxman_running) && protocol != CLPROTO_MASTER) - return -ENETDOWN; - - if ((sk = cl_alloc_sock(sock, GFP_KERNEL)) == NULL) - return -ENOBUFS; - - sk->sk_protocol = protocol; - - if (protocol == CLPROTO_MASTER) - master_sock = sk; - - /* Add client sockets to the list */ - if (protocol == CLPROTO_CLIENT) { - struct cl_client_socket *clsock = - kmalloc(sizeof (struct cl_client_socket), GFP_KERNEL); - if (!clsock) { - cl_release(sock); - return -ENOMEM; - } - clsock->sock = sock; - down(&client_socket_lock); - list_add(&clsock->list, &client_socket_list); - up(&client_socket_lock); - } - - return 0; -} - -static int cl_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -{ - struct sock *sk = sock->sk; - struct sockaddr_cl *saddr = (struct sockaddr_cl *) uaddr; - struct cluster_sock *c = cluster_sk(sk); - - if (!capable(CAP_NET_BIND_SERVICE)) - return -EPERM; - - if (sk->sk_zapped == 0) - return -EINVAL; - - if (addr_len != sizeof (struct sockaddr_cl)) - return -EINVAL; - - if (saddr->scl_family != AF_CLUSTER) - return -EINVAL; - - if (saddr->scl_port == 0) - return -EINVAL; /* Port 0 is reserved for protocol messages */ - - down(&port_array_lock); - - if (port_array[saddr->scl_port]) { - up(&port_array_lock); - return -EADDRINUSE; - } - - port_array[saddr->scl_port] = sk; - - up(&port_array_lock); - - c->port = saddr->scl_port; - sk->sk_zapped = 0; - - /* If we are not a cluster member yet then make the client wait until - * we are, this allows nodes to start cluster clients at the same time - * as cluster services but they will wait until membership is achieved. - * This looks odd in bind() (open would seem more obvious) but we need - * to know which port number is being used so that things like - * membership services don't get blocked - */ - - if (saddr->scl_port > HIGH_PROTECTED_PORT) - while (!we_are_a_cluster_member || !cluster_is_quorate - || in_transition()) { - DECLARE_WAITQUEUE(wq, current); - struct task_struct *tsk = current; - - set_task_state(tsk, TASK_INTERRUPTIBLE); - add_wait_queue(&socket_waitq, &wq); - - if (!we_are_a_cluster_member || !cluster_is_quorate - || in_transition()) - schedule(); - - set_task_state(tsk, TASK_RUNNING); - remove_wait_queue(&socket_waitq, &wq); - - /* We were woken up because the cluster is going down, - * ...and we never got a chance to do any work! (sob) */ - if (atomic_read(&cnxman_running) == 0 || quit_threads) { - return -ENOTCONN; - } - } - - return 0; -} - -static int cl_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) -{ - struct sockaddr_cl *sa = (struct sockaddr_cl *) uaddr; - struct sock *sk = sock->sk; - struct cluster_sock *c = cluster_sk(sk); - - *uaddr_len = sizeof (struct sockaddr_cl); - - lock_sock(sk); - - sa->scl_port = c->port; - sa->scl_flags = 0; - sa->scl_family = AF_CLUSTER; - - release_sock(sk); - - return 0; -} - -static unsigned int cl_poll(struct file *file, struct socket *sock, - poll_table * wait) -{ - return datagram_poll(file, sock, wait); -} - -/* Copy internal node format to userland format */ -void copy_to_usernode(struct cluster_node *node, - struct cl_cluster_node *unode) -{ - strcpy(unode->name, node->name); - unode->size = sizeof (struct cl_cluster_node); - unode->votes = node->votes; - unode->state = node->state; - unode->us = node->us; - unode->node_id = node->node_id; - unode->leave_reason = node->leave_reason; - unode->incarnation = node->incarnation; -} - -static int add_clsock(int broadcast, int number, struct socket *sock, - struct file *file) -{ - struct cl_comms_socket *peer; - struct cl_comms_socket *newsock = - kmalloc(sizeof (struct cl_comms_socket), GFP_KERNEL); - if (!newsock) - return -ENOMEM; - - memset(newsock, 0, sizeof (*newsock)); - newsock->number = number; - newsock->sock = sock; - if (broadcast) { - newsock->broadcast = 1; - newsock->recv_only = 0; - } - else { - newsock->broadcast = 0; - newsock->recv_only = 1; - } - - newsock->file = file; - newsock->addr_len = sizeof(struct sockaddr_in6); - - /* Mark it active until cnxman thread is running and ready to process - * messages */ - set_bit(1, &newsock->active); - - /* Find out what it's bound to */ - newsock->sock->ops->getname(newsock->sock, - (struct sockaddr *)&newsock->saddr, - &newsock->addr_len, 0); - - num_interfaces = max(num_interfaces, newsock->number); - if (!current_interface && newsock->recv_only) - current_interface = newsock; - - /* Get peer, if this fails because we're the first socket with this - number then that's fine. The subsequent call will fill in both */ - peer = get_peer_interface(number, !broadcast); - if (peer) { - peer->peer = newsock; - newsock->peer = peer; - } - - /* Hook data_ready */ - newsock->sock->sk->sk_data_ready = cnxman_data_ready; - - /* Make an attempt to keep them in order */ - list_add_tail(&newsock->list, &socket_list); - - address_length = newsock->addr_len; - return 0; -} - -/* ioctl processing functions */ - -static int do_ioctl_set_version(unsigned long arg) -{ - struct cl_version version, *u_version; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (arg == 0) - return -EINVAL; - - if (!we_are_a_cluster_member) - return -ENOENT; - - u_version = (struct cl_version *) arg; - - if (copy_from_user(&version, u_version, sizeof(struct cl_version))) - return -EFAULT; - - if (version.major != CNXMAN_MAJOR_VERSION || - version.minor != CNXMAN_MINOR_VERSION || - version.patch != CNXMAN_PATCH_VERSION) - return -EINVAL; - - if (config_version == version.config) - return 0; - - config_version = version.config; - send_reconfigure(RECONFIG_PARAM_CONFIG_VERSION, config_version); - return 0; -} - -static int do_ioctl_get_members(unsigned long arg) -{ - struct cluster_node *node; - /* Kernel copies */ - struct cl_cluster_node user_format_node; - struct cl_cluster_nodelist user_format_nodelist; - /* User space array ptr */ - struct cl_cluster_node *user_node; - struct list_head *nodelist; - int num_nodes = 0; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if (arg == 0) - return cluster_members; - - if (copy_from_user(&user_format_nodelist, (void __user *)arg, sizeof(struct cl_cluster_nodelist))) - return -EFAULT; - - down(&cluster_members_lock); - - if (user_format_nodelist.max_members < cluster_members) { - up(&cluster_members_lock); - return -E2BIG; - } - - user_node = user_format_nodelist.nodes; - - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - if (node->state == NODESTATE_MEMBER) { - copy_to_usernode(node, &user_format_node); - if (copy_to_user(user_node, &user_format_node, - sizeof (struct cl_cluster_node))) { - up(&cluster_members_lock); - return -EFAULT; - } - user_node++; - num_nodes++; - } - } - up(&cluster_members_lock); - - return num_nodes; -} - -static int do_ioctl_get_all_members(unsigned long arg) -{ - struct cluster_node *node; - /* Kernel copies */ - struct cl_cluster_node user_format_node; - struct cl_cluster_nodelist user_format_nodelist; - /* User space array ptr*/ - struct cl_cluster_node *user_node; - struct list_head *nodelist; - int num_nodes = 0; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if (arg && - copy_from_user(&user_format_nodelist, - (void __user *)arg, sizeof(struct cl_cluster_nodelist))) - return -EFAULT; - - down(&cluster_members_lock); - - user_node = user_format_nodelist.nodes; - - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - if (arg) { - copy_to_usernode(node, - &user_format_node); - - if (copy_to_user(user_node, &user_format_node, - sizeof (struct cl_cluster_node))) { - up(&cluster_members_lock); - return -EFAULT; - } - user_node++; - if (--user_format_nodelist.max_members < 0) { - num_nodes = -EFAULT; - goto err_exit; - } - - } - num_nodes++; - } - err_exit: - up(&cluster_members_lock); - - return num_nodes; -} - - -static int do_ioctl_get_cluster(unsigned long arg) -{ - struct cl_cluster_info __user *info; - - if (!we_are_a_cluster_member) - return -ENOENT; - - info = (struct cl_cluster_info *)arg; - - if (copy_to_user(&info->number, &cluster_id, sizeof(cluster_id))) - return -EFAULT; - - if (copy_to_user(&info->name, cluster_name, strlen(cluster_name)+1)) - return -EFAULT; - - return 0; -} - -static int do_ioctl_get_node(unsigned long arg) -{ - struct cluster_node *node; - struct cl_cluster_node k_node, *u_node; - - if (!we_are_a_cluster_member) - return -ENOENT; - - u_node = (struct cl_cluster_node *) arg; - - if (copy_from_user(&k_node, u_node, sizeof(struct cl_cluster_node))) - return -EFAULT; - - if (!k_node.name[0]) { - if (k_node.node_id == 0) - k_node.node_id = us->node_id; - node = find_node_by_nodeid(k_node.node_id); - } - else - node = find_node_by_name(k_node.name); - - if (!node) - return -ENOENT; - - copy_to_usernode(node, &k_node); - - if (copy_to_user(u_node, &k_node, sizeof(struct cl_cluster_node))) - return -EFAULT; - - return 0; -} - -static int do_ioctl_set_expected(unsigned long arg) -{ - struct list_head *nodelist; - struct cluster_node *node; - unsigned int total_votes; - unsigned int newquorum; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (arg == 0) - return -EINVAL; - - if (!we_are_a_cluster_member) - return -ENOENT; - - newquorum = calculate_quorum(1, arg, &total_votes); - - if (newquorum < total_votes / 2 - || newquorum > total_votes) { - return -EINVAL; - } - - /* Now do it */ - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - if (node->state == NODESTATE_MEMBER - && node->expected_votes > arg) { - node->expected_votes = arg; - } - } - up(&cluster_members_lock); - - recalculate_quorum(1); - - send_reconfigure(RECONFIG_PARAM_EXPECTED_VOTES, arg); - sm_member_update(cluster_is_quorate); - - return 0; -} - -static int do_ioctl_kill_node(unsigned long arg) -{ - struct cluster_node *node; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if ((node = find_node_by_nodeid(arg)) == NULL) - return -EINVAL; - - /* Can't kill us */ - if (node->us) - return -EINVAL; - - if (node->state != NODESTATE_MEMBER) - return -EINVAL; - - /* Just in case it is alive, send a KILL message */ - send_kill(arg, 1); - - node->leave_reason = CLUSTER_LEAVEFLAG_KILLED; - a_node_just_died(node); - - return 0; -} - -static int do_ioctl_barrier(unsigned long arg) -{ - struct cl_barrier_info info; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if (copy_from_user(&info, (void *)arg, sizeof(info)) != 0) - return -EFAULT; - - switch (info.cmd) { - case BARRIER_IOCTL_REGISTER: - return kcl_barrier_register(info.name, - info.flags, - info.arg); - case BARRIER_IOCTL_CHANGE: - return kcl_barrier_setattr(info.name, - info.flags, - info.arg); - case BARRIER_IOCTL_WAIT: - return kcl_barrier_wait(info.name); - case BARRIER_IOCTL_DELETE: - return kcl_barrier_delete(info.name); - default: - return -EINVAL; - } -} - -static int do_ioctl_islistening(unsigned long arg) -{ - DECLARE_WAITQUEUE(wq, current); - struct cl_listen_request rq; - struct cluster_node *rem_node; - int nodeid; - int result; - struct cl_waiting_listen_request *listen_request; - - if (!arg) - return -EINVAL; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if (copy_from_user(&rq, (void *) arg, sizeof (rq)) != 0) - return -EFAULT; - - nodeid = rq.nodeid; - if (!nodeid) - nodeid = us->node_id; - - rem_node = find_node_by_nodeid(nodeid); - - /* Node not in the cluster */ - if (!rem_node) - return -ENOENT; - - if (rem_node->state != NODESTATE_MEMBER) - return -ENOTCONN; - - /* If the request is for us then just look in the ports - * array */ - if (rem_node->us) - return (port_array[rq.port] != 0) ? 1 : 0; - - /* For a remote node we need to send a request out */ - - /* If we are in transition then wait until we are not */ - while (in_transition()) { - set_task_state(current, TASK_INTERRUPTIBLE); - add_wait_queue(&socket_waitq, &wq); - - if (in_transition()) - schedule(); - - set_task_state(current, TASK_RUNNING); - remove_wait_queue(&socket_waitq, &wq); - - if (signal_pending(current)) - return -EINTR; - } - - /* Were we shut down before it completed ? */ - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - listen_request = - kmalloc(sizeof (struct cl_waiting_listen_request), - GFP_KERNEL); - if (!listen_request) - return -ENOMEM; - - /* Build the request */ - listen_request->waiting = 1; - listen_request->result = 0; - listen_request->tag = current->pid; - listen_request->nodeid = nodeid; - init_waitqueue_head(&listen_request->waitq); - - down(&listenreq_lock); - list_add(&listen_request->list, &listenreq_list); - up(&listenreq_lock); - - /* Now wait for the response to come back */ - send_listen_request(rq.nodeid, rq.port); - - while (listen_request->waiting) { - set_task_state(current, TASK_INTERRUPTIBLE); - add_wait_queue(&listen_request->waitq, &wq); - - if (listen_request->waiting) - schedule(); - - set_task_state(current, TASK_RUNNING); - remove_wait_queue(&listen_request->waitq, &wq); - - if (signal_pending(current)) { - result = -ERESTARTSYS; - goto end_listen; - } - } - result = listen_request->result; - - end_listen: - down(&listenreq_lock); - list_del(&listen_request->list); - kfree(listen_request); - up(&listenreq_lock); - return result; -} - -static int do_ioctl_set_votes(unsigned long arg) -{ - unsigned int total_votes; - unsigned int newquorum; - int saved_votes; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (!we_are_a_cluster_member) - return -ENOENT; - - /* Check votes is valid */ - saved_votes = us->votes; - us->votes = arg; - - newquorum = calculate_quorum(1, 0, &total_votes); - - if (newquorum < total_votes / 2 || newquorum > total_votes) { - us->votes = saved_votes; - return -EINVAL; - } - - recalculate_quorum(1); - - send_reconfigure(RECONFIG_PARAM_NODE_VOTES, arg); - - return 0; -} - -static int do_ioctl_pass_socket(unsigned long arg) -{ - struct cl_passed_sock sock_info; - struct file *file; - int error; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (atomic_read(&cnxman_running)) - return -EALREADY; - - error = -EBADF; - - if (copy_from_user(&sock_info, (void *)arg, sizeof(sock_info))) - return -EFAULT; - - file = fget(sock_info.fd); - if (file) { - struct inode *inode = file->f_dentry->d_inode; - - error = add_clsock(sock_info.multicast, - sock_info.number, SOCKET_I(inode), - file); - if (error) - fput(file); - } - return error; - -} - -static int do_ioctl_set_nodename(unsigned long arg) -{ - if (!capable(CAP_CLUSTER)) - return -EPERM; - if (atomic_read(&cnxman_running)) - return -EALREADY; - if (strncpy_from_user(nodename, (void *)arg, MAX_CLUSTER_MEMBER_NAME_LEN) < 0) - return -EFAULT; - return 0; -} - -static int do_ioctl_set_nodeid(unsigned long arg) -{ - int nodeid = (int)arg; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - if (atomic_read(&cnxman_running)) - return -EALREADY; - if (nodeid < 0 || nodeid > 4096) - return -EINVAL; - - wanted_nodeid = (int)arg; - return 0; -} - -static int do_ioctl_set_clusterid(unsigned long arg) -{ - if (!capable(CAP_CLUSTER)) - return -EPERM; - if (atomic_read(&cnxman_running)) - return -EALREADY; - - cluster_id = (uint16_t)arg; - return 0; -} - -static int do_ioctl_join_cluster(unsigned long arg) -{ - struct cl_join_cluster_info join_info; - pid_t membership_pid; - - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (atomic_read(&cnxman_running)) - return -EALREADY; - - if (copy_from_user(&join_info, (void *)arg, sizeof (struct cl_join_cluster_info) )) - return -EFAULT; - - if (strlen(join_info.cluster_name) > MAX_CLUSTER_NAME_LEN) - return -EINVAL; - - if (list_empty(&socket_list)) - return -ENOTCONN; - - set_votes(join_info.votes, join_info.expected_votes); - if (!cluster_id) - cluster_id = generate_cluster_id(join_info.cluster_name); - strncpy(cluster_name, join_info.cluster_name, MAX_CLUSTER_NAME_LEN); - two_node = join_info.two_node; - config_version = join_info.config_version; - - quit_threads = 0; - acks_expected = 0; - init_completion(&cluster_thread_comp); - init_completion(&member_thread_comp); - if (allocate_nodeid_array()) - return -ENOMEM; - - kcluster_pid = kernel_thread(cluster_kthread, NULL, 0); - if (kcluster_pid < 0) - return kcluster_pid; - - wait_for_completion(&cluster_thread_comp); - init_completion(&cluster_thread_comp); - - atomic_set(&cnxman_running, 1); - - /* Make sure we have a node name */ - if (nodename[0] == '\0') - strcpy(nodename, system_utsname.nodename); - - membership_pid = start_membership_services(kcluster_pid); - if (membership_pid < 0) { - quit_threads = 1; - wait_for_completion(&cluster_thread_comp); - init_completion(&member_thread_comp); - return membership_pid; - } - - sm_start(); - return 0; -} - -static int do_ioctl_leave_cluster(unsigned long leave_flags) -{ - if (!capable(CAP_CLUSTER)) - return -EPERM; - - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - /* FORCE overrides several checks */ - if (!(leave_flags & CLUSTER_LEAVEFLAG_FORCE)) { - if (!we_are_a_cluster_member) - return -ENOENT; - - if (in_transition()) - return -EBUSY; - - if (atomic_read(&use_count)) - return -ENOTCONN; - } - - us->leave_reason = leave_flags; - quit_threads = 1; - wake_up_interruptible(&cnxman_waitq); - - wait_for_completion(&cluster_thread_comp); - atomic_set(&use_count, 0); - return 0; -} - -static int cl_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - int err = -EOPNOTSUPP; - struct list_head *proclist; - struct list_head *tmp; - struct notify_struct *notify; - struct cl_version cnxman_version; - struct cl_quorumdevice_info qd_info; - - switch (cmd) { - /* Process requests notification of cluster events */ - case SIOCCLUSTER_NOTIFY: - notify = kmalloc(sizeof (struct notify_struct), GFP_KERNEL); - if (!notify) - return -ENOMEM; - notify->pid = current->pid; - notify->signal = arg; - down(&event_listener_lock); - list_add(¬ify->list, &event_listener_list); - up(&event_listener_lock); - err = 0; - break; - - /* Process is no longer interested cluster events */ - case SIOCCLUSTER_REMOVENOTIFY: - err = EINVAL; - - down(&event_listener_lock); - list_for_each_safe(proclist, tmp, &event_listener_list) { - notify = - list_entry(proclist, struct notify_struct, list); - if (notify->pid == current->pid) { - list_del(¬ify->list); - kfree(notify); - err = 0; - } - } - up(&event_listener_lock); - break; - - /* Return the cnxman version number */ - case SIOCCLUSTER_GET_VERSION: - if (!arg) - return -EINVAL; - err = 0; - cnxman_version.major = CNXMAN_MAJOR_VERSION; - cnxman_version.minor = CNXMAN_MINOR_VERSION; - cnxman_version.patch = CNXMAN_PATCH_VERSION; - cnxman_version.config = config_version; - if (copy_to_user((void *) arg, &cnxman_version, - sizeof (struct cl_version))) { - return -EFAULT; - } - break; - - /* Set the cnxman config version number */ - case SIOCCLUSTER_SET_VERSION: - err = do_ioctl_set_version(arg); - break; - - /* Return the active membership list */ - case SIOCCLUSTER_GETMEMBERS: - err = do_ioctl_get_members(arg); - break; - - /* Return the full membership list include dead nodes */ - case SIOCCLUSTER_GETALLMEMBERS: - err = do_ioctl_get_all_members(arg); - break; - - case SIOCCLUSTER_GETNODE: - err = do_ioctl_get_node(arg); - break; - - case SIOCCLUSTER_GETCLUSTER: - err = do_ioctl_get_cluster(arg); - break; - - case SIOCCLUSTER_ISQUORATE: - return cluster_is_quorate; - - case SIOCCLUSTER_ISACTIVE: - return atomic_read(&cnxman_running); - - case SIOCCLUSTER_SETEXPECTED_VOTES: - err = do_ioctl_set_expected(arg); - break; - - /* Change the number of votes for this node */ - case SIOCCLUSTER_SET_VOTES: - err = do_ioctl_set_votes(arg); - break; - - /* Return 1 if the specified node is listening on a given port */ - case SIOCCLUSTER_ISLISTENING: - err = do_ioctl_islistening(arg); - break; - - /* Forcibly kill a node */ - case SIOCCLUSTER_KILLNODE: - err = do_ioctl_kill_node(arg); - break; - - case SIOCCLUSTER_GET_JOINCOUNT: - if (!capable(CAP_CLUSTER)) - return -EPERM; - else - return atomic_read(&use_count); - - /* ioctl interface to the barrier system */ - case SIOCCLUSTER_BARRIER: - err = do_ioctl_barrier(arg); - break; - - case SIOCCLUSTER_PASS_SOCKET: - if (sock->sk->sk_protocol != CLPROTO_MASTER) - err = -EOPNOTSUPP; - else - err = do_ioctl_pass_socket(arg); - break; - - case SIOCCLUSTER_SET_NODENAME: - if (sock->sk->sk_protocol != CLPROTO_MASTER) - err = -EOPNOTSUPP; - else - err = do_ioctl_set_nodename(arg); - break; - - case SIOCCLUSTER_SET_NODEID: - if (sock->sk->sk_protocol != CLPROTO_MASTER) - err = -EOPNOTSUPP; - else - err = do_ioctl_set_nodeid(arg); - break; - - case SIOCCLUSTER_SET_CLUSTERID: - if (sock->sk->sk_protocol != CLPROTO_MASTER) - err = -EOPNOTSUPP; - else - err = do_ioctl_set_clusterid(arg); - break; - - case SIOCCLUSTER_JOIN_CLUSTER: - if (sock->sk->sk_protocol != CLPROTO_MASTER) - err = -EOPNOTSUPP; - else - err = do_ioctl_join_cluster(arg); - break; - - case SIOCCLUSTER_LEAVE_CLUSTER: - err = do_ioctl_leave_cluster(arg); - break; - - case SIOCCLUSTER_QD_REGISTER: - if (copy_from_user(&qd_info, (void *)arg, sizeof(qd_info))) - return -EFAULT; - - err = kcl_register_quorum_device(qd_info.name, qd_info.votes); - break; - - case SIOCCLUSTER_QD_POLL: - err = kcl_quorum_device_available((int)arg); - break; - - case SIOCCLUSTER_QD_UNREGISTER: - err = kcl_unregister_quorum_device(); - break; - - default: - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - err = sm_ioctl(sock, cmd, arg); - } - return err; -} - -static int cl_shutdown(struct socket *sock, int how) -{ - struct sock *sk = sock->sk; - int err = -ENOTCONN; - - lock_sock(sk); - - if (sock->state == SS_UNCONNECTED) - goto out; - - err = 0; - if (sock->state == SS_DISCONNECTING) - goto out; - - err = -EINVAL; - - if (how != SHUTDOWN_MASK) - goto out; - - sk->sk_shutdown = how; - err = 0; - - out: - release_sock(sk); - - return err; -} - - -/* We'll be giving out reward points next... */ -/* Send the packet and save a copy in case someone loses theirs. Should be - * protected by the send semaphore */ -static int __send_and_save(struct cl_comms_socket *csock, struct msghdr *msg, - struct kvec *vec, int veclen, - int size, int needack) -{ - int result; - struct kvec save_vectors[veclen]; - - /* Save a copy of the IO vectors as sendmsg mucks around with them and - * we might want to send the same stuff out more than once (for different - * interfaces) - */ - memcpy(save_vectors, vec, - sizeof (struct kvec) * veclen); - - result = kernel_sendmsg(csock->sock, msg, vec, veclen, size); - - if (result >= 0 && acks_expected && needack) { - - /* Start retransmit timer if it didn't go */ - if (result == 0) { - start_short_timer(); - } - else { - resend_delay = 1; - } - } - if (result < 0) { - printk(KERN_ERR CMAN_NAME ": sendmsg failed: %d\n", result); - } - - /* Restore IOVs */ - memcpy(vec, save_vectors, - sizeof (struct kvec) * veclen); - - return result; -} - -static void resend_last_message() -{ - struct msghdr msg; - struct kvec vec[1]; - int result; - - P_COMMS("%ld resending last message: %d bytes: port=%d, cmd=%d\n", - jiffies, saved_msg_len, saved_msg_buffer[0], - saved_msg_buffer[6]); - - /* Assume there is something wrong with the last interface */ - current_interface = get_next_interface(current_interface); - if (num_interfaces > 1) - printk(KERN_WARNING CMAN_NAME ": Now using interface %d\n", - current_interface->number); - - vec[0].iov_base = saved_msg_buffer; - vec[0].iov_len = saved_msg_len; - - memset(&msg, 0, sizeof (msg)); - msg.msg_name = ¤t_interface->peer->saddr; - msg.msg_namelen = current_interface->peer->addr_len; - - result = kernel_sendmsg(current_interface->sock, &msg, vec, 1, saved_msg_len); - - if (result < 0) - printk(KERN_ERR CMAN_NAME ": resend failed: %d\n", result); - - /* Try indefinitely to send this, the backlog must die down eventually - * !? */ - if (result == 0) - start_short_timer(); - - /* Send succeeded, continue waiting for ACKS */ - if (result > 0) - start_ack_timer(); - -} - -static int cl_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size, int flags) -{ - struct sock *sk = sock->sk; - struct sockaddr_cl *sin = (struct sockaddr_cl *) msg->msg_name; - struct sk_buff *skb; - struct cb_info *cbinfo; - int copied, err = 0; - int isoob = 0; - - /* Socket was notified of shutdown, remove any pending skbs and return - * EOF */ - if (!atomic_read(&cnxman_running)) { - while ((skb = skb_recv_datagram(sk, flags, MSG_DONTWAIT, &err))) - skb_free_datagram(sk, skb); - return 0; /* cnxman has left the building */ - } - - /* Generic datagram code does most of the work. If the user is not - * interested in OOB messages then ignore them */ - do { - skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); - if (!skb) - goto out; - - cbinfo = (struct cb_info *)skb->cb; - isoob = cbinfo->oob; - - /* If it is OOB and the user doesn't want it, then throw it away. */ - if (isoob && !(flags & MSG_OOB)) { - skb_free_datagram(sk, skb); - - /* If we peeked (?) an OOB but the user doesn't want it - then we need to discard it or we'll loop forever */ - if (flags & MSG_PEEK) { - skb = skb_recv_datagram(sk, flags & ~MSG_PEEK, - MSG_DONTWAIT, &err); - if (skb) - skb_free_datagram(sk, skb); - } - } - } - while (isoob && !(flags & MSG_OOB)); - - copied = skb->len; - if (copied > size) { - copied = size; - msg->msg_flags |= MSG_TRUNC; - } - err = memcpy_toiovec(msg->msg_iov, skb->data, copied); - - if (err) - goto out_free; - - if (msg->msg_name && msg->msg_namelen) { - memset(msg->msg_name, 0, msg->msg_namelen); - - if (msg->msg_namelen >= sizeof (struct sockaddr_cl)) { - - /* Nodeid is in native byte order - anything else is just - * perverse */ - sin->scl_nodeid = cbinfo->orig_nodeid; - } - msg->msg_namelen = sizeof (struct sockaddr_cl); - sin->scl_port = cbinfo->orig_port; - } - - if (isoob) { - msg->msg_flags |= MSG_OOB; - } - - sock_recv_timestamp(msg, sk, skb); - - err = copied; - - out_free: - skb_free_datagram(sk, skb); - - out: - return err; -} - -/* Send a message out on all interfaces */ -static int send_to_all_ints(int nodeid, struct msghdr *our_msg, - struct kvec *vec, int veclen, int size, int flags) -{ - struct sockaddr_in6 daddr; - struct cl_comms_socket *clsock; - int result = 0; - static int errors = 0; - - our_msg->msg_name = &daddr; - - list_for_each_entry(clsock, &socket_list, list) { - - /* Don't send out of a broadcast socket */ - if (clsock->recv_only) { - - /* For temporary node IDs send to the node's real IP address */ - if (nodeid < 0) { - get_addr_from_temp_nodeid(nodeid, (char *)&daddr, &our_msg->msg_namelen); - } - else { - memcpy(&daddr, &clsock->peer->saddr, clsock->peer->addr_len); - our_msg->msg_namelen = clsock->peer->addr_len; - } - - result = __send_and_save(clsock, our_msg, vec, veclen, - size + sizeof (struct cl_protheader), - !(flags & MSG_NOACK)); - if (result < 0) - errors++; - else - errors = 0; - } - } - - /* If all the interfaces error then die */ - if (errors >= num_interfaces * cman_config.max_retries) { - printk(KERN_ERR CMAN_NAME ": No functional network interfaces, leaving cluster\n"); - quit_threads = 1; - wake_up_interruptible(&cnxman_waitq); - } - return result; -} - - -/* Internal common send message routine */ -static int __sendmsg(struct socket *sock, struct msghdr *msg, - struct kvec *vec, int veclen, int size, - unsigned char port) -{ - int result = 0, i; - int flags = msg->msg_flags; - struct msghdr our_msg; - struct sockaddr_cl *caddr = msg->msg_name; - struct cl_protheader header; - struct kvec vectors[veclen + 1]; - unsigned char srcport; - int nodeid = 0; - - if (size > MAX_CLUSTER_MESSAGE) - return -EINVAL; - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - if (caddr) - nodeid = caddr->scl_nodeid; - - /* Check that the node id (if present) is valid */ - if (msg->msg_namelen && (!find_node_by_nodeid(nodeid) && - !is_valid_temp_nodeid(nodeid))) { - return -ENOTCONN; - } - - /* If there's no sending client socket then the source - port is 0: "us" */ - if (sock) { - struct cluster_sock *csock = cluster_sk(sock->sk); - srcport = csock->port; - } - else { - srcport = 0; - } - - /* We can only have one send outstanding at a time so we might as well - * lock the whole send mechanism */ - down(&send_lock); - - while ((port > HIGH_PROTECTED_PORT - && (!cluster_is_quorate || in_transition())) - || (acks_expected > 0 && !(msg->msg_flags & MSG_NOACK))) { - - DECLARE_WAITQUEUE(wq, current); - struct task_struct *tsk = current; - - if (quit_threads) { - up(&send_lock); - return -ENOTCONN; - } - - if (flags & MSG_DONTWAIT) { - up(&send_lock); - return -EAGAIN; - } - - if (current->pid == kcluster_pid) { - P_COMMS - ("Tried to make kclusterd wait, port=%d, acks_count=%d, expected=%d\n", - port, ack_count, acks_expected); - up(&send_lock); - return -EAGAIN; - } - - P_COMMS("%s process waiting. acks=%d, expected=%d\n", tsk->comm, - ack_count, acks_expected); - - set_task_state(tsk, TASK_INTERRUPTIBLE); - add_wait_queue(&socket_waitq, &wq); - - if ((port > HIGH_PROTECTED_PORT - && (!cluster_is_quorate || in_transition())) - || (acks_expected > 0)) { - - up(&send_lock); - schedule(); - down(&send_lock); - } - - set_task_state(tsk, TASK_RUNNING); - remove_wait_queue(&socket_waitq, &wq); - - /* Going down */ - if (quit_threads) { - up(&send_lock); - return -ENOTCONN; - } - - if (signal_pending(current)) { - up(&send_lock); - return -ERESTARTSYS; - } - - /* Were we shut down in the meantime ? */ - if (!atomic_read(&cnxman_running)) { - up(&send_lock); - return -ENOTCONN; - } - - } - - memset(&our_msg, 0, sizeof (our_msg)); - - /* Build the header */ - header.tgtport = port; - header.srcport = srcport; - header.flags = msg->msg_flags; /* byte-swapped later */ - header.cluster = cpu_to_le16(cluster_id); - header.srcid = us ? cpu_to_le32(us->node_id) : 0; - header.tgtid = caddr ? cpu_to_le32(nodeid) : 0; - - if (++cur_seq == 0) - ++cur_seq; - - header.seq = cpu_to_le16(cur_seq); - header.ack = 0; - - if (header.tgtid) { - struct cluster_node *remnode; - - remnode = find_node_by_nodeid(nodeid); - if (remnode) { - header.ack = cpu_to_le16(remnode->last_ackneeded_seq_recv); - } - } - - /* Set the MULTICAST flag on messages with no particular destination */ - if (!msg->msg_namelen) { - header.flags |= MSG_MULTICAST; - header.tgtid = 0; - } - - /* Loopback shortcut */ - if (nodeid == us->node_id && nodeid != 0) { - - up(&send_lock); - header.flags |= MSG_NOACK; /* Don't ack it! */ - - return send_to_user_port(NULL, &header, msg, vec, veclen, size); - } - - /* Copy the existing kvecs into our array and add the header on at the - * beginning */ - vectors[0].iov_base = &header; - vectors[0].iov_len = sizeof (header); - for (i = 0; i < veclen; i++) { - vectors[i + 1] = vec[i]; - } - - - /* Work out how many ACKS are wanted - *don't* reset acks_expected to - * zero if no acks are required as an ACK-needed message may still be - * outstanding */ - if (!(msg->msg_flags & MSG_NOACK)) { - if (msg->msg_namelen) - acks_expected = 1; /* Unicast */ - else - acks_expected = max(cluster_members - 1, 0); - - } - - P_COMMS - ("Sending message - tgt=%d port %d required %d acks, seq=%d, flags=%x\n", - nodeid, header.tgtport, - (msg->msg_flags & MSG_NOACK) ? 0 : acks_expected, - le16_to_cpu(header.seq), header.flags); - - /* Don't include temp nodeids in the message itself */ - if (header.tgtid < 0) - header.tgtid = 0; - - header.flags = cpu_to_le32(header.flags); - - /* For non-member sends we use all the interfaces */ - if ((nodeid < 0) || (flags & MSG_ALLINT)) { - - result = send_to_all_ints(nodeid, &our_msg, vectors, veclen+1, - size, msg->msg_flags); - } - else { - /* Send to only the current socket - resends will use the - * others if necessary */ - our_msg.msg_name = ¤t_interface->peer->saddr; - our_msg.msg_namelen = current_interface->peer->addr_len; - - result = - __send_and_save(current_interface, &our_msg, - vectors, veclen+1, - size + sizeof (header), - !(msg->msg_flags & MSG_NOACK)); - } - - /* Make a note in each nodes' structure that it has been sent a message - * so we can see which ones went astray */ - if (!(flags & MSG_NOACK) && nodeid >= 0) { - if (msg->msg_namelen) { - struct cluster_node *node; - - node = find_node_by_nodeid(le32_to_cpu(header.tgtid)); - if (node) - node->last_seq_sent = cur_seq; - } - else { - struct cluster_node *node; - struct list_head *nodelist; - - list_for_each(nodelist, &cluster_members_list) { - node = - list_entry(nodelist, struct cluster_node, - list); - if (node->state == NODESTATE_MEMBER) { - node->last_seq_sent = cur_seq; - } - } - } - } - - /* if the client wants a broadcast message sending back to itself - then loop it back */ - if (nodeid == 0 && (flags & MSG_BCASTSELF)) { - header.flags |= cpu_to_le32(MSG_NOACK); /* Don't ack it! */ - - result = send_to_user_port(NULL, &header, msg, vec, veclen, size); - } - - /* Save a copy of the message if we're expecting an ACK */ - if (!(flags & MSG_NOACK) && acks_expected) { - struct cl_protheader *savhdr = (struct cl_protheader *) saved_msg_buffer; - - memcpy_fromkvec(saved_msg_buffer, vectors, - size + sizeof (header)); - - saved_msg_len = size + sizeof (header); - retry_count = ack_count = 0; - clear_bit(RESEND_NEEDED, &mainloop_flags); - - /* Clear the REPLYEXPected flag so we force a real ACK - if it's necessary to resend this packet */ - savhdr->flags &= ~MSG_REPLYEXP; - start_ack_timer(); - } - - up(&send_lock); - return result; -} - -static int queue_message(struct socket *sock, void *buf, int len, - struct sockaddr_cl *caddr, - unsigned char port, int flags) -{ - struct queued_message *qmsg; - - qmsg = kmalloc(sizeof (struct queued_message), - (in_atomic() - || irqs_disabled())? GFP_ATOMIC : GFP_KERNEL); - if (qmsg == NULL) - return -1; - - memcpy(qmsg->msg_buffer, buf, len); - qmsg->msg_len = len; - if (caddr) { - memcpy(&qmsg->addr, caddr, sizeof (struct sockaddr_cl)); - qmsg->addr_len = sizeof (struct sockaddr_cl); - } - else { - qmsg->addr_len = 0; - } - qmsg->flags = flags; - qmsg->port = port; - qmsg->socket = sock; - - down(&messages_list_lock); - list_add_tail(&qmsg->list, &messages_list); - up(&messages_list_lock); - - wake_up_interruptible(&cnxman_waitq); - - return 0; -} - -static int cl_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size) -{ - struct cluster_sock *c = cluster_sk(sock->sk); - char *buffer; - int status; - uint8_t port; - struct kvec vec; - struct sockaddr_cl *caddr = msg->msg_name; - - if (sock->sk->sk_protocol == CLPROTO_MASTER) - return -EOPNOTSUPP; - - port = c->port; - - /* Only capable users can override the port number */ - if (caddr && capable(CAP_CLUSTER) && caddr->scl_port) - port = caddr->scl_port; - - if (port == 0) - return -EDESTADDRREQ; - - /* Allocate a kernel buffer for the data so we can put it into a kvec */ - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - if (memcpy_fromiovec(buffer, msg->msg_iov, size)) { - status = -EFAULT; - goto end_send; - } - - vec.iov_len = size; - vec.iov_base = buffer; - - status = __sendmsg(sock, msg, &vec, 1, size, port); - - end_send: - kfree(buffer); - - return status; -} - -/* Kernel call to sendmsg */ -int kcl_sendmsg(struct socket *sock, void *buf, int size, - struct sockaddr_cl *caddr, int addr_len, unsigned int flags) -{ - struct kvec vecs[1]; - struct msghdr msg; - struct cluster_sock *c = cluster_sk(sock->sk); - unsigned char port; - - if (size > MAX_CLUSTER_MESSAGE) - return -EINVAL; - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - port = c->port; - if (caddr && caddr->scl_port) - port = caddr->scl_port; - - if (port == 0) - return -EDESTADDRREQ; - - /* If we have no process context then queue it up for kclusterd to - * send. */ - if (in_interrupt() || flags & MSG_QUEUE) { - return queue_message(sock, buf, size, caddr, port, - flags & ~MSG_QUEUE); - } - - vecs[0].iov_base = buf; - vecs[0].iov_len = size; - - memset(&msg, 0, sizeof (msg)); - msg.msg_name = caddr; - msg.msg_namelen = addr_len; - msg.msg_flags = flags; - - return __sendmsg(sock, &msg, vecs, 1, size, port); -} - -static int send_queued_message(struct queued_message *qmsg) -{ - struct kvec vecs[1]; - struct msghdr msg; - - /* Don't send blocked messages */ - if (qmsg->port > HIGH_PROTECTED_PORT - && (!cluster_is_quorate || in_transition())) - return -EAGAIN; - - vecs[0].iov_base = qmsg->msg_buffer; - vecs[0].iov_len = qmsg->msg_len; - - memset(&msg, 0, sizeof (msg)); - msg.msg_name = qmsg->addr_len ? &qmsg->addr : NULL; - msg.msg_namelen = qmsg->addr_len; - msg.msg_flags = qmsg->flags; - - return __sendmsg(qmsg->socket, &msg, vecs, 1, - qmsg->msg_len, qmsg->port); -} - -int kcl_register_read_callback(struct socket *sock, - int (*routine) (char *, int, char *, int, - unsigned int)) -{ - struct cluster_sock *c = cluster_sk(sock->sk); - - c->kernel_callback = routine; - - return 0; -} - -/* Used where we are in kclusterd context and we can't allow the task to wait - * as we are also responsible to processing the ACKs that do the wake up. Try - * to send the message immediately and queue it if that's not possible */ -static int send_or_queue_message(struct socket *sock, void *buf, int len, - struct sockaddr_cl *caddr, - unsigned int flags) -{ - struct kvec vecs[1]; - struct msghdr msg; - int status; - - vecs[0].iov_base = buf; - vecs[0].iov_len = len; - - memset(&msg, 0, sizeof (msg)); - msg.msg_name = caddr; - msg.msg_namelen = caddr ? sizeof (struct sockaddr_cl) : 0; - msg.msg_flags = MSG_DONTWAIT | flags; - - status = __sendmsg(NULL, &msg, vecs, 1, len, 0); - - /* Did it work ? */ - if (status > 0) { - return 0; - } - - /* Failure other than EAGAIN is fatal */ - if (status != -EAGAIN) { - return status; - } - - return queue_message(sock, buf, len, caddr, 0, flags); -} - -/* Send a listen request to a node */ -static void send_listen_request(int nodeid, unsigned char port) -{ - struct cl_listenmsg listenmsg; - struct sockaddr_cl caddr; - - memset(&caddr, 0, sizeof (caddr)); - - /* Build the header */ - listenmsg.cmd = CLUSTER_CMD_LISTENREQ; - listenmsg.target_port = port; - listenmsg.listening = 0; - listenmsg.tag = current->pid; - - caddr.scl_family = AF_CLUSTER; - caddr.scl_port = 0; - caddr.scl_nodeid = nodeid; - - send_or_queue_message(NULL, &listenmsg, sizeof(listenmsg), &caddr, MSG_REPLYEXP); - return; -} - -/* Return 1 or 0 to indicate if we have a listener on the requested port */ -static void send_listen_response(struct cl_comms_socket *csock, int nodeid, - unsigned char port, unsigned short tag) -{ - struct cl_listenmsg listenmsg; - struct sockaddr_cl caddr; - int status; - - memset(&caddr, 0, sizeof (caddr)); - - /* Build the message */ - listenmsg.cmd = CLUSTER_CMD_LISTENRESP; - listenmsg.target_port = port; - listenmsg.tag = tag; - listenmsg.listening = (port_array[port] != 0) ? 1 : 0; - - caddr.scl_family = AF_CLUSTER; - caddr.scl_port = 0; - caddr.scl_nodeid = nodeid; - - status = send_or_queue_message(NULL, &listenmsg, - sizeof (listenmsg), - &caddr, 0); - - return; -} - -/* Send an ACK */ -static int cl_sendack(struct cl_comms_socket *csock, unsigned short seq, - int addr_len, char *addr, unsigned char remport, - unsigned char flag) -{ - struct kvec vec; - struct cl_ackmsg ackmsg; - struct msghdr msg; - struct sockaddr_in6 daddr; - int result; - -#ifdef DEBUG_COMMS - char buf[MAX_ADDR_PRINTED_LEN]; - - P_COMMS("Sending ACK to %s, seq=%d\n", - print_addr(addr, address_length, buf), le16_to_cpu(seq)); -#endif - - if (addr) { - memcpy(&daddr, addr, addr_len); - } - else { - memcpy(&daddr, &csock->saddr, csock->addr_len); - addr_len = csock->addr_len; - } - - /* Build the header */ - ackmsg.header.tgtport = 0; /* Protocol port */ - ackmsg.header.srcport = 0; - ackmsg.header.seq = 0; - ackmsg.header.flags = cpu_to_le32(MSG_NOACK); - ackmsg.header.cluster = cpu_to_le16(cluster_id); - ackmsg.header.srcid = us ? cpu_to_le32(us->node_id) : 0; - ackmsg.header.ack = seq; /* already in LE order */ - ackmsg.header.tgtid = 0; /* ACKS are unicast so we don't bother - * to look this up */ - ackmsg.cmd = CLUSTER_CMD_ACK; - ackmsg.remport = remport; - ackmsg.aflags = flag; - vec.iov_base = &ackmsg; - vec.iov_len = sizeof (ackmsg); - - memset(&msg, 0, sizeof (msg)); - msg.msg_name = &daddr; - msg.msg_namelen = addr_len; - - result = kernel_sendmsg(csock->sock, &msg, &vec, 1, sizeof (ackmsg)); - - if (result < 0) - printk(KERN_CRIT CMAN_NAME ": error sending ACK: %d\n", result); - - return result; - -} - -/* Wait for all ACKS to be gathered */ -void kcl_wait_for_all_acks() -{ - while (ack_count < acks_expected) { - - DECLARE_WAITQUEUE(wq, current); - struct task_struct *tsk = current; - - set_task_state(tsk, TASK_INTERRUPTIBLE); - add_wait_queue(&socket_waitq, &wq); - - if (ack_count < acks_expected) { - schedule(); - } - - set_task_state(tsk, TASK_RUNNING); - remove_wait_queue(&socket_waitq, &wq); - } -} - -/* Send a closedown OOB message to all cluster nodes - this tells them that a - * port listener has gone away */ -static void send_port_close_oob(unsigned char port) -{ - struct cl_closemsg closemsg; - - /* Build the header */ - closemsg.cmd = CLUSTER_CMD_PORTCLOSED; - closemsg.port = port; - - send_or_queue_message(NULL, &closemsg, sizeof (closemsg), NULL, 0); - return; -} - -/* A remote port has been closed - post an OOB message to the local listen on - * that port (if there is one) */ -static void post_close_oob(unsigned char port, int nodeid) -{ - struct cl_portclosed_oob *oobmsg; - struct sk_buff *skb; - struct sock *sock = port_array[port]; - struct cb_info *cbinfo; - - if (!sock) { - return; /* No-one listening */ - } - - skb = alloc_skb(sizeof (*oobmsg), GFP_KERNEL); - if (!skb) - return; - - skb_put(skb, sizeof (*oobmsg)); - oobmsg = (struct cl_portclosed_oob *) skb->data; - oobmsg->port = port; - oobmsg->cmd = CLUSTER_OOB_MSG_PORTCLOSED; - - cbinfo = (struct cb_info *)skb->cb; - cbinfo->oob = 1; - cbinfo->orig_nodeid = nodeid; - cbinfo->orig_port = port; - - sock_queue_rcv_skb(sock, skb); - -} - -/* Leave the cluster */ -static void node_shutdown() -{ - struct cl_barrier *barrier; - struct list_head *blist; - struct list_head *temp; - struct list_head *socklist; - struct cl_client_socket *csock; - struct sk_buff *null_skb; - - if (we_are_a_cluster_member) - printk(KERN_INFO CMAN_NAME ": we are leaving the cluster. %s\n", - us->leave_reason?leave_string(us->leave_reason):""); - - atomic_set(&cnxman_running, 0); - unjam(); - - /* Notify kernel listeners first */ - notify_kernel_listeners(LEAVING, 0); - - /* Notify client sockets */ - down(&client_socket_lock); - list_for_each_safe(socklist, temp, &client_socket_list) { - csock = list_entry(socklist, struct cl_client_socket, list); - - null_skb = alloc_skb(0, GFP_KERNEL); - if (null_skb) - sock_queue_rcv_skb(csock->sock->sk, null_skb); - list_del(&csock->list); - kfree(csock); - } - up(&client_socket_lock); - we_are_a_cluster_member = 0; - cluster_is_quorate = 0; - - sm_stop(1); - - /* Wake up any processes waiting for barriers */ - down(&barrier_list_lock); - list_for_each(blist, &barrier_list) { - barrier = list_entry(blist, struct cl_barrier, list); - - /* Cancel any timers */ - if (timer_pending(&barrier->timer)) - del_timer(&barrier->timer); - - /* Force it to be auto-delete so it discards itself */ - if (barrier->state == BARRIER_STATE_WAITING) { - barrier->flags |= BARRIER_ATTR_AUTODELETE; - wake_up_interruptible(&barrier->waitq); - } - else { - if (barrier->callback) { - barrier->callback(barrier->name, -ENOTCONN); - barrier->callback = NULL; - } - } - } - up(&barrier_list_lock); - - /* Wake up any processes waiting for ISLISTENING requests */ - down(&listenreq_lock); - list_for_each(blist, &listenreq_list) { - struct cl_waiting_listen_request *lrequest = - list_entry(blist, struct cl_waiting_listen_request, list); - - if (lrequest->waiting) - wake_up_interruptible(&lrequest->waitq); - } - up(&listenreq_lock); -} - -static void free_cluster_sockets() -{ - struct list_head *socklist; - struct cl_comms_socket *sock; - struct list_head *temp; - - list_for_each_safe(socklist, temp, &socket_list) { - sock = list_entry(socklist, struct cl_comms_socket, list); - - list_del(&sock->list); - fput(sock->file); - kfree(sock); - } - num_interfaces = 0; - current_interface = NULL; -} - -/* Tidy up after all the rest of the cluster bits have shut down */ -static void node_cleanup() -{ - struct list_head *nodelist; - struct list_head *proclist; - struct list_head *temp; - struct list_head *socklist; - struct list_head *blist; - struct temp_node *tn; - struct temp_node *tmp; - struct cl_comms_socket *sock; - struct kernel_notify_struct *knotify; - struct queued_message *qmsg, *qtmp; - - /* Free list of kernel listeners */ - list_for_each_safe(proclist, temp, &kernel_listener_list) { - knotify = - list_entry(proclist, struct kernel_notify_struct, list); - list_del(&knotify->list); - kfree(knotify); - } - - /* Mark the sockets as busy so they don't get added to the active - * sockets list in the next few lines of code before we free them */ - list_for_each_safe(socklist, temp, &socket_list) { - sock = list_entry(socklist, struct cl_comms_socket, list); - - set_bit(1, &sock->active); - } - - /* Tidy the active sockets list */ - list_for_each_safe(socklist, temp, &active_socket_list) { - sock = - list_entry(socklist, struct cl_comms_socket, active_list); - list_del(&sock->active_list); - } - - /* Free the memory allocated to cluster nodes */ - free_nodeid_array(); - down(&cluster_members_lock); - us = NULL; - list_for_each_safe(nodelist, temp, &cluster_members_list) { - - struct list_head *addrlist; - struct list_head *addrtemp; - struct cluster_node *node; - struct cluster_node_addr *nodeaddr; - - node = list_entry(nodelist, struct cluster_node, list); - - list_for_each_safe(addrlist, addrtemp, &node->addr_list) { - nodeaddr = - list_entry(addrlist, struct cluster_node_addr, - list); - - list_del(&nodeaddr->list); - kfree(nodeaddr); - } - list_del(&node->list); - kfree(node->name); - kfree(node); - } - cluster_members = 0; - up(&cluster_members_lock); - - /* Clean the queued messages list */ - down(&messages_list_lock); - list_for_each_entry_safe(qmsg, qtmp, &messages_list, list) { - list_del(&qmsg->list); - kfree(qmsg); - } - up(&messages_list_lock); - - /* Clean the temp node IDs list. */ - down(&tempnode_lock); - list_for_each_entry_safe(tn, tmp, &tempnode_list, list) { - list_del(&tn->list); - kfree(tn); - } - up(&tempnode_lock); - - /* Free the memory allocated to the outgoing sockets */ - free_cluster_sockets(); - - /* Make sure that all the barriers are deleted */ - down(&barrier_list_lock); - list_for_each_safe(blist, temp, &barrier_list) { - struct cl_barrier *barrier = - list_entry(blist, struct cl_barrier, list); - - list_del(&barrier->list); - kfree(barrier); - } - up(&barrier_list_lock); - - kcluster_pid = 0; - clear_bit(RESEND_NEEDED, &mainloop_flags); - acks_expected = 0; - wanted_nodeid = 0; - cur_seq = 0; - cluster_id = 0; - quorum_device = NULL; -} - -/* If "cluster_is_quorate" is 0 then all activity apart from protected ports is - * blocked. */ -void set_quorate(int total_votes) -{ - int quorate; - - if (get_quorum() > total_votes) { - quorate = 0; - } - else { - quorate = 1; - } - - if (cluster_is_quorate && !quorate) - printk(KERN_CRIT CMAN_NAME - ": quorum lost, blocking activity\n"); - if (!cluster_is_quorate && quorate) - printk(KERN_CRIT CMAN_NAME - ": quorum regained, resuming activity\n"); - - cluster_is_quorate = quorate; - - /* Wake up any sleeping processes */ - if (cluster_is_quorate) { - unjam(); - } - -} - -void queue_oob_skb(struct socket *sock, int cmd) -{ - struct sk_buff *skb; - struct cb_info *cbinfo; - struct cl_portclosed_oob *oobmsg; - - skb = alloc_skb(sizeof (*oobmsg), GFP_KERNEL); - if (!skb) - return; - - skb_put(skb, sizeof (*oobmsg)); - oobmsg = (struct cl_portclosed_oob *) skb->data; - oobmsg->port = 0; - oobmsg->cmd = cmd; - - /* There is no remote node associated with this so - clear out the field to avoid any accidents */ - cbinfo = (struct cb_info *)skb->cb; - cbinfo->oob = 1; - cbinfo->orig_nodeid = 0; - cbinfo->orig_port = 0; - - sock_queue_rcv_skb(sock->sk, skb); -} - -/* Notify interested parties that the cluster configuration has changed */ -void notify_listeners() -{ - struct notify_struct *notify; - struct list_head *proclist; - struct list_head *socklist; - struct list_head *temp; - - /* Do kernel listeners first */ - notify_kernel_listeners(CLUSTER_RECONFIG, 0); - - /* Now we deign to tell userspace */ - down(&event_listener_lock); - list_for_each_safe(proclist, temp, &event_listener_list) { - notify = list_entry(proclist, struct notify_struct, list); - - /* If the kill fails then remove the process from the list */ - if (kill_proc(notify->pid, notify->signal, 0) == -ESRCH) { - list_del(¬ify->list); - kfree(notify); - } - } - up(&event_listener_lock); - - /* Tell userspace processes which want OOB messages */ - down(&client_socket_lock); - list_for_each(socklist, &client_socket_list) { - struct cl_client_socket *csock; - csock = list_entry(socklist, struct cl_client_socket, list); - queue_oob_skb(csock->sock, CLUSTER_OOB_MSG_STATECHANGE); - } - up(&client_socket_lock); -} - -/* This fills in the list of all addresses for the local node */ -void get_local_addresses(struct cluster_node *node) -{ - struct list_head *socklist; - struct cl_comms_socket *sock; - - list_for_each(socklist, &socket_list) { - sock = list_entry(socklist, struct cl_comms_socket, list); - - if (sock->recv_only) { - add_node_address(node, (char *) &sock->saddr, address_length); - } - } -} - - -static uint16_t generate_cluster_id(char *name) -{ - int i; - int value = 0; - - for (i=0; i<strlen(name); i++) { - value <<= 1; - value += name[i]; - } - return value & 0xFFFF; -} - -/* Return the next comms socket we can use. */ -static struct cl_comms_socket *get_next_interface(struct cl_comms_socket *cur) -{ - int next; - struct list_head *socklist; - - /* Fast path for single interface systems */ - if (num_interfaces <= 1) - return cur; - - /* Next number */ - next = cur->number + 1; - if (next > num_interfaces) - next = 1; - - /* Find the socket with this number, I could optimise this by starting - * at the current i/f but most systems are going to have a small number - * of them anyway */ - list_for_each(socklist, &socket_list) { - struct cl_comms_socket *sock; - sock = list_entry(socklist, struct cl_comms_socket, list); - - if (sock->recv_only && sock->number == next) - return sock; - } - - BUG(); - return NULL; -} - -static struct cl_comms_socket *get_peer_interface(int if_num, int mcast) -{ - struct list_head *socklist; - - list_for_each(socklist, &socket_list) { - struct cl_comms_socket *sock; - sock = list_entry(socklist, struct cl_comms_socket, list); - - if (sock->broadcast == mcast && sock->number == if_num) - return sock; - } - - return NULL; -} - - -/* MUST be called with the barrier list lock held */ -static struct cl_barrier *find_barrier(char *name) -{ - struct list_head *blist; - struct cl_barrier *bar; - - list_for_each(blist, &barrier_list) { - bar = list_entry(blist, struct cl_barrier, list); - - if (strcmp(name, bar->name) == 0) - return bar; - } - return NULL; -} - -static void tidy_barriers(void) -{ - struct list_head *blist, *tmp; - struct cl_barrier *bar; - - down(&barrier_list_lock); - list_for_each_safe(blist, tmp, &barrier_list) { - bar = list_entry(blist, struct cl_barrier, list); - - if (bar->state == BARRIER_STATE_DELETED) { - P_BARRIER("Deleting barrier %s\n", bar->name); - list_del(&bar->list); - kfree(bar); - } - } - up(&barrier_list_lock); -} - -/* Do the stuff we need to do when the barrier has completed phase 1 */ -static void check_barrier_complete_phase1(struct cl_barrier *barrier) -{ - if (atomic_read(&barrier->got_nodes) == ((barrier->expected_nodes != 0) - ? barrier->expected_nodes : - cluster_members)) { - - struct cl_barriermsg bmsg; - - atomic_inc(&barrier->completed_nodes); /* We have completed */ - barrier->phase = 2; /* Wait for complete phase II */ - - /* Send completion message, remember: we are in cnxman context - * and must not block */ - bmsg.cmd = CLUSTER_CMD_BARRIER; - bmsg.subcmd = BARRIER_COMPLETE; - bmsg.flags = 0; - strcpy(bmsg.name, barrier->name); - - P_BARRIER("Sending COMPLETE for %s\n", barrier->name); - queue_message(NULL, (char *) &bmsg, sizeof (bmsg), NULL, 0, 0); - } -} - -/* Do the stuff we need to do when the barrier has been reached */ -/* Return 1 if we deleted the barrier */ -static int check_barrier_complete_phase2(struct cl_barrier *barrier, int status) -{ - spin_lock_irq(&barrier->phase2_spinlock); - - if (barrier->state != BARRIER_STATE_COMPLETE && - (status == -ETIMEDOUT || - atomic_read(&barrier->completed_nodes) == - ((barrier->expected_nodes != 0) - ? barrier->expected_nodes : cluster_members))) { - - if (status == 0 && barrier->timeout) - del_timer(&barrier->timer); - barrier->endreason = status; - - /* Wake up listener */ - if (barrier->state == BARRIER_STATE_WAITING) { - wake_up_interruptible(&barrier->waitq); - } - else { - /* Additional tasks we have to do if the user was not - * waiting... */ - /* Call the callback */ - if (barrier->callback) { - barrier->callback(barrier->name, 0); - barrier->callback = NULL; - } - /* Flag it to be removed it if it's AUTO-DELETE. - We can't actually remove it because we can't get the barrier semaphore - in timer context */ - if (barrier->flags & BARRIER_ATTR_AUTODELETE) { - barrier->state = BARRIER_STATE_DELETED; - set_bit(TIDY_BARRIERS, &mainloop_flags); - wake_up_interruptible(&cnxman_waitq); - spin_unlock_irq(&barrier->phase2_spinlock); - return 1; - } - } - barrier->state = BARRIER_STATE_COMPLETE; - } - spin_unlock_irq(&barrier->phase2_spinlock); - return 0; -} - -/* Called if a barrier timeout happens */ -static void barrier_timer_fn(unsigned long arg) -{ - struct cl_barrier *barrier = (struct cl_barrier *) arg; - - /* Ignore any further messages, they are too late. */ - barrier->phase = 0; - - /* and cause it to timeout */ - check_barrier_complete_phase2(barrier, -ETIMEDOUT); -} - -/* Process BARRIER messages from other nodes */ -static void process_barrier_msg(struct cl_barriermsg *msg, - struct cluster_node *node) -{ - struct cl_barrier *barrier; - - down(&barrier_list_lock); - barrier = find_barrier(msg->name); - up(&barrier_list_lock); - - /* Ignore other peoples messages, in_transition() is needed here so - * that joining nodes will see their barrier messages before the - * we_are_a_cluster_member is set */ - if (!we_are_a_cluster_member && !in_transition()) - return; - if (!barrier) - return; - - P_BARRIER("Got %d for %s, from node %s\n", msg->subcmd, msg->name, - node ? node->name : "unknown"); - - switch (msg->subcmd) { - case BARRIER_WAIT: - down(&barrier->lock); - if (barrier->phase == 0) - barrier->phase = 1; - - if (barrier->phase == 1) { - atomic_inc(&barrier->got_nodes); - check_barrier_complete_phase1(barrier); - } - else { - printk(KERN_WARNING CMAN_NAME - ": got WAIT barrier not in phase 1 %s (%d)\n", - msg->name, barrier->phase); - - } - up(&barrier->lock); - break; - - case BARRIER_COMPLETE: - down(&barrier->lock); - atomic_inc(&barrier->completed_nodes); - - /* First node to get all the WAIT messages sends COMPLETE, so - * we all complete */ - if (barrier->phase == 1) { - if (barrier->expected_nodes) - atomic_set(&barrier->got_nodes, barrier->expected_nodes); - else - atomic_set(&barrier->got_nodes, cluster_members); - check_barrier_complete_phase1(barrier); - } - - if (barrier->phase == 2) { - /* If it was deleted (ret==1) then no need to unlock - * the mutex */ - if (check_barrier_complete_phase2(barrier, 0) == 1) - return; - } - up(&barrier->lock); - break; - } -} - -/* In-kernel membership API */ -int kcl_add_callback(void (*callback) (kcl_callback_reason, long arg)) -{ - struct kernel_notify_struct *notify; - - notify = kmalloc(sizeof (struct kernel_notify_struct), GFP_KERNEL); - if (!notify) - return -ENOMEM; - notify->callback = callback; - - down(&kernel_listener_lock); - list_add(¬ify->list, &kernel_listener_list); - up(&kernel_listener_lock); - - return 0; -} - -int kcl_remove_callback(void (*callback) (kcl_callback_reason, long arg)) -{ - struct list_head *calllist; - struct list_head *temp; - struct kernel_notify_struct *notify; - - down(&kernel_listener_lock); - list_for_each_safe(calllist, temp, &kernel_listener_list) { - notify = list_entry(calllist, struct kernel_notify_struct, list); - if (notify->callback == callback){ - list_del(¬ify->list); - kfree(notify); - up(&kernel_listener_lock); - return 0; - } - } - up(&kernel_listener_lock); - return -EINVAL; -} - -/* Return quorate status */ -int kcl_is_quorate() -{ - return cluster_is_quorate; -} - -/* Return the address list for a node */ -struct list_head *kcl_get_node_addresses(int nodeid) -{ - struct cluster_node *node = find_node_by_nodeid(nodeid); - - if (node) - return &node->addr_list; - else - return NULL; -} - -static void copy_to_kclnode(struct cluster_node *node, - struct kcl_cluster_node *knode) -{ - strcpy(knode->name, node->name); - knode->size = sizeof (struct kcl_cluster_node); - knode->votes = node->votes; - knode->state = node->state; - knode->node_id = node->node_id; - knode->us = node->us; - knode->leave_reason = node->leave_reason; - knode->incarnation = node->incarnation; -} - -/* Return the info for a node given it's address. if addr is NULL then return - * OUR info */ -int kcl_get_node_by_addr(unsigned char *addr, int addr_len, - struct kcl_cluster_node *n) -{ - struct cluster_node *node; - - /* They want us */ - if (addr == NULL) { - node = us; - } - else { - node = find_node_by_addr(addr, addr_len); - if (!node) - return -1; - } - - /* Copy to user's buffer */ - copy_to_kclnode(node, n); - return 0; -} - -int kcl_get_node_by_name(unsigned char *name, struct kcl_cluster_node *n) -{ - struct cluster_node *node; - - /* They want us */ - if (name == NULL) { - node = us; - if (node == NULL) - return -1; - } - else { - node = find_node_by_name(name); - if (!node) - return -1; - } - - /* Copy to user's buffer */ - copy_to_kclnode(node, n); - return 0; -} - -/* As above but by node id. MUCH faster */ -int kcl_get_node_by_nodeid(int nodeid, struct kcl_cluster_node *n) -{ - struct cluster_node *node; - - /* They want us */ - if (nodeid == 0) { - node = us; - if (node == NULL) - return -1; - } - else { - node = find_node_by_nodeid(nodeid); - if (!node) - return -1; - } - - /* Copy to user's buffer */ - copy_to_kclnode(node, n); - return 0; -} - -/* Return a list of all cluster members ever */ -int kcl_get_all_members(struct list_head *list) -{ - struct list_head *nodelist; - struct cluster_node *node; - struct kcl_cluster_node *newnode; - int num_nodes = 0; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - if (list) { - node = list_entry(nodelist, struct cluster_node, list); - newnode = - kmalloc(sizeof (struct kcl_cluster_node), - GFP_KERNEL); - if (newnode) { - copy_to_kclnode(node, newnode); - list_add(&newnode->list, list); - num_nodes++; - } - } - else { - num_nodes++; - } - } - up(&cluster_members_lock); - - return num_nodes; -} - -/* Return a list of cluster members */ -int kcl_get_members(struct list_head *list) -{ - struct list_head *nodelist; - struct cluster_node *node; - struct kcl_cluster_node *newnode; - int num_nodes = 0; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->state == NODESTATE_MEMBER) { - if (list) { - newnode = - kmalloc(sizeof (struct kcl_cluster_node), - GFP_KERNEL); - if (newnode) { - copy_to_kclnode(node, newnode); - list_add(&newnode->list, list); - num_nodes++; - } - } - else { - num_nodes++; - } - } - } - up(&cluster_members_lock); - - return num_nodes; -} - -/* Copy current member's nodeids into buffer */ -int kcl_get_member_ids(uint32_t *idbuf, int size) -{ - struct list_head *nodelist; - struct cluster_node *node; - int num_nodes = 0; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->state == NODESTATE_MEMBER) { - if (idbuf && size) { - idbuf[num_nodes] = node->node_id; - num_nodes++; - size--; - } - else { - num_nodes++; - } - } - } - up(&cluster_members_lock); - - return num_nodes; -} - -/* Barrier API */ -int kcl_barrier_register(char *name, unsigned int flags, unsigned int nodes) -{ - struct cl_barrier *barrier; - - /* We are not joined to a cluster */ - if (!we_are_a_cluster_member) - return -ENOENT; - - /* Must have a valid name */ - if (name == NULL || strlen(name) > MAX_BARRIER_NAME_LEN - 1) - return -EINVAL; - - /* We don't do this yet */ - if (flags & BARRIER_ATTR_MULTISTEP) - return -ENOTSUPP; - - down(&barrier_list_lock); - - /* See if it already exists */ - if ((barrier = find_barrier(name))) { - up(&barrier_list_lock); - if (nodes != barrier->expected_nodes) { - printk(KERN_WARNING CMAN_NAME - ": Barrier registration failed for '%s', expected nodes=%d, requested=%d\n", - name, barrier->expected_nodes, nodes); - return -EINVAL; - } - else - return 0; - } - - /* Build a new struct and add it to the list */ - barrier = kmalloc(sizeof (struct cl_barrier), GFP_KERNEL); - if (barrier == NULL) { - up(&barrier_list_lock); - return -ENOMEM; - } - memset(barrier, 0, sizeof (*barrier)); - - strcpy(barrier->name, name); - barrier->flags = flags; - barrier->expected_nodes = nodes; - atomic_set(&barrier->got_nodes, 0); - atomic_set(&barrier->completed_nodes, 0); - barrier->endreason = 0; - barrier->registered_nodes = 1; - spin_lock_init(&barrier->phase2_spinlock); - barrier->state = BARRIER_STATE_INACTIVE; - init_MUTEX(&barrier->lock); - - list_add(&barrier->list, &barrier_list); - up(&barrier_list_lock); - - return 0; -} - -static int barrier_setattr_enabled(struct cl_barrier *barrier, - unsigned int attr, unsigned long arg) -{ - int status; - - /* Can't disable a barrier */ - if (!arg) { - up(&barrier->lock); - return -EINVAL; - } - - /* We need to send WAIT now because the user may not - * actually call kcl_barrier_wait() */ - if (!barrier->waitsent) { - struct cl_barriermsg bmsg; - - /* Send it to the rest of the cluster */ - bmsg.cmd = CLUSTER_CMD_BARRIER; - bmsg.subcmd = BARRIER_WAIT; - strcpy(bmsg.name, barrier->name); - - barrier->waitsent = 1; - barrier->phase = 1; - - atomic_inc(&barrier->got_nodes); - - /* Start the timer if one was wanted */ - if (barrier->timeout) { - init_timer(&barrier->timer); - barrier->timer.function = barrier_timer_fn; - barrier->timer.data = (long) barrier; - mod_timer(&barrier->timer, jiffies + (barrier->timeout * HZ)); - } - - /* Barrier WAIT and COMPLETE messages are - * always queued - that way they always get - * sent out in the right order. If we don't do - * this then one can get sent out in the - * context of the user process and the other in - * cnxman and COMPLETE may /just/ slide in - * before WAIT if its in the queue - */ - P_BARRIER("Sending WAIT for %s\n", barrier->name); - status = queue_message(NULL, &bmsg, sizeof (bmsg), NULL, 0, 0); - if (status < 0) { - up(&barrier->lock); - return status; - } - - /* It might have been reached now */ - if (barrier - && barrier->state != BARRIER_STATE_COMPLETE - && barrier->phase == 1) - check_barrier_complete_phase1(barrier); - } - if (barrier && barrier->state == BARRIER_STATE_COMPLETE) { - up(&barrier->lock); - return barrier->endreason; - } - up(&barrier->lock); - return 0; /* Nothing to propogate */ -} - -int kcl_barrier_setattr(char *name, unsigned int attr, unsigned long arg) -{ - struct cl_barrier *barrier; - - /* See if it already exists */ - down(&barrier_list_lock); - if (!(barrier = find_barrier(name))) { - up(&barrier_list_lock); - return -ENOENT; - } - up(&barrier_list_lock); - - down(&barrier->lock); - if (barrier->state == BARRIER_STATE_COMPLETE) { - up(&barrier->lock); - return 0; - } - - switch (attr) { - case BARRIER_SETATTR_AUTODELETE: - if (arg) - barrier->flags |= BARRIER_ATTR_AUTODELETE; - else - barrier->flags &= ~BARRIER_ATTR_AUTODELETE; - up(&barrier->lock); - return 0; - break; - - case BARRIER_SETATTR_TIMEOUT: - /* Can only change the timout of an inactive barrier */ - if (barrier->state == BARRIER_STATE_WAITING - || barrier->waitsent) { - up(&barrier->lock); - return -EINVAL; - } - barrier->timeout = arg; - up(&barrier->lock); - return 0; - - case BARRIER_SETATTR_MULTISTEP: - up(&barrier->lock); - return -ENOTSUPP; - - case BARRIER_SETATTR_ENABLED: - return barrier_setattr_enabled(barrier, attr, arg); - - case BARRIER_SETATTR_NODES: - /* Can only change the expected node count of an inactive - * barrier */ - if (barrier->state == BARRIER_STATE_WAITING - || barrier->waitsent) - return -EINVAL; - barrier->expected_nodes = arg; - break; - - case BARRIER_SETATTR_CALLBACK: - if (barrier->state == BARRIER_STATE_WAITING - || barrier->waitsent) - return -EINVAL; - barrier->callback = (void (*)(char *, int)) arg; - up(&barrier->lock); - return 0; /* Don't propgate this to other nodes */ - } - - up(&barrier->lock); - return 0; -} - -int kcl_barrier_delete(char *name) -{ - struct cl_barrier *barrier; - - down(&barrier_list_lock); - /* See if it exists */ - if (!(barrier = find_barrier(name))) { - up(&barrier_list_lock); - return -ENOENT; - } - - /* Delete it */ - list_del(&barrier->list); - kfree(barrier); - - up(&barrier_list_lock); - - return 0; -} - -int kcl_barrier_cancel(char *name) -{ - struct cl_barrier *barrier; - - /* See if it exists */ - down(&barrier_list_lock); - if (!(barrier = find_barrier(name))) { - up(&barrier_list_lock); - return -ENOENT; - } - down(&barrier->lock); - - barrier->endreason = -ENOTCONN; - - if (barrier->callback) { - barrier->callback(barrier->name, -ECONNRESET); - barrier->callback = NULL; - } - - if (barrier->timeout) - del_timer(&barrier->timer); - - /* Remove it if it's AUTO-DELETE */ - if (barrier->flags & BARRIER_ATTR_AUTODELETE) { - list_del(&barrier->list); - up(&barrier->lock); - kfree(barrier); - up(&barrier_list_lock); - return 0; - } - - if (barrier->state == BARRIER_STATE_WAITING) - wake_up_interruptible(&barrier->waitq); - - up(&barrier->lock); - up(&barrier_list_lock); - return 0; -} - -int kcl_barrier_wait(char *name) -{ - struct cl_barrier *barrier; - int ret; - - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - - /* Enable it */ - kcl_barrier_setattr(name, BARRIER_SETATTR_ENABLED, 1L); - - down(&barrier_list_lock); - - /* See if it still exists - enable may have deleted it! */ - if (!(barrier = find_barrier(name))) { - up(&barrier_list_lock); - return -ENOENT; - } - - down(&barrier->lock); - - up(&barrier_list_lock); - - /* If it has already completed then return the status */ - if (barrier->state == BARRIER_STATE_COMPLETE) { - up(&barrier->lock); - return barrier->endreason; - } - - barrier->state = BARRIER_STATE_WAITING; - - /* Have we all reached the barrier? */ - while (atomic_read(&barrier->completed_nodes) != - ((barrier->expected_nodes == 0) - ? cluster_members : barrier->expected_nodes) - && barrier->endreason == 0) { - - wait_queue_t wq; - - init_waitqueue_entry(&wq, current); - init_waitqueue_head(&barrier->waitq); - - /* Wait for em all */ - set_task_state(current, TASK_INTERRUPTIBLE); - add_wait_queue(&barrier->waitq, &wq); - - if (atomic_read(&barrier->completed_nodes) != - ((barrier->expected_nodes == - 0) ? cluster_members : barrier->expected_nodes) - && barrier->endreason == 0) { - up(&barrier->lock); - schedule(); - down(&barrier->lock); - } - - remove_wait_queue(&barrier->waitq, &wq); - set_task_state(current, TASK_RUNNING); - - if (signal_pending(current)) { - barrier->endreason = -EINTR; - break; - } - } - barrier->state = BARRIER_STATE_INACTIVE; - - if (barrier->timeout) - del_timer(&barrier->timer); - - /* Barrier has been reached on all nodes, call the callback */ - if (barrier->callback) { - barrier->callback(barrier->name, barrier->endreason); - barrier->callback = NULL; - } - - atomic_set(&barrier->got_nodes, 0); - - /* Return the reason we were woken */ - ret = barrier->endreason; - - /* Remove it if it's AUTO-DELETE */ - if (barrier->flags & BARRIER_ATTR_AUTODELETE) { - down(&barrier_list_lock); - list_del(&barrier->list); - up(&barrier_list_lock); - up(&barrier->lock); - kfree(barrier); - } - else { - up(&barrier->lock); - } - - /* We were woken up because the node left the cluster ? */ - if (!atomic_read(&cnxman_running)) - ret = -ENOTCONN; - - return ret; -} - -/* This is called from membership services when a node has left the cluster - - * we signal all waiting barriers with -ESRCH so they know to do something - * else, if the number of nodes is left at 0 then we compare the new number of - * nodes in the cluster with that at the barrier and return 0 (success) in that - * case */ -void check_barrier_returns() -{ - struct list_head *blist; - struct list_head *llist; - struct cl_barrier *barrier; - int status = 0; - - down(&barrier_list_lock); - list_for_each(blist, &barrier_list) { - barrier = list_entry(blist, struct cl_barrier, list); - - if (barrier->waitsent) { - int wakeit = 0; - - /* Check for a dynamic member barrier */ - if (barrier->expected_nodes == 0) { - if (barrier->registered_nodes == - cluster_members) { - status = 0; - wakeit = 1; - } - } - else { - status = -ESRCH; - wakeit = 1; - } - - /* Do we need to tell the barrier? */ - if (wakeit) { - if (barrier->state == BARRIER_STATE_WAITING) { - barrier->endreason = status; - wake_up_interruptible(&barrier->waitq); - } - else { - if (barrier->callback) { - barrier->callback(barrier->name, - status); - } - } - } - } - } - up(&barrier_list_lock); - - /* Part 2 check for outstanding listen requests for dead nodes and - * cancel them */ - down(&listenreq_lock); - list_for_each(llist, &listenreq_list) { - struct cl_waiting_listen_request *lrequest = - list_entry(llist, struct cl_waiting_listen_request, list); - struct cluster_node *node = - find_node_by_nodeid(lrequest->nodeid); - - if (node && node->state != NODESTATE_MEMBER) { - lrequest->result = -ENOTCONN; - lrequest->waiting = 0; - wake_up_interruptible(&lrequest->waitq); - } - } - up(&listenreq_lock); -} - -int get_addr_from_temp_nodeid(int nodeid, char *addr, int *addrlen) -{ - struct temp_node *tn; - int err = 1; /* true */ -#ifdef DEBUG_COMMS - char buf[MAX_ADDR_PRINTED_LEN]; -#endif - - down(&tempnode_lock); - - list_for_each_entry(tn, &tempnode_list, list) { - if (tn->nodeid == nodeid) { - memcpy(addr, tn->addr, tn->addrlen); - *addrlen = tn->addrlen; - P_COMMS("get_temp_nodeid. id %d:\n: %s\n", - tn->nodeid, print_addr(tn->addr, tn->addrlen, buf)); - - goto out; - } - } - err = 0; - - out: - up(&tempnode_lock); - return err; -} - -/* Create a new temporary node ID. This list will only ever be very small - (usaully only 1 item) but I can't take the risk that someone won't try to - boot 128 nodes all at exactly the same time. */ -int new_temp_nodeid(char *addr, int addrlen) -{ - struct temp_node *tn; - int err = -1; - int try_nodeid = 0; -#ifdef DEBUG_COMMS - char buf[MAX_ADDR_PRINTED_LEN]; -#endif - - P_COMMS("new_temp_nodeid needed for\n: %s\n", - print_addr(addr, addrlen, buf)); - - down(&tempnode_lock); - - /* First see if we already know about this node */ - list_for_each_entry(tn, &tempnode_list, list) { - - P_COMMS("new_temp_nodeid list. id %d:\n: %s\n", - tn->nodeid, print_addr(tn->addr, tn->addrlen, buf)); - - /* We're already in here... */ - if (tn->addrlen == addrlen && - memcmp(tn->addr, addr, addrlen) == 0) { - P_COMMS("reused temp node ID %d\n", tn->nodeid); - err = tn->nodeid; - goto out; - } - } - - /* Nope, OK, invent a suitable number */ - retry: - try_nodeid -= 1; - list_for_each_entry(tn, &tempnode_list, list) { - - if (tn->nodeid == try_nodeid) - goto retry; - } - - tn = kmalloc(sizeof(struct temp_node), GFP_KERNEL); - if (!tn) - goto out; - - memcpy(tn->addr, addr, addrlen); - tn->addrlen = addrlen; - tn->nodeid = try_nodeid; - list_add_tail(&tn->list, &tempnode_list); - err = try_nodeid; - P_COMMS("new temp nodeid = %d\n", try_nodeid); - out: - up(&tempnode_lock); - return err; -} - -static int is_valid_temp_nodeid(int nodeid) -{ - struct temp_node *tn; - int err = 1; /* true */ - - down(&tempnode_lock); - - list_for_each_entry(tn, &tempnode_list, list) { - if (tn->nodeid == nodeid) - goto out; - } - err = 0; - - out: - P_COMMS("is_valid_temp_nodeid. %d = %d\n", nodeid, err); - up(&tempnode_lock); - return err; -} - -/* - * Remove any temp nodeIDs that refer to now-valid cluster members. - */ -void purge_temp_nodeids() -{ - struct temp_node *tn; - struct temp_node *tmp; - struct cluster_node *node; - struct cluster_node_addr *nodeaddr; - - - down(&tempnode_lock); - down(&cluster_members_lock); - - /* - * The ordering of these nested lists is deliberately - * arranged for the fewest list traversals overall - */ - - /* For each node... */ - list_for_each_entry(node, &cluster_members_list, list) { - if (node->state == NODESTATE_MEMBER) { - /* ...We check the temp node ID list... */ - list_for_each_entry_safe(tn, tmp, &tempnode_list, list) { - - /* ...against that node's address */ - list_for_each_entry(nodeaddr, &node->addr_list, list) { - - if (memcmp(nodeaddr->addr, tn->addr, tn->addrlen) == 0) { - list_del(&tn->list); - kfree(tn); - } - } - } - } - } - up(&cluster_members_lock); - up(&tempnode_lock); -} - - -/* Quorum device functions */ -int kcl_register_quorum_device(char *name, int votes) -{ - if (quorum_device) - return -EBUSY; - - if (find_node_by_name(name)) - return -EINVAL; - - quorum_device = kmalloc(sizeof (struct cluster_node), GFP_KERNEL); - if (!quorum_device) - return -ENOMEM; - memset(quorum_device, 0, sizeof (struct cluster_node)); - - quorum_device->name = kmalloc(strlen(name) + 1, GFP_KERNEL); - if (!quorum_device->name) { - kfree(quorum_device); - quorum_device = NULL; - return -ENOMEM; - } - - strcpy(quorum_device->name, name); - quorum_device->votes = votes; - quorum_device->state = NODESTATE_DEAD; - - /* Keep this list valid so it doesn't confuse other code */ - INIT_LIST_HEAD(&quorum_device->addr_list); - - return 0; -} - -int kcl_unregister_quorum_device(void) -{ - if (!quorum_device) - return -EINVAL; - if (quorum_device->state == NODESTATE_MEMBER) - return -EINVAL; - - quorum_device = NULL; - - return 0; -} - -int kcl_quorum_device_available(int yesno) -{ - if (!quorum_device) - return -EINVAL; - - if (yesno) { - quorum_device->last_hello = jiffies; - if (quorum_device->state == NODESTATE_DEAD) { - quorum_device->state = NODESTATE_MEMBER; - recalculate_quorum(0); - sm_member_update(cluster_is_quorate); - } - } - else { - if (quorum_device->state == NODESTATE_MEMBER) { - quorum_device->state = NODESTATE_DEAD; - recalculate_quorum(0); - sm_member_update(cluster_is_quorate); - } - } - - return 0; -} - -/* APIs for cluster ref counting. */ -int kcl_addref_cluster() -{ - int ret = -ENOTCONN; - - if (!atomic_read(&cnxman_running)) - goto addref_ret; - - if (try_module_get(THIS_MODULE)) { - atomic_inc(&use_count); - ret = 0; - } - - addref_ret: - return ret; -} - -int kcl_releaseref_cluster() -{ - if (!atomic_read(&cnxman_running)) - return -ENOTCONN; - atomic_dec(&use_count); - module_put(THIS_MODULE); - return 0; -} - -int kcl_cluster_name(char **cname) -{ - char *name; - - name = kmalloc(strlen(cluster_name) + 1, GFP_KERNEL); - if (!name) - return -ENOMEM; - - strncpy(name, cluster_name, strlen(cluster_name)+1); - *cname = name; - return 0; -} - -int kcl_get_current_interface(void) -{ - return current_interface->number; -} - -/* Socket registration stuff */ -static struct net_proto_family cl_family_ops = { - .family = AF_CLUSTER, - .create = cl_create, - .owner = THIS_MODULE, -}; - -static struct proto_ops cl_proto_ops = { - .family = AF_CLUSTER, - - .release = cl_release, - .bind = cl_bind, - .connect = sock_no_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = cl_getname, - .poll = cl_poll, - .ioctl = cl_ioctl, - .listen = sock_no_listen, - .shutdown = cl_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = cl_sendmsg, - .recvmsg = cl_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, - .owner = THIS_MODULE, -}; - -#ifdef MODULE -MODULE_DESCRIPTION("Cluster Connection and Service Manager"); -MODULE_AUTHOR("Red Hat, Inc"); -MODULE_LICENSE("GPL"); -#endif - -static int __init cluster_init(void) -{ - printk("CMAN %s (built %s %s) installed\n", - CMAN_RELEASE_NAME, __DATE__, __TIME__); - - if (sock_register(&cl_family_ops)) { - printk(KERN_INFO "Unable to register cluster socket type\n"); - return -1; - } - - /* allocate our sock slab cache */ - cluster_sk_cachep = kmem_cache_create("cluster_sock", - sizeof (struct cluster_sock), 0, - SLAB_HWCACHE_ALIGN, 0, 0); - if (!cluster_sk_cachep) { - printk(KERN_CRIT - "cluster_init: Cannot create cluster_sock SLAB cache\n"); - sock_unregister(AF_CLUSTER); - return -1; - } - -#ifdef CONFIG_PROC_FS - create_proc_entries(); -#endif - - init_MUTEX(&start_thread_sem); - init_MUTEX(&send_lock); - init_MUTEX(&barrier_list_lock); - init_MUTEX(&cluster_members_lock); - init_MUTEX(&port_array_lock); - init_MUTEX(&messages_list_lock); - init_MUTEX(&listenreq_lock); - init_MUTEX(&client_socket_lock); - init_MUTEX(&event_listener_lock); - init_MUTEX(&kernel_listener_lock); - init_MUTEX(&tempnode_lock); - spin_lock_init(&active_socket_lock); - spin_lock_init(&new_dead_node_lock); - spin_lock_init(&membership_task_lock); - init_timer(&ack_timer); - - INIT_LIST_HEAD(&event_listener_list); - INIT_LIST_HEAD(&kernel_listener_list); - INIT_LIST_HEAD(&socket_list); - INIT_LIST_HEAD(&client_socket_list); - INIT_LIST_HEAD(&active_socket_list); - INIT_LIST_HEAD(&barrier_list); - INIT_LIST_HEAD(&messages_list); - INIT_LIST_HEAD(&listenreq_list); - INIT_LIST_HEAD(&cluster_members_list); - INIT_LIST_HEAD(&new_dead_node_list); - INIT_LIST_HEAD(&tempnode_list); - - atomic_set(&cnxman_running, 0); - - sm_init(); - - return 0; -} - -static void __exit cluster_exit(void) -{ -#ifdef CONFIG_PROC_FS - cleanup_proc_entries(); -#endif - - sock_unregister(AF_CLUSTER); - kmem_cache_destroy(cluster_sk_cachep); -} - -module_init(cluster_init); -module_exit(cluster_exit); - -EXPORT_SYMBOL(kcl_sendmsg); -EXPORT_SYMBOL(kcl_register_read_callback); -EXPORT_SYMBOL(kcl_add_callback); -EXPORT_SYMBOL(kcl_remove_callback); -EXPORT_SYMBOL(kcl_get_members); -EXPORT_SYMBOL(kcl_get_member_ids); -EXPORT_SYMBOL(kcl_get_all_members); -EXPORT_SYMBOL(kcl_is_quorate); -EXPORT_SYMBOL(kcl_get_node_by_addr); -EXPORT_SYMBOL(kcl_get_node_by_name); -EXPORT_SYMBOL(kcl_get_node_by_nodeid); -EXPORT_SYMBOL(kcl_get_node_addresses); -EXPORT_SYMBOL(kcl_addref_cluster); -EXPORT_SYMBOL(kcl_releaseref_cluster); -EXPORT_SYMBOL(kcl_cluster_name); - -EXPORT_SYMBOL(kcl_barrier_register); -EXPORT_SYMBOL(kcl_barrier_setattr); -EXPORT_SYMBOL(kcl_barrier_delete); -EXPORT_SYMBOL(kcl_barrier_wait); -EXPORT_SYMBOL(kcl_barrier_cancel); - -EXPORT_SYMBOL(kcl_register_quorum_device); -EXPORT_SYMBOL(kcl_unregister_quorum_device); -EXPORT_SYMBOL(kcl_quorum_device_available); - -EXPORT_SYMBOL(kcl_register_service); -EXPORT_SYMBOL(kcl_unregister_service); -EXPORT_SYMBOL(kcl_join_service); -EXPORT_SYMBOL(kcl_leave_service); -EXPORT_SYMBOL(kcl_global_service_id); -EXPORT_SYMBOL(kcl_start_done); -EXPORT_SYMBOL(kcl_get_services); -EXPORT_SYMBOL(kcl_get_current_interface); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/cman-kernel/src/cnxman.h b/cman-kernel/src/cnxman.h deleted file mode 100644 index 7ebc177..0000000 --- a/cman-kernel/src/cnxman.h +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __CNXMAN_H -#define __CNXMAN_H - -#include "linux/in6.h" -#include "cluster/cnxman-socket.h" - -/* In-kernel API */ - -/* This is the structure, per node, returned from the membership request */ -struct kcl_cluster_node { - unsigned int size; - unsigned int node_id; - unsigned int us; - unsigned int leave_reason; - unsigned int incarnation; - nodestate_t state; - struct list_head list; - char name[MAX_CLUSTER_MEMBER_NAME_LEN]; - unsigned char votes; -}; - -struct cluster_node_addr { - struct list_head list; - unsigned char addr[sizeof(struct sockaddr_in6)];/* A large sockaddr */ - int addr_len; -}; - - -/* Reasons for a kernel membership callback */ -typedef enum { CLUSTER_RECONFIG, DIED, LEAVING, NEWNODE } kcl_callback_reason; - -/* Kernel version of above, the void *sock is a struct socket */ -struct kcl_multicast_sock { - void *sock; - int number; /* Socket number, to match up recvonly & bcast - * sockets */ -}; - -extern int kcl_sendmsg(struct socket *sock, void *buf, int size, - struct sockaddr_cl *caddr, int addr_len, - unsigned int flags); -extern int kcl_register_read_callback(struct socket *sock, - int (*routine) (char *, int, char *, int, - unsigned int)); -extern int kcl_add_callback(void (*callback) (kcl_callback_reason, long)); -extern int kcl_remove_callback(void (*callback) (kcl_callback_reason, long)); -extern int kcl_get_members(struct list_head *list); -extern int kcl_get_member_ids(uint32_t * idbuf, int size); -extern int kcl_get_all_members(struct list_head *list); -extern int kcl_get_node_by_addr(unsigned char *addr, int addr_len, - struct kcl_cluster_node *n); -extern int kcl_get_node_by_name(unsigned char *name, - struct kcl_cluster_node *n); -extern int kcl_get_node_by_nodeid(int nodeid, struct kcl_cluster_node *n); -extern int kcl_is_quorate(void); -extern int kcl_addref_cluster(void); -extern int kcl_releaseref_cluster(void); -extern int kcl_cluster_name(char **cname); -extern int kcl_get_current_interface(void); -extern struct list_head *kcl_get_node_addresses(int nodeid); - -extern int kcl_barrier_register(char *name, unsigned int flags, - unsigned int nodes); -extern int kcl_barrier_setattr(char *name, unsigned int attr, - unsigned long arg); -extern int kcl_barrier_delete(char *name); -extern int kcl_barrier_wait(char *name); -extern int kcl_barrier_cancel(char *name); - -extern int kcl_register_quorum_device(char *name, int votes); -extern int kcl_unregister_quorum_device(void); -extern int kcl_quorum_device_available(int yesno); - -#endif diff --git a/cman-kernel/src/config.c b/cman-kernel/src/config.c deleted file mode 100644 index 8eb7f9a..0000000 --- a/cman-kernel/src/config.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "config.h" - -/* Config file defaults */ - -#define DEFAULT_JOIN_WAIT_TIME 16 /* Time to wait while sending JOINREQ - * messages. Should be at least twice - * the HELLO timer, probably 3x */ -#define DEFAULT_JOIN_TIMEOUT 30 /* How long we wait after getting a - * JOINACK to regarding that node as - * dead */ -#define DEFAULT_HELLO_TIMER 5 /* Period between HELLO messages */ -#define DEFAULT_DEADNODE_TIMER 21 /* If we don't get a message from a - * node in this period kill it */ -#define DEFAULT_TRANSITION_TIMER 15 /* Maximum time a state transition - * should take */ -#define DEFAULT_JOINCONF_TIMER 5 /* Time allowed to a node to respond to - * a JOINCONF message */ -#define DEFAULT_MAX_NODES 128 /* Max allowed nodes */ -#define DEFAULT_TRANSITION_RESTARTS 10 /* Maximum number of transition - * restarts before we die */ -#define DEFAULT_SM_DEBUG_SIZE 256 /* Size in bytes of SM debug buffer */ - -#define DEFAULT_NEWCLUSTER_TIMEOUT 16 /* Time to send NEWCLUSTER messages */ -#define DEFAULT_MAX_RETRIES 5 /* Number of times we resend a message */ - -struct config_info cman_config = { - .joinwait_timeout = DEFAULT_JOIN_WAIT_TIME, - .joinconf_timeout = DEFAULT_JOINCONF_TIMER, - .join_timeout = DEFAULT_JOIN_TIMEOUT, - .hello_timer = DEFAULT_HELLO_TIMER, - .deadnode_timeout = DEFAULT_DEADNODE_TIMER, - .transition_timeout = DEFAULT_TRANSITION_TIMER, - .transition_restarts = DEFAULT_TRANSITION_RESTARTS, - .max_nodes = DEFAULT_MAX_NODES, - .sm_debug_size = DEFAULT_SM_DEBUG_SIZE, - .newcluster_timeout = DEFAULT_NEWCLUSTER_TIMEOUT, - .max_retries = DEFAULT_MAX_RETRIES, -}; diff --git a/cman-kernel/src/config.h b/cman-kernel/src/config.h deleted file mode 100644 index 6452068..0000000 --- a/cman-kernel/src/config.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __CONFIG_DOT_H__ -#define __CONFIG_DOT_H__ - -struct config_info { - int joinwait_timeout; - int joinconf_timeout; - int join_timeout; - int hello_timer; - int deadnode_timeout; - int transition_timeout; - int transition_restarts; - int max_nodes; - int sm_debug_size; - int newcluster_timeout; - int max_retries; -}; - -extern struct config_info cman_config; - -#endif /* __CONFIG_DOT_H__ */ diff --git a/cman-kernel/src/kjoin.c b/cman-kernel/src/kjoin.c deleted file mode 100644 index a4aee46..0000000 --- a/cman-kernel/src/kjoin.c +++ /dev/null @@ -1,238 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/socket.h> -#include <net/sock.h> -#include <linux/list.h> -#include <cluster/cnxman.h> -#include <linux/in.h> - -#include "cnxman-private.h" - -static struct socket *mcast_sock; -static struct socket *recv_sock; -static struct socket *cluster_sock; - -extern short cluster_id; -extern int join_count; -extern struct semaphore join_count_lock; -extern atomic_t cnxman_running; - -int kcl_join_cluster(struct cl_join_cluster_info *join_info) -{ - int result; - int one = 1, error; - unsigned int ipaddr = join_info->ipaddr, brdaddr = join_info->brdaddr; - unsigned short port = join_info->port; - mm_segment_t fs; - struct sockaddr_in saddr; - struct kcl_multicast_sock mcast_info; - - down(&join_count_lock); - if (atomic_read(&cnxman_running)) - { - error = 0; - if (join_info->cluster_id == cluster_id) - join_count++; - else - error = -EINVAL; - up(&join_count_lock); - return error; - } - up(&join_count_lock); - - result = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &mcast_sock); - if (result < 0) - { - printk(KERN_ERR CMAN_NAME ": Can't create Multicast socket\n"); - return result; - } - - result = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &recv_sock); - if (result < 0) - { - printk(KERN_ERR CMAN_NAME ": Can't create Receive socket\n"); - return result; - } - - fs = get_fs(); - set_fs(get_ds()); - - if ((error = sock_setsockopt(mcast_sock, SOL_SOCKET, SO_BROADCAST, - (void *) &one, sizeof (int)))) - { - set_fs(fs); - printk("Error %d Setting master socket to SO_BROADCAST\n", - error); - sock_release(mcast_sock); - return -1; - } - set_fs(fs); - - /* Bind the multicast socket */ - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); - saddr.sin_addr.s_addr = cpu_to_be32(brdaddr); - result = - mcast_sock->ops->bind(mcast_sock, (struct sockaddr *) &saddr, - sizeof (saddr)); - if (result < 0) - { - printk(KERN_ERR CMAN_NAME ": Can't bind multicast socket\n"); - sock_release(mcast_sock); - sock_release(recv_sock); - return result; - } - - /* Bind the receive socket to our IP address */ - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); - saddr.sin_addr.s_addr = cpu_to_be32(ipaddr); - result = - recv_sock->ops->bind(recv_sock, (struct sockaddr *) &saddr, - sizeof (saddr)); - if (result < 0) - { - printk(KERN_ERR CMAN_NAME ": Can't bind receive socket\n"); - sock_release(mcast_sock); - sock_release(recv_sock); - return result; - } - - /* Create the cluster master socket */ - result = - sock_create(AF_CLUSTER, SOCK_DGRAM, CLPROTO_MASTER, &cluster_sock); - if (result < 0) - { - printk(KERN_ERR CMAN_NAME - ": Can't create cluster master socket\n"); - sock_release(mcast_sock); - sock_release(recv_sock); - return result; - } - - /* This is the broadcast transmit address */ - saddr.sin_addr.s_addr = cpu_to_be32(brdaddr); - - /* Pass the multicast socket to kernel space */ - mcast_info.sock = mcast_sock; - mcast_info.number = 1; - - fs = get_fs(); - set_fs(get_ds()); - - if ((error = cluster_sock->ops->setsockopt(cluster_sock, CLPROTO_MASTER, - KCL_SET_MULTICAST, - (void *) &mcast_info, - sizeof (mcast_info)))) - { - set_fs(fs); - printk(CMAN_NAME - ": Unable to pass multicast socket to cnxman, %d\n", - error); - sock_release(mcast_sock); - sock_release(recv_sock); - sock_release(cluster_sock); - return -1; - } - - mcast_info.sock = recv_sock; - if ((error = - cluster_sock->ops->setsockopt(cluster_sock, CLPROTO_MASTER, - KCL_SET_RCVONLY, - (void *) &mcast_info, - sizeof (mcast_info)))) - { - set_fs(fs); - printk(CMAN_NAME - ": Unable to pass receive socket to cnxman, %d\n", - error); - sock_release(mcast_sock); - sock_release(recv_sock); - sock_release(cluster_sock); - return -1; - } - - /* This setsockopt expects usermode variables */ - - if (cluster_sock->ops-> - setsockopt(cluster_sock, CLPROTO_MASTER, CLU_JOIN_CLUSTER, - (void *) join_info, - sizeof (struct cl_join_cluster_info))) - - { - set_fs(fs); - printk(CMAN_NAME ": Unable to join cluster\n"); - sock_release(mcast_sock); - sock_release(recv_sock); - sock_release(cluster_sock); - return -1; - } - set_fs(fs); - - return 0; -} - -int kcl_leave_cluster(int remove) -{ - mm_segment_t fs; - int rem = remove; - int ret = 0; - struct socket *shutdown_sock = cluster_sock; - - cluster_sock = NULL; - - if (!shutdown_sock) - { - /* Create the cluster master socket */ - int result = - sock_create(AF_CLUSTER, SOCK_DGRAM, CLPROTO_MASTER, - &shutdown_sock); - if (result < 0) - { - printk(KERN_ERR CMAN_NAME - ": Can't create cluster master socket\n"); - sock_release(mcast_sock); - sock_release(recv_sock); - return result; - } - } - - fs = get_fs(); - set_fs(get_ds()); - - if ((ret = - shutdown_sock->ops->setsockopt(shutdown_sock, CLPROTO_MASTER, - CLU_LEAVE_CLUSTER, (void *) &rem, - sizeof (int)))) - { - printk(KERN_ERR CMAN_NAME ": Unable to leave cluster, %d\n", - ret); - } - set_fs(fs); - - sock_release(shutdown_sock); - - return ret; -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/cman-kernel/src/membership.c b/cman-kernel/src/membership.c deleted file mode 100644 index d1712ce..0000000 --- a/cman-kernel/src/membership.c +++ /dev/null @@ -1,3376 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/socket.h> -#include <net/sock.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <linux/vmalloc.h> -#include <asm/uaccess.h> -#include <linux/list.h> -#include <cluster/cnxman.h> - -#include "cnxman-private.h" -#include "config.h" -#include "sm_control.h" - -#ifndef TRUE -#define TRUE 1 -#endif - -/* Barrier name for membership transitions. %d is the cluster generation number - */ -#define MEMBERSHIP_BARRIER_NAME "TRANSITION.%d" - -/* Variables also used by connection manager */ -struct list_head cluster_members_list; -struct semaphore cluster_members_lock; -int cluster_members; /* Number of ACTIVE members, not a count of - * nodes in the list */ -int we_are_a_cluster_member; -int cluster_is_quorate; -int quit_threads; -struct task_struct *membership_task; -spinlock_t membership_task_lock; -struct cluster_node *us; - -static struct task_struct *hello_task; -static struct semaphore hello_task_lock; - -/* Variables that belong to the connection manager */ -extern wait_queue_head_t cnxman_waitq; -extern struct completion member_thread_comp; -extern struct cluster_node *quorum_device; -extern unsigned short two_node; -extern char cluster_name[]; -extern unsigned int config_version; -extern unsigned int address_length; - -static struct socket *mem_socket; -static pid_t kcluster_pid; - -static char iobuf[MAX_CLUSTER_MESSAGE]; -static char scratchbuf[MAX_CLUSTER_MESSAGE + 100]; - -/* Our node name, usually system_utsname.nodename, but can be overridden */ -char nodename[MAX_CLUSTER_MEMBER_NAME_LEN + 1]; - -/* Node ID that we want. defaults of zero means - * it will be allocated by the cluster join mechanism - */ -int wanted_nodeid; - -static spinlock_t members_by_nodeid_lock; -static int sizeof_members_array; /* Can dynamically increase (vmalloc - * permitting) */ -static struct cluster_node **members_by_nodeid; - -#define MEMBER_INCREMENT_SIZE 10 -#define NON_ACKABLE_HELLO_COUNT 100 - -static int votes = 1; /* Votes this node has */ -static int expected_votes = 1; /* Total expected votes in the cluster */ -static unsigned int quorum; /* Quorum, fewer votes than this and we stop - * work */ -static int leavereason; /* Saved for the duration of a state transition */ -static int transitionreason; /* Reason this transition was initiated */ -static unsigned int highest_nodeid; /* Highest node ID known to the cluster */ -static struct timer_list transition_timer; /* Kicks in if the transition - * doesn't complete in a - * reasonable time */ -static struct timer_list hello_timer; /* Timer to send HELLOs on */ -static unsigned long join_time; /* The time that we got our JOIN-ACK */ -static unsigned long start_time; /* The time that we were started */ -static int joinconf_count; /* Number of JOINCONF messages we have sent to - * a new node */ -static unsigned long wake_flags;/* Reason we were woken */ - -/* Flags in above */ -#define WAKE_FLAG_DEADNODE 1 -#define WAKE_FLAG_TRANSTIMER 2 - -/* The time the transition finished */ -static unsigned long transition_end_time; - -/* A list of nodes that cnxman tells us are dead. I hope this never has more - * than one element in it but I can't take that chance. only non-static so it - * can be initialised in module_load. */ -struct list_head new_dead_node_list; -spinlock_t new_dead_node_lock; - -static int do_membership_packet(struct msghdr *msg, char *buf, int len); -static int do_process_joinreq(struct msghdr *msg, char *buf, int len); -static int do_process_joinack(struct msghdr *msg, char *buf, int len); -static int do_process_joinconf(struct msghdr *msg, char *buf, int len); -static int do_process_leave(struct msghdr *msg, char *buf, int len); -static int do_process_hello(struct msghdr *msg, char *buf, int len); -static int do_process_kill(struct msghdr *msg, char *buf, int len); -static int do_process_reconfig(struct msghdr *msg, char *buf, int len); -static int do_process_starttrans(struct msghdr *msg, char *buf, int len); -static int do_process_nodedown(struct msghdr *msg, char *buf, int len); -static int do_process_masterview(struct msghdr *msg, char *buf, int len); -static int do_process_endtrans(struct msghdr *msg, char *buf, int len); -static int do_process_viewack(struct msghdr *msg, char *buf, int len); -static int do_process_startack(struct msghdr *msg, char *buf, int len); -static int do_process_newcluster(struct msghdr *msg, char *buf, int len); -static int do_process_nominate(struct msghdr *msg, char *buf, int len); -static int send_cluster_view(unsigned char cmd, struct sockaddr_cl *saddr, - unsigned int flags, unsigned int flags2); -static int send_joinreq(struct sockaddr_cl *addr, int addr_len); -static int send_startack(struct sockaddr_cl *addr, int addr_len); -static int send_hello(int ackable); -static int send_master_hello(void); -static int send_newcluster(void); -static int end_transition(void); -static int dispatch_messages(struct socket *mem_socket); -static void check_for_dead_nodes(void); -static void confirm_joiner(void); -static void reset_hello_time(void); -static int add_us(void); -static int send_joinconf(void); -static int init_membership_services(void); -static int elect_master(struct cluster_node **, int disallow_node); -static void trans_timer_expired(unsigned long arg); -static void hello_timer_expired(unsigned long arg); -static void join_or_form_cluster(void); -static int do_timer_wakeup(void); -static int start_transition(unsigned char reason, struct cluster_node *node); -static uint32_t low32_of_ip(void); -static void remove_joiner(int tell_wait); -int send_leave(unsigned char); -int send_reconfigure(int, unsigned int); - -#ifdef DEBUG_MEMB -static char *msgname(int msg); -static int debug_sendmsg(struct socket *sock, void *buf, int size, - struct sockaddr_cl *caddr, int addr_len, - unsigned int flags) -{ - P_MEMB("%ld: sending %s, len=%d\n", jiffies, msgname(((char *) buf)[0]), - size); - return kcl_sendmsg(sock, buf, size, caddr, addr_len, flags); -} - -#define kcl_sendmsg debug_sendmsg -#endif - -/* State of the node */ -static enum { STARTING, NEWCLUSTER, JOINING, JOINWAIT, JOINACK, TRANSITION, - TRANSITION_COMPLETE, MEMBER, REJECTED, LEFT_CLUSTER, MASTER -} node_state = LEFT_CLUSTER; - -/* Sub-state when we are MASTER */ -static enum { MASTER_START, MASTER_COLLECT, MASTER_CONFIRM, - MASTER_COMPLETE } master_state; - -/* Number of responses collected while a master controlling a state transition */ -static int responses_collected; -static int responses_expected; - -/* Current cluster generation number */ -int cluster_generation = 1; - -/* When another node initiates a transtion then store it's pointer in here so - * we can check for other nodes trying to spoof us */ -static struct cluster_node *master_node = NULL; - -/* Struct the node wanting to join us */ -static struct cluster_node *joining_node = NULL; -static int joining_temp_nodeid; - -/* Last time a HELLO message was sent */ -unsigned long last_hello; - -/* When we got our JOINWAIT or NEWCLUSTER */ -unsigned long joinwait_time; - -/* Number of times a transition has restarted when we were master */ -int transition_restarts; - -/* Variables used by the master to collect cluster status during a transition */ -static int agreeing_nodes; -static int dissenting_nodes; -static uint8_t *node_opinion = NULL; -#define OPINION_AGREE 1 -#define OPINION_DISAGREE 2 - - -/* None of our threads is CPU intensive, but if they don't run when they are supposed - to, the node can get kicked out of the cluster. -*/ -void cman_set_realtime(struct task_struct *tsk, int prio) -{ - tsk->policy = SCHED_FIFO; - tsk->rt_priority = prio; -} - -/* Set node id of a node, also add it to the members array and expand the array - * if necessary */ -static inline void set_nodeid(struct cluster_node *node, int nodeid) -{ - if (!nodeid) - return; - - node->node_id = nodeid; - if (nodeid >= sizeof_members_array) { - int new_size = sizeof_members_array + MEMBER_INCREMENT_SIZE; - struct cluster_node **new_array; - - if (new_size < nodeid) - new_size = nodeid + MEMBER_INCREMENT_SIZE; - - new_array = vmalloc((new_size) * sizeof (struct cluster_node *)); - if (new_array) { - spin_lock(&members_by_nodeid_lock); - memcpy(new_array, members_by_nodeid, - sizeof_members_array * - sizeof (struct cluster_node *)); - memset(&new_array[sizeof_members_array], 0, - (new_size - sizeof_members_array) * - sizeof (struct cluster_node *)); - vfree(members_by_nodeid); - - members_by_nodeid = new_array; - sizeof_members_array = new_size; - spin_unlock(&members_by_nodeid_lock); - } - else { - panic("No memory for more nodes"); - } - } - notify_kernel_listeners(NEWNODE, (long) nodeid); - - /* The old node may be a failed joiner, in which case we can overwrite it with - the new node */ - if (members_by_nodeid[nodeid] && - members_by_nodeid[nodeid]->state == NODESTATE_JOINING) { - struct cluster_node *node; - - P_MEMB("Removing failed joining node %s (%d)\n", - members_by_nodeid[nodeid]->name, members_by_nodeid[nodeid]->node_id); - - down(&cluster_members_lock); - list_del(&members_by_nodeid[nodeid]->list); - up(&cluster_members_lock); - - node = members_by_nodeid[nodeid]; - - spin_lock(&members_by_nodeid_lock); - members_by_nodeid[nodeid] = NULL; - spin_unlock(&members_by_nodeid_lock); - - kfree(node); - } - - if (members_by_nodeid[nodeid] && - members_by_nodeid[nodeid] != node) { - printk(KERN_ERR CMAN_NAME ": Attempt to re-add node with id %d\n", nodeid); - printk(KERN_ERR CMAN_NAME ": existing node is %s\n", members_by_nodeid[nodeid]->name); - printk(KERN_ERR CMAN_NAME ": new node is %s\n", node->name); - BUG(); - } - - spin_lock(&members_by_nodeid_lock); - members_by_nodeid[nodeid] = node; - spin_unlock(&members_by_nodeid_lock); -} - -static int hello_kthread(void *unused) -{ - struct task_struct *tsk = current; - sigset_t tmpsig; - - daemonize("cman_hbeat"); - - /* Block everything but SIGKILL/SIGSTOP/SIGTERM */ - siginitset(&tmpsig, SIGKILL | SIGSTOP | SIGTERM); - sigprocmask(SIG_BLOCK, &tmpsig, NULL); - - down(&hello_task_lock); - hello_task = tsk; - up(&hello_task_lock); - - mod_timer(&hello_timer, jiffies + cman_config.hello_timer * HZ); - - cman_set_realtime(current, 1); - - while (node_state != REJECTED && node_state != LEFT_CLUSTER && - quit_threads == 0) { - - /* Scan the nodes list for dead nodes */ - if (node_state == MEMBER) - check_for_dead_nodes(); - - set_task_state(current, TASK_INTERRUPTIBLE); - schedule(); - set_task_state(current, TASK_RUNNING); - - if (node_state != REJECTED && node_state != LEFT_CLUSTER) - send_hello(1); - } - if (timer_pending(&hello_timer)) - del_timer(&hello_timer); - - down(&hello_task_lock); - hello_task = NULL; - up(&hello_task_lock); - P_MEMB("heartbeat closing down\n"); - return 0; -} - -static void process_dead_nodes(void) -{ - struct list_head *nodelist, *tmp; - struct cl_new_dead_node *deadnode; - - spin_lock(&new_dead_node_lock); - list_for_each_safe(nodelist, tmp, &new_dead_node_list) { - deadnode = list_entry(nodelist, - struct cl_new_dead_node, list); - - list_del(&deadnode->list); - if (deadnode->node->state == NODESTATE_MEMBER) { - spin_unlock(&new_dead_node_lock); - a_node_just_died(deadnode->node); - spin_lock(&new_dead_node_lock); - } - kfree(deadnode); - } - spin_unlock(&new_dead_node_lock); -} - -/* This is the membership "daemon". A client of cnxman (but symbiotic with it) - * that keeps track of and controls cluster membership. */ -static int membership_kthread(void *unused) -{ - struct task_struct *tsk = current; - sigset_t tmpsig; - - daemonize("cman_memb"); - - /* Block everything but SIGKILL/SIGSTOP/SIGTERM */ - siginitset(&tmpsig, SIGKILL | SIGSTOP | SIGTERM); - sigprocmask(SIG_BLOCK, &tmpsig, NULL); - - spin_lock(&membership_task_lock); - membership_task = tsk; - spin_unlock(&membership_task_lock); - cman_set_realtime(current, 1); - - /* Open the socket */ - if (init_membership_services()) - return -1; - - add_us(); - joining_node = us; - - init_timer(&hello_timer); - hello_timer.function = hello_timer_expired; - hello_timer.data = 0L; - - /* Do joining stuff */ - join_or_form_cluster(); - - transition_end_time = jiffies; - - /* Main loop */ - while (node_state != REJECTED && node_state != LEFT_CLUSTER && !quit_threads) { - - struct task_struct *tsk = current; - - DECLARE_WAITQUEUE(wait, tsk); - - tsk->state = TASK_INTERRUPTIBLE; - add_wait_queue(mem_socket->sk->sk_sleep, &wait); - - if (!skb_peek(&mem_socket->sk->sk_receive_queue) && - wake_flags == 0) { - if (node_state == JOINACK || - node_state == JOINWAIT) - schedule_timeout(HZ); - else - schedule(); - } - - tsk->state = TASK_RUNNING; - remove_wait_queue(mem_socket->sk->sk_sleep, &wait); - - /* Are we being shut down? */ - if (node_state == LEFT_CLUSTER || quit_threads || - signal_pending(current)) - break; - - /* Were we woken by a dead node passed down from cnxman ? */ - if (test_and_clear_bit(WAKE_FLAG_DEADNODE, &wake_flags)) { - process_dead_nodes(); - } - - /* Process received messages. If dispatch_message() returns an - * error then we shut down */ - if (skb_peek(&mem_socket->sk->sk_receive_queue)) { - if (dispatch_messages(mem_socket) < 0) - goto leave_cluster; - } - - /* Messages may cause us to quit */ - if (quit_threads) - goto leave_cluster; - - /* Check this again here, in case nodes die while we're doing stuff */ - if (test_and_clear_bit(WAKE_FLAG_DEADNODE, &wake_flags)) { - process_dead_nodes(); - } - - /* Were we woken by the transition timer firing ? */ - if (test_and_clear_bit(WAKE_FLAG_TRANSTIMER, &wake_flags)) { - switch (do_timer_wakeup()) { - case -1: - continue; - case 0: - break; - case +1: - goto leave_cluster; - } - } - - /* Got a JOINACK but no JOIN-CONF, start waiting for HELLO - * messages again */ - if (node_state == JOINACK && - time_after(jiffies, - join_time + cman_config.join_timeout * HZ)) { - P_MEMB - ("Waited a long time for a join-conf, going back to JOINWAIT state\n"); - node_state = JOINWAIT; - joinwait_time = jiffies; - } - - /* Have we had an ACK for our JOINREQ message ? */ - if (node_state == JOINING && - time_after(jiffies, - join_time + cman_config.join_timeout * HZ)) { - P_MEMB("didn't get JOINACK, going back to JOINWAIT\n"); - node_state = JOINWAIT; - joinwait_time = jiffies; - } - - /* Have we been in joinwait for too long... */ - if (node_state == JOINWAIT && - time_after(jiffies, - joinwait_time + cman_config.joinwait_timeout * HZ)) { - printk(KERN_WARNING CMAN_NAME - ": Been in JOINWAIT for too long - giving up\n"); - goto leave_cluster; - } - } - - leave_cluster: - - /* Wake up the heartbeat thread so it can exit */ - down(&hello_task_lock); - if (hello_task) - wake_up_process(hello_task); - up(&hello_task_lock); - - if (timer_pending(&transition_timer)) - del_timer(&transition_timer); - - node_state = LEFT_CLUSTER; - P_MEMB("closing down\n"); - quit_threads = 1; /* force other thread to exit too */ - - send_leave(us->leave_reason); - sock_release(mem_socket); - highest_nodeid = 0; - joining_node = NULL; - master_node = NULL; - complete(&member_thread_comp); - - spin_lock(&membership_task_lock); - membership_task = NULL; - spin_unlock(&membership_task_lock); - return 0; -} - -/* Things to do in the main thread when the transition timer has woken us. - * Usually this happens when a transition is taking too long and we need to - * take remedial action. - * - * returns: -1 continue; 0 carry on processing +1 leave cluster; */ -static int do_timer_wakeup() -{ - P_MEMB("Timer wakeup - checking for dead master node %ld\n", jiffies); - - /* Resend JOINCONF if it got lost on the wire */ - if (node_state == MASTER && master_state == MASTER_CONFIRM) { - mod_timer(&transition_timer, - jiffies + cman_config.joinconf_timeout * HZ); - if (++joinconf_count < cman_config.max_retries) { - P_MEMB("Resending JOINCONF\n"); - send_joinconf(); - } - else { - P_MEMB("JOINCONF not acked, removing node\n"); - joining_node->state = NODESTATE_DEAD; - start_transition(TRANS_REMNODE, joining_node); - remove_joiner(1); - joining_node = NULL; - } - return -1; - } - - /* A joining node probably died */ - if (cluster_members == 1) { - end_transition(); - return -1; - } - - /* See if the master is still there */ - if (node_state == TRANSITION || node_state == TRANSITION_COMPLETE) { - - /* If we are in transition and master_node is NULL then we are - * waiting for ENDTRANS after JOIN-CONF */ - if (!master_node) { - /* Hmmm. master died after sending JOINCONF, we'll have - * to die as we are in mid-transition */ - printk(KERN_INFO CMAN_NAME - ": Master died after JOINCONF, we must leave the cluster\n"); - quit_threads = 1; - return +1; - } - - /* No messages from the master - see if it's stil there */ - if (master_node->state == NODESTATE_MEMBER) { - send_master_hello(); - mod_timer(&transition_timer, - jiffies + - cman_config.transition_timeout * HZ); - } - - /* If the master is dead then elect a new one */ - if (master_node->state == NODESTATE_DEAD) { - - struct cluster_node *node; - - P_MEMB("Master node is dead...Election!\n"); - if (elect_master(&node, 0)) { - - /* We are master now, all kneel */ - master_node->leave_reason = CLUSTER_LEAVEFLAG_NORESPONSE; - start_transition(TRANS_DEADMASTER, master_node); - } - else { - /* Leave the job to someone on more pay */ - master_node = node; - mod_timer(&transition_timer, - jiffies + - cman_config.transition_timeout * HZ); - } - } - } - - /* If we are the master node then restart the transition */ - if (node_state == MASTER) { - start_transition(TRANS_RESTART, us); - } - - return 0; -} - -static void form_cluster(void) -{ - printk(KERN_INFO CMAN_NAME ": forming a new cluster\n"); - node_state = MEMBER; - we_are_a_cluster_member = TRUE; - us->state = NODESTATE_MEMBER; - if (wanted_nodeid) - set_nodeid(us, wanted_nodeid); - else - set_nodeid(us, 1); - recalculate_quorum(0); - sm_member_update(cluster_is_quorate); - send_hello(0); - kernel_thread(hello_kthread, NULL, 0); -} - -/* This does the initial JOIN part of the membership process. Actually most of - * is done in the message processing routines but this is the main loop that - * controls it. The side-effect of this routine is "node_state" which tells the - * real main loop (in the kernel thread routine) what to do next */ -static void join_or_form_cluster() -{ - start_time = jiffies; - - printk(KERN_INFO CMAN_NAME - ": Waiting to join or form a Linux-cluster\n"); - - restart_joinwait: - join_time = 0; - start_time = jiffies; - joinwait_time = jiffies; - last_hello = 0; - - /* Listen for HELLO or NEWCLUSTER messages */ - do { - DECLARE_WAITQUEUE(wait, current); - set_task_state(current, TASK_INTERRUPTIBLE); - add_wait_queue(mem_socket->sk->sk_sleep, &wait); - - if (!skb_peek(&mem_socket->sk->sk_receive_queue)) - schedule_timeout((cman_config.joinwait_timeout * HZ) / - 5); - - set_task_state(current, TASK_RUNNING); - remove_wait_queue(mem_socket->sk->sk_sleep, &wait); - - while (skb_peek(&mem_socket->sk->sk_receive_queue)) { - dispatch_messages(mem_socket); - } - if (quit_threads) - node_state = LEFT_CLUSTER; - - } - while (time_before(jiffies, start_time + cman_config.joinwait_timeout * HZ) && - node_state == STARTING); - - if (node_state == STARTING) { - start_time = jiffies; - joinwait_time = jiffies; - node_state = NEWCLUSTER; - } - - /* If we didn't hear any HELLO messages then start sending NEWCLUSTER messages */ - while (time_before(jiffies, start_time + cman_config.newcluster_timeout * HZ) && - node_state == NEWCLUSTER) { - - DECLARE_WAITQUEUE(wait, current); - - send_newcluster(); - - set_task_state(current, TASK_INTERRUPTIBLE); - add_wait_queue(mem_socket->sk->sk_sleep, &wait); - - if (!skb_peek(&mem_socket->sk->sk_receive_queue)) - schedule_timeout((cman_config.joinwait_timeout * HZ) / - 5); - - set_task_state(current, TASK_RUNNING); - remove_wait_queue(mem_socket->sk->sk_sleep, &wait); - - while (skb_peek(&mem_socket->sk->sk_receive_queue)) { - dispatch_messages(mem_socket); - } - /* Did we get a lower "NEWCLUSTER" message ? */ - if (node_state == STARTING) { - P_MEMB("NEWCLUSTER: restarting joinwait\n"); - goto restart_joinwait; - } - - if (quit_threads) - node_state = LEFT_CLUSTER; - - } - - - /* If we didn't hear any HELLO messages then form a new cluster */ - if (node_state == NEWCLUSTER) { - form_cluster(); - } - else - last_hello = jiffies; - -} - -int start_membership_services(pid_t cluster_pid) -{ - kcluster_pid = cluster_pid; - - init_timer(&transition_timer); - transition_timer.function = trans_timer_expired; - transition_timer.data = 0L; - wake_flags = 0L; - - /* Start the thread */ - return kernel_thread(membership_kthread, NULL, 0); -} - -static int init_membership_services() -{ - int result; - struct sockaddr_cl saddr; - struct socket *sock; - - init_MUTEX(&hello_task_lock); - /* Create a socket to communicate with */ - result = sock_create_kern(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT, &sock); - if (result < 0) { - printk(KERN_ERR CMAN_NAME - ": Can't create cluster socket for membership services\n"); - return result; - } - mem_socket = sock; - - /* Bind to our port */ - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - result = - sock->ops->bind(sock, (struct sockaddr *) &saddr, sizeof (saddr)); - if (result < 0) { - printk(KERN_ERR CMAN_NAME - ": Can't bind to cluster membership services port\n"); - sock_release(sock); - return result; - } - - node_state = STARTING; - return 0; -} - -static int send_joinconf() -{ - struct sockaddr_cl saddr; - int status; - - if (joining_temp_nodeid == 0) { - printk(KERN_DEBUG CMAN_NAME ": Failed to join node '%s'\n", - joining_node?joining_node->name:"unknown"); - remove_joiner(0); - return -1; - } - - master_state = MASTER_CONFIRM; - saddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - saddr.scl_family = AF_CLUSTER; - saddr.scl_nodeid = joining_temp_nodeid; - status = send_cluster_view(CLUSTER_MEM_JOINCONF, &saddr, - MSG_NOACK, 0); - - if (status < 0) { - printk(KERN_WARNING CMAN_NAME ": Error %d sending JOINCONF\n", status); - } - return status; -} - -static int send_joinreq(struct sockaddr_cl *addr, int addr_len) -{ - char *msgbuf = scratchbuf; - struct list_head *addrlist; - int ptr = sizeof (struct cl_mem_join_msg); - unsigned short num_addr = 0; - struct cluster_node_addr *nodeaddr; - struct cl_mem_join_msg *msg = (struct cl_mem_join_msg *) msgbuf; - - msg->cmd = CLUSTER_MEM_JOINREQ; - msg->votes = votes; - msg->expected_votes = cpu_to_le32(expected_votes); - msg->nodeid = cpu_to_le32(wanted_nodeid); - msg->major_version = cpu_to_le32(CNXMAN_MAJOR_VERSION); - msg->minor_version = cpu_to_le32(CNXMAN_MINOR_VERSION); - msg->patch_version = cpu_to_le32(CNXMAN_PATCH_VERSION); - msg->config_version = cpu_to_le32(config_version); - msg->addr_len = cpu_to_le32(address_length); - strcpy(msg->clustername, cluster_name); - - /* Add our addresses */ - list_for_each(addrlist, &us->addr_list) { - nodeaddr = list_entry(addrlist, struct cluster_node_addr, list); - - memcpy(msgbuf + ptr, nodeaddr->addr, address_length); - ptr += address_length; - num_addr++; - } - msg->num_addr = cpu_to_le16(num_addr); - - /* And our name */ - strcpy(msgbuf + ptr, nodename); - ptr += strlen(nodename) + 1; - - return kcl_sendmsg(mem_socket, msgbuf, ptr, - addr, addr_len, MSG_NOACK); -} - -static int send_startack(struct sockaddr_cl *addr, int addr_len) -{ - struct cl_mem_startack_msg msg; - - msg.cmd = CLUSTER_MEM_STARTACK; - msg.generation = cpu_to_le32(cluster_generation); - - return kcl_sendmsg(mem_socket, &msg, sizeof (msg), addr, addr_len, MSG_REPLYEXP); -} - -static int send_newcluster() -{ - char buf[5]; - uint32_t lowip; - - buf[0] = CLUSTER_MEM_NEWCLUSTER; - lowip = cpu_to_le32(low32_of_ip()); - memcpy(&buf[1], &lowip, sizeof(lowip)); - - return kcl_sendmsg(mem_socket, buf, sizeof(uint32_t)+1, - NULL, 0, - MSG_NOACK); -} - -static int send_hello(int ackable) -{ - struct cl_mem_hello_msg hello_msg; - int status; - static int last_ackable = 0; - int flags; - - hello_msg.cmd = CLUSTER_MEM_HELLO; - hello_msg.members = cpu_to_le16(cluster_members); - hello_msg.flags = cluster_is_quorate ? HELLO_FLAG_QUORATE : 0; - hello_msg.generation = cpu_to_le32(cluster_generation); - - /* Every so often we need request an ACK for a HELLO message - to keep the messaging system sane */ - if (ackable && !(++last_ackable % NON_ACKABLE_HELLO_COUNT)) { - flags = MSG_ALLINT; - } - else { - flags = MSG_NOACK | MSG_ALLINT; - } - status = kcl_sendmsg(mem_socket, &hello_msg, - sizeof(struct cl_mem_hello_msg), - NULL, 0, flags); - - last_hello = jiffies; - - return status; -} - -/* This is a special HELLO message that requires an ACK. clients in transition - * send these to the master to check it is still alive. If it does not ACK then - * cnxman will signal it dead and we can restart the transition */ -static int send_master_hello() -{ - struct cl_mem_hello_msg hello_msg; - int status; - struct sockaddr_cl saddr; - - hello_msg.cmd = CLUSTER_MEM_HELLO; - hello_msg.members = cpu_to_le16(cluster_members); - hello_msg.flags = HELLO_FLAG_MASTER | - (cluster_is_quorate ? HELLO_FLAG_QUORATE : 0); - hello_msg.generation = cpu_to_le32(cluster_generation); - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - saddr.scl_nodeid = master_node->node_id; - - status = kcl_sendmsg(mem_socket, &hello_msg, - sizeof(struct cl_mem_hello_msg), - &saddr, sizeof (saddr), 0); - - last_hello = jiffies; - - return status; -} - -/* Called when the transition timer has expired, meaning we sent a transition - * message that was not ACKed */ -static void trans_timer_expired(unsigned long arg) -{ - P_MEMB("Transition timer fired %ld\n", jiffies); - - set_bit(WAKE_FLAG_TRANSTIMER, &wake_flags); - wake_up_process(membership_task); -} - -static void hello_timer_expired(unsigned long arg) -{ - P_MEMB("Hello timer fired %ld\n", jiffies); - - mod_timer(&hello_timer, jiffies + cman_config.hello_timer * HZ); - - if (node_state >= TRANSITION) { - if (!wake_up_process(hello_task)) - P_MEMB("Failed to wake up hello thread\n"); - } -} - -static int wait_for_completion_barrier(void) -{ - int status; - char barriername[MAX_BARRIER_NAME_LEN]; - - sprintf(barriername, MEMBERSHIP_BARRIER_NAME, cluster_generation); - - /* Make sure we all complete together */ - P_MEMB("Waiting for completion barrier: %d members\n", cluster_members); - if ((status = - kcl_barrier_register(barriername, 0, cluster_members)) < 0) { - printk(KERN_ERR CMAN_NAME ": Error registering barrier: %d\n", status); - return -1; - } - kcl_barrier_setattr(barriername, BARRIER_SETATTR_TIMEOUT, - cman_config.transition_timeout); - status = kcl_barrier_wait(barriername); - kcl_barrier_delete(barriername); - - P_MEMB("Completion barrier reached : status = %d\n", status); - return status; -} - -/* Called at the end of a state transition when we are the master */ -static int end_transition() -{ - struct cl_mem_endtrans_msg msg; - int total_votes; - int status; - - /* Cancel the timer */ - del_timer(&transition_timer); - - printk(KERN_INFO CMAN_NAME ": Completed transition, generation %d\n", cluster_generation); - - confirm_joiner(); - - quorum = calculate_quorum(leavereason, leavereason?cluster_members:0, &total_votes); - - msg.cmd = CLUSTER_MEM_ENDTRANS; - msg.quorum = cpu_to_le32(quorum); - msg.generation = cpu_to_le32(++cluster_generation); - msg.total_votes = cpu_to_le32(total_votes); - if (joining_node && transitionreason == TRANS_NEWNODE) { - msg.new_node_id = cpu_to_le32(joining_node->node_id); - } - else { - msg.new_node_id = 0; - } - status = kcl_sendmsg(mem_socket, &msg, sizeof (msg), NULL, 0, 0); - - /* When that's all settled down, do the transition completion barrier */ - kcl_wait_for_all_acks(); - - /* We check this below too, but this can save us 3 seconds in a transition */ - if (test_bit(WAKE_FLAG_DEADNODE, &wake_flags)) { - P_MEMB("Node died during ACK collection - restart\n"); - remove_joiner(0); - return 0; - } - - if (wait_for_completion_barrier() != 0) { - P_MEMB("Barrier timed out - restart\n"); - - /* If a node died while we were waiting then restart transition with ANOTHERREMNODE */ - if (!test_bit(WAKE_FLAG_DEADNODE, &wake_flags)) { - remove_joiner(0); - start_transition(TRANS_RESTART, us); - } - return 0; - } - - joining_temp_nodeid = 0; - joining_node = NULL; - purge_temp_nodeids(); - - set_quorate(total_votes); - - notify_listeners(); - reset_hello_time(); - - /* Tell any waiting barriers that we had a transition */ - check_barrier_returns(); - - leavereason = 0; - transitionreason = TRANS_NONE; - node_state = MEMBER; - transition_end_time = jiffies; - - sm_member_update(cluster_is_quorate); - - return 0; -} - -int send_reconfigure(int param, unsigned int value) -{ - char msgbuf[66]; - struct cl_mem_reconfig_msg *msg = - (struct cl_mem_reconfig_msg *) &msgbuf; - - if (param == RECONFIG_PARAM_EXPECTED_VOTES && expected_votes > value) - expected_votes = value; - - msg->cmd = CLUSTER_MEM_RECONFIG; - msg->param = param; - msg->value = cpu_to_le32(value); - - return kcl_sendmsg(mem_socket, &msgbuf, sizeof (*msg), NULL, 0, 0); -} - -static int send_joinack(char *addr, int addr_len, unsigned char acktype) -{ - struct cl_mem_joinack_msg msg; - - msg.cmd = CLUSTER_MEM_JOINACK; - msg.acktype = acktype; - - return kcl_sendmsg(mem_socket, &msg, sizeof (msg), - (struct sockaddr_cl *)addr, addr_len, MSG_NOACK); -} - -/* Only send a leave message to one node in the cluster so that it can master - * the state transition, otherwise we get a "thundering herd" of potential - * masters fighting it out */ -int send_leave(unsigned char flags) -{ - unsigned char msg[2]; - struct sockaddr_cl saddr; - struct cluster_node *node = NULL; - int status; - - if (!mem_socket) - return 0; - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - - /* If we are in transition then use the current master */ - if (node_state == TRANSITION) { - node = master_node; - } - if (!node) { - /* If we are the master or not in transition then pick a node - * almost at random */ - struct list_head *nodelist; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->state == NODESTATE_MEMBER && !node->us) - break; - } - up(&cluster_members_lock); - } - - /* we are the only member of the cluster - there is no-one to tell */ - if (node && !node->us) { - saddr.scl_nodeid = node->node_id; - - P_MEMB("Sending LEAVE to %s\n", node->name); - msg[0] = CLUSTER_MEM_LEAVE; - msg[1] = flags; - status = kcl_sendmsg(mem_socket, msg, 2, - &saddr, sizeof (saddr), - MSG_NOACK); - if (status < 0) - return status; - } - - /* And exit */ - node_state = LEFT_CLUSTER; - wake_up_process(membership_task); - return 0; -} - -int send_kill(int nodeid, int needack) -{ - char killmsg; - struct sockaddr_cl saddr; - int flags; - - if (needack) - flags = MSG_QUEUE; - else - flags = MSG_NOACK; - - killmsg = CLUSTER_MEM_KILL; - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - saddr.scl_nodeid = nodeid; - return kcl_sendmsg(mem_socket, &killmsg, 1, &saddr, - sizeof (struct sockaddr_cl), flags); -} - -/* Tell the rest of the cluster a node has gone down */ -static int send_nodedown(int nodeid, unsigned char reason) -{ - struct cl_mem_nodedown_msg downmsg; - int status; - - downmsg.reason = reason; - downmsg.nodeid = cpu_to_le32(nodeid); - downmsg.cmd = CLUSTER_MEM_NODEDOWN; - - status = kcl_sendmsg(mem_socket, (char *)&downmsg, sizeof(downmsg), NULL, 0, 0); - return status; -} - -/* Process a message */ -static int do_membership_packet(struct msghdr *msg, char *buf, int len) -{ - int result = -1; - struct sockaddr_cl *saddr = msg->msg_name; - struct cluster_node *node; - - node = find_node_by_nodeid(saddr->scl_nodeid); - - P_MEMB("got membership message : %s, from (%d) %s, len = %d\n", - msgname(*buf), saddr->scl_nodeid, node ? node->name : "unknown", len); - - switch (*buf) { - case CLUSTER_MEM_JOINREQ: - result = do_process_joinreq(msg, buf, len); - break; - - case CLUSTER_MEM_LEAVE: - if (we_are_a_cluster_member) - result = do_process_leave(msg, buf, len); - break; - - case CLUSTER_MEM_HELLO: - result = do_process_hello(msg, buf, len); - break; - - case CLUSTER_MEM_KILL: - if (we_are_a_cluster_member) - result = do_process_kill(msg, buf, len); - break; - - case CLUSTER_MEM_JOINCONF: - if (node_state == JOINACK) { - do_process_joinconf(msg, buf, len); - } - break; - - case CLUSTER_MEM_CONFACK: - if (node_state == MASTER && master_state == MASTER_CONFIRM) { - end_transition(); - } - break; - - case CLUSTER_MEM_MASTERVIEW: - if (node_state == TRANSITION) - do_process_masterview(msg, buf, len); - break; - - case CLUSTER_MEM_JOINACK: - if (node_state == JOINING || node_state == JOINWAIT) { - do_process_joinack(msg, buf, len); - } - break; - case CLUSTER_MEM_RECONFIG: - if (we_are_a_cluster_member) { - do_process_reconfig(msg, buf, len); - } - break; - - case CLUSTER_MEM_STARTTRANS: - result = do_process_starttrans(msg, buf, len); - break; - - case CLUSTER_MEM_NODEDOWN: - result = do_process_nodedown(msg, buf, len); - break; - - case CLUSTER_MEM_ENDTRANS: - result = do_process_endtrans(msg, buf, len); - break; - - case CLUSTER_MEM_VIEWACK: - if (node_state == MASTER && master_state == MASTER_COLLECT) - result = do_process_viewack(msg, buf, len); - break; - - case CLUSTER_MEM_STARTACK: - if (node_state == MASTER) - result = do_process_startack(msg, buf, len); - break; - - case CLUSTER_MEM_NEWCLUSTER: - result = do_process_newcluster(msg, buf, len); - break; - - case CLUSTER_MEM_NOMINATE: - if (node_state != MASTER) - result = do_process_nominate(msg, buf, len); - break; - - default: - printk(KERN_ERR CMAN_NAME - ": Unknown membership services message %d received from node %d port %d\n", - *buf, saddr->scl_nodeid, saddr->scl_port); - break; - - } - return result; -} - -/* Returns -ve to reject membership of the cluster 0 to accept membership +ve - * to ignore request (node already joining) */ -static int check_duplicate_node(char *name, struct msghdr *msg, int len) -{ - struct cluster_node *node; - struct sockaddr_cl *saddr = (struct sockaddr_cl *)msg->msg_name; - char addr[address_length]; - int addrlen; - - if (strlen(name) >= MAX_CLUSTER_MEMBER_NAME_LEN) - return -3; - - /* See if we already have a cluster member with that name... */ - node = find_node_by_name(name); - if (node && node->state != NODESTATE_DEAD) { - - if (node->state == NODESTATE_JOINING) - return +1; - - printk(KERN_WARNING CMAN_NAME - ": Rejecting cluster membership application from %s - already have a node with that name\n", - name); - return -1; - - } - - /* Need to check the node's address too */ - if (get_addr_from_temp_nodeid(saddr->scl_nodeid, addr, &addrlen) && - (node = find_node_by_addr(addr, addrlen)) && - node->state != NODESTATE_DEAD) { - - if (node->state == NODESTATE_JOINING) - return +1; - - printk(KERN_WARNING CMAN_NAME - ": Rejecting cluster membership application from %s - already have a node with that address\n", - name); - return -1; - } - return 0; -} - -/* Start the state transition */ -static int start_transition(unsigned char reason, struct cluster_node *node) -{ - char *startbuf = scratchbuf; - struct cl_mem_starttrans_msg *msg = - (struct cl_mem_starttrans_msg *) startbuf; - - P_MEMB("Start transition - reason = %d(last reason = %d)\n", reason, transitionreason); - - /* If this is a restart then zero the counters */ - if (reason == TRANS_RESTART || reason == TRANS_NEWMASTER) { - agreeing_nodes = 0; - dissenting_nodes = 0; - if (node_opinion) { - kfree(node_opinion); - node_opinion = NULL; - } - responses_collected = 0; - - /* Make sure we restart with the right new node if applicable. */ - if (transitionreason == TRANS_NEWNODE && joining_node) - node = joining_node; - - /* If we are a new master then try to restart the transition proper */ - if (reason == TRANS_NEWMASTER) { - reason = transitionreason; - if (reason == TRANS_NEWNODE) { - if (joining_node) - node = joining_node; - else - reason = TRANS_NEWMASTER; - } - } - } - - /* If we have timed out too many times then just die */ - if (reason == TRANS_RESTART - && ++transition_restarts > cman_config.transition_restarts) { - printk(KERN_WARNING CMAN_NAME - ": too many transition restarts - will die\n"); - us->leave_reason = CLUSTER_LEAVEFLAG_INCONSISTENT; - node_state = LEFT_CLUSTER; - quit_threads = 1; - wake_up_process(membership_task); - wake_up_interruptible(&cnxman_waitq); - return 0; - } - if (reason != TRANS_RESTART) - transition_restarts = 0; - - /* Only keep the original state transition reason in the global - * variable. */ - if (reason != TRANS_ANOTHERREMNODE && reason != TRANS_NEWMASTER && - reason != TRANS_RESTART && reason != TRANS_DEADMASTER) - transitionreason = reason; - - if (reason == TRANS_DEADMASTER) - transitionreason = TRANS_REMNODE; - - /* Save the info of the requesting node */ - if (reason == TRANS_NEWNODE) - joining_node = node; - - node_state = MASTER; - master_state = MASTER_START; - responses_collected = 0; - responses_expected = cluster_members - 1; - - /* If we are on our own then just do it */ - if (responses_expected == 0) { - P_MEMB("We are on our own...lonely here\n"); - responses_collected--; - do_process_startack(NULL, NULL, 0); - } - else { - int ptr = sizeof (struct cl_mem_starttrans_msg); - struct list_head *addrlist; - unsigned short num_addrs = 0; - int flags = MSG_REPLYEXP; - - /* Send the STARTTRANS message */ - msg->cmd = CLUSTER_MEM_STARTTRANS; - msg->reason = reason; - msg->votes = node->votes; - msg->expected_votes = cpu_to_le32(node->expected_votes); - msg->generation = cpu_to_le32(++cluster_generation); - msg->nodeid = cpu_to_le32(node->node_id); - msg->flags = node->leave_reason; - - if (reason == TRANS_NEWNODE) { - /* Add the addresses */ - list_for_each(addrlist, &node->addr_list) { - struct cluster_node_addr *nodeaddr = - list_entry(addrlist, - struct cluster_node_addr, list); - - memcpy(startbuf + ptr, nodeaddr->addr, - address_length); - ptr += address_length; - num_addrs++; - } - - /* And the name */ - strcpy(startbuf + ptr, node->name); - ptr += strlen(node->name) + 1; - } - printk(KERN_INFO CMAN_NAME ": Initiating transition, generation %d\n", cluster_generation); - - /* If another node died then we must queue the STARTTRANS - * messages so that membershipd can carry on processing the - * other replies */ - if (reason == TRANS_ANOTHERREMNODE) - flags |= MSG_QUEUE; - - msg->num_addrs = cpu_to_le16(num_addrs); - kcl_sendmsg(mem_socket, msg, ptr, NULL, 0, flags); - - /* Set a timer in case we don't get 'em all back */ - mod_timer(&transition_timer, - jiffies + cman_config.transition_timeout * HZ); - } - return 0; -} - -/* A node has died - decide what to do */ -void a_node_just_died(struct cluster_node *node) -{ - /* If we are not in the context of kmembershipd then stick it on the - * list and wake it */ - if (current != membership_task) { - struct cl_new_dead_node *newnode = - kmalloc(sizeof (struct cl_new_dead_node), GFP_KERNEL); - if (!newnode) - return; - newnode->node = node; - spin_lock(&new_dead_node_lock); - list_add_tail(&newnode->list, &new_dead_node_list); - set_bit(WAKE_FLAG_DEADNODE, &wake_flags); - spin_unlock(&new_dead_node_lock); - spin_lock(&membership_task_lock); - if (membership_task) - wake_up_process(membership_task); - spin_unlock(&membership_task_lock); - P_MEMB("Passing dead node %s onto kmembershipd\n", node->name); - return; - } - - printk(KERN_WARNING CMAN_NAME ": removing node %s from the cluster : %s\n", - node->name, leave_string(node->leave_reason)); - - /* Remove it */ - down(&cluster_members_lock); - if (node->state == NODESTATE_MEMBER) - cluster_members--; - node->state = NODESTATE_DEAD; - node->last_seq_recv = 0; - node->last_ackneeded_seq_recv = 0; - up(&cluster_members_lock); - - send_nodedown(node->node_id, node->leave_reason); - - /* Notify listeners */ - notify_kernel_listeners(DIED, (long) node->node_id); - - /* If we are in normal operation then become master and initiate a - * state-transition */ - if (node_state == MEMBER) { - start_transition(TRANS_REMNODE, node); - return; - } - - /* If we are a slave in transition then see if it's the master that has - * failed. If not then ignore it. If it /is/ the master then elect a - * new one */ - if (node_state == TRANSITION) { - if (master_node == node) { - if (elect_master(&node, 0)) { - del_timer(&transition_timer); - node_state = MASTER; - - master_node->leave_reason = CLUSTER_LEAVEFLAG_NORESPONSE; - start_transition(TRANS_DEADMASTER, master_node); - } - else { - /* Someone else can be in charge - phew! */ - } - } - return; - } - - /* If we are the master then we need to start the transition all over - * again */ - if (node_state == MASTER) { - /* Cancel timer */ - del_timer(&transition_timer); - - /* Restart the transition */ - start_transition(TRANS_ANOTHERREMNODE, node); - transition_restarts = 0; - return; - } -} - -/* - * Build up and send a set of messages consisting of the whole cluster view. - * The first byte is the command (cmd as passed in), the second is a flag byte: - * bit 0 is set in the first message, bit 1 in the last (NOTE both may be set if - * this is the only message sent The rest is a set of packed node entries, which - * are NOT split over packets. */ -static int send_cluster_view(unsigned char cmd, struct sockaddr_cl *saddr, - unsigned int flags, unsigned int flags2) -{ - int ptr = 2; - int len; - int status = 0; - int last_node_start = 2; - unsigned char first_packet_flag = 1; - struct list_head *nodelist; - struct list_head *temp; - struct cluster_node *node; - char *message = scratchbuf; - - message[0] = cmd; - P_MEMB("send_cluster_view, msg=%d\n", cmd); - - down(&cluster_members_lock); - list_for_each_safe(nodelist, temp, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - P_MEMB("Node %s (%d), state = %d\n", node->name, node->node_id, node->state); - - if (node->state == NODESTATE_MEMBER || node->state == NODESTATE_DEAD) { - unsigned int evotes; - unsigned int node_id; - unsigned short num_addrs = 0; - unsigned short num_addrs_le; - struct list_head *addrlist; - - last_node_start = ptr; - - message[ptr++] = len = strlen(node->name); - strcpy(&message[ptr], node->name); - ptr += len; - - message[ptr++] = node->state; - - /* Count the number of addresses this node has */ - list_for_each(addrlist, &node->addr_list) { - num_addrs++; - } - - num_addrs_le = cpu_to_le16(num_addrs); - memcpy(&message[ptr], &num_addrs_le, sizeof (short)); - ptr += sizeof (short); - - /* Pack em in */ - list_for_each(addrlist, &node->addr_list) { - - struct cluster_node_addr *nodeaddr = - list_entry(addrlist, - struct cluster_node_addr, list); - - memcpy(&message[ptr], nodeaddr->addr, - address_length); - ptr += address_length; - } - - message[ptr++] = node->votes; - - evotes = cpu_to_le32(node->expected_votes); - memcpy(&message[ptr], &evotes, sizeof (int)); - ptr += sizeof (int); - - node_id = cpu_to_le32(node->node_id); - memcpy(&message[ptr], &node_id, sizeof (int)); - ptr += sizeof (int); - - /* If the block is full then send it */ - if (ptr > MAX_CLUSTER_MESSAGE) { - message[1] = first_packet_flag; - - up(&cluster_members_lock); - status = kcl_sendmsg(mem_socket, message, - last_node_start, saddr, - saddr ? sizeof (struct sockaddr_cl) : 0, - flags); - - if (status < 0) - goto send_fail; - - down(&cluster_members_lock); - - first_packet_flag = 0; - /* Copy the overflow back to the start of the - * buffer for the next send */ - memcpy(&message[2], &message[last_node_start], - ptr - last_node_start); - ptr = ptr - last_node_start + 2; - } - } - } - - up(&cluster_members_lock); - - message[1] = first_packet_flag | 2; /* The last may also be first */ - status = kcl_sendmsg(mem_socket, message, ptr, - saddr, saddr ? sizeof (struct sockaddr_cl) : 0, - flags | flags2); - send_fail: - - return status; -} - -/* Make the JOINING node into a MEMBER */ -static void confirm_joiner() -{ - if (joining_node && joining_node->state == NODESTATE_JOINING) { - down(&cluster_members_lock); - joining_node->state = NODESTATE_MEMBER; - cluster_members++; - up(&cluster_members_lock); - } -} - -/* Reset HELLO timers for all nodes We do this after a state-transition as we - * have had HELLOS disabled during the transition and if we don't do this the - * nodes will go on an uncontrolled culling-spree afterwards */ -static void reset_hello_time() -{ - struct list_head *nodelist; - struct cluster_node *node; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->state == NODESTATE_MEMBER) { - node->last_hello = jiffies; - } - - } - up(&cluster_members_lock); -} - -/* Calculate the new quorum and return the value. do *not* set it in here as - * cnxman calls this to check if a new expected_votes value is valid. It - * (optionally) returns the total number of votes in the cluster */ -int calculate_quorum(int allow_decrease, int max_expected, int *ret_total_votes) -{ - struct list_head *nodelist; - struct cluster_node *node; - unsigned int total_votes = 0; - unsigned int highest_expected = 0; - unsigned int newquorum, q1, q2; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->state == NODESTATE_MEMBER) { - highest_expected = - max(highest_expected, node->expected_votes); - total_votes += node->votes; - } - } - up(&cluster_members_lock); - if (quorum_device && quorum_device->state == NODESTATE_MEMBER) - total_votes += quorum_device->votes; - - if (max_expected > 0) - highest_expected = max_expected; - - /* This quorum calculation is taken from the OpenVMS Cluster Systems - * manual, but, then, you guessed that didn't you */ - q1 = (highest_expected + 2) / 2; - q2 = (total_votes + 2) / 2; - newquorum = max(q1, q2); - - /* Normally quorum never decreases but the system administrator can - * force it down by setting expected votes to a maximum value */ - if (!allow_decrease) - newquorum = max(quorum, newquorum); - - /* The special two_node mode allows each of the two nodes to retain - * quorum if the other fails. Only one of the two should live past - * fencing (as both nodes try to fence each other in split-brain.) */ - if (two_node) - newquorum = 1; - - if (ret_total_votes) - *ret_total_votes = total_votes; - return newquorum; -} - -/* Recalculate cluster quorum, set quorate and notify changes */ -void recalculate_quorum(int allow_decrease) -{ - int total_votes; - - quorum = calculate_quorum(allow_decrease, 0, &total_votes); - set_quorate(total_votes); - notify_listeners(); -} - -/* Add new node address to an existing node */ -int add_node_address(struct cluster_node *node, unsigned char *addr, int len) -{ - struct cluster_node_addr *newaddr; - - newaddr = kmalloc(sizeof (struct cluster_node_addr), GFP_KERNEL); - if (!newaddr) - return -1; - - memcpy(newaddr->addr, addr, len); - newaddr->addr_len = len; - list_add_tail(&newaddr->list, &node->addr_list); - - return 0; -} - -static struct cluster_node *add_new_node(char *name, unsigned char votes, - unsigned int expected_votes, - int node_id, int state) -{ - struct cluster_node *newnode; - - /* Look for a dead node with this name */ - newnode = find_node_by_name(name); - - /* Is it already joining */ - if (newnode && newnode->state == NODESTATE_JOINING) - return NULL; - - /* Update existing information */ - if (newnode && newnode->state == NODESTATE_DEAD) { - newnode->last_hello = jiffies; - newnode->votes = votes; - newnode->expected_votes = expected_votes; - newnode->state = state; - newnode->us = 0; - newnode->leave_reason = 0; - newnode->last_seq_recv = 0; - newnode->last_ackneeded_seq_recv = 0; - newnode->last_seq_acked = 0; - newnode->last_seq_sent = 0; - newnode->incarnation++; - do_gettimeofday(&newnode->join_time); - /* Don't overwrite the node ID */ - - if (state == NODESTATE_MEMBER) { - down(&cluster_members_lock); - cluster_members++; - up(&cluster_members_lock); - } - - printk(KERN_INFO CMAN_NAME ": node %s rejoining\n", name); - return newnode; - } - - newnode = kmalloc(sizeof (struct cluster_node), GFP_KERNEL); - if (!newnode) - goto alloc_err; - - memset(newnode, 0, sizeof (struct cluster_node)); - newnode->name = kmalloc(strlen(name) + 1, GFP_KERNEL); - if (!newnode->name) - goto alloc_err1; - - strcpy(newnode->name, name); - newnode->last_hello = jiffies; - newnode->votes = votes; - newnode->expected_votes = expected_votes; - newnode->state = state; - newnode->node_id = node_id; - newnode->us = 0; - newnode->leave_reason = 0; - newnode->last_seq_recv = 0; - newnode->last_ackneeded_seq_recv = 0; - newnode->last_seq_acked = 0; - newnode->last_seq_sent = 0; - newnode->incarnation = 0; - do_gettimeofday(&newnode->join_time); - INIT_LIST_HEAD(&newnode->addr_list); - set_nodeid(newnode, node_id); - - /* Add the new node to the list */ - down(&cluster_members_lock); - list_add(&newnode->list, &cluster_members_list); - if (state == NODESTATE_MEMBER) - cluster_members++; - up(&cluster_members_lock); - - if (state == NODESTATE_MEMBER) - printk(KERN_INFO CMAN_NAME ": got node %s\n", name); - - return newnode; - - alloc_err1: - kfree(newnode); - alloc_err: - send_leave(CLUSTER_LEAVEFLAG_PANIC); - - printk(KERN_CRIT CMAN_NAME - ": Cannot allocate memory for new cluster node %s\n", name); - - panic("cluster memory allocation failed"); - - return NULL; -} - -/* Remove node from a NODEDOWN message */ -static struct cluster_node *remove_node(int nodeid, unsigned char reason) -{ - struct cluster_node *node; - - /* It may be a failed joiner */ - if (joining_node && joining_node->node_id == nodeid) { - remove_joiner(0); - } - - node = find_node_by_nodeid(nodeid); - if (node && node->state != NODESTATE_DEAD) { - printk(KERN_INFO CMAN_NAME ": node %s has been removed from the cluster : %s\n", - node->name, leave_string(reason)); - down(&cluster_members_lock); - node->state = NODESTATE_DEAD; - cluster_members--; - up(&cluster_members_lock); - node->leave_reason = reason; - - notify_kernel_listeners(DIED, (long) nodeid); - - /* If this node is us then go quietly */ - if (node->us) { - printk(KERN_INFO CMAN_NAME - ": killed by NODEDOWN message\n"); - node_state = LEFT_CLUSTER; - quit_threads = 1; - wake_up_process(membership_task); - wake_up_interruptible(&cnxman_waitq); - } - } - return node; -} - -/* Add a node from a STARTTRANS or NOMINATE message */ -static void add_node_from_starttrans(struct msghdr *msg, char *buf, int len) -{ - /* Add the new node but don't fill in the ID until the master has - * confirmed it */ - struct cl_mem_starttrans_msg *startmsg = - (struct cl_mem_starttrans_msg *)buf; - int ptr = sizeof (struct cl_mem_starttrans_msg); - int i; - char *name = buf + ptr + le16_to_cpu(startmsg->num_addrs) * address_length; - char *nodeaddr = buf + sizeof(struct cl_mem_starttrans_msg); - - /* Remove any old joiner */ - remove_joiner(0); - - joining_node = add_new_node(name, startmsg->votes, - le32_to_cpu(startmsg->expected_votes), - le32_to_cpu(startmsg->nodeid), NODESTATE_JOINING); - - /* add_new_node returns NULL if the node already exists */ - if (!joining_node) - joining_node = find_node_by_name(name); - - /* Add the node's addresses */ - if (list_empty(&joining_node->addr_list)) { - for (i = 0; i < le16_to_cpu(startmsg->num_addrs); i++) { - add_node_address(joining_node, buf + ptr, address_length); - ptr += address_length; - } - } - - /* Make sure we have a temp nodeid for the new node in case we - become master */ - joining_temp_nodeid = new_temp_nodeid(nodeaddr, - address_length); -} - -/* We have been nominated as master for a transition */ -static int do_process_nominate(struct msghdr *msg, char *buf, int len) -{ - struct cl_mem_starttrans_msg *startmsg = - (struct cl_mem_starttrans_msg *)buf; - struct cluster_node *node = NULL; - - P_MEMB("nominate reason is %d\n", startmsg->reason); - remove_joiner(1); - - if (startmsg->reason == TRANS_NEWNODE) { - add_node_from_starttrans(msg, buf, len); - node = joining_node; - } - - /* Start_transition needs some node info */ - if (node == NULL) - node = us; - start_transition(startmsg->reason, node); - return 0; -} - -/* Got a STARTACK response from a node */ -static int do_process_startack(struct msghdr *msg, char *buf, int len) -{ - if (node_state != MASTER && master_state != MASTER_START) { - P_MEMB("Got StartACK when not in MASTER_STARTING substate\n"); - return 0; - } - - /* buf is NULL if we are called directly from start_transition */ - if (buf) { - struct cl_mem_startack_msg *ackmsg = - (struct cl_mem_startack_msg *)buf; - - /* Ignore any messages wil old generation numbers in them */ - if (le32_to_cpu(ackmsg->generation) != cluster_generation) { - P_MEMB("Got old generation START-ACK msg - ignoring\n"); - return 0; - } - } - - /* If we have all the responses in then move to the next stage */ - if (++responses_collected == responses_expected) { - - /* Behave a little differently if we are on our own */ - if (cluster_members == 1) { - if (transitionreason == TRANS_NEWNODE) { - /* If the cluster is just us then confirm at - * once */ - joinconf_count = 0; - mod_timer(&transition_timer, - jiffies + - cman_config.joinconf_timeout * HZ); - if (send_joinconf() < 0) - end_transition(); - return 0; - } - else { /* Node leaving the cluster */ - int total_votes; - quorum = calculate_quorum(leavereason, leavereason?cluster_members:0, &total_votes); - set_quorate(total_votes); - leavereason = 0; - joining_temp_nodeid = 0; - node_state = MEMBER; - notify_listeners(); - sm_member_update(cluster_is_quorate); - } - } - else { - master_state = MASTER_COLLECT; - responses_collected = 0; - responses_expected = cluster_members - 1; - P_MEMB("Sending MASTERVIEW: expecting %d responses\n", - responses_expected); - - send_cluster_view(CLUSTER_MEM_MASTERVIEW, NULL, 0, MSG_REPLYEXP); - - /* Set a timer in case we don't get 'em all back */ - mod_timer(&transition_timer, - jiffies + - cman_config.transition_timeout * HZ); - } - } - return 0; -} - -/* Got a VIEWACK response from a node */ -static int do_process_viewack(struct msghdr *msg, char *reply, int len) -{ - struct sockaddr_cl *saddr = msg->msg_name; - - - /* This has been known to happen, but I'm not sure why */ - if (saddr->scl_nodeid < 1) - return 0; - - if (node_opinion == NULL) { - node_opinion = - kmalloc((10 + highest_nodeid) * sizeof (uint8_t), GFP_KERNEL); - if (!node_opinion) { - panic(": malloc agree/dissent failed\n"); - } - memset(node_opinion, 0, (1 + highest_nodeid) * sizeof (uint8_t)); - } - - /* Keep a list of agreeing and dissenting nodes */ - if (reply[1] == 1) { - /* ACK - remote node agrees with me */ - P_MEMB("Node agrees\n"); - node_opinion[saddr->scl_nodeid] = OPINION_AGREE; - agreeing_nodes++; - } - else { - /* Remote node disagrees */ - P_MEMB("Node disagrees\n"); - node_opinion[saddr->scl_nodeid] = OPINION_DISAGREE; - dissenting_nodes++; - } - - P_MEMB("got %d responses, expected %d\n", responses_collected + 1, - responses_expected); - - /* Are all the results in yet ? */ - if (++responses_collected == responses_expected) { - del_timer(&transition_timer); - - P_MEMB("The results are in: %d agree, %d dissent\n", - agreeing_nodes, dissenting_nodes); - - if (agreeing_nodes > dissenting_nodes) { - /* Kill dissenting nodes */ - int i; - - for (i = 1; i <= responses_collected; i++) { - if (node_opinion[i] == OPINION_DISAGREE) { - struct cluster_node *node; - node = find_node_by_nodeid(saddr->scl_nodeid); - if (node) - node->leave_reason = CLUSTER_LEAVEFLAG_INCONSISTENT; - send_kill(i, 1); - - - } - } - } - else { - /* We must leave the cluster as we are in a minority, - * the rest of them can fight it out amongst - * themselves. */ - us->leave_reason = CLUSTER_LEAVEFLAG_INCONSISTENT; - agreeing_nodes = 0; - dissenting_nodes = 0; - kfree(node_opinion); - node_opinion = NULL; - node_state = LEFT_CLUSTER; - quit_threads = 1; - wake_up_process(membership_task); - wake_up_interruptible(&cnxman_waitq); - return -1; - } - - /* Reset counters */ - agreeing_nodes = 0; - dissenting_nodes = 0; - kfree(node_opinion); - node_opinion = NULL; - - /* Confirm new node */ - if (transitionreason == TRANS_NEWNODE) { - mod_timer(&transition_timer, - jiffies + cman_config.joinconf_timeout * HZ); - joinconf_count = 0; - if (send_joinconf() >= 0) - return 0; - /* if send_joinconf failed then complete the transition here and how */ - } - - master_state = MASTER_COMPLETE; - - end_transition(); - } - - return 0; -} - -/* Remove the node from the list if it's a brand-new node, - * otherwise we end up knowing about a node that no-one - * else has and transitions get a bit fragile! - * - * Optionally tells the joining node to cancel it's join and try - * again later. - */ -static void remove_joiner(int tell_wait) -{ - if (!joining_node) - return; - - if (tell_wait) { - struct sockaddr_cl saddr; - - saddr.scl_nodeid = joining_temp_nodeid; - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - - P_MEMB("Postponing membership of node %s (incarnation=%d)\n", - joining_node->name, joining_node->incarnation); - send_joinack((char *)&saddr, sizeof(saddr), - JOINACK_TYPE_WAIT); - } - - if (joining_node->incarnation == 0) { - P_MEMB("Removing joining node %s\n", joining_node->name); - down(&cluster_members_lock); - if (joining_node->state == NODESTATE_MEMBER) - cluster_members--; - list_del(&joining_node->list); - up(&cluster_members_lock); - - if (joining_node->node_id) - members_by_nodeid[joining_node->node_id] = NULL; - kfree(joining_node); - } - else { - joining_node->state = NODESTATE_DEAD; - } - joining_node = NULL; - joining_temp_nodeid = 0; -} - -/* Got an ENDTRANS message */ -static int do_process_endtrans(struct msghdr *msg, char *buf, int len) -{ - struct cl_mem_endtrans_msg *endmsg = - (struct cl_mem_endtrans_msg *)buf; - struct sockaddr_cl *saddr = (struct sockaddr_cl *) msg->msg_name; - - /* Someone else's state transition */ - if (node_state != TRANSITION && node_state != JOINACK) - return 0; - - /* Check we got it from the MASTER node */ - if (master_node && master_node->node_id != saddr->scl_nodeid) { - printk(KERN_INFO - "Got ENDTRANS from a node not the master: master: %d, sender: %d\n", - master_node->node_id, saddr->scl_nodeid); - return 0; - } - - del_timer(&transition_timer); - - printk(KERN_INFO CMAN_NAME ": Finished transition, generation %d\n", cluster_generation); - /* Set our new node id */ - if (endmsg->new_node_id && us->node_id == 0) { - set_nodeid(us, le32_to_cpu(endmsg->new_node_id)); - P_MEMB("our new node ID is %d\n", us->node_id); - } - - node_state = TRANSITION_COMPLETE; - - if (endmsg->new_node_id) - confirm_joiner(); - else - remove_joiner(0); - - cluster_generation = le32_to_cpu(endmsg->generation); - - if (wait_for_completion_barrier() != 0) { - P_MEMB("Barrier timed out - restart client(ie do nowt)\n"); - node_state = TRANSITION; - mod_timer(&transition_timer, - jiffies + cman_config.transition_timeout * HZ); - return 0; - } - - quorum = le32_to_cpu(endmsg->quorum); - set_quorate(le32_to_cpu(endmsg->total_votes)); - highest_nodeid = get_highest_nodeid(); - - /* Tell any waiting barriers that we had a transition */ - check_barrier_returns(); - - purge_temp_nodeids(); - - /* Clear up */ - master_node = NULL; - joining_node = NULL; - joining_temp_nodeid = 0; - - node_state = MEMBER; - transitionreason = TRANS_NONE; - - /* Notify other listeners that transition has completed */ - notify_listeners(); - reset_hello_time(); - transition_end_time = jiffies; - - sm_member_update(cluster_is_quorate); - return 0; -} - -/* Turn a STARTTRANS message into NOMINATE and send it to the new master */ -static int send_nominate(struct cl_mem_starttrans_msg *startmsg, int msglen, - int nodeid) -{ - struct sockaddr_cl maddr; - - maddr.scl_port = CLUSTER_PORT_MEMBERSHIP; - maddr.scl_family = AF_CLUSTER; - maddr.scl_nodeid = nodeid; - - startmsg->cmd = CLUSTER_MEM_NOMINATE; - return kcl_sendmsg(mem_socket, startmsg, msglen, - &maddr, sizeof (maddr), 0); -} - -/* Got a NODEDOWN message */ -static int do_process_nodedown(struct msghdr *msg, char *buf, int len) -{ - struct cl_mem_nodedown_msg *downmsg = - (struct cl_mem_nodedown_msg *)buf; - - remove_node(le32_to_cpu(downmsg->nodeid), downmsg->reason); - return 0; -} - -/* Got a STARTTRANS message */ -static int do_process_starttrans(struct msghdr *msg, char *buf, int len) -{ - struct cl_mem_starttrans_msg *startmsg = - (struct cl_mem_starttrans_msg *)buf; - struct sockaddr_cl *saddr = (struct sockaddr_cl *) msg->msg_name; - struct cluster_node *node; - unsigned int newgen = le32_to_cpu(startmsg->generation); - - /* Got a WHAT from WHOM? */ - node = find_node_by_nodeid(saddr->scl_nodeid); - if (!node || node->state != NODESTATE_MEMBER) - return 0; - - /* Someone else's state transition */ - if (node_state != MEMBER && - node_state != TRANSITION && node_state != MASTER) - return 0; - - /* Ignore old generation STARTTRANS messages */ - if ((newgen < cluster_generation) || - (newgen == 0xFFFFFFFF && cluster_generation == 0)) { - P_MEMB("Ignoring STARTTRANS with old generation number\n"); - return 0; - } - - printk(KERN_INFO CMAN_NAME ": Started transition, generation %d\n", newgen); - P_MEMB("Got starttrans: newgen = %d, oldgen = %d, reason = %d\n", - newgen, cluster_generation, startmsg->reason); - - /* Up the generation number */ - cluster_generation = newgen; - - /* If we are also a master then decide between us */ - if (node_state == MASTER) { - - int not_master = 0; - - /* If one node is doing a CHECK and another a "real" transition then prevent - the CHECK from being master as it's a waste of time */ - if (transitionreason != startmsg->reason) { - if (transitionreason == TRANS_CHECK) - not_master = us->node_id; - if (startmsg->reason == TRANS_CHECK) - not_master = saddr->scl_nodeid; - } - - /* See if we really want the responsibility of being master */ - if (elect_master(&node, not_master)) { - - /* I reluctantly accept this position of responsibility - */ - P_MEMB("I elected myself master\n"); - - /* start_transition will re-establish this */ - del_timer(&transition_timer); - - start_transition(TRANS_NEWMASTER, node); - return 0; - } - else { - /* Back down */ - P_MEMB("Backing down from MASTER status\n"); - master_node = node; - node_state = TRANSITION; - - /* If we were bringing a new node into the cluster then - * we will have to abandon that now and tell the new - * node to try again later */ - if (transitionreason == TRANS_NEWNODE && joining_node) { - remove_joiner(1); - } - - /* If the new master is not us OR the node we just got - * the STARTTRANS from then make sure it knows it has - * to be master */ - if (saddr->scl_nodeid != node->node_id) { - send_nominate(startmsg, len, node->node_id); - return 0; - } - - /* Fall through into MEMBER code below if we are - * obeying the STARTTRANS we just received */ - } - } - - /* Do non-MASTER STARTTRANS bits */ - if (node_state == MEMBER) { - - P_MEMB("Normal transition start\n"); - - /* Save the master info */ - master_node = find_node_by_nodeid(saddr->scl_nodeid); - node_state = TRANSITION; - - if (startmsg->reason == TRANS_NEWNODE) { - add_node_from_starttrans(msg, buf, len); - } - - send_startack(saddr, msg->msg_namelen); - - /* Establish timer in case the master dies */ - mod_timer(&transition_timer, - jiffies + cman_config.transition_timeout * HZ); - - return 0; - } - - /* We are in transition but this may be a restart */ - if (node_state == TRANSITION) { - struct cluster_node *oldjoin = joining_node; - - master_node = find_node_by_nodeid(saddr->scl_nodeid); - - /* Is it a new joining node ? This happens if a master is - * usurped */ - if (startmsg->reason == TRANS_NEWNODE) { - - add_node_from_starttrans(msg, buf, len); - } - - /* If this is a different node joining than the one we - * were previously joining (probably cos the master is - * a nominated one) then mark our "old" joiner as DEAD. - * The original master will already have told the node - * to go back into JOINWAIT state */ - if (oldjoin && oldjoin != joining_node && - oldjoin->state == NODESTATE_JOINING) - oldjoin->state = NODESTATE_DEAD; - - send_startack(saddr, msg->msg_namelen); - - /* Is it a new master node? */ - if (startmsg->reason == TRANS_NEWMASTER || - startmsg->reason == TRANS_DEADMASTER) { - P_MEMB("starttrans %s, node=%d\n", - startmsg->reason == - TRANS_NEWMASTER ? "NEWMASTER" : "DEADMASTER", - le32_to_cpu(startmsg->nodeid)); - - /* Store new master */ - master_node = find_node_by_nodeid(saddr->scl_nodeid); - } - - - /* Restart the timer */ - del_timer(&transition_timer); - mod_timer(&transition_timer, - jiffies + cman_config.transition_timeout * HZ); - } - - return 0; -} - - -/* Change a cluster parameter */ -static int do_process_reconfig(struct msghdr *msg, char *buf, int len) -{ - struct cl_mem_reconfig_msg *confmsg; - struct sockaddr_cl *saddr = msg->msg_name; - struct cluster_node *node; - unsigned int val; - - if (len < sizeof(struct cl_mem_reconfig_msg)) - return -1; - - confmsg = (struct cl_mem_reconfig_msg *)buf; - val = le32_to_cpu(confmsg->value); - - switch (confmsg->param) { - - case RECONFIG_PARAM_EXPECTED_VOTES: - /* Set any nodes with expected_votes higher than the new value - * down */ - if (val > 0) { - struct cluster_node *node; - - down(&cluster_members_lock); - list_for_each_entry(node, &cluster_members_list, list) { - if (node->state == NODESTATE_MEMBER && - node->expected_votes > val) { - node->expected_votes = val; - } - } - up(&cluster_members_lock); - if (expected_votes > val) - expected_votes = val; - } - recalculate_quorum(1); /* Allow decrease */ - sm_member_update(cluster_is_quorate); - break; - - case RECONFIG_PARAM_NODE_VOTES: - node = find_node_by_nodeid(saddr->scl_nodeid); - node->votes = val; - recalculate_quorum(1); /* Allow decrease */ - sm_member_update(cluster_is_quorate); - break; - - case RECONFIG_PARAM_CONFIG_VERSION: - config_version = val; - break; - - default: - printk(KERN_INFO CMAN_NAME - ": got unknown parameter in reconfigure message. %d\n", - confmsg->param); - break; - } - return 0; -} - -/* Response from master node */ -static int do_process_joinack(struct msghdr *msg, char *buf, int len) -{ - struct cl_mem_joinack_msg *ackmsg = - (struct cl_mem_joinack_msg *)buf; - - join_time = jiffies; - if (ackmsg->acktype == JOINACK_TYPE_OK) { - node_state = JOINACK; - } - - if (ackmsg->acktype == JOINACK_TYPE_NAK) { - printk(KERN_WARNING CMAN_NAME - ": Cluster membership rejected\n"); - P_MEMB("Got JOINACK NACK\n"); - node_state = REJECTED; - } - - if (ackmsg->acktype == JOINACK_TYPE_WAIT) { - P_MEMB("Got JOINACK WAIT\n"); - node_state = JOINWAIT; - joinwait_time = jiffies; - } - - return 0; -} - -/* Check a JOINREQ message for validity, - return -1 if we can't let the node join our cluster */ -static int validate_joinmsg(struct cl_mem_join_msg *joinmsg, int len) -{ - struct cluster_node *node; - - /* Check version number */ - if (le32_to_cpu(joinmsg->major_version) == CNXMAN_MAJOR_VERSION) { - char *ptr = (char *) joinmsg; - char *name; - - ptr += sizeof (*joinmsg); - name = ptr + le16_to_cpu(joinmsg->num_addr) * address_length; - - /* Sanity-check the num_addrs field otherwise we could oops */ - if (le16_to_cpu(joinmsg->num_addr) * address_length > len) { - printk(KERN_WARNING CMAN_NAME - ": num_addr in JOIN-REQ message is rubbish: %d\n", - le16_to_cpu(joinmsg->num_addr)); - return -1; - } - - /* Check the cluster name matches */ - if (strcmp(cluster_name, joinmsg->clustername)) { - printk(KERN_WARNING CMAN_NAME - ": attempt to join with cluster name '%s' refused\n", - joinmsg->clustername); - return -1; - } - - /* Check we are not exceeding the maximum number of nodes */ - if (cluster_members >= cman_config.max_nodes) { - printk(KERN_WARNING CMAN_NAME - ": Join request from %s rejected, exceeds maximum number of nodes\n", - name); - return -1; - } - - /* Check that we don't exceed the two_node limit, if applicable */ - if (two_node && cluster_members == 2) { - printk(KERN_WARNING CMAN_NAME ": Join request from %s " - "rejected, exceeds two node limit\n", name); - return -1; - } - - if (le32_to_cpu(joinmsg->config_version) != config_version) { - printk(KERN_WARNING CMAN_NAME ": Join request from %s " - "rejected, config version local %u remote %u\n", - name, config_version, - le32_to_cpu(joinmsg->config_version)); - return -1; - } - - /* Validate requested static node ID */ - if (joinmsg->nodeid && - (node = find_node_by_nodeid(le32_to_cpu(joinmsg->nodeid))) && - (node->state != NODESTATE_DEAD || - (strcmp(node->name, name)))) { - printk(KERN_WARNING CMAN_NAME ": Join request from %s " - "rejected, node ID %d already in use by %s\n", - name, node->node_id, node->name); - return -1; - } - if (joinmsg->nodeid && - (node = find_node_by_name(name)) && - (node->state != NODESTATE_DEAD || - node->node_id != le32_to_cpu(joinmsg->nodeid))) { - printk(KERN_WARNING CMAN_NAME ": Join request from %s " - "rejected, wanted node %d but previously had %d\n", - name, le32_to_cpu(joinmsg->nodeid), node->node_id); - return -1; - } - - /* If these don't match then I don't know how the message - arrived! However, I can't take the chance */ - if (le32_to_cpu(joinmsg->addr_len) != address_length) { - printk(KERN_WARNING CMAN_NAME ": Join request from %s " - "rejected, address length local: %u remote %u\n", - name, address_length, - le32_to_cpu(joinmsg->addr_len)); - return -1; - } - } - else { - /* Version number mismatch, don't use any part of the message - * other than the version numbers as things may have moved */ - printk(KERN_INFO CMAN_NAME - ": Got join message from node running incompatible software. (us: %d.%d.%d, them: %d.%d.%d)\n", - CNXMAN_MAJOR_VERSION, CNXMAN_MINOR_VERSION, - CNXMAN_PATCH_VERSION, - le32_to_cpu(joinmsg->major_version), - le32_to_cpu(joinmsg->minor_version), - le32_to_cpu(joinmsg->patch_version)); - return -1; - } - return 0; -} - - -/* Request to join the cluster. This makes us the master for this state - * transition */ -static int do_process_joinreq(struct msghdr *msg, char *buf, int len) -{ - static unsigned long last_joinreq = 0; - static char last_name[MAX_CLUSTER_MEMBER_NAME_LEN]; - struct cl_mem_join_msg *joinmsg = (struct cl_mem_join_msg *)buf; - struct cluster_node *node; - char *ptr = (char *) joinmsg; - char *name; - int i; - struct sockaddr_cl *addr = msg->msg_name; - - ptr += sizeof (*joinmsg); - name = ptr + le16_to_cpu(joinmsg->num_addr) * address_length; - - /* If we are in a state transition then tell the new node to wait a bit - * longer */ - if (node_state != MEMBER) { - if (node_state == MASTER || node_state == TRANSITION) { - send_joinack(msg->msg_name, msg->msg_namelen, - JOINACK_TYPE_WAIT); - } - return 0; - } - - /* Reject application if message is invalid for any reason */ - if (validate_joinmsg(joinmsg, len)) { - send_joinack(msg->msg_name, msg->msg_namelen, - JOINACK_TYPE_NAK); - return 0; - } - - /* Do we already know about this node? */ - if (check_duplicate_node(name, msg, len) < 0) { - send_joinack(msg->msg_name, msg->msg_namelen, - JOINACK_TYPE_NAK); - return 0; - } - - /* Duplicate checking: Because joining messages do not have - * sequence numbers we may get as many JOINREQ messages as we - * have interfaces. This bit of code here just checks for - * JOINREQ messages that come in from the same node in a small - * period of time and removes the duplicates */ - if (time_before(jiffies, last_joinreq + 10 * HZ) - && strcmp(name, last_name) == 0) { - return 0; - } - - /* OK, you can be in my gang */ - last_joinreq = jiffies; - strcpy(last_name, name); - - node = add_new_node(name, joinmsg->votes, - le32_to_cpu(joinmsg->expected_votes), - le32_to_cpu(joinmsg->nodeid), - NODESTATE_JOINING); - - /* A genuinely new node, assign it a genuinely new ID */ - if (node->node_id == 0) { - set_nodeid(node, get_highest_nodeid()+1); - highest_nodeid = node->node_id; - } - P_MEMB("New node %s has id %d\n", node->name, node->node_id); - - /* Add the node's addresses */ - if (list_empty(&node->addr_list)) { - for (i = 0; i < le16_to_cpu(joinmsg->num_addr); - i++) { - add_node_address(node, ptr, address_length); - ptr += address_length; - } - } - send_joinack(msg->msg_name, msg->msg_namelen, - JOINACK_TYPE_OK); - joining_node = node; - joining_temp_nodeid = addr->scl_nodeid; - - /* Start the state transition */ - start_transition(TRANS_NEWNODE, node); - - return 0; -} - -/* A simple function to invent a small number based - on the node name */ -static int node_hash(void) -{ - int i; - int value = 0; - - for (i=0; i<strlen(nodename); i++) { - value += nodename[i]; - } - return (value & 0xF) + 1; -} - - -/* Return the low 32 bits of our IP address */ -static uint32_t low32_of_ip() -{ - struct cluster_node_addr *addr; - uint32_t lowip; - - addr = list_entry(us->addr_list.next, struct cluster_node_addr, list); - memcpy(&lowip, addr->addr+address_length-sizeof(uint32_t), sizeof(uint32_t)); - if (!lowip) - memcpy(&lowip, addr->addr - sizeof(uint32_t)*2, sizeof(uint32_t)); - - return lowip; -} - -/* A new node has stated its intent to form a new cluster. we may have - * something to say about that... */ -static int do_process_newcluster(struct msghdr *msg, char *buf, int len) -{ - /* If we are also in STARTING state then back down for a random period - * of time */ - if (node_state == STARTING) { - P_MEMB("got NEWCLUSTER, backing down for %d seconds\n", node_hash()); - start_time = jiffies + node_hash() * HZ; - } - - if (node_state == NEWCLUSTER) { - uint32_t otherip; - - memcpy(&otherip, buf+1, sizeof(otherip)); - otherip = le32_to_cpu(otherip); - P_MEMB("got NEWCLUSTER, remote ip = %x, us = %x\n", otherip, low32_of_ip()); - if (otherip < low32_of_ip()) - node_state = STARTING; - } - - if (node_state == MEMBER) - send_hello(0); - - return 0; -} - -/* Called for each node by the node-message unpacker. Returns -1 if there is a - * mismatch and the caller will stop processing */ -static int check_node(struct cluster_node *newnode, char *addrs, - unsigned short num_addr) -{ - struct cluster_node *node = find_node_by_name(newnode->name); - - P_MEMB("check_node: %s", newnode->name); - - if (!node) { - C_MEMB(" - not found\n"); - return -1; - } - - /* Don't fail things if we have a node flagged as JOINING - but the master thinks is DEAD */ - if (node->votes != newnode->votes || - node->node_id != newnode->node_id || - (node->state != NODESTATE_JOINING && - node->state != newnode->state)) { - C_MEMB(" - wrong info: votes=%d(exp: %d) id=%d(exp: %d) state = %d(exp: %d)\n", - node->votes, newnode->votes, node->node_id, - newnode->node_id, node->state, newnode->state); - return -1; - } - C_MEMB(" - OK\n"); - return 0; -} - -/* Called for each new node found in a JOINCONF message. Create a new node - * entry */ -static int add_node(struct cluster_node *node, char *addrs, - unsigned short num_addr) -{ - P_MEMB("add_node: %s, v:%d, e:%d, i:%d\n", node->name, node->votes, - node->expected_votes, node->node_id); - - if (!find_node_by_name(node->name)) { - struct cluster_node *newnode; - int i; - - if ((newnode = - add_new_node(node->name, node->votes, node->expected_votes, - node->node_id, node->state)) == NULL) { - P_MEMB("Error adding node\n"); - return -1; - } - if (list_empty(&newnode->addr_list)) { - for (i = 0; i < num_addr; i++) { - add_node_address(newnode, - addrs + i * address_length, address_length); - } - } - return 0; - } - else { - P_MEMB("Already got node with name %s\n", node->name); - return -1; - } -} - -/* Call a specified routine for each node unpacked from the message. Return - * either the number of nodes found or -1 for an error */ -static int unpack_nodes(unsigned char *buf, int len, - int (*routine) (struct cluster_node *, char *, - unsigned short)) -{ - int ptr = 0; - int num_nodes = 0; - char nodename[MAX_CLUSTER_MEMBER_NAME_LEN]; - struct cluster_node node; - - node.name = nodename; - - while (ptr < len) { - int namelen = buf[ptr++]; - unsigned int evotes; - unsigned int node_id; - unsigned short num_addr; - unsigned char *addrs; - - memcpy(nodename, &buf[ptr], namelen); - nodename[namelen] = '\0'; - ptr += namelen; - - node.state = buf[ptr++]; - - memcpy(&num_addr, &buf[ptr], sizeof (short)); - num_addr = le16_to_cpu(num_addr); - ptr += sizeof (short); - - /* Just make a note of the addrs "array" */ - addrs = &buf[ptr]; - ptr += num_addr * address_length; - - node.votes = buf[ptr++]; - - memcpy(&evotes, &buf[ptr], sizeof (int)); - node.expected_votes = le32_to_cpu(evotes); - ptr += sizeof (int); - - memcpy(&node_id, &buf[ptr], sizeof (int)); - node.node_id = le32_to_cpu(node_id); - ptr += sizeof (int); - - /* Call the callback routine */ - if (routine(&node, addrs, num_addr) < 0) - return -1; - - /* Return the number of MEMBER nodes */ - if (node.state == NODESTATE_MEMBER) - num_nodes++; - } - return num_nodes; -} - -/* Got join confirmation from a master node. This message contains a list of - * cluster nodes which we unpack and build into our cluster nodes list. When we - * have the last message we can go into TRANSITION state */ -static int do_process_joinconf(struct msghdr *msg, char *buf, int len) -{ - if (unpack_nodes(buf + 2, len - 2, add_node) < 0) { - printk(KERN_ERR CMAN_NAME - ": Error procssing joinconf message - giving up on cluster join\n"); - us->leave_reason = CLUSTER_LEAVEFLAG_PANIC; - node_state = LEFT_CLUSTER; - return -1; - } - - /* Last message in the list? */ - if (buf[1] & 2) { - char ackmsg; - struct sockaddr_cl *addr = msg->msg_name; - - us->state = NODESTATE_MEMBER; - node_state = TRANSITION; - we_are_a_cluster_member = TRUE; - - ackmsg = CLUSTER_MEM_CONFACK; - kcl_sendmsg(mem_socket, &ackmsg, 1, addr, - sizeof (struct sockaddr_cl), - MSG_NOACK); - kernel_thread(hello_kthread, NULL, 0); - mod_timer(&hello_timer, jiffies + cman_config.hello_timer * HZ); - } - return 0; -} - -/* Got the master's view of the cluster - compare it with ours and tell it the - * result */ -static int do_process_masterview(struct msghdr *msg, char *buf, int len) -{ - char reply[2] = { CLUSTER_MEM_VIEWACK, 0 }; - static int num_nodes; - - /* Someone else's state transition */ - if (node_state != MEMBER && - node_state != TRANSITION && node_state != MASTER) - return 0; - - /* First message, zero the counter */ - if (buf[1] & 1) - num_nodes = 0; - - num_nodes += unpack_nodes(buf + 2, len - 2, check_node); - - /* Last message, check the count and reply */ - if (buf[1] & 2) { - if (num_nodes == cluster_members) { - /* Send ACK */ - reply[1] = 1; - } - else { - P_MEMB - ("Got %d nodes in MASTERVIEW message, we think there s/b %d\n", - num_nodes, cluster_members); - /* Send NAK */ - reply[1] = 0; - } - kcl_sendmsg(mem_socket, reply, 2, msg->msg_name, - msg->msg_namelen, 0); - } - return 0; -} - -static int do_process_leave(struct msghdr *msg, char *buf, int len) -{ - struct cluster_node *node; - struct sockaddr_cl *saddr = msg->msg_name; - unsigned char *leavemsg = (unsigned char *)buf; - - if ((node = find_node_by_nodeid(saddr->scl_nodeid))) { - unsigned char reason = leavemsg[1]; - - node->leave_reason = reason; - leavereason = (reason == CLUSTER_LEAVEFLAG_REMOVED ? 1 : 0); - - a_node_just_died(node); - } - return 0; -} - -static int do_process_hello(struct msghdr *msg, char *buf, int len) -{ - struct cluster_node *node; - struct cl_mem_hello_msg *hellomsg = - (struct cl_mem_hello_msg *)buf; - struct sockaddr_cl *saddr = msg->msg_name; - - /* We are starting up. Send a join message to the node whose HELLO we - * just received */ - if (node_state == STARTING || node_state == JOINWAIT || - node_state == JOINING || node_state == NEWCLUSTER) { - struct sockaddr_cl *addr = msg->msg_name; - - printk(KERN_INFO CMAN_NAME ": sending membership request\n"); - - send_joinreq(addr, msg->msg_namelen); - join_time = jiffies; - node_state = JOINING; - return 0; - } - - /* Only process HELLOs if we are not in transition */ - if (node_state == MEMBER) { - - node = find_node_by_nodeid(saddr->scl_nodeid); - if (node && node->state != NODESTATE_DEAD) { - - /* Check the cluster generation in the HELLO message. - * NOTE: this may be different if the message crossed - * on the wire with an END-TRANS so we allow a period - * of grace in which this is allowable */ - if (cluster_generation != - le32_to_cpu(hellomsg->generation) - && node_state == MEMBER - && time_after(jiffies, - cman_config.hello_timer * HZ + - transition_end_time)) { - - printk(KERN_DEBUG CMAN_NAME - ": bad generation number %d in HELLO message from %d, expected %d\n", - le32_to_cpu(hellomsg->generation), - saddr->scl_nodeid, - cluster_generation); - - start_transition(TRANS_CHECK, node); - return 0; - } - - if (cluster_members != le16_to_cpu(hellomsg->members) - && node_state == MEMBER) { - printk(KERN_DEBUG CMAN_NAME - ": nmembers in HELLO message from %d does not match our view (got %d, exp %d)\n", - saddr->scl_nodeid, - le16_to_cpu(hellomsg->members), - cluster_members); - start_transition(TRANS_CHECK, node); - return 0; - } - /* The message is OK - save the time */ - node->last_hello = jiffies; - } - else { - /* This node is a danger to our valid cluster */ - if (cluster_is_quorate) { - send_kill(saddr->scl_nodeid, 0); - } - } - } - - /* If we get a master hello and we are not the master then start a CHECK transition, cos the - real master must have gone away in a period of confusion */ - if (node_state != MASTER && hellomsg->flags & HELLO_FLAG_MASTER) { - node = find_node_by_nodeid(saddr->scl_nodeid); - if (node) - start_transition(TRANS_CHECK, node); - } - - return 0; - -} - -static int do_process_kill(struct msghdr *msg, char *buf, int len) -{ - struct sockaddr_cl *saddr = msg->msg_name; - struct cluster_node *node; - - node = find_node_by_nodeid(saddr->scl_nodeid); - if (node && node->state == NODESTATE_MEMBER) { - - printk(KERN_INFO CMAN_NAME - ": Being told to leave the cluster by node %d\n", - saddr->scl_nodeid); - - node_state = LEFT_CLUSTER; - quit_threads = 1; - wake_up_process(membership_task); - wake_up_interruptible(&cnxman_waitq); - } - else { - P_MEMB("Asked to leave the cluster by a non-member. What a nerve!\n"); - } - return 0; -} - -/* Some cluster membership utility functions */ -struct cluster_node *find_node_by_name(char *name) -{ - struct list_head *nodelist; - struct cluster_node *node; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (strcmp(node->name, name) == 0) { - up(&cluster_members_lock); - return node; - } - } - up(&cluster_members_lock); - return NULL; -} - -/* Try to avoid using this as it's slow and holds the members lock */ -struct cluster_node *find_node_by_addr(unsigned char *addr, int addr_len) -{ - struct list_head *nodelist; - struct list_head *addrlist; - struct cluster_node *node; - struct cluster_node_addr *nodeaddr; - - down(&cluster_members_lock); - - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - list_for_each(addrlist, &node->addr_list) { - nodeaddr = - list_entry(addrlist, struct cluster_node_addr, - list); - - if (memcmp(nodeaddr->addr+2, addr+2, address_length-2) == 0) { - up(&cluster_members_lock); - return node; - } - } - } - - up(&cluster_members_lock); - return NULL; -} - -/* This is the quick way to find a node */ -struct cluster_node *find_node_by_nodeid(unsigned int id) -{ - struct cluster_node *node; - - if (id >= sizeof_members_array) - return NULL; - - spin_lock(&members_by_nodeid_lock); - node = members_by_nodeid[id]; - spin_unlock(&members_by_nodeid_lock); - return node; -} - -static int dispatch_messages(struct socket *mem_socket) -{ - int err = 0; - - while (skb_peek(&mem_socket->sk->sk_receive_queue)) { - struct msghdr msg; - struct kvec vec; - struct sockaddr_cl sin; - int len; - - /* Something more important to do ? */ - if (quit_threads ||test_bit(WAKE_FLAG_DEADNODE, &wake_flags)) - return 0; - - memset(&sin, 0, sizeof (sin)); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_name = &sin; - msg.msg_namelen = sizeof (sin); - msg.msg_flags = 0; - - vec.iov_len = MAX_CLUSTER_MESSAGE; - vec.iov_base = iobuf; - - len = kernel_recvmsg(mem_socket, &msg, &vec, 1, - MAX_CLUSTER_MESSAGE, - MSG_DONTWAIT); - if (len > 0) { - msg.msg_name = &sin; - do_membership_packet(&msg, iobuf, len); - } - else { - if (len == -EAGAIN) - err = 0; - else - err = -1; - break; - } - } - return err; -} - -/* Scan the nodes list for dead nodes */ -static void check_for_dead_nodes() -{ - struct list_head *nodelist; - struct cluster_node *node; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->state != NODESTATE_DEAD && - time_after(jiffies, - node->last_hello + - cman_config.deadnode_timeout * HZ) && !node->us) { - - up(&cluster_members_lock); - - P_MEMB("last hello was %ld, current time is %ld\n", - node->last_hello, jiffies); - - node->leave_reason = CLUSTER_LEAVEFLAG_DEAD; - leavereason = 0; - - /* This is unlikely to work but it's worth a try! */ - send_kill(node->node_id, 0); - - /* Start state transition */ - a_node_just_died(node); - return; - } - } - up(&cluster_members_lock); - - /* Also check for a dead quorum device */ - if (quorum_device) { - if (quorum_device->state == NODESTATE_MEMBER && - time_after(jiffies, - quorum_device->last_hello + - cman_config.deadnode_timeout * HZ)) { - quorum_device->state = NODESTATE_DEAD; - printk(KERN_WARNING CMAN_NAME - ": Quorum device %s timed out\n", - quorum_device->name); - recalculate_quorum(0); - } - } - - return; -} - -/* add "us" as a node in the cluster */ -static int add_us() -{ - struct cluster_node *newnode = - kmalloc(sizeof (struct cluster_node), GFP_KERNEL); - - if (!newnode) { - /* Oh shit, we have to commit hara kiri here for the greater - * good of the cluster */ - send_leave(CLUSTER_LEAVEFLAG_PANIC); - - printk(KERN_CRIT CMAN_NAME - ": Cannot allocate memory for our node structure\n"); - panic("Must die"); - - return -1; - } - - memset(newnode, 0, sizeof (struct cluster_node)); - newnode->name = kmalloc(strlen(nodename) + 1, GFP_KERNEL); - if (!newnode->name) { - send_leave(CLUSTER_LEAVEFLAG_PANIC); - - printk(KERN_CRIT CMAN_NAME - ": Cannot allocate memory for node name\n"); - kfree(newnode); - - panic("Must die"); - - return -1; - } - - strcpy(newnode->name, nodename); - newnode->last_hello = jiffies; - newnode->votes = votes; - newnode->expected_votes = expected_votes; - newnode->state = NODESTATE_JOINING; - newnode->node_id = 0; /* Will get filled in by ENDTRANS message */ - newnode->us = 1; - newnode->leave_reason = 0; - INIT_LIST_HEAD(&newnode->addr_list); - get_local_addresses(newnode); /* Get from cnxman socket info */ - do_gettimeofday(&newnode->join_time); - - /* Add the new node to the list */ - down(&cluster_members_lock); - list_add(&newnode->list, &cluster_members_list); - cluster_members++; - up(&cluster_members_lock); - us = newnode; - - return 0; -} - -/* Return the highest known node_id */ -unsigned int get_highest_nodeid() -{ - struct list_head *nodelist; - struct cluster_node *node = NULL; - unsigned int highest = 0; - - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - - if (node->node_id > highest) - highest = node->node_id; - } - up(&cluster_members_lock); - - return highest; -} - -/* Elect a new master if there is a clash. Returns 1 if we are the new master, - * the master's struct will also be returned. This, rather primitively, uses - * the lowest node ID */ -static int elect_master(struct cluster_node **master_node, int disallow_node) -{ - int i; - - for (i = 1; i < sizeof_members_array; i++) { - if (members_by_nodeid[i] && - members_by_nodeid[i]->state == NODESTATE_MEMBER) { - *master_node = members_by_nodeid[i]; - P_MEMB("Elected master is %s\n", (*master_node)->name); - return (*master_node)->us; - } - } - BUG(); - return 0; -} - -/* Called by node_cleanup in cnxman when we have left the cluster */ -void free_nodeid_array() -{ - vfree(members_by_nodeid); - members_by_nodeid = NULL; - sizeof_members_array = 0; -} - -int allocate_nodeid_array() -{ - /* Allocate space for the nodeid lookup array */ - if (!members_by_nodeid) { - spin_lock_init(&members_by_nodeid_lock); - members_by_nodeid = - vmalloc(cman_config.max_nodes * - sizeof (struct cluster_member *)); - } - - if (!members_by_nodeid) { - printk(KERN_WARNING - "Unable to allocate members array for %d members\n", - cman_config.max_nodes); - return -ENOMEM; - } - memset(members_by_nodeid, 0, - cman_config.max_nodes * sizeof (struct cluster_member *)); - sizeof_members_array = cman_config.max_nodes; - - return 0; -} - -/* Set the votes & expected_votes variables */ -void set_votes(int v, int e) -{ - votes = v; - expected_votes = e; -} - -int get_quorum() -{ - return quorum; -} - -/* Called by cnxman to see if activity should be blocked because we are in a - * state transition */ -int in_transition() -{ - return node_state == TRANSITION || - node_state == TRANSITION_COMPLETE || node_state == MASTER; -} - -/* Return the current membership state as a string for the main line to put - * into /proc . I really should be using snprintf rather than sprintf but it's - * not exported... */ -char *membership_state(char *buf, int buflen) -{ - switch (node_state) { - case STARTING: - strncpy(buf, "Starting", buflen); - break; - case NEWCLUSTER: - strncpy(buf, "New-Cluster?", buflen); - break; - case JOINING: - strncpy(buf, "Joining", buflen); - break; - case JOINWAIT: - strncpy(buf, "Join-Wait", buflen); - break; - case JOINACK: - strncpy(buf, "Join-Ack", buflen); - break; - case TRANSITION: - sprintf(buf, "State-Transition: Master is %s", - master_node ? master_node->name : "Unknown"); - break; - case MEMBER: - strncpy(buf, "Cluster-Member", buflen); - break; - case REJECTED: - strncpy(buf, "Rejected", buflen); - break; - case LEFT_CLUSTER: - strncpy(buf, "Not-in-Cluster", buflen); - break; - case TRANSITION_COMPLETE: - strncpy(buf, "Transition-Complete", buflen); - break; - case MASTER: - strncpy(buf, "Transition-Master", buflen); - break; - default: - sprintf(buf, "Unknown: code=%d", node_state); - break; - } - - return buf; -} - -char *leave_string(int reason) -{ - static char msg[32]; - switch (reason & 0xF) - { - case CLUSTER_LEAVEFLAG_DOWN: - return "Shutdown"; - case CLUSTER_LEAVEFLAG_KILLED: - return "Killed by another node"; - case CLUSTER_LEAVEFLAG_PANIC: - return "Panic"; - case CLUSTER_LEAVEFLAG_REMOVED: - return "Removed"; - case CLUSTER_LEAVEFLAG_REJECTED: - return "Membership rejected"; - case CLUSTER_LEAVEFLAG_INCONSISTENT: - return "Inconsistent cluster view"; - case CLUSTER_LEAVEFLAG_DEAD: - return "Missed too many heartbeats"; - case CLUSTER_LEAVEFLAG_NORESPONSE: - return "No response to messages"; - default: - sprintf(msg, "Reason is %d\n", reason); - return msg; - } -} - -#ifdef DEBUG_MEMB -static char *msgname(int msg) -{ - switch (msg) { - case CLUSTER_MEM_JOINCONF: - return "JOINCONF"; - case CLUSTER_MEM_JOINREQ: - return "JOINREQ"; - case CLUSTER_MEM_LEAVE: - return "LEAVE"; - case CLUSTER_MEM_HELLO: - return "HELLO"; - case CLUSTER_MEM_KILL: - return "KILL"; - case CLUSTER_MEM_JOINACK: - return "JOINACK"; - case CLUSTER_MEM_ENDTRANS: - return "ENDTRANS"; - case CLUSTER_MEM_RECONFIG: - return "RECONFIG"; - case CLUSTER_MEM_MASTERVIEW: - return "MASTERVIEW"; - case CLUSTER_MEM_STARTTRANS: - return "STARTTRANS"; - case CLUSTER_MEM_JOINREJ: - return "JOINREJ"; - case CLUSTER_MEM_VIEWACK: - return "VIEWACK"; - case CLUSTER_MEM_STARTACK: - return "STARTACK"; - case CLUSTER_MEM_NEWCLUSTER: - return "NEWCLUSTER"; - case CLUSTER_MEM_CONFACK: - return "CONFACK"; - case CLUSTER_MEM_NOMINATE: - return "NOMINATE"; - case CLUSTER_MEM_NODEDOWN: - return "NODEDOWN"; - - default: - return "??UNKNOWN??"; - } -} - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/cman-kernel/src/proc.c b/cman-kernel/src/proc.c deleted file mode 100644 index 6b9f52a..0000000 --- a/cman-kernel/src/proc.c +++ /dev/null @@ -1,562 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/init.h> -#include <linux/socket.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/file.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/list.h> -#include <linux/in.h> -#include <net/sock.h> -#include <cluster/cnxman.h> -#include <cluster/service.h> - -#include "cnxman-private.h" -#include "config.h" - -extern int cluster_members; -extern struct list_head cluster_members_list; -extern struct semaphore cluster_members_lock; -extern struct cluster_node *quorum_device; -extern int we_are_a_cluster_member; -extern int cluster_is_quorate; -extern uint16_t cluster_id; -extern atomic_t use_count; -extern unsigned int address_length; -extern unsigned int config_version; -extern char cluster_name[]; -extern char nodename[]; -extern struct cluster_node *us; -static struct seq_operations cluster_info_op; -static struct seq_operations cluster_status_info_op; - -enum status_state { - state_protocol_version, - state_config_version, - state_cluster_name, - state_cluster_id, - state_cluster_member, - state_cluster_member_state, - state_nodes, - state_expected_votes, - state_total_votes, - state_quorum, - state_active_subsystems, - state_nodename, - state_nodeid, - state_nodeaddrs, - state_done -}; - -struct cluster_status_info { - enum status_state state; - unsigned int total_votes; - unsigned int max_expected; - int node_addr_count; - struct sockaddr_in6 *saddr; -}; - -int sm_proc_open(struct inode *inode, struct file *file); -int sm_debug_info(char *b, char **start, off_t offset, int length); - -/* /proc interface to the configuration struct */ -static struct config_proc_info { - char *name; - int *value; -} config_proc[] = { - { - .name = "joinwait_timeout", - .value = &cman_config.joinwait_timeout, - }, - { - .name = "joinconf_timeout", - .value = &cman_config.joinconf_timeout, - }, - { - .name = "join_timeout", - .value = &cman_config.join_timeout, - }, - { - .name = "hello_timer", - .value = &cman_config.hello_timer, - }, - { - .name = "deadnode_timeout", - .value = &cman_config.deadnode_timeout, - }, - { - .name = "transition_timeout", - .value = &cman_config.transition_timeout, - }, - { - .name = "transition_restarts", - .value = &cman_config.transition_restarts, - }, - { - .name = "max_nodes", - .value = &cman_config.max_nodes, - }, - { - .name = "sm_debug_size", - .value = &cman_config.sm_debug_size, - }, - { - .name = "newcluster_timeout", - .value = &cman_config.newcluster_timeout, - }, - { - .name = "max_retries", - .value = &cman_config.max_retries, - }, - -}; - -static void cluster_status_state_mch(struct seq_file *m, - struct cluster_status_info *csi) -{ - int i; - - if (!csi || - (!we_are_a_cluster_member && csi->state > state_cluster_member_state)) - return; - - switch (csi->state) { - case state_protocol_version: - seq_printf(m, "Protocol version: %d.%d.%d\n", - CNXMAN_MAJOR_VERSION, CNXMAN_MINOR_VERSION, - CNXMAN_PATCH_VERSION); - break; - - case state_config_version: - seq_printf(m, "Config version: %d\n", config_version); - break; - - case state_cluster_name: - seq_printf(m,"Cluster name: %s\n", cluster_name); - break; - - case state_cluster_id: - seq_printf(m, "Cluster ID: %d\n", cluster_id); - break; - - case state_cluster_member: - seq_printf(m,"Cluster Member: %s\n", - we_are_a_cluster_member ? "Yes" : "No"); - break; - - case state_cluster_member_state: - { - char node_state_buf[256]; - - membership_state(node_state_buf, sizeof(node_state_buf)); - seq_printf(m, "Membership state: %s\n",node_state_buf); - break; - } - case state_nodes: - seq_printf(m, "Nodes: %d\n", cluster_members); - break; - - case state_expected_votes: - seq_printf(m, "Expected_votes: %d\n", csi->max_expected); - break; - - case state_total_votes: - seq_printf(m, "Total_votes: %d\n", csi->total_votes); - break; - - case state_quorum: - seq_printf(m, "Quorum: %d %s\n", get_quorum(), - cluster_is_quorate ? " " : "Activity blocked"); - break; - - case state_active_subsystems: - seq_printf(m, "Active subsystems: %d\n", atomic_read(&use_count)); - break; - - case state_nodename: - seq_printf(m, "Node name: %s\n", nodename); - break; - - case state_nodeid: - if (!us) - break; - seq_printf(m, "Node ID: %d\n", us->node_id); - break; - - case state_nodeaddrs: - seq_printf(m, "Node addresses: "); - for (i = 0; i < csi->node_addr_count; i++) { - if (csi->saddr[i].sin6_family == AF_INET6) { - seq_printf(m, "%x:%x:%x:%x:%x:%x:%x:%x ", - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[0]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[1]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[2]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[3]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[4]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[5]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[6]), - be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[7])); - } - else { - struct sockaddr_in *saddr4 = (struct sockaddr_in *)&csi->saddr[i]; - uint8_t *addr = (uint8_t *)&saddr4->sin_addr; - seq_printf(m, "%u.%u.%u.%u ", - addr[0], addr[1], addr[2], addr[3]); - } - } - seq_printf(m, "\n\n"); - break; - - case state_done: - break; - - default: - break; - } -} - -static void *cluster_status_seq_start(struct seq_file *m, loff_t * pos) -{ - struct cluster_status_info *csi; - struct list_head *nodelist; - struct cluster_node *node; - struct cluster_node_addr *node_addr; - - if (!m->private) { - csi = kmalloc(sizeof(struct cluster_status_info), GFP_KERNEL); - m->private = csi; - if (!csi) - return NULL; - memset(csi, 0, sizeof(struct cluster_status_info)); - } - else - csi = m->private; - - csi->state = *pos; - if (*pos == 0) { - if (!we_are_a_cluster_member) - return csi; - - /* Total the votes */ - down(&cluster_members_lock); - list_for_each(nodelist, &cluster_members_list) { - node = list_entry(nodelist, struct cluster_node, list); - if (node->state == NODESTATE_MEMBER) { - csi->total_votes += node->votes; - csi->max_expected = - max(csi->max_expected, node->expected_votes); - } - } - up(&cluster_members_lock); - if (quorum_device && quorum_device->state == NODESTATE_MEMBER) - csi->total_votes += quorum_device->votes; - - if (us) { - int i; - - csi->node_addr_count = 0; - list_for_each_entry(node_addr, &us->addr_list, list) { - csi->node_addr_count++; - } - csi->saddr = kmalloc(csi->node_addr_count * - sizeof(struct sockaddr_in6), GFP_KERNEL); - if (!csi->saddr) { - csi->node_addr_count = 0; - return csi; - } - i = 0; - list_for_each_entry(node_addr, &us->addr_list, list) { - memcpy(&csi->saddr[i++], - node_addr->addr, sizeof(struct sockaddr_in6)); - } - } - } - - return csi; -} - -static void *cluster_status_seq_next(struct seq_file *m, void *p, loff_t * pos) -{ - struct cluster_status_info *csi = p; - - csi->state++; - if (!we_are_a_cluster_member && csi->state >= state_cluster_member_state) - csi->state = state_done; - *pos = csi->state; - if (csi->state >= state_done) - return NULL; - return csi; -} - -static int cluster_status_seq_show(struct seq_file *m, void *p) -{ - struct cluster_status_info *csi = p; - - if (csi->state < state_done) - cluster_status_state_mch(m, csi); - return 0; -} - -static void cluster_status_seq_stop(struct seq_file *m, void *p) -{ - struct cluster_status_info *csi = m->private; - - if (m->private) { - if (csi->saddr) - kfree(csi->saddr); - kfree(m->private); - m->private = NULL; - } -} - -/* Allocate one of these for /proc/cluster/nodes so we can keep a track of where - * we are */ -struct cluster_seq_info { - int nodeid; - int highest_nodeid; -}; - -static int cluster_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &cluster_info_op); -} - -static int cluster_status_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &cluster_status_info_op); -} - -static void *cluster_seq_start(struct seq_file *m, loff_t * pos) -{ - struct cluster_seq_info *csi; - - if (!m->private) { - csi = kmalloc(sizeof (struct cluster_seq_info), GFP_KERNEL); - m->private = csi; - if (!csi) - return NULL; - } - else - csi = m->private; - /* Keep highest_nodeid here so we don't need to keep traversing the - * list to find it */ - csi->nodeid = *pos; - csi->highest_nodeid = get_highest_nodeid(); - - /* Print the header */ - if (*pos == 0) { - seq_printf(m, "Node Votes Exp Sts Name\n"); - } - return csi; -} - -static void *cluster_seq_next(struct seq_file *m, void *p, loff_t * pos) -{ - struct cluster_seq_info *csi = p; - - *pos = ++csi->nodeid; - if (csi->nodeid > csi->highest_nodeid) - return NULL; - - return csi; -} - -static int cluster_seq_show(struct seq_file *m, void *p) -{ - char state = '?'; - struct cluster_node *node; - struct cluster_seq_info *csi = p; - - /* - * If we have "0" here then display the quorum device if - * there is one. - */ - if (csi->nodeid == 0) - node = quorum_device; - else - node = find_node_by_nodeid(csi->nodeid); - - if (!node) - return 0; - - /* Make state printable */ - switch (node->state) { - case NODESTATE_MEMBER: - state = 'M'; - break; - case NODESTATE_JOINING: - state = 'J'; - break; - case NODESTATE_DEAD: - state = 'X'; - break; - } - seq_printf(m, "%4d %3d %3d %c %s\n", - node->node_id, - node->votes, - node->expected_votes, - state, - node->name); - - return 0; -} - -static void cluster_seq_stop(struct seq_file *m, void *p) -{ - if (m->private) { - kfree(m->private); - m->private = NULL; - } -} - -static struct seq_operations cluster_info_op = { - .start = cluster_seq_start, - .next = cluster_seq_next, - .stop = cluster_seq_stop, - .show = cluster_seq_show -}; - -static struct file_operations cluster_fops = { - .open = cluster_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, - .owner = THIS_MODULE, -}; - -static struct seq_operations cluster_status_info_op = { - .start = cluster_status_seq_start, - .next = cluster_status_seq_next, - .stop = cluster_status_seq_stop, - .show = cluster_status_seq_show -}; - -static struct file_operations cluster_status_fops = { - .open = cluster_status_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, - .owner = THIS_MODULE, -}; - -static struct file_operations service_fops = { - .open = sm_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, - .owner = THIS_MODULE, -}; - -static int cman_config_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct config_proc_info *cinfo = data; - - return snprintf(page, count, "%d\n", *cinfo->value); -} - -static int cman_config_write_proc(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - struct config_proc_info *cinfo = data; - char buff[11]; - int value; - int num; - char *end; - - num = (count < 10) ? count : 10; - if (copy_from_user(buff, buffer, num)) - return -EFAULT; - - buff[num] = '\0'; - value = simple_strtoul(buff, &end, 10); - if (*end) { - *cinfo->value = value; - } - return count; -} - -/* Base of the config directory for cman */ -static struct proc_dir_entry *proc_cman_config; -void create_proc_entries(void) -{ - struct proc_dir_entry *procentry; - struct proc_dir_entry *proc_cluster; - int i; - - proc_cluster = proc_mkdir("cluster", 0); - if (!proc_cluster) - return; - proc_cluster->owner = THIS_MODULE; - - /* Config dir filled in by us and others */ - if (!proc_mkdir("cluster/config", 0)) - return; - - /* Don't much care if this fails, it's hardly vital */ - procentry = create_proc_entry("cluster/nodes", S_IRUGO, NULL); - if (procentry) - procentry->proc_fops = &cluster_fops; - - procentry = create_proc_entry("cluster/status", S_IRUGO, NULL); - if (procentry) - procentry->proc_fops = &cluster_status_fops ; - - procentry = create_proc_entry("cluster/services", S_IRUGO, NULL); - if (procentry) - procentry->proc_fops = &service_fops; - - /* Config entries */ - proc_cman_config = proc_mkdir("cluster/config/cman", 0); - if (!proc_cman_config) - return; - - for (i=0; i<sizeof(config_proc)/sizeof(struct config_proc_info); i++) { - procentry = create_proc_entry(config_proc[i].name, 0660, - proc_cman_config); - if (procentry) { - procentry->data = &config_proc[i]; - procentry->write_proc = cman_config_write_proc; - procentry->read_proc = cman_config_read_proc; - } - } - - procentry = create_proc_entry("cluster/sm_debug", S_IRUGO, NULL); - if (procentry) - procentry->get_info = sm_debug_info; -} - -void cleanup_proc_entries(void) -{ - int i, config_count; - - remove_proc_entry("cluster/sm_debug", NULL); - - config_count = sizeof(config_proc) / sizeof(struct config_proc_info); - - if (proc_cman_config) { - for (i=0; i<config_count; i++) - remove_proc_entry(config_proc[i].name, proc_cman_config); - } - remove_proc_entry("cluster/config/cman", NULL); - remove_proc_entry("cluster/config", NULL); - - remove_proc_entry("cluster/nodes", NULL); - remove_proc_entry("cluster/status", NULL); - remove_proc_entry("cluster/services", NULL); - remove_proc_entry("cluster/config", NULL); - remove_proc_entry("cluster", NULL); -} diff --git a/cman-kernel/src/service.h b/cman-kernel/src/service.h deleted file mode 100644 index 335e5df..0000000 --- a/cman-kernel/src/service.h +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SERVICE_DOT_H__ -#define __SERVICE_DOT_H__ - -/* - * Interface between service manager and services - */ - -/* - * Service levels are started in order from lowest, so level 0 is started on - * all nodes before level 1 is started. - */ - -#define SERVICE_LEVEL_FENCE (0) -#define SERVICE_LEVEL_GDLM (1) -#define SERVICE_LEVEL_GFS (2) -#define SERVICE_LEVEL_USER (3) - -#define MAX_SERVICE_NAME_LEN (33) - -/* - * The type of start a service receives. The start (and preceding stop) may be - * due to a node joining or leaving the SG or due to a node having failed. - */ - -#define SERVICE_NODE_FAILED (1) -#define SERVICE_NODE_JOIN (2) -#define SERVICE_NODE_LEAVE (3) - - -struct kcl_service { - struct list_head list; - uint16_t level; - uint32_t local_id; - uint32_t global_id; - int node_count; - char name[MAX_SERVICE_NAME_LEN]; -}; - -int kcl_get_services(struct list_head *list, int level); - - -/* - * These routines which run in CMAN context must return quickly and cannot - * block. - */ - -struct kcl_service_ops { - int (*stop) (void *servicedata); - int (*start) (void *servicedata, uint32_t *nodeids, int count, - int event_id, int type); - void (*finish) (void *servicedata, int event_id); -}; - -/* - * Register will cause CMAN to create a Service Group (SG) for the named - * instance of the service. A local ID is returned which is used to join, - * leave and unregister the service. - */ - -int kcl_register_service(char *name, int namelen, int level, - struct kcl_service_ops *ops, int unique, - void *servicedata, uint32_t *local_id); - -void kcl_unregister_service(uint32_t local_id); - -/* - * Once a service is joined it will be managed by CMAN and receive start, stop, - * and finish calls. After leave is called the service is no longer managed by - * CMAN. The first start for a service may arrive before kcl_join_service() - * returns. - */ - -int kcl_join_service(uint32_t local_id); -int kcl_leave_service(uint32_t local_id); - -/* - * After a service is started, it can ask for its cluster-wide unique ID. - */ - -void kcl_global_service_id(uint32_t local_id, uint32_t * global_id); - -/* - * Called by a service when it's done with a start(). Cannot be called from - * the start function. - */ - -void kcl_start_done(uint32_t local_id, int event_id); - -#endif diff --git a/cman-kernel/src/sm.h b/cman-kernel/src/sm.h deleted file mode 100644 index 8e81a81..0000000 --- a/cman-kernel/src/sm.h +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_DOT_H__ -#define __SM_DOT_H__ - -/* - * This is the main header file to be included in each Service Manager source - * file. - */ - -#include <linux/list.h> -#include <linux/socket.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/file.h> -#include <linux/kthread.h> -#include <net/sock.h> - -#include <cluster/cnxman.h> -#include <cluster/service.h> - -#define SG_LEVELS (4) - -#include "sm_internal.h" -#include "sm_barrier.h" -#include "sm_control.h" -#include "sm_daemon.h" -#include "sm_joinleave.h" -#include "sm_membership.h" -#include "sm_message.h" -#include "sm_misc.h" -#include "sm_recover.h" -#include "sm_services.h" - -extern struct list_head sm_sg[SG_LEVELS]; -extern struct semaphore sm_sglock; - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#define SM_ASSERT(x, do) \ -{ \ - if (!(x)) \ - { \ - printk("\nSM: Assertion failed on line %d of file %s\n" \ - "SM: assertion: "%s"\n" \ - "SM: time = %lu\n", \ - __LINE__, __FILE__, #x, jiffies); \ - {do} \ - printk("\n"); \ - panic("SM: Record message above and reboot.\n"); \ - } \ -} - -#define SM_RETRY(do_this, until_this) \ -for (;;) \ -{ \ - do { do_this; schedule(); } while (0); \ - if (until_this) \ - break; \ - printk("SM: out of memory: %s, %u\n", __FILE__, __LINE__); \ - schedule();\ -} - - -#define log_print(fmt, args...) printk("SM: "fmt"\n", ##args) - -#define log_error(sg, fmt, args...) \ - printk("SM: %08x " fmt "\n", (sg)->global_id , ##args) - - -#define SM_DEBUG_LOG - -#ifdef SM_DEBUG_CONSOLE -#define log_debug(sg, fmt, args...) \ - printk("SM: %08x " fmt "\n", (sg)->global_id , ##args) -#endif - -#ifdef SM_DEBUG_LOG -#define log_debug(sg, fmt, args...) sm_debug_log(sg, fmt, ##args); -#endif - -#ifdef SM_DEBUG_ALL -#define log_debug(sg, fmt, args...) \ -do \ -{ \ - printk("SM: %08x "fmt"\n", (sg)->global_id, ##args); \ - sm_debug_log(sg, fmt, ##args); \ -} \ -while (0) -#endif - -#endif /* __SM_DOT_H__ */ diff --git a/cman-kernel/src/sm_barrier.c b/cman-kernel/src/sm_barrier.c deleted file mode 100644 index d2f9eb4..0000000 --- a/cman-kernel/src/sm_barrier.c +++ /dev/null @@ -1,239 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" - -static struct list_head barriers; -static spinlock_t barriers_lock; - -struct bc_entry { - struct list_head list; - uint32_t gid; - int status; - char type; -}; -typedef struct bc_entry bc_entry_t; - -void init_barriers(void) -{ - INIT_LIST_HEAD(&barriers); - spin_lock_init(&barriers_lock); -} - -static int atoi(char *c) -{ - int x = 0; - - while ('0' <= *c && *c <= '9') { - x = x * 10 + (*c - '0'); - c++; - } - return x; -} - -static void add_barrier_callback(char *name, int status, int type) -{ - char *p; - uint32_t gid; - bc_entry_t *be; - - /* an ESRCH callback just means there was a cnxman transition */ - if (status == -ESRCH) - return; - - /* extract global id of SG from barrier name */ - p = strstr(name, "sm."); - - SM_ASSERT(p, printk("name="%s" status=%d\n", name, status);); - - p += strlen("sm."); - gid = atoi(p); - - be = kmalloc(sizeof(bc_entry_t), GFP_ATOMIC); - SM_ASSERT(be,); - - be->gid = gid; - be->status = status; - be->type = type; - - spin_lock(&barriers_lock); - list_add_tail(&be->list, &barriers); - spin_unlock(&barriers_lock); - - wake_serviced(DO_BARRIERS); -} - -static void callback_recovery_barrier(char *name, int status) -{ - add_barrier_callback(name, status, SM_BARRIER_RECOVERY); -} - -static void callback_startdone_barrier_new(char *name, int status) -{ - add_barrier_callback(name, status, SM_BARRIER_STARTDONE_NEW); -} - -static void callback_startdone_barrier(char *name, int status) -{ - add_barrier_callback(name, status, SM_BARRIER_STARTDONE); -} - -int sm_barrier(char *name, int count, int type) -{ - int error; - unsigned long fn = 0; - - switch (type) { - case SM_BARRIER_STARTDONE: - fn = (unsigned long) callback_startdone_barrier; - break; - case SM_BARRIER_STARTDONE_NEW: - fn = (unsigned long) callback_startdone_barrier_new; - break; - case SM_BARRIER_RECOVERY: - fn = (unsigned long) callback_recovery_barrier; - break; - } - - error = kcl_barrier_register(name, 0, count); - if (error) { - log_print("barrier register error %d", error); - goto fail; - } - - error = kcl_barrier_setattr(name, BARRIER_SETATTR_AUTODELETE, TRUE); - if (error) { - log_print("barrier setattr autodel error %d", error); - goto fail_bar; - } - - error = kcl_barrier_setattr(name, BARRIER_SETATTR_CALLBACK, fn); - if (error) { - log_print("barrier setattr cb error %d", error); - goto fail_bar; - } - - error = kcl_barrier_setattr(name, BARRIER_SETATTR_ENABLED, TRUE); - if (error) { - log_print("barrier setattr enabled error %d", error); - goto fail_bar; - } - - return 0; - - fail_bar: - kcl_barrier_delete(name); - fail: - return error; -} - -void process_startdone_barrier_new(sm_group_t *sg, int status) -{ - sm_sevent_t *sev = sg->sevent; - - if (!sev) { - log_error(sg, "process_startdone_barrier_new: no sev %d", - status); - return; - } - - if (!test_and_clear_bit(SEFL_ALLOW_BARRIER, &sev->se_flags)) { - log_debug(sev->se_sg, "ignore barrier cb status %d", status); - return; - } - - sev->se_barrier_status = status; - sev->se_state = SEST_BARRIER_DONE; - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); -} - -void process_startdone_barrier(sm_group_t *sg, int status) -{ - sm_uevent_t *uev = &sg->uevent; - - if (!test_and_clear_bit(UEFL_ALLOW_BARRIER, &uev->ue_flags)) { - log_debug(sg, "ignore barrier cb status %d", status); - return; - } - - uev->ue_barrier_status = status; - uev->ue_state = UEST_BARRIER_DONE; - set_bit(UEFL_CHECK, &uev->ue_flags); - wake_serviced(DO_MEMBERSHIP); -} - -void process_recovery_barrier(sm_group_t *sg, int status) -{ - if (status) { - log_error(sg, "process_recovery_barrier status=%d", status); - return; - } - - if (sg->state != SGST_RECOVER || - sg->recover_state != RECOVER_BARRIERWAIT) { - log_error(sg, "process_recovery_barrier state %d recover %d", - sg->state, sg->recover_state); - return; - } - - if (!sg->recover_stop) - sg->recover_state = RECOVER_STOP; - else - sg->recover_state = RECOVER_BARRIERDONE; - - wake_serviced(DO_RECOVERIES); -} - -void process_barriers(void) -{ - sm_group_t *sg; - bc_entry_t *be; - - while (1) { - be = NULL; - - spin_lock(&barriers_lock); - if (!list_empty(&barriers)) { - be = list_entry(barriers.next, bc_entry_t, list); - list_del(&be->list); - } - spin_unlock(&barriers_lock); - - if (!be) - break; - - sg = sm_global_id_to_sg(be->gid); - if (!sg) { - log_print("process_barriers: no sg %08x", be->gid); - break; - } - - switch (be->type) { - case SM_BARRIER_STARTDONE_NEW: - process_startdone_barrier_new(sg, be->status); - break; - - case SM_BARRIER_STARTDONE: - process_startdone_barrier(sg, be->status); - break; - - case SM_BARRIER_RECOVERY: - process_recovery_barrier(sg, be->status); - break; - } - - kfree(be); - schedule(); - } -} diff --git a/cman-kernel/src/sm_barrier.h b/cman-kernel/src/sm_barrier.h deleted file mode 100644 index 9ebe7d9..0000000 --- a/cman-kernel/src/sm_barrier.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_BARRIER_DOT_H__ -#define __SM_BARRIER_DOT_H__ - -#define SM_BARRIER_STARTDONE (0) -#define SM_BARRIER_STARTDONE_NEW (1) -#define SM_BARRIER_RECOVERY (2) -#define SM_BARRIER_RESET (3) - -void init_barriers(void); -void process_barriers(void); -int sm_barrier(char *name, int count, int type); -void process_startdone_barrier(sm_group_t *sg, int status); -void process_startdone_barrier_new(sm_group_t *sg, int status); -void process_recovery_barrier(sm_group_t *sg, int status); - -#endif diff --git a/cman-kernel/src/sm_control.c b/cman-kernel/src/sm_control.c deleted file mode 100644 index 35507ad..0000000 --- a/cman-kernel/src/sm_control.c +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" -#include "config.h" - -struct socket * sm_socket; -uint32_t * sm_new_nodeids; -uint32_t sm_our_nodeid; -int sm_quorum, sm_quorum_next; -struct list_head sm_members; -int sm_member_count; - - -/* - * Context: cnxman - * Called by cnxman when it has a new member list. - */ - -void sm_member_update(int quorate) -{ - sm_quorum_next = quorate; - wake_serviced(DO_START_RECOVERY); -} - -/* - * Context: cnxman - * Called when module is loaded. - */ - -void sm_init(void) -{ - sm_socket = NULL; - sm_new_nodeids = NULL; - sm_quorum = 0; - sm_quorum_next = 0; - sm_our_nodeid = 0; - INIT_LIST_HEAD(&sm_members); - sm_member_count = 0; - - init_services(); - init_messages(); - init_barriers(); - init_serviced(); - init_recovery(); - init_joinleave(); - init_sm_misc(); -} - -/* - * Context: cnxman - * Called at beginning of cluster join procedure. - */ - -void sm_start(void) -{ - struct sockaddr_cl saddr; - struct socket *sock; - int result; - - /* Create a communication channel among service managers */ - - result = sock_create_kern(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT, &sock); - if (result < 0) { - log_print("can't create socket %d", result); - goto fail; - } - - sm_socket = sock; - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_SERVICES; - - result = sock->ops->bind(sock, (struct sockaddr *) &saddr, - sizeof(saddr)); - if (result < 0) { - log_print("can't bind socket %d", result); - goto fail_release; - } - - result = kcl_register_read_callback(sm_socket, sm_cluster_message); - if (result < 0) { - log_print("can't register read callback %d", result); - goto fail_release; - } - - sm_new_nodeids = (uint32_t *) kmalloc(cman_config.max_nodes * - sizeof(uint32_t), - GFP_KERNEL); - start_serviced(); - - /* cnxman should call sm_member_update() once we've joined - then we - * can get our first list of members and our own nodeid */ - - return; - - fail_release: - sock_release(sm_socket); - sm_socket = NULL; - - fail: - return; -} - -/* - * Context: cnxman - * Called before cnxman leaves the cluster. If this returns an error to cman, - * cman should not leave the cluster but return EBUSY. - * If force is set we go away anyway. cman knows best in this case - */ - -int sm_stop(int force) -{ - struct list_head *head; - sm_group_t *sg; - sm_node_t *node; - int i, busy = FALSE, error = -EBUSY; - - for (i = 0; i < SG_LEVELS; i++) { - if (!list_empty(&sm_sg[i])) { - sg = list_entry(sm_sg[i].next, sm_group_t, list); - log_error(sg, "sm_stop: SG still joined"); - busy = TRUE; - } - } - - if (!busy || force) { - stop_serviced(); - - if (sm_socket) - sock_release(sm_socket); - - head = &sm_members; - while (!list_empty(head)) { - node = list_entry(head->next, sm_node_t, list); - list_del(&node->list); - sm_member_count--; - kfree(node); - } - - kfree(sm_new_nodeids); - sm_init(); - error = 0; - } - return error; -} diff --git a/cman-kernel/src/sm_control.h b/cman-kernel/src/sm_control.h deleted file mode 100644 index 6a28c75..0000000 --- a/cman-kernel/src/sm_control.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_CONTROL_DOT_H__ -#define __SM_CONTROL_DOT_H__ - -void sm_init(void); -void sm_start(void); -int sm_stop(int force); -void sm_member_update(int quorate); - -#endif diff --git a/cman-kernel/src/sm_daemon.c b/cman-kernel/src/sm_daemon.c deleted file mode 100644 index 9b23718..0000000 --- a/cman-kernel/src/sm_daemon.c +++ /dev/null @@ -1,114 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" - -static unsigned long daemon_flags; -static struct task_struct * daemon_task; -extern int sm_quorum; - -void init_serviced(void) -{ - daemon_flags = 0; - daemon_task = NULL; -} - -void wake_serviced(int do_flag) -{ - set_bit(do_flag, &daemon_flags); - if (!daemon_task) - return; - wake_up_process(daemon_task); -} - -static inline int got_work(void) -{ - int rv = 0; - - rv = (test_bit(DO_START_RECOVERY, &daemon_flags) || - test_bit(DO_MESSAGES, &daemon_flags) || - test_bit(DO_BARRIERS, &daemon_flags) || - test_bit(DO_CALLBACKS, &daemon_flags)); - - if (rv) - goto out; - - if (sm_quorum) { - rv = test_bit(DO_RECOVERIES, &daemon_flags); - if (rv) - goto out; - if (no_recoveries()) - rv = test_bit(DO_JOINLEAVE, &daemon_flags) || - test_bit(DO_MEMBERSHIP, &daemon_flags); - } - out: - return rv; -} - -static int serviced(void *arg) -{ - while (!kthread_should_stop()) { - if (test_and_clear_bit(DO_START_RECOVERY, &daemon_flags)) - process_nodechange(); - - if (test_and_clear_bit(DO_MESSAGES, &daemon_flags)) - process_messages(); - - if (test_and_clear_bit(DO_BARRIERS, &daemon_flags)) - process_barriers(); - - if (test_and_clear_bit(DO_CALLBACKS, &daemon_flags)) - process_callbacks(); - - if (sm_quorum) { - if (test_and_clear_bit(DO_RECOVERIES, &daemon_flags)) - process_recoveries(); - - if (no_recoveries()) { - if (test_and_clear_bit(DO_JOINLEAVE, - &daemon_flags)) - process_joinleave(); - - if (test_and_clear_bit(DO_MEMBERSHIP, - &daemon_flags)) - process_membership(); - } - } - - set_current_state(TASK_INTERRUPTIBLE); - if (!got_work()) - schedule(); - set_current_state(TASK_RUNNING); - } - daemon_task = NULL; - return 0; -} - -int start_serviced(void) -{ - struct task_struct *p; - - p = kthread_run(serviced, NULL, "cman_serviced"); - if (IS_ERR(p)) { - printk("can't start cman_serviced daemon"); - return (IS_ERR(p)); - } - - daemon_task = p; - return 0; -} - -void stop_serviced(void) -{ - kthread_stop(daemon_task); -} diff --git a/cman-kernel/src/sm_daemon.h b/cman-kernel/src/sm_daemon.h deleted file mode 100644 index cd0e0d6..0000000 --- a/cman-kernel/src/sm_daemon.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_DAEMON_DOT_H__ -#define __SM_DAEMON_DOT_H__ - -#define DO_RUN (0) -#define DO_START_RECOVERY (1) -#define DO_MESSAGES (2) -#define DO_BARRIERS (3) -#define DO_CALLBACKS (4) -#define DO_JOINLEAVE (5) -#define DO_RECOVERIES (6) -#define DO_MEMBERSHIP (7) -#define DO_RESET (8) - -void init_serviced(void); -void wake_serviced(int do_flag); -void stop_serviced(void); -int start_serviced(void); - -#endif diff --git a/cman-kernel/src/sm_internal.h b/cman-kernel/src/sm_internal.h deleted file mode 100644 index ad26c3a..0000000 --- a/cman-kernel/src/sm_internal.h +++ /dev/null @@ -1,232 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_INTERNAL_DOT_H__ -#define __SM_INTERNAL_DOT_H__ - -/* - * Any header files needed by this file should be included before it in sm.h. - * This file should only be included by sm.h. - */ - -struct sm_group; -struct sm_sevent; -struct sm_uevent; -struct sm_node; -struct sm_msg; - -typedef struct sm_group sm_group_t; -typedef struct sm_sevent sm_sevent_t; -typedef struct sm_uevent sm_uevent_t; -typedef struct sm_node sm_node_t; -typedef struct sm_msg sm_msg_t; - - -/* - * Number of seconds to wait before trying again to join or leave an SG - */ -#define RETRY_DELAY (2) - - -/* - * Service Event - what a node uses to join or leave an sg - */ - -/* SE Flags */ -#define SEFL_CHECK (0) -#define SEFL_ALLOW_JOIN (1) -#define SEFL_ALLOW_JSTOP (2) -#define SEFL_ALLOW_LEAVE (3) -#define SEFL_ALLOW_LSTOP (4) -#define SEFL_ALLOW_STARTDONE (5) -#define SEFL_ALLOW_BARRIER (6) -#define SEFL_DELAY (7) -#define SEFL_DELAY_RECOVERY (8) -#define SEFL_LEAVE (9) -#define SEFL_CANCEL (10) - -/* SE States */ -#define SEST_JOIN_BEGIN (1) -#define SEST_JOIN_ACKWAIT (2) -#define SEST_JOIN_ACKED (3) -#define SEST_JSTOP_ACKWAIT (4) -#define SEST_JSTOP_ACKED (5) -#define SEST_JSTART_SERVICEWAIT (6) -#define SEST_JSTART_SERVICEDONE (7) -#define SEST_BARRIER_WAIT (8) -#define SEST_BARRIER_DONE (9) -#define SEST_LEAVE_BEGIN (10) -#define SEST_LEAVE_ACKWAIT (11) -#define SEST_LEAVE_ACKED (12) -#define SEST_LSTOP_ACKWAIT (13) -#define SEST_LSTOP_ACKED (14) -#define SEST_LSTART_WAITREMOTE (15) -#define SEST_LSTART_REMOTEDONE (16) - -struct sm_sevent { - struct list_head se_list; - unsigned int se_id; - sm_group_t * se_sg; - unsigned long se_flags; - unsigned int se_state; - - int se_node_count; - int se_memb_count; - int se_reply_count; - - uint32_t * se_node_ids; - char * se_node_status; - int se_len_ids; /* length of node_ids */ - int se_len_status; /* length of node_status */ - - int se_barrier_status; - struct timer_list se_restart_timer; -}; - -/* - * Update Event - what an sg member uses to respond to an sevent - */ - -/* UE Flags */ -#define UEFL_ALLOW_STARTDONE (0) -#define UEFL_ALLOW_BARRIER (1) -#define UEFL_CANCEL (2) -#define UEFL_LEAVE (3) -#define UEFL_CHECK (4) - -/* UE States */ -#define UEST_JSTOP (1) -#define UEST_JSTART_WAITCMD (2) -#define UEST_JSTART (3) -#define UEST_JSTART_SERVICEWAIT (4) -#define UEST_JSTART_SERVICEDONE (5) -#define UEST_BARRIER_WAIT (6) -#define UEST_BARRIER_DONE (7) -#define UEST_LSTOP (8) -#define UEST_LSTART_WAITCMD (9) -#define UEST_LSTART (10) -#define UEST_LSTART_SERVICEWAIT (11) -#define UEST_LSTART_SERVICEDONE (12) - -struct sm_uevent { - unsigned int ue_state; - unsigned long ue_flags; - uint32_t ue_id; - uint32_t ue_nodeid; - int ue_num_nodes; - int ue_barrier_status; - uint32_t ue_remote_seid; -}; - -/* - * Service Group - */ - -#define RECOVER_NONE (0) -#define RECOVER_STOP (1) -#define RECOVER_START (2) -#define RECOVER_STARTDONE (3) -#define RECOVER_BARRIERWAIT (4) -#define RECOVER_BARRIERDONE (5) - -/* SG Flags */ -#define SGFL_SEVENT (1) -#define SGFL_UEVENT (2) -#define SGFL_NEED_RECOVERY (3) - -/* SG States */ -#define SGST_NONE (0) -#define SGST_JOIN (1) -#define SGST_RUN (2) -#define SGST_RECOVER (3) -#define SGST_UEVENT (4) - -struct sm_group { - struct list_head list; /* list of sg's */ - uint16_t level; - uint32_t local_id; - uint32_t global_id; - unsigned long flags; - int state; - int refcount; /* references from reg/unreg */ - void * service_data; /* data from the service */ - struct kcl_service_ops *ops; /* ops from the service */ - struct completion event_comp; - - struct list_head memb; /* Membership List for RC */ - int memb_count; /* number of nodes in memb */ - struct list_head joining; /* nodes joining the sg */ - sm_sevent_t * sevent; - sm_uevent_t uevent; - - int recover_state; - int recover_stop; - struct list_head recover_list; /* recovery event list */ - void * recover_data; - char recover_barrier[MAX_BARRIER_NAME_LEN]; - - int namelen; - char name[1]; /* must be last field */ -}; - -/* - * Service Message - */ - -/* SMSG Type */ -#define SMSG_JOIN_REQ (1) -#define SMSG_JOIN_REP (2) -#define SMSG_JSTOP_REQ (3) -#define SMSG_JSTOP_REP (4) -#define SMSG_JSTART_CMD (5) -#define SMSG_LEAVE_REQ (6) -#define SMSG_LEAVE_REP (7) -#define SMSG_LSTOP_REQ (8) -#define SMSG_LSTOP_REP (9) -#define SMSG_LSTART_CMD (10) -#define SMSG_LSTART_DONE (11) -#define SMSG_RECOVER (12) - -/* SMSG Status */ -#define STATUS_POS (1) -#define STATUS_NEG (2) -#define STATUS_WAIT (3) - -struct sm_msg { - uint8_t ms_type; - uint8_t ms_status; - uint16_t ms_pad; - uint32_t ms_sevent_id; - uint32_t ms_global_sgid; - uint32_t ms_global_lastid; - uint16_t ms_sglevel; - uint16_t ms_length; - /* buf of ms_length bytes follows */ -}; - -/* - * Node structure - */ - -#define SNFL_NEED_RECOVERY (0) -#define SNFL_CLUSTER_MEMBER (1) -#define SNFL_LEAVING (2) - -struct sm_node { - struct list_head list; - uint32_t id; /* node id from cnxman */ - unsigned long flags; - int incarnation; /* node incarnation number */ -}; - -#endif /* __SM_INTERNAL_DOT_H__ */ diff --git a/cman-kernel/src/sm_joinleave.c b/cman-kernel/src/sm_joinleave.c deleted file mode 100644 index b1b62df..0000000 --- a/cman-kernel/src/sm_joinleave.c +++ /dev/null @@ -1,1293 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" - -/* - * Routines used by nodes that are joining or leaving a SG. These "sevent" - * routines initiate membership changes to a SG. Existing SG members respond - * using the "uevent" membership update routines. - */ - -extern uint32_t sm_our_nodeid; -extern struct list_head sm_members; -static struct list_head new_event; -static spinlock_t new_event_lock; -static struct list_head joinleave_events; - -void init_joinleave(void) -{ - INIT_LIST_HEAD(&new_event); - spin_lock_init(&new_event_lock); - INIT_LIST_HEAD(&joinleave_events); -} - -void new_joinleave(sm_sevent_t *sev) -{ - spin_lock(&new_event_lock); - list_add_tail(&sev->se_list, &new_event); - spin_unlock(&new_event_lock); - wake_serviced(DO_JOINLEAVE); -} - -sm_sevent_t *find_sevent(unsigned int id) -{ - sm_sevent_t *sev; - - list_for_each_entry(sev, &joinleave_events, se_list) { - if (sev->se_id == id) - return sev; - } - return NULL; -} - -static void release_sevent(sm_sevent_t *sev) -{ - if (sev->se_len_ids) { - kfree(sev->se_node_ids); - sev->se_node_ids = NULL; - } - - if (sev->se_len_status) { - kfree(sev->se_node_status); - sev->se_node_status = NULL; - } - - sev->se_node_count = 0; - sev->se_memb_count = 0; - sev->se_reply_count = 0; -} - -static int init_sevent(sm_sevent_t *sev) -{ - sm_node_t *node; - int len1, len2, count, cluster_members = 0; - - /* clear state from any previous attempt */ - release_sevent(sev); - - list_for_each_entry(node, &sm_members, list) { - if (test_bit(SNFL_CLUSTER_MEMBER, &node->flags)) - cluster_members++; - } - - sev->se_node_count = cluster_members; - sev->se_memb_count = sev->se_sg->memb_count; - - /* - * When joining, we need a node array the size of the entire cluster - * member list because we get responses from all nodes. When leaving, - * we only get responses from SG members, so the node array need only - * be that large. - */ - - if (sev->se_state < SEST_LEAVE_BEGIN) - count = sev->se_node_count; - else - count = sev->se_memb_count; - - len1 = count * sizeof(uint32_t); - sev->se_len_ids = len1; - - sev->se_node_ids = (uint32_t *) kmalloc(len1, GFP_KERNEL); - if (!sev->se_node_ids) - goto fail; - - len2 = count * sizeof (char); - sev->se_len_status = len2; - - sev->se_node_status = (char *) kmalloc(len2, GFP_KERNEL); - if (!sev->se_node_status) - goto fail_free; - - memset(sev->se_node_status, 0, len2); - memset(sev->se_node_ids, 0, len1); - - return 0; - - fail_free: - kfree(sev->se_node_ids); - sev->se_node_ids = NULL; - sev->se_len_ids = 0; - - fail: - return -ENOMEM; -} - -/* Context: timer */ - -static void sev_restart(unsigned long data) -{ - sm_sevent_t *sev = (sm_sevent_t *) data; - - clear_bit(SEFL_DELAY, &sev->se_flags); - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); -} - -static void schedule_sev_restart(sm_sevent_t *sev) -{ - init_timer(&sev->se_restart_timer); - sev->se_restart_timer.function = sev_restart; - sev->se_restart_timer.data = (long) sev; - mod_timer(&sev->se_restart_timer, jiffies + (RETRY_DELAY * HZ)); -} - -void free_sg_memb(sm_group_t *sg) -{ - sm_node_t *node; - - while (!list_empty(&sg->memb)) { - node = list_entry(sg->memb.next, sm_node_t, list); - list_del(&node->list); - kfree(node); - } - sg->memb_count = 0; -} - -/* - * 1. First step in joining a SG - send a message to all nodes in the cluster - * asking to join the named SG. If any nodes are members they will reply with - * a POS, or a WAIT (wait means try again, only one node can join at a time). - * If no one knows about this SG, they all send NEG replies which means we form - * the SG with just ourself as a member. - */ - -static int send_join_notice(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - sm_node_t *node; - char *msg; - int i = 0, error, namelen, len = 0; - - /* - * Create node array from member list in which to collect responses. - */ - - error = init_sevent(sev); - if (error) - goto out; - - list_for_each_entry(node, &sm_members, list) { - if (test_bit(SNFL_CLUSTER_MEMBER, &node->flags)) - sev->se_node_ids[i++] = node->id; - } - - /* - * Create and send a join request message. - * - * Other nodes then run process_join_request and reply to us; we - * collect the responses in process_reply and check them in - * check_join_notice. - */ - - namelen = sg->namelen; - msg = create_smsg(sg, SMSG_JOIN_REQ, namelen, &len, sev); - memcpy(msg + sizeof(sm_msg_t), sg->name, namelen); - - error = send_broadcast_message_sev(msg, len, sev); - - out: - return error; -} - -/* - * 2. Second step in joining a SG - after we collect all replies to our join - * request, we look at them. If anyone told us to wait, we'll wait a while, go - * back and start at step 1 again. - */ - -static int check_join_notice(sm_sevent_t *sev) -{ - int pos = 0, wait = 0, neg = 0, restart = 0, i, error = 0; - - for (i = 0; i < sev->se_node_count; i++) { - switch (sev->se_node_status[i]) { - case STATUS_POS: - /* this node is in the SG and will be in new proposed - * memb list */ - pos++; - break; - - case STATUS_WAIT: - /* this node is in the SG but something else is - * happening with it at the moment. */ - wait++; - break; - - case STATUS_NEG: - /* this node has no record of the SG we're interested - * in */ - neg++; - - if (sev->se_node_ids[i] == sm_our_nodeid) - sev->se_node_status[i] = STATUS_POS; - break; - - default: - /* we didn't get a valid response from this node, - * restart the entire sev. */ - restart++; - break; - } - } - - if (pos && !wait && !restart) { - /* all current members of this sg pos'ed our entry */ - } else if (!pos && !wait && !restart && neg) { - /* we're the first in the cluster to join this sg */ - sev->se_sg->global_id = sm_new_global_id(sev->se_sg->level); - if (sev->se_sg->global_id == 0) - error = -EOVERFLOW; - } else - error = -1; - - return error; -} - -/* - * 3. Third step in joining the SG - tell the nodes that are already members - * to "stop" the service. We stop them so that everyone can restart with the - * new member (us!) added. - */ - -static int send_join_stop(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - sm_node_t *node; - char *msg; - uint32_t be_count; - int i, len = 0, error = 0; - - /* - * Form the SG memb list with us in it. - */ - - for (i = 0; i < sev->se_node_count; i++) { - if (sev->se_node_status[i] != STATUS_POS) - continue; - - node = sm_new_node(sev->se_node_ids[i]); - if (!node) - goto fail; - - list_add_tail(&node->list, &sg->memb); - sg->memb_count++; - } - - /* - * Re-init the node vector in which to collect responses again. - */ - - sev->se_memb_count = sg->memb_count; - - memset(sev->se_node_status, 0, sev->se_len_status); - memset(sev->se_node_ids, 0, sev->se_len_ids); - i = 0; - - list_for_each_entry(node, &sg->memb, list) - sev->se_node_ids[i++] = node->id; - - /* - * Create and send a stop message. - * - * Other nodes then run process_stop_request and process_join_stop and - * reply to us. They stop the sg we're trying to join if they agree. - * We collect responses in process_reply and check them in - * check_join_stop. - */ - - msg = create_smsg(sg, SMSG_JSTOP_REQ, sizeof(uint32_t), &len, sev); - be_count = cpu_to_be32(sg->memb_count); - memcpy(msg + sizeof(sm_msg_t), &be_count, sizeof(uint32_t)); - - error = send_members_message_sev(sg, msg, len, sev); - if (error < 0) - goto fail; - - return 0; - - fail: - free_sg_memb(sg); - return error; -} - -/* - * 4. Fourth step in joining the SG - after we collect replies to our stop - * request, we look at them. Everyone sending POS agrees with us joining and - * has stopped their SG. If some nodes sent NEG, something is wrong and we - * don't have a good way to address that yet since some nodes may have sent - * POS. - * - * FIXME: even nodes replying with NEG should stop their SG so we can send an - * abort and have everyone at the same place to start from again. - */ - -static int check_join_stop(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - int i, pos = 0, neg = 0; - - for (i = 0; i < sev->se_memb_count; i++) { - switch (sev->se_node_status[i]) { - case STATUS_POS: - pos++; - break; - - case STATUS_NEG: - log_error(sg, "check_join_stop: neg from nodeid %u " - "(%d, %d, %u)", sev->se_node_ids[i], - pos, neg, sev->se_memb_count); - neg++; - break; - - default: - log_error(sg, "check_join_stop: unknown status=%u " - "nodeid=%u", sev->se_node_status[i], - sev->se_node_ids[i]); - neg++; - break; - } - } - - if (pos == sg->memb_count) - return 0; - - free_sg_memb(sg); - return -1; -} - -/* - * 5. Fifth step in joining the SG - everyone has stopped their service and we - * all now start the service with us, the new member, added to the SG member - * list. We send start to our own service here and send a message to the other - * members that they should also start their service. - */ - -static int send_join_start(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - sm_node_t *node; - uint32_t *memb; - char *msg; - int error, count = 0, len = 0; - - /* - * Create a start message and send it. - */ - - msg = create_smsg(sg, SMSG_JSTART_CMD, 0, &len, sev); - - error = send_members_message(sg, msg, len); - if (error < 0) - goto fail; - - /* - * Start the service ourself. The chunk of memory with the member ids - * must be freed by the service when it is done with it. - */ - - SM_RETRY(memb = kmalloc(sg->memb_count * sizeof(uint32_t), GFP_KERNEL), - memb); - - list_for_each_entry(node, &sg->memb, list) - memb[count++] = node->id; - - set_bit(SEFL_ALLOW_STARTDONE, &sev->se_flags); - - sg->ops->start(sg->service_data, memb, count, sev->se_id, - SERVICE_NODE_JOIN); - return 0; - - fail: - free_sg_memb(sg); - return error; -} - -/* - * 6. Sixth step in joining the SG - once the service has completed its start, - * it does a kcl_start_done() to signal us that it's done. That gets us here - * and we do a barrier with all other members which join the barrier when their - * service is done starting. - */ - -static int startdone_barrier_new(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - char bname[MAX_BARRIER_NAME_LEN]; - int error; - - memset(bname, 0, MAX_BARRIER_NAME_LEN); - sev->se_barrier_status = -1; - - set_bit(SEFL_ALLOW_BARRIER, &sev->se_flags); - - /* If we're the only member, skip the barrier */ - if (sg->memb_count == 1) { - process_startdone_barrier_new(sg, 0); - return 0; - } - - snprintf(bname, MAX_BARRIER_NAME_LEN, "sm.%u.%u.%u.%u", - sg->global_id, sm_our_nodeid, sev->se_id, sg->memb_count); - - error = sm_barrier(bname, sg->memb_count, SM_BARRIER_STARTDONE_NEW); - if (error) - goto fail; - - return 0; - - fail: - clear_bit(SEFL_ALLOW_BARRIER, &sev->se_flags); - sg->ops->stop(sg->service_data); - free_sg_memb(sg); - return error; -} - -/* - * 7. Seventh step in joining the SG - check that the barrier we joined with - * all other members returned with a successful status. - */ - -static int check_startdone_barrier_new(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - int error = sev->se_barrier_status; - - if (error) { - sg->ops->stop(sg->service_data); - free_sg_memb(sg); - } - return error; -} - -/* - * 8. Eigth step in joining the SG - send the service a "finish" indicating - * that all members have successfully started the service. - */ - -static void do_finish_new(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - sg->state = SGST_RUN; - sg->sevent = NULL; - clear_bit(SGFL_SEVENT, &sg->flags); - - sg->ops->finish(sg->service_data, sev->se_id); -} - -/* - * 9. Ninth step in joining the SG - it's done so get rid of the sevent stuff - * and tell the process which initiated the join that it's done. - */ - -static void sevent_done(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - list_del(&sev->se_list); - release_sevent(sev); - kfree(sev); - complete(&sg->event_comp); -} - -/* - * Move through the steps of a join. Summary: - * - * 1. Send a join notice to all cluster members. - * 2. Collect and check replies to the join notice. - * 3. Send a stop message to all SG members. - * 4. Collect and check replies to the stop message. - * 5. Send a start message to all SG members and start service ourself. - * 6. Use barrier to wait for all nodes to complete the start. - * 7. Check that all SG members joined the barrier. - * 8. Send finish to the service indicating that all nodes started it. - * 9. Clean up sevent and signal completion to the process that started the join - */ - -static void process_join_sevent(sm_sevent_t *sev) -{ - int error = 0; - - /* - * We may cancel the current join attempt if another node is also - * attempting to join or leave. (Only a single node can join or leave - * at once.) If cancelled, 0ur join attempt will be restarted later. - */ - - if (test_and_clear_bit(SEFL_CANCEL, &sev->se_flags)) { - error = 1; - goto cancel; - } - - log_debug(sev->se_sg, "sevent state %u", sev->se_state); - - switch (sev->se_state) { - - /* - * An sevent is created in kcl_join_service with a state of - * JOIN_BEGIN. - */ - - case SEST_JOIN_BEGIN: - sev->se_state = SEST_JOIN_ACKWAIT; - error = send_join_notice(sev); - break; - - /* - * se_state is changed from JOIN_ACKWAIT to JOIN_ACKED in - * process_reply (when all the replies have been received) - */ - - case SEST_JOIN_ACKED: - error = check_join_notice(sev); - if (error) - break; - - sev->se_state = SEST_JSTOP_ACKWAIT; - error = send_join_stop(sev); - break; - - /* - * se_state is changed from JSTOP_ACKWAIT to JSTOP_ACKED in - * proces_reply (when all the replies have been received) - */ - - case SEST_JSTOP_ACKED: - error = check_join_stop(sev); - if (error) - break; - - sev->se_state = SEST_JSTART_SERVICEWAIT; - error = send_join_start(sev); - break; - - /* - * se_state is changed from JSTART_SERVICEWAIT to - * JSTART_SERVICEDONE in kcl_start_done - */ - - case SEST_JSTART_SERVICEDONE: - sev->se_state = SEST_BARRIER_WAIT; - error = startdone_barrier_new(sev); - break; - - /* - * se_state is changed from BARRIER_WAIT to BARRIER_DONE in - * process_startdone_barrier_new - */ - - case SEST_BARRIER_DONE: - error = check_startdone_barrier_new(sev); - if (error) - break; - - do_finish_new(sev); - sevent_done(sev); - break; - - default: - log_error(sev->se_sg, "no join processing for state %u", - sev->se_state); - } - - cancel: - if (error) { - /* restart the sevent from the beginning */ - log_debug(sev->se_sg, "process_join error %d %lx", error, - sev->se_flags); - sev->se_state = SEST_JOIN_BEGIN; - sev->se_sg->global_id = 0; - set_bit(SEFL_DELAY, &sev->se_flags); - schedule_sev_restart(sev); - } -} - -/* - * 1. First step in leaving an SG - send a message to other SG members asking - * to leave the SG. Nodes that don't have another active sevent or uevent for - * this SG will return POS. - */ - -static int send_leave_notice(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - sm_node_t *node; - char *msg; - int i = 0, error = -1, len = 0; - - /* - * Create a node array from member list in which to collect responses. - */ - - error = init_sevent(sev); - if (error) - goto out; - - list_for_each_entry(node, &sg->memb, list) - sev->se_node_ids[i++] = node->id; - - /* - * Create and send a leave request message. - */ - - msg = create_smsg(sg, SMSG_LEAVE_REQ, 0, &len, sev); - - error = send_members_message_sev(sg, msg, len, sev); - - out: - return error; -} - -/* - * 2. Second step in leaving an SG - after we collect all replies to our leave - * request, we look at them. If anyone replied with WAIT, we abort our attempt - * at leaving and try again in a bit. - */ - -static int check_leave_notice(sm_sevent_t *sev) -{ - int pos = 0, wait = 0, neg = 0, restart = 0, i; - - for (i = 0; i < sev->se_memb_count; i++) { - switch (sev->se_node_status[i]) { - case STATUS_POS: - pos++; - break; - - case STATUS_WAIT: - wait++; - break; - - case STATUS_NEG: - neg++; - break; - - default: - /* we didn't get a valid response from this node, - * restart the entire sev. */ - restart++; - break; - } - } - - /* all members approve */ - if (pos && !wait && !restart) - return 0; - - return -1; -} - -/* - * 3. Third step in leaving the SG - tell the member nodes to "stop" the SG. - * They must be stopped in order to restart without us as a member. - */ - -static int send_leave_stop(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - char *msg; - int error, len = 0; - - /* - * Re-init the status vector in which to collect responses. - */ - - memset(sev->se_node_status, 0, sev->se_len_status); - - /* - * Create and send a stop message. - */ - - msg = create_smsg(sg, SMSG_LSTOP_REQ, 0, &len, sev); - - error = send_members_message_sev(sg, msg, len, sev); - if (error < 0) - goto out; - - /* - * we and all others stop the SG now - */ - - sg->ops->stop(sg->service_data); - - out: - return error; -} - -/* - * 4. Fourth step in leaving the SG - check the replies to our stop request. - * Same problem with getting different replies as check_join_stop. - */ - -static int check_leave_stop(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - int i, pos = 0, neg = 0; - - for (i = 0; i < sev->se_memb_count; i++) { - switch (sev->se_node_status[i]) { - case STATUS_POS: - pos++; - break; - - case STATUS_NEG: - log_error(sg, "check_leave_stop: fail from nodeid %u " - "(%d, %d, %u)", sev->se_node_ids[i], - pos, neg, sev->se_memb_count); - neg++; - break; - - default: - log_error(sg, "check_leave_stop: status %u nodeid %u", - sev->se_node_status[i], sev->se_node_ids[i]); - neg++; - break; - } - } - - if (pos == sg->memb_count) - return 0; - - return -1; -} - -/* - * 5. Fifth step in leaving the SG - tell the other SG members to restart the - * service without us. We, of course, don't start our own stopped service. If - * we're the last SG member and leaving, we jump right to the next step. - */ - -static int send_leave_start(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - char *msg; - int error = 0, len = 0; - - if (sg->memb_count == 1) { - sev->se_state = SEST_LSTART_REMOTEDONE; - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } else { - msg = create_smsg(sg, SMSG_LSTART_CMD, 0, &len, sev); - error = send_members_message(sg, msg, len); - } - return error; -} - -/* - * Move through the steps of a leave. Summary: - * - * 1. Send a leave notice to all SG members. - * 2. Collect and check replies to the leave notice. - * 3. Send a stop message to all SG members and stop our own SG. - * 4. Collect and check replies to the stop message. - * 5. Send a start message to SG members. - * 6. Clean up sevent and signal completion to the process that - * started the leave. - */ - -static void process_leave_sevent(sm_sevent_t *sev) -{ - int error = 0; - - /* - * We may cancel the current leave attempt if another node is also - * attempting to join or leave. (Only a single node can join or leave - * at once.) Our leave attempt will be restarted after being - * cancelled. - */ - - if (test_and_clear_bit(SEFL_CANCEL, &sev->se_flags)) { - error = 1; - goto cancel; - } - - if (test_bit(SGFL_UEVENT, &sev->se_sg->flags)) { - error = 2; - goto cancel; - } - - if (!list_empty(&sev->se_sg->joining)) { - error = 3; - goto cancel; - } - - log_debug(sev->se_sg, "sevent state %u", sev->se_state); - - switch (sev->se_state) { - - /* - * An sevent is created in kcl_leave_service with a state of - * LEAVE_BEGIN. - */ - - case SEST_LEAVE_BEGIN: - sev->se_state = SEST_LEAVE_ACKWAIT; - error = send_leave_notice(sev); - break; - - /* - * se_state is changed from LEAVE_ACKWAIT to LEAVE_ACKED in - * process_reply (when all the replies have been received) - */ - - case SEST_LEAVE_ACKED: - error = check_leave_notice(sev); - if (error) - break; - - sev->se_state = SEST_LSTOP_ACKWAIT; - error = send_leave_stop(sev); - break; - - /* - * se_state is changed from LSTOP_ACKWAIT to LSTOP_ACKED in - * process_reply - */ - - case SEST_LSTOP_ACKED: - error = check_leave_stop(sev); - if (error) - break; - - sev->se_state = SEST_LSTART_WAITREMOTE; - error = send_leave_start(sev); - break; - - /* - * se_state is changed from LSTART_WAITREMOTE to - * LSTART_REMOTEDONE in process_leave_done - */ - - case SEST_LSTART_REMOTEDONE: - sevent_done(sev); - break; - - default: - log_error(sev->se_sg, "process_leave_sevent state=%u", - sev->se_state); - } - - cancel: - if (error) { - log_debug(sev->se_sg, "process_leave error %d %lx", error, - sev->se_flags); - /* restart the sevent from the beginning */ - sev->se_state = SEST_LEAVE_BEGIN; - set_bit(SEFL_DELAY, &sev->se_flags); - schedule_sev_restart(sev); - } -} - -/* - * Sevent backout code. Take appropriate steps when a recovery occurs while - * we're in the midst of an sevent. The recovery may or may not affect the - * sevent. If it does, it usually means cancelling the sevent and restarting - * it from the beginning once the recovery processing is done. - */ - -/* - * If any of the nodes that replied with OK is dead, we give up on the current - * join attempt and restart. Otherwise, this sevent can continue. - */ - -static int backout_join_acked(sm_sevent_t *sev) -{ - sm_node_t *node; - int i; - - for (i = 0; i < sev->se_node_count; i++) { - if (sev->se_node_status[i] != STATUS_POS) - continue; - - list_for_each_entry(node, &sm_members, list) { - if (test_bit(SNFL_NEED_RECOVERY, &node->flags) && - (node->id == sev->se_node_ids[i])) - return TRUE; - } - } - return FALSE; -} - -/* - * In this state our sg member list exists and mark_affected_sgs() will have - * set NEED_RECOVERY if any of the nodes in the sg we're joining is dead. We - * restart the join process if this is the case, otherwise this sevent can - * continue. - */ - -static int backout_jstop_ackwait(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - clear_bit(SEFL_ALLOW_JSTOP, &sev->se_flags); - free_sg_memb(sg); - return TRUE; -} - -/* - * Same as previous. - */ - -static int backout_jstop_acked(sm_sevent_t *sev) -{ - return backout_jstop_ackwait(sev); -} - -/* - * If NEED_RECOVERY is set a member of the sg we're joining died while we were - * starting our service. The recovery process will restart the service on all - * the prior sg members (not including those that died or us). We will - * reattempt our join which should be accepted once the nodes are done with - * recovery. - */ - -static int backout_jstart_servicewait(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - clear_bit(SEFL_ALLOW_STARTDONE, &sev->se_flags); - sg->ops->stop(sg->service_data); - free_sg_memb(sg); - return TRUE; -} - -/* - * Same as previous. - */ - -static int backout_jstart_servicedone(sm_sevent_t *sev) -{ - return backout_jstart_servicewait(sev); -} - -/* - * If NEED_RECOVERY is set a member of the sg we're joining died while we were - * waiting on the "all done" barrier. Stop our service that we just started - * and cancel the barrier. The recovery process will restart the service on - * all the prior sg members (not including those that died or us). We will - * reattempt our join which should be accepted once the nodes are done with - * recovery. - */ - -static int backout_barrier_wait(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - char bname[MAX_BARRIER_NAME_LEN]; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - clear_bit(SEFL_ALLOW_BARRIER, &sev->se_flags); - - sg->ops->stop(sg->service_data); - - memset(bname, 0, MAX_BARRIER_NAME_LEN); - snprintf(bname, MAX_BARRIER_NAME_LEN, "sm.%u.%u.%u.%u", - sg->global_id, sm_our_nodeid, sev->se_id, - sg->memb_count); - kcl_barrier_cancel(bname); - - free_sg_memb(sg); - return TRUE; -} - -/* - * If NEED_RECOVERY is set, a member of the sg we just joined has failed. The - * recovery began after the barrier callback. If the result in the callback is - * "success" then we are joined, this sevent is finished and we'll process the - * sg within the forthcoming recovery with the other members. - * - * We rely upon cnxman to guarantee that once all nodes have joined a barrier, - * all nodes will receive the corresponding barrier callback *before any* - * receive an sm_member_update() due to one of those nodes failing just after - * joining the barrier. If some nodes receive the sm_member_update() before - * the barrier callback and others receive the barrier callback before the - * sm_member_update() then they will disagree as to whether the node joining/ - * leaving is in/out of the sg. - */ - -static int backout_barrier_done(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - if (!sev->se_barrier_status) { - do_finish_new(sev); - sevent_done(sev); - return FALSE; - } else { - sg->ops->stop(sg->service_data); - free_sg_memb(sg); - return TRUE; - } -} - -/* - * We've done nothing yet, just restart when recovery is done (if sg is flagged - * with recovery.) - */ - -static int backout_leave_begin(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - return TRUE; -} - -/* - * Ignore any replies to our leave notice and restart when recovery is done (if - * sg is flagged with recovery.) - */ - -static int backout_leave_ackwait(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - clear_bit(SEFL_ALLOW_LEAVE, &sev->se_flags); - - return TRUE; -} - -/* - * Same as previous. - */ - -static int backout_leave_acked(sm_sevent_t *sev) -{ - return backout_leave_ackwait(sev); -} - -/* - * Ignore any stop replies. All the members will be stopped anyway to do the - * recovery. Let that happen and restart our leave when done. - */ - -static int backout_lstop_ackwait(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - clear_bit(SEFL_ALLOW_LSTOP, &sev->se_flags); - - return TRUE; -} - -/* - * Same as previous. - */ - -static int backout_lstop_acked(sm_sevent_t *sev) -{ - return backout_lstop_ackwait(sev); -} - -/* - * All members will be stopped due to recovery and restarted by recovery - * processing. That includes us, we have to retry the leave once the recovery - * is done. - */ - -static int backout_lstart_waitremote(sm_sevent_t *sev) -{ - sm_group_t *sg = sev->se_sg; - - if (!test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - return FALSE; - - return TRUE; -} - -/* - * Reset an sevent to its beginning so it can be restarted. This is necessary - * when recovery affects an SG while we're trying to join or leave (ie. a node - * in the SG fails). - */ - -void backout_sevents(void) -{ - sm_sevent_t *sev, *safe; - int delay; - - list_for_each_entry_safe(sev, safe, &joinleave_events, se_list) { - - delay = FALSE; - - log_debug(sev->se_sg, "backout sevent state %u", sev->se_state); - - switch (sev->se_state) { - - /* backout after kcl_join_service and before - * send_join_notice */ - case SEST_JOIN_BEGIN: - break; - - /* backout after send_join_notice and before final - * process_reply */ - case SEST_JOIN_ACKWAIT: - clear_bit(SEFL_ALLOW_JOIN, &sev->se_flags); - sev->se_state = SEST_JOIN_BEGIN; - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - break; - - /* backout after final process_reply and before - * check_join_notice */ - case SEST_JOIN_ACKED: - delay = backout_join_acked(sev); - break; - - /* backout after send_join_stop and before final - * process_reply */ - case SEST_JSTOP_ACKWAIT: - delay = backout_jstop_ackwait(sev); - break; - - /* backout after final process_reply and before - * check_join_stop */ - case SEST_JSTOP_ACKED: - delay = backout_jstop_acked(sev); - break; - - /* backout after send_join_start and before - * kcl_start_done */ - case SEST_JSTART_SERVICEWAIT: - delay = backout_jstart_servicewait(sev); - break; - - /* backout after kcl_start_done and before - * startdone_barrier_new */ - case SEST_JSTART_SERVICEDONE: - delay = backout_jstart_servicedone(sev); - break; - - /* backout after startdone_barrier_new and before - * callback_startdone_barrier_new */ - case SEST_BARRIER_WAIT: - delay = backout_barrier_wait(sev); - break; - - /* backout after callback_startdone_barrier_new and - * before check_startdone_barrier_new */ - case SEST_BARRIER_DONE: - delay = backout_barrier_done(sev); - break; - - /* backout after kcl_leave_service and before - * send_leave_notice */ - case SEST_LEAVE_BEGIN: - delay = backout_leave_begin(sev); - break; - - /* backout after send_leave_notice and before final - * process_reply */ - case SEST_LEAVE_ACKWAIT: - delay = backout_leave_ackwait(sev); - break; - - /* backout after final process_reply and before - * check_leave_notice */ - case SEST_LEAVE_ACKED: - delay = backout_leave_acked(sev); - break; - - /* backout after send_leave_stop and before final - * process_reply */ - case SEST_LSTOP_ACKWAIT: - delay = backout_lstop_ackwait(sev); - break; - - /* backout after final process_reply and before - * check_leave_stop */ - case SEST_LSTOP_ACKED: - delay = backout_lstop_acked(sev); - break; - - /* backout after send_leave_start and before - * process_lstart_done */ - case SEST_LSTART_WAITREMOTE: - delay = backout_lstart_waitremote(sev); - break; - - /* backout after process_lstart_done and before - * process_leave_sevent */ - case SEST_LSTART_REMOTEDONE: - sevent_done(sev); - delay = FALSE; - break; - - default: - log_error(sev->se_sg, "backout_sevents: bad state %d", - sev->se_state); - } - - if (delay) { - if (test_bit(SEFL_LEAVE, &sev->se_flags)) { - sev->se_state = SEST_LEAVE_BEGIN; - set_bit(SEFL_DELAY_RECOVERY, &sev->se_flags); - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } else { - sev->se_state = SEST_JOIN_BEGIN; - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } - } - } -} - -void process_joinleave(void) -{ - sm_sevent_t *sev = NULL, *safe; - - spin_lock(&new_event_lock); - if (!list_empty(&new_event)) { - sev = list_entry(new_event.next, sm_sevent_t, se_list); - list_del(&sev->se_list); - list_add_tail(&sev->se_list, &joinleave_events); - set_bit(SEFL_CHECK, &sev->se_flags); - } - spin_unlock(&new_event_lock); - - list_for_each_entry_safe(sev, safe, &joinleave_events, se_list) { - if (!test_and_clear_bit(SEFL_CHECK, &sev->se_flags)) - continue; - - if (test_bit(SEFL_DELAY, &sev->se_flags) || - test_bit(SEFL_DELAY_RECOVERY, &sev->se_flags)) - continue; - - if (sev->se_state < SEST_LEAVE_BEGIN) - process_join_sevent(sev); - else - process_leave_sevent(sev); - } -} diff --git a/cman-kernel/src/sm_joinleave.h b/cman-kernel/src/sm_joinleave.h deleted file mode 100644 index db86803..0000000 --- a/cman-kernel/src/sm_joinleave.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_JOINLEAVE_DOT_H__ -#define __SM_JOINLEAVE_DOT_H__ - -void init_joinleave(void); -void new_joinleave(sm_sevent_t *sev); -void process_joinleave(void); -void backout_sevents(void); -sm_sevent_t *find_sevent(unsigned int id); - -#endif diff --git a/cman-kernel/src/sm_membership.c b/cman-kernel/src/sm_membership.c deleted file mode 100644 index 3ae6565..0000000 --- a/cman-kernel/src/sm_membership.c +++ /dev/null @@ -1,701 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" - -extern struct list_head sm_members; - -/* - * Routines for SG members to handle other nodes joining or leaving the SG. - * These "uevent" membership update routines are the response to an "sevent" on - * a joining/leaving node. - */ - -static void del_memb_node(sm_group_t *sg, uint32_t nodeid) -{ - sm_node_t *node; - - list_for_each_entry(node, &sg->memb, list) { - if (node->id != nodeid) - continue; - list_del(&node->list); - kfree(node); - sg->memb_count--; - log_debug(sg, "del node %u count %d", nodeid, sg->memb_count); - break; - } -} - -static void add_memb_node(sm_group_t *sg, sm_node_t *node) -{ - list_add_tail(&node->list, &sg->memb); - sg->memb_count++; - log_debug(sg, "add node %u count %d", node->id, sg->memb_count); -} - -/* - * Join 1. The receive end of send_join_stop() from a node requesting to join - * the SG. We stop the service so it can be restarted with the new node. - */ - -static int process_join_stop(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - sm_node_t *node; - sm_msg_t reply; - int error; - - if (uev->ue_num_nodes != sg->memb_count + 1) { - log_error(sg, "process_join_stop: bad num nodes %u %u", - uev->ue_num_nodes, sg->memb_count); - return -1; - } - - sm_set_event_id(&uev->ue_id); - - node = sm_find_joiner(sg, uev->ue_nodeid); - if (!node) { - log_error(sg, "process_join_stop: no node %d", uev->ue_nodeid); - return -1; - } - - sg->state = SGST_UEVENT; - sg->ops->stop(sg->service_data); - - reply.ms_type = SMSG_JSTOP_REP; - reply.ms_status = STATUS_POS; - reply.ms_sevent_id = uev->ue_remote_seid; - smsg_bswap_out(&reply); - - error = send_nodeid_message((char *) &reply, sizeof(reply), - uev->ue_nodeid); - if (error < 0) - return error; - return 0; -} - -/* - * Join 2. The receive end of send_join_start() from a node joining the SG. - * We are re-starting the service with the new member added. - */ - -static int process_join_start(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - sm_node_t *node; - uint32_t *memb; - int count = 0; - - /* this memory is passed to the service which must free it */ - SM_RETRY(memb = - kmalloc((sg->memb_count + 1) * sizeof(uint32_t), GFP_KERNEL), - memb); - - /* transfer joining node from joining list to member list */ - node = sm_find_joiner(sg, uev->ue_nodeid); - SM_ASSERT(node, printk("nodeid=%u\n", uev->ue_nodeid);); - list_del(&node->list); - add_memb_node(sg, node); - - /* the new member list for the service */ - list_for_each_entry(node, &sg->memb, list) - memb[count++] = node->id; - - set_bit(UEFL_ALLOW_STARTDONE, &uev->ue_flags); - - sg->ops->start(sg->service_data, memb, count, uev->ue_id, - SERVICE_NODE_JOIN); - return 0; -} - -/* - * Join 3. When done starting their local service, every previous SG member - * calls startdone_barrier() and the new/joining member calls - * startdone_barrier_new(). The barrier returns when everyone has started - * their service and joined the barrier. - */ - -static int startdone_barrier(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - char bname[MAX_BARRIER_NAME_LEN]; - int error; - - memset(bname, 0, MAX_BARRIER_NAME_LEN); - uev->ue_barrier_status = -1; - - set_bit(UEFL_ALLOW_BARRIER, &uev->ue_flags); - - /* If we're the only member, skip the barrier */ - if (sg->memb_count == 1) { - process_startdone_barrier(sg, 0); - return 0; - } - - snprintf(bname, MAX_BARRIER_NAME_LEN, "sm.%u.%u.%u.%u", - sg->global_id, uev->ue_nodeid, uev->ue_remote_seid, - sg->memb_count); - - error = sm_barrier(bname, sg->memb_count, SM_BARRIER_STARTDONE); - - return error; -} - -/* - * Join 4. Check that the "all started" barrier returned a successful status. - * The newly joined member calls check_startdone_barrier_new(). - */ - -static int check_startdone_barrier(sm_group_t *sg) -{ - int error = sg->uevent.ue_barrier_status; - return error; -} - -/* - * Join 5. Send the service a "finish" indicating that all members have - * successfully started. The newly joined member calls do_finish_new(). - */ - -static void do_finish(sm_group_t *sg) -{ - sg->state = SGST_RUN; - clear_bit(SGFL_UEVENT, &sg->flags); - sg->ops->finish(sg->service_data, sg->uevent.ue_id); -} - -/* - * Join 6. The uevent is done. If this was a uevent for a node leaving the - * SG, then send a final message to the departed node signalling that the - * remaining nodes have restarted since it left. - */ - -static void uevent_done(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - sm_msg_t reply; - - if (test_bit(UEFL_LEAVE, &uev->ue_flags)) { - reply.ms_type = SMSG_LSTART_DONE; - reply.ms_status = STATUS_POS; - reply.ms_sevent_id = uev->ue_remote_seid; - smsg_bswap_out(&reply); - send_nodeid_message((char *) &reply, sizeof(reply), - uev->ue_nodeid); - } - memset(&sg->uevent, 0, sizeof(sm_uevent_t)); -} - -/* - * Leave 1. The receive end of send_leave_stop() from a node leaving the SG. - */ - -static int process_leave_stop(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - sm_msg_t reply; - int error; - - sm_set_event_id(&uev->ue_id); - - sg->state = SGST_UEVENT; - sg->ops->stop(sg->service_data); - - reply.ms_type = SMSG_LSTOP_REP; - reply.ms_status = STATUS_POS; - reply.ms_sevent_id = uev->ue_remote_seid; - smsg_bswap_out(&reply); - - error = send_nodeid_message((char *) &reply, sizeof(reply), - uev->ue_nodeid); - if (error < 0) - return error; - return 0; -} - -/* - * Leave 2. The receive end of send_leave_start() from a node leaving the SG. - * We are re-starting the service (without the node that's left naturally.) - */ - -static int process_leave_start(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - sm_node_t *node; - uint32_t *memb; - int count = 0; - - SM_ASSERT(sg->memb_count > 1, - printk("memb_count=%u\n", sg->memb_count);); - - /* this memory is passed to the service which must free it */ - SM_RETRY(memb = - kmalloc((sg->memb_count - 1) * sizeof(uint32_t), GFP_KERNEL), - memb); - - /* remove departed member from sg member list */ - del_memb_node(sg, uev->ue_nodeid); - - /* build member list to pass to service */ - list_for_each_entry(node, &sg->memb, list) - memb[count++] = node->id; - - /* allow us to accept the start_done callback for this start */ - set_bit(UEFL_ALLOW_STARTDONE, &uev->ue_flags); - - sg->ops->start(sg->service_data, memb, count, uev->ue_id, - SERVICE_NODE_LEAVE); - return 0; -} - -/* - * Move through the steps of another node joining or leaving the SG. - */ - -static void process_one_uevent(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - int error = 0; - - log_debug(sg, "uevent state %u node %u", uev->ue_state, uev->ue_nodeid); - - switch (uev->ue_state) { - - /* - * a uevent is initialized with state JSTOP in - * process_stop_request - */ - - case UEST_JSTOP: - uev->ue_state = UEST_JSTART_WAITCMD; - error = process_join_stop(sg); - break; - - /* - * ue_state is changed from JSTART_WAITCMD to JSTART in - * process_start_request - */ - - case UEST_JSTART: - uev->ue_state = UEST_JSTART_SERVICEWAIT; - error = process_join_start(sg); - break; - - /* - * ue_state is changed from JSTART_SERVICEWAIT to - * JSTART_SERVICEDONE in kcl_start_done - */ - - case UEST_JSTART_SERVICEDONE: - uev->ue_state = UEST_BARRIER_WAIT; - error = startdone_barrier(sg); - break; - - /* - * ue_state is changed from BARRIER_WAIT to BARRIER_DONE in - * process_startdone_barrier - */ - - case UEST_BARRIER_DONE: - error = check_startdone_barrier(sg); - if (error) - break; - - do_finish(sg); - uevent_done(sg); - break; - - /* - * a uevent is initialized with state LSTOP in - * process_stop_request - */ - - case UEST_LSTOP: - uev->ue_state = UEST_LSTART_WAITCMD; - error = process_leave_stop(sg); - break; - - /* - * a uevent is changed from LSTART_WAITCMD to LSTART in - * process_start_request - */ - - case UEST_LSTART: - uev->ue_state = UEST_LSTART_SERVICEWAIT; - error = process_leave_start(sg); - break; - - /* - * a uevent is changed from LSTART_SERVICEWAIT to to - * LSTART_SERVICEDONE in kcl_start_done - */ - - case UEST_LSTART_SERVICEDONE: - uev->ue_state = UEST_BARRIER_WAIT; - error = startdone_barrier(sg); - break; - - default: - error = -1; - } - - /* If we encounter an error during these routines, we do nothing, - expecting that a node failure related to this sg will cause a - recovery event to arrive and call cancel_one_uevent(). */ - - if (error) - log_error(sg, "process_one_uevent error %d state %u", - error, uev->ue_state); -} - -static sm_node_t *failed_memb(sm_group_t *sg, int *count) -{ - sm_node_t *node, *sm_node, *failed_uev_node = NULL; - - list_for_each_entry(node, &sg->memb, list) { - - sm_node = sm_find_member(node->id); - SM_ASSERT(sm_node, ); - - if (test_bit(SNFL_NEED_RECOVERY, &sm_node->flags)) { - (*count)++; - if (node->id == sg->uevent.ue_nodeid) - failed_uev_node = sm_node; - } - } - return failed_uev_node; -} - -static void send_recover_msg(sm_group_t *sg) -{ - char *msg; - int len = 0; - msg = create_smsg(sg, SMSG_RECOVER, 0, &len, NULL); - send_members_message(sg, msg, len); -} - -static void cancel_barrier(sm_group_t *sg) -{ - sm_uevent_t *uev = &sg->uevent; - char bname[MAX_BARRIER_NAME_LEN]; - - clear_bit(UEFL_ALLOW_BARRIER, &uev->ue_flags); - - memset(bname, 0, MAX_BARRIER_NAME_LEN); - snprintf(bname, MAX_BARRIER_NAME_LEN, "sm.%u.%u.%u.%u", - sg->global_id, uev->ue_nodeid, uev->ue_remote_seid, - sg->memb_count); - kcl_barrier_cancel(bname); -} - -static void cancel_one_uevent(sm_group_t *sg, int *effected) -{ - sm_uevent_t *uev = &sg->uevent; - int failed_count; - sm_node_t *node, *failed_joiner, *failed_leaver; - - log_debug(sg, "cancel uevent state %u node %u", uev->ue_state, - uev->ue_nodeid); - - switch (uev->ue_state) { - - case UEST_JSTOP: - case UEST_JSTART_WAITCMD: - case UEST_JSTART: - - sg->ops->stop(sg->service_data); - - failed_count = 0; - failed_joiner = failed_memb(sg, &failed_count); - SM_ASSERT(!failed_joiner, ); - - node = sm_find_member(uev->ue_nodeid); - if (node && test_bit(SNFL_NEED_RECOVERY, &node->flags)) - failed_joiner = node; - - if (!failed_count) { - /* only joining node failed */ - SM_ASSERT(failed_joiner, ); - SM_ASSERT(!test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - set_bit(SGFL_NEED_RECOVERY, &sg->flags); - (*effected)++; - /* some nodes may not have gotten a JSTOP message - in which case this will tell them to begin - recovery for this sg. */ - send_recover_msg(sg); - - } else { - /* a member node failed (and possibly joining node, it - doesn't matter) */ - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - } - - clear_bit(SGFL_UEVENT, &sg->flags); - memset(uev, 0, sizeof(sm_uevent_t)); - break; - - - case UEST_JSTART_SERVICEWAIT: - case UEST_JSTART_SERVICEDONE: - - clear_bit(UEFL_ALLOW_STARTDONE, &uev->ue_flags); - sg->ops->stop(sg->service_data); - - failed_count = 0; - failed_joiner = failed_memb(sg, &failed_count); - SM_ASSERT(failed_count, ); - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - - if (failed_count == 1 && failed_joiner) { - /* only joining node failed */ - - } else if (failed_count && failed_joiner) { - /* joining node and another member failed */ - - } else { - /* other member failed, joining node still alive */ - SM_ASSERT(!failed_joiner, ); - del_memb_node(sg, uev->ue_nodeid); - } - - clear_bit(SGFL_UEVENT, &sg->flags); - memset(uev, 0, sizeof(sm_uevent_t)); - break; - - - case UEST_LSTOP: - case UEST_LSTART_WAITCMD: - case UEST_LSTART: - - sg->ops->stop(sg->service_data); - - failed_count = 0; - failed_leaver = failed_memb(sg, &failed_count); - SM_ASSERT(failed_count, ); - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - - if (failed_count == 1 && failed_leaver) { - /* only leaving node failed */ - - } else if (failed_count && failed_leaver) { - /* leaving node and another member failed */ - - } else { - /* other member failed, leaving node still alive */ - SM_ASSERT(!failed_leaver, ); - } - - clear_bit(SGFL_UEVENT, &sg->flags); - memset(uev, 0, sizeof(sm_uevent_t)); - break; - - - case UEST_LSTART_SERVICEWAIT: - case UEST_LSTART_SERVICEDONE: - - clear_bit(UEFL_ALLOW_STARTDONE, &uev->ue_flags); - sg->ops->stop(sg->service_data); - - failed_count = 0; - failed_leaver = failed_memb(sg, &failed_count); - SM_ASSERT(!failed_leaver, ); - - node = sm_find_member(uev->ue_nodeid); - if (node && test_bit(SNFL_NEED_RECOVERY, &node->flags)) - failed_leaver = node; - - if (!failed_count) { - /* only leaving node failed */ - SM_ASSERT(failed_leaver, ); - SM_ASSERT(!test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - set_bit(SGFL_NEED_RECOVERY, &sg->flags); - (*effected)++; - - } else if (failed_count && failed_leaver) { - /* leaving node and another member failed */ - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - - } else { - /* other member failed, leaving node still alive */ - SM_ASSERT(failed_count, ); - SM_ASSERT(!failed_leaver, ); - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - node = sm_new_node(sg->uevent.ue_nodeid); - add_memb_node(sg, node); - } - - clear_bit(SGFL_UEVENT, &sg->flags); - memset(uev, 0, sizeof(sm_uevent_t)); - break; - - - case UEST_BARRIER_WAIT: - - if (test_bit(UEFL_LEAVE, &uev->ue_flags)) - goto barrier_wait_leave; - - sg->ops->stop(sg->service_data); - cancel_barrier(sg); - - barrier_wait_join: - - failed_count = 0; - failed_joiner = failed_memb(sg, &failed_count); - SM_ASSERT(failed_count, ); - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - - if (failed_count == 1 && failed_joiner) { - /* only joining node failed */ - - } else if (failed_count && failed_joiner) { - /* joining node and another member failed */ - - } else { - /* other member failed, joining node still alive */ - SM_ASSERT(!failed_joiner, ); - del_memb_node(sg, uev->ue_nodeid); - } - - clear_bit(SGFL_UEVENT, &sg->flags); - memset(uev, 0, sizeof(sm_uevent_t)); - break; - - barrier_wait_leave: - - failed_count = 0; - failed_leaver = failed_memb(sg, &failed_count); - SM_ASSERT(!failed_leaver, ); - - node = sm_find_member(uev->ue_nodeid); - if (node && test_bit(SNFL_NEED_RECOVERY, &node->flags)) - failed_leaver = node; - - if (!failed_count) { - /* only leaving node failed */ - SM_ASSERT(failed_leaver, ); - SM_ASSERT(!test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - set_bit(SGFL_NEED_RECOVERY, &sg->flags); - (*effected)++; - - } else if (failed_count && failed_leaver) { - /* leaving node and another member failed */ - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - - } else { - /* other member failed, leaving node still alive */ - SM_ASSERT(failed_count, ); - SM_ASSERT(!failed_leaver, ); - SM_ASSERT(test_bit(SGFL_NEED_RECOVERY, &sg->flags), ); - node = sm_new_node(sg->uevent.ue_nodeid); - add_memb_node(sg, node); - } - - clear_bit(SGFL_UEVENT, &sg->flags); - memset(uev, 0, sizeof(sm_uevent_t)); - break; - - - case UEST_BARRIER_DONE: - - if (!uev->ue_barrier_status) { - do_finish(sg); - uevent_done(sg); - break; - } - - if (test_bit(UEFL_LEAVE, &uev->ue_flags)) - goto barrier_wait_leave; - else - goto barrier_wait_join; - - - default: - log_error(sg, "cancel_one_uevent: state %d", uev->ue_state); - } -} - -void cancel_uevents(int *effected) -{ - sm_group_t *sg; - sm_node_t *node, *sgnode; - int i; - - list_for_each_entry(node, &sm_members, list) { - if (!test_bit(SNFL_NEED_RECOVERY, &node->flags)) - continue; - - /* - * Clear this dead node from the "interested in joining" list - * of any SG. The node is added to this list before the uevent - * begins. - */ - - for (i = 0; i < SG_LEVELS; i++) { - list_for_each_entry(sg, &sm_sg[i], list) { - sgnode = sm_find_joiner(sg, node->id); - if (sgnode) { - log_debug(sg, "clear joining node %u", - sgnode->id); - list_del(&sgnode->list); - kfree(sgnode); - } - } - } - schedule(); - } - - /* Adjust any uevents in sg's effected by the failed node(s) */ - - for (i = 0; i < SG_LEVELS; i++) { - list_for_each_entry(sg, &sm_sg[i], list) { - if (!test_bit(SGFL_UEVENT, &sg->flags)) - continue; - - /* We may have some cancelling to do if this sg is - flagged as having a failed member, or if a joining - or leaving node has died. */ - - if (test_bit(SGFL_NEED_RECOVERY, &sg->flags)) - cancel_one_uevent(sg, effected); - else if (sg->uevent.ue_nodeid) { - node = sm_find_member(sg->uevent.ue_nodeid); - SM_ASSERT(node, ); - if (test_bit(SNFL_NEED_RECOVERY, &node->flags)) - cancel_one_uevent(sg, effected); - } - } - schedule(); - } -} - -void process_membership(void) -{ - sm_group_t *sg; - int i; - - down(&sm_sglock); - - for (i = 0; i < SG_LEVELS; i++) { - list_for_each_entry(sg, &sm_sg[i], list) { - if (!test_bit(SGFL_UEVENT, &sg->flags)) - continue; - - if (!test_and_clear_bit(UEFL_CHECK, - &sg->uevent.ue_flags)) - continue; - - process_one_uevent(sg); - } - } - up(&sm_sglock); -} diff --git a/cman-kernel/src/sm_membership.h b/cman-kernel/src/sm_membership.h deleted file mode 100644 index 2f4b7d3..0000000 --- a/cman-kernel/src/sm_membership.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_MEMBERSHIP_DOT_H__ -#define __SM_MEMBERSHIP_DOT_H__ - -void process_membership(void); -void cancel_uevents(int *effected); - -#endif diff --git a/cman-kernel/src/sm_message.c b/cman-kernel/src/sm_message.c deleted file mode 100644 index aa9a985..0000000 --- a/cman-kernel/src/sm_message.c +++ /dev/null @@ -1,884 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" - -#define SMSG_BUF_SIZE (sizeof(sm_msg_t) + MAX_SERVICE_NAME_LEN + 1) - -extern struct socket * sm_socket; -extern uint32_t sm_our_nodeid; -static uint32_t global_last_id; -static struct list_head messages; -static spinlock_t message_lock; -static char smsg_buf[SMSG_BUF_SIZE]; - -int send_nodeid_message(char *msg, int len, uint32_t nodeid); - -struct rq_entry { - struct list_head list; - char *msg; - int len; - uint32_t nodeid; -}; -typedef struct rq_entry rq_entry_t; - -void init_messages(void) -{ - global_last_id = 1; - INIT_LIST_HEAD(&messages); - spin_lock_init(&message_lock); -} - -uint32_t sm_new_global_id(int level) -{ - uint32_t id = global_last_id + sm_our_nodeid; - uint8_t l = (uint8_t) level; - - if (level > 255) - return 0; - - if (id > 0x00FFFFFF) { - log_print("ERROR: max global group id"); - return 0; - } - global_last_id = id; - id |= (l << 24); - return id; -} - -static void smsg_copy_in(char *msg, sm_msg_t *smsg) -{ - sm_msg_t *in = (sm_msg_t *) msg; - - smsg->ms_type = in->ms_type; - smsg->ms_status = in->ms_status; - smsg->ms_sevent_id = le32_to_cpu(in->ms_sevent_id); - smsg->ms_global_sgid = le32_to_cpu(in->ms_global_sgid); - smsg->ms_global_lastid = le32_to_cpu(in->ms_global_lastid); - smsg->ms_sglevel = le16_to_cpu(in->ms_sglevel); - smsg->ms_length = le16_to_cpu(in->ms_length); -} - -/* swapping bytes in place is an easy source of errors - be careful not to - * access the fields after calling this */ - -void smsg_bswap_out(sm_msg_t *smsg) -{ - smsg->ms_sevent_id = cpu_to_le32(smsg->ms_sevent_id); - smsg->ms_global_sgid = cpu_to_le32(smsg->ms_global_sgid); - smsg->ms_global_lastid = cpu_to_le32(smsg->ms_global_lastid); - smsg->ms_sglevel = cpu_to_le16(smsg->ms_sglevel); - smsg->ms_length = cpu_to_le16(smsg->ms_length); -} - -char *create_smsg(sm_group_t *sg, int type, int datalen, int *msglen, - sm_sevent_t *sev) -{ - char *msg; - sm_msg_t *smsg; - int fulllen = sizeof(sm_msg_t) + datalen; - - msg = smsg_buf; - memset(smsg_buf, 0, SMSG_BUF_SIZE); - SM_ASSERT(fulllen <= SMSG_BUF_SIZE,); - - smsg = (sm_msg_t *) msg; - smsg->ms_type = type; - smsg->ms_global_sgid = sg->global_id; - smsg->ms_sglevel = sg->level; - smsg->ms_length = datalen; - smsg->ms_sevent_id = sev ? sev->se_id : 0; - - smsg_bswap_out(smsg); - *msglen = fulllen; - return msg; -} - -static unsigned int msgtype_to_flag(int type) -{ - unsigned int flag; - - switch (type) { - case SMSG_JOIN_REP: - case SMSG_JOIN_REQ: - flag = SEFL_ALLOW_JOIN; - break; - - case SMSG_JSTOP_REP: - case SMSG_JSTOP_REQ: - flag = SEFL_ALLOW_JSTOP; - break; - - case SMSG_LEAVE_REP: - case SMSG_LEAVE_REQ: - flag = SEFL_ALLOW_LEAVE; - break; - - case SMSG_LSTOP_REP: - case SMSG_LSTOP_REQ: - flag = SEFL_ALLOW_LSTOP; - break; - - default: - SM_ASSERT(0, printk("msgtype_to_flag bad type %d\n", type);); - } - return flag; -} - -static int test_allowed_msgtype(sm_sevent_t *sev, int type) -{ - unsigned int flag = msgtype_to_flag(type); - - return test_bit(flag, &sev->se_flags); -} - -static void clear_allowed_msgtype(sm_sevent_t *sev, int type) -{ - unsigned int flag = msgtype_to_flag(type); - - clear_bit(flag, &sev->se_flags); -} - -static void set_allowed_msgtype(sm_sevent_t *sev, int type) -{ - unsigned int flag = msgtype_to_flag(type); - - set_bit(flag, &sev->se_flags); -} - -static int save_global_id(sm_sevent_t *sev, sm_msg_t *smsg) -{ - sm_group_t *sg = sev->se_sg; - - if (!smsg->ms_global_sgid) { - log_error(sg, "save_global_id: zero sg id"); - return -1; - } - - if (!sg->global_id) - sg->global_id = smsg->ms_global_sgid; - - if (sg->global_id != smsg->ms_global_sgid) { - log_error(sg, "save_global_id: id %x", smsg->ms_global_sgid); - return -1; - } - return 0; -} - -static void save_lastid(sm_msg_t *smsg) -{ - uint32_t gid = smsg->ms_global_lastid & 0x00FFFFFF; - - /* - * Keep track of the highst SG id which has been used - * in the cluster in case we need to choose a new SG id. - */ - - if (gid > global_last_id) - global_last_id = gid; -} - -static int next_sev_state(int msg_type, int cur_state) -{ - int next = 0; - - switch (msg_type) { - case SMSG_JOIN_REP: - SM_ASSERT(cur_state == SEST_JOIN_ACKWAIT,); - next = SEST_JOIN_ACKED; - break; - - case SMSG_JSTOP_REP: - SM_ASSERT(cur_state == SEST_JSTOP_ACKWAIT,); - next = SEST_JSTOP_ACKED; - break; - - case SMSG_LEAVE_REP: - SM_ASSERT(cur_state == SEST_LEAVE_ACKWAIT,); - next = SEST_LEAVE_ACKED; - break; - - case SMSG_LSTOP_REP: - SM_ASSERT(cur_state == SEST_LSTOP_ACKWAIT,); - next = SEST_LSTOP_ACKED; - break; - } - return next; -} - -/* - * Functions in sevent.c send messages to other nodes and then expect replies. - * This function collects the replies for the sevent messages and moves the - * sevent to the next stage when all the expected replies have been received. - */ - -static void process_reply(sm_msg_t *smsg, uint32_t nodeid) -{ - sm_sevent_t *sev; - int i, expected, type = smsg->ms_type; - - /* - * Find the relevant sevent. - */ - - sev = find_sevent(smsg->ms_sevent_id); - if (!sev) { - log_print("process_reply invalid id=%u nodeid=%u", - smsg->ms_sevent_id, nodeid); - goto out; - } - - /* - * Check if this message type is what this sevent is waiting for. - */ - - if (!test_allowed_msgtype(sev, type)) { - log_debug(sev->se_sg, "process_reply ignored type=%u nodeid=%u " "id=%u", type, nodeid, sev->se_id); - goto out; - } - - expected = - (type == SMSG_JOIN_REP) ? sev->se_node_count : sev->se_memb_count; - - SM_ASSERT(expected * sizeof(uint32_t) <= sev->se_len_ids, - printk("type=%d expected=%d len_ids=%d node_count=%d " - "memb_count=%d\n", type, expected, sev->se_len_ids, - sev->se_node_count, sev->se_memb_count);); - - SM_ASSERT(expected * sizeof(char) <= sev->se_len_status, - printk("type=%d expected=%d len_status=%d node_count=%d " - "memb_count=%d\n", type, expected, sev->se_len_status, - sev->se_node_count, sev->se_memb_count);); - - for (i = 0; i < expected; i++) { - if (sev->se_node_ids[i] == nodeid) { - /* - * Save the status from the replying node - */ - - if (!sev->se_node_status[i]) - sev->se_node_status[i] = smsg->ms_status; - else { - log_error(sev->se_sg, "process_reply duplicate" - "id=%u nodeid=%u %u/%u", - sev->se_id, nodeid, - sev->se_node_status[i], - smsg->ms_status); - goto out; - } - - if (type == SMSG_JOIN_REP) { - save_lastid(smsg); - - if (smsg->ms_status == STATUS_POS) - save_global_id(sev, smsg); - } - - /* - * Signal sm if we have all replies - */ - - if (++sev->se_reply_count == expected) { - clear_allowed_msgtype(sev, type); - sev->se_state = next_sev_state(type, - sev->se_state); - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } - - break; - } - } - - out: - return; -} - -/* - * A node wants to join an SG and has run send_join_notice. If we know nothing - * about the SG , then we have no objection - send back STATUS_POS. If we're a - * member of the SG, then send back STATUS_POS (go ahead and join) if there's - * no sevent or uevent of higher priority in progress (only a single join or - * leave is permitted for the SG at once). If there happens to be a higher - * priority sevent/uevent in progress, send back STATUS_WAIT to defer the - * requested join for a bit. - */ - -static void process_join_request(sm_msg_t *smsg, uint32_t nodeid, char *name) -{ - sm_group_t *sg = NULL; - sm_sevent_t *sev = NULL; - sm_node_t *node; - int found = FALSE; - int level = smsg->ms_sglevel; - sm_msg_t reply; - - memset(&reply, 0, sizeof(reply)); - - down(&sm_sglock); - - if (nodeid == sm_our_nodeid) - goto next; - - /* - * search SG list for an SG with given name/len - */ - - list_for_each_entry(sg, &sm_sg[level], list) { - if ((sg->namelen != smsg->ms_length) || - memcmp(sg->name, name, sg->namelen)) - continue; - found = TRUE; - break; - } - - /* - * build reply message - */ - - next: - - if (!found) { - reply.ms_type = SMSG_JOIN_REP; - reply.ms_status = STATUS_NEG; - reply.ms_global_lastid = global_last_id; - reply.ms_sevent_id = smsg->ms_sevent_id; - } else { - reply.ms_type = SMSG_JOIN_REP; - reply.ms_status = STATUS_POS; - reply.ms_sevent_id = smsg->ms_sevent_id; - reply.ms_global_sgid = sg->global_id; - reply.ms_global_lastid = global_last_id; - - /* - * The node trying to join should wait and try again until - * we're done with recovery. - */ - - if (sg->state == SGST_RECOVER) { - reply.ms_status = STATUS_WAIT; - goto send; - } - - /* - * An sevent node trying to join may have gotten as far as - * creating a uevent with us and then backed out. That node - * will retry joining from the beginning so we should not turn - * them away. If we're handling a uevent for another node, - * tell the joining node to wait. - */ - - if (test_bit(SGFL_UEVENT, &sg->flags)) { - if (sg->uevent.ue_nodeid != nodeid) - reply.ms_status = STATUS_WAIT; - goto send; - } - - /* - * We're trying to join or leave the SG at the moment. - */ - - if (test_bit(SGFL_SEVENT, &sg->flags)) { - - /* not sure how/when this happens */ - if (!sg->sevent) { - log_print("process_join_request from %d " - "sevent flag no struct", nodeid); - reply.ms_status = STATUS_NEG; - goto send; - } - - sev = sg->sevent; - - /* - * We're trying to leave. Make the join wait until - * we've left if we're beyond LEAVE_ACKWAIT. - */ - - if (test_bit(SEFL_LEAVE, &sev->se_flags)) { - if (sev->se_state > SEST_LEAVE_ACKED) - reply.ms_status = STATUS_WAIT; - else { - reply.ms_status = STATUS_POS; - clear_bit(SEFL_ALLOW_LEAVE, - &sev->se_flags); - set_bit(SEFL_CANCEL, &sev->se_flags); - } - } - - /* - * We're trying to join. Making the other join wait - * until we're joined if we're beyond JOIN_ACKWAIT or - * if we have a lower id. (Send NEG to allow the other - * node to go ahead because we're not in the SG.) - */ - - else { - if (sev->se_state > SEST_JOIN_ACKED) - reply.ms_status = STATUS_WAIT; - else if (sm_our_nodeid < nodeid) - reply.ms_status = STATUS_WAIT; - else { - reply.ms_status = STATUS_NEG; - clear_bit(SEFL_ALLOW_JOIN, - &sev->se_flags); - set_bit(SEFL_CANCEL, &sev->se_flags); - } - } - - if (test_bit(SEFL_CANCEL, &sev->se_flags)) { - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } - goto send; - } - - /* no r,u,s event, stick with STATUS_POS */ - } - - send: - - if (reply.ms_status == STATUS_POS) { - node = sm_find_joiner(sg, nodeid); - if (!node) { - node = sm_new_node(nodeid); - list_add_tail(&node->list, &sg->joining); - } - } - - up(&sm_sglock); - smsg_bswap_out(&reply); - send_nodeid_message((char *) &reply, sizeof(reply), nodeid); -} - -/* - * Another node wants us to stop a service so it can join or leave the SG. We - * do this by saving the request info in a uevent and having the sm thread do - * the processing and then replying. - */ - -static void process_stop_request(sm_msg_t *smsg, uint32_t nodeid, - uint32_t *msgbuf) -{ - sm_group_t *sg; - sm_uevent_t *uev; - sm_msg_t reply; - int type = smsg->ms_type; - - if (nodeid == sm_our_nodeid) - goto agree; - - sg = sm_global_id_to_sg(smsg->ms_global_sgid); - if (!sg) { - log_print("process_stop_request: unknown sg id %x", - smsg->ms_global_sgid); - return; - } - - /* - * We shouldn't get here with uevent already set. - */ - - if (test_and_set_bit(SGFL_UEVENT, &sg->flags)) { - log_error(sg, "process_stop_request: uevent already set"); - return; - } - - uev = &sg->uevent; - uev->ue_nodeid = nodeid; - uev->ue_remote_seid = smsg->ms_sevent_id; - uev->ue_state = (type == SMSG_JSTOP_REQ) ? UEST_JSTOP : UEST_LSTOP; - - if (type == SMSG_JSTOP_REQ) - uev->ue_num_nodes = be32_to_cpu(*msgbuf); - else - set_bit(UEFL_LEAVE, &uev->ue_flags); - - /* - * Do process_join_stop() or process_leave_stop(). - */ - - set_bit(UEFL_CHECK, &uev->ue_flags); - wake_serviced(DO_MEMBERSHIP); - return; - - agree: - reply.ms_status = STATUS_POS; - reply.ms_type = - (type == SMSG_JSTOP_REQ) ? SMSG_JSTOP_REP : SMSG_LSTOP_REP; - reply.ms_sevent_id = smsg->ms_sevent_id; - smsg_bswap_out(&reply); - send_nodeid_message((char *) &reply, sizeof(reply), nodeid); -} - -static void process_start_request(sm_msg_t *smsg, uint32_t nodeid) -{ - sm_group_t *sg; - sm_uevent_t *uev; - int type = smsg->ms_type; - - if (nodeid == sm_our_nodeid) - return; - - sg = sm_global_id_to_sg(smsg->ms_global_sgid); - if (!sg) { - log_print("process_start_request: unknown sg id %x", - smsg->ms_global_sgid); - return; - } - - if (!test_bit(SGFL_UEVENT, &sg->flags)) { - log_error(sg, "process_start_request: no uevent"); - return; - } - - uev = &sg->uevent; - - if (type == SMSG_JSTART_CMD) - uev->ue_state = UEST_JSTART; - else - uev->ue_state = UEST_LSTART; - - set_bit(UEFL_CHECK, &uev->ue_flags); - wake_serviced(DO_MEMBERSHIP); -} - -static void process_leave_request(sm_msg_t *smsg, uint32_t nodeid) -{ - sm_group_t *sg; - sm_node_t *node; - sm_msg_t reply; - sm_sevent_t *sev; - int found = FALSE; - - sg = sm_global_id_to_sg(smsg->ms_global_sgid); - if (sg) { - if (nodeid == sm_our_nodeid) - found = TRUE; - else { - list_for_each_entry(node, &sg->memb, list) { - if (node->id != nodeid) - continue; - set_bit(SNFL_LEAVING, &node->flags); - found = TRUE; - break; - } - } - } - - if (!found) { - reply.ms_type = SMSG_LEAVE_REP; - reply.ms_status = STATUS_NEG; - reply.ms_sevent_id = smsg->ms_sevent_id; - } else { - reply.ms_type = SMSG_LEAVE_REP; - reply.ms_status = STATUS_POS; - reply.ms_sevent_id = smsg->ms_sevent_id; - - if (sg->state == SGST_RECOVER) - reply.ms_status = STATUS_WAIT; - - else if (test_bit(SGFL_SEVENT, &sg->flags) && - nodeid != sm_our_nodeid) { - - /* not sure how/when this happens */ - if (!sg->sevent) { - log_print("process_leave_request from %d " - "sevent flag no struct", nodeid); - reply.ms_status = STATUS_NEG; - goto out; - } - - sev = sg->sevent; - - /* - * We're trying to join or leave at the moment. If - * we're past JOIN/LEAVE_ACKWAIT, we make the requestor - * wait. Otherwise, if joining we'll cancel to let the - * leave happen first, or if we're leaving allow the - * lower nodeid to leave first. - */ - - if (test_bit(SEFL_LEAVE, &sev->se_flags)) { - if (sev->se_state > SEST_LEAVE_ACKWAIT) - reply.ms_status = STATUS_WAIT; - else if (sm_our_nodeid < nodeid) - reply.ms_status = STATUS_WAIT; - else { - reply.ms_status = STATUS_POS; - clear_bit(SEFL_ALLOW_LEAVE, - &sev->se_flags); - set_bit(SEFL_CANCEL, &sev->se_flags); - } - } else { - if (sev->se_state > SEST_JOIN_ACKWAIT) - reply.ms_status = STATUS_WAIT; - else { - reply.ms_status = STATUS_NEG; - clear_bit(SEFL_ALLOW_JOIN, - &sev->se_flags); - set_bit(SEFL_CANCEL, &sev->se_flags); - } - } - - if (test_bit(SEFL_CANCEL, &sev->se_flags)) { - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } - } - - else if (test_bit(SGFL_UEVENT, &sg->flags)) { - if (sg->uevent.ue_nodeid != nodeid) - reply.ms_status = STATUS_WAIT; - } - - } - out: - smsg_bswap_out(&reply); - send_nodeid_message((char *) &reply, sizeof(reply), nodeid); -} - -/* - * Each remaining node will send us a done message. We quit when we get the - * first. The subsequent done messages for the finished sevent get here and - * are ignored. - */ - -static void process_lstart_done(sm_msg_t *smsg, uint32_t nodeid) -{ - sm_sevent_t *sev; - - sev = find_sevent(smsg->ms_sevent_id); - if (!sev) - return; - - if (sev->se_state != SEST_LSTART_WAITREMOTE) - return; - - sev->se_state = SEST_LSTART_REMOTEDONE; - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); -} - -/* - * This function and everything it calls always runs in sm context. - */ - -static void process_message(char *msg, uint32_t nodeid) -{ - sm_msg_t smsg; - - smsg_copy_in(msg, &smsg); - - switch (smsg.ms_type) { - case SMSG_JOIN_REQ: - process_join_request(&smsg, nodeid, msg + sizeof(sm_msg_t)); - break; - - case SMSG_JSTOP_REQ: - process_stop_request(&smsg, nodeid, - (uint32_t *) (msg + sizeof(sm_msg_t))); - break; - - case SMSG_LEAVE_REQ: - process_leave_request(&smsg, nodeid); - break; - - case SMSG_LSTOP_REQ: - process_stop_request(&smsg, nodeid, NULL); - break; - - case SMSG_JSTART_CMD: - case SMSG_LSTART_CMD: - process_start_request(&smsg, nodeid); - break; - - case SMSG_LSTART_DONE: - process_lstart_done(&smsg, nodeid); - break; - - case SMSG_JOIN_REP: - case SMSG_JSTOP_REP: - case SMSG_LEAVE_REP: - case SMSG_LSTOP_REP: - process_reply(&smsg, nodeid); - break; - - case SMSG_RECOVER: - process_recover_msg(&smsg, nodeid); - break; - - default: - log_print("process_message: unknown type %u nodeid %u", - smsg.ms_type, nodeid); - } -} - -/* - * Always called from sm context. - */ - -void process_messages(void) -{ - rq_entry_t *re; - - while (1) { - re = NULL; - - spin_lock(&message_lock); - if (!list_empty(&messages)) { - re = list_entry(messages.next, rq_entry_t, list); - list_del(&re->list); - } - spin_unlock(&message_lock); - - if (!re) - break; - - if (!re->msg) { - log_print("process_messages: NULL msg re %p len %d " - "nodeid %d", re, re->len, re->nodeid); - kfree(re); - continue; - } - - process_message(re->msg, re->nodeid); - kfree(re->msg); - kfree(re); - schedule(); - } -} - -/* - * Context: cnxman and sm - */ - -static int add_to_recvqueue(char *msg, int len, uint32_t nodeid) -{ - rq_entry_t *re; - - SM_RETRY(re = (rq_entry_t *) kmalloc(sizeof(rq_entry_t), GFP_KERNEL), - re); - SM_RETRY(re->msg = (char *) kmalloc(len, GFP_KERNEL), re->msg); - - memcpy(re->msg, msg, len); - re->len = len; - re->nodeid = nodeid; - - spin_lock(&message_lock); - list_add_tail(&re->list, &messages); - spin_unlock(&message_lock); - - wake_serviced(DO_MESSAGES); - return 0; -} - -/* - * Context: cnxman - * Called by cnxman when a service manager message arrives. - */ - -int sm_cluster_message(char *msg, int len, char *addr, int addr_len, - unsigned int node_id) -{ - if (!node_id) - return -EINVAL; - return add_to_recvqueue(msg, len, node_id); -} - -/* - * These send routines are used by sm and are always called from sm context. - */ - -int send_nodeid_message(char *msg, int len, uint32_t nodeid) -{ - int error = 0; - struct sockaddr_cl saddr; - - if (nodeid == sm_our_nodeid) { - add_to_recvqueue(msg, len, nodeid); - goto out; - } - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = CLUSTER_PORT_SERVICES; - saddr.scl_nodeid = nodeid; - error = kcl_sendmsg(sm_socket, msg, len, &saddr, sizeof(saddr), 0); - if (error > 0) - error = 0; - - if (error) - log_print("send_nodeid_message error %d to %u", error, nodeid); - out: - return error; -} - -int send_broadcast_message(char *msg, int len) -{ - int error; - - error = kcl_sendmsg(sm_socket, msg, len, NULL, 0, 0); - if (error > 0) - error = 0; - - add_to_recvqueue(msg, len, sm_our_nodeid); - - if (error) - log_print("send_broadcast_message error %d", error); - - return error; -} - -int send_members_message(sm_group_t *sg, char *msg, int len) -{ - sm_node_t *node; - int error = 0; - - list_for_each_entry(node, &sg->memb, list) { - error = send_nodeid_message(msg, len, node->id); - if (error < 0) - break; - } - return error; -} - -int send_members_message_sev(sm_group_t *sg, char *msg, int len, - sm_sevent_t * sev) -{ - int error; - sm_msg_t *smsg = (sm_msg_t *) msg; - - set_allowed_msgtype(sev, smsg->ms_type); - sev->se_reply_count = 0; - - error = send_members_message(sg, msg, len); - if (error < 0) - clear_allowed_msgtype(sev, smsg->ms_type); - - return error; -} - -int send_broadcast_message_sev(char *msg, int len, sm_sevent_t * sev) -{ - int error; - sm_msg_t *smsg = (sm_msg_t *) msg; - - set_allowed_msgtype(sev, smsg->ms_type); - sev->se_reply_count = 0; - - error = send_broadcast_message(msg, len); - if (error < 0) - clear_allowed_msgtype(sev, smsg->ms_type); - - return error; -} diff --git a/cman-kernel/src/sm_message.h b/cman-kernel/src/sm_message.h deleted file mode 100644 index 6f173a8..0000000 --- a/cman-kernel/src/sm_message.h +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_MESSAGE_DOT_H__ -#define __SM_MESSAGE_DOT_H__ - -void init_messages(void); -uint32_t sm_new_global_id(int level); -void smsg_bswap_out(sm_msg_t * smsg); -char *create_smsg(sm_group_t *sg, int type, int datalen, int *msglen, - sm_sevent_t *sev); -void process_messages(void); -int sm_cluster_message(char *msg, int len, char *addr, int addr_len, - unsigned int node_id); -int send_nodeid_message(char *msg, int len, uint32_t nodeid); -int send_broadcast_message(char *msg, int len); -int send_broadcast_message_sev(char *msg, int len, sm_sevent_t * sev); -int send_members_message(sm_group_t *sg, char *msg, int len); -int send_members_message_sev(sm_group_t *sg, char *msg, int len, - sm_sevent_t * sev); -int sm_cluster_message(char *msg, int len, char *addr, int addr_len, - unsigned int node_id); - -#endif diff --git a/cman-kernel/src/sm_misc.c b/cman-kernel/src/sm_misc.c deleted file mode 100644 index e7ce7a5..0000000 --- a/cman-kernel/src/sm_misc.c +++ /dev/null @@ -1,454 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" -#include "config.h" -#include <linux/seq_file.h> - -#define MAX_DEBUG_MSG_LEN (40) - -extern struct list_head sm_members; -static uint32_t local_ids; -static uint32_t event_id; -static spinlock_t event_id_lock; -static char * debug_buf; -static unsigned int debug_size; -static unsigned int debug_point; -static int debug_wrap; -static spinlock_t debug_lock; - - -void init_sm_misc(void) -{ - local_ids = 1; - event_id = 1; - spin_lock_init(&event_id_lock); - debug_buf = NULL; - debug_size = 0; - debug_point = 0; - debug_wrap = 0; - spin_lock_init(&debug_lock); - - sm_debug_setup(cman_config.sm_debug_size); -} - -sm_node_t *sm_new_node(uint32_t nodeid) -{ - struct kcl_cluster_node kclnode; - sm_node_t *node; - int error; - - error = kcl_get_node_by_nodeid(nodeid, &kclnode); - SM_ASSERT(!error, printk("error = %d, nodeid = %u\n", error, nodeid);); - - SM_RETRY(node = (sm_node_t *) kmalloc(sizeof(sm_node_t), GFP_KERNEL), - node); - - memset(node, 0, sizeof(sm_node_t)); - node->id = nodeid; - node->incarnation = kclnode.incarnation; - return node; -} - -sm_node_t *sm_find_joiner(sm_group_t *sg, uint32_t nodeid) -{ - sm_node_t *node; - - list_for_each_entry(node, &sg->joining, list) { - if (node->id == nodeid) - return node; - } - return NULL; -} - -sm_node_t *sm_find_member(uint32_t nodeid) -{ - sm_node_t *node; - - list_for_each_entry(node, &sm_members, list) { - if (node->id == nodeid) - return node; - } - log_print("sm_find_member %u failed", nodeid); - return NULL; -} - -uint32_t sm_new_local_id(int level) -{ - uint32_t id = local_ids++; - uint8_t l = (uint8_t) level; - - if (level > 0xFF) - return 0; - - if (id > 0x00FFFFFF) - return 0; - - id |= (l << 24); - return id; -} - -int sm_id_to_level(uint32_t id) -{ - uint8_t l = (id & 0xFF000000) >> 24; - - return (int) l; -} - -void sm_set_event_id(unsigned int *id) -{ - spin_lock(&event_id_lock); - *id = event_id++; - spin_unlock(&event_id_lock); -} - -sm_group_t *sm_local_id_to_sg(int id) -{ - sm_group_t *sg; - int level = sm_id_to_level(id); - int found = FALSE; - - down(&sm_sglock); - - list_for_each_entry(sg, &sm_sg[level], list) { - if (sg->local_id == id) { - found = TRUE; - break; - } - } - up(&sm_sglock); - if (!found) - sg = NULL; - return sg; -} - -sm_group_t *sm_global_id_to_sg(int id) -{ - sm_group_t *sg; - int level = sm_id_to_level(id); - int found = FALSE; - - down(&sm_sglock); - - list_for_each_entry(sg, &sm_sg[level], list) { - if (sg->global_id == id) { - found = TRUE; - break; - } - } - up(&sm_sglock); - if (!found) - sg = NULL; - return sg; -} - -void sm_debug_log(sm_group_t *sg, const char *fmt, ...) -{ - va_list va; - int i, n, size, len; - char buf[MAX_DEBUG_MSG_LEN+1]; - - spin_lock(&debug_lock); - - if (!debug_buf) - goto out; - - size = MAX_DEBUG_MSG_LEN; - memset(buf, 0, size+1); - - n = snprintf(buf, size, "%08x ", sg->global_id); - size -= n; - - va_start(va, fmt); - vsnprintf(buf+n, size, fmt, va); - va_end(va); - - len = strlen(buf); - if (len > MAX_DEBUG_MSG_LEN-1) - len = MAX_DEBUG_MSG_LEN-1; - buf[len] = '\n'; - buf[len+1] = '\0'; - - for (i = 0; i < strlen(buf); i++) { - debug_buf[debug_point++] = buf[i]; - - if (debug_point == debug_size) { - debug_point = 0; - debug_wrap = 1; - } - } - out: - spin_unlock(&debug_lock); -} - -void sm_debug_setup(int size) -{ - char *b = kmalloc(size, GFP_KERNEL); - - spin_lock(&debug_lock); - if (debug_buf) - kfree(debug_buf); - - if (size > PAGE_SIZE) - size = PAGE_SIZE; - debug_size = size; - debug_point = 0; - debug_wrap = 0; - debug_buf = b; - memset(debug_buf, 0, debug_size); - spin_unlock(&debug_lock); -} - -#ifdef CONFIG_PROC_FS -static struct seq_operations sm_info_op; - -struct sm_seq_info -{ - int pos; - int level; - sm_group_t *sg; -}; - -int sm_debug_info(char *b, char **start, off_t offset, int length) -{ - int i, n = 0; - - spin_lock(&debug_lock); - - if (debug_wrap) { - for (i = debug_point; i < debug_size; i++) - n += sprintf(b + n, "%c", debug_buf[i]); - } - for (i = 0; i < debug_point; i++) - n += sprintf(b + n, "%c", debug_buf[i]); - - spin_unlock(&debug_lock); - - return n; -} - - - -static sm_group_t *sm_walk(loff_t offset, int *rlevel) -{ - sm_group_t *sg; - int level; - loff_t n = 0; - - down(&sm_sglock); - - for (level = 0; level < SG_LEVELS; level++) { - list_for_each_entry(sg, &sm_sg[level], list) { - if (++n == offset) - goto walk_finish; - } - } - sg = NULL; - - walk_finish: - up(&sm_sglock); - *rlevel = level; - - return sg; -} - - -static void *sm_seq_start(struct seq_file *m, loff_t * pos) -{ - struct sm_seq_info *ssi; - - if (!m->private) { - ssi=kmalloc(sizeof (struct sm_seq_info), GFP_KERNEL); - m->private = ssi; - if (!ssi) - return NULL; - } - else - ssi = m->private; - - ssi->pos = *pos; - ssi->level = 0; - ssi->sg = NULL; - - /* Print the header */ - if (*pos == 0) { - seq_printf(m, - "Service Name GID LID State Code\n"); - } - else - ssi->sg = sm_walk(ssi->pos, &ssi->level); - - return ssi; -} - -static void *sm_seq_next(struct seq_file *m, void *p, loff_t * pos) -{ - struct sm_seq_info *ssi = p; - - *pos = ++ssi->pos; - - if ( !(ssi->sg = sm_walk(ssi->pos, &ssi->level)) ) - return NULL; - - return ssi; -} - -/* Called from /proc when /proc/cluster/services is opened */ -int sm_proc_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &sm_info_op); -} - -static int sm_seq_show(struct seq_file *s, void *p) -{ - struct sm_seq_info *ssi = p; - sm_node_t *node; - int i; - - if (!ssi || !ssi->sg) - return 0; - - /* - * Cluster Service - */ - - switch (ssi->level) { - case SERVICE_LEVEL_FENCE: - seq_printf(s, "Fence Domain: "); - break; - case SERVICE_LEVEL_GDLM: - seq_printf(s, "DLM Lock Space: "); - break; - case SERVICE_LEVEL_GFS: - seq_printf(s, "GFS Mount Group: "); - break; - case SERVICE_LEVEL_USER: - seq_printf(s, "User: "); - break; - } - - /* - * Name - */ - - seq_printf(s, """); - for (i = 0; i < ssi->sg->namelen; i++) - seq_printf(s, "%c", ssi->sg->name[i]); - seq_printf(s, """); - - for (; i < MAX_SERVICE_NAME_LEN-1; i++) - seq_printf(s, " "); - - /* - * GID LID (sans level from top byte) - */ - - seq_printf(s, "%3u %3u ", - (ssi->sg->global_id & 0x00FFFFFF), - (ssi->sg->local_id & 0x00FFFFFF)); - - /* - * State - */ - - switch (ssi->sg->state) { - case SGST_NONE: - seq_printf(s, "none "); - break; - case SGST_JOIN: - seq_printf(s, "join "); - break; - case SGST_RUN: - seq_printf(s, "run "); - break; - case SGST_RECOVER: - seq_printf(s, "recover %u ", - ssi->sg->recover_state); - break; - case SGST_UEVENT: - seq_printf(s, "update "); - break; - } - - /* - * Code - */ - - if (test_bit(SGFL_SEVENT, &ssi->sg->flags)) - seq_printf(s, "S"); - if (test_bit(SGFL_UEVENT, &ssi->sg->flags)) - seq_printf(s, "U"); - if (test_bit(SGFL_NEED_RECOVERY, &ssi->sg->flags)) - seq_printf(s, "N"); - - seq_printf(s, "-"); - - if (test_bit(SGFL_SEVENT, &ssi->sg->flags) - && ssi->sg->sevent) { - seq_printf(s, "%u,%lx,%u", - ssi->sg->sevent->se_state, - ssi->sg->sevent->se_flags, - ssi->sg->sevent->se_reply_count); - } - - if (test_bit(SGFL_UEVENT, &ssi->sg->flags)) { - seq_printf(s, "%u,%lx,%u", - ssi->sg->uevent.ue_state, - ssi->sg->uevent.ue_flags, - ssi->sg->uevent.ue_nodeid); - } - - seq_printf(s, "\n"); - - /* - * node list - */ - - i = 0; - - seq_printf(s, "["); - - list_for_each_entry(node, &ssi->sg->memb, list) { - if (i && !(i % 24)) - seq_printf(s, "\n"); - - if (i) - seq_printf(s, " "); - - seq_printf(s, "%u", node->id); - i++; - } - - seq_printf(s, "]\n\n"); - - return 0; -} - -static void sm_seq_stop(struct seq_file *m, void *p) -{ - if (m->private) { - kfree(m->private); - m->private = NULL; - } -} - - -static struct seq_operations sm_info_op = { - .start = sm_seq_start, - .next = sm_seq_next, - .stop = sm_seq_stop, - .show = sm_seq_show -}; - - -#endif diff --git a/cman-kernel/src/sm_misc.h b/cman-kernel/src/sm_misc.h deleted file mode 100644 index 399bc59..0000000 --- a/cman-kernel/src/sm_misc.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_MISC_DOT_H__ -#define __SM_MISC_DOT_H__ - -void init_sm_misc(void); -sm_node_t *sm_new_node(uint32_t nodeid); -sm_node_t *sm_find_joiner(sm_group_t *sg, uint32_t nodeid); -sm_node_t *sm_find_member(uint32_t nodeid); -uint32_t sm_new_local_id(int level); -int sm_id_to_level(uint32_t id); -void sm_set_event_id(unsigned int *id); -sm_group_t *sm_local_id_to_sg(int id); -sm_group_t *sm_global_id_to_sg(int id); -void sm_debug_log(sm_group_t *sg, const char *fmt, ...); -void sm_debug_setup(int size); - -#endif diff --git a/cman-kernel/src/sm_recover.c b/cman-kernel/src/sm_recover.c deleted file mode 100644 index e379dfd..0000000 --- a/cman-kernel/src/sm_recover.c +++ /dev/null @@ -1,577 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" -#include "config.h" - -/* - * A collection of sg's which need to be recovered due to a failed member. - * These sg's are recovered in order of level. An sg subject to cascading - * failures is moved from one of these structs to a newer one. - */ - -/* - * There is a bug in the way SM manages multiple recovery events. - * A specific arrangement would be required to see this: - * - * - nodes A,B,C,D,E are in the cluster - * - nodes A,B,C,D,E are in the fence domain (FD) - * - A,B,C are using gfs X - * - C,D,E are using gfs Y - * - * The bug is possible on node C if A fails creating a - * recovery event for X (rev1), and just after that D fails - * creating a recovery event for Y (rev2). If the two nodes - * fail at once there won't be a problem because a single - * recovery event will be created. The timing of the - * consecutive failures would need to be just right. - * - * The problem arises when the group representing the - * fence domain (FD) is moved from rev1 into rev2. This - * makes the groups in rev2 depend on FD recovery, but - * removes the dependecy of rev1 groups on FD recovery. - * In actual fact, both rev1 and rev2 groups depend on - * FD recovery, but the code has no way right now to - * make two rev's depend on the same group. - * - * When the FD dependency is removed from rev1, recovery - * for the higher level groups in rev1 (which are the dlm - * and gfs groups for X) goes ahead without waiting for - * FD recovery to finish. - * - * Both A and D will still be fenced, and given how recovery - * works it's likely to happen before gfs recovery on X - * begins. But, if gfs-X recovery happens to start before - * A is fenced, and A isn't really dead and comes back to - * life and writes to X, then X could be corrupted. If - * manual fencing is used, then it becomes very likely that - * recovery for gfs-X happens before A is fenced, and you - * have to hope A won't come back to life and write to X. - */ - -struct recover { - struct list_head list; /* list of current re's */ - struct list_head sgs[SG_LEVELS]; /* lists of sg's by level */ - int event_id; /* event id */ - int cur_level; -}; -typedef struct recover recover_t; - - -extern uint32_t * sm_new_nodeids; -extern int sm_quorum, sm_quorum_next; -extern uint32_t sm_our_nodeid; -extern struct list_head sm_members; -extern int sm_member_count; -static struct list_head recoveries; - - -void init_recovery(void) -{ - INIT_LIST_HEAD(&recoveries); -} - -int no_recoveries(void) -{ - if (list_empty(&recoveries)) - return TRUE; - return FALSE; -} - -/* - * This is the first thing called when a change is announced in cluster - * membership. Nodes are marked as being a CLUSTER_MEMBER or not. SM adds new - * nodes to its sm_members list which it's not seen before. Nodes which were - * alive but are now gone are marked as "need recovery". - * - * The "need recovery" status of nodes is propagated to the node's SG's in - * mark_effected_sgs. The effected SG's are themselves marked as needing - * recovery and in new_recovery the dead nodes are removed from the SG's - * individual member lists. The "need recovery" status of nodes is cleared in - * adjust_members_done(). - */ - -static int adjust_members(void) -{ - sm_node_t *node; - struct kcl_cluster_node knode; - int i, error, num_nodes, sub = 0, add = 0, found; - - /* - * Get list of current members from cnxman - */ - - memset(sm_new_nodeids, 0, cman_config.max_nodes * sizeof(uint32_t)); - num_nodes = kcl_get_member_ids(sm_new_nodeids, cman_config.max_nodes); - - /* - * Determine who's gone - */ - - list_for_each_entry(node, &sm_members, list) { - found = FALSE; - for (i = 0; i < num_nodes; i++) { - if (node->id == sm_new_nodeids[i]) { - found = TRUE; - sm_new_nodeids[i] = 0; - break; - } - } - - if (found) { - error = kcl_get_node_by_nodeid(node->id, &knode); - SM_ASSERT(!error, printk("error=%d\n", error);); - - if (!test_bit(SNFL_CLUSTER_MEMBER, &node->flags)) { - /* former member is back */ - set_bit(SNFL_CLUSTER_MEMBER, &node->flags); - node->incarnation = knode.incarnation; - add++; - } else { - /* current member is still alive - if the - * incarnation number is different it died and - * returned between checks */ - if (node->incarnation != knode.incarnation) { - set_bit(SNFL_NEED_RECOVERY, - &node->flags); - node->incarnation = knode.incarnation; - sub++; - } - } - } else { - /* current member has died */ - if (test_and_clear_bit(SNFL_CLUSTER_MEMBER, - &node->flags)) { - set_bit(SNFL_NEED_RECOVERY, &node->flags); - sub++; - } - } - } - - /* - * Look for new nodes - */ - - for (i = 0; i < num_nodes; i++) { - if (sm_new_nodeids[i]) { - node = sm_new_node(sm_new_nodeids[i]); - set_bit(SNFL_CLUSTER_MEMBER, &node->flags); - add++; - list_add_tail(&node->list, &sm_members); - sm_member_count++; - } - } - - /* - * Get our own nodeid - */ - - if (!sm_our_nodeid) { - list_for_each_entry(node, &sm_members, list) { - error = kcl_get_node_by_nodeid(node->id, &knode); - SM_ASSERT(!error, printk("error=%d\n", error);); - - if (knode.us) { - sm_our_nodeid = knode.node_id; - break; - } - } - } - - return sub; -} - -/* - * Given some number of dead nodes, flag SG's the dead nodes were part of. - * This requires a number of loops because each node structure does not keep a - * list of SG's it's in. - */ - -static int mark_effected_sgs(void) -{ - sm_group_t *sg; - sm_node_t *node, *sgnode; - uint32_t dead_id; - int i, effected = 0; - - down(&sm_sglock); - - list_for_each_entry(node, &sm_members, list) { - if (!test_bit(SNFL_NEED_RECOVERY, &node->flags)) - continue; - - dead_id = node->id; - - for (i = 0; i < SG_LEVELS; i++) { - list_for_each_entry(sg, &sm_sg[i], list) { - /* check if dead node is among sg's members */ - list_for_each_entry(sgnode, &sg->memb, list) { - if (sgnode->id == dead_id) { - set_bit(SGFL_NEED_RECOVERY, - &sg->flags); - effected++; - break; - } - } - schedule(); - } - } - schedule(); - } - up(&sm_sglock); - - return effected; -} - -static recover_t *alloc_recover(void) -{ - recover_t *rev; - int i; - - SM_RETRY(rev = kmalloc(sizeof(recover_t), GFP_KERNEL), rev); - - memset(rev, 0, sizeof(recover_t)); - - sm_set_event_id(&rev->event_id); - - for (i = 0; i < SG_LEVELS; i++) { - INIT_LIST_HEAD(&rev->sgs[i]); - } - - return rev; -} - -/* - * An in-progress revent re-start for an SG is interrupted by another node - * failure in the SG. Cancel an outstanding barrier if there is one. The SG - * will be moved to the new revent and re-started as part of that. - */ - -static void cancel_prev_recovery(sm_group_t *sg) -{ - int error; - - if (sg->recover_state == RECOVER_BARRIERWAIT) { - error = kcl_barrier_cancel(sg->recover_barrier); - if (error) - log_error(sg, "cancel_prev_recovery: error %d", error); - } -} - -static void pre_recover_sg(sm_group_t *sg, recover_t *rev) -{ - if (sg->state == SGST_RECOVER) { - cancel_prev_recovery(sg); - list_del(&sg->recover_list); - } - - sg->ops->stop(sg->service_data); - sg->state = SGST_RECOVER; - sg->recover_state = RECOVER_NONE; - sg->recover_data = rev; - list_add(&sg->recover_list, &rev->sgs[sg->level]); -} - -/* - * When adjust_members finds that some nodes are dead and mark_effected_sgs - * finds that some SG's are effected by departed nodes, this is called to - * collect together the SG's which need to be recovered. An revent (recovery - * event) is the group of effected SG's. - */ - -static int new_recovery(void) -{ - sm_group_t *sg; - recover_t *rev; - sm_node_t *node, *sgnode, *safe; - int i; - - rev = alloc_recover(); - list_add_tail(&rev->list, &recoveries); - - down(&sm_sglock); - - /* - * Stop effected SG's and add them to the rev - */ - - for (i = 0; i < SG_LEVELS; i++) { - list_for_each_entry(sg, &sm_sg[i], list) { - if (test_and_clear_bit(SGFL_NEED_RECOVERY, &sg->flags)){ - if (sg->state == SGST_JOIN) - continue; - pre_recover_sg(sg, rev); - } - } - schedule(); - } - - /* - * For an SG needing recovery, remove dead nodes from sg->memb list - */ - - for (i = 0; i < SG_LEVELS; i++) { - list_for_each_entry(sg, &rev->sgs[i], recover_list) { - - /* Remove dead members from SG's member list */ - list_for_each_entry_safe(sgnode, safe, &sg->memb, list){ - - node = sm_find_member(sgnode->id); - SM_ASSERT(node, printk("id %u\n", sgnode->id);); - - if (test_bit(SNFL_NEED_RECOVERY, &node->flags)){ - list_del(&sgnode->list); - sg->memb_count--; - log_debug(sg, "remove node %u count %d", - sgnode->id, sg->memb_count); - kfree(sgnode); - } - schedule(); - } - schedule(); - } - } - - up(&sm_sglock); - rev->cur_level = 0; - return 0; -} - -/* - * The NEED_RECOVERY bit on MML nodes is set in adjust_members() and is used in - * mark_effected_sgs() and add_revent(). After that, we're done using the bit - * and we clear it here. - */ - -static void adjust_members_done(void) -{ - sm_node_t *node; - - list_for_each_entry(node, &sm_members, list) - clear_bit(SNFL_NEED_RECOVERY, &node->flags); -} - -/* - * Start the service of the given SG. The service must be given an array of - * nodeids specifying the new sg membership. The service is responsible to - * free this chunk of memory when done with it. - */ - -static void start_sg(sm_group_t *sg, uint32_t event_id) -{ - sm_node_t *node; - uint32_t *memb; - int count = 0; - - SM_RETRY(memb = kmalloc(sg->memb_count * sizeof(uint32_t), GFP_KERNEL), - memb); - - list_for_each_entry(node, &sg->memb, list) - memb[count++] = node->id; - - sg->ops->start(sg->service_data, memb, count, event_id, - SERVICE_NODE_FAILED); -} - -static void recovery_barrier(sm_group_t *sg) -{ - char bname[MAX_BARRIER_NAME_LEN]; - int error, len; - - memset(bname, 0, MAX_BARRIER_NAME_LEN); - - /* bypass the barrier if we're the only member */ - if (sg->memb_count == 1) { - process_recovery_barrier(sg, 0); - return; - } - - len = snprintf(bname, MAX_BARRIER_NAME_LEN, "sm.%u.%u.RECOV.%u", - sg->global_id, sg->recover_stop, sg->memb_count); - - /* We save this barrier name so we can cancel it if needed. */ - memset(sg->recover_barrier, 0, MAX_BARRIER_NAME_LEN); - memcpy(sg->recover_barrier, bname, len); - - error = sm_barrier(bname, sg->memb_count, SM_BARRIER_RECOVERY); - if (error) - log_error(sg, "recovery_barrier error %d: %s", error, bname); -} - -static void recover_sg(sm_group_t *sg, int event_id) -{ - log_debug(sg, "recover state %d", sg->recover_state); - - switch (sg->recover_state) { - - case RECOVER_NONE: - /* must wait for recovery to stop sg on all nodes */ - sg->recover_state = RECOVER_BARRIERWAIT; - sg->recover_stop = 0; - recovery_barrier(sg); - break; - - case RECOVER_BARRIERWAIT: - break; - - case RECOVER_STOP: - /* barrier callback sets state STOP */ - sg->recover_stop = 1; - sg->recover_state = RECOVER_START; - start_sg(sg, event_id); - break; - - case RECOVER_START: - break; - - case RECOVER_STARTDONE: - /* service callback sets state STARTDONE */ - sg->recover_state = RECOVER_BARRIERWAIT; - recovery_barrier(sg); - break; - - case RECOVER_BARRIERDONE: - /* barrier callback sets state BARRIERDONE */ - sg->ops->finish(sg->service_data, event_id); - list_del(&sg->recover_list); - sg->recover_state = RECOVER_NONE; - sg->state = SGST_RUN; - - /* Continue a previous, interrupted attempt to leave the sg */ - if (sg->sevent) { - sm_sevent_t *sev = sg->sevent; - log_debug(sg, "restart leave %lx", sev->se_flags); - clear_bit(SEFL_DELAY_RECOVERY, &sev->se_flags); - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } - break; - - default: - log_error(sg, "invalid recover_state %u", sg->recover_state); - } -} - -static void recover_level(recover_t *rev, int level) -{ - sm_group_t *sg, *safe; - - list_for_each_entry_safe(sg, safe, &rev->sgs[level], recover_list) { - recover_sg(sg, rev->event_id); - schedule(); - } -} - -static void recover_levels(recover_t *rev) -{ - for (;;) { - recover_level(rev, rev->cur_level); - - if (list_empty(&rev->sgs[rev->cur_level])) { - if (rev->cur_level == SG_LEVELS - 1) { - list_del(&rev->list); - kfree(rev); - return; - } - rev->cur_level++; - continue; - } - break; - } -} - -/* - * Called by SM thread when the cluster is quorate. It restarts - * SG's that were stopped in new_recovery() due to a member death. - * It waits for all SG's at level N to complete restart before - * restarting SG's at level N+1. - */ - -void process_recoveries(void) -{ - recover_t *rev, *safe; - - down(&sm_sglock); - list_for_each_entry_safe(rev, safe, &recoveries, list) - recover_levels(rev); - up(&sm_sglock); -} - -/* - * The cnxman membership has changed. Check if there's still quorum and - * whether any nodes have died. If nodes have died, initiate recovery on any - * SG's they were in. This begins immediately if the cluster remains quorate; - * if not this waits until the cluster regains quorum. - */ - -void process_nodechange(void) -{ - int gone, effected; - - if ((sm_quorum = sm_quorum_next)) - wake_serviced(DO_RUN); - - gone = adjust_members(); - if (gone > 0) { - effected = mark_effected_sgs(); - - backout_sevents(); - cancel_uevents(&effected); - - if (effected > 0) { - new_recovery(); - wake_serviced(DO_RECOVERIES); - } - } - adjust_members_done(); -} - -int check_recovery(sm_group_t *sg, int event_id) -{ - if (sg->state == SGST_RECOVER) { - recover_t *rev = (recover_t *) sg->recover_data; - if (rev && rev->event_id == event_id) - return 1; - } - return 0; -} - -void process_recover_msg(sm_msg_t *smsg, uint32_t nodeid) -{ - sm_group_t *sg; - recover_t *rev; - - sg = sm_global_id_to_sg(smsg->ms_global_sgid); - if (!sg) { - log_print("process_recover_msg: unknown sg id %x", - smsg->ms_global_sgid); - return; - } - - /* we already know about the recovery and can ignore the msg */ - if (sg->state == SGST_RECOVER) - return; - - if (test_bit(SGFL_UEVENT, &sg->flags)) { - /* we will initiate recovery on our own if we know about the - uevent so we can ignore this */ - log_debug(sg, "process_recover_msg: ignore from %u", nodeid); - return; - } - - log_debug(sg, "recovery initiated by msg from %u", nodeid); - rev = alloc_recover(); - list_add_tail(&rev->list, &recoveries); - pre_recover_sg(sg, rev); - wake_serviced(DO_RECOVERIES); -} diff --git a/cman-kernel/src/sm_recover.h b/cman-kernel/src/sm_recover.h deleted file mode 100644 index dd3f1f0..0000000 --- a/cman-kernel/src/sm_recover.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_RECOVER_DOT_H__ -#define __SM_RECOVER_DOT_H__ - -void init_recovery(void); -void process_recoveries(void); -void process_nodechange(void); -int check_recovery(sm_group_t *sg, int event_id); -void process_recover_msg(sm_msg_t *smsg, uint32_t nodeid); -int no_recoveries(void); - -#endif diff --git a/cman-kernel/src/sm_services.c b/cman-kernel/src/sm_services.c deleted file mode 100644 index 86ac5e2..0000000 --- a/cman-kernel/src/sm_services.c +++ /dev/null @@ -1,420 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" - -static struct list_head callbacks; -static spinlock_t callback_lock; -static struct list_head sg_registered[SG_LEVELS]; - -/* - * These are the functions to register, join, leave, unregister, callback - * with/to the sm. - */ - -struct sc_entry { - struct list_head list; - uint32_t local_id; - int event_id; -}; -typedef struct sc_entry sc_entry_t; - -void init_services(void) -{ - int i; - - INIT_LIST_HEAD(&callbacks); - spin_lock_init(&callback_lock); - - for (i = 0; i < SG_LEVELS; i++) { - INIT_LIST_HEAD(&sm_sg[i]); - INIT_LIST_HEAD(&sg_registered[i]); - } - init_MUTEX(&sm_sglock); -} - -/* Context: service */ - -int kcl_register_service(char *name, int namelen, int level, - struct kcl_service_ops *ops, int unique, - void *servicedata, uint32_t *service_id) -{ - sm_group_t *sg; - int found = FALSE; - int error = -EINVAL; - - if (level > SG_LEVELS - 1) - goto fail; - - if (namelen > MAX_SERVICE_NAME_LEN) - goto fail; - - error = kcl_addref_cluster(); - if (error) - goto fail; - - down(&sm_sglock); - - list_for_each_entry(sg, &sm_sg[level], list) { - if ((sg->namelen == namelen) && - (!strncmp(sg->name, name, namelen))) { - found = TRUE; - goto next; - } - } - - list_for_each_entry(sg, &sg_registered[level], list) { - if ((sg->namelen == namelen) && - (!strncmp(sg->name, name, namelen))) { - found = TRUE; - goto next; - } - } - - next: - - if (found && unique) { - error = -EEXIST; - goto fail_unlock; - } - - if (found) { - sg->refcount++; - goto out; - } - - sg = (sm_group_t *) kmalloc(sizeof(sm_group_t) + namelen, GFP_KERNEL); - if (!sg) { - error = -ENOMEM; - goto fail_unlock; - } - memset(sg, 0, sizeof(sm_group_t) + namelen); - - sg->refcount = 1; - sg->service_data = servicedata; - sg->ops = ops; - sg->level = level; - sg->namelen = namelen; - memcpy(sg->name, name, namelen); - sg->local_id = sm_new_local_id(level); - sg->state = SGST_NONE; - INIT_LIST_HEAD(&sg->memb); - INIT_LIST_HEAD(&sg->joining); - init_completion(&sg->event_comp); - - list_add_tail(&sg->list, &sg_registered[level]); - - out: - *service_id = sg->local_id; - up(&sm_sglock); - return 0; - - fail_unlock: - up(&sm_sglock); - kcl_releaseref_cluster(); - fail: - return error; -} - -/* Context: service */ - -void kcl_unregister_service(uint32_t local_id) -{ - sm_group_t *sg; - int level = sm_id_to_level(local_id); - - down(&sm_sglock); - - list_for_each_entry(sg, &sg_registered[level], list) { - if (sg->local_id == local_id) { - SM_ASSERT(sg->refcount,); - sg->refcount--; - - if (!sg->refcount) { - list_del(&sg->list); - kfree(sg); - } - kcl_releaseref_cluster(); - break; - } - } - up(&sm_sglock); -} - -/* Context: service */ - -int kcl_join_service(uint32_t local_id) -{ - sm_group_t *sg; - sm_sevent_t *sev; - int level = sm_id_to_level(local_id); - int error, found = FALSE; - - down(&sm_sglock); - - list_for_each_entry(sg, &sg_registered[level], list) { - if (sg->local_id == local_id) { - found = TRUE; - break; - } - } - - if (!found) { - up(&sm_sglock); - error = -ENOENT; - goto out; - } - - if (sg->state != SGST_NONE) { - up(&sm_sglock); - error = -EINVAL; - goto out; - } - - sev = kmalloc(sizeof(sm_sevent_t), GFP_KERNEL); - if (!sev) { - up(&sm_sglock); - error = -ENOMEM; - goto out; - } - - memset(sev, 0, sizeof (sm_sevent_t)); - sev->se_state = SEST_JOIN_BEGIN; - sm_set_event_id(&sev->se_id); - sev->se_sg = sg; - sg->sevent = sev; - sg->state = SGST_JOIN; - set_bit(SGFL_SEVENT, &sg->flags); - list_del(&sg->list); - list_add_tail(&sg->list, &sm_sg[sg->level]); - - up(&sm_sglock); - - /* - * The join is a service event which will be processed asynchronously. - */ - - new_joinleave(sev); - wait_for_completion(&sg->event_comp); - error = 0; - - out: - return error; -} - -/* Context: service */ - -int kcl_leave_service(uint32_t local_id) -{ - sm_group_t *sg = NULL; - sm_sevent_t *sev; - int error; - - error = -ENOENT; - sg = sm_local_id_to_sg(local_id); - if (!sg) - goto out; - - /* sg was never joined */ - error = -EINVAL; - if (sg->state == SGST_NONE) - goto out; - - down(&sm_sglock); - - /* may still be joining */ - if (test_and_set_bit(SGFL_SEVENT, &sg->flags)) { - up(&sm_sglock); - error = -EBUSY; - goto out; - } - - sev = kmalloc(sizeof(sm_sevent_t), GFP_KERNEL); - if (!sev) { - up(&sm_sglock); - error = -ENOMEM; - goto out; - } - - memset(sev, 0, sizeof (sm_sevent_t)); - sev->se_state = SEST_LEAVE_BEGIN; - sm_set_event_id(&sev->se_id); - set_bit(SEFL_LEAVE, &sev->se_flags); - sev->se_sg = sg; - sg->sevent = sev; - - up(&sm_sglock); - - new_joinleave(sev); - wait_for_completion(&sg->event_comp); - error = 0; - - down(&sm_sglock); - list_del(&sg->list); - list_add_tail(&sg->list, &sg_registered[sg->level]); - up(&sm_sglock); - - out: - return error; -} - -static void process_callback(uint32_t local_id, unsigned int event_id) -{ - sm_group_t *sg; - sm_sevent_t *sev; - sm_uevent_t *uev; - - sg = sm_local_id_to_sg(local_id); - if (!sg) - return; - - if (sg->state == SGST_RECOVER) { - if (!check_recovery(sg, event_id)) { - log_error(sg, "process_callback invalid recover " - "event id %d", event_id); - return; - } - - log_debug(sg, "cb recover state %u", sg->recover_state); - - if (sg->recover_state == RECOVER_START) - sg->recover_state = RECOVER_STARTDONE; - else - log_error(sg, "process_callback recover state %u", - sg->recover_state); - wake_serviced(DO_RECOVERIES); - } - - else if (test_bit(SGFL_SEVENT, &sg->flags) && sg->sevent && - (sg->sevent->se_id == event_id)) { - sev = sg->sevent; - - if (test_and_clear_bit(SEFL_ALLOW_STARTDONE, &sev->se_flags) && - (sev->se_state == SEST_JSTART_SERVICEWAIT)) - sev->se_state = SEST_JSTART_SERVICEDONE; - - set_bit(SEFL_CHECK, &sev->se_flags); - wake_serviced(DO_JOINLEAVE); - } - - else if (test_bit(SGFL_UEVENT, &sg->flags) && - (sg->uevent.ue_id == event_id)) { - uev = &sg->uevent; - - if (test_and_clear_bit(UEFL_ALLOW_STARTDONE, &uev->ue_flags)) { - if (uev->ue_state == UEST_JSTART_SERVICEWAIT) - uev->ue_state = UEST_JSTART_SERVICEDONE; - else if (uev->ue_state == UEST_LSTART_SERVICEWAIT) - uev->ue_state = UEST_LSTART_SERVICEDONE; - } - set_bit(UEFL_CHECK, &uev->ue_flags); - wake_serviced(DO_MEMBERSHIP); - } - - else - log_error(sg, "ignoring service callback id=%x event=%u", - local_id, event_id); -} - -void process_callbacks(void) -{ - sc_entry_t *se; - - while (1) { - se = NULL; - - spin_lock(&callback_lock); - if (!list_empty(&callbacks)) { - se = list_entry(callbacks.next, sc_entry_t, list); - list_del(&se->list); - } - spin_unlock(&callback_lock); - - if (!se) - break; - process_callback(se->local_id, se->event_id); - kfree(se); - schedule(); - } -} - -/* Context: service */ - -void kcl_start_done(uint32_t local_id, int event_id) -{ - sc_entry_t *se; - - SM_RETRY(se = kmalloc(sizeof(sc_entry_t), GFP_KERNEL), se); - - se->local_id = local_id; - se->event_id = event_id; - - spin_lock(&callback_lock); - list_add_tail(&se->list, &callbacks); - spin_unlock(&callback_lock); - - wake_serviced(DO_CALLBACKS); -} - -/* Context: service */ - -void kcl_global_service_id(uint32_t local_id, uint32_t *global_id) -{ - sm_group_t *sg = sm_local_id_to_sg(local_id); - - if (!sg) - log_print("kcl_global_service_id: can't find %x", local_id); - else - *global_id = sg->global_id; -} - -static void copy_to_service(sm_group_t *sg, struct kcl_service *s) -{ - s->level = sg->level; - s->local_id = sg->local_id; - s->global_id = sg->global_id; - s->node_count = sg->memb_count; - strcpy(s->name, sg->name); -} - -int kcl_get_services(struct list_head *head, int level) -{ - sm_group_t *sg; - struct kcl_service *s; - int error = -ENOMEM, count = 0; - - down(&sm_sglock); - - list_for_each_entry(sg, &sm_sg[level], list) { - if (test_bit(SGFL_SEVENT, &sg->flags)) - continue; - if (head) { - - s = kmalloc(sizeof(struct kcl_service), GFP_KERNEL); - if (!s) - goto out; - copy_to_service(sg, s); - list_add(&s->list, head); - } - count++; - } - - error = count; - out: - up(&sm_sglock); - return error; -} - -/* These three global variables listed in extern form in sm.h. */ -struct list_head sm_sg[SG_LEVELS]; -struct semaphore sm_sglock; diff --git a/cman-kernel/src/sm_services.h b/cman-kernel/src/sm_services.h deleted file mode 100644 index ed8dc7c..0000000 --- a/cman-kernel/src/sm_services.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_SERVICES_DOT_H__ -#define __SM_SERVICES_DOT_H__ - -void init_services(void); -void process_callbacks(void); - -#endif diff --git a/cman-kernel/src/sm_user.c b/cman-kernel/src/sm_user.c deleted file mode 100644 index 4ae5d77..0000000 --- a/cman-kernel/src/sm_user.c +++ /dev/null @@ -1,569 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "sm.h" -#include "cnxman-private.h" - -void copy_to_usernode(struct cluster_node *node, struct cl_cluster_node *unode); - -#define UST_REGISTER 1 -#define UST_UNREGISTER 2 -#define UST_JOIN 3 -#define UST_LEAVE 4 -#define UST_JOINED 5 - -struct event { - struct list_head list; - service_event_t type; - service_start_t start_type; - unsigned int event_id; - unsigned int last_stop; - unsigned int last_start; - unsigned int last_finish; - unsigned int node_count; - uint32_t * nodeids; -}; -typedef struct event event_t; - -struct user_service { - uint32_t local_id; - pid_t pid; - int signal; - struct socket * sock; - uint8_t state; - uint8_t async; - struct semaphore lock; - struct list_head events; - spinlock_t event_lock; - unsigned int last_stop; - unsigned int last_start; - unsigned int last_finish; - unsigned int need_startdone; - unsigned int node_count; - uint32_t * nodeids; - int name_len; - char name[MAX_SERVICE_NAME_LEN]; -}; -typedef struct user_service user_service_t; - - -static void add_event(user_service_t *us, event_t *ev) -{ - spin_lock(&us->event_lock); - list_add_tail(&ev->list, &us->events); - - switch(ev->type) { - case SERVICE_EVENT_STOP: - us->last_stop = us->last_start; - break; - case SERVICE_EVENT_START: - us->last_start = ev->event_id; - break; - case SERVICE_EVENT_FINISH: - us->last_finish = ev->event_id; - break; - case SERVICE_EVENT_LEAVEDONE: - break; - } - spin_unlock(&us->event_lock); -} - -static event_t *get_event(user_service_t *us) -{ - event_t *ev = NULL; - - spin_lock(&us->event_lock); - if (!list_empty(&us->events)) { - ev = list_entry(us->events.next, event_t, list); - ev->last_stop = us->last_stop; - ev->last_start = us->last_start; - ev->last_finish = us->last_finish; - } - spin_unlock(&us->event_lock); - return ev; -} - -static void del_event(user_service_t *us, event_t *ev) -{ - spin_lock(&us->event_lock); - list_del(&ev->list); - spin_unlock(&us->event_lock); -} - -static event_t *alloc_event(void) -{ - event_t *ev; - SM_RETRY(ev = (event_t *) kmalloc(sizeof(event_t), GFP_KERNEL), ev); - memset(ev, 0, sizeof(event_t)); - return ev; -} - -/* us->lock must be held before calling */ -static void user_notify(user_service_t *us) -{ - if (us->sock) - queue_oob_skb(us->sock, CLUSTER_OOB_MSG_SERVICEEVENT); - if (us->pid && us->signal) - kill_proc(us->pid, us->signal, 0); -} - -static service_start_t start_type(int type) -{ - switch (type) { - case SERVICE_NODE_FAILED: - return SERVICE_START_FAILED; - case SERVICE_NODE_JOIN: - return SERVICE_START_JOIN; - case SERVICE_NODE_LEAVE: - return SERVICE_START_LEAVE; - } - return 0; -} - -static int user_stop(void *servicedata) -{ - user_service_t *us = (user_service_t *) servicedata; - event_t *ev; - - down(&us->lock); - if (!us->sock) - goto out; - - ev = alloc_event(); - ev->type = SERVICE_EVENT_STOP; - - add_event(us, ev); - user_notify(us); - out: - up(&us->lock); - return 0; -} - -static int user_start(void *servicedata, uint32_t *nodeids, int count, - int event_id, int type) -{ - user_service_t *us = (user_service_t *) servicedata; - event_t *ev; - - down(&us->lock); - if (!us->sock) { - kcl_start_done(us->local_id, event_id); - goto out; - } - - us->need_startdone = event_id; - - ev = alloc_event(); - ev->type = SERVICE_EVENT_START; - ev->node_count = count; - ev->start_type = start_type(type); - ev->event_id = event_id; - ev->nodeids = nodeids; - - add_event(us, ev); - user_notify(us); - out: - up(&us->lock); - return 0; -} - -static void user_finish(void *servicedata, int event_id) -{ - user_service_t *us = (user_service_t *) servicedata; - event_t *ev; - - down(&us->lock); - if (!us->sock) - goto out; - - ev = alloc_event(); - ev->type = SERVICE_EVENT_FINISH; - ev->event_id = event_id; - - add_event(us, ev); - user_notify(us); - out: - up(&us->lock); -} - -struct kcl_service_ops user_service_ops = { - .stop = user_stop, - .start = user_start, - .finish = user_finish -}; - -static int user_register(char *u_name, user_service_t **us_data) -{ - user_service_t *us; - char name[MAX_SERVICE_NAME_LEN+1]; - int len, error; - - memset(name, 0, MAX_SERVICE_NAME_LEN+1); - - if (copy_from_user(&name, u_name, MAX_SERVICE_NAME_LEN)) - return -EFAULT; - - len = strlen(name); - if (len > MAX_SERVICE_NAME_LEN) - return -ENAMETOOLONG; - if (!len) - return -EINVAL; - - us = kmalloc(sizeof(user_service_t), GFP_KERNEL); - if (!us) - return -ENOMEM; - memset(us, 0, sizeof(user_service_t)); - us->nodeids = NULL; - INIT_LIST_HEAD(&us->events); - spin_lock_init(&us->event_lock); - init_MUTEX(&us->lock); - us->name_len = len; - memcpy(us->name, name, len); - - error = kcl_register_service(name, len, SERVICE_LEVEL_USER, - &user_service_ops, TRUE, (void *) us, - &us->local_id); - if (error) { - kfree(us); - us = NULL; - } - *us_data = us; - return error; -} - -static void user_unregister(user_service_t *us) -{ - event_t *ev; - - kcl_unregister_service(us->local_id); - - if (us->nodeids) - kfree(us->nodeids); - - while ((ev = get_event(us))) { - del_event(us, ev); - if (ev->nodeids) - kfree(ev->nodeids); - kfree(ev); - } -} - -static int user_join_async(void *arg) -{ - user_service_t *us = arg; - int user_gone = 0; - - daemonize("cman_userjoin"); - - kcl_join_service(us->local_id); - - down(&us->lock); - us->state = UST_JOINED; - us->async = 0; - if (!us->sock) { - if (us->need_startdone) - kcl_start_done(us->local_id, us->need_startdone); - user_gone = 1; - } - up(&us->lock); - - if (user_gone) { - kcl_leave_service(us->local_id); - user_unregister(us); - kfree(us); - } - return 0; -} - -static int user_leave_async(void *arg) -{ - user_service_t *us = arg; - - daemonize("cman_userleave"); - - kcl_leave_service(us->local_id); - - down(&us->lock); - us->async = 0; - if (!us->sock) { - user_unregister(us); - kfree(us); - } else { - event_t *ev = alloc_event(); - ev->type = SERVICE_EVENT_LEAVEDONE; - add_event(us, ev); - user_notify(us); - up(&us->lock); - } - - return 0; -} - -static int user_join(user_service_t *us, int wait) -{ - int error = 0; - - if (wait) { - error = kcl_join_service(us->local_id); - us->state = UST_JOINED; - } - else { - us->async = 1; - kernel_thread(user_join_async, us, 0); - } - - return error; -} - -static void user_leave(user_service_t *us, int wait) -{ - if (wait) - kcl_leave_service(us->local_id); - else { - us->async = 1; - kernel_thread(user_leave_async, us, 0); - } -} - -static int user_start_done(user_service_t *us, unsigned int event_id) -{ - if (!us->need_startdone) - return -EINVAL; - if (us->need_startdone == event_id) - us->need_startdone = 0; - kcl_start_done(us->local_id, event_id); - return 0; -} - -static void user_set_signal(user_service_t *us, int signal) -{ - us->pid = current->pid; - us->signal = signal; -} - -static int user_get_event(user_service_t *us, - struct cl_service_event *user_event) -{ - event_t *ev; - struct cl_service_event event; - - ev = get_event(us); - if (!ev) - return 0; - - event.type = ev->type; - event.start_type = ev->start_type; - event.event_id = ev->event_id; - event.last_stop = ev->last_stop; - event.last_start = ev->last_start; - event.last_finish = ev->last_finish; - event.node_count = ev->node_count; - - if (copy_to_user(user_event, &event, sizeof(struct cl_service_event))) - return -EFAULT; - - del_event(us, ev); - - if (ev->type == SERVICE_EVENT_START) { - if (us->nodeids) - kfree(us->nodeids); - us->nodeids = ev->nodeids; - us->node_count = ev->node_count; - } - - kfree(ev); - return 1; -} - -static int user_get_members(user_service_t *us, - struct cl_cluster_nodelist *u_nodelist) -{ - struct cl_cluster_nodelist user_nodelist; - struct cl_cluster_node user_node, *u_node; - struct cluster_node *node; - unsigned int i; - int num_nodes = 0; - - if (!u_nodelist) - return us->node_count; - - if (copy_from_user(&user_nodelist, (void __user *) u_nodelist, - sizeof(struct cl_cluster_nodelist))) - return -EFAULT; - - if (user_nodelist.max_members < us->node_count) - return -E2BIG; - - u_node = user_nodelist.nodes; - - for (i = 0; i < us->node_count; i++) { - node = find_node_by_nodeid(us->nodeids[i]); - if (!node) - continue; - - copy_to_usernode(node, &user_node); - if (copy_to_user(u_node, &user_node, - sizeof(struct cl_cluster_node))) - return -EFAULT; - - u_node++; - num_nodes++; - } - return num_nodes; -} - -static int user_global_id(user_service_t *us, uint32_t *id) -{ - uint32_t gid = 0; - - if (us->state != UST_JOINED) - return -EINVAL; - - kcl_global_service_id(us->local_id, &gid); - - if (copy_to_user(id, &gid, sizeof(uint32_t))) - return -EFAULT; - return 0; -} - -static int user_set_level(user_service_t *us, int level) -{ - int prev_id = us->local_id; - int error; - - if (us->state != UST_REGISTER) - return -EINVAL; - - error = kcl_register_service(us->name, us->name_len, level, - &user_service_ops, TRUE, (void *) us, - &us->local_id); - if (error) - return error; - - kcl_unregister_service(prev_id); - return 0; -} - -int sm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - struct cluster_sock *c = cluster_sk(sock->sk); - user_service_t *us = c->service_data; - int error = 0; - - if (!us && cmd != SIOCCLUSTER_SERVICE_REGISTER) - return -EINVAL; - - switch (cmd) { - case SIOCCLUSTER_SERVICE_REGISTER: - error = user_register((char *) arg, &us); - if (!error) { - us->state = UST_REGISTER; - us->sock = sock; - c->service_data = us; - } - break; - - case SIOCCLUSTER_SERVICE_UNREGISTER: - down(&us->lock); - us->state = UST_UNREGISTER; - user_unregister(us); - up(&us->lock); - break; - - case SIOCCLUSTER_SERVICE_JOIN: - us->state = UST_JOIN; - user_join(us, 0); - break; - - case SIOCCLUSTER_SERVICE_LEAVE: - down(&us->lock); - if (us->state != UST_JOINED) { - error = -EBUSY; - up(&us->lock); - } else { - us->state = UST_LEAVE; - up(&us->lock); - user_leave(us, 0); - } - break; - - case SIOCCLUSTER_SERVICE_SETSIGNAL: - user_set_signal(us, (int) arg); - break; - - case SIOCCLUSTER_SERVICE_STARTDONE: - error = user_start_done(us, (unsigned int) arg); - break; - - case SIOCCLUSTER_SERVICE_GETEVENT: - error = user_get_event(us, (struct cl_service_event *) arg); - break; - - case SIOCCLUSTER_SERVICE_GETMEMBERS: - error = user_get_members(us, (struct cl_cluster_nodelist *)arg); - break; - - case SIOCCLUSTER_SERVICE_GLOBALID: - error = user_global_id(us, (uint32_t *) arg); - break; - - case SIOCCLUSTER_SERVICE_SETLEVEL: - error = user_set_level(us, (int) arg); - break; - - default: - error = -EINVAL; - } - - return error; -} - -void sm_sock_release(struct socket *sock) -{ - struct cluster_sock *c = cluster_sk(sock->sk); - user_service_t *us = c->service_data; - int state; - - if (!us) - return; - - down(&us->lock); - us->sock = NULL; - c->service_data = NULL; - - if (us->need_startdone) - kcl_start_done(us->local_id, us->need_startdone); - - if (us->async) { - /* async thread will clean up before exiting */ - up(&us->lock); - return; - } - state = us->state; - up(&us->lock); - - switch (state) { - case UST_JOIN: - break; - case UST_JOINED: - user_leave(us, 1); - /* fall through */ - case UST_LEAVE: - case UST_REGISTER: - user_unregister(us); - /* fall through */ - case UST_UNREGISTER: - kfree(us); - break; - } -} diff --git a/cman-kernel/src/sm_user.h b/cman-kernel/src/sm_user.h deleted file mode 100644 index a7bf496..0000000 --- a/cman-kernel/src/sm_user.h +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SM_USER_DOT_H__ -#define __SM_USER_DOT_H__ - -int sm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); -void sm_sock_release(struct socket *sock); -void sm_sock_bind(struct socket *sock); - -#endif diff --git a/cman/Makefile b/cman/Makefile deleted file mode 100644 index 06043ed..0000000 --- a/cman/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd lib && ${MAKE} all - cd cman_tool && ${MAKE} all - cd qdisk && ${MAKE} all - -copytobin: - cd cman_tool && ${MAKE} copytobin - cd qdisk && ${MAKE} copytobin - cd lib && ${MAKE} copytobin - -clean: - cd bin && ${MAKE} clean - cd cman_tool && ${MAKE} clean - cd qdisk && ${MAKE} clean - cd lib && ${MAKE} clean - -distclean: clean - rm -f make/defines.mk - -install: - cd man && ${MAKE} install - cd cman_tool && ${MAKE} install - cd lib && ${MAKE} install - cd qdisk && ${MAKE} install - cd init.d && ${MAKE} install - -uninstall: - cd cman_tool && ${MAKE} uninstall - cd lib && ${MAKE} uninstall - cd man && ${MAKE} uninstall - cd qdisk && ${MAKE} uninstall - cd init.d && ${MAKE} uninstall diff --git a/cman/bin/Makefile b/cman/bin/Makefile deleted file mode 100644 index a4a60d1..0000000 --- a/cman/bin/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -all: - cd .. && ${MAKE} copytobin - -clean: - rm -f *~ *.o cman_tool - -install: - cd .. && ${MAKE} install - -uninstall: - cd .. && ${MAKE} uninstall diff --git a/cman/cman_tool/Makefile b/cman/cman_tool/Makefile deleted file mode 100644 index 8c3a692..0000000 --- a/cman/cman_tool/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -g -I${incdir} -I${top_srcdir}/config \ - -DCMAN_RELEASE_NAME="${RELEASE}" - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -CFLAGS += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -CFLAGS += -I${incdir}/cluster -endif - -CFLAGS += -I../lib - - -TARGET=cman_tool - -all: ${TARGET} - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -cman_tool: main.o join.o join_ccs.o - $(CC) $(LDFLAGS) -L$(libdir) -L../lib -o $@ $^ -lccs -lcman - -main.o: main.c cman_tool.h - $(CC) $(CFLAGS) -c -o $@ $< - -join.o: join.c cman_tool.h - $(CC) $(CFLAGS) -c -o $@ $< - -join_ccs.o: join_ccs.c cman_tool.h - $(CC) $(CFLAGS) -c -o $@ $< - -install: cman_tool - install -d ${sbindir} - install cman_tool ${sbindir} - -uninstall: - ${UNINSTALL} cman_tool ${sbindir} - -clean: - rm -f *.o cman_tool - diff --git a/cman/cman_tool/cman_tool.h b/cman/cman_tool/cman_tool.h deleted file mode 100644 index b6c32e1..0000000 --- a/cman/cman_tool/cman_tool.h +++ /dev/null @@ -1,108 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __CMAN_TOOL_DOT_H__ -#define __CMAN_TOOL_DOT_H__ - -#include <sys/types.h> -#include <sys/uio.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/utsname.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdint.h> -#include <fcntl.h> -#include <netdb.h> -#include <limits.h> -#include <unistd.h> - -extern char *prog_name; - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#define die(fmt, args...) \ -do { \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt "\n", ##args); \ - exit(EXIT_FAILURE); \ -} while (0) - -#define DEFAULT_PORT 6809 -#define DEFAULT_VOTES 1 -#define MAX_INTERFACES 10 -#define MAX_FORMAT_OPTS 10 -#define MAX_NODE_NAME_LEN 65 -#define MAX_MCAST_NAME_LEN 256 -#define MAX_PATH_LEN 256 - -enum format_opt -{ - FMT_NONE, - FMT_ID, - FMT_NAME, - FMT_TYPE, - FMT_ADDR, -}; - -struct commandline -{ - int operation; - int num_multicasts; - int num_interfaces; - int num_nodenames; - char *multicast_names[MAX_INTERFACES]; - char *nodenames[MAX_INTERFACES]; - char *interfaces[MAX_INTERFACES]; - char *format_opts; - int votes; - int expected_votes; - int two_node; - int port; - char clustername[MAX_CLUSTER_NAME_LEN]; - int no_ccs; - int remove; - int force; - int verbose; - int nodeid; - int cluster_id; - int timeout; - unsigned int config_version; - - int config_version_opt; - int votes_opt; - int expected_votes_opt; - int port_opt; - int nodeid_opt; - int clustername_opt; - int wait_opt; - int wait_quorate_opt; -}; -typedef struct commandline commandline_t; - -int join(commandline_t *comline); -int get_ccs_join_info(commandline_t *comline); -char *cman_error(int err); - -#endif /* __CMAN_TOOL_DOT_H__ */ diff --git a/cman/cman_tool/join.c b/cman/cman_tool/join.c deleted file mode 100644 index 33984ce..0000000 --- a/cman/cman_tool/join.c +++ /dev/null @@ -1,413 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <net/route.h> -#include "cnxman-socket.h" -#include "cman_tool.h" - -/* Size of buffer for gethostbyname2_r */ -#define HE_BUFSIZE 2048 - -static int cluster_sock; - -/* Lookup the IPv4 broadcast address for a given local address */ -static uint32_t lookup_bcast(uint32_t localaddr, char *ifname) -{ - struct ifreq ifr; - uint32_t addr, brdaddr; - int iindex; - int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - struct sockaddr_in *saddr = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_addr; - - ifname[0] = '\0'; - - for (iindex = 0; iindex < 255; iindex++) { - ifr.ifr_ifindex = iindex; - if (ioctl(sock, SIOCGIFNAME, &ifr) == 0) { - ifr.ifr_ifindex = iindex; - - ioctl(sock, SIOCGIFADDR, &ifr); - addr = saddr->sin_addr.s_addr; - - if (addr == localaddr) { - ioctl(sock, SIOCGIFBRDADDR, &ifr); - brdaddr = saddr->sin_addr.s_addr; - - strcpy(ifname, ifr.ifr_name); - close(sock); - return brdaddr; - } - } - } - - /* Didn't find it */ - close(sock); - return 0; -} - -/* Set the socket priority to INTERACTIVE to ensure - that our messages don't get queued behind anything else */ -static void set_priority(int sock) -{ - int prio = 6; /* TC_PRIO_INTERACTIVE */ - - if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int))) - perror("Error setting socket priority"); -} - -static int setup_ipv4_interface(commandline_t *comline, int num, struct hostent *he) -{ - struct hostent realbhe; - struct hostent *bhe = NULL; - struct sockaddr_in mcast_sin; - struct sockaddr_in local_sin; - struct cl_passed_sock sock_info; - char he_buffer[HE_BUFSIZE]; /* scratch area for gethostbyname2_r */ - char ifname[256]; - int mcast_sock; - int local_sock; - int ret; - int one=1; - int he_errno; - uint32_t bcast; - - memset(&mcast_sin, 0, sizeof(mcast_sin)); - mcast_sin.sin_family = AF_INET; - mcast_sin.sin_port = htons(comline->port); - - memset(&local_sin, 0, sizeof(local_sin)); - local_sin.sin_family = AF_INET; - local_sin.sin_port = htons(comline->port); - memcpy(&local_sin.sin_addr, he->h_addr, he->h_length); - - if (comline->verbose) - printf("setup up interface for address: %s\n", comline->nodenames[num]); - - if (!comline->multicast_names[num]) { - uint32_t ipaddr; - - memcpy(&ipaddr, he->h_addr, sizeof(uint32_t)); - bcast = lookup_bcast(ipaddr, ifname); - if (!bcast) - die("Can't find broadcast address for node %s\n", comline->nodenames[num]); - - if (strcmp(ifname, "lo") == 0) { - fprintf(stderr, "\nYour host name maps to the loopback device rather than a real network interface.\n"); - fprintf(stderr, "Please change your /etc/hosts file so that your host name has a proper IP\n"); - fprintf(stderr, "address, as a cluster cannot function over the loopback interface.\n"); - exit(EXIT_FAILURE); - } - - if (comline->verbose) { - printf("Broadcast address for %x is %x\n", ipaddr, bcast); - } - } - else { - uint32_t addr; - ret = gethostbyname2_r(comline->multicast_names[num], AF_INET, - &realbhe, he_buffer, sizeof(he_buffer), &bhe, - &he_errno); - if (!bhe) - die("Can't resolve multicast address %s: %s\n", comline->multicast_names[num], hstrerror(he_errno)); - - if (bhe->h_addr_list[1]) - die("multicast address %s is ambiguous\n", comline->multicast_names[num]); - - /* Check it really is a multicast address */ - memcpy(&addr, bhe->h_addr_list[0], sizeof(uint32_t)); - if ((ntohl(addr) & 0xe0000000) != 0xe0000000) - die("%s is not an IPv4 multicast address\n", comline->multicast_names[num]); - } - - mcast_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (mcast_sock < 0) - die("Can't open multicast socket: %s", strerror(errno)); - - if (bhe) { - /* Multicast */ - memcpy(&mcast_sin.sin_addr, bhe->h_addr, bhe->h_length); - } - else { - /* Broadcast */ - memcpy(&mcast_sin.sin_addr, &bcast, sizeof(struct in_addr)); - if (setsockopt(mcast_sock, SOL_SOCKET, SO_BROADCAST, (void *)&one, sizeof(int))) - die("Can't enable broadcast: %s", strerror(errno)); - } - if (bind(mcast_sock, (struct sockaddr *)&mcast_sin, sizeof(mcast_sin))) - die("Cannot bind multicast address: %s", strerror(errno)); - - /* Join the multicast group */ - if (bhe) { - struct ip_mreqn mreq; - char mcast_opt; - - memcpy(&mreq.imr_multiaddr, bhe->h_addr, bhe->h_length); - mreq.imr_ifindex = if_nametoindex(comline->interfaces[num]); - - if (setsockopt(mcast_sock, SOL_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) - die("Unable to join multicast group %s: %s\n", comline->multicast_names[num], strerror(errno)); - - mcast_opt = 10; - if (setsockopt(mcast_sock, SOL_IP, IP_MULTICAST_TTL, (void *)&mcast_opt, sizeof(mcast_opt))) - die("Unable to set ttl for multicast group %s: %s\n", comline->multicast_names[num], strerror(errno)); - - mcast_opt = 0; - setsockopt(mcast_sock, SOL_IP, IP_MULTICAST_LOOP, (void *)&mcast_opt, sizeof(mcast_opt)); - - if (setsockopt(mcast_sock, SOL_IP, IP_MULTICAST_IF, (void *)&mreq, sizeof(mreq))) { - die("Unable to set multicast interface %s\n", comline->interfaces[num]); - } - } - - /* Local socket */ - local_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (local_sock < 0) - die("Can't open local socket: %s", strerror(errno)); - - if (setsockopt(local_sock, SOL_SOCKET, SO_BROADCAST, (void *)&one, sizeof(int))) - die("Can't enable broadcast: %s", strerror(errno)); - - if (bind(local_sock, (struct sockaddr *)&local_sin, sizeof(local_sin))) - die("Cannot bind local address: %s", strerror(errno)); - - sock_info.number = num + 1; - sock_info.multicast = 1; - - set_priority(mcast_sock); - set_priority(local_sock); - - /* Pass the multicast socket to kernel space */ - sock_info.fd = mcast_sock; - if (ioctl(cluster_sock, SIOCCLUSTER_PASS_SOCKET, (void *)&sock_info)) - die("passing multicast socket to cluster kernel module"); - - /* Pass the recv socket to kernel space */ - sock_info.fd = local_sock; - sock_info.multicast = 0; - if (ioctl(cluster_sock, SIOCCLUSTER_PASS_SOCKET, (void *)&sock_info)) - die("passing unicast receive socket to cluster kernel module"); - - /* These are now owned by the kernel */ - close(local_sock); - close(mcast_sock); - - return 0; -} - - -static int setup_ipv6_interface(commandline_t *comline, int num, struct hostent *he) -{ - struct hostent realbhe; - struct hostent *bhe = NULL; - struct sockaddr_in6 mcast_sin; - struct sockaddr_in6 local_sin; - struct ipv6_mreq mreq; - char he_buffer[HE_BUFSIZE]; /* scratch area for gethostbyname2_r */ - int ret; - int he_errno; - int mcast_sock; - int local_sock; - struct cl_passed_sock sock_info; - int param; - - memset(&mcast_sin, 0, sizeof(mcast_sin)); - mcast_sin.sin6_family = AF_INET6; - mcast_sin.sin6_port = htons(comline->port); - - memset(&local_sin, 0, sizeof(local_sin)); - local_sin.sin6_family = AF_INET6; - local_sin.sin6_port = htons(comline->port); - memcpy(&local_sin.sin6_addr, he->h_addr, he->h_length); - - if (!comline->multicast_names[num]) - die("No multicast address for IPv6 node %s\n", comline->nodenames[num]); - - ret = gethostbyname2_r(comline->multicast_names[num], AF_INET6, - &realbhe, he_buffer, sizeof(he_buffer), &bhe, - &he_errno); - - if (!bhe) - die("Can't resolve multicast address %s: %s\n", comline->multicast_names[num], hstrerror(he_errno)); - - mcast_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if (mcast_sock < 0) - die("Can't open multicast socket: %s", strerror(errno)); - - memcpy(&mcast_sin.sin6_addr, bhe->h_addr, bhe->h_length); - if (bind(mcast_sock, (struct sockaddr *)&mcast_sin, sizeof(mcast_sin))) { - die("Cannot bind multicast address: %s", strerror(errno)); - } - - /* Join the multicast group */ - - memcpy(&mreq.ipv6mr_multiaddr, bhe->h_addr, bhe->h_length); - mreq.ipv6mr_interface = if_nametoindex(comline->interfaces[num]); - if (setsockopt(mcast_sock, SOL_IPV6, IPV6_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) - die("Unable to join multicast group %s: %s\n", comline->multicast_names[num], strerror(errno)); - - param = 0; /* Disable local copies of multicast messages */ - setsockopt(mcast_sock, SOL_IPV6, IPV6_MULTICAST_LOOP, (void *)¶m, sizeof(int)); - /* Failure of this is tolerable */ - - - /* Local socket */ - local_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if (local_sock < 0) - die("Can't open local socket : %s", strerror(errno)); - - if (bind(local_sock, (struct sockaddr *)&local_sin, sizeof(local_sin))) - die("Cannot bind local address: %s", strerror(errno)); - - sock_info.number = num + 1; - - set_priority(mcast_sock); - set_priority(local_sock); - - /* Pass the multicast socket to kernel space */ - sock_info.fd = mcast_sock; - sock_info.multicast = 1; - if (ioctl(cluster_sock, SIOCCLUSTER_PASS_SOCKET, (void *)&sock_info)) - die("passing multicast socket to cluster kernel module"); - - /* Pass the recv socket to kernel space */ - sock_info.fd = local_sock; - sock_info.multicast = 0; - if (ioctl(cluster_sock, SIOCCLUSTER_PASS_SOCKET, (void *)&sock_info)) - die("passing unicast receive socket to cluster kernel module"); - - /* These are now owned by the kernel */ - close(local_sock); - close(mcast_sock); - return 0; -} - - -static int setup_interface(commandline_t *comline, int num) -{ - struct hostent realhe; - struct hostent *he; - static int last_af = 0; - char he_buffer[HE_BUFSIZE]; /* scratch area for gethostbyname2_r */ - int ret; - int he_errno; - int af; - - /* Lookup the nodename address */ - af = AF_INET6; - ret = gethostbyname2_r(comline->nodenames[num], af, - &realhe, he_buffer, sizeof(he_buffer), &he, - &he_errno); - if (!he) { - af = AF_INET; - ret = gethostbyname2_r(comline->nodenames[num], af, - &realhe, he_buffer, sizeof(he_buffer), &he, - &he_errno); - } - if (!he) - die("can't resolve node name %s: %s\n", comline->nodenames[num], hstrerror(he_errno)); - - if (he->h_addr_list[1]) - die("node name %s is ambiguous\n", comline->nodenames[num]); - - /* All interfaces should be the same address family */ - if (last_af && (last_af != af)) - die("All IP addresses must have the same address family"); - - last_af = af; - - if (af == AF_INET) - return setup_ipv4_interface(comline, num, he); - else - return setup_ipv6_interface(comline, num, he); -} - -int join(commandline_t *comline) -{ - struct cl_join_cluster_info join_info; - int error, i; - char nodename[256]; - - /* - * Create the cluster master socket - */ - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_MASTER); - if (cluster_sock == -1) - { - int e = errno; - perror("can't open cluster socket"); - - if (e == EAFNOSUPPORT) - die("The cman kernel module may not be loaded"); - exit(EXIT_FAILURE); - } - - /* - * If the cluster is active then the interfaces are already set up - * and this join should just add to the join_count. - */ - error = ioctl(cluster_sock, SIOCCLUSTER_ISACTIVE); - if (error == -1) - die("Can't determine cluster state"); - - if (error) - die("Node is already active"); - - /* Set the node name - without domain part */ - strcpy(nodename, comline->nodenames[0]); - - error = ioctl(cluster_sock, SIOCCLUSTER_SET_NODENAME, nodename); - if (error) - die("Unable to set cluster node name: %s", cman_error(errno)); - - /* Optional, set the node ID */ - if (comline->nodeid) { - error = ioctl(cluster_sock, SIOCCLUSTER_SET_NODEID, - comline->nodeid); - if (error) - die("Unable to set cluster nodeid: %s", cman_error(errno)); - } - - if (comline->cluster_id) { - error = ioctl(cluster_sock, SIOCCLUSTER_SET_CLUSTERID, - comline->cluster_id); - if (error) - die("Unable to set cluster_id: %s", cman_error(errno)); - } - - /* - * Setup the interface/multicast - */ - for (i = 0; i<comline->num_nodenames; i++) - { - error = setup_interface(comline, i); - if (error) - die("Unable to setup network interface(s)"); - } - - /* - * Join cluster - */ - join_info.votes = comline->votes; - join_info.expected_votes = comline->expected_votes; - strcpy(join_info.cluster_name, comline->clustername); - join_info.two_node = comline->two_node; - join_info.config_version = comline->config_version; - - if (ioctl(cluster_sock, SIOCCLUSTER_JOIN_CLUSTER, &join_info)) - { - die("error joining cluster: %s", cman_error(errno)); - } - - close(cluster_sock); - return 0; -} diff --git a/cman/cman_tool/join_ccs.c b/cman/cman_tool/join_ccs.c deleted file mode 100644 index 9a3c8d0..0000000 --- a/cman/cman_tool/join_ccs.c +++ /dev/null @@ -1,539 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdint.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <dirent.h> -#include <netdb.h> -#include <ifaddrs.h> - -#include "ccs.h" -#include "cnxman-socket.h" -#include "cman_tool.h" - - -#define CLUSTER_NAME_PATH "/cluster/@name" -#define CONFIG_VERSION_PATH "/cluster/@config_version" -#define EXP_VOTES_PATH "/cluster/cman/@expected_votes" -#define TWO_NODE_PATH "/cluster/cman/@two_node" -#define CLUSTER_ID_PATH "/cluster/cman/@cluster_id" -#define MCAST_ADDR_PATH "/cluster/cman/multicast/@addr" -#define PORT_PATH "/cluster/cman/@port" -#define CMAN_PREFIX "/cluster/cman/@" -#define CMAN_PROC_DIR "/proc/cluster/config/cman" - -#define NODEI_NAME_PATH "/cluster/clusternodes/clusternode[%d]/@name" -#define NODE_NAME_PATH "/cluster/clusternodes/clusternode[@name="%s"]/@name" -#define NODE_VOTES_PATH "/cluster/clusternodes/clusternode[@name="%s"]/@votes" -#define NODE_NODEID_PATH "/cluster/clusternodes/clusternode[@name="%s"]/@nodeid" -#define NODE_IFNAME_PATH "/cluster/clusternodes/clusternode[@name="%s"]/@ifname" -#define NODE_ALTNAMES_PATH "/cluster/clusternodes/clusternode[@name="%s"]/altname/@name" -#define NODE_MCAST_IF_PATH "/cluster/clusternodes/clusternode[@name="%s"]/multicast[@addr="%s"]/@interface" - - -int verify_nodename(commandline_t *comline, int cd, char *nodename) -{ - char path[MAX_PATH_LEN]; - char nodename2[MAX_NODE_NAME_LEN]; - char nodename3[MAX_NODE_NAME_LEN]; - char *str, *dot = NULL; - struct ifaddrs *ifa, *ifa_list; - struct sockaddr *sa; - int error, i; - - - /* nodename is either from commandline or from uname */ - - str = NULL; - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_NAME_PATH, nodename); - - error = ccs_get(cd, path, &str); - if (!error) { - free(str); - return 0; - } - - if (comline->verbose) - printf("nodename %s not found\n", nodename); - - - /* if nodename was on command line, don't try variations */ - - if (comline->num_nodenames > 0) - return -1; - - - /* if nodename was from uname, try a domain-less version of it */ - - strcpy(nodename2, nodename); - dot = strstr(nodename2, "."); - if (dot) { - *dot = '\0'; - - str = NULL; - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_NAME_PATH, nodename2); - - error = ccs_get(cd, path, &str); - if (!error) { - free(str); - strcpy(nodename, nodename2); - return 0; - } - - if (comline->verbose) - printf("nodename %s (truncated) not found\n", nodename2); - } - - - /* if nodename (from uname) is domain-less, try to match against - cluster.conf names which may have domainname specified */ - - for (i = 1; ; i++) { - str = NULL; - memset(path, 0, 256); - sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", i); - - error = ccs_get(cd, path, &str); - if (error || !str) - break; - - strcpy(nodename3, str); - dot = strstr(nodename3, "."); - if (dot) - *dot = '\0'; - - if (strlen(nodename2) == strlen(nodename3) && - !strncmp(nodename2, nodename3, strlen(nodename3))) { - strcpy(nodename, str); - free(str); - return 0; - } - - if (comline->verbose) - printf("nodename %s doesn't match %s (%s in cluster.conf)\n", - nodename2, nodename3, str); - free(str); - } - - - /* the cluster.conf names may not be related to uname at all, - they may match a hostname on some network interface */ - - error = getifaddrs(&ifa_list); - if (error) - return -1; - - for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) { - sa = ifa->ifa_addr; - if (!sa || sa->sa_family != AF_INET) - continue; - - error = getnameinfo(sa, sizeof(*sa), nodename2, - sizeof(nodename2), NULL, 0, 0); - if (error) - goto out; - - str = NULL; - memset(path, 0, 256); - sprintf(path, NODE_NAME_PATH, nodename2); - - error = ccs_get(cd, path, &str); - if (!error) { - free(str); - strcpy(nodename, nodename2); - goto out; - } - - if (comline->verbose) - printf("nodename %s (if %s) not found\n", nodename2, - ifa->ifa_name); - - /* truncate this name and try again */ - - dot = strstr(nodename2, "."); - if (!dot) - continue; - *dot = '\0'; - - str = NULL; - memset(path, 0, 256); - sprintf(path, NODE_NAME_PATH, nodename2); - - error = ccs_get(cd, path, &str); - if (!error) { - free(str); - strcpy(nodename, nodename2); - goto out; - } - - if (comline->verbose) - printf("nodename %s (if %s truncated) not found\n", - nodename2, ifa->ifa_name); - } - - error = -1; - out: - freeifaddrs(ifa_list); - return error; -} - -/* Get "advanced" configuration options */ -static void get_ccs_cman_config(int ccs_handle, commandline_t *comline) -{ - DIR *dir; - struct dirent *entry; - char ccs_key[1024]; - char proc_filename[1024]; - char *str; - - dir = opendir(CMAN_PROC_DIR); - if (!dir) - return; - - entry = readdir(dir); - while (entry) { - sprintf(ccs_key, "%s%s", CMAN_PREFIX, entry->d_name); - if (!ccs_get(ccs_handle, ccs_key, &str)) { - - if (atoi(str)) { - FILE *procfile; - - sprintf(proc_filename, "%s/%s", CMAN_PROC_DIR, entry->d_name); - - if (comline->verbose) - printf("setting option %s to %s\n", entry->d_name, str); - procfile = fopen(proc_filename, "w+"); - if (procfile) { - fprintf(procfile, "%s\n", str); - fclose(procfile); - } - } - else { - fprintf(stderr, "CCS entry for %s is invalid: '%s'\n", - ccs_key, str); - } - free(str); - } - - entry = readdir(dir); - } - - closedir(dir); -} -/* - * It's ok to let a node join the cluster even if it's not in cluster.conf. - * It's similar to allowing the admin to lower expected_votes dynamically. The - * biggest risk with this kind of thing is that an inquorate cluster partition - * will gain quorum creating a split-brain scenario where two partitions have - * quorum. - * - * This poses no real danger to GFS. Even in a split-brain cluster, the - * fencing domain ensures that one half or the other is fenced before gfs usage - * is allowed. If both halves gain quorum, both halves will attempt to fence - * each other instead of the normal scenario where the quorate half will fence - * the inquorate half. Regardless the outcome of this fencing battle, gfs - * integrity is preserved. - * - * [This does require that the fence daemon only allow a node to join the fence - * domain if that node's cluster nodename is in cluster.conf. Mounting gfs is - * then only permitted if the node is in the fence domain.] - * - * So, if the user wants a node that's not in cluster.conf to join the cluster - * that's fine, they can always do that using the -X option to ignore - * cluster.conf. Here, when using ccs/cluster.conf, we'll assume that the user - * has made an error if we find that a node's name is missing from cluster.conf - * since that's the most likely situation and most helpful to the non-expert. - */ - -int get_ccs_join_info(commandline_t *comline) -{ - char path[MAX_PATH_LEN]; - char nodename[MAX_NODE_NAME_LEN]; - char *str, *name, *cname = NULL; - int cd, error, i, vote_sum = 0, node_count = 0; - - - if (comline->config_version_opt || - comline->votes_opt || - comline->expected_votes_opt || - comline->port_opt || - comline->nodeid_opt) - printf("command line options may override cluster.conf values\n"); - - - /* connect to ccsd */ - - if (comline->clustername_opt) - cname = comline->clustername; - - cd = ccs_force_connect(cname, 1); - if (cd < 0) - die("cannot connect to ccs (name=%s)", - cname ? comline->clustername : "none"); - - - /* cluster name */ - - error = ccs_get(cd, CLUSTER_NAME_PATH, &str); - if (error) - die("cannot find cluster name in config file"); - - if (comline->clustername_opt) { - if (strcmp(cname, str)) - die("cluster names not equal %s %s", cname, str); - } else - strcpy(comline->clustername, str); - free(str); - - if (strlen(comline->clustername) > MAX_CLUSTER_NAME_LEN-1) { - die("Cluster name in CCS is longer than %d characters", - MAX_CLUSTER_NAME_LEN); - } - - /* our nodename */ - - memset(nodename, 0, MAX_NODE_NAME_LEN); - - if (comline->num_nodenames > 0) - strcpy(nodename, comline->nodenames[0]); - else { - struct utsname utsname; - error = uname(&utsname); - if (error) - die("cannot get node name, uname failed"); - /* we set up the comline nodenames below */ - strcpy(nodename, utsname.nodename); - } - - - /* find our nodename in cluster.conf */ - - error = verify_nodename(comline, cd, nodename); - if (error) - die("local node name "%s" not found in cluster.conf", - nodename); - if (comline->verbose) - printf("selected nodename %s\n", nodename); - - - /* config version */ - - if (!comline->config_version_opt) { - error = ccs_get(cd, CONFIG_VERSION_PATH, &str); - if (!error) { - comline->config_version = atoi(str); - free(str); - } - } - - - /* sum node votes for expected */ - - if (!comline->expected_votes_opt) { - for (i = 1; ; i++) { - name = NULL; - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODEI_NAME_PATH, i); - - error = ccs_get(cd, path, &name); - if (error || !name) - break; - - node_count++; - - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_VOTES_PATH, name); - free(name); - - error = ccs_get(cd, path, &str); - if (error) - vote_sum++; - else { - if (atoi(str) < 0) - die("negative votes not allowed"); - vote_sum += atoi(str); - free(str); - } - } - - /* optional expected_votes supercedes vote sum */ - - error = ccs_get(cd, EXP_VOTES_PATH, &str); - if (!error) { - comline->expected_votes = atoi(str); - free(str); - } else - comline->expected_votes = vote_sum; - } - - - /* optional port */ - - if (!comline->port_opt) { - error = ccs_get(cd, PORT_PATH, &str); - if (!error) { - comline->port = atoi(str); - free(str); - } - } - - - /* optional multicast name(s) with interfaces */ - - if (!comline->num_multicasts) { - comline->num_multicasts = 0; - comline->num_interfaces = 0; - - for (i = 0; ; i++) { - str = NULL; - - error = ccs_get_list(cd, MCAST_ADDR_PATH, &str); - if (error || !str) - break; - - if (comline->verbose) - printf("multicast address %s\n", str); - - comline->multicast_names[i] = str; - comline->num_multicasts++; - } - - for (i = 0; i < comline->num_multicasts; i++) { - str = NULL; - name = comline->multicast_names[i]; - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_MCAST_IF_PATH, nodename, name); - - error = ccs_get(cd, path, &str); - if (error || !str) - die("no interface for multicast address %s", name); - - if (comline->verbose) - printf("if %s for mcast address %s\n", str, name); - - comline->interfaces[i] = str; - comline->num_interfaces++; - } - } - - - - /* find our own number of votes */ - - if (!comline->votes_opt) { - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_VOTES_PATH, nodename); - - error = ccs_get(cd, path, &str); - if (!error) { - comline->votes = atoi(str); - if (comline->votes < 0 || comline->votes > 255) - die("invalid votes value %d", comline->votes); - free(str); - } - } - - - /* optional nodeid */ - - if (!comline->nodeid_opt) { - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_NODEID_PATH, nodename); - - error = ccs_get(cd, path, &str); - if (!error) { - comline->nodeid = atoi(str); - free(str); - } - } - - - /* get all alternative node names */ - - if (!comline->num_nodenames) { - comline->nodenames[0] = strdup(nodename); - comline->num_nodenames = 1; - - memset(path, 0, MAX_PATH_LEN); - sprintf(path, NODE_ALTNAMES_PATH, nodename); - - for (i = 1; ; i++) { - str = NULL; - - error = ccs_get(cd, path, &str); - if (error || !str) - break; - - /* If we get the same thing twice, it's probably the - end of a 1-element list */ - - if (strcmp(str, comline->nodenames[i-1]) == 0) { - free(str); - break; - } - - if (comline->verbose) - printf("alternative node name %s\n", str); - - comline->nodenames[i] = str; - comline->num_nodenames++; - } - } - - - /* two_node mode */ - - error = ccs_get(cd, TWO_NODE_PATH, &str); - if (!error) { - comline->two_node = atoi(str); - free(str); - if (comline->two_node) { - if (node_count != 2 || vote_sum != 2) - die("the two-node option requires exactly two " - "nodes with one vote each and expected " - "votes of 1 (node_count=%d vote_sum=%d)", - node_count, vote_sum); - - if (comline->votes_opt && comline->votes != 1) - die("the two-node option requires exactly two " - "nodes with one vote each and expected " - "votes of 1 (votes=%d)", comline->votes); - - if (!comline->votes_opt && comline->votes != 0 && - comline->votes != 1) - die("the two-node option requires exactly two " - "nodes with one vote each and expected " - "votes of 1 (votes=%d)", comline->votes); - - /* if no comline votes option and no votes value found - in cluster.conf, then votes is set to DEFAULT_VOTES - (1) in check_arguements() */ - } - } - - /* cluster_id override? */ - error = ccs_get(cd, CLUSTER_ID_PATH, &str); - if (!error) { - comline->cluster_id = atoi(str); - free(str); - } - - get_ccs_cman_config(cd, comline); - - ccs_disconnect(cd); - return 0; -} diff --git a/cman/cman_tool/main.c b/cman/cman_tool/main.c deleted file mode 100644 index cd9e74f..0000000 --- a/cman/cman_tool/main.c +++ /dev/null @@ -1,831 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <inttypes.h> -#include <unistd.h> -#include <signal.h> -#include <time.h> -#include <netinet/in.h> -#include "copyright.cf" -#include "cnxman-socket.h" -#include "libcman.h" -#include "cman_tool.h" - -#define OPTION_STRING ("m:n:v:e:2p:c:r:i:N:t:XF:Vwqh?d") -#define OP_JOIN 1 -#define OP_LEAVE 2 -#define OP_EXPECTED 3 -#define OP_VOTES 4 -#define OP_KILL 5 -#define OP_VERSION 6 -#define OP_WAIT 7 -#define OP_STATUS 8 -#define OP_NODES 9 -#define OP_SERVICES 10 - - -static void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s <join|leave|kill|expected|votes|version|wait|status|nodes|services> [options]\n", - prog_name); - printf("\n"); - printf("Options:\n"); - printf(" -h Print this help, then exit\n"); - printf(" -V Print program version information, then exit\n"); - printf(" -d Enable debug output\n"); - printf("\n"); - - printf("join\n"); - printf(" -m <addr> * Multicast address to use (combines with -i)\n"); - printf(" -i <ifname> * Interfaces for above multicast addresses\n"); - printf(" -v <votes> Number of votes this node has (default 1)\n"); - printf(" -e <votes> Number of expected votes for the cluster (no default)\n"); - printf(" -c <clustername> Name of the cluster to join\n"); - printf(" -2 This is a two node cluster (-e must be 1)\n"); - printf(" -p <port> UDP port number for cman communications (default %d)\n", DEFAULT_PORT); - printf(" -n <nodename> * The name of this node (defaults to hostname)\n"); - printf(" -N <id> Node id (defaults to automatic)\n"); - printf(" -X Do not use cluster.conf values from CCS\n"); - printf(" -w Wait until node has joined a cluster\n"); - printf(" -q Wait until the cluster is quorate\n"); - printf(" -t Maximum time (in seconds) to wait\n"); - printf(" options with marked * can be specified multiple times for multi-path systems\n"); - - printf("\n"); - printf("wait Wait until the node is a member of a cluster\n"); - printf(" -q Wait until the cluster is quorate\n"); - printf(" -t Maximum time (in seconds) to wait\n"); - printf("\n"); - - printf("leave\n"); - printf(" -w If cluster is in transition, wait and keep trying\n"); - printf(" -t Maximum time (in seconds) to wait\n"); - printf(" remove Tell other nodes to ajust quorum downwards if necessary\n"); - printf(" force Leave even if cluster subsystems are active\n"); - - printf("\n"); - printf("kill\n"); - printf(" -n <nodename> The name of the node to kill (can specify multiple times)\n"); - - printf("\n"); - printf("expected\n"); - printf(" -e <votes> New number of expected votes for the cluster\n"); - - printf("\n"); - printf("votes\n"); - printf(" -v <votes> New number of votes for this node\n"); - - printf("\n"); - printf("status Show local record of cluster status\n"); - printf("\n"); - printf("nodes Show local record of cluster nodes\n"); - printf(" -n <nodename> Only show information for specific node\n"); - printf(" -F <format> Specify output format (see man page)\n"); - printf("\n"); - printf("services Show local record of cluster services\n"); - - printf("\n"); - printf("version\n"); - printf(" -r <config> A new config version to set on all members\n"); - printf("\n"); -} - -static void sigalarm_handler(int sig) -{ - fprintf(stderr, "Timed-out waiting for cluster\n"); - exit(2); -} - -static void show_file(char *name) -{ - FILE *file; - char line[256]; - - file = fopen(name, "r"); - if (!file) - die("can't open %s, cman not running", name); - - while (fgets(line, 256, file)) - printf("%s", line); - - fclose(file); -} - -static void show_status(void) -{ - show_file("/proc/cluster/status"); -} - -static void show_nodes(void) -{ - show_file("/proc/cluster/nodes"); -} - -static void show_services(void) -{ - show_file("/proc/cluster/services"); -} - -static int node_filter(commandline_t *comline, const char *node) -{ - int i; - - for (i = 0; i < comline->num_nodenames; i++) { - if (strcmp(comline->nodenames[i], node) == 0) { - return TRUE; - } - } - - return FALSE; -} - -static int get_format_opt(const char *opt) -{ - if (!opt) - return FMT_NONE; - - if (!strcmp(opt, "id")) - return FMT_ID; - if (!strcmp(opt, "name")) - return FMT_NAME; - if (!strcmp(opt, "type")) - return FMT_TYPE; - if (!strcmp(opt, "addr")) - return FMT_ADDR; - - return FMT_NONE; -} - -static void show_nodes_opt(commandline_t *comline) -{ - cman_handle_t h; - int count; - int i; - int j; - int numnodes; - int format[MAX_FORMAT_OPTS]; - cman_node_t *nodes; - - h = cman_init(NULL); - - count = cman_get_node_count(h); - if (count < 0) - die("cman_get_node_count failed: %s", cman_error(errno)); - - count += 2; - - nodes = malloc(sizeof(cman_node_t) * count); - if (!nodes) - die("cannot allocate memory for nodes list\n"); - - if (comline->format_opts != NULL) { - char *format_str = comline->format_opts; - char *format_tmp; - for (i = 0; i < MAX_FORMAT_OPTS; i++) { - format_tmp = strtok(format_str, ","); - format_str = NULL; - format[i] = get_format_opt(format_tmp); - } - } - - if (cman_get_nodes(h, count, &numnodes, nodes) < 0) - die("cman_get_nodes failed: %s", cman_error(errno)); - - if (!comline->format_opts) { - printf("Node Sts Inc Name\n"); - } - - for (i = 0; i < numnodes; i++) { - char member_type; - - if (comline->num_nodenames > 0) { - if (node_filter(comline, nodes[i].cn_name) == 0) { - continue; - } - } - - switch (nodes[i].cn_member) { - case 0: - member_type = 'X'; - break; - case 1: - member_type = 'M'; - break; - default: - member_type = '?'; - break; - } - - if (!comline->format_opts) { - printf("%4d %c %5d %s\n", - nodes[i].cn_nodeid, member_type, - nodes[i].cn_incarnation, nodes[i].cn_name); - } else { - for (j = 0; j < MAX_FORMAT_OPTS; j++) { - switch (format[j]) { - case FMT_NONE: - break; - case FMT_ID: - printf("%d ", nodes[i].cn_nodeid); - break; - case FMT_NAME: - printf("%s ", nodes[i].cn_name); - break; - case FMT_TYPE: - printf("%c ", member_type); - break; - case FMT_ADDR: - break; - default: - break; - } - } - printf("\n"); - } - } - - free(nodes); - cman_finish(h); -} - -static int open_cluster_socket() -{ - int cluster_sock; - - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_MASTER); - if (cluster_sock == -1) - die("can't open cluster socket, cman kernel module probably not loaded"); - - return cluster_sock; -} - -char *cman_error(int err) -{ - char *die_error; - - switch (errno) { - case ENOTCONN: - die_error = "Cluster software not started"; - break; - case ENOENT: - die_error = "Node is not yet a cluster member"; - break; - case EBUSY: - die_error = "Cluster is in transition, try later or use -w"; - break; - default: - die_error = strerror(errno); - break; - } - return die_error; -} - -static void leave(commandline_t *comline) -{ - int cluster_sock; - int result; - int flags = CLUSTER_LEAVEFLAG_DOWN; - - cluster_sock = open_cluster_socket(); - - /* "cman_tool leave remove" adjusts quorum downward */ - - if (comline->remove) - flags |= CLUSTER_LEAVEFLAG_REMOVED; - if (comline->force) - flags |= CLUSTER_LEAVEFLAG_FORCE; - - /* If the join count is != 1 then there are other things using - the cluster and we need to be forced */ - - if ((result = ioctl(cluster_sock, SIOCCLUSTER_GET_JOINCOUNT, 0)) != 0) { - if (result < 0) - die("error getting join count: %s", cman_error(errno)); - - if (!comline->force) { - die("Can't leave cluster while there are %d active subsystems\n", result); - } - } - - /* Unlikely this will be needed, but no point in leaving it out */ - if (comline->wait_opt && comline->timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(comline->timeout); - } - - do { - result = ioctl(cluster_sock, SIOCCLUSTER_LEAVE_CLUSTER, flags); - if (result < 0 && errno == EBUSY && comline->wait_opt) - sleep(1); - - } while (result < 0 && errno == EBUSY && comline->wait_opt); - - if (result) { - die("Error leaving cluster: %s", cman_error(errno)); - } - - close(cluster_sock); -} - -static void set_expected(commandline_t *comline) -{ - int cluster_sock; - int result; - - cluster_sock = open_cluster_socket(); - - if ((result = ioctl(cluster_sock, SIOCCLUSTER_SETEXPECTED_VOTES, - comline->expected_votes))) - die("can't set expected votes: %s", cman_error(errno)); - - close(cluster_sock); -} - -static void set_votes(commandline_t *comline) -{ - int cluster_sock; - int result; - - cluster_sock = open_cluster_socket(); - - if ((result = ioctl(cluster_sock, SIOCCLUSTER_SET_VOTES, - comline->votes))) - die("can't set votes: %s", cman_error(errno)); - - close(cluster_sock); -} - -static void version(commandline_t *comline) -{ - struct cl_version ver; - int cluster_sock; - int result; - - cluster_sock = open_cluster_socket(); - - if ((result = ioctl(cluster_sock, SIOCCLUSTER_GET_VERSION, &ver))) - die("can't get version: %s", cman_error(errno)); - - if (!comline->config_version) { - printf("%d.%d.%d config %d\n", ver.major, ver.minor, ver.patch, - ver.config); - goto out; - } - - ver.config = comline->config_version; - - if ((result = ioctl(cluster_sock, SIOCCLUSTER_SET_VERSION, &ver))) - die("can't set version: %s", cman_error(errno)); - out: - close(cluster_sock); -} - -static int wait_for_sock(int sock) -{ - int recvbuf[256]; /* Plenty big enough for an OOB message */ - int ret; - - ret = recv(sock, recvbuf, sizeof(recvbuf), MSG_OOB); - if (ret < 0) - { - return errno; - } - - /* EOF also means we are no longer connected to the cluster */ - if (ret == 0) - return ENOTCONN; - - return 0; -} - -static int cluster_wait(commandline_t *comline) -{ - int cluster_sock; - int ret = 0; - - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cluster_sock == -1) - die("can't open cluster socket, cman kernel module probably not loaded"); - - if (comline->wait_quorate_opt) { - while (ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0) <= 0) { - if ((ret = wait_for_sock(cluster_sock))) - goto end_wait; - } - } - else { - while (ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0) < 0) { - if ((ret = wait_for_sock(cluster_sock))) - goto end_wait; - } - } - - end_wait: - close(cluster_sock); - - return ret; -} - -static void kill_node(commandline_t *comline) -{ - int cluster_sock; - int i; - struct cl_cluster_node node; - - if (!comline->num_nodenames) { - die("No node name specified\n"); - } - - cluster_sock = open_cluster_socket(); - - for (i=0; i<comline->num_nodenames; i++) { - - /* Resolve node name into a number */ - node.node_id = 0; - strcpy(node.name, comline->nodenames[i]); - if (ioctl(cluster_sock, SIOCCLUSTER_GETNODE, &node)) { - fprintf(stderr, "Can't kill node %s : %s\n", node.name, strerror(errno)); - continue; - } - - - if (ioctl(cluster_sock, SIOCCLUSTER_KILLNODE, node.node_id)) - perror("kill node failed"); - } - - close(cluster_sock); -} - - -static int get_int_arg(char argopt, char *arg) -{ - char *tmp; - int val; - - val = strtol(arg, &tmp, 10); - if (tmp == arg || tmp != arg + strlen(arg)) - die("argument to %c (%s) is not an integer", argopt, arg); - - if (val < 0) - die("argument to %c cannot be negative", argopt); - - return val; -} - - -static void decode_arguments(int argc, char *argv[], commandline_t *comline) -{ - int cont = TRUE; - int optchar, i; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - - case 'i': - i = comline->num_interfaces; - if (i >= MAX_INTERFACES) - die("maximum of %d interfaces allowed", - MAX_INTERFACES); - comline->interfaces[i] = strdup(optarg); - if (!comline->interfaces[i]) - die("no memory"); - comline->num_interfaces++; - break; - - case 'm': - i = comline->num_multicasts; - if (i >= MAX_INTERFACES) - die("maximum of %d multicast addresses allowed", - MAX_INTERFACES); - if (strlen(optarg) > MAX_MCAST_NAME_LEN) - die("maximum multicast name length is %d", - MAX_MCAST_NAME_LEN); - comline->multicast_names[i] = strdup(optarg); - comline->num_multicasts++; - break; - - case 'n': - i = comline->num_nodenames; - if (i >= MAX_INTERFACES) - die("maximum of %d node names allowed", - MAX_INTERFACES); - if (strlen(optarg) > MAX_NODE_NAME_LEN) - die("maximum node name length is %d", - MAX_NODE_NAME_LEN); - comline->nodenames[i] = strdup(optarg); - comline->num_nodenames++; - break; - - case 'r': - comline->config_version = get_int_arg(optchar, optarg); - comline->config_version_opt = TRUE; - break; - - case 'v': - comline->votes = get_int_arg(optchar, optarg); - comline->votes_opt = TRUE; - break; - - case 'e': - comline->expected_votes = get_int_arg(optchar, optarg); - comline->expected_votes_opt = TRUE; - break; - - case '2': - comline->two_node = TRUE; - break; - - case 'p': - comline->port = get_int_arg(optchar, optarg); - comline->port_opt = TRUE; - break; - - case 'N': - comline->nodeid = get_int_arg(optchar, optarg); - comline->nodeid_opt = TRUE; - break; - - case 'c': - if (strlen(optarg) >= MAX_CLUSTER_NAME_LEN) - die("maximum cluster name length is %d", - MAX_CLUSTER_NAME_LEN); - strcpy(comline->clustername, optarg); - comline->clustername_opt = TRUE; - break; - - case 'X': - comline->no_ccs = TRUE; - break; - - case 'F': - comline->format_opts = strdup(optarg); - break; - - case 'V': - printf("cman_tool %s (built %s %s)\n", - CMAN_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case 'd': - comline->verbose++; - break; - - case 'w': - comline->wait_opt = TRUE; - break; - - case 'q': - comline->wait_quorate_opt = TRUE; - break; - - case 't': - comline->timeout = get_int_arg(optchar, optarg); - break; - - case EOF: - cont = FALSE; - break; - - default: - die("unknown option: %c", optchar); - break; - }; - } - - while (optind < argc) { - if (strcmp(argv[optind], "join") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_JOIN; - } else if (strcmp(argv[optind], "leave") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_LEAVE; - } else if (strcmp(argv[optind], "expected") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_EXPECTED; - } else if (strcmp(argv[optind], "votes") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_VOTES; - } else if (strcmp(argv[optind], "kill") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_KILL; - } else if (strcmp(argv[optind], "version") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_VERSION; - } else if (strcmp(argv[optind], "wait") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_WAIT; - } else if (strcmp(argv[optind], "status") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_STATUS; - } else if (strcmp(argv[optind], "nodes") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_NODES; - } else if (strcmp(argv[optind], "services") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_SERVICES; - } else if (strcmp(argv[optind], "remove") == 0) { - comline->remove = TRUE; - } else if (strcmp(argv[optind], "force") == 0) { - comline->force = TRUE; - } else - die("unknown option %s", argv[optind]); - - optind++; - } - - if (!comline->operation) - die("no operation specified"); -} - -static void check_arguments(commandline_t *comline) -{ - int error; - - if (!comline->expected_votes) - die("expected votes not set"); - - if (!comline->clustername[0]) - die("cluster name not set"); - - if (comline->votes < 0) - comline->votes = DEFAULT_VOTES; - - if (!comline->port) - comline->port = DEFAULT_PORT; - - if (comline->two_node && comline->expected_votes != 1) - die("expected_votes value (%d) invalid in two node mode", - comline->expected_votes); - - if (!comline->nodenames[0]) { - struct utsname utsname; - error = uname(&utsname); - if (error) - die("cannot get node name, uname failed"); - - comline->nodenames[0] = strdup(utsname.nodename); - comline->num_nodenames++; - } - - if (!comline->num_interfaces) { - comline->interfaces[0] = strdup("eth0"); - if (!comline->interfaces[0]) - die("no memory"); - } - - if (comline->num_multicasts != comline->num_interfaces) { - die("Number of multicast addresses (%d) must match number of " - "interfaces (%d)", comline->num_multicasts, - comline->num_interfaces); - } - - if (comline->num_nodenames && comline->num_multicasts && - comline->num_nodenames != comline->num_multicasts) { - die("Number of node names (%d) must match number of multicast " - "addresses (%d)", comline->num_nodenames, - comline->num_multicasts); - } - - if (comline->port <= 0 || comline->port > 65535) - die("Port must be a number between 1 and 65535"); - - /* This message looks like it contradicts the condition but - a nodeid of zero simply means "assign one for me" and is a - perfectly reasonable override */ - if (comline->nodeid < 0 || comline->nodeid > 4096) - die("Node id must be between 1 and 4096"); - - /* Cluster name needs to include trailing NUL */ - if (strlen(comline->clustername) > MAX_CLUSTER_NAME_LEN-1) { - die("Cluster name must be < %d characters long", - MAX_CLUSTER_NAME_LEN); - } - - if (comline->timeout && !comline->wait_opt && !comline->wait_quorate_opt) - die("timeout is only appropriate with wait"); -} - -int main(int argc, char *argv[]) -{ - commandline_t comline; - int ret; - - prog_name = argv[0]; - - memset(&comline, 0, sizeof(commandline_t)); - comline.votes = -1; - - decode_arguments(argc, argv, &comline); - - switch (comline.operation) { - case OP_JOIN: - if (!comline.no_ccs) - get_ccs_join_info(&comline); - check_arguments(&comline); - - if (comline.timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(comline.timeout); - } - - join(&comline); - if (comline.wait_opt || comline.wait_quorate_opt) { - do { - ret = cluster_wait(&comline); - if (ret == ENOTCONN) - join(&comline); - - } while (ret == ENOTCONN); - } - break; - - case OP_LEAVE: - leave(&comline); - break; - - case OP_EXPECTED: - set_expected(&comline); - break; - - case OP_VOTES: - set_votes(&comline); - break; - - case OP_KILL: - kill_node(&comline); - break; - - case OP_VERSION: - version(&comline); - break; - - case OP_WAIT: - if (comline.timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(comline.timeout); - } - cluster_wait(&comline); - break; - - case OP_STATUS: - show_status(); - break; - - case OP_NODES: - if ((comline.num_nodenames != 0) || - (comline.format_opts != NULL)) - { - show_nodes_opt(&comline); - } else { - show_nodes(); - } - break; - - case OP_SERVICES: - show_services(); - break; - - /* FIXME: support CLU_SET_NODENAME? */ - } - - exit(EXIT_SUCCESS); -} - -char *prog_name; diff --git a/cman/config/copyright.cf b/cman/config/copyright.cf deleted file mode 100644 index 8847c05..0000000 --- a/cman/config/copyright.cf +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) Red Hat, Inc. 2004 All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __COPYRIGHT_DOT_CF__ -#define __COPYRIGHT_DOT_CF__ - -#define REDHAT_COPYRIGHT ("Copyright (C) Red Hat, Inc. 2004 All rights reserved.") - -#endif /* __COPYRIGHT_DOT_CF__ */ - - - diff --git a/cman/configure b/cman/configure deleted file mode 100755 index dd4d532..0000000 --- a/cman/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/cman/init.d/Makefile b/cman/init.d/Makefile deleted file mode 100644 index d388d7e..0000000 --- a/cman/init.d/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= cman qdiskd - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -copytobin: - -clean: - -install: - install -d ${DESTDIR}/etc/init.d - install ${TARGET} ${DESTDIR}/etc/init.d - -uninstall: - ${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d diff --git a/cman/init.d/cman b/cman/init.d/cman deleted file mode 100755 index 85122ff..0000000 --- a/cman/init.d/cman +++ /dev/null @@ -1,224 +0,0 @@ -#!/bin/bash -# -# chkconfig: 345 21 79 -# description: Starts and stops cman -# -# -### BEGIN INIT INFO -# Provides: -### END INIT INFO - -# CMAN_CLUSTER_TIMEOUT -- amount of time to wait for joinging a cluster -# before giving up. If CMAN_CLUSTER_TIMEOUT is positive, then we will -# wait CMAN_CLUSTER_TIMEOUT seconds before giving up and failing when -# a cluster is not joined. If CMAN_CLUSTER_TIMEOUT is zero, then -# wait indefinately for a cluster join. If CMAN_CLUSTER_TIMEOUT is -# negative, do not check to see that the cluster has been joined -CMAN_CLUSTER_TIMEOUT=120 - -# CMAN_QUORUM_TIMEOUT -- amount of time to wait for a quorate cluster on -# startup quorum is needed by many other applications, so we may as -# well wait here. If CMAN_QUORUM_TIMEOUT is less than 1, quorum will -# be ignored. -CMAN_QUORUM_TIMEOUT=300 - -# CMAN_SHUTDOWN_TIMEOUT -- amount of time to wait for cman to become a -# cluster member before calling cman_tool leave during shutdown. -# default is 60 seconds -CMAN_SHUTDOWN_TIMEOUT=60 - -. /etc/init.d/functions -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - -LOCK_FILE="/var/lock/subsys/cman" - -[ -n "$CLUSTERNAME" ] && cman_join_opts="-c $CLUSTERNAME" - -in_cluster() -{ - grep -q "Cluster Member: Yes" /proc/cluster/status -} - - -start_qdiskd() -{ - declare current_runlevel - - current_runlevel=$(/sbin/runlevel 2>/dev/null | awk '{ print $2 }' 2>/dev/null) - # - # Start qdiskd before fenced to resolve bug #436381. This only - # happens if qdiskd is configured to run in the runlevel we are in - # - /sbin/chkconfig --levels "$current_runlevel" qdiskd 2>/dev/null - if [ $? -ne 0 ]; then - # qdiskd doesn't start at this runlevel. - return 0 - fi - - echo -n "Starting Quorum Disk Daemon:" - service qdiskd start &> /dev/null - if [ $? -eq 0 ] - then - echo_success - echo - else - echo_failure - echo - return 1 - fi - - return 0 -} - - -start() -{ - # Qdiskd will wait for CMAN to start, but if CMAN - # waits for qdiskd to start, it will delay booting by - # a very long time. So, start qdiskd if configured - # to do so. #469103 - # If qdiskd is not configured for this runlevel, this - # operation is a no-op. - start_qdiskd - - echo -n "Starting cman:" - - # If gulm is in ccs, don't start cman - # FIXME -- Should this be silent? I think users should get some - # feedback, but others might not want added verbosity to - # the boot process. Oh well... it's only one line :) - if ! [ -r /etc/cluster/cluster.conf ] - then - # TODO -- cman can start w/out cluster.conf file. This - # should not stop cman from starting up. - initlog -n ${0##*/} -s "/etc/cluster/cluster.conf was not detected" - elif grep -qE "<[[:space:]]*gulm([[:space:]]|[>]|$)" \ - /etc/cluster/cluster.conf - then - warning "Skipping because of <gulm> section detected in /etc/cluster/cluster.conf" - echo - exit 0 - fi - - rtrn=1 - - for try in block - do - # load the cman module (modprobe won't error if the modules - # are already loaded - errmsg=$(modprobe cman 2>&1) || break - - # try to load the dlm module - modprobe dlm &> /dev/null - - # TODO -- configure tunable paramters? - # [ -n "$CMAN_TRANSITION_RESTARTS" ] && - # echo $CMAN_TRANSITION_RESTARTS > \ - # /proc/cluster/config/cman/transition_restarts - - if in_cluster - then - rtrn=0 - break - fi - - # specify -w to make sure we have joined the cluster - # TODO -- should we call cman_tool leave if this times out? - errmsg=$(cman_tool -t $CMAN_CLUSTER_TIMEOUT -w join \ - $cman_join_opts 2>&1) || break - - # make sure that we are quorate? - if [ $CMAN_QUORUM_TIMEOUT -gt 0 ] - then - errmsg=$( cman_tool -t $CMAN_QUORUM_TIMEOUT \ - -q wait 2>&1 ) || break - fi - - rtrn=0 - done - - if [ $rtrn -eq 0 ] - then - success "startup" - echo - else - failure "$errmsg" - echo - fi - - # need the extra echo to properlly terminate the line - return $rtrn -} - -# This function can be called with an additional argument, remove -# The cman_tool command will fail if the additional argument is -# something else. -stop() -{ - echo -n "Stopping cman:" - rtrn=0 - if [ -r /proc/cluster/status ] - then - rtrn=1 - - cman_tool -t $CMAN_SHUTDOWN_TIMEOUT -w leave $1 &> /dev/null && rtrn=0 - - # allow cman time to clean up BZ 149282 - sleep 3 - - # try to unload dlm module - modprobe -r dlm &>/dev/null - - modprobe -r cman &>/dev/null - fi - - if [ $rtrn -eq 0 ] - then - success "shutdown" - echo - else - failure "failed to stop cman" - echo - fi - - # need the extra echo to properlly terminate the line - return $rtrn -} - -rtrn=1 - -# See how we were called. -case "$1" in - start) - start - rtrn=$? - [ $rtrn = 0 ] && touch $LOCK_FILE - ;; - - stop) - if [ $2 ]; then - stop - else - stop remove - fi - rtrn=$? - [ $rtrn = 0 ] && rm -f $LOCK_FILE - ;; - - restart) - $0 stop restart - $0 start - rtrn=$? - ;; - - status) - cat /proc/cluster/status 2>/dev/null - rtrn=$? - ;; - - *) - echo $"Usage: $0 {start|stop|restart|status}" - ;; -esac - -exit $rtrn diff --git a/cman/init.d/qdiskd b/cman/init.d/qdiskd deleted file mode 100755 index 1ba6940..0000000 --- a/cman/init.d/qdiskd +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -# -# chkconfig: 345 22 78 -# description: Starts and stops the quroum disk daemon -# -# -### BEGIN INIT INFO -# Provides: -### END INIT INFO - -. /etc/init.d/functions -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - -LOCK_FILE="/var/lock/subsys/qdiskd" - -rtrn=1 -retries=0 - -# See how we were called. -case "$1" in - start) - status qdiskd >/dev/null - if [ $? -eq 0 ]; then - exit 0 - fi - - action "Starting the Quorum Disk Daemon:" qdiskd -Q - rtrn=$? - if [ $rtrn = 0 ]; then - touch $LOCK_FILE - echo_success - echo - else - echo_failure - echo - fi - - ;; - - stop) - echo -n "Stopping the Quorum Disk Daemon:" - killproc qdiskd - while [ -n "`pidof qdiskd`" ] && [ $retries -lt 5 ]; do - sleep 1 - killproc qdiskd - ((retries++)) - done - if [ -z "`pidof qdiskd`" ]; then - echo_success - echo - rtrn=0 - rm -f $LOCK_FILE - else - echo_failure - echo - rtrn=1 - fi - ;; - - restart) - $0 stop || exit $? - $0 start - rtrn=$? - ;; - - status) - status qdiskd - rtrn=$? - ;; - - *) - echo $"Usage: $0 {start|stop|restart|status}" - ;; -esac - -exit $rtrn diff --git a/cman/lib/Makefile b/cman/lib/Makefile deleted file mode 100644 index 03f92f9..0000000 --- a/cman/lib/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2004 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE=libcman.c - -LIBNAME=libcman -SHAREDLIB=$(LIBNAME).so.${RELEASE_MAJOR}.${RELEASE_MINOR} -STATICLIB=$(LIBNAME).a - -top_srcdir=.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -CFLAGS += -g -O -I. -fPIC - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -CFLAGS += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -CFLAGS += -I${incdir}/cluster -endif - - -all: $(STATICLIB) $(SHAREDLIB) - -$(LIBNAME).a: libcman.o - ${AR} r libcman.a libcman.o - ${RANLIB} libcman.a - - -$(LIBNAME).so.${RELEASE_MAJOR}.${RELEASE_MINOR}: libcman.o - $(CC) -shared -o $@ -Wl,-soname=$(LIBNAME).so.$(RELEASE_MAJOR) $^ - -libcman.o: libcman.c - $(CC) $(CFLAGS) -c -o $@ $< - -copytobin: all - - -install: all - install -d ${incdir} - install libcman.h ${incdir} - install -d ${libdir} - install $(LIBNAME).a ${libdir} - install $(LIBNAME).so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir} - ln -sf $(LIBNAME).so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir}/$(LIBNAME).so - ln -sf $(LIBNAME).so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir}/$(LIBNAME).so.$(RELEASE_MAJOR) - -uninstall: - ${UNINSTALL} libcman.h ${incdir} - ${UNINSTALL} \ - ${LIBNAME}.a \ - $(LIBNAME).so \ - $(LIBNAME).so.$(RELEASE_MAJOR) \ - ${LIBNAME}.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir} \ - rm -f /lib/${LIBNAME}.* - -clean: - rm -f *.o *.a *.so *.so.* - rm -f *~ diff --git a/cman/lib/libcman.c b/cman/lib/libcman.c deleted file mode 100644 index b9d9286..0000000 --- a/cman/lib/libcman.c +++ /dev/null @@ -1,503 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with this library; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -** -******************************************************************************* -******************************************************************************/ - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <inttypes.h> -#include <unistd.h> -#include <stdlib.h> -#include <netinet/in.h> -#include <string.h> -#include <errno.h> -#include <cluster/cnxman-socket.h> -#include "libcman.h" - -struct cman_handle -{ - int fd; - void *private; - cman_callback_t callback; - cman_datacallback_t data_callback; -}; - - - -static void copy_node(cman_node_t *unode, struct cl_cluster_node *knode) -{ - unode->cn_nodeid = knode->node_id; - unode->cn_member = knode->state == NODESTATE_MEMBER?1:0; - strcpy(unode->cn_name, knode->name); - unode->cn_incarnation = knode->incarnation; - - /* These are not supported in this cman version */ - memset(&unode->cn_address, 0, sizeof(cman_node_address_t)); - memset(&unode->cn_jointime, 0, sizeof(struct timeval)); -} - - -cman_handle_t cman_init(void *private) -{ - struct cman_handle *h; - - h = malloc(sizeof(struct cman_handle)); - if (!h) - return NULL; - - h->private = private; - h->callback = NULL; - - h->fd = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (h->fd == -1) - { - int saved_errno = errno; - free(h); - errno = saved_errno; - return NULL; - } - return (cman_handle_t)h; -} - -int cman_finish(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - close(h->fd); - free(h); - - return 0; -} - -int cman_set_private(cman_handle_t *handle, void *private) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - h->private = private; - return 0; -} - -int cman_get_private(cman_handle_t *handle, void **private) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - *private = h->private; - - return 0; -} - -int cman_start_notification(cman_handle_t handle, cman_callback_t callback) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - if (!callback) - { - errno = EINVAL; - return -1; - } - - h->callback = callback; - - return 0; -} - -int cman_stop_notification(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - h->callback = NULL; - - return 0; -} - - -int cman_get_fd(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return h->fd; -} - -int cman_dispatch(cman_handle_t handle, int flags) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct iovec iov[1]; - struct msghdr msg; - struct sockaddr_cl saddr; - int len; - int recv_flags = MSG_OOB; - char buf[1600]; - - if (!(flags & CMAN_DISPATCH_BLOCKING)) - recv_flags |= MSG_DONTWAIT; - - - do { - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = &saddr; - msg.msg_flags = 0; - msg.msg_namelen = sizeof(saddr); - iov[0].iov_len = sizeof(buf); - iov[0].iov_base = buf; - - len = recvmsg(h->fd, &msg, recv_flags); - if (len < 0 && errno == EAGAIN) - return len; - - if (len == 0) { - errno = EHOSTDOWN; - return -1; - } - - /* Send a callback if registered */ - if (msg.msg_flags & MSG_OOB) - { - int reason; - int arg = 0; - switch (buf[0]) - { - case CLUSTER_OOB_MSG_PORTCLOSED: - reason = CMAN_REASON_PORTCLOSED; - arg = saddr.scl_nodeid; - break; - - case CLUSTER_OOB_MSG_STATECHANGE: - reason = CMAN_REASON_STATECHANGE; - break; - - case CLUSTER_OOB_MSG_SERVICEEVENT: - reason = CMAN_REASON_SERVICEEVENT; - break; - default: - continue; - } - if (h->callback) - h->callback(h, h->private, reason, arg); - } - else - { - if (h->data_callback) - h->data_callback(h, h->private, buf, len, saddr.scl_port, saddr.scl_nodeid); - } - - } - while ( flags & CMAN_DISPATCH_ALL && - !(len < 0 && errno == EAGAIN) ); - - return len; -} - -int cman_get_node_count(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_GETALLMEMBERS, 0); -} - -int cman_get_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_cluster_node *cman_nodes; - struct cl_cluster_nodelist cman_req; - int status; - int count = 0; - - if (!retnodes || !nodes || maxnodes < 1) - { - errno = EINVAL; - return -1; - } - - cman_nodes = malloc(sizeof(struct cl_cluster_node) * maxnodes); - if (!cman_nodes) - return -1; - - cman_req.max_members = maxnodes; - cman_req.nodes = cman_nodes; - status = ioctl(h->fd, SIOCCLUSTER_GETALLMEMBERS, &cman_req); - if (status < 0) - { - int saved_errno = errno; - free(cman_nodes); - errno = saved_errno; - return -1; - } - if (cman_nodes[0].size != sizeof(struct cl_cluster_node)) - { - free(cman_nodes); - errno = EINVAL; - return -1; - } - - for (count = 0; count < status; count++) - { - copy_node(&nodes[count], &cman_nodes[count]); - } - free(cman_nodes); - *retnodes = count; - return 0; -} - -int cman_get_node(cman_handle_t handle, int nodeid, cman_node_t *node) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_cluster_node cman_node; - int status; - - if (!node) - { - errno = EINVAL; - return -1; - } - - cman_node.node_id = nodeid; - cman_node.name[0] = 0;/* Get by id */ - status = ioctl(h->fd, SIOCCLUSTER_GETNODE, &cman_node); - if (status < 0) - return -1; - - copy_node(node, &cman_node); - - return 0; -} - -int cman_is_active(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_ISACTIVE, 0); -} - -int cman_is_listening(cman_handle_t handle, int nodeid, uint8_t port) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_listen_request req; - - req.port = port; - req.nodeid = nodeid; - return ioctl(h->fd, SIOCCLUSTER_ISLISTENING, &req); - -} -int cman_is_quorate(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_ISQUORATE, 0); -} - - -int cman_get_version(cman_handle_t handle, cman_version_t *version) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - if (!version) - { - errno = EINVAL; - return -1; - } - return ioctl(h->fd, SIOCCLUSTER_GET_VERSION, version); -} - -int cman_set_version(cman_handle_t handle, cman_version_t *version) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - if (!version) - { - errno = EINVAL; - return -1; - } - return ioctl(h->fd, SIOCCLUSTER_SET_VERSION, version); -} - -int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - if (!clinfo) - { - errno = EINVAL; - return -1; - } - return ioctl(h->fd, SIOCCLUSTER_GETCLUSTER, clinfo); -} - -int cman_send_data(cman_handle_t handle, char *buf, int len, int flags, uint8_t port, int nodeid) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct iovec iov[2]; - struct msghdr msg; - struct sockaddr_cl saddr; - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_flags = 0; - iov[0].iov_len = len; - iov[0].iov_base = buf; - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = port; - if (nodeid) { - msg.msg_name = &saddr; - msg.msg_namelen = sizeof(saddr); - saddr.scl_nodeid = nodeid; - } else { /* Cluster broadcast */ - - msg.msg_name = NULL; - msg.msg_namelen = 0; - } - - do { - len = sendmsg(h->fd, &msg, 0); - - } while (len == -1 && errno == EAGAIN); - return len; -} - - -int cman_start_recv_data(cman_handle_t handle, cman_datacallback_t callback, uint8_t port) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct sockaddr_cl saddr; - - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = port; - - if (bind(h->fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_cl))) { - return -1; - } - - h->data_callback = callback; - return 0; -} - -int cman_end_recv_data(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - - h->data_callback = NULL; - return 0; -} - - -/* Basic... barrier handling */ -int cman_barrier_register(cman_handle_t handle, char *name, int flags, int nodes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - - binfo.cmd = BARRIER_IOCTL_REGISTER; - strcpy(binfo.name, name); - binfo.flags = flags; - binfo.arg = nodes; - return ioctl(h->fd, SIOCCLUSTER_BARRIER, &binfo, sizeof(binfo)); -} - -int cman_barrier_change(cman_handle_t handle, char *name, int flags, int arg) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - - binfo.cmd = BARRIER_IOCTL_CHANGE; - strcpy(binfo.name, name); - binfo.flags = flags; - binfo.arg = arg; - return ioctl(h->fd, SIOCCLUSTER_BARRIER, &binfo, sizeof(binfo)); - -} - - -int cman_barrier_wait(cman_handle_t handle, char *name) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - - binfo.cmd = BARRIER_IOCTL_WAIT; - strcpy(binfo.name, name); - return ioctl(h->fd, SIOCCLUSTER_BARRIER, &binfo, sizeof(binfo)); -} - -int cman_barrier_delete(cman_handle_t handle, char *name) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - - binfo.cmd = BARRIER_IOCTL_DELETE; - strcpy(binfo.name, name); - return ioctl(h->fd, SIOCCLUSTER_BARRIER, &binfo, sizeof(binfo)); -} - - -int cman_register_quorum_device(cman_handle_t handle, char *name, int votes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_quorumdevice_info qd_info; - - if (votes <= 0 || strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) - { - errno = EINVAL; - return -1; - } - qd_info.votes = votes; - strcpy(qd_info.name, name); - - return ioctl(h->fd, SIOCCLUSTER_QD_REGISTER, &qd_info, sizeof(qd_info)); -} - -int cman_unregister_quorum_device(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_QD_UNREGISTER, NULL, 0); -} - -int cman_poll_quorum_device(cman_handle_t handle, int isavailable) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_QD_POLL, isavailable, sizeof(int)); -} - -int cman_get_subsys_count(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_GET_JOINCOUNT, NULL, 0); -} - - -int cman_kill_node(cman_handle_t handle, int nodeid) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_KILLNODE, nodeid, sizeof(int)); -} - - -int cman_set_expected_votes(cman_handle_t handle, int evotes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_SETEXPECTED_VOTES, evotes, sizeof(int)); -} - - -int cman_set_votes(cman_handle_t handle, int votes, int nodeid) -{ - struct cman_handle *h = (struct cman_handle *)handle; - return ioctl(h->fd, SIOCCLUSTER_SET_VOTES, nodeid, sizeof(int)); -} - diff --git a/cman/lib/libcman.h b/cman/lib/libcman.h deleted file mode 100644 index 86099e2..0000000 --- a/cman/lib/libcman.h +++ /dev/null @@ -1,165 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with this library; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -** -******************************************************************************* -******************************************************************************/ - -#ifndef _LIBCMAN_H_ -#define _LIBCMAN_H_ - -#include <netinet/in.h> -#define CMAN_MAX_ADDR_LEN sizeof(struct sockaddr_in6) -#define CMAN_MAX_NODENAME_LEN 255 -#define MAX_CLUSTER_NAME_LEN 16 -/* Pass this into cman_get_node() as the nodeid to get local node information */ -#define CMAN_NODEID_US 0 - -/* Pass this into cman_send_data to send a message to all nodes */ -#define CMAN_NODEID_ALL 0 - -/* Hang onto this, it's your key into the library. get one from cman_init() */ -typedef void *cman_handle_t; - -typedef enum {CMAN_REASON_PORTCLOSED, - CMAN_REASON_STATECHANGE, - CMAN_REASON_SERVICEEVENT} cman_call_reason_t; - - -/* Flags passed to cman_dispatch() */ -#define CMAN_DISPATCH_ONE 0 -#define CMAN_DISPATCH_ALL 1 -#define CMAN_DISPATCH_BLOCKING 2 - -/* A node address. this is a complete sockaddr_in[6] */ -typedef struct cman_node_address -{ - int cna_addrlen; - char cna_address[CMAN_MAX_ADDR_LEN]; -} cman_node_address_t; - -/* Return from cman_get_node() */ -typedef struct cman_node -{ - int cn_nodeid; - cman_node_address_t cn_address; - char cn_name[CMAN_MAX_NODENAME_LEN+1]; - int cn_member; - int cn_incarnation; - struct timeval cn_jointime; -} cman_node_t; - -/* Returned from cman_get_version(), input to cman_set_version() */ -typedef struct cman_version -{ - unsigned int cv_major; - unsigned int cv_minor; - unsigned int cv_patch; - unsigned int cv_config; -} cman_version_t; - -/* Return from cman_get_cluster() */ -typedef struct cman_cluster -{ - char ci_name[MAX_CLUSTER_NAME_LEN+1]; - uint16_t ci_number; -} cman_cluster_t; - -/* Callback routine for a membership event */ -typedef void (*cman_callback_t)(cman_handle_t handle, void *privdata, int reason, int arg); - -/* Callback routine for data received */ -typedef void (*cman_datacallback_t)(cman_handle_t handle, void *privdata, - char *buf, int len, uint8_t port, int nodeid); - - -/* cman_init returns the handle you need to pass to the other API calls, - cman_finish destroys that handle -*/ -cman_handle_t cman_init(void *privdata); -int cman_finish(cman_handle_t handle); - -/* Update/retrieve private data */ -int cman_set_private(cman_handle_t *h, void *privdata); -int cman_get_private(cman_handle_t *h, void **privdata); - -/* Notification of membership change events. NOte that these are sent after - a transition so multiple nodes may have left the cluster (but a maximum of - one will have joined) for each callback. -*/ -int cman_start_notification(cman_handle_t handle, cman_callback_t callback); -int cman_stop_notification(cman_handle_t handle); - -/* Get the internal CMAN fd so you can pass it into poll() or select(). - if it's active then call cman_dispatch() on the handle to process the event */ -int cman_get_fd(cman_handle_t handle); -int cman_dispatch(cman_handle_t handle, int flags); - -/* Get info calls, self-explanatory I hope. nodeid can be CMAN_NODEID_US */ - -int cman_get_node_count(cman_handle_t handle); -int cman_get_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes); -int cman_get_node(cman_handle_t handle, int nodeid, cman_node_t *node); -int cman_is_active(cman_handle_t handle); -int cman_is_listening(cman_handle_t handle, int nodeid, uint8_t port); -int cman_is_quorate(cman_handle_t handle); -int cman_get_version(cman_handle_t handle, cman_version_t *version); -int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo); -int cman_get_subsys_count(cman_handle_t handle); - - -/* "You should know what you're doing" calls */ -int cman_kill_node(cman_handle_t handle, int nodeid); -int cman_set_expected_votes(cman_handle_t handle, int evotes); - -/* Warning, 'nodeid' is ignored in this version of the library */ -int cman_set_votes(cman_handle_t handle, int votes, int nodeid); - - - -/* You can only set the config version via this call, not the - software/protocol version ! - */ -int cman_set_version(cman_handle_t handle, cman_version_t *version); - -/* Data transmission API. Uses the same FD as the rest of the calls. - If the nodeid passed to cman_send_data() is zero then it will be - broadcast to all nodes in the cluster. - cman_start_recv_data() is like a bind(), and marks the port - as "listening". See cman_is_listening() above. -*/ -int cman_send_data(cman_handle_t handle, char *buf, int len, int flags, uint8_t port, int nodeid); -int cman_start_recv_data(cman_handle_t handle, cman_datacallback_t, uint8_t port); -int cman_end_recv_data(cman_handle_t handle); - -/* - * Barrier API - */ -int cman_barrier_register(cman_handle_t handle, char *name, int flags, int nodes); -int cman_barrier_change(cman_handle_t handle, char *name, int flags, int arg); -int cman_barrier_wait(cman_handle_t handle, char *name); -int cman_barrier_delete(cman_handle_t handle, char *name); - -/* - * Add your own quorum device here - */ -int cman_register_quorum_device(cman_handle_t handle, char *name, int votes); -int cman_unregister_quorum_device(cman_handle_t handle); -int cman_poll_quorum_device(cman_handle_t handle, int isavailable); - -#endif diff --git a/cman/make/defines.mk.input b/cman/make/defines.mk.input deleted file mode 100644 index 19f85ab..0000000 --- a/cman/make/defines.mk.input +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/cman/make/flags.mk b/cman/make/flags.mk deleted file mode 100644 index 7b18984..0000000 --- a/cman/make/flags.mk +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - diff --git a/cman/make/release.mk.input b/cman/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/cman/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/cman/man/Makefile b/cman/man/Makefile deleted file mode 100644 index 8c379c4..0000000 --- a/cman/man/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -install: - install -d ${mandir}/man5 - install -d ${mandir}/man8 - install cman.5 qdisk.5 ${mandir}/man5 - install cman_tool.8 qdiskd.8 mkqdisk.8 ${mandir}/man8 - -uninstall: - ${UNINSTALL} cman.5 qdisk.5 ${mandir}/man5 - ${UNINSTALL} cman_tool.8 qdiskd.8 mkqdisk.8 ${mandir}/man8 - diff --git a/cman/man/cman.5 b/cman/man/cman.5 deleted file mode 100644 index 5110b95..0000000 --- a/cman/man/cman.5 +++ /dev/null @@ -1,114 +0,0 @@ -." -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -." groff -t -e -mandoc -Tlatin1 cman.5 | less - -.tl 'cman(5)' 'cman(5)' - -\fBNAME\fP -.in +7 -cman - cluster.conf cman configuration section -.sp -.in -7 - - -\fBDESCRIPTION\fP -.in +7 -Cman configuration values are placed in the <cman> </cman> section of -\fBcluster.conf\fP. Per-node configuration related to cman is placed -in the standard <clusternode> </clusternode> sections. All cman -configuration settings are optional; usually none are used. -.in -7 - - -\fIUDP port\fR -.in +7 -By default, cman will use UDP port 6809 for internode communication. This can -be changed by setting a port number as follows: - - <cman port="6809"> - </cman> -.in -7 - - -\fIExpected votes\fR -.in +7 -The expected votes value is used by cman to determine quorum. The cluster is -quorate if the sum of votes of existing members is over half of the expected -votes value. By default, cman_tool sets the expected votes value to be the sum -of votes of all nodes listed in cluster.conf. This can be overriden by setting -an explicit expected_votes value as follows: - - <cman expected_votes="3"> - </cman> - -If the cluster becomes partitioned, improper use of this option can result -in more than one partition gaining quorum. In that event, nodes in each -partition will enable cluster services. -.in -7 - - -\fITwo node clusters\fR -.in +7 -Ordinarily, the loss of quorum after one out of two nodes fails will prevent -the remaining node from continuing (if both nodes have one vote.) Special -configuration options can be set to allow the one remaining node to continue -operating if the other fails. To do this only two nodes, each with one vote, -can be defined in cluster.conf. The two_node and expected_votes values must -then be set to 1 in the cman section as follows. - - <cman two_node="1" expected_votes="1"> - </cman> -.in -7 - - -\fINode votes\fR -.in +7 -By default, a node is given one vote toward the calculation of quorum. -This can be changed by giving a node a specific number of votes as -follows: - - <clusternode name="nd1" votes="2"> - </clusternode> -.in -7 - - -\fINode ID\fR -.in +7 - -By default, a node is assigned a nodeid by the cluster manager (cman) when -it joins the cluster. This can be overriden by specifying a nodeid here. -Using this option will ensure that a given node always has the same ID. -A node's application to join the cluster may be rejected if you try to set -the nodeid to one that is already used. - - <clusternode name="nd1" nodeid="1"> - </clusternode> -.in -7 - - -\fIMulticast network configuration\fR -.in +7 -Cman can be configured to use multicast instead of broadcast (broadcast is used -by default if no multicast parameters are given.) To configure multicast add -one line under the <cman> section and another under the <clusternode> section: - - <cman> - <multicast addr="224.0.0.1"/> - </cman> - - <clusternode name="nd1"> - <multicast addr="224.0.0.1" interface="eth0"/> - </clusternode> - -The multicast addresses must match and the address must be usable on the -interface name given for the node. -.in -7 - - -.sp -.in -7 -\fBSEE ALSO\fP -.in +7 -cluster.conf(5), ccs(7), cman_tool(8) - diff --git a/cman/man/cman_tool.8 b/cman/man/cman_tool.8 deleted file mode 100644 index b51e8e1..0000000 --- a/cman/man/cman_tool.8 +++ /dev/null @@ -1,306 +0,0 @@ -.TH CMAN_TOOL 8 "Nov 23 2004" "Cluster utilities" - -.SH NAME -cman_tool - Cluster Management Tool -.SH SYNOPSIS -.B cman_tool join | leave | kill | expected | votes | version | wait | status | nodes | services [options] -.br -.SH DESCRIPTION -.PP -.B cman_tool -is a program that manages the cluster management subsystem CMAN. cman_tool -can be used to join the node to a cluster, leave the cluster, kill another -cluster node or change the value of expected votes of a cluster. -.br -Be careful that you understand the consequences of the commands issued via cman_tool -as they can affect all nodes in your cluster. Most of the time the cman_tool -will only be invoked from your startup and shutdown scripts. -.br -.SH SUBCOMMANDS -.TP -.I join -This is the main use of cman_tool. It instructs the cluster manager to attempt -to join an existing cluster or (if no existing cluster exists) then to form -a new one on its own. -.br -If no options are given to this command then it will take the cluster -configuration information from CCS. However, it is possible to provide -all the information on the command-line or to override CCS values by using -the command line. - -.TP -.I leave -Tells CMAN to leave the cluster. You cannot do this if there are subsystems -(eg DLM, GFS) active. You should dismount all GFS filesystems, -shutdown CLVM, fenced and anything else using the cluster manager before -using -.B cman_tool leave. -Look at 'cman_tool status|services' to see how many (and which) services are -running. -.br -When a node leaves the cluster, the remaining nodes recalculate quorum and this -may block cluster activity if the required number of votes is not present. -If this node is to be down for an extended period of time and you need to -keep the cluster running, add the -.B remove -option, and the remaining nodes will recalculate quorum such that activity -can continue. - -.TP -.I kill -Tells CMAN to kill another node in the cluster. This will cause the local -node to send a "KILL" message to that node and it will shut down. Recovery -will occur for the killed node as if it had failed. This is a sort of remote -version of "leave force" so only use if if you really know what you are doing. - -.TP -.I expected -Tells CMAN a new value of expected votes and instructs it to recalculate -quorum based on this value. -.br -Use this option if your cluster has lost quorum due to nodes failing and -you need to get it running again in a hurry. - -.TP -.I version -Used alone this will report the major, minor, patch and config versions -used by CMAN (also displayed in 'cman_tool status'). It can also be used -with -r to set a new config version on all cluster members. - -.TP -.I wait -Waits until the node is a member of the cluster and then returns. - -.TP -.I status -Displays the local view of the cluster status. - -.TP -.I nodes -Displays the local view of the cluster nodes. - -.TP -.I services -Displays the local view of the cluster services. - -.SH "LEAVE" OPTIONS -.TP -.I -w -Normally, "cman_tool leave" will fail if the cluster is in transition (ie -another node is joining or leaving the cluster). By adding the -w flag, -cman_tool will wait and retry the leave operation repeatedly until it succeeds -or a more serious error occurs. -.TP -.I -t <seconds> -If -w is also specified then -t dictates the maximum amount of time cman_tool -is prepared to wait. If the operation times out then a status of 2 is returned. -.TP -.I force -Shuts down the cluster manager without first telling any of the subsystems -to close down. Use this option with extreme care as it could easily cause data -loss. -.TP -.I remove -Tells the rest of the cluster to recalculate quorum such that activity can -continue without this node. - -.SH "EXPECTED" OPTIONS -.TP -.I -e <expected-votes> -The new value of expected votes to use. This will usually be enough -to bring the cluster back to life. Values that would cause incorrect -quorum will be rejected. - -.SH "KILL" OPTIONS -.TP -.I -n <nodename> -The node name of the node to be killed. This should be the unqualified node -name as it appears in 'cman_tool nodes'. - -.SH "VERSION" OPTIONS -.TP -.I -r <config_version> -The new config version. - -.SH "WAIT" OPTIONS -.TP -.I -q -Waits until the cluster is quorate before returning. -.I -t <seconds> -Dictates the maximum amount of time cman_tool is prepared to wait. -If the operation times out then a status of 2 is returned. - -.SH "JOIN" OPTIONS -.TP -.I -X -Tells cman_tool to ignore CCS altogether. All of the information necessary -to join the cluster must be provided on the command-line. Note that if -you get this wrong, it is possible that the node will form a cluster on -it's own and ignore a cluster it is supposed to be joining, so this method -of invocation is not recommended. -.TP -.I -c <clustername> -Provides a text name for the cluster. You can have several clusters on one -LAN and they are distinguished by this name. Note that the name is hashed to -provide a unique number which is what actually distinguishes the cluster, so -it is possible that two different names can clash. If this happens, the node -will not be allowed into the existing cluster and you will have to pick -another name or use different port number for cluster communication. -.TP -.I -p <port> -UDP port number used for cluster communication. This defaults to 6809. -.TP -.I -v <votes> -Number of votes this node has in the cluster. Defaults to 1. -.TP -.I -e <expected votes> -Number of expected votes for the whole cluster. If different nodes -provide different values then the highest is used. The cluster will -only operate when quorum is reached - that is more than half the -available votes are available to the cluster. There is no default for -this value. If you are using CCS then ccs_tool will use the total -number of votes for all nodes in the configuration file. -.TP -.I -2 -Sets the cluster up for a special "two node only" mode. Because of the -quorum requirements mentioned above, a two-node cluster cannot be valid. -This option tells the cluster manager that there will only ever be two -nodes in the cluster and relies on fencing to ensure cluster integrity. -If you specify this you cannot add more nodes without taking down the -existing cluster and reconfiguring it. Expected votes should be set to -1 for a two-node cluster. -.TP -.I -n <nodename> -Overrides the node name. By default the unqualified hostname is used. This -option can also be used to specify which interface is used for cluster -communication as cman_tool will (unless multicast is specified below) -use the broadcast address associated with that hostname. If you -are using IPv6 then you will have to use multicast rather than broadcast. -.TP -.I -N <nodeid> -Overrides the node ID for this node. Normally, nodes are assigned a -node id by the cluster join mechanism. If you want to ensure that -your nodes always have the same number regardless of the order in -which they join the cluster then you can hard-code these IDs. -.BR -Setting node IDs in CCS is a far better way to do this though. -.BR -Note that the node's application to join the cluster may be rejected if you -try to set the nodeid to one that has already been used, or if the node -was previously a member of the cluster but with a different nodeid. -.TP -.I -m <multicast-address> -Specifies a multicast address to use for cluster communication. This -is required for IPv6 operation. You should also specify an ethernet -interface to bind to this multicast address using the -i option. -.TP -.I -i <interface> -Used in conjunction with -m above to specify the interface for -multicast to use. -.TP -.I -w -Join and wait until the node is a cluster member. -.TP -.I -q -Join and wait until the cluster is quorate. -If the cluster join fails and -w (or -q) is specified, then it will be retried. Note that -cman_tool cannot tell whether the cluster join was rejected by another node for a good reason -or that it timed out for some benign reason; so it is strongly recommended that a timeout -is also given with the wait options to join. If you don't want join to retry on failure but -do want to wait, use the -.B cman_tool join -command without -w followed by -.B cman_tool wait. -.TP -.I -t <seconds> -If -w or -q is also specified then -t dictates the maximum amount of time cman_tool -is prepared to wait. If the operation times out then a status of 2 is returned. -Note that just because cman_tool has given up, does not mean that cman itself -has stopped trying to join a cluster. - -.SH "NODES" OPTIONS -.TP -.I -n <nodename> -Shows node information for a specific node. This should be the unqualified node -name as it appears in 'cman_tool nodes'. -.TP -.I -F <format> -Specify the format of the output. The format string may contain one or -more format options, each seperated by a comma. Valid format options -include: id, name, type, and addr. - -.br -.SH "SERVICES" OUTPUT - -Lists the gfs, dlm, fence and rgmanager (user) groups registered locally -with cman. Cman manages the membership of each group, and coordinates -their recovery. The group name, global ID, local ID, State and Code are -shown for each group. The nodeid's of the current group members are shown -on the second line within "[ ... ]". - -The following details relate to the internal cman group states and can be -useful for debugging. - -\fBGroup states\fP include: -.TP 8 -.I run -normal operation, no transition in progress -.TP -.I join -local node is joining the group -.TP -.I update -local node is adding/removing another node to/from the group -.TP -.I recover -group is being recovered from the failure of a member - - -.TP 0 -\fBRecovery codes\fP indicating the local state of recovery: - -.TP 2 -1 -STOP the group has been told to stop in preparation for a recovery -.TP -2 -START the group has been told to do recovery -.TP -3 -STARTDONE the group has finished recovery locally -.TP -4 -BARRIERWAIT the group has finished recovery locally and is waiting for -remote nodes to finish their recovery, too -.TP -5 -BARRIERDONE recovery for the group has completed on all nodes, and all -nodes have joined the completion barrier - -.TP 0 -\fBEvent codes\fP related to nodes joining and leaving the group. There -are two forms these codes can take: - -.TP 0 -S-se_state,se_flags,se_reply_count -.TP 4 -"S" indicates that the local node is joining or leaving the group. -.br -se_state is the state of the sevent, see SEST_* in sm_internal.h. -.br -se_flags are flags in the sevent, see SEFL_* in sm_internal.h. -.br -se_reply_count is the number of ack's received for the sevent. - -.TP 0 -U-ue_state,ue_flags,ue_nodeid -.TP 4 -"U" indicates that the local node is processing the join or leave of -another node. -.br -ue_state is the state of the uevent, see UEST_* in sm_internal.h. -.br -ue_flags are flags in the uevent, see UEFL_* in sm_internal.h. -.br -ue_nodeid is the node whose join or leave the uevent relates to. - diff --git a/cman/man/mkqdisk.8 b/cman/man/mkqdisk.8 deleted file mode 100644 index ca3009a..0000000 --- a/cman/man/mkqdisk.8 +++ /dev/null @@ -1,28 +0,0 @@ -.TH "mkqdisk" "8" "July 2006" "" "Quorum Disk Management" -.SH "NAME" -mkqdisk - Cluster Quorum Disk Utility -.SH "WARNING" -Use of this command can cause the cluster to malfunction. -.SH "SYNOPSIS" -\fBmkqdisk [-?|-h] | [-L] | [-f \fPlabel\fB] [-c \fPdevice \fB -l \fPlabel\fB] -.SH "DESCRIPTION" -.PP -The \fBmkqdisk\fP command is used to create a new quorum disk or display -existing quorum disks accessible from a given cluster node. -.SH "OPTIONS" -.IP "-c device -l label" -Initialize a new cluster quorum disk. This will destroy all data on the given -device. If a cluster is currently using that device as a quorum disk, the -entire cluster will malfunction. Do not run this on an active cluster when -qdiskd is running. Only one device on the SAN should ever have the given -label; using multiple different devices is currently not supported (it is -expected a RAID array is used for quorum disk redundancy). The label can be -any textual string up to 127 characters - and is therefore enough space to hold -a UUID created with uuidgen(1). -.IP "-f label" -Find the cluster quorum disk with the given label and display information about it. -.IP "-L" -Display information on all accessible cluster quorum disks. - -.SH "SEE ALSO" -qdisk(5), qdiskd(8), uuidgen(1) diff --git a/cman/man/qdisk.5 b/cman/man/qdisk.5 deleted file mode 100644 index e5c5947..0000000 --- a/cman/man/qdisk.5 +++ /dev/null @@ -1,461 +0,0 @@ -.TH "QDisk" "5" "06 Sep 2007" "" "Cluster Quorum Disk" -.SH "NAME" -QDisk 1.2.1 - a disk-based quorum daemon for CMAN / Linux-Cluster -.SH "1. Overview" -.SH "1.1 Problem" -In some situations, it may be necessary or desirable to sustain -a majority node failure of a cluster without introducing the need for -asymmetric cluster configurations (e.g. client-server, or heavily-weighted -voting nodes). - -.SH "1.2. Design Requirements" -* Ability to sustain 1..(n-1)/n simultaneous node failures, without the -danger of a simple network partition causing a split brain. That is, we -need to be able to ensure that the majority failure case is not merely -the result of a network partition. - -* Ability to use external reasons for deciding which partition is the -the quorate partition in a partitioned cluster. For example, a user may -have a service running on one node, and that node must always be the master -in the event of a network partition. Or, a node might lose all network -connectivity except the cluster communication path - in which case, a -user may wish that node to be evicted from the cluster. - -* Integration with CMAN. We must not require CMAN to run with us (or -without us). Linux-Cluster does not require a quorum disk normally - -introducing new requirements on the base of how Linux-Cluster operates -is not allowed. - -* Data integrity. In order to recover from a majority failure, fencing -is required. The fencing subsystem is already provided by Linux-Cluster. - -* Non-reliance on hardware or protocol specific methods (i.e. SCSI -reservations). This ensures the quorum disk algorithm can be used on the -widest range of hardware configurations possible. - -* Little or no memory allocation after initialization. In critical paths -during failover, we do not want to have to worry about being killed during -a memory pressure situation because we request a page fault, and the Linux -OOM killer responds... - -.SH "1.3. Hardware Considerations and Requirements" -.SH "1.3.1. Concurrent, Synchronous, Read/Write Access" -This quorum daemon requires a shared block device with concurrent read/write -access from all nodes in the cluster. The shared block device can be -a multi-port SCSI RAID array, a Fiber-Channel RAID SAN, a RAIDed iSCSI -target, or even GNBD. The quorum daemon uses O_DIRECT to write to the -device. - -.SH "1.3.2. Bargain-basement JBODs need not apply" -There is a minimum performance requirement inherent when using disk-based -cluster quorum algorithms, so design your cluster accordingly. Using a -cheap JBOD with old SCSI2 disks on a multi-initiator bus will cause -problems at the first load spike. Plan your loads accordingly; a node's -inability to write to the quorum disk in a timely manner will cause the -cluster to evict the node. Using host-RAID or multi-initiator parallel -SCSI configurations with the qdisk daemon is unlikely to work, and will -probably cause administrators a lot of frustration. That having been -said, because the timeouts are configurable, most hardware should work -if the timeouts are set high enough. - -.SH "1.3.3. Fencing is Required" -In order to maintain data integrity under all failure scenarios, use of -this quorum daemon requires adequate fencing, preferrably power-based -fencing. Watchdog timers and software-based solutions to reboot the node -internally, while possibly sufficient, are not considered 'fencing' for -the purposes of using the quorum disk. - -.SH "1.4. Limitations" -* At this time, this daemon supports a maximum of 16 nodes. This is -primarily a scalability issue: As we increase the node count, we increase -the amount of synchronous I/O contention on the shared quorum disk. - -* Cluster node IDs must be statically configured in cluster.conf and -must be numbered from 1..16 (there can be gaps, of course). - -* Cluster nodes must have one vote each. The effects of nodes having -any number of votes besides 1 has not been explored. - -* CMAN must be running before the qdisk program can operate in full -capacity. If CMAN is not running, qdisk will wait for it. - -* CMAN's eviction timeout should be at least 2x the quorum daemon's -to give the quorum daemon adequate time to converge on a master during a -failure + load spike situation. - -* For 'all-but-one' failure operation, the total number of votes assigned -to the quorum device should be equal to the number of nodes in the cluster -minus 1. For example, if you have 3 nodes in the cluster, each node should -get one vote and qdisk should get 2 votes. This then lets the cluster -operate without qdisk if all nodes are online for testing and other purposes. - -* For 'tiebreaker' operation in a two-node cluster, unset CMAN's two_node -flag (or set it to 0), set CMAN's expected votes to '3', set each node's -vote to '1', and set qdisk's vote count to '1' as well. This will allow -the cluster to operate if either both nodes are online, or a single node & -the heuristics. - -* Currently, the quorum disk daemon is difficult to use with CLVM if -the quorum disk resides on a CLVM logical volume. CLVM requires a -quorate cluster to correctly operate, which introduces a chicken-and-egg -problem for starting the cluster: CLVM needs quorum, but the quorum daemon -needs CLVM (if and only if the quorum device lies on CLVM-managed storage). -One way to work around this is to *not* set the cluster's expected votes -to include the quorum daemon's votes. Bring all nodes online, and start -the quorum daemon *after* the whole cluster is running. This will allow -the expected votes to increase naturally. - -.SH "2. Algorithms" -.SH "2.1. Heartbeating & Liveliness Determination" -Nodes update individual status blocks on the quorum disk at a user- -defined rate. Each write of a status block alters the timestamp, which -is what other nodes use to decide whether a node has hung or not. If, -after a user-defined number of 'misses' (that is, failure to update a -timestamp), a node is declared offline. After a certain number of 'hits' -(changed timestamp + "i am alive" state), the node is declared online. - -The status block contains additional information, such as a bitmask of -the nodes that node believes are online. Some of this information is -used by the master - while some is just for performace recording, and -may be used at a later time. The most important pieces of information -a node writes to its status block are: - -.in 12 -- Timestamp -.br -- Internal state (available / not available) -.br -- Score -.br -- Known max score (may be used in the future to detect invalid configurations) -.br -- Vote/bid messages -.br -- Other nodes it thinks are online -.in 0 - -.SH "2.2. Scoring & Heuristics" -The administrator can configure up to 10 purely arbitrary heuristics, and -must exercise caution in doing so. At least one administrator- -defined heuristic is required for operation, but it is generally a good -idea to have more than one heuristic. By default, only nodes scoring over -1/2 of the total maximum score will claim they are available via the -quorum disk, and a node (master or otherwise) whose score drops too low -will remove itself (usually, by rebooting). - -The heuristics themselves can be any command executable by 'sh -c'. For -example, in early testing the following was used: - -.ti 12 -<\fBheuristic \fP\fIprogram\fP\fB="\fP[ -f /quorum ]\fB" \fP\fIscore\fP\fB="\fP10\fB" \fP\fIinterval\fP\fB="\fP2\fB"/>\fP - -This is a literal sh-ism which tests for the existence of a file called -"/quorum". Without that file, the node would claim it was unavailable. -This is an awful example, and should never, ever be used in production, -but is provided as an example as to what one could do... - -Typically, the heuristics should be snippets of shell code or commands which -help determine a node's usefulness to the cluster or clients. Ideally, you -want to add traces for all of your network paths (e.g. check links, or -ping routers), and methods to detect availability of shared storage. - -.SH "2.3. Master Election" -Only one master is present at any one time in the cluster, regardless of -how many partitions exist within the cluster itself. The master is -elected by a simple voting scheme in which the lowest node which believes -it is capable of running (i.e. scores high enough) bids for master status. -If the other nodes agree, it becomes the master. This algorithm is -run whenever no master is present. - -If another node comes online with a lower node ID while a node is still -bidding for master status, it will rescind its bid and vote for the lower -node ID. If a master dies or a bidding node dies, the voting algorithm -is started over. The voting algorithm typically takes two passes to -complete. - -Master deaths take marginally longer to recover from than non-master -deaths, because a new master must be elected before the old master can -be evicted & fenced. - -.SH "2.4. Master Duties" -The master node decides who is or is not in the master partition, as -well as handles eviction of dead nodes (both via the quorum disk and via -the linux-cluster fencing system by using the cman_kill_node() API). - -.SH "2.5. How it All Ties Together" -When a master is present, and if the master believes a node to be online, -that node will advertise to CMAN that the quorum disk is available. The -master will only grant a node membership if: - -.in 12 -(a) CMAN believes the node to be online, and -.br -(b) that node has made enough consecutive, timely writes -.in 16 -to the quorum disk, and -.in 12 -(c) the node has a high enough score to consider itself online. -.in 0 - -.SH "3. Configuration" -.SH "3.1. The <quorumd> tag" -This tag is a child of the top-level <cluster> tag. - -.in 8 -\fB<quorumd\fP -.in 9 -\fIinterval\fP\fB="\fP1\fB"\fP -.in 12 -This is the frequency of read/write cycles, in seconds. - -.in 9 -\fItko\fP\fB="\fP10\fB"\fP -.in 12 -This is the number of cycles a node must miss in order to be declared dead. - -.in 9 -\fItko_up\fP\fB="\fPX\fB"\fP -.in 12 -This is the number of cycles a node must be seen in order to be declared -online. Default is \fBfloor(tko/3)\fP. - -.in 9 -\fIupgrade_wait\fP\fB="\fP2\fB"\fP -.in 12 -This is the number of cycles a node must wait before initiating a bid -for master status after heuristic scoring becomes sufficient. The -default is 2. This can not be set to 0, and should not exceed \fBtko\fP. - -.in 9 -\fImaster_wait\fP\fB="\fPX\fB"\fP -.in 12 -This is the number of cycles a node must wait for votes before declaring -itself master after making a bid. Default is \fBfloor(tko/2)\fP. -This can not be less than 2, must be greater than tko_up, and should not -exceed \fBtko\fP. - -.in 9 -\fIvotes\fP\fB="\fP3\fB"\fP -.in 12 -This is the number of votes the quorum daemon advertises to CMAN when it -has a high enough score. - -.in 9 -\fIlog_level\fP\fB="\fP4\fB"\fP -.in 12 -This controls the verbosity of the quorum daemon in the system logs. -0 = emergencies; 7 = debug. - -.in 9 -\fIlog_facility\fP\fB="\fPdaemon\fB"\fP -.in 12 -This controls the syslog facility used by the quorum daemon when logging. -For a complete list of available facilities, see \fBsyslog.conf(5)\fP. -The default value for this is 'daemon'. - -.in 9 -\fIstatus_file\fP\fB="\fP/foo\fB"\fP -.in 12 -Write internal states out to this file periodically ("-" = use stdout). -This is primarily used for debugging. The default value for this -attribute is undefined. - -.in 9 -\fImin_score\fP\fB="\fP3\fB"\fP -.in 12 -Absolute minimum score to be consider one's self "alive". If omitted, -or set to 0, the default function "floor((n+1)/2)" is used, where \fIn\fP -is the total of all of defined heuristics' \fIscore\fP attribute. This -must never exceed the sum of the heuristic scores, or else the quorum -disk will never be available. - -.in 9 -\fIreboot\fP\fB="\fP1\fB"\fP -.in 12 -If set to 0 (off), qdiskd will *not* reboot after a negative transition -as a result in a change in score (see section 2.2). The default for -this value is 1 (on). - -.in 9 -\fIallow_kill\fP\fB="\fP1\fB"\fP -.in 12 -If set to 0 (off), qdiskd will *not* instruct to kill nodes it thinks -are dead (as a result of not writing to the quorum disk). The default -for this value is 1 (on). - -.in 9 -\fIparanoid\fP\fB="\fP0\fB"\fP -.in 12 -If set to 1 (on), qdiskd will watch internal timers and reboot the node -if it takes more than (interval * tko) seconds to complete a quorum disk -pass. The default for this value is 0 (off). - -.in 9 -\fIio_timeout\fP\fB="\fP0\fB"\fP -.in 12 -If set to 1 (on), qdiskd will watch internal timers and reboot the node -if qdisk is not able to write to disk after (interval * tko) seconds. -The default for this value is 0 (off). - -.in 9 -\fIscheduler\fP\fB="\fPrr\fB"\fP -.in 12 -Valid values are 'rr', 'fifo', and 'other'. Selects the scheduling queue -in the Linux kernel for operation of the main & score threads (does not -affect the heuristics; they are always run in the 'other' queue). Default -is 'rr'. See sched_setscheduler(2) for more details. - -.in 9 -\fIpriority\fP\fB="\fP1\fB"\fP -.in 12 -Valid values for 'rr' and 'fifo' are 1..100 inclusive. Valid values -for 'other' are -20..20 inclusive. Sets the priority of the main & score -threads. The default value is 1 (in the RR and FIFO queues, higher numbers -denote higher priority; in OTHER, lower values denote higher priority). - -.in 9 -\fIstop_cman\fP\fB="\fP0\fB"\fP -.in 12 -Ordinarily, cluster membership is left up to CMAN, not qdisk. -If this parameter is set to 1 (on), qdiskd will tell CMAN to leave the -cluster if it is unable to initialize the quorum disk during startup. This -can be used to prevent cluster participation by a node which has been -disconnected from the SAN. The default for this value is 0 (off). - -.in 9 -\fIuse_uptime\fP\fB="\fP1\fB"\fP -.in 12 -If this parameter is set to 1 (on), qdiskd will use values from -/proc/uptime for internal timings. This is a bit less precise -than \fBgettimeofday(2)\fP, but the benefit is that changing the -system clock will not affect qdiskd's behavior - even if \fBparanoid\fP -is enabled. If set to 0, qdiskd will use \fBgettimeofday(2)\fP, which -is more precise. The default for this value is 1 (on / use uptime). - -.in 9 -\fIdevice\fP\fB="\fP/dev/sda1\fB"\fP -.in 12 -This is the device the quorum daemon will use. This device must be the -same on all nodes. - -.in 9 -\fIlabel\fP\fB="\fPmylabel\fB"/>\fP -.in 12 -This overrides the device field if present. If specified, the quorum -daemon will read /proc/partitions and check for qdisk signatures -on every block device found, comparing the label against the specified -label. This is useful in configurations where the block device name -differs on a per-node basis. - -.in 9 -\fIcman_label\fP\fB="\fPmylabel\fB"/>\fP -.in 12 -This overrides the label advertised to CMAN if present. If specified, -the quorum daemon will register with this name instead of the actual -device name. -.in 8 -\fB...>\fP -.in 0 - -.SH "3.2. The <heuristic> tag" -This tag is a child of the <quorumd> tag. - -.in 8 -\fB<heuristic\fP -.in 9 -\fIprogram\fP\fB="\fP/test.sh\fB"\fP -.in 12 -This is the program used to determine if this heuristic is alive. This -can be anything which may be executed by \fI/bin/sh -c\fP. A return -value of zero indicates success; anything else indicates failure. This -is required. - -.in 9 -\fIscore\fP\fB="\fP1\fB"\fP -.in 12 -This is the weight of this heuristic. Be careful when determining scores -for heuristics. The default score for each heuristic is 1. - -.in 9 -\fIinterval\fP\fB="\fP2\fB"/>\fP -.in 12 -This is the frequency (in seconds) at which we poll the heuristic. The -default interval for every heuristic is 2 seconds. -.in 0 - -.in 9 -\fItko\fP\fB="\fP1\fB"/>\fP -.in 12 -After this many failed attempts to run the heuristic, it is considered DOWN, -and its score is removed. The default tko for each heuristic is 1, which -may be inadequate for things such as 'ping'. -.in 8 -\fB/>\fP -.in 0 - - -.SH "3.3. Examples" -.SH "3.3.1. 3 cluster nodes & 3 routers" -.in 8 -<cman expected_votes="6" .../> -.br -<clusternodes> -.in 12 -<clusternode name="node1" votes="1" ... /> -.br -<clusternode name="node2" votes="1" ... /> -.br -<clusternode name="node3" votes="1" ... /> -.in 8 -</clusternodes> -.br -<quorumd interval="1" tko="10" votes="3" label="testing"> -.in 12 -<heuristic program="ping A -c1 -t1" score="1" interval="2" tko="3"/> -.br -<heuristic program="ping B -c1 -t1" score="1" interval="2" tko="3"/> -.br -<heuristic program="ping C -c1 -t1" score="1" interval="2" tko="3"/> -.br -.in 8 -</quorumd> - -.SH "3.3.2. 2 cluster nodes & 1 IP tiebreaker" -.in 8 -<cman two_node="0" expected_votes="3" .../> -.br -<clusternodes> -.in 12 -<clusternode name="node1" votes="1" ... /> -.br -<clusternode name="node2" votes="1" ... /> -.in 8 -</clusternodes> -.br -<quorumd interval="1" tko="10" votes="1" label="testing"> -.in 12 -<heuristic program="ping A -c1 -t1" score="1" interval="2" tko="3"/> -.br -.in 8 -</quorumd> -.in 0 - - -.SH "3.4. Heuristic score considerations" -* Heuristic timeouts should be set high enough to allow the previous run -of a given heuristic to complete. - -* Heuristic scripts returning anything except 0 as their return code -are considered failed. - -* The worst-case for improperly configured quorum heuristics is a race -to fence where two partitions simultaneously try to kill each other. - -.SH "3.5. Creating a quorum disk partition" -The mkqdisk utility can create and list currently configured quorum disks -visible to the local node; see -.B mkqdisk(8) -for more details. - -.SH "SEE ALSO" -mkqdisk(8), qdiskd(8), cman(5), syslog.conf(5), gettimeofday(2) diff --git a/cman/man/qdiskd.8 b/cman/man/qdiskd.8 deleted file mode 100644 index 21bccbf..0000000 --- a/cman/man/qdiskd.8 +++ /dev/null @@ -1,25 +0,0 @@ -.TH "qdiskd" "8" "July 2006" "" "Quorum Disk Management" -.SH "NAME" -qdiskd - Cluster Quorum Disk Daemon -.SH "SYNOPSIS" -\fBqdiskd [-f] [-d] -.SH "DESCRIPTION" -.PP -The \fBqdiskd\fP daemon talks to CMAN and provides a mechanism for determining -node-fitness in a cluster environment. See -.B -qdisk(5) -for configuration information. -.SH "OPTIONS" -.IP "-f" -Run in the foreground (do not fork / daemonize). -.IP "-d" -Enable debug output. -.IP "-Q" -Close stdin/out/err immediately before doing validations. This -is primarily for use when being called from an init script. Using -this option will stop all output, and can not be used with the -d -option. - -.SH "SEE ALSO" -mkqdisk(8), qdisk(5), cman(5) diff --git a/cman/qdisk/Makefile b/cman/qdisk/Makefile deleted file mode 100644 index 632e47b..0000000 --- a/cman/qdisk/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -INCLUDES+=-I. -I../lib -CFLAGS +=-I${incdir} -I${top_srcdir}/config \ - -Wall -Werror -Wstrict-prototypes -Wshadow -D_GNU_SOURCE -g - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -CFLAGS += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -CFLAGS += -I${incdir}/cluster -endif - -TARGET=qdiskd mkqdisk - -all: ${TARGET} - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -install: ${TARGET} - install -d ${sbindir} - install ${TARGET} ${sbindir} - -qdiskd: disk.o crc32.o disk_util.o main.o score.o bitmap.o clulog.o \ - gettid.o proc.o daemon_init.o iostate.o ../lib/libcman.a - gcc -o $@ $^ -lpthread -L../lib -lccs -lrt - -mkqdisk: disk.o crc32.o disk_util.o iostate.o \ - proc.o mkqdisk.o clulog.o gettid.o - gcc -o $@ $^ -lrt - - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS) - -clean: - rm -f *.o ${TARGET} - -uninstall: - ${UNINSTALL} ${TARGET} ${sbindir} diff --git a/cman/qdisk/README b/cman/qdisk/README deleted file mode 100644 index 86ecf1a..0000000 --- a/cman/qdisk/README +++ /dev/null @@ -1 +0,0 @@ -See qdisk(5) for setup and other information diff --git a/cman/qdisk/bitmap.c b/cman/qdisk/bitmap.c deleted file mode 100644 index 7cb5804..0000000 --- a/cman/qdisk/bitmap.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003, 2006 - - The Red Hat Cluster Manager API Library is free software; you can - redistribute it and/or modify it under the terms of the GNU Lesser - General Public License as published by the Free Software Foundation; - either version 2.1 of the License, or (at your option) any later - version. - - The Red Hat Cluster Manager API Library is distributed in the hope - that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Bitmap and membership mask handling routines. - */ -#include <stdint.h> - - -/** - * Clear a bit in a bitmap / bitmask. - * - * @param mask Bitmask to modify. - * @param bitidx Bit to modify. - * @param masklen Bitmask length (in uint8_t units) - * @return -1 if the index exceeds the number of bits in the - * bitmap, otherwise 0. - */ -int -clear_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen) -{ - uint32_t idx; - uint32_t bit; - - /* Index into array */ - idx = bitidx >> 3; - bit = 1 << (bitidx & 0x7); - - if (idx >= masklen) - return -1; - - mask[idx] &= ~bit; - - return 0; -} - - -/** - * Set a bit in a bitmap / bitmask. - * - * @param mask Bitmask to modify. - * @param bitidx Bit to modify. - * @param masklen Bitmask length (in uint8_t units). - * @return -1 if the index exceeds the number of bits in the - * bitmap, otherwise 0. - */ -int -set_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen) -{ - uint32_t idx; - uint32_t bit; - - /* Index into array */ - idx = bitidx >> 3; - bit = 1 << (bitidx & 0x7); - - if (idx >= masklen) - return -1; - - mask[idx] |= bit; - - return 0; -} - - -/** - * Check the status of a bit in a bitmap / bitmask. - * - * @param mask Bitmask to check. - * @param bitidx Bit to to check. - * @param masklen Bitmask length (in uint8_t units). - * @return -1 if the index exceeds the number of bits in the - * bitmap, 0 if not set, or 1 if set. - */ -int -is_bit_set(uint8_t *mask, uint32_t bitidx, uint32_t masklen) -{ - uint32_t idx; - uint32_t bit; - - /* Index into array */ - idx = bitidx >> 3; - bit = 1 << (bitidx & 0x7); - - if (idx >= masklen) - return -1; - - return !!(mask[idx]&bit); -} - - diff --git a/cman/qdisk/clulog.c b/cman/qdisk/clulog.c deleted file mode 100644 index 6b998f1..0000000 --- a/cman/qdisk/clulog.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Library routines for communicating with the logging daemon. - * - * Author: Jeff Moyer moyer@missioncriticallinux.com - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <malloc.h> -#include <dirent.h> -#include <signal.h> -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <ccs.h> -#define SYSLOG_NAMES -#include <sys/syslog.h> -#undef SYSLOG_NAMES - -#include <sys/wait.h> -#include <sys/types.h> -#include <linux/unistd.h> -#include <pthread.h> -#include <gettid.h> -#include <clulog.h> -#include <string.h> - - -#ifdef DEBUG -#include <assert.h> -#define Dprintf(fmt,args...) printf(fmt,##args) -#define DBG_ASSERT(x) assert(x) -#else -#define Dprintf(fmt,args...) -#define DBG_ASSERT(x) -#endif - -/* - * Globals - */ -static int log_is_open = 0; -static int useconsole = 0; -static int loglevel = LOGLEVEL_DFLT; -static int syslog_facility = LOG_DAEMON; -static char *daemon_name = NULL; -static pid_t daemon_pid = -1; -static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; - -CODE logger_prioritynames[] = -{ {"emerg", LOG_EMERG}, - {"alert", LOG_ALERT}, - {"crit", LOG_CRIT}, - {"err", LOG_ERR}, - {"warning", LOG_WARNING}, - {"notice", LOG_NOTICE}, - {"info", LOG_INFO}, - {"debug", LOG_DEBUG} -}; - -/* - * Exported Functions. - */ - -/** - * @return The current cluster log level. - */ -int -clu_get_loglevel(void) -{ - return loglevel; -} - - -/** - * Set the cluster log level. - * - * @param severity New log level. - * @return Old log level, or -1 if 'severity' is an invalid log - * level. - */ -int -clu_set_loglevel(int severity) -{ - int ret = loglevel; - - if (severity > 0) { - loglevel = severity; - return ret; - } - - return -1; -} - - -/** - * @return The current cluster log facility. - */ -char * -clu_get_facility(void) -{ - int x = 0; - - pthread_mutex_lock(&log_mutex); - for (; facilitynames[x].c_name; x++) { - if (syslog_facility == facilitynames[x].c_val) { - pthread_mutex_unlock(&log_mutex); - return facilitynames[x].c_name; - } - } - - pthread_mutex_unlock(&log_mutex); - return "daemon"; -} - - -/** - * Set the cluster log facility. - * - * @param facilityname New log facility (see /usr/include/sys/syslog.h). - * @return 0 - */ -int -clu_set_facility(char *facilityname) -{ - int x = 0, old; - - pthread_mutex_lock(&log_mutex); - old = syslog_facility; - - for (; facilitynames[x].c_name; x++) { - if (strcmp(facilityname, facilitynames[x].c_name)) - continue; - syslog_facility = facilitynames[x].c_val; - break; - } - - if (syslog_facility == old) { - pthread_mutex_unlock(&log_mutex); - return 0; - } - - closelog(); - log_is_open = 0; - pthread_mutex_unlock(&log_mutex); - return 0; -} - - -/** - * Set the console logging mode. Does not work for daemons. - * - * @param onoff 0 = off, otherwise on. - * @return Old log-to-console state. - */ -int -clu_log_console(int onoff) -{ - int ret = useconsole; - - useconsole = !!onoff; - return ret; -} - - -/** - * Cluster logging function. Talks to syslog and writes to the - * console, if necessary. - */ -int -do_clulog(int severity, - int write_to_cons, - pid_t pid, - char *prog, - const char *fmt, ...) -{ - va_list args; - char logmsg[MAX_LOGMSG_LEN]; /* message to go to the log */ - char printmsg[MAX_LOGMSG_LEN]; /* message to go to stdout */ - int syslog_flags = LOG_NDELAY; - - pthread_mutex_lock(&log_mutex); - if (severity > loglevel) { - pthread_mutex_unlock(&log_mutex); - return 0; - } - - memset(logmsg, 0, MAX_LOGMSG_LEN); - memset(printmsg, 0, MAX_LOGMSG_LEN); - - /* - * Check to see if the caller has forked. - */ - if (!pid) { - - /* Use thread IDs */ - if (daemon_pid != gettid()) { - - daemon_pid = gettid(); - log_is_open = 0; - } - - syslog_flags |= LOG_PID; - - } else { - - daemon_pid = pid; - closelog(); - log_is_open = 0; - snprintf(logmsg, MAX_LOGMSG_LEN, "[%d]: ", pid); - } - - if (prog) { - - if (daemon_name) { - - free(daemon_name); - daemon_name = NULL; - } - - daemon_name = strdup(prog); - } - - if (!log_is_open) { - - openlog(daemon_name, syslog_flags, syslog_facility); - log_is_open = 1; - } - /* - * Note: This can be called in the context of a CGI program, in which - * case anything printed to stdout goes to the web page. This can - * cause problems if we have our standard <warning> strings b/c - * the web client will try to interpret this as an html tag. - */ - snprintf(logmsg + strlen(logmsg), MAX_LOGMSG_LEN - strlen(logmsg), - "<%s> ", logger_prioritynames[severity].c_name); - - va_start(args, fmt); - vsnprintf(logmsg + strlen(logmsg), MAX_LOGMSG_LEN - strlen(logmsg), - fmt, args); - va_end(args); - - if (write_to_cons || useconsole) { - snprintf(printmsg, MAX_LOGMSG_LEN, "[%d] %s: ", daemon_pid, - logger_prioritynames[severity].c_name); - - va_start(args, fmt); - vsnprintf(printmsg + strlen(printmsg), - MAX_LOGMSG_LEN - strlen(printmsg), fmt, args); - va_end(args); - - fprintf(stdout, "%s", printmsg); - } - - syslog(severity, "%s", logmsg); - - pthread_mutex_unlock(&log_mutex); - - return 0; -} - - -/** - * Stop the cluster logging facility. - */ -void -clulog_close(void) -{ - closelog(); -} diff --git a/cman/qdisk/clulog.h b/cman/qdisk/clulog.h deleted file mode 100644 index 856d83c..0000000 --- a/cman/qdisk/clulog.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Header for clulog.c - */ -/* - * author: Jeff Moyer moyer@missioncriticallinux.com - */ - -#ifndef __CLUSTER_LOG_H -#define __CLUSTER_LOG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <syslog.h> -#include <sys/types.h> - -#define LOGLEVEL_DFLT LOG_INFO -#define MAX_LOGMSG_LEN 512 - -/* - * int clu_set_loglevel(int severity) - * - * DESCRIPTION - * Set the logging level for this daemon. This is not a - * system-wide setting. - * - * ARGUMENTS - * severity Severity as documented in sys/syslog.h (i.e. LOG_ERR) - * - * RETURN VALUES - * On success, the previous loglevel is returned. On error -1 is returned. - * - * NOTES - * The only way of generating errors for this call is to give a negative - * value for severity. Currently, syslog lists severities up to 8, but - * I see no reason for this restriction if, in the future, we decided to - * add more levels. Thus, any number up to MAXINT will be supported. - */ -int clu_set_loglevel(int severity); -int clu_set_facility(char *facility); -int clu_log_console(int onoff); - -/* - * int clu_get_loglevel(void) - * - * DESCRIPTION - * Get the current logging level. - * - * ARGUMENTS - * none - * - * RETURN VALUES - * The current logging level is returned. - */ -int clu_get_loglevel(void); - -/* - * DESCRIPTION - * Cluster logging facility. This is the actual function that does the - * logging. No one should call this, you should call the wrappers provided. - * i.e. clulog and clulog_and_print. - */ -int do_clulog(int severity, int write_to_cons, pid_t pid, - char *prog, const char *fmt, ...); -/* - * int clulog(int severity, const char *fmt, ...) - * - * DESCRIPTION - * Cluster logging facility. This is a library routine which sends the - * supplied parameters to the syslog daemon. If the supplied severity is - * numerically larger than the current loglevel, the message is never sent - * to the log. - * - * ARGUMENTS - * severity Severity as documented in sys/syslog.h (i.e. LOG_ERR) - * fmt Format string as used with printf. - * - * RETURN VALUES - * On success, 0 is returned. On error, -1 is returned. - * - * NOTES - * Inability to contact the logging daemon is the only source of error - * for this function. Thus, it would behoove you to try a clulog before - * daemonizing your process. If it fails, print a message to stderr - * explaining that the cluster logging daemon should probably be started. - * If you really want your message to be heard by someone, use - * clulog_and_print(). - */ -#define clulog(x,fmt,args...) do_clulog(x,0,0,NULL,fmt,##args) -#define clulog_pid(x,pid,prog,fmt,args...) do_clulog(x,0,pid,prog,fmt,##args) - -/* - * int clulog_and_print(int severity, int write_to_cons, const char *fmt, ...) - * - * DESCRIPTION - * Cluster logging facility. This is a library routine which sends the - * supplied parameters to the syslog daemon. If the supplied severity is - * numerically larger than the current loglevel, the message is never sent - * to the log. This version also prints the given message to the terminal. - * - * ARGUMENTS - * severity Severity as documented in sys/syslog.h (i.e. LOG_ERR) - * fmt Format string as used with printf. - * - * RETURN VALUES - * On success, 0 is returned. On error, -1 is returned. - */ -#define clulog_and_print(x,fmt,args...) do_clulog(x,1,0,NULL,fmt,##args) - - -/* - * void clulog_close(void) - * - * DESCRIPTION - * This is an optional call to close the logfile. This translates into a - * closelog() call. - * - * ARGUMENTS - * none - * - * RETURN VALUES - * This function does not return anything. - */ -void clulog_close(void); - - -#ifdef __cplusplus -} -#endif -#endif /* __CLUSTER_LOG_H */ -/* - * Local variables: - * c-basic-offset: 8 - * c-indent-level: 8 - * tab-width: 8 - * End: - */ diff --git a/cman/qdisk/crc32.c b/cman/qdisk/crc32.c deleted file mode 100644 index df80849..0000000 --- a/cman/qdisk/crc32.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2000 Bryan Call bc@fodder.org - * - * Modified by Lon H. Hohberger <lhh at redhat.com> - * Copyright (C) 2003 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/** @file - * Calculates CRC32s on data. - */ - -#include <stdint.h> -#include <sys/types.h> -#include <stdio.h> -#include <sys/types.h> -#include <unistd.h> - -static const unsigned long crctable[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - - -/** - * Calculate CRC32 of a data set. - * - * @param data Data set for building CRC32 - * @param count Size of data set, in bytes. - * @return CRC32 of data set. - */ -uint32_t clu_crc32(const char *data, size_t count) -{ - uint32_t x; - uint32_t crc = (uint32_t)~0; - - for (x = 0; x < count; x++) - crc = (crc >> 8) ^ crctable[(crc ^ data[x]) & 0xff]; - - if (crc == (uint32_t)~0) - return 0; - return ~crc; -} - -#if 0 -int -main(int argc, const char **argv) -{ - printf("%08x\n",crc32(argv[1],strlen(argv[1]))); -} -#endif diff --git a/cman/qdisk/daemon_init.c b/cman/qdisk/daemon_init.c deleted file mode 100644 index 4fd0309..0000000 --- a/cman/qdisk/daemon_init.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002, 2007 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * daemon_init function, does sanity checks and calls daemon(). - * - * Author: Jeff Moyer jmoyer@redhat.com - */ -/* - * TODO: Clean this up so that only one function constructs the - * pidfile /var/run/loggerd.PID, and perhaps only one function - * forms the /proc/PID/ path. - * - * Also need to add file locking for the pid file. - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <fcntl.h> -#include <dirent.h> -#include <sys/mman.h> -#include <sys/errno.h> -#include <libgen.h> -#include <signal.h> - -/* - * This should ultimately go in a header file. - */ -void daemon_init(char *prog); -int check_pid_valid(pid_t pid, char *prog); -int check_process_running(char *prog, pid_t * pid); - -/* - * Local prototypes. - */ -static void update_pidfile(char *prog); -static int setup_sigmask(void); - - -int -check_pid_valid(pid_t pid, char *prog) -{ - FILE *fp; - DIR *dir; - char filename[PATH_MAX]; - char dirpath[PATH_MAX]; - char proc_cmdline[64]; /* yank this from kernel somewhere */ - char *s = NULL; - - memset(filename, 0, PATH_MAX); - memset(dirpath, 0, PATH_MAX); - - snprintf(dirpath, sizeof (dirpath), "/proc/%d", pid); - if ((dir = opendir(dirpath)) == NULL) { - closedir(dir); - return 0; /* Pid has gone away. */ - } - closedir(dir); - - /* - * proc-pid directory exists. Now check to see if this - * PID corresponds to the daemon we want to start. - */ - snprintf(filename, sizeof (filename), "/proc/%d/cmdline", pid); - fp = fopen(filename, "r"); - if (fp == NULL) { - perror("check_pid_valid"); - return 0; /* Who cares.... Let's boogy on. */ - } - - if (!fgets(proc_cmdline, sizeof (proc_cmdline) - 1, fp)) { - /* - * Okay, we've seen processes keep a reference to a - * /proc/PID/stat file and not let go. Then when - * you try to read /proc/PID/cmline, you get either - * \000 or -1. In either case, we can safely assume - * the process has gone away. - */ - fclose(fp); - return 0; - } - fclose(fp); - - s = &(proc_cmdline[strlen(proc_cmdline)]); - if (*s == '\n') - *s = 0; - - /* - * Check to see if this is the same executable. - */ - if ((s = strstr(proc_cmdline, prog)) == NULL) { - return 0; - } else { - return 1; - } -} - - -int -check_process_running(char *prog, pid_t * pid) -{ - pid_t oldpid; - FILE *fp; - char filename[PATH_MAX]; - char *cmd; - int ret; - struct stat st; - - *pid = -1; - - /* - * Now see if there is a pidfile associated with this cmd in /var/run - */ - fp = NULL; - memset(filename, 0, PATH_MAX); - - cmd = basename(prog); - snprintf(filename, sizeof (filename), "/var/run/%s.pid", cmd); - - ret = stat(filename, &st); - if ((ret < 0) || (!st.st_size)) - return 0; - - /* - * Read the pid from the file. - */ - fp = fopen(filename, "r"); - if (fp == NULL) { /* error */ - return 0; - } - fscanf(fp, "%d\n", &oldpid); - fclose(fp); - if (check_pid_valid(oldpid, cmd)) { - *pid = oldpid; - return 1; - } - return 0; -} - - -static void -update_pidfile(char *prog) -{ - FILE *fp = NULL; - char *cmd; - char filename[PATH_MAX]; - - memset(filename, 0, PATH_MAX); - - cmd = basename(prog); - snprintf(filename, sizeof (filename), "/var/run/%s.pid", cmd); - - fp = fopen(filename, "w"); - if (fp == NULL) { - exit(1); - } - - fprintf(fp, "%d", getpid()); - fclose(fp); -} - - -static int -setup_sigmask(void) -{ - sigset_t set; - - sigfillset(&set); - - /* - * Dont't block signals which would cause us to dump core. - */ - sigdelset(&set, SIGQUIT); - sigdelset(&set, SIGILL); - sigdelset(&set, SIGTRAP); - sigdelset(&set, SIGABRT); - sigdelset(&set, SIGFPE); - sigdelset(&set, SIGSEGV); - sigdelset(&set, SIGBUS); - - /* - * Don't block SIGTERM or SIGCHLD - */ - sigdelset(&set, SIGTERM); - sigdelset(&set, SIGCHLD); - - return (sigprocmask(SIG_BLOCK, &set, NULL)); -} - - -void -daemon_init(char *prog) -{ - uid_t uid; - pid_t pid; - - uid = getuid(); - if (uid) { - fprintf(stderr, - "daemon_init: Sorry, only root wants to run this.\n"); - exit(1); - } - - if (check_process_running(prog, &pid) && (pid != getpid())) { - fprintf(stderr, - "daemon_init: Process "%s" already running.\n", - prog); - exit(1); - } - if (setup_sigmask() < 0) { - fprintf(stderr, "daemon_init: Unable to set signal mask.\n"); - exit(1); - } - - daemon(0, 0); - - update_pidfile(prog); -} diff --git a/cman/qdisk/disk.c b/cman/qdisk/disk.c deleted file mode 100644 index 723b35f..0000000 --- a/cman/qdisk/disk.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003, 2006 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR lgPURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Single-block Raw/Direct I/O Functions - */ -/* - * author: Tim Burke <tburke at redhat.com> - * description: Raw IO Interfaces. - * - * The RAW IO code we are using from 2.2.13 requires user buffers and - * disk offsets to be 512 byte aligned. So this code consists of a - * read and write routine which check to see if the user buffer is - * aligned. If it isn't a temporary aligned buffer is allocated, a data - * copy is performed along with the IO operation itself. - */ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <string.h> -#include <errno.h> -#include <disk.h> -#include <platform.h> -#include <unistd.h> -#include <time.h> -#include <linux/fs.h> -#include "iostate.h" - -static int diskRawRead(target_info_t *disk, char *buf, int len); -uint32_t clu_crc32(const char *data, size_t count); - - -/** - * Swap the bytes of a shared header so that it's always in big-endian form - * when stored on disk. - * - * @param hdr Header to encode. - */ -static void -header_encode(shared_header_t *hdr) -{ - /* sanity check - LE machine -> already encoded. */ - if (hdr->h_magic == be_swap32(SHARED_HEADER_MAGIC)) - return; - - swab32(hdr->h_magic); - swab32(hdr->h_hcrc); - swab32(hdr->h_dcrc); - swab32(hdr->h_length); - swab64(hdr->h_view); - swab64(hdr->h_timestamp); -} - - -/** - * Swap the bytes of a shared header so that it's always in host-byte order - * after we read it. This should be a macro calling header_encode. - * - * @param hdr Header to decode. - */ -static void -header_decode(shared_header_t *hdr) -{ - /* sanity check - LE machine -> already decoded. */ - if (hdr->h_magic == SHARED_HEADER_MAGIC) - return; - - swab32(hdr->h_magic); - swab32(hdr->h_hcrc); - swab32(hdr->h_dcrc); - swab32(hdr->h_length); - swab64(hdr->h_view); - swab64(hdr->h_timestamp); -} - - -/** - * Generate a shared header suitable for storing data. This includes: - * header magic, header crc, data crc, header length, timestamp. - * The header CRC is generated *after* the data CRC; so the header, - * in effect, ensures that the data CRC is valid before we even look - * at the data. Thus, if the header CRC decodes properly, then we - * assume that there's a very very high chance that the data CRC is valid. - * If the data CRC doesn't match the data, it's indicative of a problem. - * - * @param hdr Preallocated pointer to shared_header_t structure. - * @param data Data to be stored with hdr. - * @param count Size of data. - * @return -1 if CRC32 generation fails, or 0 on success. - */ -static int -header_generate(shared_header_t *hdr, const char *data, size_t count) -{ - memset(hdr,0,sizeof(*hdr)); - - hdr->h_magic = SHARED_HEADER_MAGIC; - - if (data && count) { - hdr->h_dcrc = clu_crc32(data, count); - hdr->h_length = (uint32_t)count; - - if (hdr->h_dcrc == 0) { - fprintf(stderr, "Invalid CRC32 generated on data!\n"); - return -1; - } - } - - hdr->h_timestamp = (uint64_t)time(NULL); - - hdr->h_hcrc = clu_crc32((char *)hdr, sizeof(*hdr)); - if (hdr->h_hcrc == 0) { - fprintf(stderr, "Invalid CRC32 generated on header!\n"); - return -1; - } - - header_encode(hdr); - - return 0; -} - - -/** - * Verify the integrity of a shared header. Basically, check the CRC32 - * information against the data and header. A better name for this would - * be "shared_block_verify". - * - * @param hdr Preallocated pointer to shared_header_t structure. - * @param data Data to be stored with hdr. - * @param count Size of data. - * @return -1 if CRC32 generation fails, or 0 on success. - */ -static int -header_verify(shared_header_t *hdr, const char *data, size_t count) -{ - uint32_t crc; - uint32_t bkupcrc; - - header_decode(hdr); - /* - * verify the header's CRC32. Ok, we know it's overkill taking - * the CRC32 of a friggin' 16-byte (12 bytes, really) structure, - * but why not? - */ - bkupcrc = hdr->h_hcrc; - hdr->h_hcrc = 0; - crc = clu_crc32((char *)hdr, sizeof(*hdr)); - hdr->h_hcrc = bkupcrc; - if (bkupcrc != crc) { -#if 0 - fprintf(stderr, "Header CRC32 mismatch; Exp: 0x%08x " - "Got: 0x%08x\n", bkupcrc, crc); -#endif - return -1; - } - - /* - * Verify the magic number. - */ - if (hdr->h_magic != SHARED_HEADER_MAGIC) { -#if 0 - fprintf(stderr, "Magic mismatch; Exp: 0x%08x " - "Got: 0x%08x\n", SHARED_HEADER_MAGIC, hdr->h_magic); -#endif - return -1; - } - - /* - * If there's no data or no count, or perhaps the length fed in is less - * then the expected length, bail. - */ - if (!data || !count || (count < hdr->h_length)) - return 0; - - crc = clu_crc32(data, (count > hdr->h_length) ? - hdr->h_length : count); - - if (hdr->h_dcrc != crc) { -#if 0 - fprintf(stderr, "Data CRC32 mismatch; Exp: 0x%08x " - "Got: 0x%08x\n", hdr->h_dcrc, crc); -#endif - return -1; - } - - return 0; -} - - - -/* - * qdisk_open - * Called to open the shared state partition with appropriate mode. - * Returns - (the file descriptor), a value >= 0 on success. - */ -int -qdisk_open(char *name, target_info_t *disk) -{ - int ret; - int ssz; - - /* - * Open for synchronous writes to insure all writes go directly - * to disk. - */ - disk->d_fd = open(name, O_RDWR | O_SYNC | O_DIRECT); - if (disk->d_fd < 0) - return disk->d_fd; - - ret = ioctl(disk->d_fd, BLKSSZGET, &ssz); - if (ret < 0) { - perror("qdisk_open: ioctl(BLKSSZGET)"); - return -1; - } - - disk->d_blksz = ssz; - disk->d_pagesz = sysconf(_SC_PAGESIZE); - - /* Check to verify that the partition is large enough.*/ - io_state(STATE_LSEEK); - ret = lseek(disk->d_fd, END_OF_DISK(disk->d_blksz), SEEK_SET); - io_state(STATE_NONE); - if (ret < 0) { - perror("open_partition: seek"); - return -1; - } - - if (ret < END_OF_DISK(disk->d_blksz)) { - fprintf(stderr, "Partition %s too small\n", name); - errno = EINVAL; - return -1; - } - - /* Set close-on-exec bit */ - ret = fcntl(disk->d_fd, F_GETFD, 0); - if (ret < 0) { - perror("open_partition: fcntl(F_GETFD)"); - close(disk->d_fd); - return -1; - } - - ret |= FD_CLOEXEC; - if (fcntl(disk->d_fd, F_SETFD, ret) < 0) { - perror("open_partition: fcntl(F_SETFD)"); - close(disk->d_fd); - return -1; - } - - return 0; -} - - -/* - * qdisk_close - * Closes the shared state disk partition. - * Returns - value from close syscall. - */ -int -qdisk_close(target_info_t *disk) -{ - int retval; - - if (!disk || disk->d_fd < 0) { - errno = EINVAL; - return -1; - } - - retval = close(disk->d_fd); - disk->d_fd = -1; - - return retval; -} - -/* - * qdisk_validate - * Called to verify that the specified device special file representing - * the partition appears to be a valid device. - * Returns: 0 - success, 1 - failure - */ -int -qdisk_validate(char *name) -{ - struct stat stat_st, *stat_ptr; - target_info_t disk; - stat_ptr = &stat_st; - - if (stat(name, stat_ptr) < 0) { - perror("stat"); - return -1; - } - /* - * Verify that its a block or character special file. - */ - if (S_ISCHR(stat_st.st_mode) == 0 && S_ISBLK(stat_st.st_mode) == 0) { -/* - errno = EINVAL; - return -1; -*/ - fprintf(stderr, "Warning: %s is not a block device\n", - name); - } - - /* - * Verify read/write permission. - */ - if (qdisk_open(name, &disk) < 0) { - fprintf(stderr, "%s: open of %s for RDWR failed: %s\n", - __FUNCTION__, name, strerror(errno)); - return -1; - } - qdisk_close(&disk); - return 0; -} - - -static int -diskRawReadShadow(target_info_t *disk, off_t readOffset, char *buf, int len) -{ - int ret; - shared_header_t *hdrp; - char *data; - int datalen; - - io_state(STATE_LSEEK); - ret = lseek(disk->d_fd, readOffset, SEEK_SET); - io_state(STATE_NONE); - if (ret != readOffset) { -#if 0 - fprintf(stderr, - "diskRawReadShadow: can't seek to offset %d.\n", - (int) readOffset); -#endif - errno = ENODATA; - return -1; - } - - ret = diskRawRead(disk, buf, len); - if (ret != len) { -#if 0 - fprintf(stderr, "diskRawReadShadow: aligned read " - "returned %d, not %d.\n", ret, len); -#endif - errno = ENODATA; - return -1; - } - - /* Decode the header portion so we can run a checksum on it. */ - hdrp = (shared_header_t *)buf; - data = (char *)buf + sizeof(*hdrp); - swab_shared_header_t(hdrp); - datalen = hdrp->h_length; - - if (header_verify(hdrp, data, len)) { -#if 0 - fprintf(stderr, "diskRawReadShadow: bad CRC32, " - "fd = %d offset = %d len = %d\n", fd, - (int) readOffset, len); -#endif - errno = EPROTO; - return -1; - } - - return 0; -} - - -/* - * The RAW IO implementation requires buffers to be 512 byte aligned. - * Here we check for alignment and do a bounceio if necessary. - */ -static int -diskRawRead(target_info_t *disk, char *buf, int len) -{ - char *alignedBuf; - int readret; - int extraLength; - int readlen; - int bounceNeeded = 1; - - - /* was 3ff, which is (512<<1-1) */ - if ((((unsigned long) buf & - (unsigned long) ((disk->d_blksz << 1) -1)) == 0) && - ((len % (disk->d_blksz)) == 0)) { - bounceNeeded = 0; - } - - if (bounceNeeded == 0) { - /* Already aligned and even multiple of 512, no bounceio - * required. */ - io_state(STATE_READ); - readret = read(disk->d_fd, buf, len); - io_state(STATE_NONE); - return readret; - } - - if (len > disk->d_blksz) { - fprintf(stderr, - "diskRawRead: not setup for reads larger than %d.\n", - (int)disk->d_blksz); - return (-1); - } - /* - * All IOs must be of size which is a multiple of 512. Here we - * just add in enough extra to accommodate. - * XXX - if the on-disk offsets don't provide enough room we're cooked! - */ - extraLength = 0; - if (len % disk->d_blksz) { - extraLength = disk->d_blksz - (len % disk->d_blksz); - } - - readlen = len; - if (extraLength) { - readlen += extraLength; - } - - readret = posix_memalign((void **)&alignedBuf, disk->d_pagesz, disk->d_blksz); - if (readret < 0) { - return -1; - } - - io_state(STATE_READ); - readret = read(disk->d_fd, alignedBuf, readlen); - io_state(STATE_NONE); - if (readret > 0) { - if (readret > len) { - memcpy(alignedBuf, buf, len); - readret = len; - } else { - memcpy(alignedBuf, buf, readret); - } - } - - free(alignedBuf); - if (readret != len) { - fprintf(stderr, "diskRawRead: read err, len=%d, readret=%d\n", - len, readret); - } - - return (readret); -} - - -/* - * The RAW IO implementation requires buffers to be 512 byte aligned. - * Here we check for alignment and do a bounceio if necessary. - */ -static int -diskRawWrite(target_info_t *disk, char *buf, int len) -{ - char *alignedBuf; - int ret; - int extraLength; - int writelen; - int bounceNeeded = 1; - - /* was 3ff, which is (512<<1-1) */ - if ((((unsigned long) buf & - (unsigned long) ((disk->d_blksz << 1) -1)) == 0) && - ((len % (disk->d_blksz)) == 0)) { - bounceNeeded = 0; - } - - if (bounceNeeded == 0) { - /* Already aligned and even multiple of 512, no bounceio - * required. */ - io_state(STATE_WRITE); - ret = write(disk->d_fd, buf, len); - io_state(STATE_NONE); - return ret; - } - - if (len > disk->d_blksz) { - fprintf(stderr, - "diskRawRead: not setup for reads larger than %d.\n", - (int)disk->d_blksz); - return (-1); - } - /* - * All IOs must be of size which is a multiple of 512. Here we - * just add in enough extra to accommodate. - * XXX - if the on-disk offsets don't provide enough room we're cooked! - */ - extraLength = 0; - if (len % disk->d_blksz) { - extraLength = disk->d_blksz - (len % disk->d_blksz); - } - - writelen = len; - if (extraLength) { - writelen += extraLength; - } - - ret = posix_memalign((void **)&alignedBuf, disk->d_pagesz, disk->d_blksz); - if (ret < 0) { - return -1; - } - - if (len > disk->d_blksz) { - fprintf(stderr, - "diskRawWrite: not setup for larger than %d.\n", - (int)disk->d_blksz); - return (-1); - } - - memcpy(buf, alignedBuf, len); - io_state(STATE_WRITE); - ret = write(disk->d_fd, alignedBuf, writelen); - io_state(STATE_NONE); - if (ret > len) { - ret = len; - } - - free(alignedBuf); - if (ret != len) { - fprintf(stderr, "diskRawWrite: write err, len=%d, ret=%dn", - len, ret); - } - - return (ret); -} - - -static int -diskRawWriteShadow(target_info_t *disk, __off64_t writeOffset, char *buf, int len) -{ - off_t retval_seek; - ssize_t retval_write; - - if ((writeOffset < 0) || (len < 0)) { - fprintf(stderr, - "diskRawWriteShadow: writeOffset=%08x, " - "len=%08x.\n", (int)writeOffset, len); - return (-1); - } - - io_state(STATE_LSEEK); - retval_seek = lseek(disk->d_fd, writeOffset, SEEK_SET); - io_state(STATE_NONE); - if (retval_seek != writeOffset) { - fprintf(stderr, - "diskRawWriteShadow: can't seek to offset %d\n", - (int) writeOffset); - return (-1); - } - - retval_write = diskRawWrite(disk, buf, len); - if (retval_write != len) { - if (retval_write == -1) { - fprintf(stderr, "%s: %s\n", __FUNCTION__, - strerror(errno)); - } - fprintf(stderr, - "diskRawWriteShadow: aligned write returned %d" - ", not %d\n", (int)retval_write, (int)len); - return (-1); - } - - return 0; -} - - -int -qdisk_read(target_info_t *disk, __off64_t offset, void *buf, int count) -{ - shared_header_t *hdrp; - char *data; - size_t total; - int rv; - - /* - * Calculate the total length of the buffer, including the header. - * Raw blocks are 512 byte aligned. - */ - total = count + sizeof(shared_header_t); - if (total < disk->d_blksz) - total = disk->d_blksz; - - /* Round it up */ - if (total % disk->d_blksz) - total = total + (disk->d_blksz * !!(total % disk->d_blksz)) - (total % disk->d_blksz); - - hdrp = NULL; - rv = posix_memalign((void **)&hdrp, disk->d_pagesz, disk->d_blksz); - if (rv < 0) - return -1; - - if (hdrp == NULL) - return -1; - - data = (char *)hdrp + sizeof(shared_header_t); - - rv = diskRawReadShadow(disk, offset, (char *)hdrp, disk->d_blksz); - - if (rv == -1) { - return -1; - } - - /* Copy out the data */ - memcpy(buf, data, hdrp->h_length); - - /* Zero out the remainder. */ - if (hdrp->h_length < count) { - memset(buf + hdrp->h_length, 0, - count - hdrp->h_length); - } - - free(hdrp); - return count; -} - - -int -qdisk_write(target_info_t *disk, __off64_t offset, const void *buf, int count) -{ - size_t maxsize; - shared_header_t *hdrp; - char *data; - size_t total = 0, rv = -1, psz = disk->d_blksz; //sysconf(_SC_PAGESIZE); - - maxsize = psz - (sizeof(shared_header_t)); - if (count >= (maxsize + sizeof(shared_header_t))) { - printf("error: count %d >= (%d + %d)\n", (int)count, - (int)maxsize, (int)sizeof(shared_header_t)); - errno = ENOSPC; - return -1; - } - - /* - * Calculate the total length of the buffer, including the header. - */ - total = count + sizeof(shared_header_t); - if (total < psz) - total = psz; - - /* Round it up */ - if (total % psz) - total = total + (psz * !!(total % psz)) - (total % psz); - - hdrp = NULL; - rv = posix_memalign((void **)&hdrp, disk->d_pagesz, total); - if (rv < 0) { - perror("posix_memalign"); - return -1; - } - - /* - * Copy the data into our new buffer - */ - data = (char *)hdrp + sizeof(shared_header_t); - memcpy(data, buf, count); - - if (header_generate(hdrp, buf, count) == -1) { - free((char *)hdrp); - return -1; - } - swab_shared_header_t(hdrp); - - /* - * Locking must be performed elsewhere. We make no assumptions - * about locking here. - */ - if (total == psz) - rv = diskRawWriteShadow(disk, offset, (char *)hdrp, psz); - - if (rv == -1) - perror("diskRawWriteShadow"); - - free((char *)hdrp); - if (rv == -1) - return -1; - return count; -} - - -static int -header_init(target_info_t *disk, char *label) -{ - quorum_header_t qh; - - if (qdisk_read(disk, OFFSET_HEADER, &qh, sizeof(qh)) == sizeof(qh)) { - swab_quorum_header_t(&qh); - if (qh.qh_magic == HEADER_MAGIC_OLD) { - printf("Warning: Red Hat Cluster Manager 1.2.x " - "header found\n"); - } else if (qh.qh_magic == HEADER_MAGIC_NUMBER) { - printf("Warning: Initializing previously " - "initialized partition\n"); - } - } - - if (gethostname(qh.qh_updatehost, sizeof(qh.qh_updatehost)) < 0) { - perror("gethostname"); - return -1; - } - - /* Copy in the cluster/label name */ - snprintf(qh.qh_cluster, sizeof(qh.qh_cluster)-1, "%s", label); - - qh.qh_version = VERSION_MAGIC_V2; - if ((qh.qh_timestamp = (uint64_t)time(NULL)) <= 0) { - perror("time"); - return -1; - } - - qh.qh_magic = HEADER_MAGIC_NUMBER; - qh.qh_blksz = disk->d_blksz; - qh.qh_pad = 0; - - swab_quorum_header_t(&qh); - if (qdisk_write(disk, OFFSET_HEADER, &qh, sizeof(qh)) != sizeof(qh)) { - return -1; - } - - return 0; -} - - -int -qdisk_init(char *partname, char *label) -{ - target_info_t disk; - status_block_t ps, wps; - int nid, ret; - time_t t; - - ret = qdisk_validate(partname); - if (ret < 0) { - perror("qdisk_verify"); - return -1; - } - - ret = qdisk_open(partname, &disk); - if (ret < 0) { - perror("qdisk_open"); - return -1; - } - - if (header_init(&disk, label) < 0) { - return -1; - } - - time(&t); - - ps.ps_magic = STATE_MAGIC_NUMBER; - ps.ps_updatenode = 0; - ps.pad0 = 0; - ps.ps_timestamp = (uint64_t)t; - ps.ps_state = (uint8_t)S_NONE; - ps.pad1[0] = 0; - ps.ps_flags = 0; - ps.ps_score = 0; - ps.ps_scoremax = 0; - ps.ps_ca_sec = 0; - ps.ps_ca_usec = 0; - ps.ps_lc_sec = 0; - ps.ps_ca_usec = 0; - - /* Node IDs 1..N */ - for (nid = 1; nid <= MAX_NODES_DISK; nid++) { - ps.ps_nodeid = nid; - - printf("Initializing status block for node %d...\n", nid); - wps = ps; - swab_status_block_t(&wps); - - if (qdisk_write(&disk, qdisk_nodeid_offset(nid, disk.d_blksz), &wps, sizeof(wps)) < 0) { - printf("Error writing node ID block %d\n", nid); - qdisk_close(&disk); - return -1; - } - } - - qdisk_close(&disk); - - return 0; -} - diff --git a/cman/qdisk/disk.h b/cman/qdisk/disk.h deleted file mode 100644 index f6d1212..0000000 --- a/cman/qdisk/disk.h +++ /dev/null @@ -1,302 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Main quorum daemon include file - */ -#ifndef _QUORUM_DISK_H -#define _QUORUM_DISK_H - -#include <stdint.h> -#include <pthread.h> -#include <arpa/inet.h> -#include <libcman.h> - -#define MAX_NODES_DISK 16 -#define MEMB_MASK_LEN ((MAX_NODES_DISK / 8) + \ - (!!(MAX_NODES_DISK % 8))) -#define DISK_MEMB_MASK_LEN ((MEMB_MASK_LEN + 7) & ~7) - -/** The membership bitmask type */ -typedef uint8_t memb_mask_t [DISK_MEMB_MASK_LEN]; - -typedef enum { - S_NONE = 0x0, // Shutdown / not quorate / not running - S_EVICT = 0x1, // Voted out / about to be fenced. - /* ^^^ Fencing OK */ - S_INIT = 0x2, // Initializing. Hold your fire. - /* vvv Fencing will kill a node */ - S_RUN = 0x5, // I think I'm running. - S_MASTER= 0x6 // I know I'm running, and have advertised to - // CMAN the availability of the disk vote for my - // partition. -} disk_node_state_t; - - -typedef enum { - M_NONE = 0x0, - M_BID = 0x1, - M_ACK = 0x2, - M_NACK = 0x3, - M_MASK = 0x4 -} disk_msg_id_t; - - -typedef enum { - FL_MSG = 0x1, - FL_BID = 0x2, - FL_VOTE = 0x4 -} disk_state_flag_t; - - -typedef enum { - RF_REBOOT = 0x1, /* Reboot if we go from master->none */ - RF_STOP_CMAN = 0x2, - RF_DEBUG = 0x4, - RF_PARANOID = 0x8, - RF_ALLOW_KILL = 0x10, - RF_UPTIME = 0x20, - RF_CMAN_LABEL = 0x40, - RF_IOTIMEOUT = 0x80 -} run_flag_t; - - -/* RHEL 2.1 / RHCS3 old magic numbers */ -#define HEADER_MAGIC_OLD 0x39119FCD /* partition header */ -#define STATE_MAGIC_OLD 0xF1840DCE /* Status block */ -#define SHARED_HEADER_MAGIC_OLD 0x00DEBB1E /* Per-block header */ - -/* Conversion */ -#define HEADER_MAGIC_NUMBER 0xeb7a62c2 /* Partition header */ -#define STATE_MAGIC_NUMBER 0x47bacef8 /* Status block */ -#define SHARED_HEADER_MAGIC 0x00DEBB1E /* Per-block headeer */ - -/* Version magic. */ -#define VERSION_MAGIC_V2 0x389fabc4 - - -typedef struct __attribute__ ((packed)) { - uint32_t ps_magic; - /* 4 */ - uint32_t ps_updatenode; // Last writer - /* 8 */ - uint64_t ps_timestamp; // time of last update - /* 16 */ - uint32_t ps_nodeid; - uint32_t pad0; - /* 24 */ - uint8_t ps_state; // running or stopped - uint8_t pad1[1]; - uint16_t ps_flags; - /* 26 */ - uint16_t ps_score; // Local points - uint16_t ps_scoremax; // What we think is our max - // points, if other nodes - // disagree, we may be voted - // out - /* 28 */ - uint32_t ps_ca_sec; // Cycle speed (average) - uint32_t ps_ca_usec; - /* 36 */ - uint32_t ps_lc_sec; // Cycle speed (last) - uint32_t ps_lc_usec; - uint64_t ps_incarnation; // Token to detect hung + - // restored node - /* 44 */ - uint16_t ps_msg; // Vote/bid mechanism - uint16_t ps_seq; - uint32_t ps_arg; - /* 52 */ - memb_mask_t ps_mask; // Bitmap - memb_mask_t ps_master_mask; // Bitmap - /* 60 */ -} status_block_t; - -#define swab_status_block_t(ptr) \ -{\ - swab32((ptr)->ps_magic);\ - swab32((ptr)->ps_updatenode);\ - swab64((ptr)->ps_timestamp);\ - swab32((ptr)->ps_nodeid);\ - swab32((ptr)->pad0);\ - /* state + pad */ \ - swab16((ptr)->ps_flags);\ - swab16((ptr)->ps_score);\ - swab16((ptr)->ps_scoremax);\ - /* Cycle speeds */ \ - swab32((ptr)->ps_ca_sec);\ - swab32((ptr)->ps_ca_usec);\ - swab32((ptr)->ps_lc_sec);\ - swab32((ptr)->ps_lc_usec);\ - /* Message */ \ - swab16((ptr)->ps_msg); \ - swab16((ptr)->ps_seq); \ - swab32((ptr)->ps_arg); \ - } - - -/* - * Shared state disk header. Describes cluster global information. - */ -typedef struct __attribute__ ((packed)) { - uint32_t qh_magic; - uint32_t qh_version; // - uint64_t qh_timestamp; // time of last update - char qh_updatehost[128];// Hostname who put this here... - char qh_cluster[120]; // Cluster name; CMAN only - // supports 16 chars. - uint32_t qh_blksz; // Known block size @ creation - uint32_t qh_pad; -} quorum_header_t; - -#define swab_quorum_header_t(ptr) \ -{\ - swab32((ptr)->qh_magic); \ - swab32((ptr)->qh_version); \ - swab32((ptr)->qh_blksz); \ - swab32((ptr)->qh_pad); \ - swab64((ptr)->qh_timestamp); \ -} - - - -/* - * The user data is stored with this header prepended. - * The header ONLY contains CRC information and the length of the data. - * The data blocks themselves contain their own respective magic numbers. - */ -typedef struct __attribute__ ((packed)) { - uint32_t h_magic; /* Header magic */ - uint32_t h_hcrc; /* Header CRC */ - uint32_t h_dcrc; /* CRC32 of data */ - uint32_t h_length; /* Length of real data */ - uint64_t h_view; /* View # of real data */ - uint64_t h_timestamp; /* Timestamp */ -} shared_header_t; - -#define SHARED_HEADER_INITIALIZER = {0, 0, 0, 0, 0, 0} - -#define swab_shared_header_t(ptr) \ -{\ - swab32((ptr)->h_magic);\ - swab32((ptr)->h_hcrc);\ - swab32((ptr)->h_dcrc);\ - swab32((ptr)->h_length);\ - swab64((ptr)->h_view);\ - swab64((ptr)->h_timestamp);\ -} - - -/* Offsets from RHCM 1.2.x */ -#define OFFSET_HEADER 0 -#define HEADER_SIZE(ssz) (ssz<4096?4096:ssz) - -#define OFFSET_FIRST_STATUS_BLOCK(ssz) (OFFSET_HEADER + HEADER_SIZE(ssz)) -#define SPACE_PER_STATUS_BLOCK(ssz) (ssz<4096?4096:ssz) -#define STATUS_BLOCK_COUNT MAX_NODES_DISK - -#define END_OF_DISK(ssz) (OFFSET_FIRST_STATUS_BLOCK(ssz) + \ - (MAX_NODES_DISK + 1) * \ - SPACE_PER_STATUS_BLOCK(ssz)) \ - - -typedef struct { - int d_fd; - int _pad_; - size_t d_blksz; - size_t d_pagesz; -} target_info_t; - - -/* From disk.c */ -int qdisk_open(char *name, target_info_t *disk); -int qdisk_close(target_info_t *disk); -int qdisk_init(char *name, char *clustername); -int qdisk_validate(char *name); -int qdisk_read(target_info_t *disk, __off64_t ofs, void *buf, int len); -int qdisk_write(target_info_t *disk, __off64_t ofs, const void *buf, int len); - -#define qdisk_nodeid_offset(nodeid, ssz) \ - (OFFSET_FIRST_STATUS_BLOCK(ssz) + (SPACE_PER_STATUS_BLOCK(ssz) * (nodeid - 1))) - -/* From disk_utils.c */ -#define HISTORY_LENGTH 60 -typedef struct { - disk_msg_id_t m_msg; /* this is an int, but will be stored as 16bit*/ - uint32_t m_arg; - uint16_t m_seq; - uint16_t pad0; -} disk_msg_t; - - -typedef struct { - uint64_t qc_incarnation; - struct timeval qc_average; - struct timeval qc_last[HISTORY_LENGTH]; - target_info_t qc_disk; - int qc_my_id; - int qc_writes; - int qc_interval; - int qc_tko; - int qc_tko_up; - int qc_upgrade_wait; - int qc_master_wait; - int qc_votes; - int qc_scoremin; - int qc_sched; - int qc_sched_prio; - disk_node_state_t qc_disk_status; - disk_node_state_t qc_status; - int qc_master; /* Master?! */ - int _pad_; - run_flag_t qc_flags; - cman_handle_t qc_ch; - char *qc_device; - char *qc_label; - char *qc_status_file; - char *qc_cman_label; -} qd_ctx; - -typedef struct { - uint64_t ni_incarnation; - uint64_t ni_evil_incarnation; - time_t ni_last_seen; - int ni_misses; - int ni_seen; - disk_msg_t ni_msg; - disk_msg_t ni_last_msg; - disk_node_state_t ni_state; - status_block_t ni_status; -} node_info_t; - -int qd_write_status(qd_ctx *ctx, int nid, disk_node_state_t state, - disk_msg_t *msg, memb_mask_t mask, memb_mask_t master); -int qd_read_print_status(target_info_t *disk, int nid); -int qd_init(qd_ctx *ctx, cman_handle_t ch, int me); -void qd_destroy(qd_ctx *ctx); - -/* proc.c */ -int find_partitions(const char *partfile, const char *label, - char *devname, size_t devlen, int print); -int check_device(char *device, char *label, int *ssz, quorum_header_t *qh, - int flags); - - -#endif diff --git a/cman/qdisk/disk_util.c b/cman/qdisk/disk_util.c deleted file mode 100644 index b36f8d7..0000000 --- a/cman/qdisk/disk_util.c +++ /dev/null @@ -1,344 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Misc. Quorum daemon context utilities / high-level functions - */ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <string.h> -#include <errno.h> -#include <disk.h> -#include <platform.h> -#include <unistd.h> -#include <sys/time.h> -#include <time.h> - - -inline void -_diff_tv(struct timeval *dest, struct timeval *start, struct timeval *end) -{ - dest->tv_sec = end->tv_sec - start->tv_sec; - dest->tv_usec = end->tv_usec - start->tv_usec; - - if (dest->tv_usec < 0) { - dest->tv_usec += 1000000; - dest->tv_sec--; - } -} - - -/** - * - * Grab the uptime from /proc/uptime. - * - * @param tv Timeval struct to store time in. The sec - * field contains seconds, the usec field - * contains the hundredths-of-seconds (converted - * to micro-seconds) - * @return -1 on failure, 0 on success. - */ -static inline int -getuptime(struct timeval *tv) -{ - FILE *fp; - struct timeval junk; - int rv; - - fp = fopen("/proc/uptime","r"); - if (!fp) - return -1; - -#if defined(__sparc__) || defined(__hppa__) || defined(__sparc64__) || defined (__hppa64__) - rv = fscanf(fp,"%ld.%d %ld.%d\n", &tv->tv_sec, &tv->tv_usec, - &junk.tv_sec, &junk.tv_usec); -#else - rv = fscanf(fp,"%ld.%ld %ld.%ld\n", &tv->tv_sec, &tv->tv_usec, - &junk.tv_sec, &junk.tv_usec); -#endif - fclose(fp); - - if (rv != 4) { - return -1; - } - - tv->tv_usec *= 10000; - - return 0; -} - - -inline int -get_time(struct timeval *tv, int use_uptime) -{ - if (use_uptime) { - return getuptime(tv); - } else { - return gettimeofday(tv, NULL); - } -} - - -/** - Update write times and calculate a new average time - */ -void -qd_update_wtime(qd_ctx *ctx, struct timeval *newtime) -{ - int x; - int max = HISTORY_LENGTH; - uint64_t sum = 0; - - /* Store the thing */ - ctx->qc_writes++; - ctx->qc_last[ctx->qc_writes % HISTORY_LENGTH].tv_sec = newtime->tv_sec; - ctx->qc_last[ctx->qc_writes % HISTORY_LENGTH].tv_usec = newtime->tv_usec; - - if (ctx->qc_writes < HISTORY_LENGTH) - max = ctx->qc_writes; - - for (x = 0; x < max; x++) { - sum += (ctx->qc_last[x].tv_sec * 1000000); - sum += ctx->qc_last[x].tv_usec; - } - - sum /= max; - - ctx->qc_average.tv_sec = (sum / 1000000); - ctx->qc_average.tv_usec = (sum % 1000000); -} - - -/** - Write a status block to disk, given state, nodeid, message, and the - membership mask. - */ -int -qd_write_status(qd_ctx *ctx, int nid, disk_node_state_t state, - disk_msg_t *msg, memb_mask_t mask, memb_mask_t master) -{ - status_block_t ps; - struct timeval start, end; - int utime_ok = 1; - - if (!ctx) { - errno = EINVAL; - return -1; - } - - if (nid <= 0) { - errno = EINVAL; - return -1; - } - - ps.ps_magic = STATE_MAGIC_NUMBER; - ps.ps_nodeid = nid; - ps.ps_updatenode = ctx->qc_my_id; - ps.pad0 = 0; - ps.ps_timestamp = (uint64_t)time(NULL); - ps.ps_state = (uint8_t)state; - ps.pad1[0] = 0; - ps.ps_flags = 0; - ps.ps_score = 0; - ps.ps_scoremax = 0; - ps.ps_ca_sec = ctx->qc_average.tv_sec; - ps.ps_ca_usec = ctx->qc_average.tv_usec; - ps.ps_incarnation = ctx->qc_incarnation; - if (mask) { - memcpy(ps.ps_mask, mask, sizeof(memb_mask_t)); - } else { - memset(ps.ps_mask, 0, sizeof(memb_mask_t)); - } - if (master) { - memcpy(ps.ps_master_mask, master, sizeof(memb_mask_t)); - } else { - memset(ps.ps_master_mask, 0, sizeof(memb_mask_t)); - } - - if (ctx->qc_writes) { - ps.ps_lc_sec = - ctx->qc_last[(ctx->qc_writes - 1) % HISTORY_LENGTH].tv_sec; - ps.ps_lc_usec = - ctx->qc_last[(ctx->qc_writes - 1) % HISTORY_LENGTH].tv_usec; - } else { - ps.ps_lc_sec = ps.ps_lc_usec = 0; - } - ps.ps_nodeid = nid; - - /* Argh! */ - if (msg) { - ps.ps_msg = msg->m_msg; - ps.ps_seq = msg->m_seq; - ps.ps_arg = msg->m_arg; - } else { - ps.ps_msg = 0; - ps.ps_seq = 0; - ps.ps_arg = 0; - } - - if (get_time(&start, ctx->qc_flags&RF_UPTIME) < 0) - utime_ok = 0; - swab_status_block_t(&ps); - if (qdisk_write(&ctx->qc_disk, - qdisk_nodeid_offset(nid, ctx->qc_disk.d_blksz), - &ps, sizeof(ps)) < 0) { - printf("Error writing node ID block %d\n", nid); - return -1; - } - if (utime_ok && (get_time(&end, ctx->qc_flags&RF_UPTIME) < 0)) - utime_ok = 0; - - if (utime_ok) { - _diff_tv(&start,&start,&end); - } else { - /* Use heuristic */ - start.tv_sec = ctx->qc_average.tv_sec; - start.tv_usec = ctx->qc_average.tv_usec; - } - qd_update_wtime(ctx, &start); - - return 0; -} - - -int -qd_print_status(target_info_t *disk, status_block_t *ps) -{ - int x; - - printf("Data @ offset %d:\n", - (int)qdisk_nodeid_offset(ps->ps_nodeid, disk->d_blksz)); - printf("status_block_t {\n"); - printf("\t.ps_magic = %08x;\n", (int)ps->ps_magic); - printf("\t.ps_nodeid = %d;\n", (int)ps->ps_nodeid); - printf("\t.ps_updatenode = %d;\n", (int)ps->ps_updatenode); - printf("\t.pad0 = %d;\n", (int)ps->pad0); - printf("\t.ps_timestamp = %llu;\n", (long long unsigned) - ps->ps_timestamp); - printf("\t.ps_state = %d;\n", ps->ps_state); - printf("\t.pad1[0] = %d;\n", ps->pad1[0]); - printf("\t.ps_flags = %d;\n", ps->ps_flags); - printf("\t.ps_score = %d;\n", ps->ps_score); - printf("\t.ps_scoremax = %d;\n", ps->ps_scoremax); - printf("\t.ps_ca_sec = %d;\n", ps->ps_ca_sec); - printf("\t.ps_ca_usec = %d;\n", ps->ps_ca_usec); - printf("\t.ps_lc_sec = %d;\n", ps->ps_lc_sec); - printf("\t.ps_lc_usec = %d;\n", ps->ps_lc_usec); - printf("\t.ps_mask = 0x"); - for (x = (sizeof(memb_mask_t)-1); x >= 0; x--) - printf("%02x", ps->ps_mask[x]); - printf("\n"); - printf("\t.ps_master_mask = 0x"); - for (x = (sizeof(memb_mask_t)-1); x >= 0; x--) - printf("%02x", ps->ps_mask[x]); - printf("\n"); - - printf("}\n"); - - return 0; -} - - -int -qd_read_print_status(target_info_t *disk, int nid) -{ - status_block_t ps; - - if (!disk || disk->d_fd < 0) { - errno = EINVAL; - return -1; - } - - if (nid <= 0) { - errno = EINVAL; - return -1; - } - - if (qdisk_read(disk, qdisk_nodeid_offset(nid, disk->d_blksz), &ps, - sizeof(ps)) < 0) { - printf("Error reading node ID block %d\n", nid); - return -1; - } - swab_status_block_t(&ps); - qd_print_status(disk, &ps); - - return 0; -} - - -/** - Generate a token based on the current system time. - */ -uint64_t -generate_token(void) -{ - uint64_t my_token = 0; - struct timeval tv; - - while(my_token == 0) { - gettimeofday(&tv, NULL); - - my_token = ((uint64_t) (tv.tv_sec) << 32) | - (uint64_t) (tv.tv_sec & 0x00000000ffffffff); - } - - return my_token; -} - - -/** - Initialize a quorum disk context, given a CMAN handle and a nodeid. - */ -int -qd_init(qd_ctx *ctx, cman_handle_t ch, int me) -{ - if (!ctx || !ch || !me) { - errno = EINVAL; - return -1; - } - - memset(ctx, 0, sizeof(*ctx)); - ctx->qc_incarnation = generate_token(); - ctx->qc_ch = ch; - ctx->qc_my_id = me; - - return 0; -} - - -/** - Destroy a quorum disk context - */ -void -qd_destroy(qd_ctx *ctx) -{ - if (ctx->qc_my_id == 0) - return; - if (ctx->qc_device) { - free(ctx->qc_device); - ctx->qc_device = NULL; - } - qdisk_close(&ctx->qc_disk); -} diff --git a/cman/qdisk/gettid.c b/cman/qdisk/gettid.c deleted file mode 100644 index 620a785..0000000 --- a/cman/qdisk/gettid.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <sys/types.h> -#include <sys/syscall.h> -#include <linux/unistd.h> -#include <gettid.h> -#include <unistd.h> -#include <errno.h> - -/* Patch from Adam Conrad / Ubuntu: Don't use _syscall macro */ - -#ifdef __NR_gettid -pid_t gettid (void) -{ - return syscall(__NR_gettid); -} -#else - -#warn "gettid not available -- substituting with pthread_self()" - -#include <pthread.h> -pid_t gettid (void) -{ - return (pid_t)pthread_self(); -} -#endif diff --git a/cman/qdisk/gettid.h b/cman/qdisk/gettid.h deleted file mode 100644 index 636560c..0000000 --- a/cman/qdisk/gettid.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __GETTID_H -#define __GETTID_H - -pid_t gettid(void); - -#endif - diff --git a/cman/qdisk/iostate.c b/cman/qdisk/iostate.c deleted file mode 100644 index f4f2329..0000000 --- a/cman/qdisk/iostate.c +++ /dev/null @@ -1,142 +0,0 @@ -#include <pthread.h> -#include <iostate.h> -#include <unistd.h> -#include <time.h> -#include <sys/time.h> -#include <clulog.h> -#include "iostate.h" - -static iostate_t main_state = 0; -static int main_incarnation = 0; -static int qdisk_timeout = 0, sleeptime = 0; -static int thread_active = 0; -static pthread_t io_nanny_tid = 0; -static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t state_cond = PTHREAD_COND_INITIALIZER; - -struct state_table { - iostate_t state; - const char *value; -}; - -static struct state_table io_state_table[] = { -{ STATE_NONE, "none" }, -{ STATE_WRITE, "write" }, -{ STATE_READ, "read" }, -{ STATE_LSEEK, "seek" }, -{ -1, NULL } }; - -static const char * -state_to_string(iostate_t state) -{ - static const char *ret = "unknown"; - int i; - - for (i=0; io_state_table[i].value; i++) { - if (io_state_table[i].state == state) { - ret = io_state_table[i].value; - break; - } - } - - return ret; -} - - -void -io_state(iostate_t state) -{ - pthread_mutex_lock(&state_mutex); - main_state = state; - main_incarnation++; /* it does not matter if this wraps. */ - pthread_mutex_unlock(&state_mutex); - - /* Optimization: Don't signal on STATE_NONE */ - if (state != STATE_NONE) - pthread_cond_broadcast(&state_cond); -} - - -static void * -io_nanny_thread(void *arg) -{ - struct timespec wait_time; - iostate_t last_main_state = 0, current_main_state = 0; - int last_main_incarnation = 0, current_main_incarnation = 0; - int logged_incarnation = 0; - - /* Start with wherever we're at now */ - pthread_mutex_lock(&state_mutex); - current_main_state = last_main_state = main_state; - current_main_incarnation = last_main_incarnation = main_incarnation; - pthread_mutex_unlock(&state_mutex); - - while (thread_active) { - pthread_mutex_lock(&state_mutex); - clock_gettime(CLOCK_REALTIME, &wait_time); - wait_time.tv_sec += sleeptime; - pthread_cond_timedwait(&state_cond, &state_mutex, &wait_time); - current_main_state = main_state; - current_main_incarnation = main_incarnation; - pthread_mutex_unlock(&state_mutex); - - if (!thread_active) - break; - - if (!current_main_state) - continue; - - /* if the state or incarnation changed, the main qdiskd - * thread is healthy */ - if (current_main_state != last_main_state || - current_main_incarnation != last_main_incarnation) { - last_main_state = current_main_state; - last_main_incarnation = current_main_incarnation; - continue; - } - - /* Don't log things twice */ - if (logged_incarnation == current_main_incarnation) - continue; - logged_incarnation = current_main_incarnation; - - clulog(LOG_WARNING, "qdiskd: %s " - "(system call) has hung for %d seconds\n", - state_to_string(current_main_state), sleeptime); - clulog(LOG_WARNING, - "In %d more seconds, we will be evicted\n", - (qdisk_timeout-sleeptime)); - } - - return NULL; -} - - -int -io_nanny_start(int timeout) -{ - int ret; - - pthread_mutex_lock(&state_mutex); - - sleeptime = timeout / 2; - qdisk_timeout = timeout; - thread_active = 1; - - ret = pthread_create(&io_nanny_tid, NULL, io_nanny_thread, NULL); - pthread_mutex_unlock(&state_mutex); - - return ret; -} - - -int -io_nanny_stop(void) -{ - thread_active = 0; - pthread_cond_broadcast(&state_cond); - pthread_join(io_nanny_tid, NULL); - io_nanny_tid = 0; - - return 0; -} diff --git a/cman/qdisk/iostate.h b/cman/qdisk/iostate.h deleted file mode 100644 index 7dd7bf6..0000000 --- a/cman/qdisk/iostate.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _IOSTATE_H -#define _IOSTATE_H - -typedef enum { - STATE_NONE = 0, - STATE_READ = 1, - STATE_WRITE = 2, - STATE_LSEEK = 3, - STATE_UNKNOWN = 4 -} iostate_t; - -void io_state(iostate_t state); - -int io_nanny_start(int timeout); -int io_nanny_stop(void); - -#endif diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c deleted file mode 100644 index 10ec337..0000000 --- a/cman/qdisk/main.c +++ /dev/null @@ -1,1664 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Main loop / functions for disk-based quorum daemon. - */ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <string.h> -#include <errno.h> -#include <disk.h> -#include <platform.h> -#include <unistd.h> -#include <time.h> -#include <sys/reboot.h> -#include <sys/time.h> -#include <linux/reboot.h> -#include <sched.h> -#include <signal.h> -#include <ccs.h> -#include "score.h" -#include "clulog.h" -#include "iostate.h" -#if (!defined(LIBCMAN_VERSION) || \ - (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION < 2)) -#include <cluster/cnxman-socket.h> -#endif - -void daemon_init(char *); -int check_process_running(char *, pid_t *); - -/* - TODO: - 1) Take into account timings to gracefully extend node timeouts during - node spikes (that's why they are there!). - 2) Poll ccsd for configuration changes. - 3) Logging. - */ - -/* From bitmap.c */ -int clear_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen); -int set_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen); -int is_bit_set(uint8_t *mask, uint32_t bitidx, uint32_t masklen); -inline int get_time(struct timeval *tv, int use_uptime); -inline void _diff_tv(struct timeval *dest, struct timeval *start, - struct timeval *end); - -static int _running = 1; -void update_local_status(qd_ctx *ctx, node_info_t *ni, int max, int score, - int score_req, int score_max); - - -static void -int_handler(int sig) -{ - _running = 0; -} - - -/** - Simple thing to see if a node is running. - */ -inline int -state_run(disk_node_state_t state) -{ - return (state >= S_INIT ? state : 0); -} - - -/** - Clear out / initialize node info block. - */ -void -node_info_init(node_info_t *ni, int max) -{ - int x; - time_t t = time(NULL); - - memset(ni, 0, sizeof(*ni) * max); - for (x = 0; x < max; x++) { - ni[x].ni_status.ps_nodeid = (x + 1); /* node ids are 1-based */ - ni[x].ni_status.ps_timestamp = t; - ni[x].ni_misses = 0; - ni[x].ni_last_seen = t; - } -} - - -/** - Check to see if someone tried to evict us but we were out to lunch. - Rare case; usually other nodes would put up the 'Undead' message and - re-evict us. - */ -void -check_self(qd_ctx *ctx, status_block_t *sb) -{ - if (!sb->ps_updatenode || - (sb->ps_updatenode == ctx->qc_my_id)) { - return; - } - - /* I did not update this??! */ - switch(sb->ps_state) { - case S_EVICT: - /* Someone told us to die. */ - reboot(RB_AUTOBOOT); - default: - clulog(LOG_EMERG, "Unhandled state: %d\n", sb->ps_state); - raise(SIGSTOP); - } -} - - -/** - Read in the node blocks off of the quorum disk and see if anyone has - or has not updated their timestamp recently. See check_transitions as - well. - */ -int -read_node_blocks(qd_ctx *ctx, node_info_t *ni, int max) -{ - int x, errors = 0; - status_block_t *sb; - - for (x = 0; x < max; x++) { - - sb = &ni[x].ni_status; - - if (qdisk_read(&ctx->qc_disk, - qdisk_nodeid_offset(x+1, ctx->qc_disk.d_blksz), - sb, sizeof(*sb)) < 0) { - clulog(LOG_WARNING,"Error reading node ID block %d\n", - x+1); - errors++; - continue; - } - swab_status_block_t(sb); - - if (sb->ps_nodeid == ctx->qc_my_id) { - check_self(ctx, sb); - continue; - } - /* message. */ - memcpy(&(ni[x].ni_last_msg), &(ni[x].ni_msg), - sizeof(ni[x].ni_last_msg)); - ni[x].ni_msg.m_arg = sb->ps_arg; - ni[x].ni_msg.m_msg = sb->ps_msg; - ni[x].ni_msg.m_seq = sb->ps_seq; - - if (!state_run(sb->ps_state)) - continue; - - /* Unchanged timestamp: miss */ - if (sb->ps_timestamp == ni[x].ni_last_seen) { - /* XXX check for average + allow grace */ - ni[x].ni_misses++; - if (ni[x].ni_misses > 1) { - clulog(LOG_DEBUG, - "Node %d missed an update (%d/%d)\n", - x+1, ni[x].ni_misses, ctx->qc_tko); - } - continue; - } - - /* Got through? The node is good. */ - ni[x].ni_misses = 0; - ni[x].ni_seen++; - ni[x].ni_last_seen = sb->ps_timestamp; - } - - return errors; -} - - -/** - Check for node transitions. - */ -void -check_transitions(qd_ctx *ctx, node_info_t *ni, int max, memb_mask_t mask) -{ - int x; - - if (mask) - memset(mask, 0, sizeof(memb_mask_t)); - - for (x = 0; x < max; x++) { - - /* - Case 1: check to see if the node is still up - according to our internal state, but has been - evicted by the master or cleanly shut down - (or restarted). - - Transition from Evicted/Shutdown -> Offline - */ - if ((ni[x].ni_state >= S_EVICT && - ni[x].ni_status.ps_state <= S_EVICT) || - (ni[x].ni_incarnation && - (ni[x].ni_incarnation != - ni[x].ni_status.ps_incarnation))) { - - if (ni[x].ni_status.ps_state == S_EVICT) { - clulog(LOG_NOTICE, "Node %d evicted\n", - ni[x].ni_status.ps_nodeid); - } else { - /* State == S_NONE or incarnation change */ - clulog(LOG_INFO, "Node %d shutdown\n", - ni[x].ni_status.ps_nodeid); - ni[x].ni_evil_incarnation = 0; - } - - ni[x].ni_incarnation = 0; - ni[x].ni_seen = 0; - ni[x].ni_misses = 0; - ni[x].ni_state = S_NONE; - - /* Clear our master mask for the node after eviction - * or shutdown */ - if (mask) - clear_bit(mask, (ni[x].ni_status.ps_nodeid-1), - sizeof(memb_mask_t)); - continue; - } - - /* - Case 2: Check for a heartbeat timeout. Write an eviction - notice if we're the master. If this is our first notice - of the heartbeat timeout, update our internal state - accordingly. When the master evicts this node, we will - hit case 1 above. - - Transition from Online -> Evicted - */ - if (ni[x].ni_misses > ctx->qc_tko && - state_run(ni[x].ni_status.ps_state)) { - - /* - Mark our internal views as dead if nodes miss too - many heartbeats... This will cause a master - transition if no live master exists. - */ - if (ni[x].ni_status.ps_state >= S_RUN && - ni[x].ni_seen) { - clulog(LOG_DEBUG, "Node %d DOWN\n", - ni[x].ni_status.ps_nodeid); - ni[x].ni_seen = 0; - } - - ni[x].ni_state = S_EVICT; - ni[x].ni_status.ps_state = S_EVICT; - ni[x].ni_evil_incarnation = - ni[x].ni_incarnation; - - /* - Write eviction notice if we're the master. - */ - if (ctx->qc_status == S_MASTER) { - clulog(LOG_NOTICE, - "Writing eviction notice for node %d\n", - ni[x].ni_status.ps_nodeid); - qd_write_status(ctx, ni[x].ni_status.ps_nodeid, - S_EVICT, NULL, NULL, NULL); - if (ctx->qc_flags & RF_ALLOW_KILL) { - clulog(LOG_DEBUG, "Telling CMAN to " - "kill the node\n"); - cman_kill_node(ctx->qc_ch, - ni[x].ni_status.ps_nodeid); - } - } - - /* Clear our master mask for the node after eviction */ - if (mask) - clear_bit(mask, (ni[x].ni_status.ps_nodeid-1), - sizeof(memb_mask_t)); - continue; - } - - /* - Case 3: Check for node who is supposed to be dead, but - has started writing to the disk again with the same - incarnation. - - Transition from Offline -> Undead (BAD!!!) - */ - if (ni[x].ni_evil_incarnation && - (ni[x].ni_evil_incarnation == - ni[x].ni_status.ps_incarnation) && - (ni[x].ni_status.ps_updatenode == - ni[x].ni_status.ps_nodeid)) { - clulog(LOG_CRIT, "Node %d is undead.\n", - ni[x].ni_status.ps_nodeid); - - clulog(LOG_ALERT, - "Writing eviction notice (again) for node %d\n", - ni[x].ni_status.ps_nodeid); - qd_write_status(ctx, ni[x].ni_status.ps_nodeid, - S_EVICT, NULL, NULL, NULL); - ni[x].ni_status.ps_state = S_EVICT; - - /* XXX Need to fence it again */ - if (ctx->qc_flags & RF_ALLOW_KILL) { - clulog(LOG_DEBUG, "Telling CMAN to " - "kill the node\n"); - cman_kill_node(ctx->qc_ch, - ni[x].ni_status.ps_nodeid); - } - continue; - } - - - /* - Case 4: Check for a node who has met our minimum # of - 'seen' requests. - - Transition from Offline -> Online - */ - if (ni[x].ni_seen > ctx->qc_tko_up && - !state_run(ni[x].ni_state)) { - /* - Node-join - everyone just kind of "agrees" - there's no consensus to just have a node join - right now. - */ - ni[x].ni_state = S_RUN; - clulog(LOG_DEBUG, "Node %d is UP\n", - ni[x].ni_status.ps_nodeid); - ni[x].ni_incarnation = - ni[x].ni_status.ps_incarnation; - ni[x].ni_evil_incarnation = 0; - - if (mask) - set_bit(mask, (ni[x].ni_status.ps_nodeid-1), - sizeof(memb_mask_t)); - - continue; - } - - /* - Case 5: Check for a node becoming master. Not really a - transition. - */ - if (ni[x].ni_state == S_RUN && - ni[x].ni_status.ps_state == S_MASTER) { - clulog(LOG_INFO, "Node %d is the master\n", - ni[x].ni_status.ps_nodeid); - ni[x].ni_state = S_MASTER; - if (mask) - set_bit(mask, (ni[x].ni_status.ps_nodeid-1), - sizeof(memb_mask_t)); - continue; - } - - /* - Case 6: Check for a node which has changed its - incarnation # quickly (e.g. killall -9 qdiskd; - qdiskd). Not a transition. - */ - if (state_run(ni[x].ni_state) && - ni[x].ni_incarnation != ni[x].ni_status.ps_incarnation) { - - clulog(LOG_DEBUG, "Node %d incarnation # changed\n", - ni[x].ni_status.ps_nodeid); - ni[x].ni_incarnation = - ni[x].ni_status.ps_incarnation; - ni[x].ni_evil_incarnation = 0; - - continue; - } - - /* - All other cases: Believe the node's reported state ;) - */ - if (state_run(ni[x].ni_state)) { - ni[x].ni_state = ni[x].ni_status.ps_state; - if (mask) - set_bit(mask, (ni[x].ni_status.ps_nodeid-1), - sizeof(memb_mask_t)); - } - } -} - - -/** - Checks for presence of an online master. If there is no - Returns - */ -int -master_exists(qd_ctx *ctx, node_info_t *ni, int max, int *low_id, int *count) -{ - int x; - int masters = 0; - int ret = 0; - - if (count) - *count = 0; - *low_id = ctx->qc_my_id; - - for (x = 0; x < max; x++) { - - /* See if this one's a master */ - if (ni[x].ni_state >= S_RUN && - ni[x].ni_status.ps_state == S_MASTER && - ni[x].ni_status.ps_nodeid != ctx->qc_my_id) { - if (!ret) - ret = ni[x].ni_status.ps_nodeid; - ++masters; - continue; - } - - /* See if it's us... */ - if (ni[x].ni_status.ps_nodeid == ctx->qc_my_id && - ni[x].ni_status.ps_state == S_MASTER) { - if (!ret) - ret = ctx->qc_my_id; - ++masters; - continue; - } - - /* Look for dead master */ - if (ni[x].ni_state < S_RUN && - ni[x].ni_status.ps_state == S_MASTER) { - clulog(LOG_DEBUG, - "Node %d is marked master, but is dead.\n", - ni[x].ni_status.ps_nodeid); - continue; - } - - if (ni[x].ni_state < S_RUN) - continue; - - if (ni[x].ni_status.ps_nodeid < *low_id) - *low_id = ni[x].ni_status.ps_nodeid; - } - - if (count) - *count = masters; - /* - else if (masters == 1) { - printf("Node %d is the master\n", ret); - } else { - printf("No master found; node %d should be the master\n", - *low_id); - } - */ - - return ret; -} - - -/** - initialize node information blocks and wait to see if there is already - a cluster running using this QD. Note that this will delay master - election if multiple nodes start with a second or two of each other. - */ -int -quorum_init(qd_ctx *ctx, node_info_t *ni, int max, struct h_data *h, int maxh) -{ - int x = 0, score, maxscore, score_req; - - clulog(LOG_INFO, "Quorum Daemon Initializing\n"); - - if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) { - clulog(LOG_ERR, "Unable to mlockall()\n"); - } - - if (qdisk_validate(ctx->qc_device) < 0) - return -1; - - if (qdisk_open(ctx->qc_device, &ctx->qc_disk) < 0) { - clulog(LOG_CRIT, "Failed to open %s: %s\n", ctx->qc_device, - strerror(errno)); - return -1; - } - - clulog(LOG_DEBUG, "I/O Size: %d Page Size: %d\n", - ctx->qc_disk.d_blksz, ctx->qc_disk.d_pagesz); - - if (h && maxh) { - start_score_thread(ctx, h, maxh); - } else { - clulog(LOG_DEBUG, "Permanently setting score to 1/1\n"); - fudge_scoring(); - } - - node_info_init(ni, max); - ctx->qc_status = S_INIT; - if (qd_write_status(ctx, ctx->qc_my_id, - S_INIT, NULL, NULL, NULL) != 0) { - clulog(LOG_CRIT, "Could not initialize status block!\n"); - return -1; - } - - while (++x <= ctx->qc_tko && _running) { - read_node_blocks(ctx, ni, max); - check_transitions(ctx, ni, max, NULL); - - if (qd_write_status(ctx, ctx->qc_my_id, - S_INIT, NULL, NULL, NULL) != 0) { - clulog(LOG_CRIT, "Initialization failed\n"); - return -1; - } - - get_my_score(&score, &maxscore); - score_req = ctx->qc_scoremin; - if (score_req <= 0) - score_req = (maxscore/2 + 1); - update_local_status(ctx, ni, max, score, score_req, maxscore); - - sleep(ctx->qc_interval); - } - - get_my_score(&score, &maxscore); - clulog(LOG_INFO, "Initial score %d/%d\n", score, maxscore); - if ((ctx->qc_flags & RF_STOP_CMAN) && (score < score_req)) - return -1; - clulog(LOG_INFO, "Initialization complete\n"); - - return 0; -} - - -/** - Vote for a master if it puts a bid in. - */ -void -do_vote(qd_ctx *ctx, node_info_t *ni, int max, disk_msg_t *msg) -{ - int x; - - for (x = 0; x < max; x++) { - if (ni[x].ni_state != S_RUN) - continue; - - if (ni[x].ni_status.ps_msg == M_BID && - ni[x].ni_status.ps_nodeid < ctx->qc_my_id) { - - /* Vote for lowest bidding ID that is lower - than us */ - msg->m_msg = M_ACK; - msg->m_arg = ni[x].ni_status.ps_nodeid; - msg->m_seq = ni[x].ni_status.ps_seq; - - return; - } - } -} - - -/* - Check to match nodes in mask with nodes online according to CMAN. - Only the master needs to do this. - */ -void -check_cman(qd_ctx *ctx, memb_mask_t mask, memb_mask_t master_mask) -{ - cman_node_t nodes[MAX_NODES_DISK]; - int retnodes, x; - - if (cman_get_nodes(ctx->qc_ch, MAX_NODES_DISK, - &retnodes, nodes) <0 ) - return; - - memset(master_mask, 0, sizeof(master_mask)); - for (x = 0; x < retnodes; x++) { - if (is_bit_set(mask, nodes[x].cn_nodeid-1, sizeof(mask)) && - nodes[x].cn_member) { - set_bit(master_mask, nodes[x].cn_nodeid-1, - sizeof(master_mask)); - } else { - /* Not in CMAN output = not allowed */ - clear_bit(master_mask, (nodes[x].cn_nodeid-1), - sizeof(memb_mask_t)); - } - } -} - - -/* - returns: - 3: all acks received - you are the master. - 2: nacked (not highest score?) might not happen - 1: other node with lower ID is bidding and we should rescind our - bid. - 0: still waiting; don't clear bid; just wait another round. - Modifies: - *msg - it will store the vote for the lowest bid if we should - clear our bid. - */ -int -check_votes(qd_ctx *ctx, node_info_t *ni, int max, disk_msg_t *msg) -{ - int x, running = 0, acks = 0, nacks = 0, low_id = ctx->qc_my_id; - - for (x = 0; x < max; x++) { - if (state_run(ni[x].ni_state)) - ++running; - else - continue; - - if (ni[x].ni_status.ps_msg == M_ACK && - ni[x].ni_status.ps_arg == ctx->qc_my_id) { - ++acks; - } - - if (ni[x].ni_status.ps_msg == M_NACK && - ni[x].ni_status.ps_arg == ctx->qc_my_id) { - ++nacks; - } - - /* If there's someone with a lower ID who is also - bidding for master, change our message to vote - for the lowest bidding node ID */ - if (ni[x].ni_status.ps_msg == M_BID && - ni[x].ni_status.ps_nodeid < low_id) { - low_id = ni[x].ni_status.ps_nodeid; - msg->m_msg = M_ACK; - msg->m_arg = ni[x].ni_status.ps_nodeid; - msg->m_seq = ni[x].ni_status.ps_seq; - } - } - - if (acks == running) - return 3; - if (nacks) - return 2; - if (low_id != ctx->qc_my_id) - return 1; - return 0; -} - - -char * -state_str(disk_node_state_t s) -{ - switch (s) { - case S_NONE: - return "None"; - case S_EVICT: - return "Evicted"; - case S_INIT: - return "Initializing"; - case S_RUN: - return "Running"; - case S_MASTER: - return "Master"; - default: - return "ILLEGAL"; - } -} - - -void -print_node_info(FILE *fp, node_info_t *ni) -{ - fprintf(fp, "node_info_t [node %d] {\n", ni->ni_status.ps_nodeid); - fprintf(fp, " ni_incarnation = 0x%08x%08x\n", - ((int)(ni->ni_incarnation>>32))&0xffffffff, - ((int)(ni->ni_incarnation)&0xffffffff)); - fprintf(fp, " ni_evil_incarnation = 0x%08x%08x\n", - ((int)(ni->ni_evil_incarnation>>32))&0xffffffff, - ((int)(ni->ni_evil_incarnation)&0xffffffff)); - fprintf(fp, " ni_last_seen = %s", ctime(&ni->ni_last_seen)); - fprintf(fp, " ni_misses = %d\n", ni->ni_misses); - fprintf(fp, " ni_seen = %d\n", ni->ni_seen); - fprintf(fp, " ni_msg = {\n"); - fprintf(fp, " m_msg = 0x%08x\n", ni->ni_msg.m_msg); - fprintf(fp, " m_arg = %d\n", ni->ni_msg.m_arg); - fprintf(fp, " m_seq = %d\n", ni->ni_msg.m_seq); - fprintf(fp, " }\n"); - fprintf(fp, " ni_last_msg = {\n"); - fprintf(fp, " m_msg = 0x%08x\n", ni->ni_last_msg.m_msg); - fprintf(fp, " m_arg = %d\n", ni->ni_last_msg.m_arg); - fprintf(fp, " m_seq = %d\n", ni->ni_last_msg.m_seq); - fprintf(fp, " }\n"); - fprintf(fp, " ni_state = 0x%08x (%s)\n", ni->ni_state, - state_str(ni->ni_state)); - fprintf(fp, "}\n\n"); -} - - -void -update_local_status(qd_ctx *ctx, node_info_t *ni, int max, int score, - int score_req, int score_max) -{ - FILE *fp; - int x, need_close = 0; - time_t now; - - if (!ctx->qc_status_file) - return; - - if (strcmp(ctx->qc_status_file, "-") == 0) { - fp = stdout; - } else { - fp = fopen(ctx->qc_status_file, "w+"); - if (fp == NULL) - return; - need_close = 1; - } - - now = time(NULL); - fprintf(fp, "Time Stamp: %s", ctime(&now)); - fprintf(fp, "Node ID: %d\n", ctx->qc_my_id); - - fprintf(fp, "Score: %d/%d (Minimum required = %d)\n", - score, score_max, score_req); - fprintf(fp, "Current state: %s\n", state_str(ctx->qc_status)); - - /* - fprintf(fp, "Current disk state: %s\n", - state_str(ctx->qc_disk_status)); - */ - fprintf(fp, "Initializing Set: {"); - for (x=0; x<max; x++) { - if (ni[x].ni_status.ps_state == S_INIT && ni[x].ni_seen) - fprintf(fp," %d", ni[x].ni_status.ps_nodeid); - } - fprintf(fp, " }\n"); - - fprintf(fp, "Visible Set: {"); - for (x=0; x<max; x++) { - if (ni[x].ni_state >= S_RUN || ni[x].ni_status.ps_nodeid == - ctx->qc_my_id) - fprintf(fp," %d", ni[x].ni_status.ps_nodeid); - } - fprintf(fp, " }\n"); - - if (ctx->qc_status == S_INIT) - goto out; - - if (ctx->qc_master) - fprintf(fp, "Master Node ID: %d\n", ctx->qc_master); - else - fprintf(fp, "Master Node ID: (none)\n"); - - if (!ctx->qc_master) - goto out; - - fprintf(fp, "Quorate Set: {"); - for (x=0; x<max; x++) { - if (is_bit_set(ni[ctx->qc_master-1].ni_status.ps_master_mask, - ni[x].ni_status.ps_nodeid-1, - sizeof(memb_mask_t))) { - fprintf(fp," %d", ni[x].ni_status.ps_nodeid); - } - } - - fprintf(fp, " }\n"); - -out: - if (ctx->qc_flags & RF_DEBUG) { - for (x = 0; x < max; x++) - print_node_info(fp, &ni[x]); - } - - fprintf(fp, "\n"); - if (need_close) - fclose(fp); -} - - -/* Timeval functions from clumanager */ -/** - * Scale a (struct timeval). - * - * @param tv The timeval to scale. - * @param scale Positive multiplier. - * @return tv - */ -struct timeval * -_scale_tv(struct timeval *tv, int scale) -{ - tv->tv_sec *= scale; - tv->tv_usec *= scale; - - if (tv->tv_usec > 1000000) { - tv->tv_sec += (tv->tv_usec / 1000000); - tv->tv_usec = (tv->tv_usec % 1000000); - } - - return tv; -} - - - -#define _print_tv(val) \ - printf("%s: %d.%06d\n", #val, (int)((val)->tv_sec), \ - (int)((val)->tv_usec)) - - -static inline int -_cmp_tv(struct timeval *left, struct timeval *right) -{ - if (left->tv_sec > right->tv_sec) - return -1; - - if (left->tv_sec < right->tv_sec) - return 1; - - if (left->tv_usec > right->tv_usec) - return -1; - - if (left->tv_usec < right->tv_usec) - return 1; - - return 0; -} - - -void -set_priority(int queue, int prio) -{ - struct sched_param s; - int ret; - char *func = "nice"; - - if (queue == SCHED_OTHER) { - s.sched_priority = 0; - ret = sched_setscheduler(0, queue, &s); - errno = 0; - ret = nice(prio); - } else { - memset(&s,0,sizeof(s)); - s.sched_priority = prio; - ret = sched_setscheduler(0, queue, &s); - func = "sched_setscheduler"; - } - - if (ret < 0 && errno) { - clulog(LOG_WARNING, "set_priority [%s] failed: %s\n", func, - strerror(errno)); - } -} - - -int -cman_alive(cman_handle_t ch) -{ - fd_set rfds; - int fd = cman_get_fd(ch); - struct timeval tv = {0, 0}; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - if (select(fd + 1, &rfds, NULL, NULL, &tv) == 1) { - if (cman_dispatch(ch, CMAN_DISPATCH_ALL) < 0) { - if (errno == EAGAIN) - return 0; - return -1; - } - } - return 0; -} - - -int -quorum_loop(qd_ctx *ctx, node_info_t *ni, int max) -{ - disk_msg_t msg = {0, 0, 0}; - int low_id, bid_pending = 0, score, score_max, score_req, - upgrade = 0, count; - memb_mask_t mask, master_mask; - struct timeval maxtime, oldtime, newtime, diff, sleeptime, interval, rd_lastok, wr_lastok; - - ctx->qc_status = S_NONE; - - maxtime.tv_usec = 0; - maxtime.tv_sec = ctx->qc_interval * ctx->qc_tko; - - interval.tv_usec = 0; - interval.tv_sec = ctx->qc_interval; - - rd_lastok.tv_usec = 0; - rd_lastok.tv_sec = 0; - - wr_lastok.tv_usec = 0; - wr_lastok.tv_sec = 0; - - get_my_score(&score, &score_max); - if (score_max < ctx->qc_scoremin) { - clulog(LOG_WARNING, "Minimum score (%d) is impossible to " - "achieve (heuristic total = %d)\n", - ctx->qc_scoremin, score_max); - } - - _running = 1; - while (_running) { - /* XXX this was getuptime() in clumanager */ - get_time(&oldtime, (ctx->qc_flags&RF_UPTIME)); - - /* Read everyone else's status */ - if ( read_node_blocks(ctx, ni, max) == 0 ) - get_time(&rd_lastok, ctx->qc_flags&RF_UPTIME); - - /* Check for node transitions */ - check_transitions(ctx, ni, max, mask); - - /* Check heuristics and remove ourself if necessary */ - get_my_score(&score, &score_max); - - /* If we recently upgraded, decrement our wait time */ - if (upgrade > 0) - --upgrade; - - score_req = ctx->qc_scoremin; - if (score_req <= 0) - score_req = (score_max/2 + 1); - - if (score < score_req) { - clear_bit(mask, (ctx->qc_my_id-1), sizeof(mask)); - if (ctx->qc_status > S_NONE) { - clulog(LOG_NOTICE, - "Score insufficient for master " - "operation (%d/%d; required=%d); " - "downgrading\n", - score, score_max, score_req); - ctx->qc_status = S_NONE; - msg.m_msg = M_NONE; - ++msg.m_seq; - bid_pending = 0; - if (cman_alive(ctx->qc_ch) < 0) { - clulog(LOG_ERR, "cman: %s\n", - strerror(errno)); - } else { - cman_poll_quorum_device(ctx->qc_ch, 0); - } - if (ctx->qc_flags & RF_REBOOT) - reboot(RB_AUTOBOOT); - } - } else { - set_bit(mask, (ctx->qc_my_id-1), sizeof(mask)); - if (ctx->qc_status == S_NONE) { - clulog(LOG_NOTICE, - "Score sufficient for master " - "operation (%d/%d; required=%d); " - "upgrading\n", - score, score_max, score_req); - ctx->qc_status = S_RUN; - upgrade = ctx->qc_upgrade_wait; - bid_pending = 0; - msg.m_msg = M_NONE; - ++msg.m_seq; - } - } - - /* Find master */ - ctx->qc_master = master_exists(ctx, ni, max, &low_id, &count); - - /* Resolve master conflict, if one exists */ - if (count >= 1 && ctx->qc_status == S_MASTER && - ctx->qc_master != ctx->qc_my_id) { - clulog(LOG_WARNING, "Master conflict: abdicating\n"); - - /* Handle just like a recent upgrade */ - ctx->qc_status = S_RUN; - upgrade = ctx->qc_upgrade_wait; - bid_pending = 0; - msg.m_msg = M_NONE; - ++msg.m_seq; - } - - /* Figure out what to do based on what we know */ - if (!ctx->qc_master && - low_id == ctx->qc_my_id && - ctx->qc_status == S_RUN && - !bid_pending && - !upgrade) { - /* - If there's no master, and we are the lowest node - ID, make a bid to become master if we're not - already bidding. We can't do this if we've just - upgraded. - */ - - clulog(LOG_DEBUG,"Making bid for master\n"); - msg.m_msg = M_BID; - ++msg.m_seq; - bid_pending = 1; - - } else if (!ctx->qc_master && !bid_pending) { - - /* We're not the master, and we do not have a bid - pending. Check for voting on other nodes. */ - do_vote(ctx, ni, max, &msg); - } else if (!ctx->qc_master && bid_pending) { - - /* We're currently bidding for master. - See if anyone's voted, or if we should - rescind our bid */ - ++bid_pending; - - /* Yes, those are all deliberate fallthroughs */ - switch (check_votes(ctx, ni, max, &msg)) { - case 3: - /* - * Give ample time to become aware of other - * nodes - */ - if (bid_pending < (ctx->qc_master_wait)) - break; - - clulog(LOG_INFO, - "Assuming master role\n"); - ctx->qc_status = S_MASTER; - case 2: - msg.m_msg = M_NONE; - case 1: - bid_pending = 0; - default: - break; - } - } else if (ctx->qc_status == S_MASTER && - ctx->qc_master != ctx->qc_my_id) { - - /* We think we're master, but someone else claims - that they are master. */ - - clulog(LOG_CRIT, - "A master exists, but it's not me?!\n"); - /* XXX Handle this how? Should not happen*/ - /* reboot(RB_AUTOBOOT); */ - - } else if (ctx->qc_status == S_MASTER && - ctx->qc_master == ctx->qc_my_id) { - - /* We are the master. Poll the quorum device. - We can't be the master unless we score high - enough on our heuristics. */ - if (cman_alive(ctx->qc_ch) < 0) { - clulog(LOG_ERR, "cman_dispatch: %s\n", - strerror(errno)); - clulog(LOG_ERR, - "Halting qdisk operations\n"); - return -1; - } - check_cman(ctx, mask, master_mask); - cman_poll_quorum_device(ctx->qc_ch, 1); - - } else if (ctx->qc_status == S_RUN && ctx->qc_master && - ctx->qc_master != ctx->qc_my_id) { - - /* We're not the master, but a master exists - Check to see if the master thinks we are - online. If we are, tell CMAN so. */ - if (is_bit_set( - ni[ctx->qc_master-1].ni_status.ps_master_mask, - ctx->qc_my_id-1, - sizeof(memb_mask_t))) { - if (cman_alive(ctx->qc_ch) < 0) { - clulog(LOG_ERR, "cman_dispatch: %s\n", - strerror(errno)); - clulog(LOG_ERR, - "Halting qdisk operations\n"); - return -1; - } - cman_poll_quorum_device(ctx->qc_ch, 1); - } - } - - /* Write out our status */ - if (qd_write_status(ctx, ctx->qc_my_id, ctx->qc_status, - &msg, mask, master_mask) != 0) { - clulog(LOG_ERR, "Error writing to quorum disk\n"); - } else { - get_time(&wr_lastok, ctx->qc_flags&RF_UPTIME); - } - - /* write out our local status */ - update_local_status(ctx, ni, max, score, score_req, score_max); - - /* Cycle. We could time the loop and sleep - usleep(interval-looptime), but this is fine for now.*/ - get_time(&newtime, ctx->qc_flags&RF_UPTIME); - - /* - * Reboot if the last successful hearbeat was longer ago than interval*TKO_COUNT - */ - _diff_tv(&diff, &wr_lastok, &newtime); - if (_cmp_tv(&maxtime, &diff) == 1 && - ctx->qc_flags & RF_IOTIMEOUT) { - clulog(LOG_EMERG, "Failed to send a heartbeat within " - "%d second%s (%d.%06d) - REBOOTING\n", - (int)maxtime.tv_sec, - maxtime.tv_sec==1?"":"s", - (int)diff.tv_sec, - (int)diff.tv_usec); - if (!(ctx->qc_flags & RF_DEBUG)) - reboot(RB_AUTOBOOT); - } - - /* - * Reboot if the last successful hearbeat was longer ago than interval*TKO_COUNT - */ - _diff_tv(&diff, &rd_lastok, &newtime); - if (_cmp_tv(&maxtime, &diff) == 1 && - ctx->qc_flags & RF_IOTIMEOUT) { - clulog(LOG_EMERG, "Failed to read from qdisk within " - "%d second%s (%d.%06d) - REBOOTING\n", - (int)maxtime.tv_sec, - maxtime.tv_sec==1?"":"s", - (int)diff.tv_sec, - (int)diff.tv_usec); - if (!(ctx->qc_flags & RF_DEBUG)) - reboot(RB_AUTOBOOT); - } - - /* - * Reboot if we didn't send a heartbeat in interval*TKO_COUNT - */ - _diff_tv(&diff, &oldtime, &newtime); - if (_cmp_tv(&maxtime, &diff) == 1 && - ctx->qc_flags & RF_PARANOID) { - clulog(LOG_EMERG, "Failed to complete a cycle within " - "%d second%s (%d.%06d) - REBOOTING\n", - (int)maxtime.tv_sec, - maxtime.tv_sec==1?"":"s", - (int)diff.tv_sec, - (int)diff.tv_usec); - if (!(ctx->qc_flags & RF_DEBUG)) - reboot(RB_AUTOBOOT); - } - - /* - * If the amount we took to complete a loop is greater or less - * than our interval, we adjust by the difference each round. - * - * It's not really "realtime", but it helps! - */ - if (_cmp_tv(&diff, &interval) == 1) { - _diff_tv(&sleeptime, &diff, &interval); - } else { - clulog(LOG_WARNING, "qdisk cycle took more " - "than %d second%s to complete (%d.%06d)\n", - ctx->qc_interval, ctx->qc_interval==1?"":"s", - (int)diff.tv_sec, (int)diff.tv_usec); - memcpy(&sleeptime, &interval, sizeof(sleeptime)); - } - - /* Could hit a watchdog timer here if we wanted to */ - if (_running) - select(0, NULL, NULL, NULL, &sleeptime); - } - - return 0; -} - - -/** - Tell the other nodes we're done (safely!). - */ -int -quorum_logout(qd_ctx *ctx) -{ - /* Write out our status */ - if (qd_write_status(ctx, ctx->qc_my_id, S_NONE, - NULL, NULL, NULL) != 0) { - clulog(LOG_WARNING, - "Error writing to quorum disk during logout\n"); - } - return 0; -} - - -/** - Grab all our configuration data from CCSD - */ -int -get_config_data(char *cluster_name, qd_ctx *ctx, struct h_data *h, int maxh, - int *cfh, int debug) -{ - int ccsfd = -1, loglevel = 4; - char query[256]; - char *val; - - clulog(LOG_DEBUG, "Loading configuration information\n"); - - ccsfd = ccs_force_connect(cluster_name, 1); - if (ccsfd < 0) { - clulog(LOG_CRIT, "Connection to CCSD failed; cannot start\n"); - return -1; - } - - ctx->qc_interval = 1; - ctx->qc_tko = 10; - ctx->qc_scoremin = 0; - ctx->qc_flags = RF_REBOOT | RF_ALLOW_KILL | RF_UPTIME; - /* | RF_STOP_CMAN;*/ - if (debug) - ctx->qc_flags |= RF_DEBUG; - ctx->qc_sched = SCHED_RR; - ctx->qc_sched_prio = 1; - - /* Get log log_facility */ - snprintf(query, sizeof(query), "/cluster/quorumd/@log_facility"); - if (ccs_get(ccsfd, query, &val) == 0) { - clu_set_facility(val); - clulog(LOG_DEBUG, "Log facility: %s\n", val); - free(val); - } - - /* Get log level */ - snprintf(query, sizeof(query), "/cluster/quorumd/@log_level"); - if (ccs_get(ccsfd, query, &val) == 0) { - loglevel = atoi(val); - free(val); - if (loglevel < 0) - loglevel = 4; - - if (!debug) - clu_set_loglevel(loglevel); - } - - /* Get interval */ - snprintf(query, sizeof(query), "/cluster/quorumd/@interval"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_interval = atoi(val); - free(val); - if (ctx->qc_interval < 1) - ctx->qc_interval = 1; - } - - /* Get tko */ - snprintf(query, sizeof(query), "/cluster/quorumd/@tko"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_tko = atoi(val); - free(val); - if (ctx->qc_tko < 3) - ctx->qc_tko = 3; - } - - /* Get up-tko (transition off->online) */ - ctx->qc_tko_up = (ctx->qc_tko / 3); - snprintf(query, sizeof(query), "/cluster/quorumd/@tko_up"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_tko_up = atoi(val); - free(val); - } - if (ctx->qc_tko_up < 2) - ctx->qc_tko_up = 2; - - /* After coming online, wait this many intervals before - being allowed to bid for master. */ - ctx->qc_upgrade_wait = 2; /* (ctx->qc_tko / 3); */ - snprintf(query, sizeof(query), "/cluster/quorumd/@upgrade_wait"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_upgrade_wait = atoi(val); - free(val); - } - if (ctx->qc_upgrade_wait < 1) - ctx->qc_upgrade_wait = 1; - - /* wait this many intervals after bidding for master before - becoming Caesar */ - ctx->qc_master_wait = (ctx->qc_tko / 2); - snprintf(query, sizeof(query), "/cluster/quorumd/@master_wait"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_master_wait = atoi(val); - free(val); - } - if (ctx->qc_master_wait <= ctx->qc_tko_up) - ctx->qc_master_wait = ctx->qc_tko_up + 1; - - /* Get votes */ - - /* check if votes is set in cluster.conf */ - snprintf(query, sizeof(query), "/cluster/quorumd/@votes"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_votes = atoi(val); - free(val); - if (ctx->qc_votes < 0) - ctx->qc_votes = 0; - } else { /* if votes is not set, default to node_num - 1 */ - int nodes = 0, error; - for (;;) { - error = ccs_get_list(ccsfd, "/cluster/clusternodes/child::*", &val); - if (error || !val) - break; - - nodes++; - } - nodes--; - if (nodes < 0) - nodes = 0; - - ctx->qc_votes = nodes; - } - - /* Get device */ - snprintf(query, sizeof(query), "/cluster/quorumd/@device"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_device = val; - } - - /* Get label (overrides device) */ - snprintf(query, sizeof(query), "/cluster/quorumd/@label"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_label = val; - } - - /* Get status file */ - snprintf(query, sizeof(query), "/cluster/quorumd/@status_file"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_status_file = val; - } - - /* Get min score */ - snprintf(query, sizeof(query), "/cluster/quorumd/@min_score"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_scoremin = atoi(val); - free(val); - if (ctx->qc_scoremin < 0) - ctx->qc_scoremin = 0; - } - - /* Get scheduling queue */ - snprintf(query, sizeof(query), "/cluster/quorumd/@scheduler"); - if (ccs_get(ccsfd, query, &val) == 0) { - switch(val[0]) { - case 'r': - case 'R': - ctx->qc_sched = SCHED_RR; - break; - case 'f': - case 'F': - ctx->qc_sched = SCHED_FIFO; - break; - case 'o': - case 'O': - ctx->qc_sched = SCHED_OTHER; - break; - default: - clulog(LOG_WARNING, "Invalid scheduling queue '%s'\n", - val); - break; - } - free(val); - } - - /* Get priority */ - snprintf(query, sizeof(query), "/cluster/quorumd/@priority"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_sched_prio = atoi(val); - free(val); - } - - /* Get reboot flag for when we transition -> offline */ - /* default = on, so, 0 to turn off */ - snprintf(query, sizeof(query), "/cluster/quorumd/@reboot"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (!atoi(val)) - ctx->qc_flags &= ~RF_REBOOT; - free(val); - } - - /* Get cman_label */ - snprintf(query, sizeof(query), "/cluster/quorumd/@cman_label"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (strlen(val) > 0) { - ctx->qc_flags |= RF_CMAN_LABEL; - ctx->qc_cman_label = val; - } - } - - /* - * Get flag to see if we're supposed to kill cman if qdisk is not - * available. - */ - /* default = off, so, 1 to turn on */ - snprintf(query, sizeof(query), "/cluster/quorumd/@stop_cman"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (!atoi(val)) - ctx->qc_flags &= ~RF_STOP_CMAN; - else - ctx->qc_flags |= RF_STOP_CMAN; - free(val); - } - - /* default = off, so, 1 to turn on */ - snprintf(query, sizeof(query), "/cluster/quorumd/@io_timeout"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (!atoi(val)) - ctx->qc_flags &= ~RF_IOTIMEOUT; - else - ctx->qc_flags |= RF_IOTIMEOUT; - free(val); - } - - /* - * Get flag to see if we're supposed to reboot if we can't complete - * a pass in failure time - */ - /* default = off, so, 1 to turn on */ - snprintf(query, sizeof(query), "/cluster/quorumd/@paranoid"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (!atoi(val)) - ctx->qc_flags &= ~RF_PARANOID; - else - ctx->qc_flags |= RF_PARANOID; - free(val); - } - - - /* - * Get flag to see if we're supposed to reboot if we can't complete - * a pass in failure time - */ - /* default = off, so, 1 to turn on */ - snprintf(query, sizeof(query), "/cluster/quorumd/@allow_kill"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (!atoi(val)) - ctx->qc_flags &= ~RF_ALLOW_KILL; - else - ctx->qc_flags |= RF_ALLOW_KILL; - free(val); - } - - /* - * Get flag to see if we're supposed to use /proc/uptime instead of - * gettimeofday(2) - */ - /* default = off, so, 1 to turn on */ - snprintf(query, sizeof(query), "/cluster/quorumd/@use_uptime"); - if (ccs_get(ccsfd, query, &val) == 0) { - if (!atoi(val)) - ctx->qc_flags &= ~RF_UPTIME; - else - ctx->qc_flags |= RF_UPTIME; - free(val); - } - - *cfh = configure_heuristics(ccsfd, h, maxh); - - clulog(LOG_DEBUG, - "Quorum Daemon: %d heuristics, %d interval, %d tko, %d votes," - " flags=%08x\n", - *cfh, ctx->qc_interval, ctx->qc_tko, ctx->qc_votes, ctx->qc_flags); - - ccs_disconnect(ccsfd); - - return 0; -} - - -void -check_stop_cman(qd_ctx *ctx) -{ - if (!(ctx->qc_flags & RF_STOP_CMAN)) - return; - - clulog(LOG_WARNING, "Telling CMAN to leave the cluster; qdisk is not" - " available\n"); -#if (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2) - if (cman_shutdown(ctx->qc_ch, 0) < 0) { -#else - int x = 0; - if (ioctl(cman_get_fd(ctx->qc_ch), SIOCCLUSTER_LEAVE_CLUSTER, &x) < 0) { -#endif - clulog(LOG_CRIT, "Could not leave the cluster - rebooting\n"); - sleep(5); - if (ctx->qc_flags & RF_DEBUG) - return; - reboot(RB_AUTOBOOT); - } -} - - -int -main(int argc, char **argv) -{ - cman_node_t me; - int cfh, rv, forked = 0, nfd = -1; - qd_ctx ctx; - cman_handle_t ch; - node_info_t ni[MAX_NODES_DISK]; - struct h_data h[10]; - char debug = 0, foreground = 0; - char device[128]; - pid_t pid; - quorum_header_t qh; - - if (check_process_running(argv[0], &pid) && pid !=getpid()) { - printf("QDisk services already running\n"); - return 0; - } - - while ((rv = getopt(argc, argv, "fdQ")) != EOF) { - switch (rv) { - case 'd': - debug = 1; - break; - case 'f': - foreground = 1; - clu_log_console(1); - break; - case 'Q': - /* Make qdisk very quiet */ - nfd = open("/dev/null", O_RDWR); - close(0); - close(1); - close(2); - dup2(nfd, 0); - dup2(nfd, 1); - dup2(nfd, 2); - close(nfd); - break; - default: - break; - } - } - -#if (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2) - ch = cman_admin_init(NULL); -#else - ch = cman_init(NULL); -#endif - if (!ch) { - if (!foreground && !forked) { - daemon_init(argv[0]); - forked = 1; - } - - clulog(LOG_INFO, "Waiting for CMAN to start\n"); - - do { - sleep(5); -#if (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2) - ch = cman_admin_init(NULL); -#else - ch = cman_init(NULL); -#endif - } while (!ch); - } - - memset(&me, 0, sizeof(me)); - while (cman_get_node(ch, CMAN_NODEID_US, &me) < 0) { - if (!foreground && !forked) { - daemon_init(argv[0]); - forked = 1; - } - sleep(5); - } - - qd_init(&ctx, ch, me.cn_nodeid); - - signal(SIGINT, int_handler); - signal(SIGTERM, int_handler); - - if (debug) { - clu_set_loglevel(LOG_DEBUG); - ctx.qc_flags |= RF_DEBUG; - } - - if (get_config_data(NULL, &ctx, h, 10, &cfh, debug) < 0) { - clulog_and_print(LOG_CRIT, "Configuration failed\n"); - check_stop_cman(&ctx); - return -1; - } - - if (ctx.qc_label) { - if (find_partitions("/proc/partitions", - ctx.qc_label, device, - sizeof(device), 0) != 0) { - clulog_and_print(LOG_CRIT, "Unable to match label" - " '%s' to any device\n", - ctx.qc_label); - check_stop_cman(&ctx); - return -1; - } - - if (ctx.qc_device) - free(ctx.qc_device); - - ctx.qc_device = strdup(device); - - clulog(LOG_INFO, "Quorum Partition: %s Label: %s\n", - ctx.qc_device, ctx.qc_label); - } else if (ctx.qc_device) { - if (check_device(ctx.qc_device, NULL, &rv, &qh, 0) != 0) { - clulog(LOG_CRIT, - "Specified partition %s does not have a " - "qdisk label\n", ctx.qc_device); - check_stop_cman(&ctx); - return -1; - } - - if (qh.qh_version == VERSION_MAGIC_V2 && - qh.qh_blksz != rv) { - clulog(LOG_CRIT, - "Specified device %s does match kernel's " - "reported sector size (%d != %d)\n", - ctx.qc_device, - ctx.qc_disk.d_blksz, rv); - check_stop_cman(&ctx); - return -1; - } - } - - if (!foreground && !forked) { - daemon_init(argv[0]); - } - - set_priority(ctx.qc_sched, ctx.qc_sched_prio); - - if (quorum_init(&ctx, ni, MAX_NODES_DISK, h, cfh) < 0) { - clulog_and_print(LOG_CRIT, "Initialization failed\n"); - check_stop_cman(&ctx); - return -1; - } - - if (!_running) - return 0; - - cman_register_quorum_device(ctx.qc_ch, - (ctx.qc_flags&RF_CMAN_LABEL)? - ctx.qc_cman_label: - ctx.qc_device, - ctx.qc_votes); - /* - XXX this always returns -1 / EBUSY even when it works?!!! - - if ((rv = cman_register_quorum_device(ctx.qc_ch, ctx.qc_device, - ctx.qc_votes)) < 0) { - clulog_and_print(LOG_CRIT, - "Could not register %s with CMAN; " - "return = %d; error = %s\n", - ctx.qc_device, rv, strerror(errno)); - return -1; - } - */ - io_nanny_start(ctx.qc_tko * ctx.qc_interval); - - if (quorum_loop(&ctx, ni, MAX_NODES_DISK) == 0) - cman_unregister_quorum_device(ctx.qc_ch); - - io_nanny_stop(); - - quorum_logout(&ctx); - qd_destroy(&ctx); - - return 0; -} - diff --git a/cman/qdisk/mkqdisk.c b/cman/qdisk/mkqdisk.c deleted file mode 100644 index 057193a..0000000 --- a/cman/qdisk/mkqdisk.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Quorum disk utility - */ -#include <stdio.h> -#include <stdlib.h> -#include <disk.h> -#include <errno.h> -#include <sys/types.h> -#include <platform.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - - -int -main(int argc, char **argv) -{ - char device[128]; - char *newdev = NULL, *newlabel = NULL; - int rv; - - printf("mkqdisk v0.5.2\n"); - - while ((rv = getopt(argc, argv, "Lf:c:l:h")) != EOF) { - switch (rv) { - case 'L': - /* List */ - close(2); - return find_partitions("/proc/partitions", - NULL, NULL, 0, 1); - break; - case 'f': - close(2); - return find_partitions("/proc/partitions", - optarg, device, - sizeof(device), 1); - case 'c': - newdev = optarg; - break; - case 'l': - newlabel = optarg; - break; - case 'h': - printf("usage: mkqdisk -L | -f <label> | -c " - "<device> -l <label>\n"); - return 0; - default: - break; - } - } - - if (!newdev && !newlabel) { - printf("usage: mkqdisk -L | -f <label> | -c " - "<device> -l <label>\n"); - return 1; - } - - if (!newdev || !newlabel) { - printf("Both a device and a label are required\n"); - return 1; - } - - printf("Writing new quorum disk label '%s' to %s.\n", - newlabel, newdev); - printf("WARNING: About to destroy all data on %s; proceed [N/y] ? ", - newdev); - if (getc(stdin) != 'y') { - printf("Good thinking.\n"); - return 0; - } - - return qdisk_init(newdev, newlabel); -} diff --git a/cman/qdisk/platform.h b/cman/qdisk/platform.h deleted file mode 100644 index e757a22..0000000 --- a/cman/qdisk/platform.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - The Red Hat Cluster Manager API Library is free software; you can - redistribute it and/or modify it under the terms of the GNU Lesser - General Public License as published by the Free Software Foundation; - either version 2.1 of the License, or (at your option) any later - version. - - The Red Hat Cluster Manager API Library is distributed in the hope - that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Defines for byte-swapping - */ -#ifndef __PLATFORM_H -#define __PLATFORM_H - -#include <endian.h> -#include <sys/param.h> -#include <byteswap.h> -#include <bits/wordsize.h> - -/* No swapping on little-endian machines */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define le_swap16(x) (x) -#define le_swap32(x) (x) -#define le_swap64(x) (x) -#else -#define le_swap16(x) bswap_16(x) -#define le_swap32(x) bswap_32(x) -#define le_swap64(x) bswap_64(x) -#endif - -/* No swapping on big-endian machines */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define be_swap16(x) bswap_16(x) -#define be_swap32(x) bswap_32(x) -#define be_swap64(x) bswap_64(x) -#else -#define be_swap16(x) (x) -#define be_swap32(x) (x) -#define be_swap64(x) (x) -#endif - - -#define swab16(x) x=be_swap16(x) -#define swab32(x) x=be_swap32(x) -#define swab64(x) x=be_swap64(x) - - -#endif /* __PLATFORM_H */ diff --git a/cman/qdisk/proc.c b/cman/qdisk/proc.c deleted file mode 100644 index 8868466..0000000 --- a/cman/qdisk/proc.c +++ /dev/null @@ -1,156 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Quorum disk /proc/partition scanning functions - */ -#include <stdio.h> -#include <stdlib.h> -#include <disk.h> -#include <errno.h> -#include <sys/types.h> -#include <platform.h> -#include <stdlib.h> -#include <string.h> - - -int -check_device(char *device, char *label, int *ssz, quorum_header_t *qh, - int flags) -{ - int ret = -1; - quorum_header_t qh_local; - target_info_t disk; - - if (!qh) - qh = &qh_local; - - ret = qdisk_validate(device); - if (ret < 0) { - perror("qdisk_verify"); - return -1; - } - - ret = qdisk_open(device, &disk); - if (ret < 0) { - perror("qdisk_open"); - return -1; - } - - if (ssz) - *ssz = disk.d_blksz; - - ret = -1; - if (qdisk_read(&disk, OFFSET_HEADER, qh, sizeof(*qh)) == sizeof(*qh)) { - swab_quorum_header_t(qh); - if (qh->qh_magic == HEADER_MAGIC_NUMBER) { - if (!label || !strcmp(qh->qh_cluster, label)) { - ret = 0; - } - } - } - - /* only flag now is 'strict device check'; i.e., - "block size recorded must match kernel's reported size" */ - if (flags && qh->qh_version == VERSION_MAGIC_V2 && - disk.d_blksz != qh->qh_blksz) { - ret = -1; - } - - qdisk_close(&disk); - - return ret; -} - - -int -find_partitions(const char *partfile, const char *label, - char *devname, size_t devlen, int print) -{ - char line[4096]; - FILE *fp; - int minor, major; - unsigned long long blkcnt; - char device[128]; - char realdev[256]; - quorum_header_t qh; - int ssz; - - fp = fopen(partfile, "r"); - if (!fp) - return -1; - - while (fgets(line, sizeof(line), fp) != NULL) { - if (strlen(line) > 128 + (22) /* 5 + 5 + 11 + 1 */) { - /*printf("Line too long!\n");*/ - continue; - } - - /* This line is taken from 2.6.15.4's proc line */ - sscanf(line, "%4d %4d %10llu %s", &major, &minor, - &blkcnt, device); - - if (strlen(device)) { - snprintf(realdev, sizeof(realdev), - "/dev/%s", device); - - /* If we're not "just printing", then - then reject devices which don't match - the recorded sector size */ - if (check_device(realdev, (char *)label, &ssz, - &qh, !print) != 0) - continue; - - if (print) { - printf("%s:\n", realdev); - printf("\tMagic: %08x\n", qh.qh_magic); - printf("\tLabel: %s\n", qh.qh_cluster); - printf("\tCreated: %s", - ctime((time_t *)&qh.qh_timestamp)); - printf("\tHost: %s\n", qh.qh_updatehost); - printf("\tKernel Sector Size: %d\n", ssz); - if (qh.qh_version == VERSION_MAGIC_V2) { - printf("\tRecorded Sector Size: %d\n\n", (int)qh.qh_blksz); - if (qh.qh_blksz != ssz) { - printf("WARNING: Sector size mismatch: Header: %d Kernel: %d\n", - (int)qh.qh_blksz, ssz); - } - } else - printf("\n"); - } - - if (devname && devlen) { - /* Got it */ - strncpy(devname, realdev, devlen); - fclose(fp); - return 0; - } - } - } - - fclose(fp); - - if (print) - /* No errors if we're just printing stuff */ - return 0; - - errno = ENOENT; - return -1; -} diff --git a/cman/qdisk/score.c b/cman/qdisk/score.c deleted file mode 100644 index 3f508a2..0000000 --- a/cman/qdisk/score.c +++ /dev/null @@ -1,490 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Quorum daemon scoring functions + thread. - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <pthread.h> -#include <string.h> -#include <ccs.h> -#include <clulog.h> -#include <sched.h> -#include <sys/mman.h> -#include "disk.h" -#include "score.h" - -static pthread_mutex_t sc_lock = PTHREAD_MUTEX_INITIALIZER; -static int _score = 0, _maxscore = 0, _score_thread_running = 0; -static pthread_t score_thread = (pthread_t)0; -void set_priority(int, int); - -struct h_arg { - struct h_data *h; - int sched_queue; - int sched_prio; - int count; -}; - - -/* - XXX Messy, but works for now... - */ -void -nullify(void) -{ - int fd[3]; - - close(0); - close(1); - close(2); - - fd[0] = open("/dev/null", O_RDONLY); - if (fd[0] != 0) - dup2(fd[0], 0); - fd[1] = open("/dev/null", O_WRONLY); - if (fd[1] != 1) - dup2(fd[1], 1); - fd[2] = open("/dev/null", O_WRONLY); - if (fd[2] != 2) - dup2(fd[2], 2); -} - - -/** - Set all signal handlers to default for exec of a script. - ONLY do this after a fork(). - */ -void -restore_signals(void) -{ - sigset_t set; - int x; - - for (x = 1; x < _NSIG; x++) - signal(x, SIG_DFL); - - sigfillset(&set); - sigprocmask(SIG_UNBLOCK, &set, NULL); -} - - -/** - Spin off a user-defined heuristic - */ -static int -fork_heuristic(struct h_data *h) -{ - int pid; - char *argv[4]; - time_t now; - - if (h->childpid) { - errno = EINPROGRESS; - return -1; - } - - now = time(NULL); - if (now < h->nextrun) - return 0; - - h->nextrun = now + h->interval; - - pid = fork(); - if (pid < 0) - return -1; - - if (pid) { - h->childpid = pid; - return 0; - } - - /* - * always use SCHED_OTHER for the child processes - * nice -1 is fine; but we don't know what the child process - * might do, so leaving it (potentially) in SCHED_RR or SCHED_FIFO - * is out of the question - * - * XXX if you set SCHED_OTHER in the conf file and nice 20, the below - * will make the heuristics a higher prio than qdiskd. This should be - * fine in practice, because running qdiskd at nice 20 will cause all - * sorts of problems on a busy system. - */ - set_priority(SCHED_OTHER, -1); - munlockall(); - restore_signals(); - - argv[0] = "/bin/sh"; - argv[1] = "-c"; - argv[2] = h->program; - argv[3] = NULL; - - nullify(); - - execv("/bin/sh", argv); - - printf("Execv failed\n"); - return 0; -} - - -/** - Total our current score - */ -static void -total_score(struct h_data *h, int max, int *score, int *maxscore) -{ - int x; - - *score = 0; - *maxscore = 0; - - //printf("max = %d\n", max); - /* Allow operation w/o any heuristics */ - if (!max) { - *score = *maxscore = 1; - return; - } - - for (x = 0; x < max; x++) { - *maxscore += h[x].score; - if (h[x].available) - *score += h[x].score; - } -} - - -/** - Check for response from a user-defined heuristic / script - */ -static int -check_heuristic(struct h_data *h, int block) -{ - int ret; - int status; - - if (h->childpid == 0) - /* No child to check */ - return 0; - - ret = waitpid(h->childpid, &status, block?0:WNOHANG); - if (!block && ret == 0) - /* No children exited */ - return 0; - - h->childpid = 0; - if (ret < 0 && errno == ECHILD) - /* wrong child? */ - goto miss; - if (!WIFEXITED(status)) { - ret = 0; - goto miss; - } - if (WEXITSTATUS(status) != 0) { - ret = 0; - goto miss; - } - - /* Returned 0 and was not killed */ - if (!h->available) { - h->available = 1; - clulog(LOG_INFO, "Heuristic: '%s' UP\n", h->program); - } - h->misses = 0; - return 0; - -miss: - if (h->available) { - h->misses++; - if (h->misses >= h->tko) { - clulog(LOG_INFO, - "Heuristic: '%s' DOWN (%d/%d)\n", - h->program, h->misses, h->tko); - h->available = 0; - } else { - clulog(LOG_DEBUG, - "Heuristic: '%s' missed (%d/%d)\n", - h->program, h->misses, h->tko); - } - } - - return ret; -} - - -/** - Kick off all available heuristics - */ -static int -fork_heuristics(struct h_data *h, int max) -{ - int x; - - for (x = 0; x < max; x++) - fork_heuristic(&h[x]); - return 0; -} - - -/** - Check all available heuristics - */ -static int -check_heuristics(struct h_data *h, int max, int block) -{ - int x; - - for (x = 0; x < max; x++) - check_heuristic(&h[x], block); - return 0; -} - - -/** - Read configuration data from CCS into the array provided - */ -int -configure_heuristics(int ccsfd, struct h_data *h, int max) -{ - int x = 0; - char *val; - char query[128]; - - if (!h || !max) - return -1; - - do { - h[x].program = NULL; - h[x].available = 0; - h[x].misses = 0; - h[x].interval = 2; - h[x].tko = 1; - h[x].score = 1; - h[x].childpid = 0; - h[x].nextrun = 0; - - /* Get program */ - snprintf(query, sizeof(query), - "/cluster/quorumd/heuristic[%d]/@program", x+1); - if (ccs_get(ccsfd, query, &val) != 0) - /* No more */ - break; - h[x].program = val; - - /* Get score */ - snprintf(query, sizeof(query), - "/cluster/quorumd/heuristic[%d]/@score", x+1); - if (ccs_get(ccsfd, query, &val) == 0) { - h[x].score = atoi(val); - free(val); - if (h[x].score <= 0) - h[x].score = 1; - } - - /* Get query interval */ - snprintf(query, sizeof(query), - "/cluster/quorumd/heuristic[%d]/@interval", x+1); - if (ccs_get(ccsfd, query, &val) == 0) { - h[x].interval = atoi(val); - free(val); - if (h[x].interval <= 0) - h[x].interval = 2; - } - - /* Get tko for this heuristic */ - snprintf(query, sizeof(query), - "/cluster/quorumd/heuristic[%d]/@tko", x+1); - if (ccs_get(ccsfd, query, &val) == 0) { - h[x].tko= atoi(val); - free(val); - if (h[x].tko <= 0) - h[x].tko = 1; - } - - clulog(LOG_DEBUG, - "Heuristic: '%s' score=%d interval=%d tko=%d\n", - h[x].program, h[x].score, h[x].interval, h[x].tko); - - } while (++x < max); - - clulog(LOG_DEBUG, "%d heuristics loaded\n", x); - - return x; -} - - -/** - Return the current score + maxscore to the caller - */ -int -get_my_score(int *score, int *maxscore) -{ - pthread_mutex_lock(&sc_lock); - *score = _score; - *maxscore = _maxscore; - pthread_mutex_unlock(&sc_lock); - - return 0; -} - - -/** - Call this if no heuristics are set to run in master-wins mode - */ -int -fudge_scoring(void) -{ - pthread_mutex_lock(&sc_lock); - _score = _maxscore = 1; - pthread_mutex_unlock(&sc_lock); - - return 0; -} - - -/** - Loop for the scoring thread. - */ -void * -score_thread_main(void *arg) -{ - struct h_arg *args = (struct h_arg *)arg; - int score, maxscore; - - set_priority(args->sched_queue, args->sched_prio); - - while (_score_thread_running) { - fork_heuristics(args->h, args->count); - check_heuristics(args->h, args->count, 0); - total_score(args->h, args->count, &score, &maxscore); - - pthread_mutex_lock(&sc_lock); - _score = score; - _maxscore = maxscore; - pthread_mutex_unlock(&sc_lock); - - if (_score_thread_running) - sleep(1); - } - - free(args->h); - free(args); - printf("Score thread going away\n"); - return (NULL); -} - - -/** - Stop the score thread for shutdown / reconfiguration - */ -int -stop_score_thread(void) -{ - void *ret; - - if (!_score_thread_running) - return 0; - - _score_thread_running = 0; - pthread_join(score_thread, &ret); - - return 0; -} - - -/** - Start the score thread. h is copied into an argument which is - passed in as the arg parameter in the score thread, so it is safe - to pass in h if it was allocated on the stack. - */ -int -start_score_thread(qd_ctx *ctx, struct h_data *h, int count) -{ - pthread_attr_t attrs; - struct h_arg *args; - - if (!h || !count) - return -1; - - args = malloc(sizeof(struct h_arg)); - if (!args) - return -1; - - args->h = malloc(sizeof(struct h_data) * count); - if (!args->h) { - free(args); - return -1; - } - - memcpy(args->h, h, (sizeof(struct h_data) * count)); - args->count = count; - args->sched_queue = ctx->qc_sched; - args->sched_prio = ctx->qc_sched_prio; - - _score_thread_running = 1; - - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_create(&score_thread, &attrs, score_thread_main, args); - pthread_attr_destroy(&attrs); - - if (score_thread) - return 0; - _score_thread_running = 0; - return -1; -} - - -#if 0 -int -main(int argc, char **argv) -{ - struct h_data h[10]; - int max = 0, score, maxscore, ccsfd; - - ccsfd = ccs_force_connect("test", 1); - if (ccsfd < 0) - return -1; - max = configure_heuristics(ccsfd, h, 10); - ccs_disconnect(ccsfd); - - start_score_thread(h, max); - max = 0; - while (max < 10) { - get_my_score(&score,&maxscore); - printf("current %d/%d\n", score, maxscore); - sleep(1); - ++max; - } - stop_score_thread(); - - get_my_score(&score,&maxscore); - printf("final! %d/%d\n", score, maxscore); - - return 0; -} -#endif - diff --git a/cman/qdisk/score.h b/cman/qdisk/score.h deleted file mode 100644 index 95b53d6..0000000 --- a/cman/qdisk/score.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - */ -/** - @file Quorum daemon scoring functions + thread header file - */ -#ifndef _SCORE_H -#define _SCORE_H - -#include <time.h> -#include <sys/time.h> -#include <sys/types.h> - -struct h_data { - char * program; - int score; - int available; - int tko; - int interval; - int misses; - pid_t childpid; - time_t nextrun; -}; - -/* - Grab score data from CCSD - */ -int configure_heuristics(int ccsfd, struct h_data *hp, int max); - -/* - Stop the thread which runs the scoring applets. - */ -int stop_score_thread(void); - -/* - Start the thread which runs the scoring applets - */ -int start_score_thread(qd_ctx *ctx, struct h_data *h, int count); - -/* - Get our score + maxscore - */ -int get_my_score(int *score, int *maxscore); - -/* - Set score + maxscore to 1. Call if no heuristics are present - to enable master-wins mode - */ -int fudge_scoring(void); - - -#endif diff --git a/cman/scripts/cman.init b/cman/scripts/cman.init deleted file mode 100755 index ef67f23..0000000 --- a/cman/scripts/cman.init +++ /dev/null @@ -1,69 +0,0 @@ -#! /bin/sh -# -# cman This starts and stops the CMAN cluster subsystems -# -# chkconfig: 345 60 19 -# description: CMAN Cluster subsystems - -# Source function library. -. /etc/rc.d/init.d/functions - -# Get Configuration variables -[ -f /etc/sysconfig/cman ] && . /etc/sysconfig/cman - -# My stuff -CLUSTER_NAME=Patrick2 -CLDIR=/mnt/export/home/msp/pcaulfie/new/cluster -PATH=$PATH:$CLDIR/cman/cman_tool:$CLDIR/fence/fence_tool:$CLDIR/fence/fenced:$CLDIR/ccs/daemon:$CLDIR/../../LVM2/daemons/clvmd - -# Need a cluster name -if [ -z "$CLUSTER_NAME" ] -then - echo "Cluster services not started, no cluster name" - exit 1 -fi - -set -e - -case "$1" in - start) - echo -n $"Starting cluster services" - ccsd - sleep 1 - modprobe cman - modprobe dlm - modprobe lock_harness - modprobe gfs - modprobe lock_dlm - cman_tool join -c $CLUSTER_NAME - fenced - clvmd - lvm vgchange -aly & - touch /var/lock/subsys/cman - echo - ;; - - stop) - echo -n $"Stopping cluster services" - umount -a -tgfs - grep "blocked" /proc/cluster/status > /dev/null - [ $? = 1 ] && lvm vgchange -aln --ignorelockingfailure - killproc clvmd || true - killproc ccsd || true - fence_tool leave || true - sleep 3 - cman_tool leave remove - rm -f /var/lock/subsys/cman - echo - ;; - - status) - cat /proc/cluster/status - ;; - *) - echo "Usage cluster {start|stop|status}" - exit 1; - ;; -esac - -exit 0 diff --git a/cman/scripts/uninstall.pl b/cman/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/cman/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/cman/tests/Makefile b/cman/tests/Makefile deleted file mode 100644 index 3ff0b94..0000000 --- a/cman/tests/Makefile +++ /dev/null @@ -1,36 +0,0 @@ - - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk -include ${top_srcdir}/make/flags.mk - -CFLAGS+= -g -I${top_srcdir}/config - -ifneq (${KERNEL_SRC}, ) -CFLAGS += -I${KERNEL_SRC}/include/cluster -else -CFLAGS += -I/usr/include/linux/cluster -endif - -TARGET=user_service sysman sysmand client qwait msgtest - -all: ${TARGET} - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -user_service: user_service.o - $(CC) $(LDFLAGS) -o $@ $^ -lpthread - -user_service.o: user_service.c - $(CC) $(CFLAGS) -c -o $@ $< - -install: - install -d ${sbindir} - install user_service ${sbindir} - -clean: - rm -f *.o ${TARGET} - - diff --git a/cman/tests/client.c b/cman/tests/client.c deleted file mode 100644 index 25ae46b..0000000 --- a/cman/tests/client.c +++ /dev/null @@ -1,156 +0,0 @@ -/* test client */ -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - - -#include "cnxman-socket.h" - -int cluster_sock; -void get_members(void); - -void signal_handler(int sig) -{ - get_members(); - return; -} - -int main(int argc, char *argv[]) -{ - - struct sockaddr_cl saddr; - unsigned char port = 100; - char message[256]; - struct utsname ubuf; - - if (argc >= 2) - port = atoi(argv[1]); - - if (argc >= 3) - strcpy(message, argv[2]); - - printf("Cluster port number is %d\n", port); - uname(&ubuf); - sprintf(message, "Hello from %s", ubuf.nodename); - - signal(SIGUSR1, signal_handler); - - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cluster_sock == -1) - { - perror("Can't open cluster socket"); - return -1; - } - - /* Bind to our port number on the cluster. Ports < 10 are special - and will not be blocked if the cluster loses quorum */ - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = port; - - if (bind(cluster_sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_cl))) - { - perror("Can't bind cluster socket"); - return -1; - } - fcntl(cluster_sock, F_SETFL, fcntl(cluster_sock, F_GETFL, 0) | O_NONBLOCK); - - /* Get the cluster to send us SIGUSR1 if the configuration changes */ - ioctl(cluster_sock, SIOCCLUSTER_NOTIFY, SIGUSR1); - - while (1) - { - char buf[1024]; - fd_set in; - int len; - struct iovec iov; - struct msghdr msg; - struct sockaddr saddr; - struct timeval tv = {2,0}; - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = &iov; - msg.msg_name = &saddr; - msg.msg_flags = O_NONBLOCK; - msg.msg_namelen = sizeof(saddr); - iov.iov_len = sizeof(buf); - iov.iov_base = buf; - - if (write(cluster_sock, message, strlen(message)+1) < 0) - { - perror("write"); - close(cluster_sock); - exit(-1); - } - - FD_ZERO(&in); - FD_SET(cluster_sock, &in); - while (select(cluster_sock+1, &in, NULL, NULL, &tv) > 0) - { - int i; - struct sockaddr_cl *scl = (struct sockaddr_cl *)msg.msg_name; - - len = recvmsg(cluster_sock, &msg, O_NONBLOCK); - if (len < 0) - { - perror("read"); - close(cluster_sock); - exit(-1); - } - if (len == 0) - break; // EOF - - buf[len] = '\0'; - fprintf(stderr, "\nRead %d: '%s'\n", len, buf); - fprintf(stderr, "port=%d, nodeid = %d\n", scl->scl_port, scl->scl_nodeid); - for (i=0; i<14; i++) - { - fprintf(stderr, "%02x ", scl->scl_nodeid); - } - fprintf(stderr, "\n"); - } - } - fprintf(stderr, "EOF: finished\n"); -} - - -void get_members(void) -{ - struct cl_cluster_node *nodes; - int i; - int num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0); - - if (num_nodes == -1) - { - perror("get nodes"); - } - else - { - - printf("There are %d nodes: \n", num_nodes); - - nodes = malloc(num_nodes * sizeof(struct cl_cluster_node)); - if ( (num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, nodes) >= 0) ) - { - for (i=0; i<num_nodes; i++) - { - printf("%s %d\n", nodes[i].name, nodes[i].votes); - } - } - else - { - perror("get node details"); - } - } -} diff --git a/cman/tests/libtest.c b/cman/tests/libtest.c deleted file mode 100644 index 7a17b39..0000000 --- a/cman/tests/libtest.c +++ /dev/null @@ -1,96 +0,0 @@ -#include <netinet/in.h> -#include <inttypes.h> -#include "libcman.h" - -#include <stdlib.h> -#include <stdio.h> - -static void cman_callback(cman_handle_t handle, void *private, int reason, int arg) -{ - printf("callback called reason = %d, arg=%d\n", reason, arg); -} - -static void print_node(cman_node_t *node) -{ - printf(" node id %d\n", node->cn_nodeid); - printf(" node member %d\n", node->cn_member); - printf(" node name %s\n", node->cn_name); - printf(" node incarn %d\n", node->cn_incarnation); - printf("\n"); -} - -int main() -{ - cman_handle_t h; - int num; - int retnodes; - cman_node_t *nodes; - cman_version_t ver; - cman_cluster_t clinfo; - - h = cman_init(0); - if (!h) - { - perror("cman_init failed"); - exit(1); - } - - num = cman_get_node_count(h); - if (num > 0) - printf("cluster has %d nodes\n", num); - else - perror("node count"); - - printf("cman is active: %d\n", cman_is_active(h)); - printf("cman is quorate: %d\n", cman_is_quorate(h)); - printf("cman is listening: %d\n", cman_is_listening(h, CMAN_NODEID_US, 1)); /* membership! */ - cman_get_version(h, &ver); - printf("cman version %d.%d.%d (config %d)\n", - ver.cv_minor, - ver.cv_major, - ver.cv_patch, - ver.cv_config); - - if (!cman_get_cluster(h, &clinfo)) - { - printf("Cluster '%s', number %d\n", clinfo.name, clinfo.number); - } - else - perror("cluster info failed"); - - nodes = malloc(num * sizeof(cman_node_t)); - if (!nodes) - { - perror("malloc"); - exit(1); - } - - if (!cman_get_nodes(h, num, &retnodes, nodes)) - { - int i; - printf("Getting all nodes:\n"); - for (i=0; i<retnodes; i++) - print_node(&nodes[i]); - } - else - { - perror("get_nodes failed"); - } - - if (!cman_get_node(h, CMAN_NODEID_US, &nodes[0])) - { - printf("Getting our info:\n"); - print_node(&nodes[0]); - } - else - { - perror("get_node failed"); - } - - cman_start_notification(h, cman_callback); - cman_dispatch(h, CMAN_DISPATCH_BLOCKING | CMAN_DISPATCH_ALL); - - cman_finish(h); - - return 0; -} diff --git a/cman/tests/msgtest.c b/cman/tests/msgtest.c deleted file mode 100644 index 558e97e..0000000 --- a/cman/tests/msgtest.c +++ /dev/null @@ -1,175 +0,0 @@ -/* test client */ -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <netinet/in.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include "cnxman-socket.h" - - -int send_seq=1; -int recv_seq[100]; -int cluster_sock; -int sleep_ms = 10000; - -void get_members(void); - -void signal_handler(int sig) -{ - get_members(); - return; -} - -int main(int argc, char *argv[]) -{ - - struct sockaddr_cl saddr; - unsigned char port = 100; - char message[256]; - struct utsname ubuf; - - if (argc >= 2) - port = atoi(argv[1]); - - if (argc >= 3) - sleep_ms = atoi(argv[2]); - - printf("Cluster port number is %d\n", port); - uname(&ubuf); - sprintf(message, "Hello from %s", ubuf.nodename); - - signal(SIGUSR1, signal_handler); - - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cluster_sock == -1) - { - perror("Can't open cluster socket"); - return -1; - } - - /* Bind to our port number on the cluster. Ports < 10 are special - and will not be blocked if the cluster loses quorum */ - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = port; - - if (bind(cluster_sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_cl))) - { - perror("Can't bind cluster socket"); - return -1; - } - fcntl(cluster_sock, F_SETFL, fcntl(cluster_sock, F_GETFL, 0) | O_NONBLOCK); - - /* Get the cluster to send us SIGUSR1 if the configuration changes */ - ioctl(cluster_sock, SIOCCLUSTER_NOTIFY, SIGUSR1); - - while (1) - { - int buf; - fd_set in; - int len; - struct iovec iov; - struct msghdr msg; - struct sockaddr saddr; - struct timeval tv = {0,sleep_ms}; - struct timeval tv0 = {0,0}; - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = &iov; - msg.msg_name = &saddr; - msg.msg_flags = O_NONBLOCK; - msg.msg_namelen = sizeof(saddr); - iov.iov_len = sizeof(buf); - iov.iov_base = &buf; - - select(cluster_sock+1, NULL, NULL, NULL, &tv); - - send_seq++; -retry_send: - fprintf(stderr, "sending %d\n", send_seq); - if (write(cluster_sock, &send_seq, 4) < 0) - { - if (errno == EAGAIN) { - fprintf(stderr, "write sleep\n"); - sleep(1); - goto retry_send; - } - fprintf(stderr, "errno=%d\n", errno); - perror("write"); - close(cluster_sock); - exit(-1); - } - - FD_ZERO(&in); - FD_SET(cluster_sock, &in); - while (select(cluster_sock+1, &in, NULL, NULL, &tv0) > 0) - { - struct sockaddr_cl *scl = (struct sockaddr_cl *)msg.msg_name; - retry_read: - len = recvmsg(cluster_sock, &msg, O_NONBLOCK); - if (len < 0) - { - if (errno == EAGAIN) { - fprintf(stderr, "read sleep\n"); - goto retry_read; - } - perror("read"); - close(cluster_sock); - exit(-1); - } - if (len == 0) - break; // EOF - - fprintf(stderr, "port=%d, nodeid = %d, seq=%d\n", scl->scl_port, scl->scl_nodeid, buf); - if (recv_seq[scl->scl_nodeid] && recv_seq[scl->scl_nodeid] != buf-1) { - fprintf(stderr, "got %d, expected %d\n", buf, recv_seq[scl->scl_nodeid]+1); - exit(9); - } - recv_seq[scl->scl_nodeid] = buf; - } - } - fprintf(stderr, "EOF: finished\n"); - return 0; -} - - -void get_members(void) -{ - struct cl_cluster_node *nodes; - int i; - int num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0); - - if (num_nodes == -1) - { - perror("get nodes"); - } - else - { - - printf("There are %d nodes: \n", num_nodes); - - nodes = malloc(num_nodes * sizeof(struct cl_cluster_node)); - if ( (num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, nodes) >= 0) ) - { - for (i=0; i<num_nodes; i++) - { - printf("%s %d\n", nodes[i].name, nodes[i].votes); - } - } - else - { - perror("get node details"); - } - } -} diff --git a/cman/tests/qwait.c b/cman/tests/qwait.c deleted file mode 100644 index f446eef..0000000 --- a/cman/tests/qwait.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - qwait.c - - (c) 2002 Sistina Software Inc. - - Wait for the cluster to become quorate -*/ - - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> - -#include "cnxman-socket.h" - -static int cluster_sock; - -static void signal_handler(int sig) -{ - - return; -} - - -int main(int argc, char *argv[]) -{ - struct sigaction sa; - sigset_t ss; - - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cluster_sock == -1) - { - perror("Can't open cluster socket"); - return -1; - } - sa.sa_handler = signal_handler; - sa.sa_mask = ss; - sa.sa_flags = 0; - sigaction(SIGUSR1, &sa, NULL); - - if (ioctl(cluster_sock, SIOCCLUSTER_NOTIFY, SIGUSR1) == -1) - { - perror("Can't set up cluster notification"); - close(cluster_sock); - return -1; - } - - while (!ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0)) - { - pause(); - } - - close(cluster_sock); - - return 0; -} diff --git a/cman/tests/sysman.c b/cman/tests/sysman.c deleted file mode 100644 index 803308e..0000000 --- a/cman/tests/sysman.c +++ /dev/null @@ -1,73 +0,0 @@ -/* "sysman" client */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> - -#define LOCAL_SOCKNAME "/var/run/sysman" -static int open_local_sock(void); - -int main(int argc, char *argv[]) -{ - char message[2048]; - int local_sock; - int len; - - if (argc < 2) - { - printf("usage: sysman "command"\n"); - return 0; - } - - local_sock = open_local_sock(); - if (local_sock < 0) - exit(2); - - /* Send the command */ - write(local_sock, argv[1], strlen(argv[1])+1); - - /* Print the replies */ - while ( (len = read(local_sock, message, sizeof(message))) ) - { - message[len] = '\0'; - printf("%s", message); - } - printf("\n"); - return 0; -} - - -static int open_local_sock(void) -{ - int local_socket; - struct sockaddr_un sockaddr; - - // Open local socket - local_socket = socket(PF_UNIX, SOCK_STREAM, 0); - if (local_socket < 0) - { - perror("Can't create local socket"); - return -1; - } - - strcpy(sockaddr.sun_path, LOCAL_SOCKNAME); - sockaddr.sun_family = AF_UNIX; - if (connect(local_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) - { - fprintf(stderr, "sysmand is not running\n"); - close(local_socket); - return -1; - } - return local_socket; -} - diff --git a/cman/tests/sysmand.c b/cman/tests/sysmand.c deleted file mode 100644 index 6b20834..0000000 --- a/cman/tests/sysmand.c +++ /dev/null @@ -1,542 +0,0 @@ -/* "sysman" server - - Listens on a cluster port and executes commands. - - This is just a demonstration piece of code, not for production use - - ************************************* - *** IT IS A MASSIVE SECURITY HOLE *** - ************************************* - - Any command passed to it will be run as root! - -*/ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <sys/errno.h> -#include <syslog.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <time.h> -#include <unistd.h> -#include <fcntl.h> - -#include "cnxman-socket.h" -#define LOCAL_SOCKNAME "/var/run/sysman" - -static struct cl_cluster_node *nodes = NULL; -static int num_nodes; -static int cluster_sock; - -/* Header for all commands sent to other sysmand servers */ -struct sysman_header -{ - int fd; /* local FD to return output to. in network byte order */ - int ret; /* Return code of command */ - char cmd; -#define SYSMAN_CMD_REQUEST 1 -#define SYSMAN_CMD_REPLY 2 -}; - -/* One of these for each fd we are listening on - some fields are specific to particular types. -*/ -struct read_fd -{ - int fd; - enum {CLUSTER_SOCK, LOCAL_RENDEZVOUS, LOCAL_SOCK} type; - int nodes_done; - time_t start_time; - struct read_fd *next; -}; -/* Head of the fd list. Also contains - the cluster_socket details */ -static struct read_fd read_fd_head; - - -static void get_members(void); -static int open_local_sock(void); -static int exec_command(char *cmd, char *reply, int *len); -static int name_from_nodeid(int nodeid, char *name); -static void remove_sock(struct read_fd *deadfd); -static struct read_fd *find_by_fd(int fd); -static int nodes_listening(int); - -static void signal_handler(int sig) -{ - get_members(); - return; -} - -int main(int argc, char *argv[]) -{ - struct sockaddr_cl saddr; - unsigned char port = CLUSTER_PORT_SYSMAN; - int local_sock; - struct read_fd *newfd; - struct utsname nodeinfo; - int expected_responses; - - cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cluster_sock == -1) - { - perror("Can't open cluster socket"); - return -1; - } - - uname(&nodeinfo); - - /* Just a sensible default, we work out just how many - responses we expectect properly later */ - expected_responses = num_nodes; - - /* Bind to our port number on the cluster. - Writes to this will block if the cluster loses quorum */ - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = port; - - if (bind(cluster_sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_cl))) - { - perror("Can't bind cluster socket"); - return -1; - } - fcntl(cluster_sock, F_SETFL, fcntl(cluster_sock, F_GETFL, 0) | O_NONBLOCK); - - /* Get the cluster to send us SIGUSR1 if the configuration changes */ - ioctl(cluster_sock, SIOCCLUSTER_NOTIFY, SIGUSR1); - read_fd_head.fd = cluster_sock; - read_fd_head.type = CLUSTER_SOCK; - - /* Preload cluster members list */ - get_members(); - signal(SIGUSR1, signal_handler); - - /* Open the Unix socket we listen for commands on */ - local_sock = open_local_sock(); - if (local_sock < 0) - exit(2); - - newfd = malloc(sizeof(struct read_fd)); - if (!newfd) - exit(2); - - newfd->fd = local_sock; - newfd->type = LOCAL_RENDEZVOUS; - newfd->next = NULL; - read_fd_head.next = newfd; - - while (1) - { - char buf[MAX_CLUSTER_MESSAGE]; - fd_set in; - int len; - struct iovec iov[2]; - struct read_fd *thisfd; - struct msghdr msg; - struct sockaddr_cl saddr; - struct timeval tv = {10,0}; - - FD_ZERO(&in); - for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next) - { - FD_SET(thisfd->fd, &in); - } - - if (select(FD_SETSIZE, &in, NULL, NULL, &tv) > 0) - { - struct read_fd *lastfd = NULL; - struct read_fd *replyfd = NULL; - char reply[MAX_CLUSTER_MESSAGE]; - char title[MAX_CLUSTER_MESSAGE]; - char nodename[MAX_CLUSTER_MEMBER_NAME_LEN]; - struct sysman_header header; - struct sysman_header *inheader; - int status; - int title_len; - - for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next) - { - if (FD_ISSET(thisfd->fd, &in)) - { - switch(thisfd->type) - { - /* Request or response from another cluster node */ - case CLUSTER_SOCK: - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = &saddr; - msg.msg_flags = O_NONBLOCK; - msg.msg_namelen = sizeof(saddr); - iov[0].iov_len = sizeof(buf); - iov[0].iov_base = buf; - - len = recvmsg(cluster_sock, &msg, O_NONBLOCK); - if (len < 0 && (errno == EAGAIN || errno == EINTR)) continue; - if (len < 0) - { - perror("read"); - close(cluster_sock); - exit(-1); - } - if (len == 0) - goto closedown; // EOF - we have left the cluster - - /* Make sure we get more than just a header(!) */ - if (len == sizeof(struct sysman_header)) - { - len += recvmsg(cluster_sock, &msg, O_NONBLOCK); - } - inheader = (struct sysman_header *)iov[0].iov_base; - - switch (inheader->cmd) - { - case SYSMAN_CMD_REQUEST: - /* Execute command and capture stdout/stderr into 'reply'*/ - status = exec_command(iov[0].iov_base+sizeof(struct sysman_header), reply, &len); - - /* Send reply */ - header.fd = inheader->fd; /* Already in the right format */ - header.cmd = SYSMAN_CMD_REPLY; - header.ret = htonl(status); - - iov[0].iov_len = sizeof(struct sysman_header); - iov[0].iov_base = &header; - iov[1].iov_len = len; - iov[1].iov_base = reply; - msg.msg_iovlen = 2; - if (sendmsg(cluster_sock, &msg, 0) < 0) - { - perror("write"); - close(cluster_sock); - exit(-1); - } - break; - - case SYSMAN_CMD_REPLY: - name_from_nodeid(saddr.scl_nodeid, nodename); - title_len = sprintf(title, "\nReply from %s:", nodename); - if (inheader->ret != 0) - title_len += sprintf(title+title_len, " (ret=%d)", ntohl(inheader->ret)); - strcat(title, "\n"); title_len++; - write(ntohl(inheader->fd), title, title_len); - write(ntohl(inheader->fd), iov[0].iov_base+sizeof(struct sysman_header), - len - sizeof(struct sysman_header)); - - replyfd = find_by_fd(ntohl(inheader->fd)); - if (replyfd) - { - /* If we've done all nodes then close the client down */ - if (++replyfd->nodes_done == expected_responses) - { - close (replyfd->fd); - remove_sock(replyfd); - } - } - break; - - default: - name_from_nodeid(saddr.scl_nodeid, nodename); - syslog(LOG_ERR, "Unknown sysman command received from %s: %d\n", - nodename, inheader->cmd); - break; - } - break; - - /* Someone connected to our local socket */ - case LOCAL_RENDEZVOUS: - { - struct sockaddr_un socka; - struct read_fd *newfd; - socklen_t sl = sizeof(socka); - int client_fd = accept(local_sock, (struct sockaddr *)&socka, &sl); - - if (client_fd >= 0) - { - newfd = malloc(sizeof(struct read_fd)); - if (!newfd) - { - close(client_fd); - break; - } - newfd->fd = client_fd; - newfd->type = LOCAL_SOCK; - newfd->next = thisfd->next; - newfd->nodes_done = 0; - newfd->start_time = time(NULL); - thisfd->next = newfd; - } - } - break; - - /* Data on a connected socket */ - case LOCAL_SOCK: - { - int len; - char buffer[1024]; - len = read(thisfd->fd, buffer, sizeof(buffer)); - - /* EOF on socket */ - if (len <= 0) - { - struct read_fd *free_fd; - - close(thisfd->fd); - /* Remove it from the list safely */ - lastfd->next = thisfd->next; - free_fd = thisfd; - thisfd = lastfd; - free(free_fd); - } - else - { - struct sysman_header header; - - expected_responses = nodes_listening(thisfd->fd); - - header.fd = htonl(thisfd->fd); - header.cmd = SYSMAN_CMD_REQUEST; - - iov[0].iov_len = sizeof(struct sysman_header); - iov[0].iov_base = &header; - iov[1].iov_len = len; - iov[1].iov_base = buffer; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 2; - msg.msg_iov = iov; - msg.msg_name = NULL; - msg.msg_flags = O_NONBLOCK; - msg.msg_namelen = 0; - - /* Send command to cluster */ - if (sendmsg(cluster_sock, &msg, 0) < 0) - { - perror("write"); - close(cluster_sock); - exit(-1); - } - - /* Also do local execution on this node */ - status = exec_command(buffer, reply, &len); - title_len = sprintf(title, "Reply from %s:", nodeinfo.nodename); - if (status != 0) - title_len += sprintf(title+title_len, " (ret=%d)", status); - strcat(title, "\n"); title_len++; - write(thisfd->fd, title, title_len); - write(thisfd->fd, reply, len); - - /* If we've done all nodes then close the client down */ - if (++thisfd->nodes_done == expected_responses) - { - close (thisfd->fd); - remove_sock(thisfd); - } - } - } - break; - - } /* switch */ - - } - lastfd = thisfd; - } - } - /* Check for timed-out connections */ - for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next) - { - if (thisfd->type == LOCAL_SOCK && (thisfd->start_time <= time(NULL)-10)) - { - write(thisfd->fd,"Timed-out\n", 10); - close(thisfd->fd); - remove_sock(thisfd); - - /* Refresh members list in case a node has gone down - or a remote sysmand has crashed */ - get_members(); - } - } - } - closedown: - close(cluster_sock); - close(local_sock); - - return 0; -} - -/* Get a list of members */ -static void get_members() -{ - struct cl_cluster_nodelist nodelist; - - num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0); - if (num_nodes == -1) - { - perror("get nodes"); - } - else - { - if (nodes) free(nodes); - - nodes = malloc(num_nodes * sizeof(struct cl_cluster_node)); - - nodelist.nodes = nodes; - nodelist.max_members = num_nodes; - num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, &nodelist); - if (num_nodes < 0) - perror("Error getting node list"); - } -} - -/* Convert a nodeid to a node name */ -static int name_from_nodeid(int nodeid, char *name) -{ - int i; - - for (i=0; i<num_nodes; i++) - { - if (nodeid == nodes[i].node_id) - { - strcpy(name, nodes[i].name); - return 0; - } - } - /* Who?? */ - strcpy(name, "Unknown"); - return -1; -} - -/* Check which nodes are listening on the SYSMAN port */ -static int nodes_listening(int errfd) -{ - int i; - int num_listening = 0; - - for (i=0; i<num_nodes; i++) - { - struct cl_listen_request rq; - int listening; - - rq.port=CLUSTER_PORT_SYSMAN; - rq.nodeid = nodes[i].node_id; - - listening = ioctl(cluster_sock, SIOCCLUSTER_ISLISTENING, &rq); - - if (listening) - { - num_listening++; - } - else - { - char errstring[1024]; - int len; - len = snprintf(errstring, sizeof(errstring), - "WARNING: node %s is not listening for SYSMAN requests\n", - nodes[i].name); - write(errfd, errstring, len); - } - } - return num_listening; -} - -static int open_local_sock() -{ - int local_socket; - struct sockaddr_un sockaddr; - - // Open local socket - unlink(LOCAL_SOCKNAME); - local_socket = socket(PF_UNIX, SOCK_STREAM, 0); - if (local_socket < 0) - { - syslog(LOG_ERR, "Can't create local socket: %m"); - return -1; - } - - strcpy(sockaddr.sun_path, LOCAL_SOCKNAME); - sockaddr.sun_family = AF_UNIX; - if (bind(local_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) - { - syslog(LOG_ERR, "can't bind local socket: %m"); - close(local_socket); - return -1; - } - if (listen(local_socket, 1) != 0) - { - syslog(LOG_ERR, "listen local: %m"); - close(local_socket); - return -1; - } - // Make sure only root can talk to us via the local socket. - // Considering the rest of the security implications of - // this code, this is simply pathetic! - chmod(LOCAL_SOCKNAME, 0600); - - return local_socket; -} - -static struct read_fd *find_by_fd(int fd) -{ - struct read_fd *thisfd; - - for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next) - if (fd == thisfd->fd) return thisfd; - - return NULL; -} - -static void remove_sock(struct read_fd *deadfd) -{ - struct read_fd *thisfd; - struct read_fd *lastfd=NULL; - - for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next) - { - if (thisfd == deadfd) - { - lastfd->next = deadfd->next; - free(deadfd); - } - lastfd = thisfd; - } -} - -static int exec_command(char *cmd, char *reply, int *len) -{ - FILE *pipe; - int readlen; - int avail = MAX_CLUSTER_MESSAGE-sizeof(struct sysman_header)-1; - char realcmd[strlen(cmd)+25]; - - /* Send stderr back to the caller, and make stdin /dev/null */ - snprintf(realcmd, sizeof(realcmd), "%s </dev/null 2>&1", cmd); - - *len = 0; - pipe = popen(realcmd, "r"); - - /* Fill the buffer as full as possible */ - do - { - readlen = fread(reply + *len, 1, avail, pipe); - if (readlen > 0) - { - *len += readlen; - avail -= readlen; - } - } - while (avail>0 && readlen > 0); - - reply[*len] ='\0'; - - /* Return completion status of command */ - return pclose(pipe); -} diff --git a/cman/tests/user_service.c b/cman/tests/user_service.c deleted file mode 100644 index 9322e1a..0000000 --- a/cman/tests/user_service.c +++ /dev/null @@ -1,298 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <inttypes.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include "cnxman-socket.h" - -static pthread_t recv_thread; -static int cl_sock; -static int quit = 0; -static int leave_finished = 0; -static pid_t our_pid; - - -/* SIGUSR1 will cause this program to look for a new service event from SM - using the GETEVENT ioctl. - - SIGTERM will cause this program to leave the service group cleanly; it will - do a LEAVE ioctl, get a stop event and then exit. - - SIGKILL will cause the program to exit without first leaving the service - group. In that case the kernel will clean up and leave the service group - (as a part of cl_release on the cluster socket). */ - - -static void sigusr1_handler(int sig) -{ -} - -static void sigterm_handler(int sig) -{ - quit = 1; -} - -/* This thread receives messages on the cluster socket and prints them. */ - -static void *recv_thread_fn(void *arg) -{ - struct iovec iov[2]; - struct msghdr msg; - struct sockaddr_cl saddr; - char buf[256]; - int len; - int nodeid; - - for (;;) { - memset(buf, 0, 256); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = &saddr; - msg.msg_flags = 0; - msg.msg_namelen = sizeof(saddr); - iov[0].iov_len = sizeof(buf); - iov[0].iov_base = buf; - - len = recvmsg(cl_sock, &msg, MSG_OOB); - - if (len < 0 && errno == EAGAIN) - continue; - - if (!len || len < 0) - continue; - - nodeid = saddr.scl_nodeid; - - if (buf[0] == CLUSTER_OOB_MSG_PORTCLOSED) - printf("message: oob port-closed from nodeid %d\n", - nodeid); - - else if (buf[0] == CLUSTER_OOB_MSG_SERVICEEVENT) - printf("message: oob service-event\n"); - - else if (!strcmp(buf, "hello")) - printf("message: "%s" from nodeid %d\n", buf, nodeid); - - else - printf("message: unknown len %d byte0 %x nodeid %d\n", - len, buf[0], nodeid); - } -} - -static void send_group_message(void) -{ - struct iovec iov[2]; - struct msghdr msg; - char buf[256]; - int len; - - strcpy(buf, "hello"); - - iov[0].iov_len = strlen(buf); - iov[0].iov_base = buf; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = NULL; - msg.msg_flags = O_NONBLOCK; - msg.msg_namelen = 0; - - len = sendmsg(cl_sock, &msg, 0); -} - -static void print_ev(struct cl_service_event *ev) -{ - switch (ev->type) { - case SERVICE_EVENT_STOP: - printf("stop:\n"); - break; - case SERVICE_EVENT_START: - printf("start:\n"); - break; - case SERVICE_EVENT_FINISH: - printf("finish:\n"); - break; - case SERVICE_EVENT_LEAVEDONE: - printf("leavedone:\n"); - break; - } - printf(" event_id = %u\n", ev->event_id); - printf(" last_stop = %u\n", ev->last_stop); - printf(" last_start = %u\n", ev->last_start); - printf(" last_finish = %u\n", ev->last_finish); - printf(" node_count = %u\n", ev->node_count); -} - -static void print_members(int count, struct cl_cluster_node *nodes) -{ - int i; - - printf("members:\n"); - for (i = 0; i < count; i++) { - printf(" nodeid = %u "%s"\n", nodes->node_id, nodes->name); - nodes++; - } -} - -static int process_event(struct cl_service_event *ev) -{ - struct cl_cluster_node *nodes; - int error = 0; - - print_ev(ev); - - if (ev->type == SERVICE_EVENT_START) { - - nodes = malloc(ev->node_count * sizeof(struct cl_cluster_node)); - if (!nodes) { - perror("process_event: malloc failed"); - return -ENOMEM; - } - - memset(nodes, 0, ev->node_count*sizeof(struct cl_cluster_node)); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_GETMEMBERS, nodes); - if (error < 0) - perror("process_event: service get members failed"); - - print_members(ev->node_count, nodes); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_STARTDONE, - ev->event_id); - if (error < 0) - perror("process_event: start done error"); - - /* send_group_message(); */ - - free(nodes); - } - - if (ev->type == SERVICE_EVENT_LEAVEDONE) - leave_finished = 1; - - return error; -} - -int main(int argc, char **argv) -{ - struct cl_service_event event; - struct sockaddr_cl saddr; - char *name; - int error; - - our_pid = getpid(); - - if (argc > 1) - name = argv[1]; - else - name = "example"; - - - cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cl_sock < 0) { - perror("main: can't create cluster socket"); - return -1; - } - - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_REGISTER, name); - if (error < 0) { - perror("main: service register failed"); - return -1; - } - - - /* binding to an address is only needed if we want to send/recv - messages to other nodes on the cluster socket. */ - -#if 0 - saddr.scl_family = AF_CLUSTER; - saddr.scl_port = 13; /* CLUSTER_PORT_USER_SERVICE */ - - error = bind(cl_sock, (struct sockaddr *) &saddr, - sizeof(struct sockaddr_cl)); - if (error < 0) { - perror("main: can't bind to cluster socket"); - return -1; - } - pthread_create(&recv_thread, NULL, recv_thread_fn, 0); -#endif - - signal(SIGUSR1, sigusr1_handler); - signal(SIGTERM, sigterm_handler); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_SETSIGNAL, SIGUSR1); - if (error < 0) { - perror("main: service set signal failed"); - return -1; - } - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_JOIN, NULL); - if (error < 0) { - perror("main: service join failed"); - return -1; - } - - - for (;;) { - memset(&event, 0, sizeof(struct cl_service_event)); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_GETEVENT, &event); - if (error < 0) { - perror("main: service get event failed"); - return -1; - } - - if (!error) - pause(); - else - process_event(&event); - - - if (quit) { - quit = 0; - leave_finished = 0; - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_LEAVE, NULL); - if (error < 0) { - perror("main: service leave failed"); - return -1; - } - } - - if (leave_finished) - break; - } - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_UNREGISTER, NULL); - if (error < 0) - perror("main: unregister failed"); - - return 0; -} diff --git a/cmirror-kernel/Makefile b/cmirror-kernel/Makefile deleted file mode 100644 index d30d84f..0000000 --- a/cmirror-kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: - cd src && ${MAKE} all - -clean: - cd src && ${MAKE} clean - -install: - cd src && ${MAKE} install - -uninstall: - cd src && ${MAKE} uninstall - -distclean: clean - rm -f make/defines.mk diff --git a/cmirror-kernel/README b/cmirror-kernel/README deleted file mode 100644 index 20de282..0000000 --- a/cmirror-kernel/README +++ /dev/null @@ -1,10 +0,0 @@ -The table file for the cluster mirror target looks like: - -<start> <length> mirror \ -cluster 2 <log device> <region size> \ -<N> <dev1> <offset> <dev2> <offset> ... <devN> <offset> - -an example might be: - -#Example device mapper table file for cluster mirror -0 4724028 mirror cluster 2 /dev/sda1 1024 2 /dev/sda2 0 /dev/sdb2 0 diff --git a/cmirror-kernel/TODO b/cmirror-kernel/TODO deleted file mode 100644 index 0bf3342..0000000 --- a/cmirror-kernel/TODO +++ /dev/null @@ -1,50 +0,0 @@ -HIGH PRIORITY (data integrity related) -============= -1. Ensure that the proper blocks are being re-sync'ed upon node failure - A) Just regions in use by client machines when they die. - B) All regions in use when server dies. - -2. Ensure that it is not possible to have a machine (client or server) - die and lose important state. An example might be: - 1) two machines have marked a region dirty (only marked once - in the bitmap, server maintains info on the two machines) - 2) server dies - 3) new server designated, mirror region resync'ed - 4) machines continue to use region without server knowing region - should be in dirty state - 5) one of the original machines dies - -MEDIUM PRIORITY (functionality related, but data not at risk) -=============== -1. cluster_dtr (or disk_dtr?) should write bits to disk if it is - in charge of the log. This must be done in such a way so that - a new master does not pick up the disk before the leaving node - has flushed it. - - -LOW PRIORITY (coding practice, extended functionality, etc) -============ - -1. Basic code clean-up - -2. Figure out how to best utilize dm-log.c code without duplication - -3. Use mempool - -4. Use hash for server-side region use tracking, as opposed to linked list - -5. register the cluster_log service with cman at a level between - SERVICE_LEVEL_GDLM and SERVICE_LEVEL_GFS. - - this is not all that important right now, since we do - not use the DLM. So, recovery can happen in parallel with - the DLM (before or after). It must, however, happen after - fence and before GFS, which is why SERVICE_LEVEL_GDLM was - chosen. - -6. Implement paranoid mode - -7. Implement core mode - -8. Unable to specify port numbers (unable to change the default) - -9. the uuid scheme for identifying logs sucks diff --git a/cmirror-kernel/configure b/cmirror-kernel/configure deleted file mode 100755 index 430d161..0000000 --- a/cmirror-kernel/configure +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$kernel_src) { - $kernel_src="/usr/src/linux-2.6"; -} -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -open VER, "<$kernel_src/include/linux/version.h" or die "Can't open $kernel_src/include/linux/version.h"; -while(<VER>){ - chomp; - if( $_ =~ /^#define\s*UTS_RELEASE\s*"(.*)"$/ ){ - $kernel_version = $1; - $module_dir = "${prefix}/lib/modules/$1/kernel"; - } -} - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@KERNEL_VERSION@/$kernel_version/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@MODULE_DIR@/$module_dir/; - $_ =~ s/@SBINDIR@/$sbindir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/cmirror-kernel/make/defines.mk.input b/cmirror-kernel/make/defines.mk.input deleted file mode 100644 index 0c2ea7a..0000000 --- a/cmirror-kernel/make/defines.mk.input +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -module_dir ?= ${DESTDIR}/@MODULE_DIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ -KERNEL_VERSION = @KERNEL_VERSION@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/cmirror-kernel/make/release.mk.input b/cmirror-kernel/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/cmirror-kernel/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/cmirror-kernel/scripts/uninstall.pl b/cmirror-kernel/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/cmirror-kernel/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/cmirror-kernel/src/Makefile b/cmirror-kernel/src/Makefile deleted file mode 100644 index 59ce86b..0000000 --- a/cmirror-kernel/src/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = .. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -PWD := $(shell pwd) - -obj-m := dm-cmirror.o -dm-cmirror-objs := dm-cmirror-client.o \ - dm-cmirror-server.o \ - dm-cmirror-xfr.o \ - dm-cmirror-cman.o - -EXTRA_CFLAGS += -I$(obj) -Idrivers/md - -all: - if [ ! -e cluster ]; then ln -s . cluster; fi - if [ ! -e service.h ]; then cp ${incdir}/cluster/service.h .; fi - if [ ! -e cnxman.h ]; then cp ${incdir}/cluster/cnxman.h .; fi - if [ ! -e cnxman-socket.h ]; then cp ${incdir}/cluster/cnxman-socket.h .; fi - ${MAKE} -C ${KERNEL_SRC} M=${PWD} modules USING_KBUILD=yes - -install: all - install -d ${module_dir}/cluster - install dm-cmirror.ko ${module_dir}/cluster - -uninstall: - ${UNINSTALL} dm-cmirror.ko ${module_dir}/cluster - -clean: - rm -rf cluster cnxman* service.h *.ko *.o *.mod.c *~ .*o.cmd .tmp_versions - diff --git a/cmirror-kernel/src/dm-cmirror-client.c b/cmirror-kernel/src/dm-cmirror-client.c deleted file mode 100644 index 0ca1741..0000000 --- a/cmirror-kernel/src/dm-cmirror-client.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/vmalloc.h> -#include <linux/list.h> -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <linux/signal.h> -#include <linux/mempool.h> -#include <linux/bio.h> -#include <linux/blkdev.h> -#include <linux/device-mapper.h> -#include <linux/delay.h> -#include <cluster/service.h> -#include <cluster/cnxman.h> -#include <cluster/cnxman-socket.h> - -#include "dm-log.h" -#include "dm-cmirror-xfr.h" -#include "dm-cmirror-common.h" -#include "dm-cmirror-server.h" -#include "dm-cmirror-cman.h" - -DECLARE_MUTEX(log_list_lock); -LIST_HEAD(log_list_head); - -struct region_state { - int rs_mark_logged; - region_t rs_region; - struct list_head rs_list; -}; - -static mempool_t *region_state_pool = NULL; - -static int shutting_down=0; -static atomic_t suspend_client; -static wait_queue_head_t suspend_client_queue; -static wait_queue_head_t event_queue; - -static DECLARE_MUTEX(consult_server_lock); - -/* These vars are just for stats, and will be removed */ -static uint32_t request_count=0; -static uint32_t request_retry_count=0; - -static void *region_state_alloc(int gfp_mask, void *pool_data){ - return kmalloc(sizeof(struct region_state), gfp_mask); -} - -static void region_state_free(void *element, void *pool_data){ - kfree(element); -} - -#define BYTE_SHIFT 3 -/* - * <region_size> <uuid> [[no]sync] [block_on_error] - */ -static int core_ctr(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv) -{ - enum sync sync = DEFAULTSYNC; - int failure_response = FR_NONBLOCK; - - struct log_c *lc; - sector_t region_size; - unsigned int region_count; - size_t bitset_size; - int uuid = 0; - int i; - - /* Already checked argument count */ - - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "sync")) - sync = FORCESYNC; - else if (!strcmp(argv[i], "nosync")) - sync = NOSYNC; - else if (!strcmp(argv[i], "block_on_error")) - failure_response = FR_BLOCK; - else if (!uuid) - uuid = i; - else { - DMWARN("unrecognised argument to clustered mirror log: %s", - argv[i]); - return -EINVAL; - } - } - - if (sscanf(argv[0], SECTOR_FORMAT, ®ion_size) != 1) { - DMWARN("invalid region size string"); - return -EINVAL; - } - - region_count = dm_sector_div_up(ti->len, region_size); - - lc = kmalloc(sizeof(*lc), GFP_KERNEL); - if (!lc) { - DMWARN("Couldn't allocate core log"); - return -ENOMEM; - } - memset(lc, 0, sizeof(*lc)); - - lc->ti = ti; - lc->region_size = region_size; - lc->region_count = region_count; - lc->sync = sync; - lc->failure_response = failure_response; - strncpy(lc->uuid, argv[uuid], MAX_NAME_LEN); - init_completion(&lc->complete); - - /* - * Work out how many words we need to hold the bitset. - */ - bitset_size = dm_round_up(region_count, - sizeof(*lc->clean_bits) << BYTE_SHIFT); - - bitset_size >>= BYTE_SHIFT; - - lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits); - lc->clean_bits = vmalloc(bitset_size); - if (!lc->clean_bits) { - DMWARN("couldn't allocate clean bitset"); - kfree(lc); - return -ENOMEM; - } - memset(lc->clean_bits, -1, bitset_size); - - lc->sync_bits = vmalloc(bitset_size); - if (!lc->sync_bits) { - DMWARN("couldn't allocate sync bitset"); - vfree(lc->clean_bits); - kfree(lc); - return -ENOMEM; - } - memset(lc->sync_bits, (sync == NOSYNC) ? -1 : 0, bitset_size); - lc->sync_count = (sync == NOSYNC) ? region_count : 0; - - lc->recovering_region = (uint64_t)-1; - lc->recovering_next = (uint64_t)-1; - lc->sync_search = 0; - log->context = lc; - return 0; -} - -static void core_dtr(struct dirty_log *log) -{ - struct log_c *lc = (struct log_c *) log->context; - vfree(lc->clean_bits); - vfree(lc->sync_bits); - kfree(lc); -} - -/*---------------------------------------------------------------- - * disk log constructor/destructor - * - * <device> <region_size> <uuid> [[no]sync] [block_on_error] - *--------------------------------------------------------------*/ -static int disk_ctr(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv) -{ - int r; - size_t size; - struct log_c *lc; - struct dm_dev *dev; - - /* already checked argument count */ - r = dm_get_device(ti, argv[0], 0, 0 /* FIXME */, - FMODE_READ | FMODE_WRITE, &dev); - if (r){ - DMWARN("Unable to get device %s", argv[0]); - return r; - } - - r = core_ctr(log, ti, argc - 1, argv + 1); - if (r) { - dm_put_device(ti, dev); - return r; - } - - lc = (struct log_c *) log->context; - lc->log_dev = dev; - lc->log_dev_failed = 0; - /* init_completion(&lc->failure_completion); */ - - /* setup the disk header fields */ - lc->header_location.bdev = lc->log_dev->bdev; - lc->header_location.sector = 0; - lc->header_location.count = 1; - - /* - * We can't read less than this amount, even though we'll - * not be using most of this space. - */ - lc->disk_header = vmalloc(1 << SECTOR_SHIFT); - if (!lc->disk_header) - goto bad; - - /* setup the disk bitset fields */ - lc->bits_location.bdev = lc->log_dev->bdev; - lc->bits_location.sector = LOG_OFFSET; - - size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t), - 1 << SECTOR_SHIFT); - lc->bits_location.count = size >> SECTOR_SHIFT; - - return 0; - - bad: - dm_put_device(ti, lc->log_dev); - core_dtr(log); - return -ENOMEM; -} - -static void disk_dtr(struct dirty_log *log) -{ - struct log_c *lc = (struct log_c *) log->context; - dm_put_device(lc->ti, lc->log_dev); - vfree(lc->disk_header); - core_dtr(log); -} - - - -static int run_election(struct log_c *lc, uint32_t initial_server){ - int error=0, len; - struct sockaddr_in saddr_in; - struct msghdr msg; - struct iovec iov; - mm_segment_t fs; - struct log_request lr; /* ATTENTION -- could be too much on the stack */ - - memset(&lr, 0, sizeof(lr)); - - lr.lr_type = LRT_ELECTION; - lr.u.lr_starter = my_id; - lr.u.lr_coordinator = initial_server; - memcpy(lr.lr_uuid, lc->uuid, MAX_NAME_LEN); - lr.lr_uuid_ref = lc->uuid_ref; - - memset(&saddr_in, 0, sizeof(struct sockaddr_cl)); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = &iov; - msg.msg_flags = 0; - - saddr_in.sin_family = AF_INET; - saddr_in.sin_port = CLUSTER_LOG_PORT; - if(!(saddr_in.sin_addr.s_addr = nodeid_to_ipaddr(my_id))){ - DMERR("Unable to convert nodeid_to_ipaddr in run_election"); - } - msg.msg_name = &saddr_in; - msg.msg_namelen = sizeof(saddr_in); - - iov.iov_len = sizeof(struct log_request); - iov.iov_base = &lr; - - fs = get_fs(); - set_fs(get_ds()); - - len = sock_sendmsg(lc->client_sock, &msg, sizeof(struct log_request)); - - if(len < 0){ - DMERR("unable to send election notice to server (error = %d)", len); - error = len; - set_fs(fs); - goto fail; - } - - - /* why do we need to reset this? */ - iov.iov_len = sizeof(struct log_request); - iov.iov_base = &lr; - - len = my_recvmsg(lc->client_sock, &msg, sizeof(struct log_request), - 0, 20); - set_fs(fs); - - if(len > 0){ - lc->server_id = lr.u.lr_coordinator; - } else { - /* ATTENTION -- what do we do with this ? */ - DMWARN("Failed to receive election results from server: (%s/%d,%d)", - lc->uuid + (strlen(lc->uuid) - 8), lc->uuid_ref, len); - error = len; - } - - fail: - return error; -} - -static int _consult_server(struct log_c *lc, region_t region, - int type, region_t *result, int *retry){ - static int seq = 0; - int len; - int error=0; - struct sockaddr_in saddr_in; - struct msghdr msg; - struct iovec iov; - mm_segment_t fs; - struct log_request *lr; - - request_count++; - - lr = kmalloc(sizeof(struct log_request), GFP_NOFS); - if (!lr) { - BUG(); - error = -ENOMEM; - goto retry; - } - - memset(lr, 0, sizeof(struct log_request)); - - lr->lr_type = type; - lr->lr_seq = seq; - if(type == LRT_MASTER_LEAVING){ - lr->u.lr_starter = my_id; - } else { - lr->u.lr_region = region; - } - - if (type == LRT_COMPLETE_RESYNC_WORK) - lr->u.lr_int_rtn = (*result) ? 1 : 0; - - memcpy(lr->lr_uuid, lc->uuid, MAX_NAME_LEN); - lr->lr_uuid_ref = lc->uuid_ref; - - memset(&saddr_in, 0, sizeof(struct sockaddr_in)); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = &iov; - msg.msg_flags = 0; - - saddr_in.sin_family = AF_INET; - saddr_in.sin_port = CLUSTER_LOG_PORT; - if (!(saddr_in.sin_addr.s_addr = nodeid_to_ipaddr(lc->server_id))) { - error = -ENXIO; - goto retry; - } - msg.msg_name = &saddr_in; - msg.msg_namelen = sizeof(saddr_in); - - iov.iov_len = sizeof(struct log_request); - iov.iov_base = lr; - - fs = get_fs(); - set_fs(get_ds()); - - len = sock_sendmsg(lc->client_sock, &msg, sizeof(struct log_request)); - - set_fs(fs); - - if (len < sizeof(struct log_request)) { - DMWARN("unable to send log request to server"); - error = -EBADE; - goto fail; - } - -rerecv: - iov.iov_len = sizeof(struct log_request); - iov.iov_base = lr; - - fs = get_fs(); - set_fs(get_ds()); - - len = my_recvmsg(lc->client_sock, &msg, - sizeof(struct log_request), 0, 15); - set_fs(fs); - - if (len <= 0) { - /* ATTENTION -- what do we do with this ? */ - DMWARN("Error listening for server(%u) response for %s: %d", - lc->server_id, lc->uuid + (strlen(lc->uuid) - 8), len); - error = len; - seq++; - goto retry; - } - - if (seq != lr->lr_seq) { - DMDEBUG("Message sequence number mismatch: %d/%d", - seq, lr->lr_seq); - if (seq > lr->lr_seq) { - DMDEBUG(" Skipping. Listening again for response to %s", - RQ_STRING(type)); - memset(lr, 0, sizeof(struct log_request)); - goto rerecv; - } - DMERR(" Seq# mismatch: Must try to resend request, %s", RQ_STRING(type)); - error = -EBADE; - seq++; - goto retry; - } - seq++; - - if (type != lr->lr_type) { - DMERR("Got incorrect message type back: %s/%s", - RQ_STRING(type), RQ_STRING(lr->lr_type)); - error = -EBADE; - goto retry; - } - - if (memcmp(lc->uuid, lr->lr_uuid, MAX_NAME_LEN)) { - DMERR("Got reply from server for wrong log:"); - DMERR(" Expected UUID: %s", lc->uuid); - DMERR(" Recieved UUID: %s", lr->lr_uuid); - error = -EBADE; - goto retry; - } - - if (lr->u.lr_int_rtn == -EAGAIN) { - DMWARN("Server (%u), request type %d, -EAGAIN.", - lc->server_id, lr->lr_type); - goto retry; - } - - if (lr->u.lr_int_rtn == -ENXIO) { - DMDEBUG("Server (%u) says it no longer controls this log (%s)", - lc->server_id, lc->uuid + (strlen(lc->uuid) - 8)); - lc->server_id = 0xDEAD; - goto retry; - } - - if (result) - *result = lr->u.lr_region_rtn; - - error = lr->u.lr_int_rtn; - kfree(lr); - return error; - - retry: - *retry = 1; - request_retry_count++; - if (!(request_retry_count & 0x1F)) { - DMINFO("Clustered mirror retried requests :: %u of %u (%u%%)", - request_retry_count, - request_count, - dm_div_up(request_retry_count*100, request_count)); - DMDEBUG("Last request:"); - DMDEBUG(" - my_id :: %u", my_id); - DMDEBUG(" - server :: %u", lc->server_id); - DMDEBUG(" - log uuid:: %s (%s)", - lc->uuid + (strlen(lc->uuid) - 8), - atomic_read(&lc->suspended) ? "suspended" : "active"); - DMDEBUG(" - request :: %s", RQ_STRING(type)); - DMDEBUG(" - error :: %d", error); - DMINFO("Too many retries, attempting to re-establish server connection."); - lc->server_id = 0xDEAD; - } - -fail: - if (lr) - kfree(lr); - return error; -} - -static int consult_server(struct log_c *lc, region_t region, - int type, region_t *result){ - int rtn=0; - int retry=0; - int new_server=0; - struct region_state *rs=NULL; - - /* ATTENTION -- need to change this, the server could fail at anypoint ** - ** we do not want to send requests to the wrong place, or fail to run ** - ** an election when needed */ - down(&consult_server_lock); - - do{ - retry = 0; - suspend_on(&suspend_client_queue, atomic_read(&suspend_client)); - if ((type == LRT_MASTER_LEAVING) && (lc->server_id == 0xDEAD)) { - /* Nothing to do */ - goto out; - } - election: - while ((lc->server_id == 0xDEAD) || (!lc->server_valid)) { - DMDEBUG("server_id=%x, server_valid=%u, %s", - lc->server_id, lc->server_valid, - lc->uuid + (strlen(lc->uuid) - 8)); - DMDEBUG("trigger = %s", RQ_STRING(type)); - run_election(lc, my_id); - new_server = 1; - lc->server_valid = 1; - } - - spin_lock(&lc->state_lock); - if(new_server && - !list_empty(&lc->mark_logged)){ - int i=0; - LIST_HEAD(mark); - - DMINFO("Clean-up required due to new server"); - DMINFO(" - Resending all mark region requests"); - list_splice_init(&lc->mark_logged, &mark); - - spin_unlock(&lc->state_lock); - - list_for_each_entry(rs, &mark, rs_list){ - do { - retry = 0; - rtn = _consult_server(lc, rs->rs_region, - LRT_MARK_REGION, NULL, &retry); - if (lc->server_id == 0xDEAD) { - goto election; - } - } while(retry); - i++; - } - - spin_lock(&lc->state_lock); - list_splice_init(&mark, &lc->mark_logged); - - DMINFO(" - %d mark region requests resent", i); - DMINFO("Clean-up complete"); - DMINFO("Continuing request type, %d (%s)", type, - RQ_STRING(type)); - new_server = 0; - } - spin_unlock(&lc->state_lock); - - retry = 0; - rtn = _consult_server(lc, region, type, result, &retry); - } while(retry); -out: - up(&consult_server_lock); - - return rtn; -} - - -static int cluster_connect(void); -static int cluster_disconnect(void); - -static int cluster_ctr(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv, int disk) -{ - int error = 0; - struct log_c *lc, *tmp_lc; - struct sockaddr_in saddr_in; - - if (!disk) { - if ((error = core_ctr(log, ti, argc, argv))) { - DMWARN("Clustered mirror:: core_ctr failed"); - return error; - } - } else { - /* NOTE -- we take advantage of the fact that disk_ctr does ** - ** not actually read the disk. I suppose, however, that if ** - ** it does in the future, we will simply reread it when a ** - ** server is started here.................................. */ - - if((error = disk_ctr(log, ti, argc, argv))) { - DMWARN("Clustered mirror:: disk_ctr failed"); - return error; - } - } - - lc = log->context; - - /* Pull this out to support pvmove - if (lc->failure_response != FR_BLOCK) { - DMERR("Clustered mirror requires "block_on_error" parameter"); - error = -EINVAL; - goto fail; - } - */ - - atomic_set(&lc->in_sync, -1); - lc->uuid_ref = 1; - - down(&log_list_lock); - list_for_each_entry(tmp_lc, &log_list_head, log_list){ - if(!strncmp(tmp_lc->uuid, lc->uuid, MAX_NAME_LEN)){ - lc->uuid_ref = (lc->uuid_ref > tmp_lc->uuid_ref) ? - lc->uuid_ref : tmp_lc->uuid_ref + 1; - /* - * A second instance of the same log - * should start out suspended. - */ - atomic_set(&lc->suspended, 1); - lc->recovery_halted = 1; - DMDEBUG("Secondary log... suspended and recovery_halted"); - } - } - - list_add(&lc->log_list, &log_list_head); - up(&log_list_lock); - DMDEBUG("Creating %s (%d)", - lc->uuid + (strlen(lc->uuid) - 8), - lc->uuid_ref); - - INIT_LIST_HEAD(&lc->region_users); - INIT_LIST_HEAD(&lc->clear_waiting); - INIT_LIST_HEAD(&lc->mark_waiting); - INIT_LIST_HEAD(&lc->mark_logged); - spin_lock_init(&lc->state_lock); - - lc->server_valid = 0; - lc->server_id = 0xDEAD; - - if ((error = cluster_connect())) { - DMWARN("Unable to connect to cluster infrastructure."); - goto fail; - } - - error = sock_create(AF_INET, SOCK_DGRAM, - 0, - &lc->client_sock); - - if(error){ - DMWARN("unable to create clustered log client socket"); - goto fail; - } - - saddr_in.sin_family = AF_INET; - saddr_in.sin_port = CLUSTER_LOG_PORT+1; - if(!(saddr_in.sin_addr.s_addr = nodeid_to_ipaddr(my_id))){ - DMERR("Unable to convert nodeid_to_ipaddr in cluster_ctr"); - } - error = lc->client_sock->ops->bind(lc->client_sock, - (struct sockaddr *)&saddr_in, - sizeof(struct sockaddr_in)); - while(error == -EADDRINUSE){ - saddr_in.sin_port++; - error = lc->client_sock->ops->bind(lc->client_sock, - (struct sockaddr *)&saddr_in, - sizeof(struct sockaddr_in)); - } - - if(error){ - DMWARN("unable to bind clustered log client socket"); - sock_release(lc->client_sock); - goto fail; - } - - return 0; - - fail: - if (lc->log_dev) - disk_dtr(log); - else - core_dtr(log); - - return error; -} - -/*------------------------------------------------------------------ - * clustered_core log constructor - * (preceding args:: <start> <len> mirror clustered_core <log_args> - * - * Right now, 2 <= argc <= 4. - * - * argv contains: - * <region_size> <uuid> [[no]sync] [block_on_error] - *--------------------------------------------------------------*/ -static int cluster_core_ctr(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv) { - int i; - if ((argc < 2) || (argc > 4)) { - DMERR("Too %s arguments to clustered_core mirror log type.", - (argc < 2) ? "few" : "many"); - DMERR(" %d arguments supplied:", argc); - for (i = 0; i < argc; i++) - DMERR(" %s", argv[i]); - return -EINVAL; - } - - return cluster_ctr(log, ti, argc, argv, 0); -} - -/*------------------------------------------------------------------ - * clustered_disk log constructor - * (preceding args:: <start> <len> mirror clustered_disk <log_args> - * - * Right now, 3 <= argc <= 5. - * - * argv contains: - * <disk> <region_size> <uuid> [[no]sync] [block_on_error] - *--------------------------------------------------------------*/ -static int cluster_disk_ctr(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv) { - int i; - if ((argc < 3) || (argc > 5)) { - DMERR("Too %s arguments to clustered_disk mirror log type.", - (argc < 3) ? "few" : "many"); - DMERR(" %d arguments supplied:", argc); - for (i = 0; i < argc; i++) - DMERR(" %s", argv[i]); - return -EINVAL; - } - - return cluster_ctr(log, ti, argc, argv, 1); -} - -static void cluster_dtr(struct dirty_log *log) -{ - struct log_c *lc = (struct log_c *) log->context; - struct region_state *rs, *tmp_rs; - - DMDEBUG("Removing %s (%d)", - lc->uuid + (strlen(lc->uuid) - 8), - lc->uuid_ref); - - down(&log_list_lock); - list_del_init(&lc->log_list); - up(&log_list_lock); - - if ((lc->server_id == my_id) && !atomic_read(&lc->suspended)) - consult_server(lc, 0, LRT_MASTER_LEAVING, NULL); - - sock_release(lc->client_sock); - - spin_lock(&lc->state_lock); - - if (!list_empty(&lc->clear_waiting)) { - DMINFO("Clear requests remain at cluster log deactivation"); - list_for_each_entry_safe(rs, tmp_rs, &lc->clear_waiting, rs_list) { - list_del_init(&rs->rs_list); - DMINFO(" - Ignoring clear request: %Lu", rs->rs_region); - mempool_free(rs, region_state_pool); - } - } - - if (!list_empty(&lc->mark_waiting)) { - DMERR("Pending mark requests remain at cluster_dtr"); - BUG(); - } - - if (!list_empty(&lc->mark_logged)) { - int i = 0; - - list_for_each_entry_safe(rs, tmp_rs, &lc->mark_logged, rs_list) { - i++; - list_del_init(&rs->rs_list); - mempool_free(rs, region_state_pool); - } - DMDEBUG("%d mark requests remain at cluster log deactivation", i); - } - - spin_unlock(&lc->state_lock); - - server_free_region_users(lc); - - if (lc->log_dev) - disk_dtr(log); - else - core_dtr(log); - - if (cluster_disconnect()) - DMERR("Unable to disconnect from cluster infrastructure.\n"); -} - -static int cluster_presuspend(struct dirty_log *log) -{ - struct log_c *lc = (struct log_c *) log->context; - - DMDEBUG("cluster_presuspend: recovery halted on %s(%d)", - lc->uuid + (strlen(lc->uuid) - 8), lc->uuid_ref); - lc->recovery_halted = 1; - return 0; -} - -static int cluster_postsuspend(struct dirty_log *log) -{ - int i; - struct region_state *rs, *tmp_rs; - struct log_c *lc = (struct log_c *) log->context; - - DMDEBUG("cluster_postsuspend"); - spin_lock(&lc->state_lock); - if (!list_empty(&lc->mark_waiting)) { - DMERR("Mark requests remain at postsuspend!"); - BUG(); - } - - if (!list_empty(&lc->clear_waiting)) { - DMERR("Clear requests remain at postsuspend!"); - - list_for_each_entry_safe(rs, tmp_rs, &lc->clear_waiting, rs_list) { - list_del_init(&rs->rs_list); - DMERR(" - Ignoring clear request: %Lu", rs->rs_region); - mempool_free(rs, region_state_pool); - } - } - - spin_unlock(&lc->state_lock); - - if(lc->server_id == my_id) { - for (i = 0; server_busy(lc) && (i < 10); i++) { - DMDEBUG("Server for %s still busy, waiting for others", - lc->uuid + (strlen(lc->uuid) - 8)); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ*2); - } - } - - atomic_set(&lc->suspended, 1); - if(lc->server_id == my_id) { - while (1) { - DMDEBUG("Telling everyone I'm suspending (%s)", - lc->uuid + (strlen(lc->uuid) - 8)); - consult_server(lc, 0, LRT_MASTER_LEAVING, NULL); - - down(&consult_server_lock); - run_election(lc, 0xDEAD); - up(&consult_server_lock); - - if ((my_id && (lc->server_id == my_id))) { - DMDEBUG("Delaying suspend, work to be done (%s)", - lc->uuid + (strlen(lc->uuid) - 8)); - atomic_set(&lc->suspended, 0); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ*2); - atomic_set(&lc->suspended, 1); - } else { - DMDEBUG("Suspending now (%s)", - lc->uuid + (strlen(lc->uuid) - 8)); - break; - } - } - } - atomic_set(&lc->suspended, 2); - - return 0; -} - -static int cluster_resume(struct dirty_log *log){ - struct log_c *lc = (struct log_c *) log->context; - - lc->sync_search = 0; - resume_server_requests(); - DMDEBUG("cluster_resume: Setting recovery_halted = 0"); - lc->recovery_halted = 0; - atomic_set(&lc->suspended, 0); - atomic_set(&lc->in_sync,0); - - return 0; -} - -static uint32_t cluster_get_region_size(struct dirty_log *log) -{ - struct log_c *lc = (struct log_c *) log->context; - - return lc->region_size; -} - - -static int cluster_is_clean(struct dirty_log *log, region_t region) -{ - int rtn; - struct log_c *lc = (struct log_c *) log->context; - - rtn = consult_server(lc, region, LRT_IS_CLEAN, NULL); - - return rtn; -} - -static int cluster_is_remote_recovering(struct dirty_log *log, region_t region) -{ - int rtn; - struct log_c *lc = (struct log_c *) log->context; - - if (atomic_read(&lc->in_sync) == 1) { - return 0; - } - - rtn = consult_server(lc, region, LRT_IS_REMOTE_RECOVERING, NULL); - return rtn; -} - -static int cluster_in_sync(struct dirty_log *log, region_t region, int block) -{ - int rtn; - struct log_c *lc = (struct log_c *) log->context; - - /* check known_regions, return if found */ - - if(atomic_read(&lc->in_sync) == 1){ - return 1; - } - - if(!block){ - return -EWOULDBLOCK; - } - - rtn = consult_server(lc, region, LRT_IN_SYNC, NULL); - - return rtn; -} - -static int cluster_flush(struct dirty_log *log) -{ - int r = 0; - int clear_count = 0; - int mark_count = 0; - struct log_c *lc = (struct log_c *) log->context; - struct region_state *rs, *tmp_rs; - LIST_HEAD(mark); - LIST_HEAD(clear); - - /* - * It should never be a problem to temporarily have - * the mark requests in limbo. The only functions - * that call cluster_flush are rh_update_states and - * do_writes, and they are in the same thread as - * those changing the region states - */ - spin_lock(&lc->state_lock); - list_splice_init(&lc->clear_waiting, &clear); - list_splice_init(&lc->mark_waiting, &mark); - spin_unlock(&lc->state_lock); - - list_for_each_entry_safe(rs, tmp_rs, &clear, rs_list) { - /* don't really care if LRT_CLEAR_REGION fails */ - consult_server(lc, rs->rs_region, LRT_CLEAR_REGION, NULL); - list_del_init(&rs->rs_list); - mempool_free(rs, region_state_pool); - clear_count++; - } - - list_for_each_entry_safe(rs, tmp_rs, &mark, rs_list) { - while (1) { - r = consult_server(lc, rs->rs_region, - LRT_MARK_REGION, NULL); - if (!r) - break; - - if (r == -EBUSY) { - DMDEBUG("Delaying mark to region %Lu, due to recovery", - rs->rs_region); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - continue; - } - - if (r == -EIO) - goto fail; - - DMWARN("unable to get server (%u) to mark region (%Lu)", - lc->server_id, rs->rs_region); - DMWARN("Reason :: %d", r); - } - mark_count++; - } - - /* No flush work? */ - if (!clear_count && !mark_count) - return 0; - - spin_lock(&lc->state_lock); - list_splice_init(&mark, &lc->mark_logged); - spin_unlock(&lc->state_lock); - - while ((r = consult_server(lc, 0, LRT_FLUSH, NULL))) { - if (r == -EBUSY) { - DMDEBUG("Delaying flush due to recovery (%s)", - lc->uuid + (strlen(lc->uuid) - 8)); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - continue; - } - - if (r == -EIO) - break; - } - -fail: - if (r) { - DMERR("Log flush failure: %d%s", r, - (r == -EIO) ? " -EIO" : ""); - if (lc->failure_response == FR_BLOCK) - dm_table_event(lc->ti->table); - lc->log_dev_failed = 1; - } - - return r; -} - -static void cluster_mark_region(struct dirty_log *log, region_t region) -{ - struct region_state *rs, *tmp_rs, *rs_new; - struct log_c *lc = (struct log_c *) log->context; - - spin_lock(&lc->state_lock); - - /* - * An item on the clear_waiting list should have been flushed - * before getting this mark_region call. - */ - list_for_each_entry_safe(rs, tmp_rs, &lc->clear_waiting, rs_list) - if (region == rs->rs_region) { - DMERR("Region being marked found on clear_waiting list (%Lu/%s)", - region, lc->uuid + (strlen(lc->uuid) - 8)); - BUG(); - } - - /* - * We should never get two marks before a flush, unless the - * region is not in-sync. One valid scenario would be: - * 0) region not in-sync - * 1) rh_inc (mark region) - * 2) rh_update_states - * 3) rh_dec (dec pending and put on clean_region list) - * 4) do_writes -> rh_inc (second mark) - */ - list_for_each_entry_safe(rs, tmp_rs, &lc->mark_waiting, rs_list) - if (region == rs->rs_region) - goto out; - - /* - * It is possible for the following in the mirror code: - * 0) Mark is already logged for a region - * 1) rh_update_states (were the clear_region happens) - * 2) rh_dec, sets region state to RH_CLEAN (asynchronous) - * 3) do_writes, trys to mark region - * - * This can lead to this next case being valid. - */ - list_for_each_entry_safe(rs, tmp_rs, &lc->mark_logged, rs_list) - if (region == rs->rs_region) - goto out; - - spin_unlock(&lc->state_lock); - - rs_new = mempool_alloc(region_state_pool, GFP_NOFS); - BUG_ON(!rs_new); - memset(rs_new, 0, sizeof(struct region_state)); - - spin_lock(&lc->state_lock); - rs_new->rs_mark_logged = 1; - rs_new->rs_region = region; - INIT_LIST_HEAD(&rs_new->rs_list); - list_add(&rs_new->rs_list, &lc->mark_waiting); -out: - spin_unlock(&lc->state_lock); - - return; -} - -static void cluster_clear_region(struct dirty_log *log, region_t region) -{ - struct log_c *lc = (struct log_c *) log->context; - struct region_state *rs, *tmp_rs, *rs_new; - - spin_lock(&lc->state_lock); - - /* - * The nominal case is to find the region in the marked list - */ - list_for_each_entry_safe(rs, tmp_rs, &lc->mark_logged, rs_list){ - if(region == rs->rs_region){ - list_del_init(&rs->rs_list); - list_add(&rs->rs_list, &lc->clear_waiting); - goto out; - } - } - - /* - * It is possible, but unlikely to get to this case. It requires - * the following to happen: - * 1) mark the region for writing - * 2) clear the region - * 3) clear doesn't get flushed because of bug 235040 - * 4) suspend due to server relocation - * 5) on-disk log says we need to recover (because it hasn't been cleared) - * 6) we recover the region - * 7) clearing the region after recovery causes us to get here - * - * Bug 235040 cleared. This should no longer happen. - */ - list_for_each_entry_safe(rs, tmp_rs, &lc->clear_waiting, rs_list){ - if(region == rs->rs_region){ - DMERR("Double clear on region (%Lu/%s)", - region, lc->uuid + (strlen(lc->uuid) - 8)); - BUG(); - } - } - - list_for_each_entry_safe(rs, tmp_rs, &lc->mark_waiting, rs_list){ - if(region == rs->rs_region){ - DMERR("Clear pre-empting mark (%Lu/%s)", - region, lc->uuid + (strlen(lc->uuid) - 8)); - BUG(); - } - } - - /* We can get here because we may be doing resync_work, and therefore,** - ** clearing without ever marking..................................... */ - - /* Don't need to spin_unlock, because allocation is non-blocking */ - rs_new = mempool_alloc(region_state_pool, GFP_ATOMIC); - if (!rs_new) { - DMERR("Failed to allocate space for clear region request: %Lu", - region); - BUG(); - } - memset(rs_new, 0, sizeof(struct region_state)); - - rs_new->rs_region = region; - INIT_LIST_HEAD(&rs_new->rs_list); - list_add(&rs_new->rs_list, &lc->clear_waiting); - -out: - spin_unlock(&lc->state_lock); - - return; -} - -static int cluster_get_resync_work(struct dirty_log *log, region_t *region) -{ - int rtn; - struct log_c *lc = (struct log_c *) log->context; - - rtn = consult_server(lc, 0, LRT_GET_RESYNC_WORK, region); - - if (*region > lc->region_count) { - DMWARN("Error while getting resync work: bad region"); - rtn = 0; - } - - if (rtn) - DMDEBUG("Received recovery work from %u: %Lu/%s", - lc->server_id, *region, lc->uuid + (strlen(lc->uuid) - 8)); - - /* - * Check for bug 235039 - * Note the changes in cluser_clear_region - */ - if (rtn == 1) { - struct region_state *rs, *tmp_rs; - list_for_each_entry_safe(rs, tmp_rs, &lc->clear_waiting, rs_list) { - if (*region == rs->rs_region) { - DMERR("WARNING: Bug 235039/235040 detected!"); - BUG(); - } - } - } - - return rtn; -} - -static void cluster_complete_resync_work(struct dirty_log *log, - region_t region, int success) -{ - int i; - region_t success_tmp = success; - struct log_c *lc = (struct log_c *) log->context; - - if (success) - DMDEBUG("Client finishing recovery: %Lu/%s", - region, lc->uuid + (strlen(lc->uuid) - 8)); - else - DMDEBUG("Notifying server(%u) of sync change: %Lu/%s", - lc->server_id, region, - lc->uuid + (strlen(lc->uuid) - 8)); - for (i = 0; i < 5; i++) { - if (!consult_server(lc, region, - LRT_COMPLETE_RESYNC_WORK, &success_tmp)) - break; - success_tmp = success; - DMWARN("Unable to notify server of sync state change"); - } - return; -} - -static region_t cluster_get_sync_count(struct dirty_log *log) -{ - int i; - region_t rtn; - struct log_c *lc = (struct log_c *) log->context; - - if (atomic_read(&lc->suspended)) { - return (atomic_read(&lc->in_sync) == 1) ? lc->region_count : 0; - } - - /* Try to get sync count up to five times */ - for (i = 0; i < 5 && consult_server(lc, 0, LRT_GET_SYNC_COUNT, &rtn); i++); - if(i >= 5){ - return 0; - } - - if(rtn > lc->region_count){ - DMERR("sync_count (" - SECTOR_FORMAT - ") > region_count (" - SECTOR_FORMAT - ") - (%s)!", - rtn, lc->region_count, lc->uuid + (strlen(lc->uuid) - 8)); - } - - if(rtn >= lc->region_count){ - atomic_set(&lc->in_sync, 1); - } else if(unlikely(atomic_read(&lc->in_sync) < 0)){ - atomic_set(&lc->in_sync, 0); - } - - return rtn; -} - -static int cluster_status(struct dirty_log *log, status_type_t status, - char *result, unsigned int maxlen) -{ - int sz = 0; - int arg_count=2; - struct log_c *lc = (struct log_c *) log->context; - - switch(status){ - case STATUSTYPE_INFO: - if(lc->sync != DEFAULTSYNC) - arg_count++; - - if (lc->log_dev) - DMEMIT("3 %s %s %c", - log->type->name, /* NAME */ - lc->log_dev->name, /* THE LOG DEVICE */ - (lc->log_dev_failed)? 'D' : 'A'); /* LOG DEVICE LIVENESS */ - else - DMEMIT("1 %s", log->type->name); - - break; - - case STATUSTYPE_TABLE: - DMDEBUG("LOG INFO:"); - DMDEBUG(" uuid: %s", lc->uuid); - DMDEBUG(" uuid_ref : %d", lc->uuid_ref); - DMDEBUG(" log type : %s", (lc->log_dev) ? "disk" : "core"); - DMDEBUG(" ?region_count: %Lu", lc->region_count); - DMDEBUG(" ?sync_count : %Lu", lc->sync_count); - DMDEBUG(" ?sync_search : %d", lc->sync_search); - DMDEBUG(" in_sync : %s", (atomic_read(&lc->in_sync)) ? "YES" : "NO"); - DMDEBUG(" suspended : %s", (atomic_read(&lc->suspended)) ? "YES" : "NO"); - DMDEBUG(" recovery_halted : %s", (lc->recovery_halted) ? "YES" : "NO"); - DMDEBUG(" server_id : %u", lc->server_id); - DMDEBUG(" server_valid: %s", - ((lc->server_id != 0xDEAD) && lc->server_valid) ? "YES" : "NO"); - { - struct log_c *tmp_lc; - - down(&log_list_lock); - list_for_each_entry(tmp_lc, &log_list_head, log_list){ - if(!strncmp(tmp_lc->uuid, lc->uuid, MAX_NAME_LEN) && - (tmp_lc->uuid_ref != lc->uuid_ref)){ - DMDEBUG("LOG INFO [COPY FOUND]:"); - DMDEBUG(" uuid: %s", tmp_lc->uuid); - DMDEBUG(" uuid_ref : %d", tmp_lc->uuid_ref); - DMDEBUG(" ?region_count: %Lu", tmp_lc->region_count); - DMDEBUG(" ?sync_count : %Lu", tmp_lc->sync_count); - DMDEBUG(" ?sync_search : %d", tmp_lc->sync_search); - DMDEBUG(" in_sync : %s", - (atomic_read(&tmp_lc->in_sync)) ? "YES" : "NO"); - DMDEBUG(" suspended : %s", - (atomic_read(&tmp_lc->suspended)) ? "YES" : "NO"); - DMDEBUG(" recovery_halted : %s", - (tmp_lc->recovery_halted) ? "YES" : "NO"); - DMDEBUG(" server_id : %u", tmp_lc->server_id); - DMDEBUG(" server_valid: %s", - ((tmp_lc->server_id != 0xDEAD) && - tmp_lc->server_valid) ? "YES" : "NO"); - } - } - up(&log_list_lock); - } - if(lc->sync != DEFAULTSYNC) - arg_count++; - - if (lc->failure_response == FR_BLOCK) - arg_count++; - - if (lc->log_dev) { - arg_count++; - - DMEMIT("%s %u %s " SECTOR_FORMAT " %s ", - log->type->name, /* NAME */ - arg_count, /* # OF ARGS */ - lc->log_dev->name, /* THE LOG DEVICE */ - lc->region_size, /* REGION SIZE */ - lc->uuid); /* UUID */ - } else { - DMEMIT("%s %u " SECTOR_FORMAT " %s ", - log->type->name, /* NAME */ - arg_count, /* # OF ARGS */ - lc->region_size, /* REGION SIZE */ - lc->uuid); /* UUID */ - } - if (lc->sync != DEFAULTSYNC) - DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : ""); - - if (lc->failure_response == FR_BLOCK) - DMEMIT("block_on_error "); - } - - return sz; -} - -static int cluster_get_failure_response(struct dirty_log *log) -{ - struct log_c *lc = (struct log_c *) log->context; - return lc->failure_response; -} - -static int clog_stop(void *data){ - struct log_c *lc; - - atomic_set(&suspend_client, 1); - - down(&log_list_lock); - list_for_each_entry(lc, &log_list_head, log_list) { - atomic_set(&lc->in_sync, 0); - } - up(&log_list_lock); - - return 0; -} - -static int clog_start(void *data, uint32_t *nodeids, int count, int event_id, int type){ - int i; - uint32_t server; - struct log_c *lc; - struct kcl_cluster_node node; - - if(global_nodeids){ - kfree(global_nodeids); - } - global_nodeids = nodeids; - global_count = count; - - for (i = 0; kcl_get_node_by_nodeid(0, &node); i++) { - if (i > 10) - BUG(); - else - DMERR("Bad call to kcl_get_node_by_nodeid"); - } - my_id = node.node_id; - - /* Wait for any outstanding starts to complete */ - suspend_on(&event_queue, atomic_read(&restart_event_type)); - - restart_event_id = event_id; - atomic_set(&restart_event_type, type); - - switch(type){ - case SERVICE_NODE_LEAVE: - case SERVICE_NODE_FAILED: - down(&log_list_lock); - list_for_each_entry(lc, &log_list_head, log_list){ - for(i=0, server = 0xDEAD; i < count; i++){ - if(lc->server_id == nodeids[i]){ - server = nodeids[i]; - } - } - /* ATTENTION -- need locking around this ? */ - lc->server_id = server; - } - up(&log_list_lock); - - break; - case SERVICE_NODE_JOIN: - break; - default: - DMERR("Invalid service event type received"); - BUG(); - break; - } - - return 0; -} - -static void clog_finish(void *data, int event_id){ - atomic_set(&suspend_client, 0); - wake_up_all(&suspend_client_queue); -} - -static struct kcl_service_ops clog_ops = { - .stop = clog_stop, - .start = clog_start, - .finish = clog_finish, -}; - -static int mirror_set_count = 0; /* used to prevent multiple cluster [dis]connects */ -static DECLARE_MUTEX(cmirror_register_lock); - -static int cluster_connect(void) -{ - int r = 0; - - down(&cmirror_register_lock); - - if (mirror_set_count++) - goto out; - - r = kcl_register_service("clustered_log", 13, SERVICE_LEVEL_GDLM, &clog_ops, - 1, NULL, &local_id); - if (r) { - DMWARN("Couldn't register clustered_log service. Reason: %d", r); - goto out; - } - - r = start_server(); - if(r){ - DMWARN("Unable to start clustered log server daemon"); - kcl_unregister_service(local_id); - goto out; - } - - r = kcl_join_service(local_id); - - if(r){ - DMWARN("couldn't join service group"); - stop_server(); - kcl_unregister_service(local_id); - } - -out: - up(&cmirror_register_lock); - return r; -} - -static int cluster_disconnect(void) -{ - down(&cmirror_register_lock); - - if (--mirror_set_count) { - up(&cmirror_register_lock); - return 0; - } - - /* By setting 'shutting_down', the server will not be suspended ** - ** when a stop is received */ - shutting_down = 1; - kcl_leave_service(local_id); - stop_server(); - kcl_unregister_service(local_id); - - up(&cmirror_register_lock); - return 0; -} - -static struct dirty_log_type _clustered_core_type = { - .name = "clustered_core", - .module = THIS_MODULE, - .ctr = cluster_core_ctr, - .dtr = cluster_dtr, - .presuspend = cluster_presuspend, - .postsuspend = cluster_postsuspend, - .resume = cluster_resume, - .get_region_size = cluster_get_region_size, - .is_clean = cluster_is_clean, - .is_remote_recovering = cluster_is_remote_recovering, - .in_sync = cluster_in_sync, - .flush = cluster_flush, - .mark_region = cluster_mark_region, - .clear_region = cluster_clear_region, - .get_resync_work = cluster_get_resync_work, - .complete_resync_work = cluster_complete_resync_work, - .get_sync_count = cluster_get_sync_count, - .status = cluster_status, - .get_failure_response = cluster_get_failure_response, -}; - -static struct dirty_log_type _clustered_disk_type = { - .name = "clustered_disk", - .module = THIS_MODULE, - .ctr = cluster_disk_ctr, - .dtr = cluster_dtr, - .presuspend = cluster_presuspend, - .postsuspend = cluster_postsuspend, - .resume = cluster_resume, - .get_region_size = cluster_get_region_size, - .is_clean = cluster_is_clean, - .is_remote_recovering = cluster_is_remote_recovering, - .in_sync = cluster_in_sync, - .flush = cluster_flush, - .mark_region = cluster_mark_region, - .clear_region = cluster_clear_region, - .get_resync_work = cluster_get_resync_work, - .complete_resync_work = cluster_complete_resync_work, - .get_sync_count = cluster_get_sync_count, - .status = cluster_status, - .get_failure_response = cluster_get_failure_response, -}; - -#define CMIRROR_RELEASE_NAME "0.2.0" -static int __init cluster_dirty_log_init(void) -{ - int r = 0; - - DMINFO("dm-cmirror %s (built %s %s) installed", - CMIRROR_RELEASE_NAME, __DATE__, __TIME__); - - region_state_pool = mempool_create(500, region_state_alloc, - region_state_free, NULL); - if(!region_state_pool){ - DMWARN("couldn't create region state pool"); - return -ENOMEM; - } - - init_waitqueue_head(&suspend_client_queue); - init_waitqueue_head(&event_queue); - - r = dm_register_dirty_log_type(&_clustered_core_type); - if (r) { - DMWARN("couldn't register clustered_core dirty log type"); - mempool_destroy(region_state_pool); - return r; - } - - r = dm_register_dirty_log_type(&_clustered_disk_type); - if (r) { - DMWARN("couldn't register clustered_disk dirty log type"); - dm_unregister_dirty_log_type(&_clustered_core_type); - mempool_destroy(region_state_pool); - return r; - } - - return r; - -} - -static void __exit cluster_dirty_log_exit(void) -{ - if(!list_empty(&log_list_head)){ - DMERR("attempt to remove module, but dirty logs are still in place!"); - DMERR("this is a fatal error"); - BUG(); - } - dm_unregister_dirty_log_type(&_clustered_core_type); - dm_unregister_dirty_log_type(&_clustered_disk_type); - mempool_destroy(region_state_pool); - DMINFO("dm-cmirror %s (built %s %s) removed", - CMIRROR_RELEASE_NAME, __DATE__, __TIME__); -} - -module_init(cluster_dirty_log_init); -module_exit(cluster_dirty_log_exit); - -MODULE_DESCRIPTION(DM_NAME " cluster capable mirror logs (clustered mirroring)"); -MODULE_AUTHOR("Jonathan Brassow"); -MODULE_LICENSE("GPL"); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/cmirror-kernel/src/dm-cmirror-cman.c b/cmirror-kernel/src/dm-cmirror-cman.c deleted file mode 100644 index db0ee9c..0000000 --- a/cmirror-kernel/src/dm-cmirror-cman.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/vmalloc.h> -#include <linux/list.h> -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <linux/signal.h> -#include <linux/bio.h> -#include <linux/blkdev.h> -#include <linux/device-mapper.h> -#include <cluster/service.h> -#include <cluster/cnxman.h> -#include <cluster/cnxman-socket.h> - -#include "dm-log.h" -#include "dm-cmirror-common.h" - -uint32_t local_id; -uint32_t my_id=0; -int global_count=0; -uint32_t *global_nodeids=NULL; - -atomic_t restart_event_type = ATOMIC_INIT(0); -int restart_event_id=0; - -uint32_t nodeid_to_ipaddr(uint32_t nodeid){ - struct cluster_node_addr *cna; - struct sockaddr_in *saddr; - struct list_head *list = kcl_get_node_addresses(nodeid); - - if(!list){ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/4); - return 0; - } - - - list_for_each_entry(cna, list, list){ - saddr = (struct sockaddr_in *)(&cna->addr); - return (uint32_t)(saddr->sin_addr.s_addr); - } - return 0; -} - -uint32_t ipaddr_to_nodeid(struct sockaddr *addr){ - struct list_head *addr_list; - struct kcl_cluster_node node; - struct cluster_node_addr *tmp; - - if(!(addr_list = kcl_get_node_addresses(my_id))){ - DMWARN("No address list available for %u\n", my_id); - goto fail; - } - - if(addr->sa_family == AF_INET){ - struct sockaddr_in a4; - struct sockaddr_in *tmp_addr; - list_for_each_entry(tmp, addr_list, list){ - tmp_addr = (struct sockaddr_in *)tmp->addr; - if(tmp_addr->sin_family == AF_INET){ - memcpy(&a4, tmp_addr, sizeof(a4)); - memcpy(&a4.sin_addr, - &((struct sockaddr_in *)addr)->sin_addr, - sizeof(a4.sin_addr)); - if(!kcl_get_node_by_addr((char *)&a4, - sizeof(a4), - &node)){ - return node.node_id; - } - } - } - } else if(addr->sa_family == AF_INET6){ - struct sockaddr_in6 a6; - struct sockaddr_in6 *tmp_addr; - list_for_each_entry(tmp, addr_list, list){ - tmp_addr = (struct sockaddr_in6 *)tmp->addr; - if(tmp_addr->sin6_family == AF_INET6){ - memcpy(&a6, tmp_addr, sizeof(a6)); - memcpy(&a6.sin6_addr, - &((struct sockaddr_in6 *)addr)->sin6_addr, - sizeof(a6.sin6_addr)); - if(!kcl_get_node_by_addr((char *)&a6, - sizeof(a6), - &node)){ - return node.node_id; - } - } - } - } - - fail: - DMWARN("Failed to convert IP address to nodeid."); - return 0; -} diff --git a/cmirror-kernel/src/dm-cmirror-cman.h b/cmirror-kernel/src/dm-cmirror-cman.h deleted file mode 100644 index 16d7c33..0000000 --- a/cmirror-kernel/src/dm-cmirror-cman.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#ifndef __DM_CMIRROR_CMAN_H__ -#define __DM_CMIRROR_CMAN_H__ - -extern uint32_t local_id; -extern uint32_t my_id; -extern int global_count; -extern uint32_t *global_nodeids; - -extern atomic_t restart_event_type; -extern int restart_event_id; - -uint32_t nodeid_to_ipaddr(uint32_t nodeid); -uint32_t ipaddr_to_nodeid(struct sockaddr *addr); - -#endif /* __DM_CMIRROR_CMAN_H__ */ diff --git a/cmirror-kernel/src/dm-cmirror-common.h b/cmirror-kernel/src/dm-cmirror-common.h deleted file mode 100644 index e8d2144..0000000 --- a/cmirror-kernel/src/dm-cmirror-common.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#ifndef __DM_CMIRROR_COMMON_H__ -#define __DM_CMIRROR_COMMON_H__ - -/* from dm-io.h */ -struct io_region { - struct block_device *bdev; - sector_t sector; - sector_t count; -}; -int dm_io_get(unsigned int num_pages); -void dm_io_put(unsigned int num_pages); -int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw, - void *data, unsigned long *error_bits); -int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw, - void *data, void (*fn)(unsigned long, void *),/*io_notify_fn fn,*/ void *context); - -/* from dm.h */ -#define DM_NAME "dm-cmirror" -#define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x) -#define DMERR(f, x...) printk(KERN_ERR DM_NAME ": " f "\n" , ## x) -#define DMINFO(f, x...) printk(KERN_INFO DM_NAME ": " f "\n" , ## x) -#define DMDEBUG(f, x...) printk(KERN_DEBUG DM_NAME ": " f "\n" , ## x) -#define DMEMIT(x...) sz += ((sz >= maxlen) ? \ - 0 : scnprintf(result + sz, maxlen - sz, x)) - -#ifdef CONFIG_LBD -#define SECTOR_FORMAT "%Lu" -#else -#define SECTOR_FORMAT "%lu" -#endif - -#define SECTOR_SHIFT 9 -/* - * Ceiling(n / sz) - */ -#define dm_div_up(n, sz) (((n) + (sz) - 1) / (sz)) - -#define dm_sector_div_up(n, sz) ( \ -{ \ - sector_t _r = ((n) + (sz) - 1); \ - sector_div(_r, (sz)); \ - _r; \ -} \ -) - -/* - * ceiling(n / size) * size - */ -#define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz)) - -struct dm_dev { - struct list_head list; - - atomic_t count; - int mode; - struct block_device *bdev; - char name[16]; -}; - -void dm_table_event(struct dm_table *t); -/* end of dm.h */ - -#define SHORT_UUID(x) (strlen(x) > 8) ? ((x) + (strlen(x) - 8)) : (x) -/* - * Magic for persistent mirrors: "MiRr" - */ -#define MIRROR_MAGIC 0x4D695272 - -/* - * The on-disk version of the metadata. - */ -#define MIRROR_DISK_VERSION 2 -#define LOG_OFFSET 2 -#define MAX_NAME_LEN 128 - -struct log_header { - uint32_t magic; - - /* - * Simple, incrementing version. no backward - * compatibility. - */ - uint32_t version; - sector_t nr_regions; - char uuid[MAX_NAME_LEN]; -}; - -struct log_c { - struct dm_target *ti; - int touched; - sector_t region_size; - region_t region_count; - region_t sync_count; - - unsigned bitset_uint32_count; - uint32_t *clean_bits; - uint32_t *sync_bits; - uint64_t recovering_region; - uint64_t recovering_next; - - int sync_pass; /* number of passes attempting to resync */ - int sync_search; - int recovery_halted; /* only useful for is_remote_recovering */ - - /* Resync flag */ - enum sync { - DEFAULTSYNC, /* Synchronize if necessary */ - NOSYNC, /* Devices known to be already in sync */ - FORCESYNC, /* Force a sync to happen */ - } sync; - - int failure_response; - /* - * Disk log fields - */ - int log_error; - struct completion complete; - - int log_dev_failed; - atomic_t suspended; - /* - struct completion failure_completion; - */ - struct dm_dev *log_dev; - struct log_header header; - - struct io_region header_location; - struct log_header *disk_header; - - struct io_region bits_location; - - /* - * Cluster log fields - */ - char uuid[MAX_NAME_LEN]; - int uuid_ref; - atomic_t in_sync; /* like sync_count, except all or nothing */ - - struct list_head log_list; - struct list_head region_users; /* Used by Server */ - - spinlock_t state_lock; - struct list_head clear_waiting; - struct list_head mark_waiting; - struct list_head mark_logged; - - uint32_t server_valid; - uint32_t server_id; - struct socket *client_sock; -}; - -#define suspend_on(wq, sleep_cond) \ -do \ -{ \ - DECLARE_WAITQUEUE(__wait_chan, current); \ - current->state = TASK_UNINTERRUPTIBLE; \ - add_wait_queue(wq, &__wait_chan); \ - if ((sleep_cond)){ \ - schedule(); \ - } \ - remove_wait_queue(wq, &__wait_chan); \ - current->state = TASK_RUNNING; \ -} \ -while (0) - -#endif /*__DM_CMIRROR_COMMON_H__ */ -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/cmirror-kernel/src/dm-cmirror-server.c b/cmirror-kernel/src/dm-cmirror-server.c deleted file mode 100644 index 25a82b5..0000000 --- a/cmirror-kernel/src/dm-cmirror-server.c +++ /dev/null @@ -1,1480 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/vmalloc.h> -#include <linux/list.h> -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <linux/signal.h> -#include <linux/bio.h> -#include <linux/blkdev.h> -#include <linux/device-mapper.h> -#include <cluster/service.h> -#include <cluster/cnxman.h> -#include <cluster/cnxman-socket.h> - -#include "dm-log.h" -#include "dm-cmirror-common.h" -#include "dm-cmirror-xfr.h" -#include "dm-cmirror-cman.h" - -#define RU_READ 0 -#define RU_WRITE 1 -#define RU_RECOVER 2 -#define BYTE_SHIFT 3 - -struct region_user { - struct list_head ru_list; - int32_t ru_rw; - uint32_t ru_nodeid; - region_t ru_region; -}; - -static mempool_t *region_user_pool; - -static atomic_t server_run; -static struct completion server_completion; - -static atomic_t _do_requests; - -static int debug_disk_write = 0; -extern struct semaphore log_list_lock; -extern struct list_head log_list_head; - -static void *region_user_alloc(int gfp_mask, void *pool_data){ - return kmalloc(sizeof(struct region_user), gfp_mask); -} - -static void region_user_free(void *element, void *pool_data){ - kfree(element); -} - -/* - * The touched member needs to be updated every time we access - * one of the bitsets. - */ -static inline int log_test_bit(uint32_t *bs, unsigned bit) -{ - return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0; -} - -static inline void log_set_bit(struct log_c *l, - uint32_t *bs, unsigned bit) -{ - ext2_set_bit(bit, (unsigned long *) bs); - l->touched = 1; -} - -static inline void log_clear_bit(struct log_c *l, - uint32_t *bs, unsigned bit) -{ - ext2_clear_bit(bit, (unsigned long *) bs); - l->touched = 1; -} - -/*---------------------------------------------------------------- - * Header IO - *--------------------------------------------------------------*/ -static void header_to_disk(struct log_header *core, struct log_header *disk) -{ - disk->magic = cpu_to_le32(core->magic); - disk->version = cpu_to_le32(core->version); - disk->nr_regions = cpu_to_le64(core->nr_regions); - memcpy(disk->uuid, core->uuid, MAX_NAME_LEN); -} - -static void header_from_disk(struct log_header *core, struct log_header *disk) -{ - core->magic = le32_to_cpu(disk->magic); - core->version = le32_to_cpu(disk->version); - core->nr_regions = le64_to_cpu(disk->nr_regions); - memcpy(core->uuid, disk->uuid, MAX_NAME_LEN); -} - -static void do_io_callback(unsigned long error, void *context) -{ - struct log_c *lc = context; - - lc->log_error = (error) ? -EIO : 0; - complete(&lc->complete); -} - -/* - * do_io - * @log - * @rw: read/write - * @header: header (if not, then bits) - * - * Returns: 0 on success, -EXXX on error - */ -static int do_io(struct log_c *log, int rw, int header) -{ - int r; - - r = dm_io_async_vm(1, - (header) ? &log->header_location : &log->bits_location, - rw, - (header) ? (void *)(log->disk_header) : (void *)(log->clean_bits), - do_io_callback, log); - if (r) { - DMERR("Error while submitting log I/O: %d", r); - return r; - } - - r = wait_for_completion_timeout(&log->complete, 5 * HZ); - if (!r) { - DMERR("[%s] Timed out waiting for log I/O: %s of %s", - SHORT_UUID(log->uuid), (rw == WRITE) ? "Write" : "Read", - (header) ? "header" : "bits"); - return -EDEADLK; - } - return log->log_error; -} - -int read_header(struct log_c *log) -{ - int r; - - if (!log->log_dev) - return 0; - - if (atomic_read(&log->suspended)) - return -EDEADLK; - - r = do_io(log, READ, 1); - if (unlikely(r)) - return r; - - header_from_disk(&log->header, log->disk_header); - - /* New log required? */ - if (log->sync != DEFAULTSYNC || log->header.magic != MIRROR_MAGIC) { - log->header.magic = MIRROR_MAGIC; - log->header.version = MIRROR_DISK_VERSION; - log->header.nr_regions = 0; - memset(log->header.uuid, 0, MAX_NAME_LEN); - } - - if (log->header.version != MIRROR_DISK_VERSION) { - DMWARN("incompatible disk log version"); - return -EINVAL; - } - - return 0; -} - -int write_header(struct log_c *log) -{ - if (!log->log_dev) - return 0; - - if (atomic_read(&log->suspended)) - return -EDEADLK; - - header_to_disk(&log->header, log->disk_header); - - return do_io(log, WRITE, 1); -} - -/*---------------------------------------------------------------- - * Bits IO - *--------------------------------------------------------------*/ -static inline void zeros_to_core(uint32_t *core, unsigned count) -{ - memset(core, 0, sizeof(uint32_t)*count); -} - -static inline void bits_to_core(uint32_t *core, uint32_t *disk, unsigned count) -{ - unsigned i; - - for (i = 0; i < count; i++) - core[i] = le32_to_cpu(disk[i]); -} - -static inline void zeros_to_disk(uint32_t *disk, unsigned count) -{ - memset(disk, 0, sizeof(uint32_t)*count); -} - -static inline void bits_to_disk(uint32_t *core, uint32_t *disk, unsigned count) -{ - unsigned i; - - /* copy across the clean/dirty bitset */ - for (i = 0; i < count; i++) - disk[i] = cpu_to_le32(core[i]); -} - -static int read_bits(struct log_c *log) -{ - int r; - - if (!log->log_dev) - return 0; - - if (atomic_read(&log->suspended)) - return -EDEADLK; - - r = do_io(log, READ, 0); - - if (unlikely(r)) - return r; - - return 0; -} - -static int write_bits(struct log_c *log) -{ - if (!log->log_dev) - return 0; - - if (atomic_read(&log->suspended)) - return -EDEADLK; - - return do_io(log, WRITE, 0); -} - -static int count_bits32(uint32_t *addr, unsigned size) -{ - int count = 0, i; - - for (i = 0; i < size; i++) { - count += hweight32(*(addr+i)); - } - return count; -} - -static int print_zero_bits(unsigned char *str, int offset, int bit_count){ - int i,j; - int count=0; - int len = bit_count/8 + ((bit_count%8)?1:0); - int region = offset; - int range_count=0; - - for(i = 0; i < len; i++){ - if(str[i] == 0x0){ - region+=(bit_count < 8)? bit_count: 8; - range_count+= (bit_count < 8)? bit_count: 8; - count+=(bit_count < 8)? bit_count: 8; - - bit_count -= (bit_count < 8)? bit_count: 8; - continue; - } else if(str[i] == 0xFF){ - if(range_count==1){ - DMDEBUG(" %d", region - 1); - } else if(range_count){ - DMDEBUG(" %d - %d", region-range_count, region-1); - } - range_count = 0; - region+=(bit_count < 8)? bit_count: 8; - - bit_count -= (bit_count < 8)? bit_count: 8; - continue; - } - for(j=0; j<8; j++){ - if(!bit_count--){ - break; - } - if(!(str[i] & 1<<j)){ - range_count++; - region++; - count++; - } else { - if(range_count==1){ - DMDEBUG(" %d", region - 1); - } else if(range_count){ - DMDEBUG(" %d - %d", region-range_count, region-1); - } - range_count = 0; - region++; - } - } - } - - if(range_count==1){ - DMDEBUG(" %d", region - 1); - } else if(range_count){ - DMDEBUG(" %d - %d", region-range_count, region); - } - return count; -} - -static int disk_resume(struct log_c *lc) -{ - int r; - int good_count=0, bad_count=0; - unsigned i; - size_t size = lc->bitset_uint32_count * sizeof(uint32_t); - struct region_user *tmp_ru, *ru; - unsigned char live_nodes[16]; /* Attention -- max of 128 nodes... */ - - DMDEBUG("Disk Resume:: %s (%s)", lc->uuid + (strlen(lc->uuid) - 8), - atomic_read(&lc->suspended) ? "suspended" : "active"); - - debug_disk_write = 1; - memset(live_nodes, 0, sizeof(live_nodes)); - for(i = 0; i < global_count; i++){ - live_nodes[global_nodeids[i]/8] |= 1 << (global_nodeids[i]%8); - } - - /* read the disk header */ - i = 1; - if (!lc->log_dev_failed && - ((r = read_header(lc)) || (i = 0) || (r = read_bits(lc)))) { - if (r == -EINVAL || r == -EDEADLK) - return r; - - DMWARN("Read %s failed on mirror log device, %s", - i ? "header" : "bits", lc->log_dev->name); - lc->log_dev_failed = 1; - lc->header.nr_regions = 0; - } - - /* set or clear any new bits -- device has grown */ - if (lc->sync == NOSYNC) { - DMDEBUG(" NOSYNC :: set"); - for (i = lc->header.nr_regions; i < lc->region_count; i++) - /* FIXME: amazingly inefficient */ - log_set_bit(lc, lc->clean_bits, i); - } else { - DMDEBUG(" NOSYNC :: unset"); - for (i = lc->header.nr_regions; i < lc->region_count; i++) - /* FIXME: amazingly inefficient */ - log_clear_bit(lc, lc->clean_bits, i); - } - - /* clear any old/unused bits -- device has shrunk */ - for(i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++) - log_clear_bit(lc, lc->clean_bits, i); - - /* copy clean across to sync */ - memcpy(lc->sync_bits, lc->clean_bits, size); - - /* must go through the list twice. The dead node could have been using ** - ** the same region as other nodes and we want any region that was in ** - ** use by the dead node to be marked _not_ in-sync..................... */ - lc->recovering_region = (uint64_t)-1; - list_for_each_entry(ru, &lc->region_users, ru_list){ - if (live_nodes[ru->ru_nodeid/8] & 1 << (ru->ru_nodeid%8)) { - good_count++; - if (ru->ru_rw == RU_WRITE) { - log_set_bit(lc, lc->sync_bits, ru->ru_region); - } else if (ru->ru_rw == RU_RECOVER) { - log_clear_bit(lc, lc->sync_bits, ru->ru_region); - lc->recovering_region = ru->ru_region; - } - } - } - - list_for_each_entry_safe(ru, tmp_ru, &lc->region_users, ru_list){ - if(!(live_nodes[ru->ru_nodeid/8] & 1 << (ru->ru_nodeid%8))){ - bad_count++; - log_clear_bit(lc, lc->sync_bits, ru->ru_region); - if (ru->ru_rw == RU_RECOVER) { - DMINFO("Failed node was recovering region %Lu - cleared", - ru->ru_region); - lc->recovering_region = (uint64_t)-1; - } - list_del(&ru->ru_list); - mempool_free(ru, region_user_pool); - } - } - - DMDEBUG(" Live nodes :: %d", global_count); - DMDEBUG(" In-Use Regions :: %d", good_count+bad_count); - DMDEBUG(" Good IUR's :: %d", good_count); - DMDEBUG(" Bad IUR's :: %d", bad_count); - - lc->sync_count = count_bits32(lc->sync_bits, lc->bitset_uint32_count); - lc->sync_search = 0; - - DMDEBUG(" in_sync :: %d", atomic_read(&lc->in_sync)); - DMDEBUG(" Sync count :: %Lu", lc->sync_count); - DMDEBUG(" Disk Region count :: %Lu", lc->header.nr_regions); - DMDEBUG(" Region count :: %Lu", lc->region_count); - - if (lc->header.nr_regions != lc->region_count) { - DMDEBUG(" NOTE: Mapping has changed."); - } -/* Take this out for now. - if(list_empty(&lc->region_users) && (lc->sync_count != lc->header.nr_regions)){ - struct region_user *new; - - for(sync_search = 0; sync_search < lc->header.nr_regions;){ - region = find_next_zero_bit((unsigned long *)lc->clean_bits, - lc->header.nr_regions, - sync_search); - sync_search = region+1; - if(region < lc->header.nr_regions){ - for(i=0; i < global_count; i++){ - new = kmalloc(sizeof(struct region_user), - GFP_KERNEL); - if(!new){ - DMERR("Unable to allocate space to track region users."); - BUG(); - } - new->ru_nodeid = global_nodeids[i]; - new->ru_region = region; - DMINFO("Adding %u/%Lu", - new->ru_nodeid, new->ru_region); - list_add(&new->ru_list, &lc->region_users); - } - } - } - } - -*/ - DMDEBUG("Marked regions::"); - i = print_zero_bits((unsigned char *)lc->clean_bits, 0, lc->region_count); - DMDEBUG(" Total = %d", i); - - DMDEBUG("Out-of-sync regions::"); - i = print_zero_bits((unsigned char *)lc->sync_bits, 0, lc->region_count); - DMDEBUG(" Total = %d", i); - - /* set the correct number of regions in the header */ - lc->header.nr_regions = lc->region_count; - - i = 1; - if ((r = write_bits(lc)) || (i = 0) || (r = write_header(lc))) { - if (r != -EDEADLK) { - DMWARN("Write %s failed on mirror log device, %s.", - i ? "bits" : "header", lc->log_dev->name); - lc->log_dev_failed = 1; - } - } else - lc->log_dev_failed = 0; - - return r; -} - - -struct region_user *find_ru(struct log_c *lc, uint32_t who, region_t region){ - struct region_user *ru; - list_for_each_entry(ru, &lc->region_users, ru_list){ - if((who == ru->ru_nodeid) && (region == ru->ru_region)){ - return ru; - } - } - return NULL; -} - -struct region_user *find_ru_by_region(struct log_c *lc, region_t region){ - struct region_user *ru; - list_for_each_entry(ru, &lc->region_users, ru_list){ - if(region == ru->ru_region){ - return ru; - } - } - return NULL; -} - - -static int server_is_clean(struct log_c *lc, struct log_request *lr) -{ - lr->u.lr_int_rtn = log_test_bit(lc->clean_bits, lr->u.lr_region); - - return 0; -} - -static int server_is_remote_recovering(struct log_c *lc, struct log_request *lr) -{ - lr->u.lr_int_rtn = 0; - - if ((lc->sync_search > lc->region_count) && !lc->sync_pass) - return 0; - - if (lc->recovery_halted && - (lc->recovering_region != lr->u.lr_region)) { - DMDEBUG("Recovery halted, allowing client: %Lu/%s", - lr->u.lr_region, - lc->uuid + (strlen(lc->uuid) - 8)); - return 0; - } - - /* - * If the region hasn't been recovered yet, - * we need to block the write - */ - if (!log_test_bit(lc->sync_bits, lr->u.lr_region) || - (lc->recovering_region == lr->u.lr_region)) { - lr->u.lr_int_rtn = 1; - - /* Try to make this region a priority */ - if ((lr->u.lr_region != lc->recovering_region) && - ((lc->recovering_next == (uint64_t)-1) || - (lc->recovering_next > lr->u.lr_region))) - lc->recovering_next = lr->u.lr_region; - return 0; - } - - return 0; -} - -static int server_in_sync(struct log_c *lc, struct log_request *lr) -{ - if (lr->u.lr_region > lc->region_count) { - lr->u.lr_int_rtn = 0; - return -EINVAL; - } - - if(likely(log_test_bit(lc->sync_bits, lr->u.lr_region))) - /* in-sync */ - lr->u.lr_int_rtn = 1; - else - lr->u.lr_int_rtn = 0; - - return 0; -} - - -static int server_mark_region(struct log_c *lc, struct log_request *lr, uint32_t who) -{ - struct region_user *ru, *new; - - new = mempool_alloc(region_user_pool, GFP_NOFS); - if(!new){ - return -ENOMEM; - } - - new->ru_nodeid = who; - new->ru_region = lr->u.lr_region; - new->ru_rw = RU_WRITE; - - if (find_ru(lc, who, lr->u.lr_region)) { - DMWARN("Attempt to mark a already marked region (%u," - SECTOR_FORMAT - "/%s)", - who, lr->u.lr_region, lc->uuid + (strlen(lc->uuid) - 8)); - mempool_free(new, region_user_pool); - } else if (!(ru = find_ru_by_region(lc, lr->u.lr_region))) { - log_clear_bit(lc, lc->clean_bits, lr->u.lr_region); - list_add(&new->ru_list, &lc->region_users); - } else if (ru->ru_rw == RU_RECOVER) { - /* - * A mark that happens to a region in recovery - * means certain corruption. - */ - DMERR("Mark attempted to recovering region by %u: %Lu/%s", - who, lr->u.lr_region, - lc->uuid + (strlen(lc->uuid) - 8)); - DMERR(" region_user { rw=%s, nodeid=%u, region=%Lu }", - (ru->ru_rw == RU_WRITE) ? "RU_WRITE": - (ru->ru_rw == RU_RECOVER) ? "RU_RECOVER": - (ru->ru_rw == RU_READ) ? "RU_READ" : "UNKOWN", - ru->ru_nodeid, ru->ru_region); - DMERR(" lc->recovering_region = %Lu", lc->recovering_region); - DMERR(" lc->sync_count = %Lu", lc->sync_count); - DMERR(" lc->in_sync = %d", atomic_read(&lc->in_sync)); - DMERR(" lc->sync_pass = %d", lc->sync_pass); - DMERR(" lc->sync_search = %d", lc->sync_search); - DMERR(" lc->recovery_halted = %d -> 1", lc->recovery_halted); - - lc->recovery_halted = 1; - mempool_free(new, region_user_pool); - return -EAGAIN; - } else { - list_add(&new->ru_list, &ru->ru_list); - } - - return 0; -} - - -static int server_clear_region(struct log_c *lc, struct log_request *lr, uint32_t who) -{ - int check_bug = 0; - struct region_user *ru; - - ru = find_ru(lc, who, lr->u.lr_region); - if(!ru){ - DMDEBUG("Request to remove unrecorded region user (%u/%Lu)", - who, lr->u.lr_region); - return -EINVAL; - } else { - if (lc->recovering_region == lr->u.lr_region) { - lc->recovering_region = (uint64_t)-1; - check_bug = 1; - } - list_del(&ru->ru_list); - mempool_free(ru, region_user_pool); - } - - if (!find_ru_by_region(lc, lr->u.lr_region)) { - /* Only clear the region if it is also in sync */ - if (log_test_bit(lc->sync_bits, lr->u.lr_region)) - log_set_bit(lc, lc->clean_bits, lr->u.lr_region); - } else if (check_bug) { - DMERR("Multiple marks exist on a region being recovered: %Lu/%s", - lr->u.lr_region, lc->uuid + (strlen(lc->uuid) - 8)); - BUG(); - } - - return 0; -} - - -static int server_flush(struct log_c *lc, uint32_t who) -{ - int r = 0; - struct region_user *ru; - - if (lc->recovering_region != (uint64_t)-1) { - list_for_each_entry(ru, &lc->region_users, ru_list) { - if ((ru->ru_region == lc->recovering_region) && - (ru->ru_rw != RU_RECOVER)) { - DMERR("Flush attempted to recovering region by %u: %Lu/%s", - who, lc->recovering_region, - lc->uuid + (strlen(lc->uuid) - 8)); - BUG(); - } - } - } - - r = write_bits(lc); - if (!r) { - lc->touched = 0; - lc->log_dev_failed = 0; - } else { - lc->log_dev_failed = 1; - } - - return (lc->log_dev_failed) ? -EIO : 0; -} - - -static int server_get_resync_work(struct log_c *lc, struct log_request *lr, uint32_t who) -{ - struct region_user *new, *test; - region_t *region = &(lr->u.lr_region_rtn); - region_t sync_search = lc->sync_search; - - lr->u.lr_int_rtn = 0; /* Default to no work */ - - if (lc->recovery_halted) { - DMDEBUG("Recovery halted due to error on %s", - lc->uuid + (strlen(lc->uuid) - 8)); - return 0; - } - - if (lc->recovering_region != (uint64_t)-1) { - DMDEBUG("Someone is already recovering region %Lu/%s", - lc->recovering_region, lc->uuid + (strlen(lc->uuid) - 8)); - return 0; - } - - if (lc->sync_search >= lc->region_count) { - /* - * FIXME: pvmove is not supported yet, but when it is, - * an audit of sync_count changes will need to be made - */ - if ((lc->sync_count < lc->region_count) && !lc->sync_pass) { - lc->sync_search = 0; - lc->sync_pass++; - } else { - return 0; - } - } - - if ((lc->recovering_next != (uint64_t)-1) && - (!log_test_bit(lc->sync_bits, lc->recovering_next))) { - *region = lc->recovering_next; - DMDEBUG("Preempting normal recovery work for preferred region..."); - } else { - *region = ext2_find_next_zero_bit((unsigned long *) lc->sync_bits, - lc->region_count, - lc->sync_search); - sync_search = *region + 1; - } - - if ((test = find_ru_by_region(lc, *region))) { - /* - * We disallow writes to regions that have not yet been - * recovered via is_remote_recovering(), so this should - * not happen. - */ - DMERR("Recovery blocked by outstanding write on region %Lu/%s", - *region, lc->uuid + (strlen(lc->uuid) - 8)); - DMERR(" region_user { %s, %u, %Lu }", - (test->ru_rw == RU_WRITE) ? "RU_WRITE": - (test->ru_rw == RU_RECOVER) ? "RU_RECOVER": - (test->ru_rw == RU_READ) ? "RU_READ" : "UNKOWN", - test->ru_nodeid, test->ru_region); - DMERR(" lc->recovering_region = %Lu", lc->recovering_region); - DMERR(" lc->sync_count = %Lu", lc->sync_count); - DMERR(" lc->in_sync = %d", atomic_read(&lc->in_sync)); - DMERR(" lc->sync_pass = %d", lc->sync_pass); - DMERR(" lc->sync_search = %d", lc->sync_search); - DMERR(" lc->recovery_halted = %d -> 1", lc->recovery_halted); - - lc->recovery_halted = 1; - return 0; - } - - if (*region >= lc->region_count) - return 0; - - new = mempool_alloc(region_user_pool, GFP_NOFS); - if (!new) - return -ENOMEM; - - lc->sync_search = sync_search; - lc->recovering_region = *region; - lc->recovering_next = (uint64_t)-1; - lr->u.lr_int_rtn = 1; /* Assigning work */ - new->ru_nodeid = who; - new->ru_region = *region; - new->ru_rw = RU_RECOVER; - list_add(&new->ru_list, &lc->region_users); - DMDEBUG("Assigning recovery work to %u: %Lu/%s", - who, new->ru_region, lc->uuid + (strlen(lc->uuid) - 8)); - - return 0; -} - -static int server_complete_resync_work(struct log_c *lc, struct log_request *lr, - int success, uint32_t who){ - struct region_user *ru; - - if (lr->u.lr_region > lc->region_count) { - return -EINVAL; - } - - if (success) { - if (lr->u.lr_region != lc->recovering_region) { - DMERR("Told to clear recovery on wrong region %Lu/%Lu", - lr->u.lr_region, lc->recovering_region); - return -EINVAL; - } - - /* We could receive multiple identical request due to network failure */ - if (!log_test_bit(lc->sync_bits, lr->u.lr_region)) { - log_set_bit(lc, lc->sync_bits, lr->u.lr_region); - lc->sync_count++; - } - - /* - * We will: - * lc->recovering_region = (uint64_t)-1; - * in clear_region so we can do extra validation - */ - - lc->sync_pass = 0; - - DMDEBUG("Resync work completed by %u: %Lu/%s", - who, lr->u.lr_region, lc->uuid + (strlen(lc->uuid) - 8)); - return 0; - } - - /* - * Recovery failed or mirror is being marked out-of-sync - * - * We need to stop dishing out recovery work. If we don't - * writes happening to NOSYNC regions can't proceed and the - * mirror won't be able to suspend for reconfiguration - due - * to the return of is_remote_recovering(). - * - * We can recieve multiple calls to mark out-of-sync - * if there were several writes to the same region that - * failed. In this case, there will not be a record for - * the region. - */ - if (!lc->recovery_halted) { - DMDEBUG("server_complete_resync_work - Setting recovery_halted = 1"); - lc->recovery_halted = 1; - } - - ru = find_ru(lc, who, lr->u.lr_region); - - if ((lr->u.lr_region == lc->recovering_region) && !ru) { - DMERR("Unable to locate record of recovery"); - BUG(); - } - - if (!ru) { - DMDEBUG("Unable to find region to be marked out-of-sync: %Lu/%s/%u", - lr->u.lr_region, lc->uuid + (strlen(lc->uuid) - 8), who); - /* - * This is a valid case, when the following happens: - * 1) a region is recovering and has waiting writes - * 2) recovery fails and calls complete_resync_work (w/ failure) - * 2.1) RU is removed from our list - * 3) waiting writes are released - * 3.1) writes do not mark, because b/c region state != RH_CLEAN - * 4) write fails and calls complete_resync_work (w/ failure) - * 5) boom, we are here. - * - * Not a bug to be here - */ - } else if (ru->ru_rw == RU_RECOVER) { - if (lr->u.lr_region != lc->recovering_region) { - DMERR("Recovering region mismatch from node %u: (%Lu/%Lu)", - who, lr->u.lr_region, lc->recovering_region); - BUG(); - } - /* - * Clear the recovery - */ - DMDEBUG("Setting recovering region out-of-sync: %Lu/%s/%u", - lr->u.lr_region, lc->uuid + (strlen(lc->uuid) - 8), who); - lc->recovering_region = (uint64_t)-1; - list_del(&ru->ru_list); - mempool_free(ru, region_user_pool); - } - - /* else if (ru->ru_rw == RU_WRITE) - * Mirror has place the region into RH_NOSYNC - * We will leave the record in place. It is - * likely there are more requests coming to - * mark this region out-of-sync, due to the - * way mirror handles the situation. - * - DMDEBUG("Setting marked region out-of-sync: %Lu/%s", - lr->u.lr_region, lc->uuid + (strlen(lc->uuid) - 8)); - */ - - /* gone again: lc->sync_count--;*/ - log_clear_bit(lc, lc->sync_bits, lr->u.lr_region); - - return 0; -} - -static int server_get_sync_count(struct log_c *lc, struct log_request *lr){ - if (lc->sync_count > lc->region_count) { - DMERR("sync_count (" SECTOR_FORMAT ") > region_count (" SECTOR_FORMAT ") in %s!", - lc->sync_count, lc->region_count, lc->uuid + (strlen(lc->uuid) - 8)); - disk_resume(lc); - } - - lr->u.lr_region_rtn = lc->sync_count; - return 0; -} - -static void report_duplicate_log(struct log_c *lc) -{ - DMERR("HEY!!! There are two matches for %s", - lc->uuid + (strlen(lc->uuid) - 8)); - list_for_each_entry(lc, &log_list_head, log_list) { - DMERR(" %s", lc->uuid + (strlen(lc->uuid) - 8)); - } -} - -static struct log_c *get_log_context(char *uuid, int uuid_ref){ - struct log_c *lc, *r = NULL; - - down(&log_list_lock); - list_for_each_entry(lc, &log_list_head, log_list){ - if (!strncmp(lc->uuid, uuid, MAX_NAME_LEN) && - (uuid_ref == lc->uuid_ref)) { - if (r) - report_duplicate_log(lc); - else - r = lc; - } - } - up(&log_list_lock); - - return r; -} - - -static int process_election(struct log_request *lr, struct log_c *lc, - struct sockaddr_in *saddr){ - int i; - uint32_t lowest, next; - uint32_t node_count=global_count, *nodeids=global_nodeids; - - DMDEBUG("%s(%d): (%s)", RQ_STRING(lr->lr_type), lr->lr_type, - (lc) ? lc->uuid + (strlen(lc->uuid) - 8) : "none"); - DMDEBUG(" starter : %u", lr->u.lr_starter); - DMDEBUG(" co-ordinator: %u", lr->u.lr_coordinator); - DMDEBUG(" node_count : %d", lr->u.lr_node_count); - - /* Record the starter's port number so we can get back to him */ - if((lr->u.lr_starter == my_id) && (!lr->u.lr_node_count)){ - lr->u.lr_starter_port = saddr->sin_port; - } - - /* Find the next node id in the circle */ - for(lowest = my_id, next = my_id, i=0; i < node_count; i++){ - if(lowest > nodeids[i]){ - lowest = nodeids[i]; - } - if(((next == my_id) || (next > nodeids[i])) && - (nodeids[i] > my_id)){ - next = nodeids[i]; - } - } - - /* Set address to point to next node in the circle */ - next = (next == my_id)? lowest: next; - saddr->sin_port = CLUSTER_LOG_PORT; - if(!(saddr->sin_addr.s_addr = nodeid_to_ipaddr(next))){ - return -1; - } - - if(lr->lr_type == LRT_MASTER_LEAVING) { - /* - * if we started this and (lr->u.lr_node_count != 0), - * then we have told everyone that we are leaving - */ - if ((lr->u.lr_starter == my_id) && lr->u.lr_node_count){ - lr->u.lr_coordinator = 0xDEAD; - if(!(saddr->sin_addr.s_addr = nodeid_to_ipaddr(lr->u.lr_starter))){ - return -1; - } - saddr->sin_port = lr->u.lr_starter_port; - return 0; - } - } - - /* - * Check if we have access to the log. We may not - * yet have loaded this device. - */ - if (!lc) { - lr->u.lr_node_count++; - return 0; - } - - if(lr->lr_type == LRT_MASTER_LEAVING){ - if (lr->u.lr_starter == lc->server_id) - lc->server_id = 0xDEAD; - lr->u.lr_node_count++; - return 0; - } - - /* - * New node joins and needs to know I am the server - * We shortcut the election here and respond directly - * to the inquirer - * - if((lc->server_id == my_id) && !atomic_read(&lc->suspended)){ - */ - if (lc->server_id == my_id) { - int r = atomic_read(&lc->suspended); - - if (r >= 2) { - DMDEBUG("I am the assigned server while suspended: %s", - lc->uuid + (strlen(lc->uuid) - 8)); - lc->server_id = 0xDEAD; - lr->u.lr_node_count++; - return 0; - } - - if (r == 1) - DMDEBUG("I'm suspended, but still responding as server: %s", - lc->uuid + (strlen(lc->uuid) - 8)); - lr->u.lr_coordinator = my_id; - if(!(saddr->sin_addr.s_addr = nodeid_to_ipaddr(lr->u.lr_starter))){ - return -1; - } - saddr->sin_port = lr->u.lr_starter_port; - return 0; - } - - if(lr->lr_type == LRT_ELECTION){ - if((lr->u.lr_starter == my_id) && (lr->u.lr_node_count)){ - /* - * We started this election, and we've been - * around the loop. If the node count hasn't - * changed since we started, we can proceed to - * selection. Otherwise, go again setting - * ourself as the leader to start. - */ - if(node_count == lr->u.lr_node_count){ - lr->lr_type = LRT_SELECTION; - } else { - lr->u.lr_coordinator = my_id; - } - lr->u.lr_node_count = 1; - return 0; - } - - /* - * We are in the election phase, so - * if we have the lowest ID so far, - * we elect ourselves for server. - * - * However, if the mirror is being suspended - * (lc->suspended), then we leave the current - * coordinator in place. - * - * The client must not set lc->suspended until - * it has completed sending all requests. That - * way, everyone is done sending requests when - * the last server is stuck holding the ball. - */ - lr->u.lr_node_count++; - - if((my_id < lr->u.lr_coordinator) && !atomic_read(&lc->suspended)){ - lr->u.lr_coordinator = my_id; - } - return 0; - } else if(lr->lr_type == LRT_SELECTION){ - if(lr->u.lr_starter != my_id){ - lr->u.lr_node_count++; - return 0; - } - - /* - * Need to restart election if someone - * has joined since we started. - * - * Here, we are the started, so set - * node_count = 1 - */ - if(lr->u.lr_node_count == node_count){ - lr->lr_type = LRT_MASTER_ASSIGN; - } else { - lr->lr_type = LRT_ELECTION; - lr->u.lr_coordinator = my_id; - return 0; - } - lr->u.lr_node_count = 1; - } else if(lr->lr_type == LRT_MASTER_ASSIGN){ - /* - * If we are the server, assign it - */ - if(lr->u.lr_coordinator == my_id){ - lc->server_valid = 0; - lc->server_id = my_id; - } - - /* - * Continue around the loop - */ - if(lr->u.lr_starter != my_id){ - return 0; - } - - /* - * If I was the one who asked for the election, - * the send the results back to the client - */ - if(!(saddr->sin_addr.s_addr = nodeid_to_ipaddr(lr->u.lr_starter))){ - return -1; - } - saddr->sin_port = lr->u.lr_starter_port; - lc->server_id = lr->u.lr_coordinator; - } - return 0; -} - - -/** - * process_log_request - * @sock - the socket to receive requests on - * - * This function receives a region request for a specific - * mirror set/region. ATTENTION -- fill rest of desc. - * - * Returns: 0 on success, -1 on error - */ -static int process_log_request(struct socket *sock){ - static struct log_request *lr = NULL; - int error; - uint32_t nodeid; - struct msghdr msg; - struct iovec iov; - struct sockaddr_in saddr_in; - mm_segment_t fs; - struct log_c *lc; - - if (unlikely(!lr)) - lr = kmalloc(sizeof(*lr), GFP_KERNEL); - if (!lr) - return -1; - - memset(lr, 0, sizeof(struct log_request)); - memset(&saddr_in, 0, sizeof(saddr_in)); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = &iov; - msg.msg_flags = 0; - msg.msg_name = &saddr_in; - msg.msg_namelen = sizeof(saddr_in); - iov.iov_len = sizeof(struct log_request); - iov.iov_base = lr; - - fs = get_fs(); - set_fs(get_ds()); - - error = my_recvmsg(sock, &msg, sizeof(struct log_request), - 0, 5); - set_fs(fs); - - if(error > 0){ - if(error < sizeof(struct log_request)){ - DMERR("Cluster mirror log server received incomplete message."); - } - lc = get_log_context(lr->lr_uuid, lr->lr_uuid_ref); - - if(lr->lr_type == LRT_ELECTION || - lr->lr_type == LRT_SELECTION || - lr->lr_type == LRT_MASTER_ASSIGN || - lr->lr_type == LRT_MASTER_LEAVING){ - uint32_t old = (lc)?lc->server_id: 0xDEAD; - if(process_election(lr, lc, &saddr_in)){ - DMERR("Election processing failed."); - return -1; - } - if(lc && (old != lc->server_id) && (my_id == lc->server_id)){ - DMDEBUG("I'm the cluster mirror log server for %s", - lc->uuid + (strlen(lc->uuid) - 8)); - if (atomic_read(&lc->suspended)) { - DMDEBUG("Not reading disk log because I'm suspended (%s)", - lc->uuid + (strlen(lc->uuid) - 8)); - - } else if (disk_resume(lc) == -EDEADLK) { - DMDEBUG("Unable to read disk log - deadlock potential."); - } - } - goto reply; - } - - if(!lc){ - lr->u.lr_int_rtn = -ENXIO; - goto reply; - } - - if (lc->server_id != my_id) { - lr->u.lr_int_rtn = -ENXIO; - goto reply; - } - - if (atomic_read(&lc->suspended)) { - nodeid = ipaddr_to_nodeid((struct sockaddr *)msg.msg_name); - /* - DMDEBUG("Getting request while server (%u) is suspended:", my_id); - DMDEBUG(" - Requester :: %u", nodeid); - DMDEBUG(" - log uuid :: %s", lc->uuid + (strlen(lc->uuid) - 8)); - DMDEBUG(" - req type :: %s", RQ_STRING(lr->lr_type)); - */ - if (my_id != nodeid) { - lr->u.lr_int_rtn = -ENXIO; - goto reply; - } - } - - switch(lr->lr_type){ - case LRT_IS_CLEAN: - error = server_is_clean(lc, lr); - break; - case LRT_IS_REMOTE_RECOVERING: - error = server_is_remote_recovering(lc, lr); - break; - case LRT_IN_SYNC: - error = server_in_sync(lc, lr); - break; - case LRT_MARK_REGION: - if(!(nodeid = - ipaddr_to_nodeid((struct sockaddr *)msg.msg_name))){ - error = -ENXIO; - break; - } - error = server_mark_region(lc, lr, nodeid); - lr->u.lr_int_rtn = 0; - break; - case LRT_CLEAR_REGION: - if(!(nodeid = - ipaddr_to_nodeid((struct sockaddr *)msg.msg_name))){ - error = -ENXIO; - break; - } - error = server_clear_region(lc, lr, nodeid); - break; - case LRT_FLUSH: - if(!(nodeid = - ipaddr_to_nodeid((struct sockaddr *)msg.msg_name))){ - error = -ENXIO; - break; - } - error = server_flush(lc, nodeid); - break; - case LRT_GET_RESYNC_WORK: - if(!(nodeid = - ipaddr_to_nodeid((struct sockaddr *)msg.msg_name))){ - error = -ENXIO; - break; - } - error = server_get_resync_work(lc, lr, nodeid); - break; - case LRT_COMPLETE_RESYNC_WORK: - if(!(nodeid = - ipaddr_to_nodeid((struct sockaddr *)msg.msg_name))){ - error = -ENXIO; - break; - } - error = server_complete_resync_work(lc, lr, lr->u.lr_int_rtn, nodeid); - lr->u.lr_int_rtn = 0; - break; - case LRT_GET_SYNC_COUNT: - error = server_get_sync_count(lc, lr); - break; - default: - DMWARN("unknown request type received"); - return 0; /* do not send a reply */ - break; - } - - /* ATTENTION -- if error? */ - if(error){ -/* - DMWARN("Error (%d) while processing request (%s)", - error, RQ_STRING(lr->lr_type)); -*/ - lr->u.lr_int_rtn = error; - } - reply: - - /* Why do we need to reset this? */ - iov.iov_len = sizeof(struct log_request); - iov.iov_base = lr; - msg.msg_name = &saddr_in; - msg.msg_namelen = sizeof(saddr_in); - - fs = get_fs(); - set_fs(get_ds()); - - error = sock_sendmsg(sock, &msg, sizeof(struct log_request)); - - set_fs(fs); - if(error < 0){ - DMWARN("unable to sendmsg to client (type = %s, error = %d)", - RQ_STRING(lr->lr_type), error); - return error; - } - } else if(error == -EAGAIN || error == -ETIMEDOUT){ - return 0; - } else { - /* ATTENTION -- what do we do with this ? */ - return error; - } - return 0; -} - -static int cluster_log_serverd(void *data){ - int error; - struct log_c *lc; - struct sockaddr_in saddr_in; - struct socket *sock; - - /* read the disk logs */ - - daemonize("cluster_log_serverd"); - - error = sock_create(AF_INET, SOCK_DGRAM, - 0, - &sock); - if(error < 0){ - DMWARN("failed to create cluster mirror log server socket."); - goto fail1; - } - - memset(&saddr_in, 0, sizeof(struct sockaddr_cl)); - saddr_in.sin_family = AF_INET; - saddr_in.sin_port = CLUSTER_LOG_PORT; - error = sock->ops->bind(sock, (struct sockaddr *)&saddr_in, - sizeof(saddr_in)); - - if(error < 0){ - DMWARN("failed to bind cluster mirror log server socket."); - goto fail2; - } - - complete(&server_completion); - - DMDEBUG("cluster_log_serverd ready for work"); - for(;;){ - if(!atomic_read(&server_run)){ - break; - } - - switch(atomic_read(&restart_event_type)){ - case SERVICE_NODE_LEAVE: - /* ATTENTION -- may wish to check if regions ** - ** are still in use by this node. For now, ** - ** we do the same as if the node failed. If ** - ** there are no region still in-use by the ** - ** leaving node, it won't hurt anything - and** - ** if there is, they will be recovered. */ - case SERVICE_NODE_FAILED: - if (atomic_read(&restart_event_type) == SERVICE_NODE_FAILED) - DMINFO("A cluster mirror log member has failed."); - - down(&log_list_lock); - list_for_each_entry(lc, &log_list_head, log_list){ - if(lc->server_id == my_id){ - if (atomic_read(&lc->suspended)) { - DMDEBUG("Not reading disk log because I'm suspended."); - } else if (disk_resume(lc) == -EDEADLK) { - DMDEBUG("Unable to read disk log - deadlock potential."); - } - } - } - up(&log_list_lock); - - break; - case SERVICE_NODE_JOIN: - DMDEBUG("Node joining"); - break; - default: - /* Someone has joined, or there is no event */ - break; - } - - - if(atomic_read(&restart_event_type)){ - /* finish the start phase */ - kcl_start_done(local_id, restart_event_id); - restart_event_id = 0; - - /* Trigger any waiting starts to proceed */ - atomic_set(&restart_event_type, 0); - } else if (atomic_read(&_do_requests)) { - /* ATTENTION -- what to do with error ? */ - if(process_log_request(sock)) - DMINFO("process_log_request:: failed"); - } - schedule(); - } - - DMDEBUG("Closing socket on server side"); - sock_release(sock); - complete(&server_completion); - return 0; - - fail2: - sock_release(sock); - fail1: - DMWARN("Server thread failed to start"); - atomic_set(&server_run, 0); - complete(&server_completion); - return error; -} - -/* -void print_server_status(struct log_c *lc){ - int i; - - DMINFO("SERVER OUTPUT::"); - - DMINFO(" Live nodes :: %d", global_count); - DMINFO(" Sync count :: %Lu", lc->sync_count); - DMINFO(" Disk Region count :: %Lu", lc->header.nr_regions); - DMINFO(" Region count :: %Lu", lc->region_count); - DMINFO(" nr_regions :: %Lu", lc->header.nr_regions); - DMINFO(" region_count :: %Lu", lc->region_count); - - if(lc->header.nr_regions != lc->region_count){ - DMINFO(" NOTE: Mapping has changed."); - } - - DMINFO("Marked regions::"); - i = print_zero_bits((unsigned char *)lc->clean_bits, 0, lc->bitset_uint32_count); - DMINFO(" Total = %d", i); - - DMINFO("Out-of-sync regions::"); - i = print_zero_bits((unsigned char *)lc->sync_bits, 0, lc->bitset_uint32_count); - DMINFO(" Total = %d", i); - -} -*/ - -int server_busy(struct log_c *lc) -{ - if (!list_empty(&lc->region_users) || - (lc->recovering_region != (uint64_t)-1)) - return 1; - else - return 0; -} - -int server_free_region_users(struct log_c *lc) -{ - int i = 0; - struct region_user *ru, *tmp_ru; - - list_for_each_entry_safe(ru, tmp_ru, &lc->region_users, ru_list) { - i++; - list_del(&ru->ru_list); - mempool_free(ru, region_user_pool); - } - - DMDEBUG("%d region user structures freed", i); - return 0; -} - -int resume_server_requests(void) { - atomic_set(&_do_requests, 1); - return 0; -} - -int start_server(void /* log_devices ? */){ - int error; - - DMDEBUG("start_server called"); - region_user_pool = mempool_create(1000, region_user_alloc, - region_user_free, NULL); - if(!region_user_pool){ - DMWARN("unable to allocate region user pool for server"); - return -ENOMEM; - } - - atomic_set(&_do_requests, 0); - atomic_set(&server_run, 1); - init_completion(&server_completion); - - error = kernel_thread(cluster_log_serverd, NULL, 0); - if(error < 0){ - mempool_destroy(region_user_pool); - DMWARN("failed to start kernel thread."); - return error; - } - wait_for_completion(&server_completion); - - if(!atomic_read(&server_run)){ - mempool_destroy(region_user_pool); - DMWARN("Cluster mirror log server thread failed to start"); - return -1; - } - dm_io_get(32); - return 0; -} - - -void stop_server(void){ - DMDEBUG("stop_server called"); - atomic_set(&server_run, 0); - - wait_for_completion(&server_completion); - down(&log_list_lock); - if (!list_empty(&log_list_head)) { - DMERR("Log elements remain at cluster log server shutdown"); - } - up(&log_list_lock); - mempool_destroy(region_user_pool); - - dm_io_put(32); -} -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/cmirror-kernel/src/dm-cmirror-server.h b/cmirror-kernel/src/dm-cmirror-server.h deleted file mode 100644 index fc43423..0000000 --- a/cmirror-kernel/src/dm-cmirror-server.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#ifndef __DM_CMIRROR_SERVER_H__ -#define __DM_CMIRROR_SERVER_H__ - -int server_busy(struct log_c *lc); -int resume_server(void); -int resume_server_requests(void); -int start_server(void); -void stop_server(void); -void print_server_status(struct log_c *lc); -int server_free_region_users(struct log_c *lc); - -#endif /* __DM_CMIRROR_SERVER_H__ */ diff --git a/cmirror-kernel/src/dm-cmirror-xfr.c b/cmirror-kernel/src/dm-cmirror-xfr.c deleted file mode 100644 index 75148d4..0000000 --- a/cmirror-kernel/src/dm-cmirror-xfr.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#include <linux/module.h> -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <linux/timer.h> -#include <linux/signal.h> - - -static void set_sigusr1(unsigned long arg){ - struct task_struct *tsk = (struct task_struct *)arg; - send_sig(SIGUSR1, tsk, 0); -} - -int my_recvmsg(struct socket *sock, struct msghdr *msg, - size_t size, int flags, int time_out){ - int rtn; - unsigned long sig_flags; - sigset_t blocked_save; - struct timer_list timer = TIMER_INITIALIZER(set_sigusr1, - jiffies+(time_out*HZ), - (unsigned long)current); - - spin_lock_irqsave(¤t->sighand->siglock, sig_flags); - blocked_save = current->blocked; - sigdelsetmask(¤t->blocked, sigmask(SIGUSR1)); - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, sig_flags); - - add_timer(&timer); - rtn = sock_recvmsg(sock, msg, size, flags); - del_timer(&timer); - - /* flush after recalc? Redo this function. */ - spin_lock_irqsave(¤t->sighand->siglock, sig_flags); - current->blocked = blocked_save; - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, sig_flags); - flush_signals(current); - - if(rtn < 0){ - return -ETIMEDOUT; /* perhaps not the best error number */ - } - return rtn; -} diff --git a/cmirror-kernel/src/dm-cmirror-xfr.h b/cmirror-kernel/src/dm-cmirror-xfr.h deleted file mode 100644 index c8452e2..0000000 --- a/cmirror-kernel/src/dm-cmirror-xfr.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2005 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#ifndef __DM_CMIRROR_XFR_H__ -#define __DM_CMIRROR_XFR_H__ - -#define MAX_NAME_LEN 128 - -#define LRT_IS_CLEAN 1 -#define LRT_IS_REMOTE_RECOVERING 2 -#define LRT_IN_SYNC 3 -#define LRT_MARK_REGION 4 -#define LRT_CLEAR_REGION 5 -#define LRT_FLUSH 6 -#define LRT_GET_RESYNC_WORK 7 -#define LRT_COMPLETE_RESYNC_WORK 8 -#define LRT_GET_SYNC_COUNT 9 - -#define LRT_ELECTION 10 -#define LRT_SELECTION 11 -#define LRT_MASTER_ASSIGN 12 -#define LRT_MASTER_LEAVING 13 - -#define CLUSTER_LOG_PORT 51005 - -#define RQ_STRING(x) \ - ((x) == LRT_IS_CLEAN) ? "LRT_IS_CLEAN": \ - ((x) == LRT_IN_SYNC) ? "LRT_IN_SYNC": \ - ((x) == LRT_MARK_REGION) ? "LRT_MARK_REGION": \ - ((x) == LRT_CLEAR_REGION) ? "LRT_CLEAR_REGION": \ - ((x) == LRT_FLUSH) ? "LRT_FLUSH": \ - ((x) == LRT_GET_RESYNC_WORK) ? "LRT_GET_RESYNC_WORK": \ - ((x) == LRT_COMPLETE_RESYNC_WORK) ? "LRT_COMPLETE_RESYNC_WORK": \ - ((x) == LRT_GET_SYNC_COUNT) ? "LRT_GET_SYNC_COUNT": \ - ((x) == LRT_ELECTION) ? "LRT_ELECTION": \ - ((x) == LRT_SELECTION) ? "LRT_SELECTION": \ - ((x) == LRT_MASTER_ASSIGN) ? "LRT_MASTER_ASSIGN": \ - ((x) == LRT_MASTER_LEAVING) ? "LRT_MASTER_LEAVING" : "UNKNOWN" - -struct log_request { - int lr_type; - int lr_seq; - union { - struct { - uint32_t lr_starter; - int lr_starter_port; - uint32_t lr_node_count; - uint32_t lr_coordinator; - }; - struct { - int lr_int_rtn; /* use this if int return */ - region_t lr_region_rtn; /* use this if region_t return */ - sector_t lr_region; - }; - } u; - char lr_uuid[MAX_NAME_LEN]; - int lr_uuid_ref; -}; - -int my_recvmsg(struct socket *sock, struct msghdr *msg, - size_t size, int flags, int time_out); - -#endif /* __DM_CMIRROR_XFR_H__ */ diff --git a/cmirror-kernel/src/dm-log.h b/cmirror-kernel/src/dm-log.h deleted file mode 100644 index f7ef7d3..0000000 --- a/cmirror-kernel/src/dm-log.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2003 Sistina Software - * - * This file is released under the LGPL. - */ - -#ifndef DM_DIRTY_LOG -#define DM_DIRTY_LOG - -/* - * Values returned by get_failure_response() - * FR_NONBLOCK: ignore device failures - * FR_BLOCK: issue dm event, and do not complete - * I/O until presuspend is recieved. - */ -#define FR_NONBLOCK 0 -#define FR_BLOCK 1 - -typedef sector_t region_t; - -struct dirty_log_type; - -struct dirty_log { - struct dirty_log_type *type; - void *context; -}; - -struct dirty_log_type { - struct list_head list; - const char *name; - struct module *module; - unsigned int use_count; - - int (*ctr)(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv); - void (*dtr)(struct dirty_log *log); - - /* - * There are times when we don't want the log to touch - * the disk. - */ - int (*presuspend)(struct dirty_log *log); - int (*postsuspend)(struct dirty_log *log); - int (*resume)(struct dirty_log *log); - - /* - * Retrieves the smallest size of region that the log can - * deal with. - */ - uint32_t (*get_region_size)(struct dirty_log *log); - - /* - * A predicate to say whether a region is clean or not. - * May block. - */ - int (*is_clean)(struct dirty_log *log, region_t region); - - /* - * Returns: 0, 1 - * - * This is necessary for cluster mirroring. It provides - * a way to detect recovery on another node, so we - * aren't writing concurrently. This function is likely - * to block (when a cluster log is used). - */ - int (*is_remote_recovering)(struct dirty_log *log, region_t region); - - /* - * Returns: 0, 1, -EWOULDBLOCK, < 0 - * - * A predicate function to check the area given by - * [sector, sector + len) is in sync. - * - * If -EWOULDBLOCK is returned the state of the region is - * unknown, typically this will result in a read being - * passed to a daemon to deal with, since a daemon is - * allowed to block. - */ - int (*in_sync)(struct dirty_log *log, region_t region, int can_block); - - /* - * Flush the current log state (eg, to disk). This - * function may block. - */ - int (*flush)(struct dirty_log *log); - - /* - * Mark an area as clean or dirty. These functions may - * block, though for performance reasons blocking should - * be extremely rare (eg, allocating another chunk of - * memory for some reason). - */ - void (*mark_region)(struct dirty_log *log, region_t region); - void (*clear_region)(struct dirty_log *log, region_t region); - - /* - * Returns: <0 (error), 0 (no region), 1 (region) - * - * The mirrord will need perform recovery on regions of - * the mirror that are in the NOSYNC state. This - * function asks the log to tell the caller about the - * next region that this machine should recover. - * - * Do not confuse this function with 'in_sync()', one - * tells you if an area is synchronised, the other - * assigns recovery work. - */ - int (*get_resync_work)(struct dirty_log *log, region_t *region); - - /* - * This notifies the log that the resync of an area has - * been completed. The log should then mark this region - * as CLEAN. - */ - void (*complete_resync_work)(struct dirty_log *log, - region_t region, int success); - - /* - * Returns the number of regions that are in sync. - */ - region_t (*get_sync_count)(struct dirty_log *log); - - /* - * Support function for mirror status requests. - */ - int (*status)(struct dirty_log *log, status_type_t status_type, - char *result, unsigned int maxlen); - - /* - * Return the code describing what to do in the event - * of a device failure. - */ - int (*get_failure_response)(struct dirty_log *log); -}; - -int dm_register_dirty_log_type(struct dirty_log_type *type); -int dm_unregister_dirty_log_type(struct dirty_log_type *type); - - -/* - * Make sure you use these two functions, rather than calling - * type->constructor/destructor() directly. - */ -struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, - unsigned int argc, char **argv); -void dm_destroy_dirty_log(struct dirty_log *log); - -/* - * init/exit functions. - */ -int dm_dirty_log_init(void); -void dm_dirty_log_exit(void); - -#endif diff --git a/configure b/configure deleted file mode 100755 index fa65068..0000000 --- a/configure +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -echo "configure cman-kernel" -(cd cman-kernel && ./configure $@) - -echo "configure dlm-kernel" -(cd dlm-kernel && ./configure $@) - -echo "configure gfs-kernel" -(cd gfs-kernel && ./configure $@) - -echo "configure gnbd-kernel" -(cd gnbd-kernel && ./configure $@) - -echo "configure magma" -(cd magma && ./configure $@) - -echo "configure ccs" -(cd ccs && ./configure $@) - -echo "configure cman" -(cd cman && ./configure $@) - -echo "configure dlm" -(cd dlm && ./configure $@) - -echo "configure fence" -(cd fence && ./configure $@) - -echo "configure iddev" -(cd iddev && ./configure $@) - -echo "configure gfs" -(cd gfs && ./configure $@) - -echo "configure gnbd" -(cd gnbd && ./configure $@) - -echo "configure gulm" -(cd gulm && ./configure $@) - -echo "configure magma-plugins" -(cd magma-plugins && ./configure $@) - -echo "configure rgmanager" -(cd rgmanager && ./configure $@) - -echo "configure cmirror-kernel" -(cd cmirror-kernel && ./configure $@) diff --git a/csnap/Makefile b/csnap/Makefile deleted file mode 100644 index 757396c..0000000 --- a/csnap/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -binaries = mksnapstore csnap-server csnap-create csnap-delete csnap-agent testclient devpoke devspam -deps = csnap.h ../dm-csnap.h trace.h sock.h buffer.h list.h buffer.h Makefile - -all: buffer.o $(binaries) - -buffer.o: buffer.c $(deps) - cc -g -Wall buffer.c -c - -mksnapstore: csnap.c buffer.o $(deps) - cc -g -Wall csnap.c buffer.o -DCREATE -o mksnapstore - -csnap-server: csnap.c buffer.o $(deps) - cc -g -Wall csnap.c buffer.o -DSERVER -o csnap-server - -csnap-agent: agent.c $(deps) - cc -g -Wall agent.c -I../../../ -ldlm -lmagma -ldl -lpthread -o csnap-agent - -csnap-create csnap-delete: create.c $(deps) - cc -Wall create.c -DCREATE -o csnap-create - cc -Wall create.c -DDELETE -o csnap-delete - -testclient: testclient.c $(deps) - cc -Wall testclient.c -o testclient - -devpoke: devpoke.c - cc -Wall devpoke.c -o devpoke - -devspam: devspam.c - cc -Wall devspam.c -o devspam - -clean: - rm -f $(binaries) *.o a.out - -kernel: - cd ../../.. && make bzImage - -kern: - cd ../../.. && make bzImage SUBDIRS=drivers/md - -test: test1 test2 test3 - -test1: - killall csnap-server || true - sudo killall csnap-agent || true - ./mksnapstore /dev/test-snapstore /dev/test-origin - sudo /sbin/dmsetup remove testdev || true - sudo ./csnap-agent @test - ./csnap-server /dev/test-snapstore /dev/test-origin @test 8080 - -test2: - sudo ./csnap-create localhost:8080 0 - echo 0 497976 csnapshot /dev/test-snapstore /dev/test-origin @test -1 | sudo /sbin/dmsetup create testdev - -test3: -# sudo ./devpoke /dev/mapper/testdev write 2 -# sudo ./devpoke /dev/mapper/testdev read 2 -# sleep 1 -# killall csnap-server - sudo ./devspam /dev/mapper/testdev write 19 77 - -test4: -# sudo ./devspam /dev/mapper/testdev write 1 77 - -test9: - sudo /sbin/dmsetup remove testdev diff --git a/csnap/README b/csnap/README deleted file mode 100644 index 6f7c050..0000000 --- a/csnap/README +++ /dev/null @@ -1,67 +0,0 @@ -To install: - -For 2.4: - - - Start with a 2.4.26 tree from kernel.org - - - Apply the 2.4.26 (pre) device mapper patch - -For 2.6: - - - Get a 2.6.7 kernel.org tree, it already has device mapper - -For both: - - - Make sure device mapper is enabled in the configuration - - - Now: - cd drivers/md - tar -xzf csnap-2.4.26.tgz - cd csnap - make - - - Apply the csnap-2.4.26 patch that you see in this directory. - From the root of the 2.4.26 tree: - - patch -p1 <csnap-2.4.26 - - - Rebuild the kernel on your test machine, install and reboot - -To run tests, you need a couple of block devices named /dev/test-origin -and /dev/test-snapstore. These can just be symlinks to test partitions -on some disk, or they can even be files (I think, but I haven't tested -this for a while). Once you have the devices you are ready to go: - - make test - -Check out what the test is actually doing by looking in the makefile. -Basically, it's: - - - try to clean up from a previous test by killing the server and - removing the dm device - - - recreate the snapshot store, so each test starts clean - - - start the snapshot server - - - create a snapshot or origin client - - - run pokedev, which randomly or sequentially reads or writes a bunch - of 4K blocks on the snapshot or origin virtual device - -Watch the tracing output to see what happened. The kernel driver -tracing defaults to on at the moment, so there should be lots of -console output for each IO transfer. - -Please let me know what I've forgotten in the above recipes, so that I -can incorporate improvements. One thing: the makefile tests -arbitrarily bind the server to port 8080, chances are good you are -using this for something else. I should think of a better default -port. Anyway, just edit the makefile for now. - -To remove the test device mapper device: - - make test9 - -Note note note! This source tree is in mid-hack! It's pretty in place -and ugly in others. diff --git a/csnap/agent.c b/csnap/agent.c deleted file mode 100644 index 07e7b48..0000000 --- a/csnap/agent.c +++ /dev/null @@ -1,359 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> // read -#include <sys/socket.h> -#include <sys/poll.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <libdlm.h> -#include "../dm-csnap.h" // message codes -#include "csnap.h" // outbead -#include "trace.h" -#include "sock.h" // send_fd, read/writepipe, connect_socket - -#define trace trace_off - -#define LOCK "csnap" // !!! choose a sensible name and/or use a lockspace - -struct lvb_address{ u32 type; u32 port; u8 address_len; char address[16]; };; - -struct client { int sock; enum { CLIENT_CON, SERVER_CON } type; }; - -struct context { - struct server active, local; - int serv; - int waiters; - struct client *waiting[100]; - struct dlm_lksb lksb; - char lvb[DLM_LVB_LEN]; - int polldelay; - unsigned ast_state; -}; - -static inline int have_address(struct server *server) -{ - return !!server->address_len; -} - -int connect_clients(struct context *context) -{ - warn("connect clients to %x", *(int *)(context->active.address)); - while (context->waiters) - { - struct client *client = context->waiting[0]; - int control = client->sock; - struct server *server = &context->active; - struct sockaddr_in addr = { .sin_family = server->type, .sin_port = server->port }; - int sock; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - error("Can't get socket"); - memcpy(&addr.sin_addr.s_addr, server->address, server->address_len); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - warn("Can't connect to server, %s (%i)", strerror(errno), errno); -// warn("try again later"); -// context->polldelay = 500; - return -1; - } - if (outbead(control, CONNECT_SERVER, struct { }) < 0) - error("Could not send connect message"); - if (send_fd(control, sock, "fark", 4) < 0) - error("Could not pass server connection to target"); - context->waiting[0] = context->waiting[--context->waiters]; - } - return 0; -} - -/* - * Server instantiation algorithm using dlm+lvb: - * - * Repeat until bored: - * - Try to grab Protected Write without waiting - * - If we got it, write our server address to the lvb, start it, done - * - Otherwise, convert to Concurrent Read without waiting - * - If there's a server address in the lvb, use it, done - * - * Then punt to a human: somebody out there is sitting on the PW lock - * but not distributing a server address. - */ - -enum ast_state { - dormant, - read_lvb_done, - write_lvb_done, - check_write_lock, -}; - -void ast(void *arg); // bogus forward ref - -void read_lvb(struct context *context, int flags) // bogus function -{ - struct dlm_lksb *lksb = &context->lksb; - - warn("read lvb"); - if (dlm_lock(LKM_CRMODE, lksb, flags|LKF_NOQUEUE|LKF_VALBLK, LOCK, strlen(LOCK), 0, ast, context, NULL, NULL)) - error("convert failed"); - context->ast_state = read_lvb_done; -} - -void ast(void *arg) -{ - struct context *context = arg; - struct dlm_lksb *lksb = &context->lksb; - - if (lksb->sb_status == EUNLOCK) { - warn("released lock"); - memset(&context->active, 0, sizeof(struct server)); - return; - } - - switch (context->ast_state) { - case read_lvb_done: - warn("read_lvb_done"); - if (lksb->sb_status) - error("unexpected lock status (%i)", lksb->sb_status); - - if (have_address((struct server *)lksb->sb_lvbptr)) { - memcpy(&context->active, lksb->sb_lvbptr, sizeof(struct server)); - context->ast_state = dormant; - connect_clients(context); - return; - } - - /* No address in lvb? Sigh, we have to busywait. */ - context->ast_state = dormant; - context->polldelay = 100; - return; - - case write_lvb_done: - warn("write_lvb_done"); - /* if this didn't work the dlm broken, might as well die */ - if (lksb->sb_status) - error("unexpected lock status (%i)", lksb->sb_status); - - warn("Activate local server"); - memcpy(&context->active, &context->local, sizeof(struct server)); - if (outbead(context->serv, START_SERVER, struct { }) < 0) - error("Could not send message to server"); - connect_clients(context); - context->ast_state = dormant; - return; - - case check_write_lock: - warn("check_write_lock"); - warn("status = %i, %s", lksb->sb_status, strerror(lksb->sb_status)); - if (lksb->sb_status == EAGAIN) { - /* We lost the race to start a server (probably) */ - read_lvb(context, 0); - return; - } - - warn("got write lock"); - memcpy(lksb->sb_lvbptr, &context->local, sizeof(struct server)); - if (dlm_lock(LKM_PWMODE, lksb, LKF_CONVERT|LKF_NOQUEUE|LKF_VALBLK, LOCK, strlen(LOCK), 0, ast, context, NULL, NULL)) - error("convert failed"); - context->ast_state = write_lvb_done; - return; - default: - error("Bad ast state %i", context->ast_state); - } -} - -int try_to_instantiate(struct context *context) -{ - warn("Try to instantiate server"); - struct dlm_lksb *lksb = &context->lksb; - if (dlm_lock(LKM_PWMODE, lksb, LKF_NOQUEUE, LOCK, strlen(LOCK), 0, ast, context, NULL, NULL)) { - if (errno == EAGAIN) // bogus double handling of lock collision if master is local - read_lvb(context, 0); - else - error("lock failed (%i) %s", errno, strerror(errno)); - } else - context->ast_state = check_write_lock; - return 0; -} - -int incoming(struct context *context, struct client *client) -{ - int err; - struct messagebuf message; - int sock = client->sock; - - if ((err = readpipe(sock, &message.head, sizeof(message.head)))) - goto pipe_error; - if (message.head.length > maxbody) - goto message_too_long; - if ((err = readpipe(sock, &message.body, message.head.length))) - goto pipe_error; - - switch (message.head.code) { - case SERVER_READY: - warn("received server ready"); - assert(message.head.length == sizeof(struct server)); - memcpy(&context->local, message.body, sizeof(struct server)); - context->serv = sock; // !!! refuse more than one - client->type = SERVER_CON; - goto instantiate; - - case NEED_SERVER: - context->waiting[context->waiters++] = client; - /* - * If we have a local server, try to instantiate it as the master. - * If there's already a master out there, connect to it. If there - * was a master but it went away then the exclusive lock is up for - * grabs. Always ensure the exclusive is still there before by - * trying to get it, before relying on the lvb server address, - * because that could be stale. - * - * If there's no local server, don't do anything: instantiation - * will be attempted when/if the local server shows up. - */ - if (have_address(&context->active)) { - connect_clients(context); - break; - } - if (have_address(&context->local) && context->ast_state == dormant) - goto instantiate; - break; - case REPLY_CONNECT_SERVER: - warn("Everything connected properly, all is well"); - break; - default: - warn("Unknown message %x", message.head.code); - break; - } - return 0; - -instantiate: - return try_to_instantiate(context); - -message_too_long: - warn("message %x too long (%u bytes)\n", message.head.code, message.head.length); -pipe_error: - return -1; -} - -int monitor(char *sockname, struct context *context) -{ - unsigned maxclients = 100, clients = 0, others = 2; - struct pollfd pollvec[others+maxclients]; - struct client *clientvec[maxclients]; - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - int addr_len = sizeof(addr) - sizeof(addr.sun_path) + strlen(sockname); - int listener = socket(AF_UNIX, SOCK_STREAM, 0), locksock; - - assert(listener > 0); - strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); - if (sockname[0] == '@') - addr.sun_path[0] = 0; - else - unlink(sockname); - - if (bind(listener, (struct sockaddr *)&addr, addr_len) || listen(listener, 5)) - error("Can't bind to control socket (is it in use?)"); - - /* Set up lock manager */ - if ((locksock = dlm_get_fd()) < 0) - error("dlm error %i, %s", errno, strerror(errno)); - context->lksb.sb_lvbptr = context->lvb; /* Yuck! */ - memset(context->lvb, 0, sizeof(context->lvb)); - - /* Launch daemon and exit */ - switch (fork()) { - case -1: - error("fork failed"); - case 0: - break; // !!! should daemonize properly - default: - return 0; - } - - pollvec[0] = (struct pollfd){ .fd = listener, .events = POLLIN }; - pollvec[1] = (struct pollfd){ .fd = locksock, .events = POLLIN }; - assert(pollvec[0].fd > 0); - - while (1) { - switch (poll(pollvec, others+clients, context->polldelay)) { - case -1: - if (errno == EINTR) - continue; - error("poll failed, %s", strerror(errno)); - case 0: - /* Timeouts happen here */ - context->polldelay = -1; - warn("try again"); - connect_clients(context); - // If we go through this too many times it means somebody - // out there is sitting on the PW lock but did not write - // the lvb, this is breakage that should be reported to a - // human. So we should do that, but also keep looping - // forever in case somebody is just being slow or in the - // process of being fenced/ejected, in which case the PW - // will eventually come free again. Yes this sucks. - continue; - } - - /* New connection? */ - if (pollvec[0].revents) { - struct sockaddr_in addr; - int addr_len = sizeof(addr), sock; - - if (!(sock = accept(listener, (struct sockaddr *)&addr, &addr_len))) - error("Cannot accept connection"); - trace_on(warn("Received connection %i", clients);) - assert(clients < maxclients); // !!! make the array bigger - - struct client *client = malloc(sizeof(struct client)); - *client = (struct client){ .sock = sock }; - clientvec[clients] = client; - pollvec[others+clients] = (struct pollfd){ .fd = sock, .events = POLLIN }; - clients++; - } - - /* Lock event? */ - if (pollvec[1].revents) - dlm_dispatch(locksock); - - /* Activity on connection? */ - unsigned i = 0; - while (i < clients) { - if (pollvec[others+i].revents) { // !!! check for poll error - struct client **clientp = clientvec + i, *client = *clientp; - - if (incoming(context, client) == -1) { - warn("Lost connection %i", i); - if (client->type == SERVER_CON) { - warn("local server died..."); - if (!memcmp(&context->active, &context->local, sizeof(struct server))) { - warn("release lock"); - struct dlm_lksb *lksb = &context->lksb; - memset(&context->active, 0, sizeof(struct server)); - memset(lksb->sb_lvbptr, 0, sizeof(struct server)); - if (dlm_unlock(lksb->sb_lkid, 0, lksb, context) < 0) - warn("dlm error %i, %s", errno, strerror(errno)); - } - memset(&context->local, 0, sizeof(struct server)); - } - close(client->sock); - free(client); - --clients; - clientvec[i] = clientvec[clients]; - pollvec[others + i] = pollvec[others + clients]; -// memmove(clientp, clientp + 1, sizeof(struct client *) * clients); -// memmove(pollvec + i + others, pollvec + i + others + 1, sizeof(struct pollfd) * clients); - continue; - } - } - i++; - } - } -} - -int main(int argc, char *argv[]) -{ - if (argc != 2) - error("usage: %s sockname", argv[0]); - - return monitor(argv[1], &(struct context){ .polldelay = -1 }); -} diff --git a/csnap/buffer.c b/csnap/buffer.c deleted file mode 100644 index f2277f4..0000000 --- a/csnap/buffer.c +++ /dev/null @@ -1,256 +0,0 @@ -#define _XOPEN_SOURCE 500 /* pwrite */ -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include "list.h" -#include "buffer.h" -#include "trace.h" - -#define buftrace trace_off - -/* - * Kernel-like buffer layer - */ - -/* - * Even though we are in user space, for reasons of durability and speed - * we need to access the block directly, handle our own block caching and - * keep track block by block of which parts of the on-disk data structures - * as they are accessed and modified. There's no need to reinvent the - * wheel here. I have basically cloned the traditional Unix kernel buffer - * paradigm, with one small twists of my own, that is, instead of state - * bits we use scalar values. This captures the notion of buffer state - * transitions more precisely than the traditional approach. - * - * One big benefit of using a buffer paradigm that looks and acts very - * much like the kernel incarnation is, porting this into the kernel is - * going to be a whole lot easier. Most higher level code will not need - * to be modified at all. Another benefit is, it will be much easier to - * add async IO. - */ - -static struct buffer *buffer_table[BUFFER_BUCKETS]; -LIST_HEAD(dirty_buffers); - -void set_buffer_dirty(struct buffer *buffer) -{ - buftrace(printf("set_buffer_dirty %llx state=%u\n", buffer->sector, buffer->flags & BUFFER_STATE_MASK);) - if (!buffer_dirty(buffer)) - list_add_tail(&buffer->list, &dirty_buffers); - buffer->flags = BUFFER_STATE_DIRTY | (buffer->flags & ~BUFFER_STATE_MASK); -} - -void set_buffer_uptodate(struct buffer *buffer) -{ - if (buffer_dirty(buffer)) - list_del(&buffer->list); - buffer->flags = BUFFER_STATE_CLEAN | (buffer->flags & ~BUFFER_STATE_MASK); -} - -void brelse(struct buffer *buffer) -{ - buftrace(printf("Release buffer %llx\n", buffer->sector);) - if (!--buffer->count) - trace_off(printf("Free buffer %llx\n", buffer->sector)); -} - -void brelse_dirty(struct buffer *buffer) -{ - buftrace(printf("Release dirty buffer %llx\n", buffer->sector);) - set_buffer_dirty(buffer); - brelse(buffer); -} - -int read_buffer(struct buffer *buffer) -{ - buftrace(warn("read buffer %llx", buffer->sector);) - lseek(buffer->fd, buffer->sector << SECTOR_BITS , SEEK_SET); - - unsigned count = 0; - while (count < buffer->size) - { - int n = read(buffer->fd, buffer->data, buffer->size - count); - if (n == -1) -{ - printf("read error %i %s %i\n", errno, strerror(errno), buffer->size - count); - return errno; -} - count += n; - } - set_buffer_uptodate(buffer); - return 0; -} - -int write_buffer_to(struct buffer *buffer, sector_t sector) -{ - while (pwrite(buffer->fd, buffer->data, buffer->size, sector << SECTOR_BITS) == -1) - if (errno != EAGAIN) - return errno; - return 0; -} - -int write_buffer(struct buffer *buffer) -{ - buftrace(warn("write buffer %Lx/%u", buffer->sector, buffer->size);) - int err; - - if ((err = write_buffer_to(buffer, buffer->sector))) - return err; - set_buffer_uptodate(buffer); - return 0; -} - -unsigned buffer_hash(sector_t sector) -{ - return (((sector >> 32) ^ (sector_t)sector) * 978317583) % BUFFER_BUCKETS; -} - -struct buffer *new_buffer(sector_t sector, unsigned size) -{ - buftrace(printf("Allocate buffer for %llx\n", sector);) - struct buffer *buffer = (struct buffer *)malloc(sizeof(struct buffer)); - buffer->data = malloc_aligned(size, size); // what if malloc fails? - buffer->count = 1; - buffer->flags = 0; - buffer->size = size; - buffer->sector = sector; - return buffer; -} - -struct buffer *getblk(unsigned fd, sector_t sector, unsigned size) -{ - struct buffer **bucket = &buffer_table[buffer_hash(sector)], *buffer; - - for (buffer = *bucket; buffer; buffer = buffer->hashlist) - if (buffer->sector == sector) { - buftrace(printf("Found buffer for %llx\n", sector);) - buffer->count++; - return buffer; - } - - buffer = new_buffer(sector, size); - buffer->fd = fd; - buffer->hashlist = *bucket; - *bucket = buffer; - return buffer; -} - -struct buffer *bread(unsigned fd, sector_t sector, unsigned size) -{ - struct buffer *buffer = getblk(fd, sector, size); - - if (buffer_uptodate(buffer) || buffer_dirty(buffer)) - return buffer; - - read_buffer(buffer); - if (buffer_uptodate(buffer)) - return buffer; - - brelse(buffer); -error("bad read"); - return NULL; -} - -void evict_buffer(struct buffer *buffer) -{ - struct buffer **pbuffer = &buffer_table[buffer_hash(buffer->sector)]; - - for (; *pbuffer; pbuffer = &(*pbuffer)->hashlist) - if (*pbuffer == buffer) { - *pbuffer = buffer->hashlist; - buftrace(printf("Evict buffer for %llx\n", buffer->sector);) -// free(buffer->data); // !!! malloc_aligned means pointer is wrong - free(buffer); - return; - } - error("buffer not found"); -} - -void evict_buffers(void) // !!! should use lru list -{ - unsigned i; - for (i = 0; i < BUFFER_BUCKETS; i++) - { - struct buffer *buffer; - for (buffer = buffer_table[i]; buffer;) { - struct buffer *next = buffer->hashlist; - if (!buffer->count) - evict_buffer(buffer); - buffer = next; - } - } -} - -void flush_buffers(void) // !!! should use lru list -{ - while (!list_empty(&dirty_buffers)) { - struct list_head *entry = dirty_buffers.next; - struct buffer *buffer = list_entry(entry, struct buffer, list); - - if (buffer_dirty(buffer)) - write_buffer(buffer); - } -} - -void show_buffer(struct buffer *buffer) -{ - printf("%s%llx/%i ", buffer_dirty(buffer)? "+": buffer_uptodate(buffer)? "": "?", buffer->sector, buffer->count); -} - -void show_buffers_(int all) -{ - unsigned i; - - for (i = 0; i < BUFFER_BUCKETS; i++) - { - struct buffer *buffer = buffer_table[i]; - - if (!buffer) - continue; - - printf("[%i] ", i); - for (; buffer; buffer = buffer->hashlist) - if (all || buffer->count) - show_buffer(buffer); - printf("\n"); - } -} - -void show_active_buffers(void) -{ - printf("Active buffers:\n"); - show_buffers_(0); -} - -void show_buffers(void) -{ - printf("Buffers:\n"); - show_buffers_(1); -} - -void show_dirty_buffers(void) -{ - struct list_head *list; - - printf("Dirty buffers: "); - list_for_each(list, &dirty_buffers) { - struct buffer *buffer = list_entry(list, struct buffer, list); - printf("%llx ", buffer->sector); - } - printf("\n"); -} - -#if 0 -void dump_buffer(struct buffer *buffer, unsigned offset, unsigned length) -{ - hexdump(buffer->data + offset, length); -} -#endif - -void init_buffers(void) -{ - memset(buffer_table, 0, sizeof(buffer_table)); -} diff --git a/csnap/buffer.h b/csnap/buffer.h deleted file mode 100644 index 930e254..0000000 --- a/csnap/buffer.h +++ /dev/null @@ -1,59 +0,0 @@ -#define SECTOR_BITS 9 -#define BUFFER_STATE_INVAL 0 -#define BUFFER_STATE_CLEAN 1 -#define BUFFER_STATE_DIRTY 2 -#define BUFFER_STATE_MASK 3 -#define BUFFER_BUCKETS 9999 - -typedef unsigned long long sector_t; -typedef unsigned long long offset_t; - -struct buffer -{ - struct buffer *hashlist; - struct list_head list; - unsigned count; // should be atomic_t - unsigned flags; - unsigned size; - sector_t sector; - unsigned char *data; - unsigned fd; -}; - -struct list_head dirty_buffers; - -void show_dirty_buffers(void); -void set_buffer_dirty(struct buffer *buffer); -void set_buffer_uptodate(struct buffer *buffer); -void brelse(struct buffer *buffer); -void brelse_dirty(struct buffer *buffer); -int write_buffer_to(struct buffer *buffer, offset_t pos); -int write_buffer(struct buffer *buffer); -int read_buffer(struct buffer *buffer); -unsigned buffer_hash(sector_t sector); -struct buffer *new_buffer(sector_t sector, unsigned size); -struct buffer *getblk(unsigned fd, sector_t sector, unsigned size); -struct buffer *bread(unsigned fd, sector_t sector, unsigned size); -void evict_buffer(struct buffer *buffer); -void evict_buffers(void); -void flush_buffers(void); -void show_buffer(struct buffer *buffer); -void show_active_buffers(void); -void show_buffers(void); -void init_buffers(void); - -static inline int buffer_dirty(struct buffer *buffer) -{ - return (buffer->flags & BUFFER_STATE_MASK) == BUFFER_STATE_DIRTY; -} - -static inline int buffer_uptodate(struct buffer *buffer) -{ - return (buffer->flags & BUFFER_STATE_MASK) == BUFFER_STATE_CLEAN; -} - -static inline void *malloc_aligned(size_t size, unsigned binalign) -{ - unsigned long p = (unsigned long)malloc(size + binalign - 1); - return (void *)(p + (-p & (binalign - 1))); -} diff --git a/csnap/buffertest.c b/csnap/buffertest.c deleted file mode 100644 index 8a7692c..0000000 --- a/csnap/buffertest.c +++ /dev/null @@ -1,15 +0,0 @@ -#include <stdlib.h> - -#include "list.h" -#include "buffer.h" - -int main(int argc, char *argv[]) -{ - struct buffer *buffer = new_buffer(0x64, 4096); - show_dirty_buffers(); - set_buffer_dirty(buffer); - show_dirty_buffers(); - set_buffer_uptodate(buffer); - show_dirty_buffers(); - return 0; -} diff --git a/csnap/create.c b/csnap/create.c deleted file mode 100644 index 05bd810..0000000 --- a/csnap/create.c +++ /dev/null @@ -1,58 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -//#include <fcntl.h> -#include <errno.h> -#include <inttypes.h> -#include <netinet/in.h> -#include "../dm-csnap.h" -#include "csnap.h" -#include "trace.h" -#include "sock.h" - -#ifdef DELETE -# define THIS_CODE DELETE_SNAPSHOT -# define THIS_REPLY REPLY_DELETE_SNAPSHOT -#else -# define THIS_CODE CREATE_SNAPSHOT -# define THIS_REPLY REPLY_CREATE_SNAPSHOT -#endif - -int main(int argc, char *argv[]) -{ - int sock, err; - if (argc < 3) - error("usage: %s host:port snapshot", argv[0]); - - int snap = atoi(argv[2]); - char *host = argv[1]; - int len = strlen(host), port = parse_port(host, &len); - - if (port < 0) - error("expected host:port, not %s", host); - host[len] = 0; - - if (!(sock = open_socket(host, port))) - error("Can't connect to %s:%i", host, port); - - outbead(sock, THIS_CODE, struct create_snapshot, snap); - - struct head head; - unsigned maxbuf = 500; - char buf[maxbuf]; - - if ((err = readpipe(sock, &head, sizeof(head)))) - goto pipe_error; - assert(head.length < maxbuf); // !!! don't die - if ((err = readpipe(sock, buf, head.length))) - goto pipe_error; - trace_on(printf("reply = %x\n", head.code);) - err = head.code != THIS_REPLY; - - if (head.code == REPLY_ERROR) - error("%.*s", head.length - 4, buf + 4); -pipe_error: - close(sock); - return err; -} diff --git a/csnap/csnap.c b/csnap/csnap.c deleted file mode 100644 index c695e0e..0000000 --- a/csnap/csnap.c +++ /dev/null @@ -1,2264 +0,0 @@ -/* - * Clustered Snapshot Metadata Server - * - * Daniel Phillips, Nov 2003 to May 2004 - * (c) 2003 Sistina Software Inc. - * (c) 2004 Red Hat Software Inc. - * - */ - -#undef BUSHY -#define _GNU_SOURCE /* Berserk glibc headers: O_DIRECT not defined unless _GNU_SOURCE defined */ - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <time.h> -#include <signal.h> -#include <sys/poll.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <netdb.h> // gethostbyname2_r -#include <linux/fs.h> // BLKGETSIZE -#include "list.h" -#include "buffer.h" -#include "csnap.h" -#include "../dm-csnap.h" -#include "trace.h" - -#define trace trace_off -#define jtrace trace_off - -/* -Todo: - -BTree - * coalesce leafs/nodes for delete - - B*Tree splitting - -Allocation bitmaps - - allocation statistics - - Per-snapshot free space as full-tree pass - - option to track specific snapshot(s) on the fly - - return stats to client (on demand? always?) - * Bitmap block radix tree - resizing - - allocation policy - -Journal - \ allocation - \ write commit block - \ write target blocks - \ recovery - - stats and misc data in commit block? - -File backing - \ double linked list ops - - buffer lru - - buffer writeout policy - - buffer eviction policy - - verify no busy buffers between operations - -Snapshot vs origin locking - - anti-starvation measures - -Message handling - - send reply on async write completion - - build up immediate reply in separate buffer - -Snapshot handling path - - background copyout thread - - try AIO - - coalesce leaves/nodes on delete - - should wait for current queries on snap to complete - - background deletion optimization - - record current deletion list in superblock - -Multithreading - - separate thread for copyouts - - separate thread for buffer flushing - - separate thread for new connections (?) - -Utilities - - don't include anything not needed for create - - snapshot store integrity check (snapcheck) - -Error recovery - \ Mark superblock active/inactive - + upload client locks on server restart - + release snapshot read locks for dead client - - Examine entire tree to initialize statistics after unsaved halt - -General - \ Prevent multiple server starts on same snapshot store - + More configurable tracing - - Add more internal consistency checks - - Magic number + version for superblock - - Flesh out and audit error paths - - Make it endian-neutral - - Verify wordsize neutral - - Add an on-the-fly verify path - + strip out the unit testing gunk - + More documentation - - Audits and more audits - - Memory inversion prevention - -Cluster integration - + Restart/Error recovery/reporting -*/ - -/* - * Miscellaneous Primitives - */ - -typedef int fd_t; - -/* - * Ripped from libiddev. It's not quite ugly enough to convince me to - * add a new dependency on a library that nobody has yet, but it's close. - */ -static int fd_size(int fd, u64 *bytes) -{ - struct stat stat; - int error; - - if ((error = fstat(fd, &stat))) - return error; - - if (S_ISREG(stat.st_mode)) { - *bytes = stat.st_size; - return 0; - } - if ((error = ioctl(fd, BLKGETSIZE64, bytes))) { - unsigned sectors; - - if ((error = ioctl(fd, BLKGETSIZE, §ors))) - return error; - *bytes = ((u64)sectors) << 9; - } - return 0; -} - -void hexdump(void *data, unsigned length) -{ - while (length ) { - int row = length < 16? length: 16; - printf("%p: ", data); - length -= row; - while (row--) - printf("%02hhx ", *(unsigned char *)data++); - printf("\n"); - } -} - -/* BTree Operations */ - -/* Directory at the base of the leaf block */ - -#define MAX_SNAPSHOTS 64 - -struct enode -{ - u32 count; - u32 unused; - struct index_entry - { - u64 key; // note: entries[0].key never accessed - sector_t sector; // node sector address goes here - } entries[]; -}; - -struct eleaf -{ - le_u16 magic; - le_u16 version; - le_u32 count; - le_u64 base_chunk; - le_u64 using_mask; - struct etree_map - { - le_u32 offset; - le_u32 rchunk; - } - map[]; -}; - -static inline struct enode *buffer2node(struct buffer *buffer) -{ - return (struct enode *)buffer->data; -} - -static inline struct eleaf *buffer2leaf(struct buffer *buffer) -{ - return (struct eleaf *)buffer->data; -} - -/* On-disk Format */ - -struct exception -{ - le_u64 share; - le_u64 chunk; -}; - -static inline struct exception *emap(struct eleaf *leaf, unsigned i) -{ - return (struct exception *)((char *) leaf + leaf->map[i].offset); -} - -struct superblock -{ - /* Persistent, saved to disk */ - struct disksuper - { - char magic[8]; - sector_t etree_root; - sector_t bitmap_base; - sector_t chunks, freechunks; - sector_t orgchunks; - chunk_t last_alloc; - u64 flags; - u32 blocksize_bits, chunksize_bits; - u64 deleting; - struct snapshot - { - u8 tag; - u8 bit; - u32 create_time; - u16 reserved; - } snaplist[MAX_SNAPSHOTS]; - u32 snapshots; - u32 etree_levels; - u32 bitmap_blocks; - s32 journal_base, journal_next, journal_size; - u32 sequence; - } image; - - /* Derived, not saved to disk */ - u64 snapmask; - u32 blocksize, chunksize, keys_per_node; - u32 sectors_per_block_bits, sectors_per_block; - u32 sectors_per_chunk_bits, sectors_per_chunk; - unsigned flags; - unsigned snapdev, orgdev; - unsigned snaplock_hash_bits; - struct snaplock **snaplocks; - unsigned copybuf_size; - char *copybuf; - chunk_t source_chunk; - chunk_t dest_exception; - unsigned copy_chunks; - unsigned max_commit_blocks; -}; - -#define SB_BUSY 1 -#define SB_MAGIC "snapshot" - -/* Journal handling */ - -#define JMAGIC "MAGICNUM" - -struct commit_block -{ - char magic[8]; - u32 checksum; - s32 sequence; - u32 entries; - u64 sector[]; -} PACKED; - -static sector_t journal_sector(struct superblock *sb, unsigned i) -{ - return sb->image.journal_base + (i << sb->sectors_per_block_bits); -} - -static inline struct commit_block *buf2block(struct buffer *buf) -{ - return (void *)buf->data; -} - -unsigned next_journal_block(struct superblock *sb) -{ - unsigned next = sb->image.journal_next; - - if (++sb->image.journal_next == sb->image.journal_size) - sb->image.journal_next = 0; - - return next; -} - -static int is_commit_block(struct commit_block *block) -{ - return !memcmp(&block->magic, JMAGIC, sizeof(block->magic)); -} - -static u32 checksum_block(struct superblock *sb, u32 *data) -{ - int i, sum = 0; - for (i = 0; i < sb->image.blocksize_bits >> 2; i++) - sum += data[i]; - return sum; -} - -static struct buffer *jgetblk(struct superblock *sb, unsigned i) -{ - return getblk(sb->snapdev, journal_sector(sb, i), sb->blocksize); -} - -static struct buffer *jread(struct superblock *sb, unsigned i) -{ - return bread(sb->snapdev, journal_sector(sb, i), sb->blocksize); -} - -/* - * For now there is only ever one open transaction in the journal, the newest - * one, so we don't have to check for journal wrap, but just ensure that each - * transaction stays small enough to fit in the journal. - * - * Since we don't have any asynchronous IO at the moment, journal commit is - * straightforward: walk through the dirty blocks once, writing them to the - * journal, then again, adding sector locations to the commit block. We know - * the dirty list didn't change between the two passes. When ansynchronous - * IO arrives here, this all has to be handled a lot more carefully. - */ -static void commit_transaction(struct superblock *sb) -{ -// flush_buffers(); -// return; - if (list_empty(&dirty_buffers)) - return; - - struct list_head *list; - - list_for_each(list, &dirty_buffers) { - struct buffer *buffer = list_entry(list, struct buffer, list); - unsigned pos = next_journal_block(sb); - jtrace(warn("journal data sector = %Lx [%u]", buffer->sector, pos);) - assert(buffer_dirty(buffer)); - write_buffer_to(buffer, journal_sector(sb, pos)); - } - - unsigned pos = next_journal_block(sb); - struct buffer *commit_buffer = jgetblk(sb, pos); - struct commit_block *commit = buf2block(commit_buffer); - *commit = (struct commit_block){ .magic = JMAGIC, .sequence = sb->image.sequence++ }; - - while (!list_empty(&dirty_buffers)) { - struct list_head *entry = dirty_buffers.next; - struct buffer *buffer = list_entry(entry, struct buffer, list); - jtrace(warn("write data sector = %Lx", buffer->sector);) - assert(buffer_dirty(buffer)); - assert(commit->entries < sb->max_commit_blocks); - commit->sector[commit->entries++] = buffer->sector; - write_buffer(buffer); // deletes it from dirty (fixme: fragile) - // we hope the order we just listed these is the same as committed above - } - - jtrace(warn("commit journal block [%u]", pos);) - commit->checksum = 0; - commit->checksum = -checksum_block(sb, (void *)commit); - write_buffer_to(commit_buffer, journal_sector(sb, pos)); - brelse(commit_buffer); -} - -int recover_journal(struct superblock *sb) -{ - struct buffer *buffer; - typeof(((struct commit_block *)NULL)->sequence) sequence; - int scribbled = -1, last_block = -1, newest_block = -1; - int data_from_start = 0, data_from_last = 0; - int size = sb->image.journal_size; - char *why = ""; - unsigned i; - - /* Scan full journal, find newest commit */ - - for (i = 0; i < size; brelse(buffer), i++) { - buffer = jread(sb, i); - struct commit_block *block = buf2block(buffer); - - if (!is_commit_block(block)) { - jtrace(warn("[%i] <data>", i);) - if (sequence == -1) - data_from_start++; - else - data_from_last++; - continue; - } - - if (checksum_block(sb, (void *)block)) { - warn("block %i failed checksum", i); - hexdump(block, 40); - if (scribbled != -1) { - why = "Too many scribbled blocks in journal"; - goto failed; - } - - if (newest_block != -1 && newest_block != last_block) { - why = "Bad block not last written"; - goto failed; - } - - scribbled = i; - if (last_block != -1) - newest_block = last_block; - sequence++; - continue; - } - - jtrace(warn("[%i] seq=%i", i, block->sequence);) - - if (last_block != -1 && block->sequence != sequence + 1) { - int delta = sequence - block->sequence; - - if (delta <= 0 || delta > size) { - why = "Bad sequence"; - goto failed; - } - - if (newest_block != -1) { - why = "Multiple sequence wraps"; - goto failed; - } - - if (!(scribbled == -1 || scribbled == i - 1)) { - why = "Bad block not last written"; - goto failed; - } - newest_block = last_block; - } - data_from_last = 0; - last_block = i; - sequence = block->sequence; - } - - if (last_block == -1) { - why = "No commit blocks found"; - goto failed; - } - - if (newest_block == -1) { - /* test for all the legal scribble positions here */ - newest_block = last_block; - } - - jtrace(warn("found newest commit [%u]", newest_block);) - buffer = jread(sb, newest_block); - struct commit_block *commit = buf2block(buffer); - unsigned entries = commit->entries; - - for (i = 0; i < entries; i++) { - unsigned pos = (newest_block - entries + i + size) % size; - struct buffer *databuf = jread(sb, pos); - struct commit_block *block = buf2block(databuf); - - if (is_commit_block(block)) { - error("data block [%u] marked as commit block", pos); - continue; - } - - jtrace(warn("write journal [%u] data to %Lx", pos, commit->sector[i]);) - write_buffer_to(databuf, commit->sector[i]); - brelse(databuf); - } - sb->image.journal_next = (newest_block + 1 + size) % size; - sb->image.sequence = commit->sequence + 1; - brelse(buffer); - return 0; - -failed: - errno = EIO; /* return a misleading error (be part of the problem) */ - error("Journal recovery failed, %s", why); - return -1; -} - -static void _show_journal(struct superblock *sb) -{ - int i, j; - for (i = 0; i < sb->image.journal_size; i++) { - struct buffer *buf = jread(sb, i); - struct commit_block *block = buf2block(buf); - - if (!is_commit_block(block)) { - printf("[%i] <data>\n", i); - continue; - } - - printf("[%i] seq=%i (%i)", i, block->sequence, block->entries); - for (j = 0; j < block->entries; j++) - printf(" %Lx", (long long)block->sector[j]); - printf("\n"); - brelse(buf); - } - printf("\n"); -} - -#define show_journal(sb) do { warn("Journal..."); _show_journal(sb); } while (0) - -/* BTree leaf operations */ - -/* - * We operate directly on the BTree leaf blocks to insert exceptions and - * to enquire the sharing status of given chunks. This means all the data - * items in the block need to be properly aligned for architecture - * independence. To save space and to permit binary search a directory - * map at the beginning of the block points at the exceptions stored - * at the top of the block. The difference between two successive directory - * pointers gives the number of distinct exceptions for a given chunk. - * Each exception is paired with a bitmap that specifies which snapshots - * the exception belongs to. - * - * The chunk addresses in the leaf block directory are relative to a base - * chunk to save space. These are currently 32 bit values but may become - * 16 bits values. Since each is paired with a pointer into the list of - * exceptions, 16 bit emap entries would limit the blocksize to 64K. - * - * A mask in the leaf block header specifies which snapshots are actually - * encoded in the chunk. This allows lazy deletion (almost, needs fixing) - * - * The leaf operations need to know the size of the block somehow. - * Currently that is accomplished by inserting the block size as a sentinel - * in the block directory map; this may change. - * - * When an exception is created by a write to the origin it is initially - * shared by all snapshots that don't already have exceptions. Snapshot - * writes may later unshare some of these exceptions. - */ - -/* - * To do: - * - Check leaf, index structure - * - Mechanism for identifying which snapshots are in each leaf - * - binsearch for leaf, index lookup - * - enforce 32 bit address range within leaf - */ - -struct buffer *snapread(struct superblock *sb, sector_t sector) -{ - return bread(sb->snapdev, sector, sb->blocksize); -} - -void show_leaf(struct eleaf *leaf) -{ - struct exception *p; - int i; - - printf("%i chunks: ", leaf->count); - for (i = 0; i < leaf->count; i++) { - printf("%i=", leaf->map[i].rchunk); - // printf("@%i ", leaf->map[i].offset); - for (p = emap(leaf, i); p < emap(leaf, i+1); p++) - printf("%Lx/%08llx%s", p->chunk, p->share, p+1 < emap(leaf, i+1)? ",": " "); - } - // printf("top@%i", leaf->map[i].offset); - printf("\n"); -} - -/* - * origin_chunk_unique: an origin logical chunk is shared unless all snapshots - * have exceptions. - */ - -int origin_chunk_unique(struct eleaf *leaf, u64 chunk, u64 snapmask) -{ - u64 using = 0; - unsigned i, target = chunk - leaf->base_chunk; - struct exception *p; - - for (i = 0; i < leaf->count; i++) - if (leaf->map[i].rchunk == target) - goto found; - return !snapmask; -found: - for (p = emap(leaf, i); p < emap(leaf, i+1); p++) - using |= p->share; - - return !(~using & snapmask); -} - -/* - * snapshot_chunk_unique: a snapshot logical chunk is shared if it has no - * exception or has the same exception as another snapshot. In any case - * if the chunk has an exception we need to know the exception address. - */ - -int snapshot_chunk_unique(struct eleaf *leaf, u64 chunk, int snapshot, u64 *exception) -{ - u64 mask = 1LL << snapshot; - unsigned i, target = chunk - leaf->base_chunk; - struct exception *p; - - for (i = 0; i < leaf->count; i++) - if (leaf->map[i].rchunk == target) - goto found; - return 0; -found: - for (p = emap(leaf, i); p < emap(leaf, i+1); p++) - /* shared if more than one bit set including this one */ - if ((p->share & mask)) { - *exception = p->chunk; -// printf("unique %Lx %Lx\n", p->share, mask); - return !(p->share & ~mask); - } - return 0; -} - -/* - * add_exception_to_leaf: - * - cycle through map to find existing logical chunk or insertion point - * - if not found need to add new chunk address - * - move tail of map up - * - store new chunk address in map - * - otherwise - * - for origin: - * - or together all sharemaps, invert -> new map - * - for snapshot: - * - clear out bit for existing exception - * - if sharemap zero warn and reuse this location - * - insert new exception - * - move head of exceptions down - * - store new exception/sharemap - * - adjust map head offsets - * - * If the new exception won't fit in the leaf, return an error so that - * higher level code may split the leaf and try again. This keeps the - * leaf-editing code complexity down to a dull roar. - */ - -int add_exception_to_leaf(struct eleaf *leaf, u64 chunk, u64 exception, int snapshot, u64 active) -{ - unsigned i, j, target = chunk - leaf->base_chunk; - u64 mask = 1ULL << snapshot, sharemap; - struct exception *ins, *exceptions = emap(leaf, 0); - char *maptop = (char *)(&leaf->map[leaf->count + 1]); // include sentinel - int free = (char *)exceptions - maptop; - trace(warn("chunk %Lx exception %Lx, snapshot = %i", chunk, exception, snapshot);) - - for (i = 0; i < leaf->count; i++) // !!! binsearch goes here - if (leaf->map[i].rchunk >= target) - break; - - if (i == leaf->count || leaf->map[i].rchunk > target) { - if (free < sizeof(struct exception) + sizeof(struct etree_map)) - return -EFULL; - - ins = emap(leaf, i); - memmove(&leaf->map[i+1], &leaf->map[i], maptop - (char *)&leaf->map[i]); - leaf->map[i].offset = (char *)ins - (char *)leaf; - leaf->map[i].rchunk = target; - leaf->count++; - sharemap = snapshot == -1? active: mask; - goto insert; - } - - if (free < sizeof(struct exception)) - return -EFULL; - - if (snapshot == -1) { - for (sharemap = 0, ins = emap(leaf, i); ins < emap(leaf, i+1); ins++) - sharemap |= ins->share; - sharemap = (~sharemap) & active; - } else { - for (ins = emap(leaf, i); ins < emap(leaf, i+1); ins++) - if ((ins->share & mask)) { - ins->share &= ~mask; - break; - } - sharemap = mask; - } - ins = emap(leaf, i); -insert: - memmove(exceptions - 1, exceptions, (char *)ins - (char *)exceptions); - ins--; - ins->share = sharemap; - ins->chunk = exception; - - for (j = 0; j <= i; j++) - leaf->map[j].offset -= sizeof(struct exception); - - return 0; -} - -/* - * split_leaf: Split one leaf into two approximately in the middle. Copy - * the upper half of entries to the new leaf and move the lower half of - * entries to the top of the original block. - */ - -u64 split_leaf(struct eleaf *leaf, struct eleaf *leaf2) -{ - unsigned i, nhead = (leaf->count + 1) / 2, ntail = leaf->count - nhead, tailsize; - /* Should split at middle of data instead of median exception */ - u64 splitpoint = leaf->map[nhead].rchunk + leaf->base_chunk; - char *phead, *ptail; - - phead = (char *)emap(leaf, 0); - ptail = (char *)emap(leaf, nhead); - tailsize = (char *)emap(leaf, leaf->count) - ptail; - - /* Copy upper half to new leaf */ - memcpy(leaf2, leaf, offsetof(struct eleaf, map)); // header - memcpy(&leaf2->map[0], &leaf->map[nhead], (ntail + 1) * sizeof(leaf->map[0])); // map - memcpy(ptail - (char *)leaf + (char *)leaf2, ptail, tailsize); // data - leaf2->count = ntail; - - /* Move lower half to top of block */ - memmove(phead + tailsize, phead, ptail - phead); - leaf->count = nhead; - for (i = 0; i <= nhead; i++) // also adjust sentinel - leaf->map[i].offset += tailsize; - leaf->map[nhead].rchunk = 0; // tidy up - - return splitpoint; -} - -void init_leaf(struct eleaf *leaf, int block_size) -{ - leaf->magic = 0x1eaf; - leaf->version = 0; - leaf->base_chunk = 0; - leaf->count = 0; - leaf->map[0].offset = block_size; -#ifdef BUSHY - leaf->map[0].offset = 200; -#endif -} - -/* - * Chunk allocation via bitmaps - */ - -#define SB_DIRTY 1 -#define SB_LOC 8 - -void mark_sb_dirty(struct superblock *sb) -{ - sb->flags |= SB_DIRTY; -} - -int get_bitmap_bit(unsigned char *bitmap, unsigned bit) -{ - return bitmap[bit >> 3] & (1 << (bit & 7)); -} - -void set_bitmap_bit(unsigned char *bitmap, unsigned bit) -{ - bitmap[bit >> 3] |= 1 << (bit & 7); -} - -void clear_bitmap_bit(unsigned char *bitmap, unsigned bit) -{ - bitmap[bit >> 3] &= ~(1 << (bit & 7)); -} - -void init_allocation(struct superblock *sb) -{ - u64 chunks = sb->image.chunks; - unsigned chunkshift = sb->image.chunksize_bits; - unsigned bitmaps = (chunks + (1 << (chunkshift + 3)) - 1) >> (chunkshift + 3); - unsigned bitmap_base_chunk = (SB_LOC + sb->sectors_per_block + sb->sectors_per_chunk - 1) >> sb->sectors_per_chunk_bits; - unsigned bitmap_chunks = sb->image.bitmap_blocks = bitmaps; // !!! chunksize same as blocksize - unsigned reserved = bitmap_base_chunk + bitmap_chunks + sb->image.journal_size; // !!! chunksize same as blocksize - unsigned sector = sb->image.bitmap_base = bitmap_base_chunk << sb->sectors_per_chunk_bits; - - warn("snapshot store size: %Lu chunks (%Lu sectors)", chunks, chunks << sb->sectors_per_chunk_bits); - printf("Initializing %u bitmap blocks... ", bitmaps); - - unsigned i; - for (i = 0; i < bitmaps; i++, sector += sb->sectors_per_block) { - struct buffer *buffer = getblk(sb->snapdev, sector, sb->blocksize); - printf("%Lx ", buffer->sector); - memset(buffer->data, 0, sb->blocksize); - /* Reserve bitmaps and superblock */ - if (i == 0) { - unsigned i; - for (i = 0; i < reserved; i++) - set_bitmap_bit(buffer->data, i); - } - /* Suppress overrun allocation in partial last byte */ - if (i == bitmaps - 1 && (chunks & 7)) - buffer->data[(chunks >> 3) & (sb->blocksize - 1)] |= 0xff << (chunks & 7); - trace_off(dump_buffer(buffer, 0, 16);) - brelse_dirty(buffer); - } - printf("\n"); - sb->image.freechunks = chunks - reserved; - sb->image.last_alloc = 0; - sb->image.journal_base = (bitmap_base_chunk + bitmap_chunks) << sb->sectors_per_chunk_bits; -} - -#if 0 -char *memscan (char *addr, int c, size_t size) -{ - while (size-- && *addr != c) - addr++; - return addr; -} -#endif - -void free_chunk(struct superblock *sb, chunk_t chunk) -{ - unsigned bitmap_shift = sb->image.blocksize_bits + 3, bitmap_mask = (1 << bitmap_shift ) - 1; - u64 bitmap_block = chunk >> bitmap_shift; - - trace(printf("free chunk %Lx\n", chunk);) - struct buffer *buffer = snapread(sb, sb->image.bitmap_base + (bitmap_block << sb->sectors_per_block_bits)); - assert(get_bitmap_bit(buffer->data, chunk & bitmap_mask)); - clear_bitmap_bit(buffer->data, chunk & bitmap_mask); - brelse_dirty(buffer); - sb->image.freechunks++; - mark_sb_dirty(sb); // !!! optimize this away -} - -#if 0 -void grab_chunk(struct superblock *sb, chunk_t chunk) // just for testing -{ - unsigned bitmap_shift = sb->image.blocksize_bits + 3, bitmap_mask = (1 << bitmap_shift ) - 1; - u64 bitmap_block = chunk >> bitmap_shift; - - struct buffer *buffer = snapread(sb, sb->image.bitmap_base + (bitmap_block << sb->sectors_per_block_bits)); - assert(!get_bitmap_bit(buffer->data, chunk & bitmap_mask)); - set_bitmap_bit(buffer->data, chunk & bitmap_mask); - brelse_dirty(buffer); -} -#endif - -chunk_t alloc_chunk_range(struct superblock *sb, chunk_t chunk, chunk_t range) -{ - unsigned bitmap_shift = sb->image.blocksize_bits + 3, bitmap_mask = (1 << bitmap_shift ) - 1; - u64 blocknum = chunk >> bitmap_shift; - unsigned bit = chunk & 7, offset = (chunk & bitmap_mask) >> 3; - u64 length = (range + bit + 7) >> 3; - - while (1) { - struct buffer *buffer = snapread(sb, sb->image.bitmap_base + (blocknum << sb->sectors_per_block_bits)); - unsigned char c, *p = buffer->data + offset; - unsigned tail = sb->blocksize - offset, n = tail > length? length: tail; - - trace_off(printf("search %u bytes of bitmap %Lx from offset %u\n", n, blocknum, offset);) - // dump_buffer(buffer, 4086, 10); - - for (length -= n; n--; p++) - if ((c = *p) != 0xff) { - int i, bit; - trace_off(printf("found byte at offset %u of bitmap %Lx = %hhx\n", p - buffer->data, blocknum, c);) - for (i = 0, bit = 1;; i++, bit <<= 1) - if (!(c & bit)) { - chunk = i + ((p - buffer->data) << 3) + (blocknum << bitmap_shift); - assert(!get_bitmap_bit(buffer->data, chunk & bitmap_mask)); - set_bitmap_bit(buffer->data, chunk & bitmap_mask); - brelse_dirty(buffer); - sb->image.freechunks--; - mark_sb_dirty(sb); // !!! optimize this away - return chunk; - } - } - - brelse(buffer); - if (!length) - return 0; - if (++blocknum == sb->image.bitmap_blocks) - blocknum = 0; - offset = 0; - trace_off(printf("go to bitmap %Lx\n", blocknum);) - } -} - -chunk_t alloc_chunk(struct superblock *sb) -{ - chunk_t last = sb->image.last_alloc, total = sb->image.chunks, found; - - if ((found = alloc_chunk_range(sb, last, total - last))) - goto success; - if (!(found = alloc_chunk_range(sb, 0, last))) - error("snapshot store full, do something"); -success: - sb->image.last_alloc = found; - mark_sb_dirty(sb); // !!! optimize this away - return (found); -} - -/* Snapshot Store Allocation */ - -sector_t alloc_block(struct superblock *sb) -{ - return alloc_chunk(sb) << sb->sectors_per_chunk_bits; // !!! assume blocksize = chunksize -} - -u64 alloc_exception(struct superblock *sb) -{ - return alloc_chunk(sb); -} - -struct buffer *new_block(struct superblock *sb) -{ - return getblk(sb->snapdev, alloc_block(sb), sb->blocksize); -} - -struct buffer *new_leaf(struct superblock *sb) -{ - trace(printf("New leaf\n");) - struct buffer *buffer = new_block(sb); - init_leaf(buffer2leaf(buffer), sb->blocksize); - set_buffer_dirty(buffer); - return buffer; -} - -struct buffer *new_node(struct superblock *sb) -{ - trace(printf("New node\n");) - struct buffer *buffer = new_block(sb); - struct enode *node = buffer2node(buffer); - node->count = 0; - set_buffer_dirty(buffer); - return buffer; -} - -/* BTree debug dump */ - -void show_subtree(struct superblock *sb, struct enode *node, int levels, int indent) -{ - int i; - printf("%*s", indent, ""); - printf("%i nodes:\n", node->count); - for (i = 0; i < node->count; i++) { - struct buffer *buffer = snapread(sb, node->entries[i].sector); - if (levels) - show_subtree(sb, buffer2node(buffer), levels - 1, indent + 3); - else { - printf("%*s", indent + 3, ""); - show_leaf(buffer2leaf(buffer)); - } - brelse(buffer); - } -} - -void show_tree(struct superblock *sb) -{ - struct buffer *buffer = snapread(sb, sb->image.etree_root); - show_subtree(sb, buffer2node(buffer), sb->image.etree_levels - 1, 0); - brelse(buffer); -} - -/* High Level BTree Editing */ - -/* - * BTree insertion is a little hairy, as expected. We keep track of the - * access path in a vector of etree_path elements, each of which holds - * a node buffer and a pointer into the buffer data giving the address at - * which the next buffer in the path was found, which is also where a new - * node will be inserted if necessary. If a leaf is split we may need to - * work all the way up from the bottom to the top of the path, splitting - * index nodes as well. If we split the top index node we need to add - * a new tree level. We have to keep track of which nodes were modified - * and keep track of refcounts of all buffers involved, which can be quite - * a few. - * - * Note that the first key of an index block is never accessed. This is - * because for a btree, there is always one more key than nodes in each - * index node. In other words, keys lie between node pointers. We will - * micro-optimize by placing the node count in the first key, which allows - * a node to contain an esthetically pleasing binary number of pointers. - * (Not done yet.) - */ - -#define MAX_ETREE_DEPTH 6 - -struct etree_path { struct buffer *buffer; struct index_entry *pnext; }; - -struct buffer *probe(struct superblock *sb, u64 chunk, struct etree_path *path) -{ - unsigned i, levels = sb->image.etree_levels; - struct buffer *nodebuf = snapread(sb, sb->image.etree_root); - struct enode *node = buffer2node(nodebuf); - - for (i = 0; i < levels; i++) { - struct index_entry *pnext = node->entries, *top = pnext + node->count; - - while (++pnext < top) - if (pnext->key > chunk) - break; - - path[i].buffer = nodebuf; - path[i].pnext = pnext; - nodebuf = snapread(sb, (pnext - 1)->sector); - node = (struct enode *)nodebuf->data; - } - assert(((struct eleaf *)nodebuf->data)->magic == 0x1eaf); - return nodebuf; -} - -void brelse_path(struct etree_path *path, unsigned levels) -{ - unsigned i; - for (i = 0; i < levels; i++) - brelse(path[i].buffer); -} - -void show_tree_range(struct superblock *sb, chunk_t start, unsigned leaves) -{ - int levels = sb->image.etree_levels, level = -1; - struct etree_path path[levels]; - struct buffer *nodebuf; - struct enode *node; - struct buffer *leafbuf; - -#if 1 - leafbuf = probe(sb, start, path); - level = levels - 1; - nodebuf = path[level].buffer; - node = buffer2node(nodebuf); - goto start; -#endif - - while (1) { - do { - level++; - nodebuf = snapread(sb, level? path[level - 1].pnext++->sector: sb->image.etree_root); - node = buffer2node(nodebuf); - path[level].buffer = nodebuf; - path[level].pnext = node->entries; - trace(printf("push to level %i, %i nodes\n", level, node->count);) - } while (level < levels - 1); - - trace(printf("do %i leaf nodes level = %i\n", node->count, level);) - while (path[level].pnext < node->entries + node->count) { - leafbuf = snapread(sb, path[level].pnext++->sector); -start: show_leaf(buffer2leaf(leafbuf)); - brelse(leafbuf); - if (!--leaves) { - brelse_path(path, level + 1); - return; - } - } - - do { - brelse(nodebuf); - if (!level) - return; - nodebuf = path[--level].buffer; - node = buffer2node(nodebuf); - trace(printf("pop to level %i, %i of %i nodes\n", level, path[level].pnext - node->entries, node->count);) - } while (path[level].pnext == node->entries + node->count); - }; -} - -void insert_child(struct enode *node, struct index_entry *p, sector_t child, u64 childkey) -{ - memmove(p + 1, p, (char *)(&node->entries[0] + node->count) - (char *)p); - p->sector = child; - p->key = childkey; - node->count++; -} - -void add_exception_to_tree(struct superblock *sb, struct buffer *leafbuf, u64 target, u64 exception, int snapnum, struct etree_path path[], unsigned levels) -{ - if (!add_exception_to_leaf(buffer2leaf(leafbuf), target, exception, snapnum, sb->snapmask)) { - brelse_dirty(leafbuf); - return; - } - - trace(printf("add leaf\n");) - struct buffer *childbuf = new_leaf(sb); - u64 childkey = split_leaf(buffer2leaf(leafbuf), buffer2leaf(childbuf)); - sector_t childsector = childbuf->sector; - - if (add_exception_to_leaf(target < childkey? buffer2leaf(leafbuf): buffer2leaf(childbuf), target, exception, snapnum, sb->snapmask)) - error("can't happen"); - brelse_dirty(leafbuf); - brelse_dirty(childbuf); - - while (levels--) { - struct index_entry *pnext = path[levels].pnext; - struct buffer *parentbuf = path[levels].buffer; - struct enode *parent = buffer2node(parentbuf); - - if (parent->count < sb->keys_per_node) { - insert_child(parent, pnext, childsector, childkey); - set_buffer_dirty(parentbuf); - return; - } - - unsigned half = parent->count / 2; - u64 newkey = parent->entries[half].key; - struct buffer *newbuf = new_node(sb); - struct enode *newnode = buffer2node(newbuf); - - newnode->count = parent->count - half; - memcpy(&newnode->entries[0], &parent->entries[half], newnode->count * sizeof(struct index_entry)); - parent->count = half; - - if (pnext > &parent->entries[half]) { - pnext = pnext - &parent->entries[half] + newnode->entries; - set_buffer_dirty(parentbuf); - parentbuf = newbuf; - parent = newnode; - } else set_buffer_dirty(newbuf); - - insert_child(parent, pnext, childsector, childkey); - set_buffer_dirty(parentbuf); - childkey = newkey; - childsector = newbuf->sector; - brelse(newbuf); - } - - trace(printf("add tree level\n");) - struct buffer *newrootbuf = new_node(sb); // !!! handle error - struct enode *newroot = buffer2node(newrootbuf); - - newroot->count = 2; - newroot->entries[0].sector = sb->image.etree_root; - newroot->entries[1].key = childkey; - newroot->entries[1].sector = childsector; - sb->image.etree_root = newrootbuf->sector; - sb->image.etree_levels++; - mark_sb_dirty(sb); - brelse_dirty(newrootbuf); -} -#define chunk_highbit ((sizeof(chunk_t) * 8) - 1) - -int finish_copyout(struct superblock *sb) -{ - if (sb->copy_chunks) { - int is_snap = sb->source_chunk >> chunk_highbit; - chunk_t source = sb->source_chunk & ~(1ULL << chunk_highbit); - unsigned size = sb->copy_chunks << sb->image.chunksize_bits; - trace(warn("copy %u %schunks from %Lx to %Lx", sb->copy_chunks, is_snap? "snapshot ": "", source, sb->dest_exception);) - assert(size <= sb->copybuf_size); - pread(is_snap? sb->snapdev: sb->orgdev, sb->copybuf, size, source << sb->image.chunksize_bits); // 64 bit!!! - pwrite(sb->snapdev, sb->copybuf, size, sb->dest_exception << sb->image.chunksize_bits); // 64 bit!!! - sb->copy_chunks = 0; - } - return 0; -} - -int copyout(struct superblock *sb, chunk_t chunk, chunk_t exception) -{ -#if 1 - if (sb->source_chunk + sb->copy_chunks == chunk && - sb->dest_exception + sb->copy_chunks == exception && - sb->copy_chunks < sb->copybuf_size >> sb->image.chunksize_bits) { - sb->copy_chunks++; - return 0; - } - finish_copyout(sb); - sb->copy_chunks = 1; - sb->source_chunk = chunk; - sb->dest_exception = exception; -#else - int is_snap = sb->source_chunk >> chunk_highbit; - chunk_t source = chunk & ~((1ULL << chunk_highbit) - 1); - pread(is_snap? sb->snapdev: sb->orgdev, sb->copybuf, sb->chunksize, source << sb->image.chunksize_bits); // 64 bit!!! - pwrite(sb->snapdev, sb->copybuf, sb->chunksize, exception << sb->image.chunksize_bits); // 64 bit!!! -#endif - return 0; -} - -/* - * This is the bit that does all the work. It's rather arbitrarily - * factored into a probe and test part, then an exception add part, - * called only if an exception for a given chunk isn't already present - * in the Btree. This factoring will change a few more times yet as - * the code gets more asynchronous and multi-threaded. - */ -chunk_t make_unique(struct superblock *sb, chunk_t chunk, int snapnum) -{ - unsigned levels = sb->image.etree_levels; - struct etree_path path[levels + 1]; - struct buffer *leafbuf = probe(sb, chunk, path); - chunk_t exception = 0; - trace(warn("chunk %Lx, snapnum %i", chunk, snapnum)); - - if (snapnum == -1? - origin_chunk_unique(buffer2leaf(leafbuf), chunk, sb->snapmask): - snapshot_chunk_unique(buffer2leaf(leafbuf), chunk, snapnum, &exception)) - { - trace(warn("chunk %Lx already unique in snapnum %i", chunk, snapnum);) - brelse(leafbuf); - } else { - u64 newex = alloc_exception(sb); -// if (snapnum == -1) - copyout(sb, exception? (exception | (1ULL << chunk_highbit)): chunk, newex); - add_exception_to_tree(sb, leafbuf, chunk, newex, snapnum, path, levels); - exception = newex; - } - brelse_path(path, levels); - return exception; -} - -int test_unique(struct superblock *sb, chunk_t chunk, int snapnum, chunk_t *exception) -{ - unsigned levels = sb->image.etree_levels; - struct etree_path path[levels + 1]; - struct buffer *leafbuf = probe(sb, chunk, path); - trace(warn("chunk %Lx, snapnum %i", chunk, snapnum)); - int result = snapnum == -1? - origin_chunk_unique(buffer2leaf(leafbuf), chunk, sb->snapmask): - snapshot_chunk_unique(buffer2leaf(leafbuf), chunk, snapnum, exception); - brelse(leafbuf); - brelse_path(path, levels); - return result; -} - -/* Snapshot Store Superblock handling */ - -u64 calc_snapmask(struct superblock *sb) -{ - u64 mask = 0; - int i; - - for (i = 0; i < sb->image.snapshots; i++) - mask |= 1ULL << sb->image.snaplist[i].bit; - - return mask; -} - -int tag2snapnum(struct superblock *sb, unsigned tag) -{ - unsigned i, n = sb->image.snapshots; - - for (i = 0; i < n; i++) - if (sb->image.snaplist[i].tag == tag) - return sb->image.snaplist[i].bit; - - return -1; -} - -int snapnum2tag(struct superblock *sb, unsigned bit) -{ - unsigned i, n = sb->image.snapshots; - - for (i = 0; i < n; i++) - if (sb->image.snaplist[i].bit == bit) - return sb->image.snaplist[i].tag; - - return -1; -} - -int create_snapshot(struct superblock *sb, unsigned snaptag) -{ - unsigned i, snapshots = sb->image.snapshots; - struct snapshot *snapshot; - - /* Check tag not already used */ - for (i = 0; i < snapshots; i++) - if (sb->image.snaplist[i].tag == snaptag) - return -1; - - /* Find available snapshot bit */ - for (i = 0; i < MAX_SNAPSHOTS; i++) - if (!(sb->snapmask & (1ULL << i))) - goto create; - return -EFULL; - -create: - trace_on(printf("Create snapshot %i (internal %i)\n", snaptag, i);) - snapshot = sb->image.snaplist + sb->image.snapshots++; - *snapshot = (struct snapshot){ .tag = snaptag, .bit = i, .create_time = time(NULL) }; - sb->snapmask |= (1ULL << i); - mark_sb_dirty(sb); - return i; -}; - -/* - * delete_snapshot: remove all exceptions from a given snapshot from a leaf - * working from top to bottom of the exception list clearing snapshot bits - * and packing the nonzero exceptions into the top of the block. Then work - * from bottom to top in the directory map packing nonempty entries into the - * bottom of the map. - */ - -void delete_snapshots_from_leaf(struct superblock *sb, struct eleaf *leaf, u64 snapmask) -{ - struct exception *p = emap(leaf, leaf->count), *dest = p; - struct etree_map *pmap, *dmap; - unsigned i; - - /* Scan top to bottom clearing snapshot bit and moving - * non-zero entries to top of block */ - for (i = leaf->count; i--;) { - while (p != emap(leaf, i)) - if (((--p)->share &= ~snapmask)) - *--dest = *p; - else - free_chunk(sb, p->chunk); - leaf->map[i].offset = (char *)dest - (char *)leaf; - } - /* Remove empties from map */ - dmap = pmap = &leaf->map[0]; - for (i = 0; i < leaf->count; i++, pmap++) - if (pmap->offset != (pmap + 1)->offset) - *dmap++ = *pmap; - dmap->offset = pmap->offset; - dmap->rchunk = 0; // tidy up - leaf->count = dmap - &leaf->map[0]; -} - -void delete_snapshots_from_tree(struct superblock *sb, u64 snapmask) -{ - int levels = sb->image.etree_levels, level = -1; - struct etree_path path[levels]; - struct buffer *nodebuf; - struct enode *node; - - trace_on(printf("delete snapshot mask %Lx\n", snapmask);) - while (1) { - do { - level++; - nodebuf = snapread(sb, level? path[level - 1].pnext++->sector: sb->image.etree_root); - node = buffer2node(nodebuf); - path[level].buffer = nodebuf; - path[level].pnext = node->entries; - trace(printf("push to level %i, %i nodes\n", level, node->count);) - } while (level < levels - 1); - - trace(printf("do %i leaf nodes\n", node->count);) - while (path[level].pnext < node->entries + node->count) { - struct buffer *leafbuf = snapread(sb, path[level].pnext++->sector); - trace_off(printf("process leaf %Lx\n", leafbuf->sector);) - delete_snapshots_from_leaf(sb, buffer2leaf(leafbuf), snapmask); - brelse(leafbuf); - } - - do { - brelse(nodebuf); - if (!level) - return; - nodebuf = path[--level].buffer; - node = buffer2node(nodebuf); - trace(printf("pop to level %i, %i of %i nodes\n", level, path[level].pnext - node->entries, node->count);) - } while (path[level].pnext == node->entries + node->count); - }; -} - -int delete_snapshot(struct superblock *sb, unsigned tag) -{ - struct snapshot *snapshot; - unsigned i, bit; - - for (i = 0; i < sb->image.snapshots; i++) - if (sb->image.snaplist[i].tag == tag) - goto delete; - return -1; - -delete: - snapshot = sb->image.snaplist + i; - bit = snapshot->bit; - trace_on(printf("Delete snapshot %i (internal %i)\n", tag, bit);) - memmove(snapshot, snapshot + 1, (char *)(sb->image.snaplist + --sb->image.snapshots) - (char *)snapshot); - sb->snapmask &= ~(1ULL << bit); - delete_snapshots_from_tree(sb, 1ULL << bit); - mark_sb_dirty(sb); - return bit; -}; - -void show_snapshots(struct superblock *sb) -{ - unsigned snapnum, snapshots = sb->image.snapshots; - - printf("%u snapshots\n", snapshots); - for (snapnum = 0; snapnum < snapshots; snapnum++) { - struct snapshot *snapshot = sb->image.snaplist + snapnum; - printf("snapshot %u tag %u created %x\n", - snapshot->bit, - snapshot->tag, - snapshot->create_time); - } -}; - -/* Lock snapshot reads against origin writes */ - -static void reply(fd_t sock, struct messagebuf *message) -{ - trace(warn("%x/%u", message->head.code, message->head.length);) - writepipe(sock, &message->head, message->head.length + sizeof(message->head)); -} - -struct client -{ - u64 id; - fd_t sock; - int snap; -}; - -struct pending -{ - unsigned holdcount; - struct client *client; - struct messagebuf message; -}; - -struct snaplock_wait -{ - struct pending *pending; - struct snaplock_wait *next; -}; - -struct snaplock_hold -{ - struct client *client; - struct snaplock_hold *next; -}; - -struct snaplock -{ - struct snaplock_wait *waitlist; - struct snaplock_hold *holdlist; - struct snaplock *next; - chunk_t chunk; -}; - -struct snaplock *new_snaplock(struct superblock *sb) -{ - return malloc(sizeof(struct snaplock)); -} - -struct snaplock_wait *new_snaplock_wait(struct superblock *sb) -{ - return malloc(sizeof(struct snaplock_wait)); -} - -struct snaplock_hold *new_snaplock_hold(struct superblock *sb) -{ - return malloc(sizeof(struct snaplock_hold)); -} - -void free_snaplock(struct superblock *sb, struct snaplock *p) -{ - free(p); -} - -void free_snaplock_hold(struct superblock *sb, struct snaplock_hold *p) -{ - free(p); -} - -void free_snaplock_wait(struct superblock *sb, struct snaplock_wait *p) -{ - free(p); -} - -unsigned snaplock_hash(struct superblock *sb, chunk_t chunk) -{ - return ((u32)(chunk * 3498734713U)) >> (32 - sb->snaplock_hash_bits); -} - -struct snaplock *find_snaplock(struct snaplock *list, chunk_t chunk) -{ - for (; list; list = list->next) - if (list->chunk == chunk) - return list; - return NULL; -} - -void waitfor_chunk(struct superblock *sb, chunk_t chunk, struct pending **pending) -{ - struct snaplock *lock; - if ((lock = find_snaplock(sb->snaplocks[snaplock_hash(sb, chunk)], chunk))) { - if (!*pending) { - // arguably we should know the client and fill it in here - *pending = calloc(1, sizeof(struct pending)); - (*pending)->holdcount = 1; - } - struct snaplock_wait *wait = new_snaplock_wait(sb); - wait->pending = *pending; - wait->next = lock->waitlist; - lock->waitlist = wait; - (*pending)->holdcount++; - } -} - -void readlock_chunk(struct superblock *sb, chunk_t chunk, struct client *client) -{ - struct snaplock **bucket = &sb->snaplocks[snaplock_hash(sb, chunk)]; - struct snaplock *lock; - - if (!(lock = find_snaplock(*bucket, chunk))) { - lock = new_snaplock(sb); - *lock = (struct snaplock){ .chunk = chunk, .next = *bucket }; - *bucket = lock; - } - struct snaplock_hold *hold = new_snaplock_hold(sb); - hold->client = client; - hold->next = lock->holdlist; - lock->holdlist = hold; -} - -struct snaplock *release_lock(struct superblock *sb, struct snaplock *lock, struct client *client) -{ - struct snaplock *ret = lock; - struct snaplock_hold **holdp = &lock->holdlist; - while (*holdp && (*holdp)->client != client) - holdp = &(*holdp)->next; - - if (!*holdp) { - trace_on(printf("chunk %Lx holder %Lu not found\n", lock->chunk, client->id);) - return NULL; - } - - /* Delete and free holder record */ - struct snaplock_hold *next = (*holdp)->next; - free_snaplock_hold(sb, *holdp); - *holdp = next; - - if (lock->holdlist) - return ret; - - /* Release and delete waiters, delete lock */ - struct snaplock_wait *list = lock->waitlist; - while (list) { - struct snaplock_wait *next = list->next; - assert(list->pending->holdcount); - if (!--(list->pending->holdcount)) { - struct pending *pending = list->pending; - reply(pending->client->sock, &pending->message); - free(pending); - } - free_snaplock_wait(sb, list); - list = next; - } - ret = lock->next; - free_snaplock(sb, lock); - return ret; -} - -int release_chunk(struct superblock *sb, chunk_t chunk, struct client *client) -{ - trace(printf("release %Lx\n", chunk);) - struct snaplock **lockp = &sb->snaplocks[snaplock_hash(sb, chunk)]; - - /* Find pointer to lock record */ - while (*lockp && (*lockp)->chunk != chunk) - lockp = &(*lockp)->next; - struct snaplock *next, *lock = *lockp; - - if (!lock) { - trace_on(printf("chunk %Lx not locked\n", chunk);) - return -1; - } - - next = release_lock(sb, lock, client); - if (!next) - return -2; - *lockp = next; - return 0; -} - -void show_locks(struct superblock *sb) -{ - unsigned n = 0, i; - for (i = 0; i < (1 << sb->snaplock_hash_bits); i++) { - struct snaplock *lock = sb->snaplocks[i]; - if (!lock) - continue; - if (!n) printf("Locks:\n"); - printf("[%03u] ", i); - do { - printf("chunk %Lx ", lock->chunk); - struct snaplock_hold *hold = lock->holdlist; - for (; hold; hold = hold->next) - printf("held by client %Lu ", hold->client->id); - struct snaplock_wait *wait = lock->waitlist; - for (; wait; wait = wait->next) - printf("wait [%02hx/%u] ", snaplock_hash(sb, (u32)wait->pending), wait->pending->holdcount); - } while ((lock = lock->next)); - printf("\n"); - n++; - } - if (!n) printf("-- no locks --\n"); -} - -/* Build up a response as a list of chunk ranges */ - -struct addto -{ - unsigned count; - chunk_t firstchunk; - chunk_t nextchunk; - struct rwmessage *reply; - shortcount *countp; - chunk_t *top; - char *lim; -}; - -void check_response_full(struct addto *r, unsigned bytes) -{ - if ((char *)r->top < r->lim - bytes) - return; - error("Need realloc"); -} - -void addto_response(struct addto *r, chunk_t chunk) -{ - if (chunk != r->nextchunk) { - if (r->top) { - trace_off(warn("finish old range\n");) - *(r->countp) = (r->nextchunk - r->firstchunk); - } else { - trace_off(warn("alloc new reply");) - r->reply = (void *) malloc(sizeof(struct messagebuf)); - r->top = (chunk_t *)(((char *)r->reply) + sizeof(struct head) + offsetof(struct rw_request, ranges)); - r->lim = ((char *)r->reply) + maxbody; - r->count++; - } - trace_off(warn("start new range");) - check_response_full(r, 2*sizeof(chunk_t)); - r->firstchunk = *(r->top)++ = chunk; - r->countp = (shortcount *)r->top; - r->top = (chunk_t *)(((shortcount *)r->top) + 1); - } - r->nextchunk = chunk + 1; -} - -int finish_reply_(struct addto *r, unsigned code, unsigned id) -{ - if (!r->countp) - return 0; - - *(r->countp) = (r->nextchunk - r->firstchunk); - r->reply->head.code = code; - r->reply->head.length = (char *)r->top - (char *)r->reply - sizeof(struct head); - r->reply->body.id = id; - r->reply->body.count = r->count; - return 1; -} - -void finish_reply(int sock, struct addto *r, unsigned code, unsigned id) -{ - if (finish_reply_(r, code, id)) - reply(sock, (struct messagebuf *)r->reply); - free(r->reply); -} - -/* Initialization, State load/save */ - -void setup_sb(struct superblock *sb) -{ - unsigned blocksize_bits = sb->image.blocksize_bits; - unsigned chunksize_bits = sb->image.blocksize_bits; - sb->blocksize = 1 << blocksize_bits; - sb->chunksize = 1 << chunksize_bits, - sb->sectors_per_block_bits = blocksize_bits - SECTOR_BITS; - sb->sectors_per_chunk_bits = chunksize_bits - SECTOR_BITS; - sb->keys_per_node = (sb->blocksize - offsetof(struct enode, entries)) / sizeof(struct index_entry); -#ifdef BUSHY - sb->keys_per_node = 10; -#endif - sb->copybuf = malloc_aligned(sb->copybuf_size = (32 * sb->chunksize), 4096); // !!! check failed - sb->sectors_per_block = 1 << sb->sectors_per_block_bits; - sb->sectors_per_chunk = 1 << sb->sectors_per_chunk_bits; - sb->snapmask = 0; - sb->flags = 0; - - sb->max_commit_blocks = (sb->blocksize - sizeof(struct commit_block)) / sizeof(sector_t); - - unsigned snaplock_hash_bits = 8; - sb->snaplock_hash_bits = snaplock_hash_bits; - sb->snaplocks = (struct snaplock **)calloc(1 << snaplock_hash_bits, sizeof(struct snaplock *)); -} - -void load_sb(struct superblock *sb) -{ - struct buffer *buffer = bread(sb->snapdev, SB_LOC, 4096); - memcpy(&sb->image, buffer->data, sizeof(sb->image)); - assert(!memcmp(sb->image.magic, SB_MAGIC, sizeof(sb->image.magic))); - brelse(buffer); - setup_sb(sb); - sb->snapmask = calc_snapmask(sb); - trace_on(printf("Active snapshot mask: %016llx\n", sb->snapmask);) -} - -void save_sb(struct superblock *sb) -{ - if (sb->flags & SB_DIRTY) { - struct buffer *buffer = getblk(sb->snapdev, SB_LOC, 4096); - memcpy(buffer->data, &sb->image, sizeof(sb->image)); - write_buffer(buffer); - brelse(buffer); - sb->flags &= ~SB_DIRTY; - } -} - -void save_state(struct superblock *sb) -{ - flush_buffers(); - save_sb(sb); -} - -/* - * This source compiles either the snapshot server or the snapshot store setup - * utility, depending on whether the macro variable CREATE is defined. - * - * I'll leave all the testing hooks lying around in the main routine for now, - * since the low level components still tend to break every now and then and - * require further unit testing. - */ - -int init_snapstore(struct superblock *sb) -{ - int i, error; - - unsigned sectors_per_block_bits = 3; - sb->image = (struct disksuper){ .magic = SB_MAGIC }; - sb->image.etree_levels = 1, - sb->image.blocksize_bits = SECTOR_BITS + sectors_per_block_bits; - sb->image.chunksize_bits = sb->image.blocksize_bits; // !!! just for now - setup_sb(sb); - - u64 size; - if ((error = fd_size(sb->snapdev, &size))) - error("Error %i: %s determining snapshot store size", error, strerror(error)); - sb->image.chunks = size >> sb->image.chunksize_bits; - if ((error = fd_size(sb->orgdev, &size))) - error("Error %i: %s determining origin volume size", errno, strerror(errno)); - sb->image.orgchunks = size >> sb->image.chunksize_bits; - - sb->image.journal_size = 100; -#ifdef TEST_JOURNAL - sb->image.journal_size = 5; -#endif - sb->image.journal_next = 0; - sb->image.sequence = sb->image.journal_size; - init_allocation(sb); - mark_sb_dirty(sb); - - for (i = 0; i < sb->image.journal_size; i++) { - struct buffer *buffer = jgetblk(sb, i); - struct commit_block *commit = (struct commit_block *)buffer->data; - *commit = (struct commit_block){ .magic = JMAGIC, .sequence = i }; -#ifdef TEST_JOURNAL - commit->sequence = (i + 3) % 5 ; -#endif - commit->checksum = -checksum_block(sb, (void *)commit); - brelse_dirty(buffer); - } -#ifdef TEST_JOURNAL -show_journal(sb); -show_tree(sb); -flush_buffers(); -recover_journal(sb); -show_buffers(); -#endif - -#if 0 - printf("chunk = %Lx\n", alloc_chunk_range(sb, sb->image.chunks - 1, 1)); -// struct buffer *buffer = snapread(sb, sb->image.bitmap_base + 3 * 8); -// dump_buffer(buffer, 4090, 6); -return 0; -#endif - -#if 0 - grab_chunk(sb, 32769); - struct buffer *buffer = snapread(sb, sb->image.bitmap_base + 8); - printf("sector %Lx\n", buffer->sector); - free_chunk(sb, 32769); -return 0; -#endif - - struct buffer *leafbuf = new_leaf(sb); - struct buffer *rootbuf = new_node(sb); - buffer2node(rootbuf)->count = 1; - buffer2node(rootbuf)->entries[0].sector = leafbuf->sector; - sb->image.etree_root = rootbuf->sector; - -#if 0 - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); -// free_chunk(sb, 23); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); - printf("chunk = %Lx\n", alloc_chunk(sb)); -return 0; -#endif - - brelse_dirty(rootbuf); - brelse_dirty(leafbuf); -#ifdef TEST_JOURNAL - show_buffers(); - show_dirty_buffers(); - commit_transaction(sb); - evict_buffers(); - - show_journal(sb); - show_tree(sb); - recover_journal(sb); - evict_buffers(); - show_tree(sb); -#endif - save_state(sb); - return 0; -} - -int client_locks(struct superblock *sb, struct client *client, int check) -{ - int i; - - for (i = 0; i < (1 << sb->snaplock_hash_bits); i++) { - struct snaplock **lockp = &sb->snaplocks[i]; - - while (*lockp) { - struct snaplock_hold *hold; - - for (hold = (*lockp)->holdlist; hold; hold = hold->next) - if (hold->client == client) { - if (check) - return 1; - *lockp = release_lock(sb, *lockp, client); - goto next; - } - lockp = &(*lockp)->next; -next: - continue; - } - } - return 0; -} - -#define check_client_locks(x, y) client_locks(x, y, 1) -#define free_client_locks(x, y) client_locks(x, y, 0) - -/* - * Responses to IO requests take two quite different paths through the - * machinery: - * - * - Origin write requests are just sent back with their message - * code changed, unless they have to wait for a snapshot read - * lock in which case the incoming buffer is copied and the - * response takes a kafkaesque journey through the read locking - * beaurocracy. - * - * - Responses to snapshot read or write requests have to be built - * up painstakingly in allocated buffers, keeping a lot of state - * around so that they end up with a minimum number of contiguous - * chunk ranges. Once complete they can always be sent - * immediately. - * - * To mess things up further, snapshot read requests can return both - * a list of origin ranges and a list of snapshot store ranges. In - * the latter case the specific snapshot store chunks in each logical - * range are also returned, because they can (normally will) be - * discontiguous. This goes back to the client in two separate - * messages, on the theory that the client will find it nice to be - * able to process the origin read ranges and snapshot read chunks - * separately. We'll see how good an idea that is. - * - * The implementation ends up looking nice and tidy, but appearances - * can be deceiving. - */ -int incoming(struct superblock *sb, struct client *client) -{ - struct messagebuf message; - unsigned sock = client->sock; - int i, j, err; - - if ((err = readpipe(sock, &message.head, sizeof(message.head)))) - goto pipe_error; - trace(warn("%x/%u", message.head.code, message.head.length);) - if (message.head.length > maxbody) - goto message_too_long; - if ((err = readpipe(sock, &message.body, message.head.length))) - goto pipe_error; - - switch (message.head.code) { - case QUERY_WRITE: - if (client->snap == -1) { - struct pending *pending = NULL; - struct rw_request *body = (struct rw_request *)message.body; - struct chunk_range *p = body->ranges; - chunk_t chunk; - if (message.head.length < sizeof(*body)) - goto message_too_short; - trace(printf("origin write query, %u ranges\n", body->count);) - - for (i = 0; i < body->count; i++, p++) - for (j = 0, chunk = p->chunk; j < p->chunks; j++, chunk++) - if (make_unique(sb, chunk, -1)) - waitfor_chunk(sb, chunk, &pending); - finish_copyout(sb); - commit_transaction(sb); - - message.head.code = REPLY_ORIGIN_WRITE; - if (pending) { - pending->client = client; - memcpy(&pending->message, &message, message.head.length + sizeof(struct head)); - pending->holdcount--; - break; - } - reply(sock, &message); - break; - } else { - struct rw_request *body = (struct rw_request *)message.body; - if (message.head.length < sizeof(*body)) - goto message_too_short; - trace(printf("snapshot write request, %u ranges\n", body->count);) - struct addto snap = { .nextchunk = -1 }; - - for (i = 0; i < body->count; i++) - for (j = 0; j < body->ranges[i].chunks; j++) { - chunk_t chunk = body->ranges[i].chunk + j; - chunk_t exception = make_unique(sb, chunk, client->snap); - trace(printf("exception = %Lx\n", exception);) - addto_response(&snap, chunk); - check_response_full(&snap, sizeof(chunk_t)); - *(snap.top)++ = exception; - } - finish_copyout(sb); - commit_transaction(sb); - finish_reply(client->sock, &snap, REPLY_SNAPSHOT_WRITE, body->id); - break; - } - - case QUERY_SNAPSHOT_READ: - { - struct rw_request *body = (struct rw_request *)message. body; - if (message.head.length < sizeof(*body)) - goto message_too_short; - trace(printf("snapshot read request, %u ranges\n", body->count);) - struct addto snap = { .nextchunk = -1 }, org = { .nextchunk = -1 }; - - for (i = 0; i < body->count; i++) - for (j = 0; j < body->ranges[i].chunks; j++) { - chunk_t chunk = body->ranges[i].chunk + j, exception = 0; - trace(warn("read %Lx", chunk)); - test_unique(sb, chunk, client->snap, &exception); - if (exception) { - trace(warn("read exception %Lx", exception)); - addto_response(&snap, chunk); - check_response_full(&snap, sizeof(chunk_t)); - *(snap.top)++ = exception; - } else { - trace(warn("read origin %Lx", chunk)); - addto_response(&org, chunk); - readlock_chunk(sb, chunk, client); - } - } - finish_reply(client->sock, &org, REPLY_SNAPSHOT_READ_ORIGIN, body->id); - finish_reply(client->sock, &snap, REPLY_SNAPSHOT_READ, body->id); - break; - } - - case FINISH_SNAPSHOT_READ: - { - struct rw_request *body = (struct rw_request *)message.body; - if (message.head.length < sizeof(*body)) - goto message_too_short; - trace(printf("finish snapshot read, %u ranges\n", body->count);) - - for (i = 0; i < body->count; i++) - for (j = 0; j < body->ranges[i].chunks; j++) - release_chunk(sb, body->ranges[i].chunk + j, client); - - break; - } - - case IDENTIFY: - { - int tag = ((struct identify *)message.body)->snap, snap = tag2snapnum(sb, tag); - if (snap >= 0) - client->snap = snap; - client->id = ((struct identify *)message.body)->id; - warn("client id %Li, snapshot %i (snapnum %i)", client->id, tag, snap); - outbead(sock, REPLY_IDENTIFY, struct { }); - break; - } - - case UPLOAD_LOCK: - break; - - case FINISH_UPLOAD_LOCK: - break; - - case CREATE_SNAPSHOT: - create_snapshot(sb, ((struct create_snapshot *)message.body)->snap); - save_state(sb); - outbead(sock, REPLY_CREATE_SNAPSHOT, struct { }); - break; - - case DELETE_SNAPSHOT: - delete_snapshot(sb, ((struct create_snapshot *)message.body)->snap); - save_state(sb); - outbead(sock, REPLY_DELETE_SNAPSHOT, struct { }); - break; - - case INITIALIZE_SNAPSTORE: - init_snapstore(sb); - break; - - case DUMP_TREE: - show_tree(sb); - break; - - case START_SERVER: - warn("Activating server"); - load_sb(sb); - if (sb->image.flags & SB_BUSY) { - warn("Server was not shut down properly"); - jtrace(show_journal(sb);) - recover_journal(sb); - } else { - sb->image.flags |= SB_BUSY; - mark_sb_dirty(sb); - save_sb(sb); - } - break; - - case SHUTDOWN_SERVER: - return -2; - - default: - outbead(sock, REPLY_ERROR, struct { int code; char error[50]; }, message.head.code, "Unknown message"); // wrong!!! - } - -#if 0 - static int messages = 0; - if (++messages == 5) { - warn(">>>>Simulate server crash<<<<"); - exit(1); - } -#endif - return 0; - -message_too_long: - warn("message %x too long (%u bytes)\n", message.head.code, message.head.length); - return -1; -message_too_short: - warn("message %x too short (%u bytes)\n", message.head.code, message.head.length); - return -1; -pipe_error: - return -1; /* we quietly drop the client if the connect breaks */ -} - -/* Signal Delivery via pipe */ - -static int sigpipe; - -void sighandler(int signum) -{ - trace_off(printf("caught signal %i\n", signum);) - write(sigpipe, (char[]){signum}, 1); -} - -int cleanup(struct superblock *sb) -{ - warn("cleaning up"); - sb->image.flags &= ~SB_BUSY; - mark_sb_dirty(sb); - save_state(sb); - return 0; -} - -int resolve_host(char *name, int family, void *result, int length) -{ - struct hostent host, *bogus; - char work[500]; - int err, dumb; - - if ((err = gethostbyname2_r(name, family, &host, work, sizeof(work), &bogus, &dumb))) { - errno = err; - return -1; - } - memcpy(result, host.h_addr_list[0], host.h_length); - return host.h_length; -} - -int resolve_self(int family, void *result, int length) -{ - char name[HOST_NAME_MAX + 1]; - if (gethostname(name, HOST_NAME_MAX) == -1) - return -1; - - return resolve_host(name, family, result, length); -} - -int csnap_server(struct superblock *sb, char *sockname, int port) -{ - unsigned maxclients = 100, clients = 0, others = 3; - struct client *clientvec[maxclients]; - struct pollfd pollvec[others+maxclients]; - int listener, getsig, pipevec[2], err = 0; - - if (pipe(pipevec)) - error("Can't open pipe"); - sigpipe = pipevec[1]; - getsig = pipevec[0]; - - struct server server = { .port = htons(port), .type = AF_INET, }; - - if ((listener = socket(AF_INET, SOCK_STREAM, 0)) < 0) - error("Can't get socket"); - - if (bind(listener, - (struct sockaddr *)&(struct sockaddr_in){ - .sin_family = server.type, - .sin_port = server.port, - .sin_addr = { .s_addr = INADDR_ANY } }, - sizeof(struct sockaddr_in)) < 0) - error("Can't bind to socket"); - listen(listener, 5); - - warn("csnap server bound to port %i", port); - - /* Get agent connection */ - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - int addr_len = sizeof(addr) - sizeof(addr.sun_path) + strlen(sockname); - int sock, len; - - trace(warn("Connect to control socket %s", sockname);) - if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - error("Can't get socket"); - strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); - if (sockname[0] == '@') - addr.sun_path[0] = 0; - - if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) - error("Can't connect to control socket"); - - trace_on(warn("Received control connection");) - pollvec[2] = (struct pollfd){ .fd = sock, .events = POLLIN }; - - if ((len = resolve_self(AF_INET, server.address, sizeof(server.address))) == -1) - error("Can't get own address, %s (%i)", strerror(errno), errno); - server.address_len = len; - warn("host = %x/%u", *(int *)server.address, server.address_len); - writepipe(sock, &(struct head){ SERVER_READY, sizeof(server) }, sizeof(struct head)); - writepipe(sock, &server, sizeof(server)); - -#if 1 - switch (fork()) { - case -1: - error("fork failed"); - case 0: // !!! daemonize goes here - break; - default: - return 0; - } -#endif - - pollvec[0] = (struct pollfd){ .fd = listener, .events = POLLIN }; - pollvec[1] = (struct pollfd){ .fd = getsig, .events = POLLIN }; - - signal(SIGINT, sighandler); - signal(SIGTERM, sighandler); - signal(SIGPIPE, SIG_IGN); - - while (1) { - int activity = poll(pollvec, others+clients, -1); - - if (activity < 0) { - if (errno != EINTR) - error("poll failed, %s", strerror(errno)); - continue; - } - - if (!activity) { - printf("waiting...\n"); - continue; - } - - /* New connection? */ - if (pollvec[0].revents) { - struct sockaddr_in addr; - int addr_len = sizeof(addr), sock; - - if (!(sock = accept(listener, (struct sockaddr *)&addr, &addr_len))) - error("Cannot accept connection"); - - trace_on(warn("Received connection");) - assert(clients < maxclients); // !!! send error and disconnect - - struct client *client = malloc(sizeof(struct client)); - *client = (struct client){ .sock = sock }; - clientvec[clients] = client; - pollvec[others+clients] = (struct pollfd){ .fd = sock, .events = POLLIN }; - clients++; - } - - /* Signal? */ - if (pollvec[1].revents) { - u8 sig = 0; - /* it's stupid but this read also gets interrupted, so... */ - do { } while (read(getsig, &sig, 1) == -1 && errno == EINTR); - trace_on(warn("caught signal %i", sig);) - cleanup(sb); // !!! don't do it on segfault - if (sig == SIGINT) { - signal(SIGINT, SIG_DFL); - kill(getpid(), sig); /* commit harikiri */ - } - goto done; - } - - /* Agent message? */ - if (pollvec[2].revents) - incoming(sb, &(struct client){ .sock = sock, .id = -2, .snap = -2 }); - - /* Client message? */ - unsigned i = 0; - while (i < clients) { - if (pollvec[others+i].revents) { // !!! check for poll error - struct client *client = clientvec[i]; - int result; - - trace_off(printf("event on socket %i = %x\n", client->sock, pollvec[others+i].revents);) - if ((result = incoming(sb, client)) == -1) { - warn("Client %Li disconnected", client->id); - save_state(sb); // !!! just for now - close(client->sock); - free(client); - --clients; - clientvec[i] = clientvec[clients]; - pollvec[others + i] = pollvec[others + clients]; - continue; - } - - if (result == -2) { // !!! wrong !!! - cleanup(sb); - goto done; - } - } - i++; - } - } -done: - // in a perfect world we'd close all the connections - close(listener); - return err; -} - -int main(int argc, char *argv[]) -{ - struct superblock *sb = &(struct superblock){}; - - init_buffers(); -#ifdef SERVER - if (argc < 5) - error("usage: %s dev/snapshot dev/origin socket port", argv[0]); -#else - if (argc < 3) - error("usage: %s dev/snapshot dev/origin", argv[0]); -#endif - if (!(sb->snapdev = open(argv[1], O_RDWR | O_DIRECT))) - error("Could not open snapshot store %s", argv[1]); - - if (!(sb->orgdev = open(argv[2], O_RDONLY | O_DIRECT))) - error("Could not open origin volume %s", argv[2]); -#ifdef SERVER - return csnap_server(sb, argv[3], atoi(argv[4])); -#else - return init_snapstore(sb); -#endif - - void *useme = _show_journal; - useme = useme; -} diff --git a/csnap/csnap.h b/csnap/csnap.h deleted file mode 100644 index ce645c6..0000000 --- a/csnap/csnap.h +++ /dev/null @@ -1,44 +0,0 @@ -#define u8 unsigned char -#define u16 unsigned short -#define s16 short -#define s32 int -#define u32 unsigned -#define u64 unsigned long long - -#define le_u32 u32 -#define le_u16 u16 -#define le_u64 u64 -#define u64 unsigned long long -#define EFULL ENOMEM -#define PACKED __attribute__ ((packed)) - -static inline int readpipe(int fd, void *buffer, size_t count) -{ - // printf("read %u bytes\n", count); - int n; - while (count) { - if ((n = read(fd, buffer, count)) < 1) - return n? n: -EPIPE; - buffer += n; - count -= n; - } - return 0; -} - -#define writepipe write - -#define outbead(SOCK, CODE, STRUCT, VALUES...) ({ \ - struct { struct head head; STRUCT body; } PACKED message = \ - { { CODE, sizeof(STRUCT) }, { VALUES } }; \ - writepipe(SOCK, &message, sizeof(message)); }) - -typedef unsigned long long chunk_t; - -#define MAX_ADDRESS 16 - -struct server { u16 port; u8 type; u8 address_len; char address[MAX_ADDRESS]; } PACKED; - -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 256 -#endif - diff --git a/csnap/devpoke.c b/csnap/devpoke.c deleted file mode 100644 index 57a7fed..0000000 --- a/csnap/devpoke.c +++ /dev/null @@ -1,55 +0,0 @@ -#define _GNU_SOURCE /* Berserk glibc headers: O_DIRECT not defined unless _GNU_SOURCE defined */ -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); - -#define trace_on(args) args -#define trace_off(args) -#define BREAK asm("int3") -#define warn(string, args...) do { fprintf(stderr, "%s: " string "\n", __FILE__, ##args); } while (0) -#define error(string, args...) do { warn(string, ##args); BREAK; } while (0) - -#define trace trace_on - -void *malloc_aligned(size_t size, unsigned binalign) -{ - unsigned long p = (unsigned long)malloc(size + binalign - 1); - return (void *)(p + (-p & (binalign - 1))); -} - -int main(int argc, char *argv[]) -{ - int err, dev, iterations = 1, blockshift = 13, blocksize = 1 << blockshift; - char *buffer = malloc_aligned(blocksize, blocksize); - - if (!(dev = open(argv[1], O_RDWR | O_DIRECT))) - error("Could not open %s", argv[1]); - if (argc < 3 || argc > 4) - error("usage: %s device read/write [iterations]", argv[0]); - if (argc > 3) - iterations = atoi(argv[3]); - - int rw = !strcmp(argv[2], "write"); - typeof(pread) *fn = rw? ((typeof(pread) *)pwrite): pread; - char *what = rw? "write": "read"; - unsigned range = (lseek(dev, 0, SEEK_END) >> blockshift), total = 0; - - printf("range = %u, iterations = %u\n", range, iterations); - - while (iterations--) { - unsigned block = 1? (rand() % range): total; - trace(warn("%s block %x", what, block);) - if ((err = fn(dev, buffer, blocksize, block << blockshift)) < 0) - error("poke error %i", err); - trace(warn("...block %x done", block);) - total++; - } - - return err; -} diff --git a/csnap/devspam.c b/csnap/devspam.c deleted file mode 100644 index 09eb1ce..0000000 --- a/csnap/devspam.c +++ /dev/null @@ -1,83 +0,0 @@ -#define _GNU_SOURCE /* O_DIRECT */ -#define _XOPEN_SOURCE 500 /* pwrite */ -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#define error(string, args...) do { printf(string "\n", ##args); exit(1); } while (0) - -void *malloc_aligned(size_t size, unsigned binalign) -{ - unsigned long p = (unsigned long)malloc(size + binalign - 1); - return (void *)(p + (-p & (binalign - 1))); -} - -void spamdata(char *buf, unsigned len, unsigned tag, unsigned block) -{ - int i, j, k, n = len / 16; - char *p = buf; - - for(i = 0; i < n; i++) { - int spams[3] = { tag, block, i }; - memcpy(p, "SPAM", 4); - p += 4; - for(j = 0; j < 3; j++) { - int v = spams[j]; - for (k = 0; k < 4; k++,v <<= 4) { - int d = (v >> 12) & 0xf; - *p++ = d < 10? d + '0': d - 10 + 'a'; - } - } - } - /* assert(p == buf + len); */ -} - -int main(int argc, char *argv[]) -{ - #define ncommands 4 - char *commands[ncommands] = { "read", "write", "randread", "randwrite" }; - int err, dev, command, blockshift = 12, blocksize = 1 << blockshift; - char *buffer = malloc_aligned(blocksize, blocksize); - char *buffer2 = malloc(blocksize); - - if (argc != 5) -usage: error("usage: %s device read/write/randread/randwrite tag iterations", argv[0]); - - if ((dev = open(argv[1], O_RDWR | O_DIRECT)) == -1) - error("Can't open %s, %s", argv[1], strerror(errno)); - - for (command = 0; command < ncommands; command++) - if (!strcmp(argv[2], commands[command])) - break; - - if (command == ncommands) - goto usage; - - int code = atoi(argv[4]), iterations = atoi(argv[3]); - int is_write = command & 1, is_rand = command >> 1; - unsigned range = (lseek(dev, 0, SEEK_END) >> blockshift), total = 0; - typeof(pread) *fn = is_write? ((typeof(pread) *)pwrite): pread; - - printf("spam code = %u, iterations = %u, range = %u\n", code, iterations, range); - - while (iterations--) { - unsigned block = is_rand? (rand() % range): total; - - if (is_write) - spamdata(buffer, blocksize, code, block); - - if ((err = fn(dev, buffer, blocksize, block << blockshift)) < 0) - error("spam %s error %i", commands[command], err); - - if (!is_write) { - spamdata(buffer2, blocksize, code, block); - if (memcmp(buffer, buffer2, blocksize)) - printf("block %u doesn't match\n", block); - } - total++; - } - return err; -} diff --git a/csnap/doc/cluster.snapshot.design.html b/csnap/doc/cluster.snapshot.design.html deleted file mode 100644 index b64f954..0000000 --- a/csnap/doc/cluster.snapshot.design.html +++ /dev/null @@ -1,1467 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> - <title>Clustered Snapshot Design</title> -</head> -<body> -<div style="text-align: center;"><big><big><big><br> -Clustered Snapshots<br> -Detailed Design<small><br> -</small></big></big></big></div> -<div style="text-align: center;"><big><big><big><small><br> -Revised October 6, 2004<br> -</small></big></big></big><big><big><small><br> -Daniel -Phillips, Red Hat Inc.</small></big></big><br> -<big><big><big><small><br> -</small></big></big></big> -<div style="text-align: justify;"> -<ol id="mozToc"> -<!--mozToc h1 1 h2 2 h3 3 h4 4 h5 5 h6 6--><li><a href="#mozTocId615751">Design -Overview</a> - <ol> - <li><a href="#mozTocId166506">Overview of Data -structures</a></li> - <li><a href="#mozTocId399340">Snapshot Store Layout</a></li> - <li><a href="#mozTocId558118">Superblock and -Metablock </a></li> - </ol> - </li> - <li><a href="#mozTocId412004">Client-Server Messages</a> - <ol> - <li><a href="#mozTocId518793">Synchronization via -server messages </a></li> - <li><a href="#mozTocId692447">Message Sequences </a> - <ol> - <li><a href="#mozTocId226061">Sequences Initiated -by an Origin Client </a></li> - <li><a href="#mozTocId674706">Sequences Initiated -by a Snapshot Client </a></li> - <li><a href="#mozTocId170275">Sequences Initiated -by the Snapshot Server </a></li> - </ol> - </li> - </ol> - </li> - <li><a href="#mozTocId691886">Server Operation </a> - <ol> - <li><a href="#mozTocId330842">Exception Tree Format </a> - <ol> - <li><a href="#mozTocId268045">Leaf nodes</a></li> - <li><a href="#mozTocId478694">Index nodes</a></li> - </ol> - </li> - <li><a href="#mozTocId326876">Journal</a></li> - <li><a href="#mozTocId852538">Durability </a></li> - <li><a href="#mozTocId244480">Chunk Allocation -Bitmaps</a></li> - <li><a href="#mozTocId189826">Allocation Policy</a></li> - <li><a href="#mozTocId194475">Expanding the -Snapshot Store </a></li> - <li><a href="#mozTocId2062">Locking</a></li> - <li><a href="#mozTocId750451">Snapshot Deletion </a></li> - <li><a href="#mozTocId63589">Server Statistics</a></li> - </ol> - </li> - <li><a href="#mozTocId149578">Client Operation</a></li> - <li><a href="#mozTocId986766">Integration with -Cluster Infrastructure </a> - <ol> - <li><a href="#mozTocId291552">Server Start</a></li> - <li><a href="#mozTocId546783">Server Shutdown </a></li> - <li><a href="#mozTocId763101">Failure Recognition</a> - <ol> - <li><a href="#mozTocId909827">Snapshot Server Failure </a></li> - <li><a href="#mozTocId909827"> Cluster Manager -Failure </a></li> - </ol> - </li> - <li><a href="#mozTocId711483">Server Restart</a></li> - <li><a href="#mozTocId407640">Client-Server -Connections </a> - <ol> - <li><a href="#mozTocId423442">Initial connection</a></li> - <li><a href="#mozTocId755654">Disconnect</a></li> - <li><a href="#mozTocId840922">Reconnect</a></li> - </ol> - </li> - </ol> - </li> - <li><a href="#mozTocId373989">Performance -Characteristics</a> - <ol> - <li><a href="#mozTocId206505">Effect of chunk size</a></li> - <li><a href="#mozTocId700589">Effect of metadata -block size</a></li> - <li><a href="#mozTocId473026">Effect of Holding -Multiple Snapshots</a></li> - <li><a href="#mozTocId217737">Assumptions</a></li> - <li><a href="#mozTocId495690">Origin Read -Performance</a></li> - <li><a href="#mozTocId519978">Sequential Origin -Write Performance</a></li> - <li><a href="#mozTocId245882">Random Origin Write -Performance</a></li> - <li><a href="#mozTocId983353">Snapshot Read -Performance</a></li> - <li><a href="#mozTocId713768">Snapshot Write -Performance</a></li> - <li><a href="#mozTocId899929">Network Performance</a></li> - <li><a href="#mozTocId163638">Overall Performance</a></li> - </ol> - </li> - <li><a href="#mozTocId895406">Parallelizing the -Architecture</a></li> - <li><a href="#mozTocId426297">Adaptation to Single Node Client</a></li> -</ol> -</div> -<big><big><big><small></small></big></big></big></div> -<h1><a class="mozTocH1" name="mozTocId615751"></a>Design Overview</h1> -The required functionality of the clustered snapshot target, documented -in detail elsewhere, is briefly reviewed here. This target -implements a virtual block device that sits on top of some other block -device, allowing the creation of multiple writable snapshots of the -state of the underlying device. Each snapshot is also a virtual -block device implemented by the target. Multiple snapshots and -the origin device can be active simultaneously on multiple nodes of a -cluster. These virtual devices must act like real devices, that -is, they must be durable in the sense that once data is written to the -origin or to a snapshot it will never be lost even in the event of a -system crash or power outage. Performance of the virtual devices -must not be too much less than the underlying device. To save -space, snapshots must share data chunks with the origin volume and with -each other as much as possible.<br> -<br> -This design implements a client-server architecture -where almost everything interesting happens in the server. For a -write request to the origin, the client sends a message to the snapshot -server instructing it to ensure that the write will not interfere with -any snapshot by copying data from the origin to snapshot store if -necessary. The server signals that it has accomplished this by -acknowledging the message, and the client proceeds to carry out the -write. A snapshot client handles writes in a similar way with the -difference that the server informs the client in its response which of -the chunks the client wishes to write to are located in the snapshot -store, and where. Snapshot reads require some special -handling. The snapshot client sends a message to the server -indicating which chunks it wishes to read. The server locks any -of those chunks that lie on the origin and thus are at risk of being -overwritten by a client simultaneously active on the origin. The -server informs the snapshot client which chunks it has locked, and -after reading them, the client sends a message to the server that the -chunks may be unlocked. This interaction between client and -server via messages provides all the synchronization necessary to -ensure that multiple simultaneously active origin and snapshot clients -do not interfere with each other, preserving the illusion that these -virtual targets are real devices.<br> -<br> -There is a fair amount of mechanism behind the scenes in order for the -server to carry out the -work required by the above messages faithfully and efficiently. -This mechanism is implemented in the metadata server, the main focus of -this design document.<br> -<br> -The metadata server maintains the current state of all snapshots in a -single disk-based btree. The btree -permits -a variable number of exceptions to be stored per chunk. Within -btree leaf nodes, bitmaps are used to to record the sharing of snapshot -store data. Each bitmap is the same size as a logical address, 64 -bits, giving a maximum of 64 simultaneous snapshots. Btree nodes -are operated on directly as primary data, as 64 bit alignment of -objects within the nodes is considered desireable for efficiency and -to support the stringent alignment requirements of some architectures.<br> -<br> -Free space within the snapshot store is tracked with -bitmaps with a granularity of one bit per chunk. Metadata -structures on the other hand may have a finer granularity than a -chunk, typically 4K, which is the current limitation on the size of a -kernel buffer. When possible, metadata allocations will be made -metadata_blocksize / chunksize blocks at a time; where this is not -possible, the system must track partially allocated chunks. The -current plan is to remember only the most recent partially allocated -chunk and to do metadata allocations from it until it is completely -filled. (This simple approach limits the ability to optimize -metadata layout by setting allocation goal, so this strategy needs to -be looked at critically.)<br> -<br> -A journal is used for durable/atomic updating of snapshot -metadata.<br> -<br> - - Changes to the superblock<br> - - Changes to the metaroot<br> - - Current state of the BTree<br> - - State of all partially allocated chunks<br> -<br> -Each origin client caches a bitmap indicating which origin chunks are -known not to be shared by any snapshot, and thus can be written without -synchronization. Each snapshot client similarly caches a table of -exception store addresses of chunks that are known not to be shared.<br> -<h2><a class="mozTocH2" name="mozTocId166506"></a>Overview of Data -structures</h2> -This section describes the main data structures used by the server and -client, to provide context for the detailed discussions below.<br> -<br> -Data structures used by the server are disk-resident and partially -cached in memory. Client caches are memory-resident.<br> -<ul> - <li>Server On-disk Structures<br> - <br> - </li> - <ul> - <li>Superblock and Metaroot<br> -Static global data, e.g., chunk size; location of the root of the -exception btree and journal; size of the origin volume and snapshot -store; allocation bitmap stride and base<br> - </li> - <li>Metablock<br> -Miscellaneous variable data, e.g., snapshot list; -snapshot deletes in progress; list of chunks allocated for metadata but -only partially -used; freespace total [do we really need this?]<br> - </li> - <li>Journal<br> -For atomic updating and durability, changes to the exception btree, -allocation bitmaps and -miscellaneous other structures are written first to the journal then to -their final destinations. Without such measures, snapshot virtual -volumes would be vulnerable to disk corruption in the event of -unexpected system failure, which is undesirable and unlike a physical -volume.<br> - </li> - <li>Allocation bitmaps<br> -Free chunks in the snapshot store are tracked via bitmaps located just -about the journal in the snapshot store, indexed via a full-populated -radix tree<br> - </li> - <li>Exception Btree<br> -Indexed by chunk address; for each chunk address that has exceptions, -stores a list of exceptions. Each exception is paired with a -bitmap indicating which snapshots share the exception<br> - <br> - </li> - </ul> - <li>Client Cache<br> - <br> - </li> - <ul> - <li>Unique bitmap (for origin client)<br> -Each one bit in this bitmap indicates that all snapshots have -exceptions for the given chunk and so the client may write the chunk -without interacting the snapshot server. A zero means the chunk -is shared or its status is unknown, in either case the client must<br> - </li> - <li>Unique exception map (for snapshot client)<br> -Each exception in the table may be zero if its state is unknown or the -chunk does not have an exception, or the sector address of an exception -store chunk, with the low bit one if the chunk is known not to be -shared by any other snapshot.</li> - </ul> -</ul> -[need a diagram] -<h2><a class="mozTocH2" name="mozTocId399340"></a>Snapshot Store Layout</h2> -From low to high disk -address:<br> -<br> -[ superblock ]<br> -[ fixed size journal ]<br> -[ bitmaps, btree leaves and nodes ]<br> -[ exceptions ]<br> -<br> -[need a diagram]<br> -<br> -The dividing line between metadata and exceptions is not fixed, but -rather is determined by allocation policy.<span - style="font-weight: bold;"><br> -</span> -<h2><a name="mozTocId558118" class="mozTocH2"></a>Superblock and -Metablock<br> -</h2> -The first 4K block in the snapshot store is the superblock, containing -global information for the volume set at creation time:<br> -<ul> - <li>Version<br> - </li> - <li>Size of snapshot store</li> - <li>Metadata block size (4K)<br> - </li> - <li>Chunk size (binary multiple of metadata block size)<br> - </li> - <li>Sector address of the metablock</li> - <li>Sector address of root of allocation bitmap radix tree</li> - <li>Sector address of beginning of journal</li> - <li>Size of journal<br> - </li> - <li>...?<br> - </li> -</ul> -The metablock contains variable global information:<br> -<ul> - <li>Status flags</li> - <ul> - <li>Journal clean bit<br> - </li> - </ul> - <li>Highwater mark of chunk allocation</li> - <li>Total free space<br> - </li> - <li>Sector address and allocated size of partially allocated chunk<br> - </li> - <li>Bitmask of currently active snapshots</li> - <li>Bitmask of snapshots in process of being deleted</li> - <li>list of sector addresses of roots of snapshot store btrees</li> - <li>...?</li> -</ul> -Metablock data items that change frequently such as the highwater mark, -freespace and partial allocation are also recorded in the journal tag -block each time a journal transaction is committed. Updates to -the metablock are always journalled.<br> -<h1><a class="mozTocH1" name="mozTocId412004"></a><span - style="font-weight: bold;">Client-Server Messages</span></h1> -<h2><a class="mozTocH2" name="mozTocId518793"></a>Synchronization via -server messages<br> -</h2> -Some form of synchronization is required in order to make clustered -origin volumes and snapshot devices act as though they are independent -devices even when they share data. The obvious approach would be -to use -a cluster lock manager, with shared locks for reads and exclusive locks -for writes. But once a client has taken a lock for a write to a -given chunk it needs to find out from the metadata server whether the -original data of the chunk needs to be preserved in the snapshot store -in the case of a write to the origin or a new exception needs to be -created in the case of a write to a snapshot. This generates more -message traffic than necessary; it turns out that server messages alone -are sufficient for synchronization. The following fact is helpful -in reducing the number of messages required: if a chunk is known to be -unshared then it can be freely written or read without global -synchronization. Furthermore, once an origin chunk becomes -unshared it can only become shared again by creating a new -snapshot. And once a chunk shared by more than one snapshot -becomes unshared it will remain unshared until the snapshot is -deleted. This property means that once a client is told that a -given chunk is unshared it can rely on that information for a long -period, -or more precisely, until a new snapshot is created. A consequence -of this is that all origin clients must clear their bitmap cache each -time a new snapshot is created; a server-initiated request/response -sequence is provided for that purpose. (Snapshot clients on the -other hand do not have to clear their cache because snapshot chunks -known to be unique reside in the snapshot store, thus cannot become -shared with a new snapshot. This is yet another reason why -snapshot IO performance is expected to ultimately supercede origin IO -performance. [show why snapshot creation doesn't interfere with -outstanding snapshot reads])<br> -<br> -This design is therefore based on the principle that a client will -send a request to the snapshot server for every chunk that it does not -know is unshared. When the client receives the response it knows -that all requested chunks are unshared. The server has either -determined this by consulting the btree or made it so by creating new -exceptions. The -client then caches the information that the chunks are unshared (in a -bitmap) to optimize the case of repeated accesses to the same -chunk. Once a chunk is known to be unshared the client can -proceed with a write operation to the chunk.<br> -<br> -Special synchronization is required for snapshot reads, to prevent an -origin chunk that is read via a snapshot from being overwritten by a -write via the origin. Locking is used here, however the locking -is -internal to the snapshot server, except that a snapshot client must -send messages to the server to unlock chunks that the server has locked -on behalf of the client (only for snapshot reads, not for writes or -origin reads). Thus the snapshot server acts as a minimal lock -manager in the case of snapshot reads.<br> -<br> -A complete enumeration of cases should clarify the above logic:<br> -<ul> - <li><span style="font-weight: bold;">Origin write to unshared chunk</span><br> -A write to an origin chunk that is not shared (i.e., all snapshots -already have exceptions for the chunk) does not require any global -synchronization; it is the responsibility of the higher level -application to ensure that no other reads or writes race with this -write.<br> - <br> - </li> - <li><span style="font-weight: bold;">Origin write to shared chunk</span><br> -A write to an origin chunk that is shared requires global -synchronization. This synchronization is accomplished by sending -a message to the snapshot server which will ensure that the chunk is -not shared, by examining the exception btree and creating a new -exception if necessary. When the client receives the reply the -chunk is gauranteed not to be shared, which reduces to the case above -and the write can proceed. When the client doesn't know whether a -chunk is shared or unshared it must ask the server, so "unknown" is -treated the same as "shared" by the client; once the server responds -the chunk is known to be unshared and the client can cache this -information; the chunk can only become shared again if a new snapshot -is set, in which case the client will discard any sharing information -it has cached.<br> - <br> - </li> - <li><span style="font-weight: bold;">Origin read from shared or -unshared chunk</span><br> -Reads from the origin do not require any global synchronization because -the higher level application has the responsibility of ensuring that -these do not race with writes to the same volume. Snapshot writes -do not collide with origin reads because the destination of a snapshot -write is always the snapshot store.<br> - <br> - </li> - <li><span style="font-weight: bold;">Snapshot write to unshared chunk</span><br> -A write to a snapshot logical chunk that is not shared does not require -global synchronization, as for origin writes.<br> - <br> - </li> - <li><span style="font-weight: bold;">Snapshot write to shared chunk</span><br> -A write to a snapshot chunk that is shared is similar to a write to the -origin except that the snapshot server must also return a set of -exception store addresses to the client, which the client caches.<br> - <br> - </li> - <li><span style="font-weight: bold;">Snapshot read from unshared chunk<br> - </span>A snapshot read from an unshared chunk does not require any -global synchronization.<br> - <br> - </li> - <li><span style="font-weight: bold;">Snapshot read from shared chunk</span><br> -A snapshot read of a shared chunk requires global synchronization to -ensure that a write to the same chunk via the origin does not overwrite -the data while it is being read. The snapshot server performs -this synchronization by locking locally on the snapshot server between -writers and readers of shared chunks, details below. Chunks that -are locked for reading on a snapshot have to be unlocked after the read -is complete, which requires an additional message from the client to -the server. Similarly to writes to shared chunks, if the client doesn't -know that a chunk is shared it must contact the server. The -server's response indicates which chunks are unshared and the client -can cache this information.</li> -</ul> -Each chunk in the original message, once acknowledged, is guaranteed to -be unique because the metadata server has either -determined that each chunk is already unique or it has completed a copy -to snapshot store to make it unique. [note: chunks are not -necessarily acknowledged in the requested order] The only way a -unique chunk -can become shared is when a new snapshot is set, in fact, at the time a -new snapshot is set all its chunks are shared with at least the -origin. For this reason, setting a new snapshot requires that all -origin clients discard their bitmaps. Thus, the server sends a -"new snapshot" message to every client and thenew snap shot does not -become writeable until every client has acknowledged this message.<br> -<h2><a class="mozTocH2" name="mozTocId692447"></a>Message Sequences<br> -</h2> -This section enumerates the messages in each synchronization sequence.<br> -<h3><a class="mozTocH3" name="mozTocId226061"></a>Sequences Initiated -by an Origin Client<br> -</h3> -<ul> - <li>Origin write</li> - <ul> - <li>Client sends unique request</li> - <ul> - <li>request gives chunk address range<br> - </li> - </ul> - <li>Server responds with initiate</li> - <ul> - <li>empty message, i.e., "write can proceed" </li> - </ul> - <ul> - <li>server has verified each chunk is unshared or created new -exceptions as necessary<br> - </li> - <li>all chunks are now unique so unique cache can be updated for -these chunks</li> - </ul> - </ul> -</ul> -<h3><a class="mozTocH3" name="mozTocId674706"></a>Sequences Initiated -by a Snapshot Client<br> -</h3> -<ul> - <li>Snapshot write</li> - <ul> - <li>Client sends unique request</li> - <ul> - <li>request gives chunk address range<br> - </li> - </ul> - <li>Client responds with initiate</li> - <ul> - <li>response lists exception addresses, if any</li> - <li>after verifying each chunk is unshared, or creating new -exceptions where not</li> - </ul> - </ul> -</ul> -<ul> - <li>Snapshot read</li> - <ul> - <li>client sends read lock request</li> - <ul> - <li>request chunk address range<br> - </li> - </ul> - <li>Server responds with initiate</li> - <ul> - <li>lists exception addresses for non-origin chunks</li> - <li>lists which chunks need to be unlocked because they are not -unique</li> - </ul> - <li>Client sends unlock when done</li> - <ul> - <li>for non-unique chunks above<br> - <br> - </li> - </ul> - </ul> - <li>Snapshot create</li> - <ul> - <li>client sends snapshot create message</li> - <li>server sends snapshot create advice to each origin client</li> - <li>each origin client clears its bitmap cache and acknowledges -create<br> - </li> - <li>server returns create acknowlege</li> - <li>(I'm not completely satisfied with this sequence)<br> - </li> - </ul> -</ul> -<h3><a class="mozTocH3" name="mozTocId170275"></a>Sequences Initiated -by the Snapshot Server<br> -</h3> -[snapshot create]; cluster management messages; error messages; -shutdown message; [fixme]<br> -<h1><a class="mozTocH1" name="mozTocId691886"></a>Server Operation<br> -</h1> -<h2><a class="mozTocH2" name="mozTocId330842"></a>Exception Tree Format<br> -</h2> -Exceptions for all snapshots are stored in a single btree indexed by -logical chunk address. For each chunk, a list of exceptions is -stored. Each exception consists of a snapshot address and a -bitmap indicating which snapshots share that exception.<br> -<br> -Rather than serving only as a disk format to be translated into some -more efficient cache format, the btree is meant to be operated on -directly by the snapshot server. To this end, data structures in -the btree nodes and leafs are designed for direct memory access, e.g., -all numeric values are aligned according to their size.<br> -<br> -An attempt has been made to keep the btree compact by designing the -node formats carefully, without going to extremes such as using a -serial compressed encoding which is unpacked into a memory structure in -order to be accessed. In other words, difficult tradeoffs have -been made here between compactness, simplicity and efficiency.<br> -<h3><a class="mozTocH3" name="mozTocId268045"></a>Leaf nodes</h3> -Leaf block format is optimized for rapid lookup and efficient -insertion. At the bottom of each leaf is a header and a directory -map that grows up towards a table of exceptions, which grows -down. Each entry in the directory map gives the logical chunk -address -relative to a base address stored in the header, and has a pointer to -one of the exceptions in the table at the top of the block. The -entries are stored in sorted order according to logical chunk address -and the pointers increase monotonically.<br> -<br> -[need a diagram]<br> -<br> -Using relative addresses allows the map entries to be more -compact. In the current prototype map entries consist of two 32 -bit numbers, however two 16 bit numbers might work just as well and -save more space, although a 16 bit relative block number might be so -small as to cause a noticeable increase in the number of leaf blocks if -exceptions.are distributed sparsely. With 32 bit map numbers, a -single exception requires 24 bytes; with 16 bit map numbers that would -fall to 20 bytes, a 16% savings. The final determination of which -is best should probably be determined experimentally.<br> -<br> -The difference between each two pointers in the map gives the number of -exceptions for the chunk. The last entry in the map is a sentinel -and points at the top of the block (this could be designed out to save -a few bytes). Each entry in the exception table has the 64 bit -sector address of an exception in the snapshot store and a bitmap to -indicate which snapshots share the exception.<br> -<br> -The basic operations to locate and determine sharing of exceptions are -quite efficient. A binary search is used to locate the target -chunk address in the map, if it is present. This yields a list of -exceptions on which efficient bitwise operations can be performed to -determine sharing. From the point of view of the origin, a logical -chunk is shared unless all active snapshots have exceptions for that -chunk. From the point of view of a snapshot, a logical chunk is -shared if it has no exception (i.e., is shared with the origin) or it -has the same snapshot store address as another snapshot.<br> -<br> -A slight drawback of this leaf format is that insertion requires memory -moves -in order to maintain the entries in sorted order, and the memory moves -get longer as the leaf block fills up. For relatively small leaf -blocks, i.e. 4K, it is probably not a problem. This will be -determined experimentally. Other, equivalently efficient leaf -formats are certainly possible, though perhaps they will not be as -simple.<br> -<br> -A more serious drawback of this leaf format is that as the number of -snapshots increases, update overhead of the btree will increase more or -less linearly. It is thus desirable to adopt a variant leaf -format at some point capable of encoding runs of adjacent exceptions -efficiently. [variant leaf format needs to be provided for in -per-leaf flags and in superblock flags, for backward -compatibility.] This issue is treated at greater length in the -performance section, below. In brief: this will not be a problem -for reasonable numbers of simultaneous snapshots.<br> -<h3><a class="mozTocH3" name="mozTocId478694"></a>Index nodes</h3> -An index node contains a table of entries each of which consists of a -64 bit logical chunk address key and a 64 bit sector address of a lower -level index node or, at the lowest index level, a leaf. The -entries are in sorted order by logical chunk address. Two -successive keys bound the range of entries contained by the lower level -node.<br> -<br> -To locate the leaf block in which exceptions, if any, are stored for a -given logical address, we descend recursively from the root, doing a -binary search on the address key in each block and descending -recursively into the node referenced by the sector address lying -between the two keys that bound the target key.<br> -<br> -We search all the way to a leaf node even if we are examining a region -of the address space that is completely empty. For write requests -this is not inefficient because we will immediately add an exception to -the leaf node we found if one is not present. For read -requests it's a little more work than necessary but we probably do not -care since this only affects snapshot reads, and only by a small amount -(origin reads do not involve the server).<br> -<h2><a class="mozTocH2" name="mozTocId326876"></a>Journal</h2> -Any altered metadata block, i.e, btree leaf and index nodes, -allocation bitmaps, etc, are written to a journal before being written -to their final destinations. This gaurantees that the metadata -can -be restored reliably to the state of the most recently committed -exception or other metadata change.<br> -<br> -The size and location of the journal are determined at the time the -snapshot store is created and cannot be changed.<br> -<br> -Each journal transaction consists of an arbitrary number of data blocks -followed by a journal tag block. The tag block carries a magic -number allowing it to be identified as such for the purpose of journal -replay, and a sequence number used to locate the starting point for -journal replay. Any data block written to the journal that happens to -have the same number at the same location must be escaped by writing a -zero to that location in a copy of the data. The tag block -carries a list of snapshot -store sector addresses which are the final destinations of the data -blocks. The low bit of the address carries a bit flag indicating -that the data block was escaped and the magic number needs to be -restored before the data block is finally written. The tag block -carries other miscellaneous information such as partial usage status of -a chunk recently allocated for metadata.<br> -<h2><a class="mozTocH2" name="mozTocId852538"></a>Durability<br> -</h2> -Thanks to the journal, the entire state of the metadata server (with on -exception, see below) is always completely recorded on disk at the time -any write is acknowledged. Thus, if the metadata server should -fail a new one can be started, read the metadata root and continue as -if nothing had happened.<br> -<br> -The one exception to this is that locking state of snapshot read -requests against origin writes is kept only in memory on the -server. While it is enough to simply requre that all outstanding -reads on clients must complete before a newly started metadata server -can resume processing requests, there could be cases where this would -cause an unnecessary delay of serveral seconds on server restart where -there is a heavy backlog of IO. Since it is easy, -clients will be asked to upload any outstanding locked snapshot reads -to the new metadata server before the server resumes processing -requests. This should only take a few tens of milliseconds. -The total latency of starting a new metadata server then should be -measured in tens of milliseconds (though detecting that a server has -failed could easily take much longer).<br> -<br> -[more details of journalling]<br> -[for the kernel implementation, considerations for continued access to -metadata blocks that are currently in the journal writeout]<br> -<h2><a class="mozTocH2" name="mozTocId244480"></a>Chunk Allocation -Bitmaps</h2> -Freespace in the snapshot store is mangaged via bitmaps with a -resolution of one bit per chunk. Each bitmap is one 4K block in -size and maps 2**15 chunks. The bitmap blocks are indexed via a -radix tree rooted in the header. Each radix tree node contains -512 8-byte sector addresses. As a slight simplification -this tree is always 3 levels deep, giving 2^27 * 2^15 = 4 -trillion chunks, or 16 petabytes volume size limit with a minimal 4K -chunk size. It is always fully populated, i.e., the tree is -created at the time the snapshot store is created and changed only if -the snapshot store is expanded. The second lowest level of the -bitmap index tree is -loaded into memory when the volume is activated, this will be about 512 -KB per terabyte of snapshot store.<br> -<br> -Bitmaps are cached in buffers and accessed via getblk. A pointer -is kept to the most recently accessed bitmap, i.e., it is not released -until a different bitmap is accessed, which eliminates the majority of -getblk lookups assuming reasonably good locality of allocation. -Likewise, a pointer is kept to the most recently accessed index -block. Since nearly all accesses to bitmaps are associated with -changing the bitmap, the bitmaps are kept near the journal rather than -being distributed throughout the snapshot store. This is purely a -matter of allocation policy since the actual locations of bitmaps are -determined by the radix tree.<br> -<br> -Since metadata is allocated in blocks but allocation granualrity is -chunks, some chunks allocated to metadata may be only partially -full. To avoid leakage of this unallocated space on unexpected -restart, any partial allocations are recorded in the journal tag -block. As a side effect, this means that a few -metadata blocks can be allocated before a bitmap needs to be modified, -saving some journal bandwidth.<br> -<h2><a class="mozTocH2" name="mozTocId189826"></a>Allocation Policy</h2> -[coming soon]<br> -<br> -[see the performance section re why this is important]<br> -<br> -[Should there be hints re total free space in each region? -Probably]<br> -<h2><a class="mozTocH2" name="mozTocId194475"></a>Expanding the -Snapshot Store<br> -</h2> -To expand the snapshot store, additional bitmaps and associated radix -tree index blocks need to be allocated, hopefully not too far away from -the journal. Besides updating the snapshot store size in the -header, this is the only change that needs to be made (I think).<br> -<h2><a class="mozTocH2" name="mozTocId2062"></a>Locking</h2> -Synchronization via locking is only required between snapshot reads and -origin writes. This locking takes place entirely within the -server so no cluster lock manager -is involved. (In fact the server is a lock manager for the -limited case of snapshot reads.) The locks are simple, hashed -locks. The cost of this locking will be one hash lookup per -snapshot read or origin write of a shared chunk, plus the unlock -messages. This locking is only required when snapshot and origin -virtual devices are active at the same time; e.g., the server does not -have to take any locks to service origin write requests if no snapshot -device is active, even if snapshots are being held.<br> -<br> -The server takes a (local) lock for each shared chunk in the range of a -client snapshot read request, if the chunk has no exception for that -snapshot and therefore might collide with a write to the origin. -Locked chunks are marked in the response. The client sends a -message to release the lock after it has completed the read. -Meanwhile, the server briefly locks each chunk of a client's write -request after completing the copy to snapshot store and recording the -new exception, but before allowing the actual write to proceed by -replying to the client's request. This ensures that a contending -read always completes before the write to the origin takes place or is -initiated after the new exception has been recorded, thus directing the -read to the snapshot store instead of the origin.<br> -<h2><a class="mozTocH2" name="mozTocId750451"></a>Snapshot Deletion </h2> -Because it packs together information for multiple -snapshots in each leaf node, the exception btree is optimized for -lookup and exception -insertion as it should be. However, snapshot deletion is not as -simple an operation as it would be if each snapshot had its own -tree. (But if each snapshot had its own tree then exception -creation time would increase with the number of snapshots, much more -space would be used for multiple snapshots and keeping track of -exception sharing would be less efficient.) In general, deleting -a snapshot requires examining the entire btree and modifying each -leaf block that contains an exception for the snapshot. -This could amount to quite a lot of IO traffic and take a significant -amount of time. The snapshot server will therefore simply log the -status of the snapshot as "in process of deleting" and indicate -completion immediately to the requesting client. The actual -deletion will proceed in the background. When the deletion is -finished, which could require tens of seconds for a large volume, the -snapshot is logged as available for reuse.<br> -<br> -A possible optimization is to defer deletions until several snapshots -can be deleted in one pass, which will require less time than deleting -each individually. How much less depends on how common it is for -exceptions of several snapshots being deleted to lie in the same btree -node. Another possible optimization is to include in each index -node a bitmap indicating which snapshots have exceptions in the subtree -descending from that node so that entire subtrees can be skipped during -the traversal if they do not need to be modified.<br> -<br> -A more aggressive and considerably more difficult optimization would -involve introducing the concept of snapshot set generations and tagging -each leaf block with a the snapshot generation as of the most recent -alteration. Then a snapshot could be deleted by creating a new -generation that does not include the deleted snapshot. A leaf -block tagged with an earlier generation would be seen as "stale" and -would be modified when next encountered, to remap it to the current -generation, removing exceptions belonging to deleted snapshots in the -process. The complexity of this approach makes it unattractive, -however if snapshot deletion performance turns out to be a problem it -could turn out to be worth the effort.<br> -<h2><a class="mozTocH2" name="mozTocId63589"></a>Server Statistics</h2> -The current count of free chunks in the snapshot store is recorded as a -64 bit value in the journal tag block. In the event of unexpected -restart this value will be exact since it records the value as of the -most recent commit, which is the state recovered by replaying the -journal.<br> -<h1><a class="mozTocH1" name="mozTocId149578"></a>Client Operation</h1> -[this section was pasted in from the "barebones client specs" I gave to -Patrick and needs rewriting]<br> -<br> -Client operation is simple: all information required to map an incoming -request to its destination is obtained from the server, so the clients -just need to implement some simple message handling and a cache, the -latter not being essential for correct operations.<br> -<br> -Client initialization:<br> -<br> - Our target only needs to know three things from the outside -world:<br> -<br> - - device<br> - - socket<br> - - chunk size<br> -<br> - Later, snapshot clients will need to be tied to the origin -client in an<br> - as yet unidentified way.<br> -<br> - On initialization the target starts a kernel thread to handle -server<br> - responses.<br> -<br> -Read/write request handling:<br> -<br> - - Each read request is identity-mapped and dm takes care of -submitting it.<br> -<br> - - The target places each write request on a deferred list and -sends a<br> - "prepare write" request to the server. The -prepare write message<br> - contains a single range of chunk addresses (for now, -later we will add<br> - request batching) which the server will make -unique. This range covers<br> - the sector range of the corresponding deferred write -request.<br> -<br> - - For each "prepare write" response received from the server the -target<br> - searches the deferred write list for a request with -the indicated<br> - chunk address, verifies that the chunk count -matches, removes it from<br> - the list and submits it.<br> -<br> -Other messages:<br> -<br> - - We don't need to handle any other messages for now. -Later we will add<br> - a variant for handling snapshot prepare write -messages and the three-step<br> - snapshot read messages. Later, there will be a -snapshot creation message<br> - that allows origin clients to discard their 'unique' -cache.<br> -<br> -Message formats:<br> -<br> - - Messages are in network byte order, halfword aligned.<br> -<br> - - Message header:<br> - be_u16 magic;<br> - be_u16 msg_id;<br> - be_u32 msg_len;<br> -<br> -Prepare write message:<br> -<br> - header;<br> - be_u16 num_ranges; /* always 1 for now */<br> - be_u64 chunk_address;<br> - be_u16 chunk_count;<br> -<br> -Prepare write response:<br> - header;<br> - be_u16 num_ranges; /* always 1 for now */<br> - be_u64 chunk_address;<br> - be_u16 chunk_count;<br> -<br> -- Matching chunk addresses to blocked writes<br> -<br> -- Caching in client is most of it, and it's optional<br> -<h1><a class="mozTocH1" name="mozTocId986766"></a>Integration with -Cluster Infrastructure</h1> -A snapshot client's entire interface with cluster infrastructure takes -place over a named socket connection to a user space daemon, the csnap -"agent". This agent is a fairly lightweight program with a simple -interface that is intended to be customized to a particular operating -environment.<br> -<br> -At present, the only traffic between the device mapper target and the -user space agent is a three message sequence:<br> -<ol> - <li>Client requests a server connection</li> - <li>Agent responds by opening and passing a server connection to the -client</li> - <li>Client confirms that it successfully established communication -with the server. </li> -</ol> -For consistency, these messages are all in the same format as messages -between the client and server, except for 2. which additionally uses a -file descriptor passing interface operating over the local socket (see -below).<br> -<br> -The general scheme for snapshot server failover is:<br> -<ul> - <li>The client loses its connection</li> - <li>The client tells the userspace service daemon that it lost its -connection</li> - <li>The service daemon contacts rgmanager, or service manager, or -some definitive source, and asks, "where is the server?"</li> - <li>If there is a server, then the client simply tries to reconnect -to the existing server.</li> - <li>If not, then rgmanager will start one, somewhere.</li> - <li>After successfully connecting to a new snapshot server, the -service daemon passes the connection to the client<br> - </li> -</ul> -(Thanks for expressing this succinctly, Ben)<br> -<br> -If a newly started server has to recover any global state from a -client, then it must interface with the connection manager of the -cluster infrastructure to be sure that all clients possessing global -state that were connected to the previous server incarnation have -either reconnected or left the cluster. [This interface is -under construction]<br> -<br> -A pleasant property of this cluster snapshot design is that, by adding -an additional message to the snapshot client read protocol, the need to -recover global state is eliminated, and so is the need to devise a -connection manager interface protocol. However, the connection -manager interface protocol in itself is an interesting and useful -design excercise, so the current plan is to implement both options.<br> -<h2>Server Infrastructure Interface</h2> -[under construction]<br> -<br> -- needs something to start it<br> - - which tells it<br> - - local name of origin device<br> - - local name of snapshot store<br> - - port to bind to<br> -- that something needs to know only one is started<br> -<h2>Client Infrastructure Interface<br> -</h2> -<h3>Client Connection to Server <br> -</h3> -A snapshot or origin client takes the form of a device mapper target -module, which is a standard kernel module that registers itself with -device mapper at the time it is initialized, either when the module is -inserted, or at kernel bootstrap time if the module is built into the -kernel. The csnap module registers a set of methods with device -mapper, one of which is the "ctr" (constructor) method.<br> -<br> -Device mapper can be directed to instantiate a csnap virtual device -directly via the device mapper ioctl interface (ioctl on the -/dev/mapper/control device) or indirectly via libdevmapper, or by -higher level utilities such as dmsetup, LVM2 or EVMS, which use -libdevmapper, which in turn uses the ioctl interface. To -instantiate -the device, device mapper invokes the csnap constructor, passing it a -set of ascii parameters in much the same form as a C main -routine. The csnap target expects the -following parameters:<br> -<ul> - <li>Snapshot number (-1 = origin)</li> - <li>Name of the origin physical device<br> - </li> - <li>Name of the snapshot store physical device<br> - </li> - <li>Name of a control socket</li> -</ul> -The csnap target opens the two "physical" devices (which may themselves -be virtual devices) and the control socket. If everything is in -order, initialization completes by sending a message over the control -socket to request a snapshot server connection. The contructor -method returns success and device mapper dutifully enters the name of -the virtual device into the /dev/mapper directory.<br> -<br> -At this point the device exists and may receive IO requests, but any -request received before a server connection is established will merely -be queued for later processing. A user space agent -establishes the server connection and passes it to the csnap target -over the named control socket. To handle failover, -the agent monitors the control socket connection for -further server connection requests from the csnap target.<br> -<br> -Eventually, the csnap target will receive a server connection over its -control socket via a fd-passing interface. It then identifies -itself to the server, and supplies the number of the snapshot it wishs -to access. The server responds with an error if that snapshot -does not exist (do we want to have an option to force snapshot creation -on device initialization, or do we always want to do -this?). If the server indicates that it is satisfied with -its new client, the csnap target sends a success message over its -control socket and proceeds to process any queued IO requests. -<h3>Client Reconnect<br> -</h3> -The client may lose its server connection for one of several reasons:<br> -<ol> - <li>The server fails</li> - <li>The connection fails</li> - <li>The client sends an erroneous message and the server closes the -connection</li> - <li>The client detects an erroneous reponse from the server or does -not receive a response</li> -</ol> -All these cases are handled the same way: by sending an error message -over the control socket, then requesting a new connection as for -initialization. When (if) the target receives a new connection, -any outstanding requests will be retried starting from the beginning of -the relevant protocol. In the case of snapshot reads or writes, -the original query and the actual IO have to be retried, in case a -newly instantiated snapshot server has allowed some other client to -overwrite the target data blocks.<br> -<br> -The client cannot know the difference between cases 1 and 2, and in any -case, it handles the two the same way. The external control -program will try to determine only the client's connection has failed, -and reestablish it, or if the server has failed, in which case a new -one has to be started. It will rely on a higher level service in -the cluster for these determinations, the end result of which should be -a new server connection, or an unrecoverable error. In cases 3 -and 4, the external control program may decide not to supply a new -connection but to place the client into an error state instead, so that -all pending and future IO requests will be failed.<br> -<br> -There are two flavors of snapshot read protocol: the "3 message" and -the "4 message" protocol. The latter provides a confirmation that -a client's unlock message has been processed by the server, so the -client knows that a newly instantiated server has not allowed any other -client to overwrite the data it was reading. In contract, if the -3 message protocol is used, there is no confirmation of an unlock and -the client must upload the list of read locks it thinks it holds to the -new server before the new server will reply to origin write queries on -behalf of any client. So with the 4 message protocol there is no -special recovery work for the client to do on server failover, whereas -with the 3 message protocol, a list of read locks may have to be -uploaded.<br> -<br> -The 4 message protocol is clearly the more robust of the two, though -only the 3 message protocol is currently implemented.<br> -<h3><a class="mozTocH2" name="mozTocId763101"></a>Client-side Error -Detection</h3> -Currently, the client only detects errors in server reply message -syntax, which it reports to its user space agent. Traditionally, -detection of liveness of a server is handled by a cluster heartbeating -system. However, there are some errors that such a heartbeating -system will not detect, such as a stuck request, which the server -receives but never responds to, or a case where the client's connection -to the server breaks while the heatbeat system's does not. For -robustness, it is planned to incorporate additional timing-based error -detection into the client, including:<br> -<ul> - <li>Stuck request detection</li> - <li>Liveness of server connection</li> -</ul> -Because the client is designed to fail over transparently, it is -acceptable to make a pessimistic determination of failure, where a -response that is simply slow is treated as if it will never -arrive. In either case, the client will report the error to its -user space agent and wait for instructions, meanwhile attempting -to continue processing IO requests. The agent in turn will pass -the error on to a higher level: to a cluster, to a human operator, or -both.<br> -<br> -A stuck request will typically indicate a client or server -bug. In such a case, it is highly desirable to provide -accurate fault-isolation information to a central cluster manager as -opposed to silently leaving a user application stuck in a kernel -D-state.<br> -<h3><a name="mozTocId909827" class="mozTocH2"></a> User Space Agent -Failure</h3> -The user space agent is a local process and is considered reliable, so -no failover action is attempted if fails or if the client's connection -to the agent breaks. The client will respond by failing all -outstanding and future IO requests. This situation could only -arise from a bug, administrator error or similar. To recover, the -device mapper device needs to be removed and recreated.<br> -<br> -One possible exception to this might be a feature to permit live -upgrade of the agent. The adminstrator kills the agent and starts -a new, improved agent, while the client attempts to reconnect to the -agent in a polling loop. Though it is not clear at this point why -anyone would need such a feature, it would be easy to provide.<br> -<h1><a class="mozTocH1" name="mozTocId373989"></a>Performance -Characteristics</h1> -<h2><a class="mozTocH2" name="mozTocId206505"></a>Effect of chunk size</h2> -Larger chunk size will help performance for sequential and hurt for -random write loads. The total size of metadata reduces linearly -with the chunk size, saving space, IO bandwidth and seeking. On -the other hand, larger chunks increase internal fragmentation of the -snapshot store, especially for sparse, random access loads, and the -overhead of metadata updating is supposed to be small in relation to -data transfers. Therefore it is hoped that the performance and -metadata size cost of small chunk sizes will be outweighed reduced -internal fragmentation, saving space in the snapshot store. This -remains to be tested in practice.<br> -<h2><a class="mozTocH2" name="mozTocId700589"></a>Effect of metadata -block size</h2> -Larger metadata blocks will improve performance somewhat on largely -serial write loads due do requiring a fewer number of larger IOs, -especially if the snapshot metadata is fragmented. However, for -the time being Linux does not support IO buffers larger than physical -page size, so it is expected that metadata block size will not increase -until this issue is addressed, at least for a kernel implementation of -the snapshot metadata server. For compatibility with the -expected kernel metadata server, the user space implementation will use -4K blocks.<br> -<br> -It is thought that communication overhead and server load will not be -significant performance factors, due to these being highly -optimized. -Contention on large clusters with parallel loads should not be a -significant factor either, since a single server should be able to -handle the traffic of many nodes of similar power to itself. The -exception to this is copy-out overhead which could easily saturate a -server's bus; a simple solution is available: farm out the copy-out -traffic to lightly-loaded nodes as necessary.<br> -<h2><a class="mozTocH2" name="mozTocId473026"></a>Effect of Holding -Multiple Snapshots</h2> -The more snapshots that are held, the more btree leaf nodes will be -required to hold them. Journalling the extra btree leaves to disk -consumes IO bandwidth, causes more seeking and generates cache -pressure. Reading in the extra btree nodes increases -latency. However, because exceptions for all snapshots are stored -adjacent in the btree, the overhead is not as large as if a separate -map had to be updated on disk for each snapshot. Importantly, the -process of determining whether a given chunk is shared never requires -more than a single leaf node to be examined.<br> -<br> -Sharing bitmaps are used within leaf nodes to avoid having to enter any -given snapshot store address more than once into the node, and also -performs the function of specifiying which snapshot uses a given -snapshot store address. The worst case arises when a given -logical chunk is written at least once after every snapshot. Then -the leaf node entries for that chunk have a bitmap and a snapshot store -address for every snapshot. Since leaf nodes are -expected to be 50% full in the initial implementation, we can end up -with one exception stored in each leaf node. Then the number of -btree nodes that have to be journalled is equal to the number of chunks -written. The journalled node has to be written twice, once to the -journal and once to its true destination. So the worst case is a -factor of 3 degradation in write performance due to btree updating -alone. To ameliorate such degradation it would be wise to use a -larger chunk size when large numbers of snapshots are expected.<br> -<br> -The worst case degradation above can be tempered somewhat by improving -the btree update algorithm to use a b+tree algorithm, which guarantees -2/3rds leaf fullness, enough to hold two exceptions instead of -one. Larger metadata blocks will help reduce seeking overhead, -when they become practical.. Eventually though, the best -strategy is to introduce variant leaf node formats that optimize for -the many-snapshots case by representing ranges of snapshot store chunks -compactly, especially where the snapshot store chunks are allocated -sequentially, which is something we want to achieve anyway.<br> -<br> -In brief, the metadata update component of origin and snapshot write -performance will degrade linearly with the number of -snapshots held, but with a much shallower slope than if snapshot store -data were not shared and -metadata were not grouped together by logical address. In the -latter case, copy-out overhead would increase directly with number of -snapshots. Exception -table update overhead would increase rapidly as well, though the exact -rate is harder to characterize because it depends on the chunk sharing -patterns.<br> -<br> -With the maximum number of snapshots held (64) the new design should -perform better than the old one -by a factor of thirty or more. Furthermore, some fairly -straightforward improvements to the btree leaf format can make the -slope much shallower, to the point where the overhead of holding 64 -snapshots may be hard to notice.<br> -<br> -With a single snapshot held, the new design not perform quite as well -as the existing device-mapper design, but only because the existing -design does not provide durable recording of snapshot store -updates. In any case, the overhead of the durable snapshot -recording is expected to be only about 2% worst-case overhead vs raw -writing, far less than the 200% worst-case overhead of copy-outs when a -single snapshot is held, and shrinks roughly linearly with the chunk -size (extra seeking in the metadata region makes this relationship -slightly more complex). So by using a 256K chunk size, metadata -update can most likely be held to a few percent of first-time write -overhead even when the maximum number of snapshots are held.<br> -<h2><a class="mozTocH2" name="mozTocId217737"></a>Assumptions</h2> -Performance estimates below are based on the assumption that the -smallest chunk size (4K) is used. Each new exception uses -20 bytes (exception store address, sharing bitmap and directory entry) -so each btree leaf node holds a maximum of about 200 exceptions. -Due to splitting, leaf nodes are normally not full. In fact worst -case fullness of 50% is expected for the early implementations, so leaf -nodes will hold about 100 exceptions each.<br> -<br> -The performance estimates here assume asynchronous IO, which for user -space is not yet a practical possibility in Linux, therefore a kernel -implementation is assumed. The initial implementation however is -in user space; without asynchronous IO the user space implementation -will not perform as well as a kernel implementation. It is -expected that both implementations will be developed and maintained; -that the user implementation will be available first; that a kernel -implementation will supercede it in performance; and that the user -space implementation will eventually pull even with the kernel -implementation by taking advantage of newly available asynchronous IO -and user space locking facilities.<br> -<h2><a class="mozTocH2" name="mozTocId495690"></a>Origin Read -Performance</h2> -Origin reads are passed straight through to the underlying -volume. Since the overhead of the device mapper handling is -insignificant, origin read performance is essentially unchanged<br> -<h2><a class="mozTocH2" name="mozTocId519978"></a>Sequential Origin -Write Performance</h2> -Origin write throughput is affected mainly by the frequency of chunk -copy-outs and metadata update overhead. Copy-outs require -reading and writing, requiring a minimum of 200% additional bandwidth -vs raw write and additional seeking as well, especially for the -single-spindle case where the origin volume and snapshot store will be -far apart. Throughput is improved at the expense of latency by -batching the copy-out reads and copy-out writes, which happens -naturally with asynchronous IO. There will thus be fewer long -seeks between the origin and snapshot store.<br> -<br> -Worst case origin write performance is obtained when the snapshot store -is created with the smallest possible chunk size (4K) and the load -requires a copy-out for every chunk write. Such a load is -easy to generate, for example by setting a snapshot and then -immediately unpacking an archive into the volume. Required IO -bandwidth will triple, seeking between the origin and snapshot store -will increase, and metadata updating will increase. Writing in -this case should be largely linear and batching amortizes the seeking -overhead, so the dominant effect is expected to be the increased IO -bandwidth. For this load we should expect to see a 3 times -slowdown versus raw volume access. Fragmentation of the snapshot -store could make this considerably worse, perhaps by another factor of -three.<br> -<br> -Since such a load is easy to generate it is worrisome. It is -possible that in the long run, general performance for a snapshot -volume could become better than for the origin, see below.<br> -<br> -Fragmentation of the snapshot store will introduce additional seeking -and rotational latency penalties. Reducing such fragmentation by -clever snapshot store allocation policy will yield significant -performance gains, however such allocation policy improvements require -considerable time to develop. A highly fragmented snapshort store -could aggrate worst case write performance by an additional factor of a -few hundred percent.<br> -<br> -[what about latency]<br> -<h2><a class="mozTocH2" name="mozTocId245882"></a>Random Origin Write -Performance</h2> -A load that consists of 100% single-sector writes distributed randomly -over the entire volume immediately after setting a snapshot will cause -copy-out bandwidth to be much more than 200% of raw write bandwidth, -and will also cause a great deal of additional seeking. Metadata -overhead will also increase significantly since typically only a single -chunk on each leaf node will be updated each time the node is -journalled to disk; rotational latency will increase significantly -during metadata access. Performance under this random load will -typically be dominated by seeking rather than bandwidth. Analysis -is complex, however I will speculate now that the performance of the -snapshotted volume could degrade by a factor of 3 to 4 versus the raw -volume due to additional seeking and rotational latency for copy-outs -and metadata updating.<br> -<br> -Fragmentation of the snapshot store can and should be addressed over -time. For origin writes, nothing that can be done about the -copy-out -overhead. Snapshot writes on the other hand do not incurr -copy-out -overhead. They do incurr seeking and rotational penalties due to -fragmentation in the snapshot store, but so do origin writes. -Furthermore snapshot reads also suffer from fragmentation penalties -whereas origin reads do not. Very good snapshot store layout -optimization could reduce both the penalty for snapshot reading and -writing, in which case general performance on a snapshot volume -could -be better than on a snapshotted origin volume. Whether this can -be -realized in practice remains to be seen.<br> -<br> -[what about latency]<br> -<h2><a class="mozTocH2" name="mozTocId983353"></a>Snapshot Read -Performance</h2> -Unlike origin reads, snapshot read throughput is affected by snapshot -store fragmentation. Snapshot read latency is increased by the -requirement of locking against origin writes. Readahead results -in a kind of lockahead, so under loads where readahead is effective, -increased snapshot read latency will not hurt read throughput. -The predominant visible effect is expected to be read -fragmentation. With large chunk sizes, e.g., 256K and up, -moderate fragmentation should cause only slight degradation in snapshot -read performance. However, without special attention to snapshot -store allocation policy, fragmentation can be expected to be fairly -severe, so snapshot read performance is not expected to be steller in -early implementations. Fortunately, since the main purpose of -reading from a snapshot is to back it up or restore a few files, some -read performance degradation is acceptable and is unlikely to be -noticed.<br> -<br> -In the long run it is desireable to improve snapshot read performance -by controlling snapshot store fragmentation as much as possible, in -order to take advantage of the inherently superior performance of -snapshot writing versus origin writing.<br> -<h2><a class="mozTocH2" name="mozTocId713768"></a>Snapshot Write -Performance</h2> -Snapshot writes to not require copy-outs; if an origin chunk or shared -snapshot store chunk needs to be written, the logical chunk is first -remapped to a new chunk in the snapshot store. With some tweaking -of the message protocol, writing to the chunk could procede as soon as -the new allocation is known, in parallel with the logging of the new -exception. So snapshot writes are inherently quite efficient.<br> -<br> -Snapshot write overhead comes from metadata update overhead and -snapshot store fragmentation. The former is supposed to be small, -on the order of a few percent. The latter could be very large, -and probably will be in initial implementation, perhaps on the order of -a factor of 10. Larger chunk sizes will reduced this seeking -overhead, roughly linearly with the chunk size. Careful layout -optimization could conceivably reduce this to a few percent, even with -small chunks. We shall see.<br> -<h2><a class="mozTocH2" name="mozTocId899929"></a>Network Performance</h2> -The amount of message data needed for each chunk is small, especially -since the message format is designed from the outset to handle ranges -of chunks and multiple ranges in each message. Except for -snapshot reads, each message sequence is only two messages long -(note: approximately. Server responses do not correspond exactly -requests; e.g., any unshared chunks can be acknowledged -immediately). Message traffic is expected to be less than 1% of -disk array traffic. Assuming that the general purpose network -interconnect and storage array interconnect have similar bandwidth, -this is where the expectation that this architecture will scale -linearly to about 100 clients comes from.<br> -<br> -[details]<br> -<h2><a name="mozTocId163638" class="mozTocH2"></a>Overall Performance</h2> -It is expected that typical usage of a snapshotted origin volume will -show only slight reduction of performance versus the raw origin volume, -due to reading being more common than writing. Rewriting chunks -is -optimized by the client's bitmap cache, which is compact and probably -capable of caching all the hot spots of a volume, even for large -volumes. So rewriting should show now visible degradation. -The -performance of fresh writes to snapshotted chunks will degrade -significantly, due to copy-out bandwidth, and to snapshot store -fragmentation, that latter being subject to optimization while the -former is unavoidable. In general, more frequent snapshots cause -more -fresh writes, with the frequency of fresh writes peaking just after the -snapshot and declining over time, till the next snapshot.<br> -<br> -So: what will be the balance of fresh writes vs reads and -rewrites? -How frequently will we see will we see the balance shift for a short -time in the direction of the worst case? How bad is the worst -case? -How likely is it that the user will notice the shifts in write -performance? These all await measurement under live -loads. However -at this point I will speculate that even a relatively early -implementation will show average performance degradation versus a raw -volume of less than ten percent, and that, at worst, performance -degradation will be limited to a factor of four or so just after a -snapshot. For many users, and particularly enterprise users, the -benefits of snapshotting will outweigh the performance loss: it is easy -to buy bandwidth, not as easy to buy live backup -capability. For -others, the unavoidable performance degradation of origin writing will -make snapshotting unattractive enough to discourage its use. -Eventually we may be able to satisfy this group as well, by improving -snapshot store allocation policy to the point where the origin can be -made optional and all IO take place in the snapshot store.<br> -<br> -The pessimism in this section should be tempered by observing that in -many respects, performance is expected to be good:<br> -<ul> - <li>Large number of snapshots can be held without affecting -performance much</li> - <li>Snapshot store utilization is good</li> - <li>Network traffic is minimal</li> - <li>Rewrites are highly optimized</li> -</ul> -In other words, if you need snapshots then this implementation is -likely to deliver good performance versus alternatives. -Plus there is -a clear path forward to achieving near-optimal performance, by working -towards a system where the snapshot store can be used effectively -alone, with no origin volume -<h1><a class="mozTocH1" name="mozTocId895406"></a>Parallelizing the -Architecture</h1> -Normally the first question I am asked about this clustered snapshot -design is "why isn't it symmetric"? The answer: because a) it -doesn't have to be in order to perform well on today's typical clusters -and b) distributing a tree structure across independent caches is a -complex, error-prone process, and introduces overhead of its own. -At some point, however, the single node server architecture will become -a bottleneck, so I discuss parallelizing strategies here.<br> -<br> -The easist thing we can do, and with the strongest immediate effect is -to have the server distribute the copy-out work to underused -nodes. This will take significant IO bandwidth load off the -server's bus at the expense of a little messaging latency. By -doing this, a single server can likely scale to handle a hundred or so -busy nodes of similar power to itself: the real bottleneck will -probably be the storage array. A user who can afford to upgrade -the storage array to handle even larger numbers of clients can likely -afford to upgrade the snapshot server as well.<br> -<br> -At some point, perhaps two or three hundred clients, the snapshot -server -becomes a bottleneck again. Further scaling is easily achieved by -dividing up the work between a number of snapshot servers, by logical -address range. Each snapshot server maintains a separate btree in -a distinct range of logical addresses and operates its own -journal. Care must be taken that allocation bitmaps are divided -up cleanly; this is not hard (e.g., even if a logical address range -boundary lies in the middle of a bitmap block, the boundary bitmap can -be replicated between two nodes, with logic to prevent allocation -outside the boundary - needed anyway for error checking). Shared -metadata such as the current snapshot list, superblock, etc., is -updated using a RW locking strategy (i.e., using a DLM). Assuming -that workload is distributed relatively evenly across the logical -address range, this simple parallelization strategy will serve up to a -thousand clients or so, and the disk will once again be the bottleneck.<br> -<br> -[It might be best to add the metadata hooks for this range division now -since we know it's needed eventually]<br> -<br> -If we want to scale to far larger numbers of cients we probably -have to bite the bullet and distribute the btrees and allocation -bitmaps. However I do not think this problem is imminent; there -is plenty of time to think about it.<br> -<h1><a class="mozTocH1" name="mozTocId426297"></a>Adaptation to Single -Node Client</h1> -The current device-mapper snapshot design suffers from a number of -drawbacks, chiefly<br> -<ul> - <li>copy-out overhead increases linearly with number of snapshots held</li> - <li>snapshot state is not recorded durably, but only at shutdown</li> - <li>all metadata is held in memory, creating excessive cache pressure -for large volumes</li> -</ul> -It is therefore expected that this design for clustered snapshots will -be adapted sooner rather than later for use with the normal, -non-clustered machines that constitute the vast majority of Linux -installs. How best to do that?<br> -<br> -The message-based synchronization described above may not be the -optimal solution for an entirely local implementation. But then, -with some tweaking it just might be. Currently I am considering -the wisdom of adapting the clustered snapshot target for local use by -replacing the socket messaging with a lightweight ring buffer messaging -facility that presents the same interface to the rest of the -target. The obvious alternative is to incorporate the server -operations directly into the client. It's clear which is easier, -but which is better? [feedback invited]<br> -</body> -</html> diff --git a/csnap/doc/csnap.ps b/csnap/doc/csnap.ps deleted file mode 100644 index a31d7b3..0000000 --- a/csnap/doc/csnap.ps +++ /dev/null @@ -1,2994 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvips(k) 5.92b Copyright 2002 Radical Eye Software -%%Title: csnap.dvi -%%Pages: 20 -%%PageOrder: Ascend -%%BoundingBox: 0 0 612 792 -%%DocumentFonts: CMSY10 -%%EndComments -%DVIPSWebPage: (www.radicaleye.com) -%DVIPSCommandLine: dvips -t letter -o csnap.ps csnap.dvi -%DVIPSParameters: dpi=600, compressed -%DVIPSSource: TeX output 2004.09.03:1751 -%%BeginProcSet: texc.pro -%! -/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S -N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 -mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 -0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ -landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize -mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ -matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round -exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ -statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] -N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin -/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array -/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 -array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N -df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A -definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get -}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} -B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr -1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 -1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx -0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx -sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ -rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp -gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B -/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ -/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ -A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy -get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} -ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp -fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 -{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add -chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ -1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} -forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn -/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put -}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ -bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A -mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ -SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ -userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X -1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 -index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N -/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ -/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) -(LaserWriter 16/600)]{A length product length le{A length product exch 0 -exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse -end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask -grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} -imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round -exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto -fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p -delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} -B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ -p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S -rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end - -%%EndProcSet -%%BeginProcSet: bbad153f.enc -% Thomas Esser, Dec 2002. public domain -% -% Encoding for: -% cmsy10 cmsy5 cmsy6 cmsy7 cmsy8 cmsy9 -% -/TeXbbad153fEncoding [ -/minus /periodcentered /multiply /asteriskmath /divide /diamondmath -/plusminus /minusplus /circleplus /circleminus /circlemultiply -/circledivide /circledot /circlecopyrt /openbullet /bullet -/equivasymptotic /equivalence /reflexsubset /reflexsuperset /lessequal -/greaterequal /precedesequal /followsequal /similar /approxequal -/propersubset /propersuperset /lessmuch /greatermuch /precedes /follows -/arrowleft /arrowright /arrowup /arrowdown /arrowboth /arrownortheast -/arrowsoutheast /similarequal /arrowdblleft /arrowdblright /arrowdblup -/arrowdbldown /arrowdblboth /arrownorthwest /arrowsouthwest /proportional -/prime /infinity /element /owner /triangle /triangleinv /negationslash -/mapsto /universal /existential /logicalnot /emptyset /Rfractur /Ifractur -/latticetop /perpendicular /aleph /A /B /C /D /E /F /G /H /I /J /K -/L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /union /intersection -/unionmulti /logicaland /logicalor /turnstileleft /turnstileright -/floorleft /floorright /ceilingleft /ceilingright /braceleft /braceright -/angbracketleft /angbracketright /bar /bardbl /arrowbothv /arrowdblbothv -/backslash /wreathproduct /radical /coproduct /nabla /integral -/unionsq /intersectionsq /subsetsqequal /supersetsqequal /section -/dagger /daggerdbl /paragraph /club /diamond /heart /spade /arrowleft -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/minus /periodcentered /multiply /asteriskmath /divide /diamondmath -/plusminus /minusplus /circleplus /circleminus /.notdef /.notdef -/circlemultiply /circledivide /circledot /circlecopyrt /openbullet -/bullet /equivasymptotic /equivalence /reflexsubset /reflexsuperset -/lessequal /greaterequal /precedesequal /followsequal /similar -/approxequal /propersubset /propersuperset /lessmuch /greatermuch -/precedes /follows /arrowleft /spade /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -] def - -%%EndProcSet -%%BeginProcSet: texps.pro -%! -TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 -index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll -exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 -ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ -pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get -div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type -/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end -definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup -sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll -mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ -exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} -forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def -end - -%%EndProcSet -%%BeginFont: CMSY10 -%!PS-AdobeFont-1.1: CMSY10 1.0 -%%CreationDate: 1991 Aug 15 07:20:57 -% Copyright (C) 1997 American Mathematical Society. All Rights Reserved. -11 dict begin -/FontInfo 7 dict dup begin -/version (1.0) readonly def -/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def -/FullName (CMSY10) readonly def -/FamilyName (Computer Modern) readonly def -/Weight (Medium) readonly def -/ItalicAngle -14.035 def -/isFixedPitch false def -end readonly def -/FontName /CMSY10 def -/PaintType 0 def -/FontType 1 def -/FontMatrix [0.001 0 0 0.001 0 0] readonly def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 0 /.notdef put -readonly def -/FontBBox{-29 -960 1116 775}readonly def -/UniqueID 5000820 def -currentdict end -currentfile eexec -D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 -7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 -A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 -E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A -221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A -27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF -5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09 -0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730 -DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A -71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09 -4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C -515DB70A8D4F6146FE068DC1E5DE8BC5703711DA090312BA3FC00A08C453C609 -C627A8AC5158CF7CDD95058BF2B70796EB09F833A6DD557560244C58DCDF257B -36F96AF73BCDFAD79FC5AE97F7E4CB643BE6125DC257BE825C1FCE80EA9886AF -87B49B6FCF3AB57CB1960E83AD525404EDE0E99FB350CB662C8CA46B4D161320 -892A7D2FB2A57C42B874D5DE96C17F8A0FEC855E62DD37AD6088597E91527E1C -0EA9A3FB7AE720C62543ED75FF6DFA01E434F2841851CCD780F15A1EBE417E52 -0F753BEF7ADFFAA9173C4776936AD55854BC82CDB3327374E540A4A0A27B6AB0 -0E9C1B155C72BB -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndFont -TeXDict begin 40258431 52099146 1000 600 600 (csnap.dvi) -@start -%DVIPSBitmapFont: Fa ecrm0800 8 28 -/Fa 28 123 df<123C127EB4FCA21380A2127F123D1201A312031300A25A1206120E5A5A -5A126009157AAD14>39 D<B512C0A412047F9018>45 D<123C127E12FFA4127E123C0808 -7A8714>I<4A7E4A7EA34A7EA24A7EA3EC1BF81419A2EC30FCA2EC70FEEC607EA24A7EA3 -49486C7EA2010380EC000FA201066D7EA3496D7EA2011FB57EA29038180001496D7EA349 -147EA201E0147F4980A20001ED1F801203000716C0D80FF0EC3FE0D8FFFC0103B5FCA230 -2F7EAE35>65 D<007FB712F8A29039000FC003007C150000701638A200601618A200E016 -1CA248160CA5C71500B3A94A7E011FB512E0A22E2D7EAC33>84 D<13FF000713C0380F01 -F0381C00F8003F137C80A2143F001E7FC7FCA4EB07FF137F3801FE1FEA07F0EA1FC0EA3F -80EA7F00127E00FE14065AA3143F7E007E137F007FEBEF8C391F83C7FC390FFF03F83901 -FC01E01F207D9E23>97 D<EA07C012FFA2120F1207AC14FE9038C7FF809038CF03E09038 -DC01F09038F8007C49137E49133E497F1680A2150F16C0A9ED1F80A216005D6D133E6D5B -01B05B9038BC01F090380E07E0390607FF80260001FCC7FC222F7EAD27>I<EB1FE0EB7F -FC3801F01E3803E0073907C01F80EA0F80EA1F005A003EEB0F00007E90C7FCA2127C12FC -A9127EA215C07E6C130101801380380FC0033907E007003801F03E38007FF8EB1FC01A20 -7E9E1F>I<15F8141FA214011400ACEB0FE0EB7FF83801F81E3803E0073807C003380F80 -01EA1F00481300123E127EA25AA9127C127EA2003E13017EEB8003000F13073903E00EFC -3A01F03CFFC038007FF090391FC0F800222F7EAD27>I<EB1F80EBFFF03803E0783807C0 -3E380F801E381F001FEC0F80123E007E130715C0127C12FCA3B6FCA200FCC8FCA5127EA2 -003E14C0123F6C1301390F80038001C013003803E00F3801F03C38007FF8EB1FC01A207E -9E1F>I<EB03F0EB0FFCEB3E1EEB7C3F13F8EA01F0A23803E00C1400AAB512E0A23803E0 -00B3A6487E387FFF80A2182F7FAE16>I<013F13F89038FFC3FE3903E1FF1E3807807C00 -0F140C391F003E00A2003E7FA76C133EA26C6C5A00071378380FE1F0380CFFC0D81C3FC7 -FC90C8FCA3121E121F380FFFF814FF6C14C04814F0391E0007F848130048147C12F84814 -3CA46C147C007C14F86CEB01F06CEB03E03907E01F803901FFFE0038003FF01F2D7E9D23 ->I<EA07C012FFA2120F1207AC14FE9038C3FF809038C703E09038DE01F013F8496C7EA2 -5BA25BB2486C487E3AFFFE1FFFC0A2222E7EAD27>I<EA0780EA0FC0EA1FE0A4EA0FC0EA -0780C7FCA8EA07C012FFA2120F1207B3A5EA0FE0EAFFFCA20E2E7EAD14>I<EA07C012FF -A2120F1207B3B3A3EA0FE0EAFFFEA20F2E7EAD14>108 D<2607C07FEB07F03BFFC3FFC0 -3FFC903AC783F0783F3C0FCE01F8E01F803B07DC00F9C00F01F8D9FF8013C04990387F00 -0749137EA249137CB2486C01FEEB0FE03CFFFE0FFFE0FFFEA2371E7E9D3C>I<3807C0FE -39FFC3FF809038C703E0390FDE01F0EA07F8496C7EA25BA25BB2486C487E3AFFFE1FFFC0 -A2221E7E9D27>I<EB1FE0EB7FF83801F03E3803C00F3907800780390F0003C04814E000 -3EEB01F0A248EB00F8A300FC14FCA9007C14F8A26CEB01F0A26CEB03E0A2390F8007C039 -07C00F803901F03E0038007FF8EB1FE01E207E9E23>I<3807C0FE39FFC7FF809038CF03 -E0390FDC01F03907F800FC49137E49133E49133FED1F80A3ED0FC0A8151F1680A2ED3F00 -A26D137E6D137C5D9038FC01F09038CE07E09038C7FF80D9C1FCC7FC01C0C8FCA9487EEA -FFFEA2222B7E9D27>I<90380FE01890387FF8383801F81C3903E00E783807C007390F80 -03F8001F1301EA3F00A2007E1300A212FE5AA8127EA36C13017EEB8003380FC0073803E0 -0E3801F03C38007FF0EB1FC090C7FCA94A7E91381FFFC0A2222B7E9D25>I<380781F038 -FF87FCEB9E7EEA0F98EA07B813B0EBF03CEBE000A35BB1487EB5FCA2171E7E9D1B>I<38 -01FE183807FFB8381E01F8EA3C00481378481338A21418A27E7EB41300EA7FF06CB4FC6C -13C06C13F0000113F838001FFC130138C0007E143EA26C131EA27EA26C133CA26C137838 -FF01F038E3FFC000C0130017207E9E1C>I<1360A413E0A312011203A21207121FB512F0 -A23803E000AF1418A714383801F03014703800F860EB3FE0EB0F80152A7FA81B>I<D807 -C013F800FF131FA2000F130100071300B21401A314033803E007EC0EFC3A01F81CFFC038 -007FF890391FE0F800221F7E9D27>I<3AFFFC01FFC0A23A0FE0007E000007147C153800 -03143015706C6C1360A26C6C5BA390387C0180A26D48C7FCA2EB3F07EB1F06A2EB0F8CA2 -14DCEB07D8A2EB03F0A36D5AA26D5A221E7F9C25>I<3BFFFC3FFE07FFA23B0FE003F001 -F801C09038E000F00007010114E0812603E00314C0A2913807F8012701F006781380A290 -39F80E7C030000D90C3C1300A290397C181E06A2151F6D486C5AA2168C90391F600798A2 -16D890390FC003F0A36D486C5AA36DC75A301E7F9C33>I<3AFFFC01FFC0A23A0FE0007E -000007147C1538000314306D137000011460A26C6C5BA2EBFC01017C5BEB7E03013E90C7 -FCA2EB1F06A2148EEB0F8CA2EB07D8A2EB03F0A36D5AA26D5AA2495AA2130391C8FC1278 -EAFC06A25B131CEA7838EA7070EA3FE0EA0F80222B7F9C25>121 -D<003FB51280A2EB003F003C14000038137E00305BEA700100605B495A495A130F00005B -495A49C7FC5B137E9038FC0180EA01F8120313F03807E003EA0FC0001F1400138048485A -007E5B00FE133FB6FCA2191D7E9C1F>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fb ecrm0600 6 2 -/Fb 2 51 df<13E01201120712FF12F91201B3A7487EB512C0A212217AA01E>49 -D<EA01FC3807FF80381C0FC0383003E0386001F0EB00F812F86C13FCA2147C1278003013 -FCC7FC14F8A2EB01F0EB03E014C0EB0780EB0F00131E13385B5B3801C00CEA0380380600 -185A5A383FFFF85AB512F0A216217CA01E>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fc ecrm0700 7 2 -/Fc 2 51 df<13381378EA01F8121F12FE12E01200B3AB487EB512F8A215267BA521>49 -D<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80A4127CC7FC15 -005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA018039030003 -0012065A001FB5FC5A485BB5FCA219267DA521>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fd ecbx1000 10 35 -/Fd 35 122 df<913A03FF8007FE027F9039F07FFF800103B500FDB512E0010F903A00FF -FE0FF0D93FF8ECF81F90267FE0019038F03FF849485A4816E014804816C00200ED1FF081 -F007C06F91C7FCA8B912E0A4000390C701C0C7FCB3ABB5D8FC3FEBFF80A43D3A7EB938> -27 D<B61280A819087F9620>45 D<ED03E04B7EA24B7EA34B7EA24B7EA34B7EA292B57E -A34A8015F302038015E1A202078015C0020F80ED807FA2021F80ED003F4A80023E131FA2 -027E80027C7F02FC814A7FA20101824A7F49B77EA3498202C0C7FC010F824A147FA2011F -8291C8123F4982013E151FA2017E82017C8101FE83B500F80107B61280A4413A7DB948> -65 D<B812C017FC17FF18C028007FF000037F04007F717E717E171F84A2717EA74D5AA2 -60173F4D5A4D5A4C13C0040F5B91B600FCC7FCA2EFFF8002F0C713F0EF3FF8717E717E71 -7E19807113C0A319E0A719C0A25F4D138019005FEF7FFE4C485AB912F018C095C7FC17F0 -3B397DB844>I<DB3FFCEB01C00203B5EAC003021FECF00791B6EAFC0F01039039FC00FF -3F4901C0EB1FFFD91FFEC77E49481403D97FF080494880485B48177F4849153F4890C9FC -181F485A180F123F5B1807127FA24993C7FC12FFAD127F7FF003C0123FA27F001F1707A2 -6C6C1780180F6C6D16006C6D5D6C173E6C6D157ED97FF85D6D6C4A5A6DB44A5A010701C0 -EB0FE06D01FCEBFF80010090B548C7FC021F14F8020314E09126003FFEC8FC3A3B7BB945 ->I<B87E17F817FF18C028007FF8000713F09338007FF8EF1FFE717E050313807113C0A2 -7113E0F07FF0A2F03FF8A219FC181FA219FEA419FFAC19FEA419FC183FA219F8187F19F0 -F0FFE0A24D13C04D13804D1300EF1FFEEF7FFC933807FFF0B912C095C7FC17FC17804039 -7DB849>I<B912F0A426007FF8C7FCEF1FF8170717031701A21700A21878A3043C137C18 -3CA41800167CA216FC150391B5FCA4ECF8031500167CA2163C180FA3181EA293C7FCA218 -3EA2183C187CA218FCA2EF01F81703170F173FEE01FFB9FC18F0A338397DB83F>I<B612 -FCA439007FF800B3B3ADB612FCA41E397DB824>73 D<B7FCA426007FF8C9FCB3ACEF0780 -A5170F1800A35FA25FA25F5F5E5EEE0FFE167FB8FCA431397DB839>76 -D<B500F80403B512F06E5EA26E5ED8007FF1E000A2D97BFF161EA201796D5DA201786D5D -A26E6C5DA36E6C4A5AA26E6C4A5AA26E6C4A5AA26E6C4A5AA26E6C141EA36E6D5BA26E6D -5BA26F6C5BA26F6C485AA36F6C485AA26F6C485AA26F6C48C7FCA2923803FF1EA36F13BC -A26F13F8A2705AA2705AA213FCB500FC6D4848B612F0A2EE0F80EE070054397DB85B>I< -EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 -6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 -3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C -4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 -C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>79 -D<D907FF130E013FEBE01E90B5EAF83E0003ECFE7E3A07FC01FFFE390FF0001F4848130F -48481303491301007F140090C8FC167E5A163EA27F161E7F7F6D91C7FC13FC387FFFE014 -FEECFFF06C14FE6F7E6C816C15F06C816C81C681133F010F801301D9000F1480EC007F03 -0F13C01503818100F0157FA3163FA27E17807E167F6C16007E6D14FE01E0495A01F81303 -9039FF801FF800FC90B512E0D8F83F5CD8F00749C7FC39E0007FF02A3B7BB935>83 -D<B600FC011FB512C0A426007FF8C8381FC000725AB3B3181F013F94C7FC8060011F163E -6D6C157E187C6D6C15FC6D6D495A6D6DEB07F06D01F0EB1FE0DA7FFEEBFFC0021FB6C8FC -02075C020014F0030F1380423A7DB849>85 D<EB3FFE0003B512E0000F14F8391FF00FFE -003FEB03FF6D6C7F6E7FA26F7EA26C5A6C5AEA0380C8FCA2EC3FFF010FB5FC137F3901FF -F87F00071380380FFE00EA3FF85B485A12FF5BA415FF6D5A127F263FF00713F83B1FFC1F -BFFFC0390FFFFE1F0003EBF80F39003FE0032A257DA42E>97 D<13FFB5FCA412077EAF4A -B47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB3FE091C713F0EE1FF8 -A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14C0903AFDF001FF8090 -3AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB935>I<903801FFC001 -0F13FC017F13FFD9FF8013802603FE0013C048485AEA0FF8121F13F0123F6E13804848EB -7F00151C92C7FC12FFA9127FA27F123FED01E06C7E15036C6CEB07C06C6C14806C6C131F -C69038C07E006DB45A010F13F00101138023257DA42A>I<EE7F80ED7FFFA4150381AF90 -3801FF81010F13F1013F13FD9038FFC07F0003EB001FD807FC1307000F8048487F5B123F -A2485AA312FFAA127FA27F123FA26C6C5B000F5C6C6C5B6C6C4913C02701FF80FD13FE39 -007FFFF9011F13E1010113012F3A7DB935>I<903803FF80011F13F0017F13FC3901FF83 -FE3A03FE007F804848133F484814C0001FEC1FE05B003FEC0FF0A2485A16F8150712FFA2 -90B6FCA301E0C8FCA4127FA36C7E1678121F6C6C14F86D14F000071403D801FFEB0FE06C -9038C07FC06DB51200010F13FC010113E025257DA42C>I<EC1FF0903801FFFC010713FF -90391FF87F8090383FE0FFD9FFC113C0A2481381A24813016E1380A2ED3E0092C7FCA8B6 -FCA4000390C8FCB3ABB512FEA4223A7DB91D>I<161FD907FEEBFFC090387FFFE348B6EA -EFE02607FE07138F260FF801131F48486C138F003F15CF4990387FC7C0EEC000007F81A6 -003F5DA26D13FF001F5D6C6C4890C7FC3907FE07FE48B512F86D13E0261E07FEC8FC90CA -FCA2123E123F7F6C7E90B512F8EDFF8016E06C15F86C816C815A001F81393FC0000F48C8 -138048157F5A163FA36C157F6C16006D5C6C6C495AD81FF0EB07FCD807FEEB3FF00001B6 -12C06C6C91C7FC010713F02B377DA530>I<13FFB5FCA412077EAFED7FC0913803FFF802 -0F13FE91381F03FFDA3C01138014784A7E4A14C05CA25CA291C7FCB3A3B5D8FC3F13FFA4 -303A7DB935>I<EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412 -077EB3A9B512F8A4153B7DBA1B>I<13FFB5FCA412077EAF92380FFFE0A4923803FC0016 -F0ED0FE0ED1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0F -FF496C7F806E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 -D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 -FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA -CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 -A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 -13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 -FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 -491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C -6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9039FF01FF80B500 -0F13F0023F13FC9138FE07FFDAF00113800003496C13C00280EB7FE091C713F0EE3FF8A2 -EE1FFCA3EE0FFEAA17FC161FA217F8163F17F06E137F6E14E06EEBFFC0DAF00313809139 -FC07FE0091383FFFF8020F13E0020390C7FC91C9FCACB512FCA42F357EA435>I<9038FE -03F000FFEB0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00 -150C92C7FC91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13 -FF381FC00F383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF -806C14C06C14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C -6C14FC6C14F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA5 -5BA45BA25B5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816C -EBC3E090383FFFC06D1380903803FE001D357EB425>I<01FFEC3FC0B5EB3FFFA4000714 -016C80B3A35DA25DA26C5C6E4813E06CD9C03E13FF90387FFFFC011F13F0010313803025 -7DA435>I<B539F001FFF8A4000390C7EA1F00161E6E133E6C153C6E137C6C15786E13F8 -017F5CECF001013F5C14F8011F495AA2ECFC07010F5CECFE0F010791C7FC6E5A6D131E15 -BE6D13BC15FC6D5BA36E5AA26E5AA26E5AA26E5AA22D257EA432>I<B539F01FFFF0A400 -0390398003F8006C01C013E06C1407D97FE05B6D6C485A6E48C7FC90381FFC3E010F5B90 -3807FEFC6D6C5A5D6D5B6D5B6E7E6E7E814A7EA24A7E903801F3FFD903E37FD907C17FEB -0FC049486C7E4A6C7E013E80496D7E49130F00016E7EB590383FFFF8A42D257EA432> -120 D<B539F001FFF8A4000390C7EA1F00161E6E133E6C153C6E137C6C15786E13F8017F -5CECF001013F5C14F8011F495AA2ECFC07010F5CECFE0F010791C7FC6E5A6D131E15BE6D -13BC15FC6D5BA36E5AA26E5AA26E5AA26E5AA292C8FCA25C141E003F133E387F803C38FF -C07C147814F8EBC1F0EBC3E06C485A387D1F80D83FFFC9FCEA1FFCEA07F02D357EA432> -I E -%EndDVIPSBitmapFont -/Fe 254[28 1[{ TeXbbad153fEncoding ReEncodeFont }1 99.6264 -/CMSY10 rf -%DVIPSBitmapFont: Ff ecrm1000 10 83 -/Ff 83 123 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 -0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 -A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 -3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 -12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I<DA0FF8 -13FC91397FFF07FF903B01F807DF83C0903A07E001FF0F903B1F8007FE1FE090393F000F -FC137E16F85B9338F007804848010790C7FC1503ACB812F8A32801F80003F0C7FCB3AB48 -6C497E267FFFE0B512F0A3333B7FBA30>27 D<EC0FF8EC7FFE903901F80780903907E001 -C090391F8000E090383F0007017E497EA25BA2485A6F5AED018092C8FCA9ED03F0B7FCA3 -3901F8000F1503B3AA486C497E267FFFE0B512C0A32A3B7FBA2E>I<EC0FFC91387FFF70 -903901F803F0903807E00790381F800FEB3F00137EA25B150748481303ADB7FCA33901F8 -0003B3AB486C497E267FFFE0B512C0A32A3B7FBA2E>I<DA0FF0EB1FF0DA7FFEEBFFFC90 -3B01F80F83F00F903C07E001CFC00380903C1F8000FF0001C090273F0007FE130F017E49 -48497EA2495CA248485C03076E5A03030203C7FC95C8FCA9F007E0BAFCA33C01F80003F0 -001F1807B3AA486C496C497E267FFFE0B500C1B51280A3413B7FBA45>I<DA0FF8EB1FF8 -DA7FFF9038FFFEE0903B01F80783F007903B07E001CFC00F903B1F8007FF001F4948485A -017E5CA2495C180F48486D4813071503ACBAFCA33C01F80003F00007B3AB486C496C497E -267FFFE0B500C1B51280A3413B7FBA45>I<007C137C00FE13FEEAFF01A3EAFE00A7007E -13FC007C137CA8003C137800381338A700181330171E77BA2A>34 -D<017C166048B416F02607C3801401260F81C01403D900E04A5A001E01784A5A003E6D14 -1F003C013FEC7F80007C90271BE003FFC7FC0218B512BF007891381FFC3E00F8011CC75A -020C14FC5F4C5A16035F4C5A160F5F4CC8FC021C5B00780118133E007C5D16FC003C0138 -5B003E90383001F0001EEB70036C01E05B903981C007C03907C3800F2601FF005BD8007C -49C9FC90C748EB07C0033EEB1FF04BEB3C3803FCEBF81C4B497E913A01F001E006020301 -03130703E0497E912607C0071480020F15011580DA1F00018013C04A010F1300143E5C14 -FC5C495A13035C495A130F4A0107130149C701C013805B013E1603490203140001FC6F5A -49020113064848913800F00E0003705A49ED3C3849ED1FF06C48ED07C03A437BBD45>37 -D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A -12600A1979B917>39 D<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485A -A212075B120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F1207 -7F1203A26C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>I<12 -C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7FA214 -80A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A25BA2 -485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<EB0380497EA7397803803C00 -FC147E00FE14FE397F8383FC393FC387F8390FE38FE03903FBBF803900FFFE00EB3FF8EB -0FE0A2EB3FF8EBFFFE3903FBBF80390FE38FE0393FC387F8397F8383FC39FE0380FE00FC -147E0078143C390007C000A76D5A1F247BBD2A>I<1530B3A8B912FCA2C80030C8FCB3A8 -36367BAF41>I<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A12 -06120E5A5A5A12600A19798817>I<B512FCA516057F941C>I<121C127FEAFF80A5EA7F00 -121C0909798817>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A2 -14011580A2140315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA2 -13015CA2130391C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05B -A212015B120390C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05A -A21F537BBD2A>I<EB03F8EB1FFF90387E0FC09038F803E03901E000F048481378000714 -7C48487FA248C77EA2481580A3007EEC0FC0A500FE15E0B3007E15C0A4007F141F6C1580 -A36C1500A26C6C133EA26C6C5B6C6C5BEBF0013900F803E090387E0FC0D91FFFC7FCEB03 -F823397DB62A>I<EB01C013031307131F13FFB5FCA2131F1200B3B3A7497E007FB512F0 -A31C3779B62A>I<EB0FF0EB7FFE48B57E3903E03FE0390F000FF0001E6D7E001C6D7E48 -6D7E5A6E7E126012FE6CEC7F807FA56CC7FC121CC8FCEDFF00A25D14015D14035D4A5A4A -5A5D4A5A4AC7FC147E5C495A14E0495A495A49C8FC011EEB01805B5B4913034848140048 -5A485A90C75A48B6FC5A5A485CB6FCA321377CB62A>I<EB07F8EB3FFF90B512C03901F8 -0FF03903C007F848486C7E390E0001FEEA0F80391FE000FF7FA56C5A6C5AC7485AA25D14 -035D4A5A5DEC0F80027FC7FCEB1FFCECFF809038000FE06E7EEC01FC816E7EED7F80A216 -C0A2153F16E0A2121EEA7F80A2487EA316C0157F491480007EC7FC0070ECFF006C495A12 -1E390F8003F83907F00FF00001B512C06C6C90C7FCEB0FF823397DB62A>I<1538A21578 -15F8A2140114031407A2140F141F141B14331473146314C313011483EB03031307130613 -0C131C131813301370136013C01201EA038013005A120E120C5A123812305A12E0B712F8 -A3C73803F800AA4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F8 -90B5FC5D5D158092C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E0 -3907C003F0496C7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12 -FC00605C12704A5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB -1FE021397CB62A>I<EC3FC0903801FFF0010713FC90380FE03E90383F800790387E001F -49EB3F804848137F485A12075B000FEC3F0049131E001F91C7FC5B123FA3127F90C9FCEB -01FC903807FF8039FF1E07E090383801F0496C7E01607F01E0137E497F16805BED1FC0A3 -90C713E0A57EA47F123F16C0A2001FEC3F807F000F15006D5B000714FE6C6C5B6C6C485A -3900FE07F090387FFFC0011F90C7FCEB03FC23397DB62A>I<12301238123E003FB612E0 -A316C05A168016000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC -1406140E5CA25C1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA9 -6DC8FC131E233A7BB72A>I<EB03F8EB1FFF017F13C09038FC07F03901E001F83903C000 -7C4848133C90C7123E48141E000E141F001E80A3121FA26D5B6D131E7FD80FF85B6D137C -01FF13786C6D5A6CEBE3E0ECF780C601FFC7FC6D5A6D6C7E010F13E0013F7F01F97F3901 -E07FFE48486C7E380F800F48486C1380001E010113C0487F007C143F0078EC1FE0150F00 -F81407481403A21501A36C15C0A200781403007C15806C14076CEC0F006C6C131ED807E0 -137C3903F803F0C6B55A013F1380D907FCC7FC23397DB62A>I<EB03F8EB1FFF017F13C0 -3901FC07E048486C7E3907E001F8000F6D7E4848137E5B003F80A248C71380A25AED1FC0 -A516E0A56C143FA36C7E157F121F6C6C13FF6C6C13DF000313013901F0039F3900FC0F1F -D93FFC13C0EB07F090C7FCA2153F1680A216005D120F486C137E486C5BA24A5A4A5A4948 -5A381F000F001CEB1F80260F807FC7FC3807FFFE000113F838003FC023397DB62A>I<12 -1C127FEAFF80A5EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<12 -1C127FEAFF80A5EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A4120113 -80A2120313005A1206120E5A5A5A12600A3479A317>I<007FB812F8B912FCCCFCB0B912 -FC6C17F836147B9E41>61 D<EB3FE03801FFFE3907C03F80390E000FC0003CEB07F00030 -1303007014F8007C130100FE14FC7EA4127E003CEB03F8C7FCEC07F0A2EC0FE0EC1F80EC -3F00147E147C5C495A5C495A5CA249C7FCA31306AA90C8FCA8130EEB3F80497EA56D5A01 -0EC7FC1E3B7CBA27>63 D<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA2020E -7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D901807F -81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7EA2 -13E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 -D<B712E016FC16FF0001903980007FC06C90C7EA1FE0707E707E707EA2707EA283A75F16 -035F4C5A4C5A4C5A4C5AEEFF8091B500FCC7FCA291C7EA7F80EE1FE0EE07F0707E707E83 -707EA21880177F18C0A7188017FFA24C13005F16034C5AEE1FF8486DEB7FF0B812C094C7 -FC16F832397DB83B>I<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 -FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 -48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 -3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 -5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D -7BBA3C>I<B712C016F816FE000190398001FF806C90C7EA3FE0EE0FF0EE03F8707E707E -177FA2EF3F8018C0171F18E0170F18F0A3EF07F8A418FCAC18F8A4EF0FF0A218E0A2171F -18C0EF3F80A2EF7F0017FE4C5A4C5AEE0FF0EE3FE0486DEBFF80B8C7FC16F816C036397D -B83F>I<B812FEA3000190388000076C90C8FC173F838383A383A31880170116C0A394C7 -FCA31501A21503150F91B5FCA3EC000F15031501A21500A21860A318E093C712C0A41701 -A3EF0380A21707A2170F173F177F486D903807FF00B9FCA333397EB838>I<B812F8A300 -01903880001F6C90C71201EE00FC177C173C171CA2170CA4170E1706A2ED0180A21700A4 -1503A21507151F91B5FCA3EC001F15071503A21501A692C8FCAD4813C0B612C0A32F397D -B836>I<DBFF8013C0020FEBF001023F13FC9139FF803F03903A03FC000787D90FF0EB03 -CF4948EB00EF4948147F4948143F49C8121F485A4848150F48481507A248481503A2485A -1701123F5B007F1600A448481600AB93B6FCA26C7E9338007FE0EF3FC0A2123F7F121FA2 -6C7EA26C7EA26C7E6C7E6C6C157F6D7E6D6C14FF6D6C14EFD90FF8EB03C7D903FEEB0783 -903A00FFC03F0191393FFFFC00020F01F0130002001380383D7CBA41>I<B648B512FEA3 -0001902680000313006C90C76C5AB3A491B6FCA391C71201B3A6486D497EB648B512FEA3 -37397DB83E>I<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81E>I<013FB512 -E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C -5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>I<B649B5FCA300010180 -9038007FF06C90C8EA3F80053EC7FC173C17385F5F4C5A4C5A4CC8FC160E5E5E5E5E4B5A -ED0780030EC9FC5D153E157E15FF5C4A7F4A6C7E140E4A6C7E4A6C7E14704A6C7E4A6C7E -14804A6C7E6F7EA26F7F707EA2707E707EA2707EA2707E707EA2707E707F8484486D497F -B6011FEBFF80A339397DB841>I<B612E0A3000101C0C8FC6C90C9FCB3AD1718A5173817 -30A31770A317F0A216011603160FEE1FE0486D13FFB8FCA32D397DB834>I<B5933807FF -F86E5DA20001F0FC002600DFC0ED1BF8A2D9CFE01533A3D9C7F01563A3D9C3F815C3A2D9 -C1FCEC0183A3D9C0FEEC0303A2027F1406A36E6C130CA36E6C1318A26E6C1330A36E6C13 -60A26E6C13C0A3913901FC0180A3913900FE0300A2ED7F06A3ED3F8CA2ED1FD8A3ED0FF0 -A3486C6D5A487ED80FFC6D48497EB500C00203B512F8A2ED018045397DB84C>I<B59138 -07FFFE8080C69238007FE06EEC1F80D9DFF0EC0F001706EBCFF8EBC7FCA2EBC3FEEBC1FF -A201C07F6E7EA26E7E6E7E81140F6E7E8114036E7E168080ED7FC016E0153FED1FF0ED0F -F8A2ED07FCED03FEA2ED01FF6F1386A2EE7FC6EE3FE6A2EE1FF6EE0FFEA216071603A216 -011600A2177E486C153E487ED80FFC151EB500C0140EA2170637397DB83E>I<EC03FF02 -1F13E09138FE01FC903901F8007ED907E0EB1F8049486D7ED93F80EB07F049C76C7E01FE -6E7E48486E7E49157E0003167F4848ED3F80A24848ED1FC0A2001F17E049150F003F17F0 -A3007F17F8491507A300FF17FCAC007F17F86D150FA3003F17F0A26C6CED1FE0A36C6CED -3FC0000717806D157F000317006C6C15FEA26C6C4A5A017F4A5A6D6C495A6D6C495AD907 -E0EB1F80D903F8017FC7FC903900FE01FC91381FFFE0020390C8FC363D7BBA41>I<B712 -C016FC16FF0001D9800013C06C90C7EA1FE0707EEE03F883707EA2707EA21880A71800A2 -4C5AA24C5A5FEE0FF04C5AEEFF8091B548C7FC16F091CAFCB3A5487FB6FCA331397EB838 ->I<EC03FF021F13E09138FE01FC903901F8007ED907E0EB1F8049486D7ED93F80EB07F0 -49C76C7E01FE6E7E48486E7EA24848157F0007178049153F000F17C049151F001F17E0A2 -4848ED0FF0A3007F17F8A2491507A200FF17FCAC007F17F8A26D150FA2003F17F0A26C6C -ED1FE0A36C6CED3FC00007027C14804AB4FC3C03F80383807F003B01FC0701C0FEEC0E00 -2600FE0CEBE1FC017FEC63F8D93F8CEB77F0D91FCCEB3FE0D907EE14806DB449C7FC0100 -D981FC130CEC1FFF0203131C91C7001E131C161F183CEF807CEFC0F8EE0FFFA318F08218 -E07013C07013809338007E00364B7BBA41>I<B612FEEDFFE016F8000190388007FE6C90 -C76C7EEE3FC0707E707E707EA2707EA283A65FA24C5AA24C5A4C5AEE3F8004FFC8FCED07 -FC91B512E05E9138000FF0ED03F8ED00FE82707E707EA2161F83A583A6F00180A217F816 -0F1803486D01071400B66D6C5A04011306933800FE0ECAEA3FFCEF07F0393B7DB83D>I< -D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F -003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 -F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 -151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D -EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< -003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 -A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>I<B6903807 -FFFEA3000101809038007FE06C90C8EA1F80EF0F001706B3B2170E6D150C80171C133F17 -186D6C14385F6D6C14F06D6C5C6D6C495A6D6CEB07806D6C49C7FC91387F807E91381FFF -F8020713E09138007F80373B7DB83E>I<B500FC91387FFF80A30003018091380FFC006C -90C8EA07E0715A6C705A6E1403017F93C7FCA280013F1506A26E140E011F150C80010F5D -A28001075DA26E147001031560A26D6C5CA2806D4A5AA2ED8003027F91C8FCA291383FC0 -06A215E0021F5BA2EDF01C020F1318A26E6C5AA215FC02035BA2EDFEE002015BA26E6C5A -A36FC9FCA3153EA2151CA3393B7EB83E>I<B5D8FC07B5D8F001B5FCA30007902780001F -FEC7EA1FF86C48C7D80FF8EC07E000010307ED03C01B807F6C6F6C1500A26E5F017F6E6C -1406A280013F4A6C5CA280011F4A6D5BEE067FA26D6C010E6D5BEE0C3FA26D6C011C6D5B -EE181FA26D6C6F5BEE300FA26D6C6F485AEE6007A26D6C4CC7FC9338C003FCA203805D91 -3B7F818001FE06A203C1150EDA3FC3C7EAFF0CA203E3151CDA1FE6EC7F98A215F6DA0FFC -EC3FF0A302075E4B141FA202035E4B140FA202015E4B1407A2020093C8FC4B80503B7EB8 -55>I<1303EB0FC0497E497EEB7CF83801F87E3803E01F3907C00F80391F0003E0003CEB -00F048147800E0141C48140C1E0D76B333>94 D<007FB81280B912C0A26C178032047970 -41>I<EB1FE0EBFFFC3803E03F3907000F80390F8007E0486C6C7E13E06E7EA26E7E6C5A -6C5AC8FCA4147FEB07FFEB3FE0EBFE00EA03F8EA0FF0EA1FC0123F485A90C7FC160C12FE -A31401A26C13036CEB077C903980063E18383FC01E3A0FE0781FF03A03FFF00FE03A007F -8007C026277DA52A>97 D<EA03F012FFA3120F1203B0EC1FE0EC7FF89038F1E03E9039F3 -801F809039F7000FC001FEEB07E049EB03F049EB01F85BED00FCA216FEA2167E167FAA16 -7E16FEA216FC15016D14F8ED03F07F01EEEB07E001C6EB0FC09039C7801F00903881E07E -903800FFF8C7EA1FC0283B7EB92E>I<EB03FC90381FFF8090387E03E03901F800704848 -13F83907E001FC380FC003A2EA1F80123F90380001F848EB00F01500A2127E12FEAA127E -127FA26C14067F001F140E6D130C000F141C6C6C13386C6C13706C6C13E039007C07C090 -381FFF00EB07F81F277DA525>I<ED0FC0EC03FFA3EC003F150FB0EB03F8EB1FFF90387E -078F9038F801EF3903F0007F4848133F4848131FA24848130F123F90C7FC5AA2127E12FE -AA127E127FA27EA26C6C131FA26C6C133F6C6C137F6C6CEBEFF03A01F801CFFF39007C07 -8F90381FFE0FD907F813C0283B7DB92E>I<EB07F8EB1FFF90387C0FC03901F803E03903 -F001F0D807E013F8380FC0004848137CA248C7127E153E5A153F127E12FEA3B7FCA248C8 -FCA5127EA2127FA26C14037F001F14076C6C13060007140E6D131CD801F013386C6C1370 -90387E03E090381FFF80903803FC0020277EA525>I<147E903803FF8090380FC1E0EB1F -8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FCB3AB487E387F -FFF8A31C3B7FBA19>I<ED03F090390FF00FF890393FFC3C3C9039F81F707C3901F00FE0 -3903E007C03A07C003E010000FECF000A248486C7EA86C6C485AA200075C6C6C485A6D48 -5A6D48C7FC38073FFC38060FF0000EC9FCA4120FA213C06CB512C015F86C14FE6CECFF80 -4815C03A0F80007FE048C7EA0FF0003E140348140116F8481400A56C1401007C15F06CEC -03E0003F1407D80F80EB0F80D807E0EB3F003901FC01FC39007FFFF0010790C7FC26387E -A52A>I<EA03F012FFA3120F1203B0EC0FF0EC3FFCECF03F9039F1C01F809039F3800FC0 -EBF70013FE496D7EA25BA35BB3A3486C497EB500C1B51280A3293A7EB92E>I<EA0380EA -0FE0487EA56C5AEA0380C8FCAAEA03F012FFA312071203B3AA487EB512C0A312387EB717 ->I<EB01C0EB07F0EB0FF8A5EB07F0EB01C090C7FCAAEB01F813FFA313071301B3B3A212 -3C127E00FF13F01303A214E038FE07C0127C383C0F00EA0FFEEA03F8154984B719>I<EA -03F012FFA3120F1203B1913801FFFCA39138007FC01600157C15705D4A5A4A5A4AC7FC14 -1E1438147814FC13F1EBF3FEEBF73F01FE7FEBF81F496C7E8114076E7E6E7E811400157E -157F811680ED1FC0486CEB3FF0B500C0B5FCA3283A7EB92C>I<EA03F012FFA3120F1203 -B3B3AD487EB512C0A3123A7EB917>I<2703F00FF0EB1FE000FFD93FFCEB7FF8913AF03F -01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC49D907F8EB0F -C0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445>I<3903F00F -F000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7EA25BA35BB3A3 -486C497EB500C1B51280A329257EA42E>I<EB03FE90380FFF8090383E03E09038F800F8 -4848137C48487F48487F4848EB0F80001F15C090C712074815E0A2007EEC03F0A400FE15 -F8A9007E15F0A2007F14076C15E0A26C6CEB0FC0000F15806D131F6C6CEB3F006C6C137E -C66C13F890387E03F090381FFFC0D903FEC7FC25277EA52A>I<3903F01FE000FFEB7FF8 -9038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F849130116FC15 -0016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614C09039F7803F -009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E>I<D903F813C0 -90381FFE0190387E07819038FC01C33903F000E3000714774848133749133F001F141F48 -5A150F48C7FCA312FEAA127FA37E6D131F121F6D133F120F6C6C137F6C6C13EF3901F801 -CF39007E078F90381FFE0FEB07F890C7FCABED1FE00203B5FCA328357DA42C>I<3807E0 -1F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E09038FC008049 -1300A45BB3A2487EB512F0A31C257EA421>I<EBFF03000313E7380F80FF381E003F487F -487F00707F12F0A2807EA27EB490C7FCEA7FE013FF6C13E06C13F86C7F00037FC67F0107 -1380EB007F141F00C0EB0FC01407A26C1303A37E15806C13077EEC0F00B4131E38F3C07C -38E1FFF038C03F801A277DA521>I<1318A51338A31378A313F8120112031207001FB5FC -B6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFEEB01F81A347F -B220>I<D803F0EB07E000FFEB01FFA3000FEB001F00031407B3A4150FA3151F12016D13 -3F0000EC77F86D9038E7FF8090383F03C790381FFF87903A03FC07E00029267EA42E>I< -B538803FFEA33A0FF8000FF06C48EB07E00003EC03C06D148000011500A26C6C1306A26D -130E017E130CA26D5BA2EC8038011F1330A26D6C5AA214E001075BA2903803F180A3D901 -FBC7FCA214FF6D5AA2147CA31438A227257EA32C>I<B53A1FFFE03FFEA3260FF8009038 -000FF86C48017EEB03E018C00003023EEB0180A26C6C013FEB0300A36C6CEC8006156FA2 -017E9038EFC00C15C7171CD93F01EBE01815830281EBF038D91F831430150102C3EBF870 -90260FC6001360A2D907E66D5A02EC137CA2D903FCEB7F804A133FA2010192C7FC4A7FA2 -0100141E4A130E0260130C37257EA33C>I<B538807FFFA33A03FE003FF00001EC1F8000 -0092C7FC017E131C6D13186D6C5AECC070010F5B6D6C5AECF180EB03FB6DB4C8FC6D5AA2 -147F804A7E8114CF903801C7E090380383F090380703F8EB0601496C7E011C137E49137F -01787F496D7E486C80000FEC3FF0D8FFFE90B51280A329247FA32C>I<B538803FFEA33A -0FF8000FF06C48EB07C00003EC03806C7E16007F00001406A2017E5BA2137F6D5BA26D6C -5AA2ECC070010F1360A26D6C5AA214F101035BA2D901FBC7FCA214FF6D5AA2147CA31438 -A21430A214701460A25CA2EA7C0100FE5B130391C8FC1306EAFC0EEA701C6C5AEA1FF0EA -0FC027357EA32C>I<003FB512FCA2EB8003D83E0013F8003CEB07F00038EB0FE0123000 -70EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495AA290387F0006 -13FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48EB03FC90B5FC -A21F247EA325>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fg ecbx1200 12 59 -/Fg 59 123 df<DB0FFFEB03FF4AB5D8C03F13C0020F02F1B512E0027F91B612F0902701 -FFF8039038FE1FF849018002F813FC010F4948EBF03F49484913E0495A4A15C0495AF11F -F801FF16804A6DEC07E070EC018096C7FCABBA12F0A5C69026E000030180C7FCB3B0007F -D9FFC1B67EA546467EC541>27 D<B612F8A91D097F9A25>45 D<EA07C0EA1FF0EA3FF8EA -7FFCEAFFFEA7EA7FFCEA3FF8EA1FF0EA07C00F0F788E1F>I<EC3FF849B5FC010F14E001 -3F14F890397FF01FFC9039FFC007FE4890380001FF48486D1380000716C049147F000F16 -E049143F001F16F0A2003F16F8A249141F007F16FCA600FF16FEB3A3007F16FCA56C6CEC -3FF8A3001F16F0A2000F16E06D147F000716C06D14FF6C6C4913806C6D4813006C6D485A -90397FF01FFC6DB55A010F14E0010314809026003FF8C7FC2F427CC038>48 -D<EC03C01407141F147FEB03FF133FB6FCA413C3EA0003B3B3ADB712FCA5264177C038> -I<ECFFE0010F13FE013F6D7E90B612E0000315F82607FC0313FE3A0FE0007FFFD81F806D -138048C7000F13C0488001C015E001F07F00FF6E13F07F17F881A46C5A6C5A6C5AC9FC17 -F05DA217E05D17C04B13804B1300A2ED1FFC4B5A5E4B5A4B5A4A90C7FC4A5A4A5AEC0FF0 -4A5AEC3F804AC7127814FE495A494814F8D907E014F0495A495A49C8FC017C1401491403 -48B7FC4816E05A5A5A5A5AB8FC17C0A42D417BC038>I<ECFFF0010713FF011F14C0017F -14F049C66C7ED803F8EB3FFED807E06D7E81D80FF86D138013FE001F16C07FA66C5A6C48 -15806C485BC814005D5E4B5A4B5A4B5A4A5B020F1380902607FFFEC7FC15F815FF16C090 -C713F0ED3FFCED0FFEEEFF80816F13C017E0A26F13F0A217F8A3EA0FC0EA3FF0487EA248 -7EA217F0A25D17E06C5A494913C05BD83F80491380D81FF0491300D80FFEEBFFFE6CB612 -F800015D6C6C14C0011F49C7FC010113E02D427BC038>I<163FA25E5E5D5DA25D5D5D5D -A25D92B5FCEC01F7EC03E7140715C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E013 -0714C0EB0F80EB1F00133E5BA25B485A485A485A120F5B48C7FC123E5A12FCB91280A5C8 -000F90C7FCAC027FB61280A531417DC038>I<0007150301E0143F01FFEB07FF91B6FC5E -5E5E5E5E16804BC7FC5D15E092C8FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F090 -39FFE03FFC9138000FFE01FC6D7E01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8 -A4EA0F80EA3FE0487E12FF7FA317F05B5D6C4815E05B007EC74813C0123E003F4A1380D8 -1FC0491300D80FF0495AD807FEEBFFFC6CB612F0C65D013F1480010F01FCC7FC010113C0 -2D427BC038>I<4AB47E021F13F0027F13FC49B6FC01079038807F8090390FFC001FD93F -F014C04948137F4948EBFFE048495A5A1400485A120FA248486D13C0EE7F80EE1E00003F -92C7FCA25B127FA2EC07FC91381FFF8000FF017F13E091B512F89039F9F01FFC9039FBC0 -07FE9039FF8003FF17804A6C13C05B6F13E0A24915F0A317F85BA4127FA5123FA217F07F -121FA2000F4A13E0A26C6C15C06D4913806C018014006C6D485A6C9038E01FFC6DB55A01 -1F5C010714C0010191C7FC9038003FF02D427BC038>I<121E121F13FC90B712FEA45A17 -FC17F817F017E017C0A2481680007EC8EA3F00007C157E5E00785D15014B5A00F84A5A48 -4A5A5E151FC848C7FC157E5DA24A5A14035D14074A5AA2141F5D143FA2147F5D14FFA25B -A35B92C8FCA35BA55BAA6D5A6D5A6D5A2F447AC238>I<EC7FF00103B5FC010F14C0013F -14F090397F801FFC3A01FC0003FE48486D7E497F4848EC7F80163F484815C0A2001F151F -A27FA27F7F01FE143F6D158002C0137F02F014006C01FC5B6E485A6C9038FF83FCEDE7F8 -6CECFFE06C5D6C92C7FC6D14C06D80010F14F882013F8090B7FC48013F14802607FC0F14 -C0260FF80314E04848C6FC496D13F0003F141F48481307496D13F8150000FF157F90C812 -3F161F160FA21607A36D15F0127F160F6D15E06C6C141F6DEC3FC06C6CEC7F80D80FFE90 -3801FF003A07FFC00FFE6C90B55AC615F0013F14C0010F91C7FC010013F02D427BC038> -I<EC7FF0903807FFFE011F6D7E017F14E09039FFE03FF0489038800FF848496C7E484880 -48486D7E001F80003F1680A2484815C08117E0A212FF17F0A617F8A45D127FA3003F5CA2 -6C7E5D6C6C5B12076C6C131E6CEBC07C6CEBFFF8013F5B010F01C013F00101130090C8FC -A217E05DA2EA03C0D80FF015C0487E486C491380A217004B5A150F5E49495A6C48495A01 -C0EBFFE0260FF0035B6CB65A6C4AC7FC6C14F86C6C13E0D907FEC8FC2D427BC038>I<90 -3807FFC0013F13FC48B612804815E0260FF80013F0D81FC0EB3FF848C7EA1FFC4815FE01 -C0130F486C14FF7FA66C485B6C4814FE000FC7FCC8EA3FFCED7FF8EDFFF04A13E04A1380 -1600EC07FC4A5A5D4A5A5D4A5A92C7FCA2147E147CA31478AA91C8FCA814F8EB03FE497E -497FA2497FA56D5BA26D90C7FC6D5AEB00F828467AC535>63 D<EE1F80A24C7EA24C7EA3 -4C7EA24B7FA34B7FA24B7FA34B7F169F031F80161F82033F80ED3E07037E80157C8203FC -804B7E02018115F0820203814B137F0207815D173F020F814B7F021F8292C77EA24A8202 -3E80027E82027FB7FCA291B87EA2498302F0C8FCA20103834A157F0107834A153FA24948 -8284011F8491C97E4984133E017E82B6020FB612F0A54C457CC455>65 -D<B9FC18F018FE727E19E026003FFCC700077F05017F716C7E727E727EA2721380A37213 -C0A74E1380A24E1300A24E5A4E5A4E5A4D5B05075B94B5128091B700FCC7FC18F018FF19 -E002FCC7000113F8716C7EF01FFE727E7213801AC07213E0A27213F0A31AF8A71AF0A260 -1AE0604E13C0604E138095B5120005075BBA12F86119C04EC7FC18E045447CC350>I<DC -FFF01470031F01FF14F04AB6EAE0010207EDF803023FEDFE0791B539E001FF0F4949C7EA -3F9F010701F0EC0FFF4901C0804990C87E4948814948814948167F4849163F4849161F5A -4A160F485B19074890CAFC19035A5BA2007F1801A34994C7FC12FFAE127F7F1AF0A2123F -A27F6C18011AE06C7F19036C6D17C06E16077E6C6DEE0F806C6DEE1F006D6C5E6D6C167E -6D6C6C5D6D6D4A5A6D01F0EC07F0010101FEEC1FE06D903AFFF001FF80023F90B6C7FC02 -0715FC020115F0DA001F1480030001F8C8FC44467AC451>I<B9FC18F018FE727E19E026 -003FFEC7001F13F805017F9438003FFF060F7F727F727F727F84737E737EA2737EA2737E -A21B80A2851BC0A51BE0AD1BC0A51B8061A21B006162193F624F5A19FF624E5B06075B4E -5B063F90C7FC4DB45A050F13F8BA5A19C04EC8FC18F095C9FC4B447CC356>I<BA12F8A4 -85D8001F90C71201EF003F180F180318011800A2197E193EA3191EA21778A285A405F890 -C7FCA316011603161F92B5FCA5ED001F160316011600A2F101E01778A2F103C0A494C7FC -1907A21A80A2190FA2191FA2193FF17F0061601807181F4DB5FCBBFC61A443447DC34A> -I<BA1280A419C026003FFEC7121F1701EF007F183F181F180F180719E01803A31801A3EE -01E0F000F0A419001603A31607160F167F91B6FCA59138FE007F160F16071603A31601A6 -93C9FCAFB712F0A53C447CC346>I<DCFFF01470031F01FF14F04AB6EAE0010207EDF803 -023FEDFE0791B539E001FF0F4949C7EA3F9F010701F0EC0FFF4901C0804990C87E494881 -4948814948167F4849163F4849161F5A4A160F485B19074890CAFC19035A5BA2007F1801 -A34994C8FC12FFAD057FB612F0127F7FA3003FDC0001EBF000A27F7EA26C7FA26C7F807E -6C7F6C7F6D7E6D6C5D6D6C7E6D6D5C6D01F05C010101FE143F6D903AFFF001FF9F023F90 -B6120F0207EDFC030201EDF000DA001F02C01330030001FCC9FC4C467AC458>I<B7D880 -03B612FEA526003FFEC9EBF800B3A791B9FCA54AC9FCB3AAB7D88003B612FEA54F447CC3 -58>I<0107B7FCA590C7001F1300B3B3A9EA1FE0487E487EA2487EA44B5AA26C48495A49 -5C6C4813FF6C48485B260FFC0713C06CB65A6C4AC7FCC66C13F8010F138030457DC33A> -74 D<B712F0A526003FFECAFCB3B1F00780A4180F1900A460A360A2187EA218FE170117 -031707171F177FEE03FFB95AA539447CC343>76 D<B500FE067FB512806E95B6FCA26F5E -A2D8003F50C7FC013D6DEE03DFA2013C6DEE079FA26E6CEE0F1FA26E6C161EA26E6C163C -A36E6C1678A26E6C16F0A26E6DEC01E0A26E6DEC03C0A36E6DEC0780A26F6CEC0F00A26F -6C141EA26F6C5CA36F6C5CA26F6C5CA26F6D485AA26F6D485AA26F6D485AA3706C48C7FC -A293383FF81EA2706C5AA2706C5AA3706C5AA2705BA2705BA2705BA2B6057FB6128071C7 -FCA2173E171C61447CC36A>I<B64BB512FE8181A281D8003F6D91C7EA780081013D7F81 -133C6E7E6E7F6E7F6E7F6E7F82806E7F6E7F6F7E6F7F83816F7F6F7F6F7F6F7F6F7F8382 -707F707F707F707F8482707F707F717E7113807113C019E0837113F07113F87113FC7113 -FE19FF847213F884848484A28484197F193F191FA2190F1907B61603190119001A78A24F -447CC358>I<923807FFC092B512FE0207ECFFC0021F15F091267FFE0013FC902601FFF0 -EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E49486F7E49486F7E01FF8348496F -7E48496F1380A248496F13C0A24890C96C13E0A24819F04982003F19F8A3007F19FC4917 -7FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19F0A26E5D6C19E0A26C6D4B13 -C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D6C4A5B6D01C001075B6D01F0 -011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002004AC8FC030713C047467AC4 -54>I<B9FC18F018FE727E19E0D8001F90C7000F7F05017F716C7E727E727E721380A21A -C084A21AE0A91AC0A24E1380A21A00604E5A4E5A4D485A050F5B92B712C096C7FC18FC18 -C092CBFCB3A7B712E0A543447DC34D>I<923807FFC092B512FE0207ECFFC0021F15F091 -267FFE0013FC902601FFF0EB1FFF010701C0010713C04990C700017F49486E7F49486F7E -49486F7E49486F7E48496F7E48496F1380A248496F13C0A24819E091C97E4819F0A24848 -7013F8A3007F19FCA249177FA300FF19FEAD007F19FCA36D17FF003F19F8A3001F19F06D -5EA26C19E06E01FE5B6C912603FF8014C06C6D486D4813804B13E06C9028E01F83F00F13 -006C903BF01E00F81FFE90267FF83E90387C3FFC90263FFC3C6D485AD91FFE91381EFFF0 -D90FFF021F5B6D01FE5D010194C7FC6D6D6CB45A023F90B512F8020703E0130202006F13 -07030713C792C7EA07F8716C130F72131F9538FF80FF96B5FC7114FEA3831AFCA27213F8 -1AF0847213E07213C0721300F001FC48587AC454>I<B812F8EFFFC018F818FE727ED800 -1F90C7003F13E005037F05007F727E727E727EA28684A286A762A24E90C7FCA24E5A6118 -7F943801FFF005075B053F138092B7C8FC18F818E018F892C77FEF3FFF050F7F717F717F -A2717FA2717FA785A61B0F85A2187F73131F72141EB700E06DEB803E72EBE0FC72EBFFF8 -060114F0726C13E0CC0007138050457DC354>I<DAFFE0131C010701FE133C013F9038FF -807C90B6EAE0FC4815F9489038801FFF3907FC00014848EB007F4848143F4848140F4914 -07007F15035B1601160012FF177CA27FA26D153C7F7F6D92C7FC6C7EEBFFE014FE6CEBFF -F015FF6C15E016FC6C816C6F7E6C826C826C6C81011F810107811300020F80140003077F -ED007F82040F1380828212F082A282A27EA218007EA26C5D6C5E6D14036D5D6D140701F8 -4A5A01FFEC3FF002F8EBFFE0486CB65AD8FC1F92C7FCD8F80714FC48C614F04801071380 -31467AC43E>I<003FBA12E0A59026FE000FEB8003D87FE09338003FF049171F90C71607 -A2007E1803007C1801A300781800A400F819F8481978A5C81700B3B3A20107B8FCA54543 -7CC24E>I<B76C010FB512F8A526003FFEC93803E000B3B3A9011F17076280190F6D606F -151F6D95C7FC6D6D5D197E6D6D5D6D6D1403DA7FFC4A5A6EB4EC3FF0020F9039F003FFE0 -6E90B61280020193C8FC6E6C14FC030F14E09226007FFEC9FC4D457CC356>I<B600FE01 -7FB691B512FEA526007FFCC8D83FFEC9EA7C006E82013F701778807415F86D705F6F7014 -016D705FA26F7014036D64814E6D14076D646F70140F6D041E94C7FCA26F023E6D5C6DDC -3C7F151E81027F037C6D5CF0783F6F70147C023F4B6C1578A26F01016F13F86E4B6C5D16 -806E02036F485A4E7E04C0EEE0036E4A486C5DA2DCE00FEDF0076E4B6C5D16F06E4A6F48 -C8FC051E7F04F8705A6E4A027F131EA2DCFC7CEDFE3E037F0178023F133C04FE16FF033F -01F85E4D8004FF17F86F496E5BA36F496E5BA26F604D80A26F90C86C5BA36F486F90C9FC -A26F48167EA30478163C6F457EC374>87 D<903801FFE0011F13FE017F6D7E48B612E03A -03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F090C7FCA40203 -B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B127F5B12FF5B -A35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF86CECE01FC66C -EB8007D90FFCC9FC322F7DAD36>97 D<EB7FC0B5FCA512037EB1ED0FF892B57E02C314E0 -02CF14F89139DFC03FFC9139FF000FFE02FCEB03FF4A6D13804A15C04A6D13E05CEF7FF0 -A218F8173FA318FCAC18F8A2177F18F0A3EFFFE06E15C06E5B6E491380027C491300496C -495A903AFC1FC07FFC496CB512F0D9F00314C049C691C7FCC8EA1FF036467DC43E>I<EC -3FFC49B512C0010F14F0013F14FC90397FF003FE9039FFC001FF0003495A48494813805B -120F485AA2485A6F1300007F6E5AED00784991C7FCA212FFAC6C7EA3123F6DEC03C0A26C -6C1407000F16806D140F6C6DEB1F006C6D133E6C01F05B3A007FFC03F86DB55A010F14C0 -010391C7FC9038003FF82A2F7CAD32>I<EE03FEED07FFA5ED001F160FB1EC3FE0903803 -FFFC010FEBFF8F013F14CF9039FFF807FF48EBC00148903880007F4890C7123F4848141F -49140F121F485AA3127F5BA212FFAC127FA37F123FA26C6C141FA26C6C143F0007157F6C -6C91B5FC6CD9C00314FC6C9038F01FEF6DB5128F011FEBFE0F010713F89026007FC0EBF8 -0036467CC43E>I<EC3FF80103B57E010F14E0013F8090397FF83FF89039FFC007FC4849 -6C7E48496C7E48486D1380485A001FED7FC05B003FED3FE0A2127F5B17F0161F12FFA290 -B7FCA401F0C9FCA5127FA27FA2123F17F06C7E16016C6C15E06C6C14036C6DEB07C06C6D -EB0F806C01F0EB3F0090397FFE01FE011FB55A010714F0010114C09026001FFEC7FC2C2F -7DAD33>I<EDFF80020F13E0027F13F049B512F849EB8FFC90390FFE0FFE90381FFC1F14 -F8133FEB7FF0A2ED0FFCEBFFE0ED03F0ED00C01600ABB612F8A5C601E0C7FCB3B0007FEB -FFE0A527467DC522>I<DAFFE0137E010F9039FE03FF80013FEBFF8F90B812C048D9C07F -133F489038001FF84848EB0FFC4848903907FE1F80001F9238FF0F00496D90C7FCA2003F -82A8001F93C7FCA26D5B000F5D6C6C495A6C6C495A6C9038C07FF04890B55A1680D8078F -49C8FC018013E0000F90CAFCA47F7F7F90B612C016FC6CEDFF8017E06C826C16FC7E0003 -82000F82D81FF0C77ED83FC014074848020113808248C9FC177FA46D15FF007F17006D5C -6C6C4A5A6C6C4A5AD80FFEEC3FF83B07FFC001FFF0000190B612C06C6C92C7FC010F14F8 -D9007F90C8FC32427DAC38>I<EB7FC0B5FCA512037EB1ED07FE92383FFF8092B512E002 -C114F89139C7F03FFC9138CF801F9139DF000FFE14DE14FC4A6D7E5CA25CA35CB3A7B600 -83B512FEA537457CC43E>I<137C48B4FC4813804813C0A24813E0A56C13C0A26C13806C -1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520>I<EB7FC0B5FC -A512037EB293387FFFE0A593380FE0004C5A4CC7FC167E5EED03F8ED07E04B5A4B5A037F -C8FC15FEECC1FCECC3FE14C7ECDFFF91B57E82A202F97F02E17F02C07FEC807F6F7E826F -7E816F7F836F7F816F7F83707E163FB60003B512F8A535457DC43B>107 -D<EB7FC0B5FCA512037EB3B3B3A3B61280A519457CC420>I<90277F8007FEEC0FFCB590 -263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D8FC0 -0FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7EA24A -5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB590383FFF -8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02F86D -7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>I<EC1FFC49B512C0010714F0011F14 -FC90397FF80FFF9026FFC0017F48496C7F4848C7EA3FE000078248486E7E49140F001F82 -A2003F82491407007F82A400FF1780AA007F1700A46C6C4A5AA2001F5E6D141F000F5E6C -6C4A5AA26C6C6CEBFFE06C6D485B27007FF80F90C7FC6DB55A010F14F8010114C0902600 -1FFCC8FC312F7DAD38>I<90397FC00FF8B590B57E02C314E002CF14F89139DFC03FFC91 -39FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF3FFC -ACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07FFC02 -CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>I<DA3FE0131E90 -2603FFFC133E010F01FF137E013F1480903AFFF80FE0FE489038E003F148EBC001489038 -8000FB4890C7127F49143F001F151F485A160F5B127FA3485AAC6C7EA46C7EA26C6C141F -163F6C6C147F6C15FF6C6D5A6C9038E003EF6C9038F01FCF6DB5128F011FEBFE0F010313 -F89038007FC091C7FCAD0307B512FCA536407CAC3B>I<90387F807FB53881FFE0028313 -F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED01E0 -92C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F381F -F003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387FFFF0 -14FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000F014 -3FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A00FC -5CD8F03F13E026E007FEC7FC232F7CAD2C>I<EB01E0A51303A41307A2130FA2131FA213 -3F137F13FF1203000F90B51280B7FCA4C601E0C7FCB3A3ED01E0A9150302F013C0137F15 -0790393FF80F8090391FFC1F006DB5FC6D13FC01015B9038003FE023407EBE2C>I<D97F -C049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F713FE -9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I<B6903803 -FFFCA5000101E09038003E006C163C80017F5D8017F8013F5D6E1301011F5D6E1303010F -5D6E13076D5DED800F6D92C7FC15C05E6DEBE01E163E6D143CEDF07C027F1378EDF8F802 -3F5B15FD021F5B15FF6E5BA36E5BA26E90C8FCA26E5AA26E5AA21578362C7EAB3B>I<B5 -D8FE1FB539801FFFF0A500019027C0003FE0C7EA7C007114786E17F86C6F6C5C6E160101 -7F6E6C5CA26E011F1403013F6F5C6E013F1407011F6F5CA26E0179140F010F048090C7FC -6E01F95C6D02F0EBC01E15806D902681E07F5B18E003C3157C6D9139C03FF07815E76DDA -801F5B18F803FF14F96E9039000FFDE018FF6E486D5BA36E486D5BA26E486D90C8FCA24B -7F02075DA26E48147C4B143C4C2C7EAB51>I<B500FE90383FFFF0A5C601F0903803E000 -6D6C495A6D6C495A011F4AC7FC6E5B6D6C137E6DEB807C6D6D5A6DEBC1F0EDE3E06DEBF7 -C06EB45A806E90C8FC5D6E7E6E7F6E7FA24A7F4A7F8291381F3FFCEC3E1F027C7F4A6C7E -49486C7F01036D7F49487E02C08049486C7F49C76C7E013E6E7E017E141FB500E090B512 -FCA5362C7EAB3B>I<B6903803FFFCA5000101E09038003E006C163C80017F5D8017F801 -3F5D6E1301011F5D6E1303010F5D6E13076D5DED800F6D92C7FC15C05E6DEBE01E163E6D -143CEDF07C027F1378EDF8F8023F5B15FD021F5B15FF6E5BA36E5BA26E90C8FCA26E5AA2 -6E5AA21578A215F85D14015D001F1303D83F805B387FC007D8FFE05B140F92C9FC5C143E -495A387FC1F8EB07F06CB45A6C5B000790CAFCEA01FC36407EAB3B>I<001FB71280A490 -26FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B003C495BA24A90C7FC -4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A4948130F49481400A2 -485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4292C7DAB32>I -E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fh ecbx1440 14.4 44 -/Fh 44 123 df<913803FF80023F13F849B6FC010715C04901017F903A3FFC007FF8D97F -F0EB1FFC49486D7E48496D7E4A7F4817804890C76C13C0A248486E13E0A2001F17F0A300 -3F17F8A249157FA2007F17FCA600FF17FEB3A5007F17FCA6003F17F86D15FFA3001F17F0 -A3000F17E06D5C6C17C0A26C6D4913806C17006E5B6C6D495A6D6C495AD93FFCEB7FF890 -3A0FFF01FFE06D90B55A010192C7FCD9003F13F802031380374F7BCD42>48 -D<151E153E15FE1403140F147FEB07FF0003B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A600 -7FB712FCA52E4E76CD42>I<EC1FFE49B512F0010F14FC013FECFF804915E02701FF803F -7F2703FC000713FCD807F001017F48486D7FD81F806E138048C87E7013C0D87FE016E001 -F8806D16F000FF817F7013F8A56C5AA26C5A6C5AEA0380C914F05EA218E05E18C05E1880 -4C13005F4C5A4C5A5F4B5B4B5B4B5B94C7FCED0FFC4B5A4B5AED7FC04B5A4A90C8FCEC03 -FC4A5A4A4814F84A5A4A5A4AC8FC02FEEC01F0495A495A495A5CD90F80140349C8FC013E -1507017FB7FC90B812E05A5A5A5A5A5A5AB9FC18C0A4354E7ACD42>I<913807FFC0027F -13FC0103B67E010F15E090261FF80313F890267FC0007F01FEC7EA3FFE48488148486E13 -8013FE486C6C6D13C0804817E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300 -A24C5A5F4C5A4B5B4B13C0030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E0 -9238007FF8EE3FFE707E70138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0F -F0EA3FFC487EA2B5FCA218FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD8 -0FF04A1380D807FE91387FFE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114 -FCD9001F1380374F7BCD42>I<17FC1601A216031607160FA2161F163F167FA216FF5D5D -A25D5D5D167F153E157E15FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14 -FC495A5C495A1307495A5C49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E -127E5ABA1280A5C901FCC7FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FE -EC01FED9FFF0133F91B65A5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFC -AC913807FF80023F13F891B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E49 -6E7E01F86E7E5B7013804916C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212 -FF7FA218F0A25B5E6C4816E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CEC -FFFCD803FE4913F02701FFE00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFC -C8FC354F7ACD42>I<ED07FE92B512C0020314F0021F14FC91397FFC01FE9139FFE0007F -01030180EB3F804990C7121F4948EC7FC0494814FF4948010313E0495A49485B5A485BA2 -485BA2486F13C091C7FC4803001300177E94C7FC5AA25B127FA2ED3FF04AB5FC020714C0 -00FF4914F091391F807FF891393E001FFE02786D7E4A6D13807013C06D5A4A6D13E018F0 -5C7013F8A291C813FCA44916FEA3127FA6123FA37F6C17FCA36C17F85E7E6E15F06C17E0 -6C6D5B6E15C06C4B13806D6C491300D93FFC495A6DB4EBFFFC010790B512F06D5D010015 -80021F01FCC7FC020313C0374F7BCD42>I<121F7F7FEBFF8091B8FCA45A18FE18FC18F8 -18F0A218E018C018804817000180C8123E007EC9127E5F007C4B5A4C5A5F16074C5A484B -5A4CC7FC167E167CC912FC4B5A4B5AA24B5A150F4B5AA24B5AA24BC8FC5DA25C5D1403A2 -14075D140FA3141FA2143FA34A5AA414FFA65BAB6D5B6E5A6E5A6E5A385279D042>I<91 -3803FFC0023F13FC49B67E010715E090260FFC0013F8D93FE0EB1FFCD97F80EB07FE49C7 -6C7E496E1380484880000317C049157F120718E0173F120FA27FA27F7F6E147F02E015C0 -8002FC14FF6C01FF15806F481300EDE0036C9138F807FE6F485A6C9138FF1FF06CEDFFE0 -17806D4AC7FC7F010F6E7E6D81010115F06D81010315FE010F81D93FF71580D97FC115C0 -2701FF807F14E048EB001F48486D14F04848010314F848481300496E13FC003F151F4914 -07007F6F13FE491400177F00FF163F49151F170F1707A21703A218FCA27F127F6DED07F8 -A26C6CED0FF07F6C6CED1FE06C6CED3FC06C6CEDFF806C01C0010313006C01FCEB3FFE6C -6CB612F8011F15E001071580010002FCC7FC020F13C0374F7BCD42>I<913807FF80027F -13F849B512FE01076E7E90261FFE0113E0903A7FF8003FF049486D7E48496D7E48496D7E -484980486F138091C7FC486F13C05A18E0485A18F0A27013F812FFA318FCA618FEA35E12 -7FA4003F5DA26C7E5E7E6C6D5B161E6C7F6C6D5B6C6C6C13F890393FFC03F06DB55A0107 -4A13FC01001400EC1FF891C8FCA218F85EA301FC16F0487E2607FF8015E05E486D15C0A2 -4C1380A24C13005F4A131F6C4B5A49C7485A494A5A6C48495B6D01075B2701FF803F90C7 -FC6C90B512FC013F5C6D14C0010791C8FC9038007FF0374F7BCD42>I<173FA24D7EA34D -7EA24C7FA34C7FA24C7FA34C7FA24C7FA34C7F163E83047E80EE7C3F04FC8016F8830301 -814C7E03038116E0830307814C7E030F81168083031F811600834B81033E80037E82157C -8403FC824B800201835D840203834B800207835D92B8FC4A83A34A8392C9FC4A83143E85 -027E84027C8202FC845C850101854A820103855C850107854A82A2494884D93FF082B600 -F0020FB712C0A55A547CD363>65 D<B912FEF0FFF019FE737E1AE0D8000F01C0C7001F7F -06037F727F726C7E867313807313C0A27313E0A37313F0A94F13E0A34F13C01B80614F13 -00624F5A06035B4E13E0063F5B92B8C7FC19F8A2F1FF8003C0C7001F13E0060113F89538 -007FFE737E070F13C01BE07313F0851BF87313FCA27313FEA31BFFA91BFEA2611BFCA261 -4F13F81BF0614F13E0077F13C04EB51280060FEBFE00BB5A1AF01AC04FC7FC19C050527B -D15D>I<932603FFF01407047F01FF140F0307B600E0131F033F03F8133F92B700FE137F -02039126C003FF13FF020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC8149 -49814901E082011F498249498292CA7E4948834948835A4A83485B4885A24849187FA248 -5B1B3FA2485B1B1FA25AA21B0091CDFCA2B5FCAE7EA280A36C1A1FA36C7FA21B3F6C7F1B -3E6C7F1B7E6C6D187C6C1AFC6E18F86C19016D6CEF03F06D7E6FEE07E06D6DEE0FC00107 -6DEE1F806D01F8EE3F006D6D16FE6D01FF4B5A023F01C0EC07F8020F01FCEC3FF0020390 -3AFFC001FFC0020091B6C7FC033F15FC030715F0DB007F1480040301F0C8FC505479D25F ->I<BAFC19F819FF1AE01AF8D8000701F0C7001F13FE06017FDE003F13C0070F7F07037F -737F737F747E747E747F86747F8886888688A2747FA3881B7FA288A51D80AF1D00A564A2 -1BFF64A3505BA2505BA2505BA2505B505B99C7FC505A1A7F4F485A4F13F0070F5B073F5B -4EB55A061F49C8FCBB12F81AE097C9FC19F896CAFC59527CD165>I<BB12FCA5D8000701 -F0C7000F7F1800191F190F19071903190119001A7E1A7F86A386A51B80DD03E0130FA497 -C7FCA31707A3170F171F173FEE01FF92B6FCA5EDF001EE003F171F170F1707A31703A794 -CAFCB3A2B812F0A549527CD153>70 D<B8D88007B712FCA5D8000701F0C9003FEB8000B3 -AE92BAFCA503F0C9123FB3B1B8D88007B712FCA55E527CD167>72 -D<B81280A5D8000701F0C7FCB3B3B3B2B81280A529527DD130>I<B912FCF0FFE019FE73 -7E1AE0D8000F01E0C7003F7F060313FC06007F737E7313807313C07313E0851BF0A21BF8 -85A21BFCA91BF8A3611BF0A21BE04F13C0614F13804F13004F5A060713F8063F5B92B812 -C097C7FC19F8198003E0CBFCB3AEB712FEA54E527CD15A>80 D<DA0FFE141C91B500F013 -3C010702FC137C011F02FF13FC017F15C19026FFF00113E148903980001FFB4890C7EA07 -FFD807FC14014848804848153F171F4848150FA2007F1607491503A2170112FFA217007F -A26D167CA27F7F6D93C7FC6C7E14C014F8ECFF806C14F8EDFFC06C15FC6CEDFF8017F06C -16FC6C826C707E6C836D82011F8201078213016D6C81020781EC007F030380ED003F0403 -14801600173F837113C0838312F883A3837EA319807EA26C5E19007F6D4B5A7F6D4B5A01 -FC4B5A6D151FD9FFC04A5AD97FF8ECFFE028FE1FFF80075B010790B6C7FCD8FC0115FC48 -6C6C14F048010F14C0489026007FFCC8FC3A5479D249>83 D<003FBB12FCA59126C0007F -EB000301FCC7ED003FD87FF0F00FFE49180749180349180190C81600A2007E1A7EA3007C -1A3EA500FC1A3F481A1FA6C91700B3B3AC49B912C0A550517BD05B>I<B700FE4AB612F0 -A5D8000F01E0CA387FC000091FC7FCB3B3B26D611B3E811B7E6D197CA26D6D17FC636D6D -1601027F4D5A6F4C5A023F170F6E6C4C5A6E6D4B5A6E01E003FFC8FC6E01F8EC03FE0200 -01FEEC1FFC923B7FFFE001FFF8031F90B612E00307168003004BC9FC041F14F0040091CA -FC5C537CD165>I<B700F8017FB600FC49B612E0A5D8001F01C0C8001F01E0C9EBC0000E -1FC7FC6F6F606D73163E6F81207E6D73167C6F8120FC6D735E6F6F17016D735E616F1B03 -6D735E616F1B076E4C6E5D7015BF1F0F6E041F6E5D70031F161F6E9AC8FC073F8070DA3E -0F5E6E73143E197E70DA7C07167E6E04FC6E147C704A7E1FFC6E03016F5C704A7E6E515A -060381704A6C15036E735C1807704A6D14076F07805B7148487F1E0F6F021F04C05B05C0 -90C77E1E1F6F4A04E090C9FCDDE03E6E5C6FF1F03E187EDDF07C6E147E6FF1F87C18FC71 -486E14FC6F01F9715ADDFDF0801DFD6F01FFEFFFF04E806F62A24E817061A24E81706195 -C97EA27096CAFC4D82040F60A24D1607040760A24D16030403604D160104016083537ED1 -88>87 D<EC3FFE0107B512E0011F14FC017F14FF2701FFC00F13C02703FE00037F486C01 -007F6E6D7E486D80707EA2707EA3707F6C5B6C90C7FC6C5AC9FCA60307B5FC0203B6FC14 -7F0103B7FC011FEBF00F017F1300EBFFFC000313F04813C0485B4890C7FC5A5B485AF081 -F012FF5BA35EA26D5C127F6D5C003F03F713C36DD901E314E06CD9C00714FF00079026F0 -1F8114C06C90B5C61480C602FC6D1300011F01F0EB3FFC01010180EB07F03C387CB642> -97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB07FC4948497E -4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92C8FC5BA312FF -AD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E6C6D5C6D6C49 -5A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203138031387CB6 -3A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F849B512FE0107 -ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048498048498048 -8291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D5C5F6C6D91B5 -FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F010114FC6D6C -13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01076E7E011F01 -0313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E48824890C77E188048 -5A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F123FA2EF03E06C -7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495AD91FFFEB07F8 -6D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C>I<ED1FF891 -3803FFFE020FEBFF80023F14C09139FFF83FE001039038E0FFF049138049010113F85BEB -3FFEA2EB7FFCA26F13F0495AEE7FE0EE1F8093C7FCAEB712C0A5C601F8C8FCB3B3A7B612 -FEA52D547CD328>I<DA1FFE14FE49B539E007FF80010FDAFC1F13C0013FDAFF7F13E090 -267FF807EBFF072701FFE001EBF07F48497E484990387FF83F91C7003F14C048EEFC1F48 -9338FE070049021F90C7FCA2003F82A9001F5EA26D143F6C5E6C5E6E137F6C6D495A6C6D -485B6CD9F80713804890B6C8FCD803EF14FC01C114E02707C01FFEC9FC49CBFCA2487EA3 -7FA27F13FC90B612FE6CEDFFF017FCEFFF806C8318F06C836C837F48B87E1207D80FFCC7 -00037F4848EC003F4848150F48486F138083485A83A56D5D007F18006D5D003F5F6C6C4B -5A01FE153FD807FFED7FF06C01C049485AC601FC011F1380013FB648C7FC010F15F80101 -15C0D9000F01F8C8FC3B4F7CB542>I<EB3FF8B5FCA51203C6FCB3A4EE1FFC93B57E0303 -14E0030F14F892391FC07FFC92397E003FFE03F86D7EECF9F04B6D7FECFBC0ECFF8092C7 -6C7FA25CA25CA45CB3ACB6D8F807B612C0A542537CD249>I<133FEBFFC0487F487FA248 -7FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B612F0A51C547C -D324>I<EB3FF8B5FCA51203C6FCB3A50407B512F0A59339007FF000EF3FC04D5A4DC7FC -EE01FC4C5AEE0FF04C5A4C5A4CC8FC16FEED03FC4B5A4B5A4B5A4B7E4B7EECF9FF02FB7F -91B57EA28203BF7F031F7F14FE4A6C7FDAF0077F6F7FA26F7F6F7F167F83707F707FA270 -7F707F707FA2707F707F84B6D8F00F14FEA53F537DD245>107 D<EB3FF8B5FCA51203C6 -FCB3B3B3B1B612F8A51D537CD224>I<D93FF0D91FF84AB47EB591B56C010F13F8030302 -E0013F13FE030F6E90B6FCDB3F809027F803F80F7F922A7E007FFC07E0077F000302F890 -283FFE0F80037FC6D9F1F0011F49487EDAF3E0DAFF3E814B153CDAF7805D92C76C496D7F -14FF4A5EA24A5EA34A5EB3ADB6D8F80FB66CB612F8A565367BB56E>I<D93FF0EB1FFCB5 -91B57E030314E0030F14F892391FC07FFC92397E003FFE000302F86D7EC6EBF1F04B6D7F -ECF3C0ECF78092C76C7F14FF5CA25CA45CB3ACB6D8F807B612C0A542367CB549>I<9138 -01FFC0023F13FE91B67E010315E0010F018013F8903A3FFC001FFED97FF0EB07FF49486D -7F48496D7F48496D7F91C8127F4883488349153F001F83A2003F8349151FA2007F83A400 -FF1880AC007F1800A3003F5F6D153FA2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C -6D495B6D6C4990C7FCD93FFCEB1FFE6DB46CB45A010790B512F0010115C0D9003F49C8FC -020313E039387CB642>I<D93FF8EB7FF0B50107B5FC031F14C0037F14F09126F9FF0013 -FCDAFFF8EB3FFF000302E0010F7FC602806D7F92C76C7F4A824A804A6E7F85187F85A218 -3F85A4721380AD4E1300A44E5AA26118FF616E5C616E4A5B6E4A5B6F495B03E04990C7FC -6FEB7FFE913AF9FE01FFF802F8B65A033F14C0030749C8FC030013E093CAFCB1B612F8A5 -414D7DB549>I<90393FF001FCB590380FFF804B13E0037F13F09238FE1FF89138F1F83F -00019138F07FFC6CEBF3E015C0ECF780A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45C -B3ABB612FEA52E367DB535>114 D<903903FFC00E011FEBFC1E90B6127E000315FE3907 -FE003FD80FF0130F4848130348481301491300127F90C8127EA248153EA27FA27F01F091 -C7FC13FCEBFF806C13FEECFFF06C14FE6F7E6C15E06C816C15FC6C81C681133F010F1580 -1301D9000F14C0EC003F030713E0150100F880167F6C153FA2161F7EA217C07E6D143F17 -807F6DEC7F0001F85C6DEB03FE9039FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39 -E0007FF02B387CB634>I<147CA614FCA41301A31303A21307A2130F131F133F137F13FF -1203000F90B512FEB7FCA426007FFCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D -5A6DEBC1F86DEBFFF001005C023F1380DA03FEC7FC294D7ECB33>I<D93FF8913801FFC0 -B50207B5FCA50003ED001FC61607B3AE5FA35FA25F137F5F6D6C14F7DC01E713F06D6CD9 -07C7EBFFC0903A0FFF801F876D90B51207010114FC6D6C13F0020701C091C7FC42377CB5 -49>I<B600E090381FFFFCA5000101F8C7000113006CEE007C6E15FC017F5E8017016D6C -5D17036D5E6F13076D5E6F130FA26D6D5C171F6D93C7FC6F5B6D153E6F137E6D157C8117 -FC027F5CEDFE01023F5CEDFF036E5C168316876E5C16CF6E5C16FF6E91C8FCA36E5BA26E -5BA26F5AA36F5AA26F5AA26F5AA23E367DB445>I<B600E1B6D8800FB5FCA500019026F0 -000301C0C7EA3FE06E6D6DEC0F806CF21F00A26E6D6D5C017F193E6E147F72147E013F19 -7C6E6F14FC6D6117FF6F6E13016D4A5E03C06E13036D615E03E001E7EB80076D02075E03 -F001C313C06D4E5A160F03F80181EBE01F6D96C7FC6F48C6FC735A027F49153EDBFE3E90 -387FF87E023F177C167EDBFF7C90383FFCFC6E01FC5D4CEB1FFF6E5FA24C7F6E5F4C7F6E -5FA24C7F6E5F4C7FA26E94C8FC93C8FC6F5DA2033E157C58367DB45F>I<B600E090381F -FFFCA5000101F8C7000113006CEE007C6E15FC017F5E6E1401013F5E8017036D6D5C1707 -6D5E6F130F6D5E6F131F6D93C7FC815F6D6D133E177E6D157C6F13FC027F5C811601DA3F -FF5B16036E5C16876E5C16CF6E5C16EF16FF6E91C8FCA26E5BA26E5BA26F5AA36F5AA26F -5AA26F5AA35E151F93C9FC5D153E157ED81FC0137C487E486C13FC486C5B14015D4A5A14 -074A5A6C48485A4948CAFC495A383F81FC6CB45A6C5B000313C0C648CBFC3E4D7DB445> -121 D<003FB712FEA4DA000113FC01F815F801E05B494913F04915E090C75A4B13C0007E -4A1380A24B13004B5A007C5D5C4A5B5E5C4A5BC75C5C4A5B93C7FC5C4A5A495B5D5B4949 -131F5D5B495B5D49153F4990C7123E5C13FF485B4849147EA2484914FE485B4A13014815 -034849130791C7EA1FFC48EC01FFB8FCA430357CB43A>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fi ecrm0900 9 36 -/Fi 36 123 df<EC1FE0ECFFFC903803F01E90390FC00780EB1F8090393F000FC0017E13 -1F5BA2485AED0F8092C7FCA9ED0FC0B7FCA33901F8001F150FB3A6486CEB1FE0267FFFC1 -B5FCA328357FB42B>28 D<123C127EB4FCA21380A2127F123D1201A412031300A25A1206 -120E120C121C5A5A126009177A8715>44 D<123C127E12FFA4127E123C08087A8715>46 -D<123C127E12FFA4127E123C1200B0123C127E12FFA4127E123C08207A9F15>58 -D<123C127EB4FCA4127E123CC7FCB0123C127EB4FCA21380A2127F123D1201A412031300 -A25A1206120E120C121C5A5A1260092F7A9F15>I<B77E16F016FE3A01FE0001FF000091 -38003FC0EE0FE0707E707E707E707E177E177FEF3F80A2EF1FC0A3EF0FE0A418F0AA18E0 -A3171F18C0A21880173F18005F17FE5F4C5AEE07F04C5AEE3FC000014AB45AB748C7FC16 -F8168034337EB23B>68 D<B81280A3D803FCC7FC0001151FEE07C01603A21601A21600A4 -1760150CA31700A2151CA2153C15FC90B5FCA3EBFC00153C151CA2150CA592C8FCAB487E -B512FEA32B337DB232>70 D<B512FEA3000113006C5AB3B3A7487EB512FEA317337EB21C ->73 D<B512FEA3D803FEC9FC6C5AB3A9EE0180A416031700A45EA25E5E5E5E16FE000314 -07B7FCA329337DB230>76 D<D8FFFC923801FFF86D5DA20003EFFE00D801BFED06FCA3D9 -9F80140CA2D98FC01418A3D987E01430A2D983F01460A3D981F814C0A3D980FCEB0180A2 -027EEB0300A36E1306A26E6C5AA36E6C5AA36E6C5AA26E6C5AA36E6C5AA3913800FD80A2 -037FC7FCA3486C133ED80FF04B7EB5011C90387FFFF8A33D337CB246>I<007FB712FEA3 -90398007F001D87C00EC003E0078161E0070160EA20060160600E01607A3481603A6C715 -00B3AB4A7E011FB512FCA330337DB237>84 D<EB7F803803FFF0380F80FC381C003E003F -133F6D6C7E6E7EA26E7EEA1F00C7FCA4EB01FF131FEBFF873803FC07EA0FF0EA1FC0EA3F -80127F13004815C05AA3140FA26C131F6C133B3A3F8071F180391FC1E1FF2607FFC01300 -3900FE003C22237DA126>97 D<EA03F012FFA312071203AEEC3F80ECFFE09038F3C0F890 -38F7007E01FE7F49EB1F8049EB0FC05BED07E016F0A2150316F8AA16F0150716E0A2ED0F -C07F6DEB1F8001ECEB3F0001CF137C90388381F8903801FFE0C76CC7FC25357EB32B>I< -EB07F8EB3FFF9038FC07C03901F000E03903E003F03807C007120FEA1F80123F90380003 -E04890C7FCA2127E12FEAA127FA26C14187F001F14386D1330000F14706C6C13E03903F0 -01C03900FC0F8090383FFE00EB07F01D237EA122>I<153FEC0FFFA3EC007F81AEEB07F0 -EB3FFCEBFC0F3901F003BF3907E001FF48487E48487F8148C7FCA25A127E12FEAA127E12 -7FA27E6C6C5BA26C6C5B6C6C4813803A03F007BFFC3900F81E3FEB3FFCD90FE013002635 -7DB32B>I<EB0FE0EB7FFCEBF83F3903F00F80D807E013C0390FC007E0381F800315F0EA -3F0014014814F8127EA212FEA2B6FCA248C8FCA5127E127FA26C1418A26C6C1338000F14 -306D13706C6C13E03901F003C03900FC0F00EB3FFEEB07F01D237EA122>I<EB01FCEB07 -FF90381F078090383E0FC0EB7C1F13FCEA01F8A20003EB070049C7FCACB512F0A3D803F0 -C7FCB3A7487E387FFFE0A31A357FB417>I<151F90391FC07F809039FFF8E3C03901F07F -C73907E03F033A0FC01F83809039800F8000001F80EB00074880A66C5CEB800F000F5CEB -C01F6C6C48C7FCEBF07C380EFFF8380C1FC0001CC9FCA3121EA2121F380FFFFEECFFC06C -14F06C14FC4880381F0001003EEB007F4880ED1F8048140FA56C141F007C15006C143E6C -5C390FC001F83903F007E0C6B51280D91FFCC7FC22337EA126>I<EA03F012FFA3120712 -03AEEC1FC0EC7FF09038F1E0FC9038F3807C9038F7007E13FE497FA25BA25BB3486CEB7F -80B538C7FFFCA326347EB32B>I<EA0780EA0FC0EA1FE0A4EA0FC0EA0780C7FCAAEA07E0 -12FFA3120F1207B3A6EA0FF0B5FCA310337EB215>I<EA03F012FFA312071203AF913803 -FFE0A36E1300EC00F8EC01E05D4A5A020FC7FC141C5C5C14F0EBF3F8EBF7FC13FEEBFC7E -EBF87F496C7E141F6E7E8114076E7E8114016E7E81486CEBFF80B500C313F0A324347EB3 -29>107 D<EA07E012FFA3120F1207B3B3A7EA0FF0B5FCA310347EB315>I<2703F01FE013 -FF00FF90267FF80313C0903BF1E07C0F03E0903BF3803E1C01F02807F7003F387FD803FE -1470496D486C7EA2495CA2495CB3486C496C487EB53BC7FFFE3FFFF0A33C217EA041>I< -3903F01FC000FFEB7FF09038F1E0FC9038F3807C3907F7007EEA03FE497FA25BA25BB348 -6CEB7F80B538C7FFFCA326217EA02B>I<EB07F0EB3FFE9038FC1F803901F007C03903C0 -01E000078048486C7E48C7127CA248147E003E143E007E143FA300FE1580A8007E1500A3 -6C147EA26C147C6D13FC6C6C485A00075C3903F007E03900FC1F80D93FFEC7FCEB07F021 -237EA126>I<3903F03F8000FFEBFFE09038F3C0F89038F7007ED807FE7F6C48EB1F8049 -14C049130F16E0ED07F0A3ED03F8A9150716F0A216E0150F16C06D131F6DEB3F80160001 -FF13FC9038F381F89038F1FFE0D9F07FC7FC91C8FCAA487EB512C0A325307EA02B>I<90 -3807F00390383FFC07EBFC0F3901F8038F3807E001000F14DF48486CB4FC497F123F90C7 -7E5AA25A5AA9127FA36C6C5B121F6D5B000F5B3907E003BF3903F0073F3800F81EEB3FF8 -EB0FE090C7FCAAED7F8091380FFFFCA326307DA029>I<3803E07C38FFE1FF9038E38F80 -9038E71FC0EA07EEEA03ECA29038FC0F8049C7FCA35BB2487EB512E0A31A217FA01E>I< -EBFF06000713CE381F00FE003C133E48131E140E5A1406A27EA200FE90C7FC6C7EEA7FFC -383FFFC014F0000F7F6C7FC67FEB0FFF1300EC3F8000C0131F140F6C1307A37E15006C5B -6C130E6C5B38F7807838E1FFE038C07F8019237EA11E>I<1330A51370A313F0A21201A2 -12031207381FFFFEB5FCA23803F000AF1403A814073801F806A23800FC0EEB7E1CEB1FF8 -EB07E0182F7FAD1E>I<D803F0133F00FFEB0FFFA30007EB007F000380B35DA35D12016D -4813800000903803BFFC90387E073FEB1FFED907F8130026227EA02B>I<B5EBFFF0A3D8 -0FF0EB3F800007EC1F000003140E150C6D131C00011418A26C6C5BA26D1370017E136013 -7F6D5BA290381F8180A214C3010F90C7FCA2EB07E6A214FE6D5AA26D5AA36D5AA2146024 -217E9F29>I<B53A1FFF81FFF0A33C07F801FC003F8001F049EB1E0000030100141C816C -6C017C1318A26D017E1338000002FE1330A290267E01FF5B159F168090263F030F5BA216 -C0903A1F8607C180A202C613E390260FCC0390C7FCA2D907FC13F6ECF80116FE6D486C5A -A36D481378A36D48133034217F9F37>I<B53801FFF8A32603FE0013806C48EB7C000000 -1478017E1370017F5B90383F81C090381F8380D90FC3C7FCEB07E614FE6D5A6D5A6D7E80 -805B9038039F809038071FC09038060FE0EB0C0790381C03F0496C7E01707FEBF0000001 -80000FECFF8026FFFC0313FCA326207F9F29>I<3A7FFF807FF8A33A07F8001FC00003EC -0F800001EC070015066C6C5BA26D131C017E1318A26D5BA2EC8070011F1360ECC0E0010F -5BA2903807E180A214F3010390C7FC14FBEB01FEA26D5AA31478A21430A25CA214E05CA2 -495A1278D8FC03C8FCA21306130EEA701CEA7838EA1FF0EA0FC025307F9F29>I<003FB5 -12F0A2EB000F003C14E00038EB1FC00030EB3F800070137F1500006013FE495A13035CC6 -485A495AA2495A495A49C7FC153013FE485A12035B48481370485A001F14604913E0485A -387F000348130F90B5FCA21C207E9F22>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fj ecbx0900 9 7 -/Fj 7 117 df<ED1F80A24B7EA24B7EA34B7EA24A7FA34A7FA24A7F15CFA2020F7F1587 -021F801503023F80EC3E01A2027E80EC7C0002FC804A137FA20101814A133F0103814A13 -1FA249B67EA24981A290271F8000077F91C77EA24982013E80017E82017C80A201FC8249 -157FB500F0013FB512F0A43C347DB343>65 D<EB7FFE0003B512E04814F8390FF00FFC39 -1FF803FF806E138016C0157F6C5A6C5AEA0180C8FCEC7FFF010FB5FC90B6FC0003EBF07F -000F1300EA1FF8485A485A485A5BA315FF7F007F5B6D4813E03A3FF80FBFFF000FB5121F -0003EBFC0F39007FE00728217EA02B>97 D<EA01FC12FFA4120F1207ADEC0FF8EC7FFF01 -FDB512C09039FFF01FF09138800FF84A6C7E496D7E496D7EA2178081A217C0A91780A25D -1700A26D495A6D495A6E485A9039F7E03FF001E1B512C0D9C07F90C7FC9038801FF02A34 -7DB331>I<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 -A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 -07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF -EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 -1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 -5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB -007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 -E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 -FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I -E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fk ecrm1200 12 20 -/Fk 20 117 df<14FF010713E090381F81F890383E007C01FC133F4848EB1F8049130F48 -48EB07C04848EB03E0A2000F15F0491301001F15F8A2003F15FCA390C8FC4815FEA54815 -FFB3A46C15FEA56D1301003F15FCA3001F15F8A26C6CEB03F0A36C6CEB07E0000315C06D -130F6C6CEB1F806C6CEB3F00013E137C90381F81F8903807FFE0010090C7FC28447CC131 ->48 D<EB03FE90381FFFC0017F13F03901F80FFC3903C001FE48486C7E000EC7EA7F8048 -EC3FC0ED1FE04815F00030140F007015F800601407126CB415FC7F7F1503A46C4813076C -C7FCC8FC16F8A2150F16F0151F16E0A2ED3FC0ED7F8016005D5D4A5A4A5A4A5A5D4A5A4A -5A4AC7FC147C5C5C495A495A495A49C7120C131E5B013814185B5B485A4848143848C812 -30000E1570001FB612F0A25A5AB712E0A326427BC131>50 D<49B4FC010F13E0013F13FC -9038FE01FE3A01F0007F80D803C0EB3FC048C7EA1FE0120EED0FF0EA0FE0486C14F8A215 -077F5BA26C48130FEA03C0C813F0A3ED1FE0A2ED3FC01680ED7F0015FE4A5AEC03F0EC1F -C0D90FFFC7FC15F090380001FCEC007FED3F80ED1FC0ED0FE016F0ED07F816FC150316FE -A2150116FFA3121EEA7F80487EA416FE491303A2007EC713FC00701407003015F8003814 -0F6C15F06CEC1FE06C6CEB3FC0D803E0EB7F803A01FE01FE0039007FFFF8010F13E00101 -90C7FC28447CC131>I<ED0380A21507150FA2151F153FA2157F15FFA25CEC03BF153F14 -071406140C141C141814301470146014C013011480EB03005B13065B131C13185B137013 -6013E0485A5B120390C7FC1206120E120C5A123812305A12E0B812C0A3C8383F8000ADED -FFE0027FEBFFC0A32A437DC231>I<B712FEEEFFE017F800019039C00007FE6C6C489038 -00FF80EF3FC0EF0FF0717E717EEF00FE8484F03F80F01FC0A2F00FE019F0180719F8A218 -0319FCA3F001FEA419FFAD19FEA3180319FCA319F8180719F0180F19E0A2F01FC0F03F80 -A2F07F0018FE4D5A4D5AEF0FF0EF3FE0EFFF8048486C010790C7FCB812FC17E04CC8FC40 -447CC34A>68 D<B712FCEEFFC017F800019039C0000FFC6C6C48EB01FF9338007F80EF1F -E0170FEF07F018F8EF03FCA218FE1701A218FFA718FEA2170318FCA2EF07F818F0EF0FE0 -EF1FC0EF7F80933801FE00EE0FFC91B612F017800280C9FCB3AA3801FFE0B612C0A33844 -7CC342>80 D<49B41303010FEBE007013F13F89039FE00FE0FD801F8131FD807E0EB079F -49EB03DF48486DB4FC48C8FC4881003E81127E82127C00FC81A282A37E82A27EA26C6C91 -C7FC7F7FEA3FF813FE381FFFE06C13FE6CEBFFE06C14FC6C14FF6C15C0013F14F0010F80 -010180D9001F7F14019138001FFF03031380816F13C0167F163F161F17E000C0150FA316 -07A37EA36C16C0160F7E17806C151F6C16006C5D6D147ED8FBC05CD8F9F0495AD8F07C49 -5A90393FC00FE0D8E00FB51280010149C7FC39C0003FF02B487BC536>83 -D<EB07FC90383FFF809038F80FE03903C003F048C66C7E000E6D7ED80FC0137E486C137F -6D6D7EA36F7EA26C5AEA0380C8FCA4EC0FFF49B5FC90380FFE1FEB3FC0EBFF00EA03FC48 -5A485A485A485A127F5B176048C7FCA3153FA36D137F007F14EF6D9038C7E0C0003F1301 -3A1FE00783F13B07F81E03FF802701FFFC0113003A001FE0007C2B2E7CAC31>97 -D<EA01FC12FFA3120712031201B3EC03FC91380FFF8091383C07E091387001F89039FDE0 -007E02807F01FFEC1F8091C713C049EC0FE049140717F0A2EE03F8A217FCA2160117FEAB -17FC1603A217F8A2EE07F0A26DEC0FE017C06D141F01FBEC3F80D9F380EB7E00D9E1C05B -9039E0F001F89039C03C07E09039801FFF80C7D803FCC7FC2F467DC436>I<167FED3FFF -A315018182B3EC7F80903803FFF090380FC07C90383F000E017E1307496D5AD803F87F48 -487F5B000F81485AA2485AA2127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B -00035C6C6C9038077F806C6C010E13C0013F011C13FE90380FC0F8903803FFE09026007F -0013002F467DC436>100 D<EB01FE903807FFC090381F03F090387E00FC49137E48487F -485A4848EB1F80000F15C049130F121F484814E01507A2007F15F090C7FCA25AA390B6FC -A290C9FCA67EA27FA2123F16306C7E1670000F15606D14E06C6C14C0000314016C6CEB03 -806C6CEB0700013E131E90381F80F8903803FFE0010090C7FC242E7DAC2B>I<EA01FC12 -FFA3120712031201B3EC01FE913807FFC091381E07F091383801F802707FECE000D9FDC0 -7F5C01FF147F91C7FCA25BA35BB3A8486CECFF80B5D8F83F13FEA32F457DC436>104 -D<EA01E0EA07F8A2487EA46C5AA2EA01E0C8FCADEA01FC12FFA3120712031201B3B0487E -B512F8A315437DC21C>I<EA01FC12FFA3120712031201B3B3B3A5487EB512F8A315457D -C41C>108 D<D801FC01FFEC1FE000FF010701E0EBFFFC913B0F03F801E07F913C3C01FC -07803F800007903C7000FE0E001FC0000349D97E1C130F2601FDC0D97F38804A143001FF -DA3FF06D7E91C75BA2495DA3495DB3A8486C4A6C497EB5D8F81FB50003B512E0A34B2C7D -AB52>I<3901FC01FE00FF903807FFC091381E07F091383801F8000701707F0003EBE000 -2601FDC07F5C01FF147F91C7FCA25BA35BB3A8486CECFF80B5D8F83F13FEA32F2C7DAB36 ->I<3901FC03FC00FF90380FFF8091383C07E091387001F83A07FDE000FE00010180137F -01FFEC3F8091C7EA1FC04915E049140F17F0160717F8160317FCA3EE01FEABEE03FCA3EE -07F8A217F0160F6D15E0EE1FC06D143F17806EEB7E00D9FDC05B9039FCF003F891383C0F -E091381FFF80DA03FCC7FC91C9FCAE487EB512F8A32F3F7DAB36>112 -D<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC007E153C -01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 D<90383FE0183901FFFC3839 -07E01F78390F0003F8001E1301481300007C1478127800F81438A21518A27EA27E6C6C13 -006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0011F13F81300EC0FFC140300 -C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14F86CEB01F039F38003E039F1 -F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130EA4131EA3133E137EA213FE12 -011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C017F1318A26D133890381F80 -30ECC070903807E0E0903801FFC09038007F001E3E7EBC26>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fl ecrm1728 17.28 19 -/Fl 19 119 df<B912F018FF19E019F8C601FCC8EA3FFED93FF8ED07FF011F040113C072 -7F737E737E737E737E1907737EA2731380A21BC085A21BE0A91BC061A21B80611B004F5A -190F624F5A4F5AF1FFE04E5B4E90C7FCF00FFEF07FF894381FFFC091B748C8FCF0FFC019 -FC02F8C8EA07FF060013C0F13FE0F11FF8737E737E737E7313807313C0F27FE0A2F23FF0 -A2F21FF8A21BFCA21A0F1BFEA91BFC1A1FA3F23FF8A2F27FF0A2F2FFE0614F13C01B8007 -0F13004F5A4F5AF1FFF8013F040313E0D9FFFC033F5BBBC7FC19FC19E04EC8FC4F6278E1 -5F>66 D<DDFFF015C0040F01FF1401047F14E00303B600F81303030F9038E003FEDB3FFC -C7007F1307DBFFE0EC0FC002030180913803E00F4A48C83801F01F4A48ED0078DA3FF0EE -3C3F4A48161E4A48EE0F7F4949EE07FF4990CA7E495A4948834948835C013F197F494818 -3F495A1B1F485B1B0F4890CCFCA248481907A2485A1B03121F5BA2123F1B015BA2127F98 -C7FCA35B12FFB0127F7FA4123FF301C07FA2121FA27F000F1A031C806C7EA26C7E1B076C -6D1900636C7F1B0E6D6C181E6D6C181C011F193C6E606D7E6D6C606D6C4D5A6D6D4C5A6D -6D16076E6C4C5A6E6C4CC7FCDA0FFC163E6E6C16FC6E6C6CEC01F0020001F0EC07E0DB3F -FCEC3F8092280FFFE003FFC8FC030390B512FCDB007F14F0040F1480040001F8C9FC5266 -79E361>I<B912F018FF19E019F8C601FCC8EA7FFED93FF892380FFF80011F04017F9538 -007FF0F11FF8737EF103FE737E737F747E747E747E1A0F87747E1A0387747EA2741380A2 -F37FC0A21CE01B3FA21CF0A21B1F1CF8A31CFCA21B0FA41CFEAF1CFCA51B1F1CF8A4F33F -F0A21CE0A21B7F1CC01BFF1C80A2501300A2505A505AA2505A505A505A505A1AFF4F5B4F -90C7FCF107FCF11FF8F17FF0953801FFC0013F04075BD9FFFCDB7FFEC8FCBA12F819E096 -C9FC18F0576278E167>I<DA07FF1403023F01F05B49B512FC010702FF5B90260FFC0013 -C0D93FE090380FF01FD97F80EB03F801FEC86C5A4848157E4848ED1F7F48486F5A484881 -5B001F824981003F8290CAFC4883A2007E83A212FE84A384A27EA36D82A26C7EA26D93C7 -FC6C7E7F7F6C7E6D7E6C13E06C13FCECFFC06C14F86CECFF806C15F86DECFF80011F15E0 -6D15F8010315FE01006F7E021F81020181DA003F80030380DB003F7F04037FEE007FEF1F -FF71138017037113C083A2F07FE0183FA2181F00E018F0180FA41807A27EA47E19E0180F -7E19C07E6C171F19806D163F6D17006D5E6D16FE486C5E6D4B5AD8FC7F1503D91F80EC0F -F026F80FE04A5AD907FCEC7F8029F001FFE003FFC7FC6D6CB512FC48011F14F0020314C0 -489026001FFEC8FC3C6679E34B>83 D<EC3FE0903803FFFE010F6D7E90393FC03FE09039 -7C000FF801F0EB03FC48486D7E48486D7E48486E7E48C86C7E7F01F06E7E487E6D6E7EA3 -707EA36C5AEA03E0C9FCA6167FED7FFF020FB5FC91387FF807903801FF80903807FC00EB -1FF0EB7FC0495AD803FEC7FC485A120F5B485A485AA24848EE01C0A312FF5BA2160FA316 -1F6D141B007F153B16736D17806C6C9138E1FC03001FEC03C16C6C903A0780FE0700D807 -FE49486C5A2701FF807CEB7FFE6C6CB4486D5A011F01E06D5A010390C7EA07E03A4179BF -43>97 D<4AB47E020F13F8023F13FE9139FF007F80D903FCEB07E0D907F0EB01F0D91FE0 -EB007849488049488049C87E48485D4915FF00034B138048485CA2485AA2485AA2003F6F -130049EC007C94C7FC127FA35B12FFAD127F7FA4123F7FA2001FEE01C07F000F16036D16 -8012076C6C15076D160000015E6C6C151E6D6C5C6D6C5C6D6C5CD90FF8495AD903FCEB07 -C0903A00FF803F8091263FFFFEC7FC020F13F80201138032417BBF3C>99 -D<EC03FE91381FFFE091B512F8903901FE03FE903A07F0007F8049486D7ED93FC06D7E49 -C76C7E496E7E49140348488148481401000782491400000F8283485A1880123F49153FA2 -007F17C0A35BA212FF90B8FCA30180CAFCA9127F7FA3123FA27F121FEF01C06C7E17036C -6C1680A26C6C15070001EE0F006D150E6C6C151E6D6C5C6D6C5C6D6C5CD907F0EB03E0D9 -03FC495A902700FF803FC7FC91383FFFFC020F13F00201138032417BBF3C>101 -D<EB03C0EA07FFB5FCA41201EA007FA2133FB3AAEE7FE0923803FFFC030F13FFDB3F0013 -C00378EB1FE04B6D7EDAC1C06D7EDAC3808002C7C7120302CE81170114DC14D802F86E7E -5CA35CA35CB3B3496C4A7F496C4A7FB6D8F003B612C0A442647CE34B>104 -D<1378EA01FE487E487FA66C90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203 -C6FCA2137FB3B3AC497E487FB61280A4195F7BDE25>I<EB03C0EA07FFB5FCA41201EA00 -7FA2133FB3AB0403B512F8A40400148094387FFC0018E06095C7FC177E5F17F04C5A4C5A -4C5A4CC8FC163E5E5E4B5A4B5A4B5A4B5A151F4B7E4B7E15FF02C17F9138C3CFF8ECC787 -9138CF07FC9138FE03FEECFC0102F87F4A6C7F4A137F4A80707E161F83707E160783707E -160183707F177F84717E171F84717E84A284496CEDFF80496C4A13E0B600F090B6FCA440 -647CE347>107 D<EB0780EA0FFFB5FCA41203C6FCA2137FB3B3B3B3AD497E487FB612C0 -A41A647BE325>I<D903C0EB7FE0D807FF903803FFFCB5010F13FFDB3F0013C00378EB1F -E04B6D7E0001D9C1C06D7E27007FC3808002C7C71203D93FCE81170114DC14D802F86E7E -5CA35CA35CB3B3496C4A7F496C4A7FB6D8F003B612C0A4423F7CBE4B>110 -D<4AB47E020F13F0027F13FE4AC67ED903F8EB1FC0D907E0EB07E0D91FC0EB03F849486D -7E49C87E01FE157F49814848ED1F80000317C04848ED0FE0A24848ED07F0A2001F17F849 -1503003F17FCA3007F17FE491501A400FF17FFAC007F17FEA26D1503A3003F17FCA2001F -17F86D1507A2000F17F06D150F000717E06C6CED1FC0A26C6CED3F806C6CED7F00017F15 -FE6D6C495A6D6C495A6D6C495AD903F8EB1FC06DB4EBFF806D6CB448C7FC020F13F00201 -138038417BBF43>I<D903C0EB7FC0D807FF903807FFFCB5011F13FFDB7F0013C003F8EB -1FF0DAC3E0EB07F80001D9C7806D7E26007FCFC76C7E02DE6E7ED93FFC6F7E4A6F7E4A82 -181F4A82727E5C727EA2727EA3727EA41A8084AC4E1300A54E5AA2611807A24E5A6E5E18 -1F6E4B5A6E5E187F6E4B5A02DE4A90C7FC02CF4A5ADAC780495ADAC3C0EB0FF0DAC1F0EB -3FE0913AC07E01FF806FB448C8FC030F13F80300138093CAFCB3A3497E497EB612F0A441 -5B7CBE4B>I<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC0913801E03F913903 -C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB0600027090C7FC -A2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 -D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 -1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE -381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F -13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 -077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 -12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 -0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 -80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 -FC2A597ED734>I<D903C0150FD807FFED1FFFB50203B5FCA40001ED0007D8007F1501A2 -013F81B3B25FA35FA35F011F15066E140E5F130F6E4A7F01075D6D6C494813E0D901FE49 -48EBFFC0903A00FFC01F8091393FFFFE00020F13F8020001C0EC800042407CBE4B>I<B6 -6C0103B512C0A4000101F8C8EBFC006C01E0ED3FF0017FEE1FC0013F5F96C7FC131F181E -80010F161C8001075EA26E157801031670A26D6C5DA26E14016D5EA26F1303027F5D8102 -3F4AC8FCA26F5B021F140E81020F5CA26F133C02071438A26E6C5BA26F13F002015CA2ED -FF016E5C168192387F8380A216C7033F90C9FCA2ED1FEEA216FE6F5AA36F5AA26F5AA36F -5AA2423F7EBD47>I E -%EndDVIPSBitmapFont -end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 600dpi -TeXDict begin -%%BeginPaperSize: Letter -letter -%%EndPaperSize - end -%%EndSetup -%%Page: 1 1 -TeXDict begin 1 0 bop 1023 424 a Fl(Cluster)46 b(Snapshot)g(Blo)t(c)l -(k)g(Device)1620 764 y Fk(Daniel)32 b(Phillips)1510 1059 -y(3rd)g(Septem)m(b)s(er)h(2004)1766 1367 y Fj(Abstract)323 -1548 y Fi(F)-6 b(or)26 b(sev)n(eral)i(y)n(ears)f(no)n(w,)g(Lin)n(ux)f -(has)g(pro)n(vided)g(a)h(blo)r(c)n(k)g(lev)n(el)g(snapshot)f(facilit)n -(y)-6 b(,)28 b(\034rst)f(as)g(part)g(of)g(the)f(logical)208 -1640 y(v)n(olume)c(manager,)j(and)f(more)f(recen)n(tly)h(as)g(part)g -(of)h(the)e(Device)h(Mapp)r(er)g(virtual)g(blo)r(c)n(k)g(device)g -(subsystem.)33 b(This)208 1731 y(w)n(ork)i(builds)g(on)g(the)g -(original)i(concept)e(and)g(extends)f(it)h(to)h(op)r(erate)g(with)f -(shared)g(storage)i(devices)e(accessed)208 1822 y(sim)n(ultaneously)27 -b(b)n(y)g(man)n(y)f(cluster)i(no)r(des)g(o)n(v)n(er)g(a)g(storage)h -(net)n(w)n(ork.)41 b(In)27 b(the)h(pro)r(cess,)h(some)f(de\034ciencies) -g(of)h(the)208 1914 y(existing)i(design)g(w)n(ere)g(corrected:)46 -b(when)30 b(m)n(ultiple)g(snapshots)i(are)f(held)f(sim)n(ultaneously)-6 -b(,)32 b(m)n(ultiple)e(cop)n(ying)h(of)208 2005 y(snapshotted)24 -b(data)g(is)h(eliminated;)g(memory)d(fo)r(otprin)n(t)j(is)g(reduced)f -(and)f(made)h(indep)r(enden)n(t)f(of)i(v)n(olume)e(size;)j(the)208 -2096 y(requiremen)n(t)k(for)k(m)n(ultiple)d(separate)j(snapshot)e -(store)h(v)n(olumes)f(is)h(eliminated;)j(and)c(a)h(single)h(Device)e -(Mapp)r(er)208 2188 y(target)26 b(serv)n(es)g(for)g(b)r(oth)f(snapshot) -h(and)f(origin)i(devices.)0 2558 y Fh(1)131 b(Bac)l(kground)0 -2856 y Fg(1.1)112 b(Wh)m(y)38 b(Snapshots?)0 3109 y Ff(In)32 -b(a)g(t)n(ypical)g(en)n(terprise)f(computing)h(en)n(vironmen)n(t,)g(a)g -(\034le)h(system)e(is)i(relied)e(on)h(to)g(store,)h(organize,)e(k)n -(eep)h(trac)n(k)f(of)0 3208 y(and)e(mak)n(e)f(a)n(v)-5 -b(ailable)28 b(the)h(\034les)g(generated)f(b)n(y)g(the)i(users.)40 -b(The)29 b(en)n(terprise)f(computing)h(system)g(ma)n(y)f(ha)n(v)n(e)g -(h)n(undreds)0 3308 y(or)h(ev)n(en)h(thousands)f(of)i(users)e(and)h -(the)g(\034le)h(system)f(is)g(required)f(to)h(supp)r(ort)g(large)f(n)n -(um)n(b)r(ers)g(of)h(users)g(reading)e(from)0 3407 y(and)e(writing)g -(to)g(the)h(disk)f(storage)f(space)g(managed)g(b)n(y)h(the)h(\034le)g -(system.)36 b(In)26 b(to)r(da)n(y's)g(business)g(en)n(vironmen)n(t,)f -(the)i(\034le)0 3507 y(system)i(ma)n(y)g(b)r(e)g(needed)h(around)e(the) -i(clo)r(c)n(k.)41 b(In)29 b(man)n(y)g(systems,)g(the)h(\034le)f(system) -g(m)n(ust)h(b)r(e)f(con)n(tin)n(uously)f(a)n(v)-5 b(ailable)0 -3607 y(and)27 b(cannot)g(b)r(e)h(sh)n(utdo)n(wn)f(temp)r(orarily)g -(without)h(incurring)e(unacceptable)h(business)g(costs.)0 -3806 y(F)-7 b(ull-system)33 b(bac)n(kup)g(copies)g(can)g(b)r(e)h(used)f -(to)g(restore)f(\034les)h(in)h(the)g(ev)n(en)n(t)f(of)g(system)g -(failure,)i(acciden)n(tal)d(deletion,)0 3906 y(\034le)j(corruption,)g -(unin)n(tended)g(edits,)h(etc.)58 b(Regularly)33 b(making)g(bac)n(kups) -h(is)g(an)g(essen)n(tial)g(safet)n(y)g(measure)f(in)i(man)n(y)0 -4005 y(systems.)g(In)22 b(order)g(to)g(mak)n(e)g(a)g(bac)n(kup)g(of)h -(a)f(\034le)h(system)f(using)g(traditional)g(cop)n(ying)f(tec)n -(hniques,)j(it)f(is)f(necessary)f(that)0 4105 y(the)i(con)n(ten)n(ts)e -(of)i(the)g(\034le)f(system)g(b)r(e)h(stable.)35 b(If)23 -b(the)f(\034le)h(system)f(is)g(liv)n(e,)h(then)g(c)n(hanges)e(ma)n(y)h -(b)r(e)h(made)f(to)g(the)h(con)n(ten)n(ts,)0 4204 y(ev)n(en)30 -b(as)g(they)h(are)f(b)r(eing)g(copied.)46 b(Th)n(us,)31 -b(the)g(\034le)g(system)f(m)n(ust)h(b)r(e)g(\020o\033-line\021)37 -b(in)31 b(order)e(to)h(mak)n(e)g(an)g(e\033ectiv)n(e)h(bac)n(k)0 -4304 y(up.)44 b(In)30 b(a)g(t)n(ypical)f(en)n(terprise)g(en)n(vironmen) -n(t,)g(this)i(pro)r(cess)d(ma)n(y)h(b)r(e)i(p)r(erformed)e(at)h(nigh)n -(t)g(or)f(during)g(o\033)h(hours.)43 b(The)0 4404 y(\034le)25 -b(system)g(ma)n(y)g(b)r(e)g(una)n(v)-5 b(ailable)24 b(for)h(sev)n(eral) -f(hours)g(eac)n(h)g(nigh)n(t)h(or)g(once)f(a)h(w)n(eek)g(as)f(the)i -(con)n(ten)n(ts)e(of)h(the)h(\034le)f(system)0 4503 y(are)g(read)g(out) -g(and)h(copied)g(to)f(tap)r(e.)37 b(The)25 b(end)h(result)g(is)g(a)f -(ph)n(ysical)g(cop)n(y)g(of)h(the)g(original)e(data.)36 -b(As)26 b(en)n(terprises)e(gro)n(w)0 4603 y(ev)n(er)30 -b(larger,)g(and)h(the)g(stored)g(data)f(accum)n(ulates,)h(the)g(v)n -(olume)g(of)g(data)f(that)i(has)e(to)h(b)r(e)h(copied)e(increases)g -(and)h(the)0 4703 y(time)26 b(that)f(it)h(tak)n(es)e(to)h(mak)n(e)f(a)h -(bac)n(kup)f(of)h(the)h(\034le)f(system)g(using)g(traditional)f(tec)n -(hniques)h(is)g(no)g(longer)f(manageable.)0 4802 y(In)33 -b(some)f(en)n(vironmen)n(ts,)h(it)g(ma)n(y)f(tak)n(e)f(more)h(than)h(a) -f(da)n(y)g(to)h(mak)n(e)f(a)g(bac)n(kup)g(cop)n(y)-7 -b(.)51 b(It)33 b(ma)n(y)f(b)r(e)h(unacceptable)f(to)0 -4902 y(tak)n(e)27 b(a)g(\034lesystem)g(o\037ine)h(for)f(suc)n(h)g(a)g -(long)g(time.)0 5101 y(It)34 b(is)g(p)r(ossible)f(to)h(ac)n(hiev)n(e)e -(the)i(e\033ect)h(of)e(susp)r(ending)h(and)f(making)g(a)h(cop)n(y)f(of) -g(an)h(en)n(tire)f(\034lesystem,)i(but)g(without)0 5201 -y(in)n(terrupting)27 b(the)h(op)r(eration)f(of)h(the)g(\034lesystem.)37 -b(A)29 b('snapshot')e(is)g(a)h(virtually)f(instan)n(t)h(cop)n(y)e(of)i -(a)g(de\034ned)g(collection)0 5300 y(of)d(data)f(created)g(at)g(a)h -(particular)e(instan)n(t)i(in)g(time.)36 b(Bac)n(kups)23 -b(and)i(other)f(functions)h(can)f(b)r(e)h(p)r(erformed)g(in)g(a)f -(leisurely)0 5400 y(w)n(a)n(y)i(on)i(a)f(snapshot)g(image)f(without)i -(impacting)g(system)f(a)n(v)-5 b(ailabilit)n(y)e(.)p -eop end -%%Page: 2 2 -TeXDict begin 2 1 bop 0 83 a Ff(Bey)n(ond)38 b(online)g(bac)n(kup,)j -(snapshots)d(ha)n(v)n(e)g(v)-5 b(arious)37 b(uses.)71 -b(F)-7 b(or)38 b(example,)j(one)d(migh)n(t)h(create)f(a)g(snapshot)g(b) -r(efore)0 183 y(making)29 b(a)g(trial)g(install)g(of)g(some)g(new)g -(system)h(soft)n(w)n(are.)40 b(If)30 b(the)g(install)f(is)g -(unsuccessful,)h(the)g(trial)f(can)g(b)r(e)g(rev)n(erted)0 -282 y(b)n(y)e(cop)n(ying)g(the)h(snapshot)e(bac)n(k)h(to)g(the)h -(origin)f(device.)0 614 y Fg(1.2)112 b(Wh)m(y)38 b(Blo)s(c)m(k-Lev)m -(el)e(Snapshots?)0 867 y Ff(Snapshots)j(ma)n(y)g(b)r(e)h(implemen)n -(ted)g(at)f(the)h(blo)r(c)n(k)f(device)g(lev)n(el,)j(where)d(the)h -(disk)f(con)n(ten)n(ts)g(are)g(view)n(ed)g(as)g(mere)0 -967 y(blo)r(c)n(ks)31 b(of)h(data,)g(or)f(at)h(the)g(\034lesystem)g -(lev)n(el,)g(where)g(the)g(\034lesystem)g(con)n(ten)n(ts)f(are)g(view)n -(ed)g(as)g(ha)n(ving)g(a)g(particular)0 1066 y(organization.)61 -b(It)36 b(has)g(b)r(een)h(argued)e(that)i(the)f(latter)g(is)h(the)f(b)r -(est)h(c)n(hoice,)h(since)e(without)h(explicit)f(kno)n(wledge)f(of)0 -1166 y(\034lesystem)24 b(structure)g(it)h(is)f(imp)r(ossible)g(to)g -(kno)n(w)g(whic)n(h)g(blo)r(c)n(ks)g(are)f(free)h(and)g(whic)n(h)h(are) -e(not.)36 b(In)24 b(the)h(absence)f(of)g(that)0 1266 -y(kno)n(wledge,)k(a)h(blo)r(c)n(k)g(lev)n(el)g(snapshot)f(sc)n(heme)h -(will)g(sometimes)g(w)n(aste)f(time)i(preserving)e(snapshot)g(data)h -(that)g(is)h(just)0 1365 y(\034lesystem)d(free)h(space.)0 -1565 y(On)f(the)h(other)f(hand,)h(it)g(is)f(m)n(uc)n(h)h(simpler)f(to)g -(implemen)n(t)h(snapshots)f(at)g(the)h(blo)r(c)n(k)f(lev)n(el)h(than)f -(to)h(incorp)r(orate)e(them)0 1664 y(in)n(to)i(the)h(design)e(of)h(a)g -(p)r(ossibly)g(already-complex)e(\034lesystem.)38 b(F)-7 -b(urthermore,)28 b(a)f(blo)r(c)n(k)h(lev)n(el)g(snapshot)f(w)n(orks)g -(for)g(all)0 1764 y(\034lesystems,)f(not)h(just)g(one)f(particular)f -(\034lesystem.)36 b(And)27 b(\034nally)-7 b(,)26 b(w)n(e)g(already)f -(ha)n(v)n(e)h(a)g(natural)f(w)n(a)n(y)g(of)i(represen)n(ting)d(a)0 -1863 y(snapshot)j(to)g(the)h(system:)37 b(as)27 b(a)g(virtual)g(blo)r -(c)n(k)g(device.)0 2195 y Fg(1.3)112 b(Multiple)35 b(Snapshots)0 -2448 y Ff(Multiple)f(snapshots)e(of)h(the)g(same)g(\034lesystem)f(ma)n -(y)h(b)r(e)g(main)n(tained)g(sim)n(ultaneously)-7 b(,)33 -b(eac)n(h)f(created)h(at)f(a)h(di\033eren)n(t)0 2548 -y(p)r(oin)n(t)27 b(in)g(time.)37 b(In)27 b(the)g(past,)g(this)g(has)f -(b)r(een)h(implemen)n(ted)g(in)g(a)g(straigh)n(tforw)n(ard)c(w)n(a)n(y) -j(b)n(y)g(giving)g(eac)n(h)g(snapshot)g(its)0 2648 y(o)n(wn)21 -b(\034xed-size)f(storage)f(area.)34 b(This)21 b(approac)n(h,)f(though)h -(simple,)i(has)e(serious)f(dra)n(wbac)n(ks.)32 b(Eac)n(h)21 -b(time)h(a)f(blo)r(c)n(k)f(of)i(data)0 2747 y(is)29 b(c)n(hanged)e(on)i -(the)g(\034lesystem,)g(it)g(m)n(ust)g(b)r(e)g(written)g(to)f(the)h -(storage)e(for)h(eac)n(h)g(snapshot)g(to)h(whic)n(h)f(it)h(b)r(elongs.) -40 b(The)0 2847 y(cost)25 b(of)f(these)h(m)n(ultiple)h(writes)e -(increases)g(directly)h(with)g(the)g(n)n(um)n(b)r(er)g(of)g(snapshots)f -(held.)36 b(In)25 b(practice,)g(p)r(erformance)0 2946 -y(degrades)33 b(noticeably)g(with)i(more)e(than)h(one)g(or)f(t)n(w)n(o) -h(sim)n(ultaneous)f(snapshots.)55 b(Dep)r(ending)35 b(on)f(the)g -(lifetime)h(of)f(a)0 3046 y(snapshot)28 b(and)g(the)h(n)n(um)n(b)r(er)g -(of)f(c)n(hanges)g(made)g(to)g(the)i(original)d(\034le)h(system,)h(eac) -n(h)f(snapshot)g(store)f(ma)n(y)h(need)h(to)g(b)r(e)0 -3146 y(as)j(large)g(as)g(the)i(original)d(disk.)53 b(In)33 -b(the)g(absence)g(of)f(some)h(clev)n(er)f(sc)n(heme)g(to)h(allo)r(cate) -f(storage)f(on)i(demand,)h(these)0 3245 y(m)n(ultiple)27 -b(snapshot)f(stores)g(ma)n(y)g(b)r(e)h(largely)e(empt)n(y)-7 -b(.)37 b(In)27 b(an)n(y)f(ev)n(en)n(t,)h(it)g(is)f(probable)g(that)h(m) -n(ultiple)g(redundan)n(t)g(copies)0 3345 y(of)h(data)f(will)g(b)r(e)h -(stored.)0 3544 y(It)35 b(is)f(clear)f(that)h(to)g(a)n(v)n(oid)f(the)i -(ab)r(o)n(v)n(e)d(problems,)j(data)f(m)n(ust)g(b)r(e)h(shared)e(b)r(et) -n(w)n(een)h(m)n(ultiple)h(snapshots)e(whenev)n(er)0 3644 -y(p)r(ossible,)44 b(b)r(oth)e(to)f(reduce)f(cop)n(ying)g(time)i(and)f -(to)f(sa)n(v)n(e)g(space.)77 b(But)41 b(this)g(sharing)f(requiremen)n -(t)g(has)h(profound)0 3743 y(implications,)27 b(v)n(ersus)f(the)i -(simple)g(existing)f(design:)138 4026 y Fe(\001)42 b -Ff(W)-7 b(e)28 b(need)f(structures)g(to)g(k)n(eep)g(trac)n(k)g(of)g -(whic)n(h)h(data)f(is)g(shared)g(b)n(y)g(whic)n(h)h(snapshots)138 -4192 y Fe(\001)42 b Ff(W)-7 b(e)28 b(need)f(a)g(space)g(allo)r(cation)g -(sc)n(heme)g(for)g(the)h(snapshot)e(store)138 4358 y -Fe(\001)42 b Ff(Both)27 b(of)g(the)h(ab)r(o)n(v)n(e)f(need)g(to)h(b)r -(e)g(p)r(ersisten)n(t)f(and)g(durable)0 4640 y(I)e(elected)g(to)g(use)g -(a)g(\034lesystem-st)n(yle)f(bitmap)h(allo)r(cation)f(sc)n(heme)h(to)g -(manage)f(the)h(allo)r(cation)f(of)h(snapshot)f(store)h(data)0 -4740 y(and)i(metadata,)h(a)f(btree)g(to)h(k)n(eep)f(trac)n(k)f(of)i -(snapshot)f(data)g(mem)n(b)r(ership,)h(and)f(a)g(journal)g(to)h(mak)n -(e)f(those)g(structures)0 4839 y(durable.)36 b(The)26 -b(co)r(de)g(to)h(manage)e(a)h(snapshot)f(store)h(th)n(us)g(ends)g(up)h -(lo)r(oking)e(lik)n(e)h(a)g(simple)h(\034lesystem,)f(a)g(far)g(cry)f -(from)0 4939 y(the)j(existing)e(implemen)n(tation)i(of)f(snapshots,)f -(and)h(ev)n(en)g(further)g(from)g(the)h(simplicit)n(y)f(of)g(a)g(ph)n -(ysical)g(disk.)36 b(But)28 b(this)0 5039 y(is)f(the)h(price)g(that)f -(m)n(ust)h(b)r(e)g(paid)f(to)h(solv)n(e)e(the)i(pressing)f(problems)f -(of)i(the)g(existing)f(implemen)n(tation.)p eop end -%%Page: 3 3 -TeXDict begin 3 2 bop 0 83 a Fg(1.4)112 b(Cluster)37 -b(Snapshots)0 336 y Ff(In)25 b(man)n(y)f(en)n(vironmen)n(ts,)g(storage) -e(systems)i(are)g(clustered,)h(with)g(m)n(ultiple)g(serv)n(er-class)d -(systems)i(accessing)f(the)i(same)0 436 y(storage)32 -b(device.)55 b(The)34 b(clien)n(ts)f(of)h(the)g(storage)e(systems)h -(need)h(to)f(comm)n(unicate)g(amongst)g(themselv)n(es)g(in)h(order)e -(to)0 535 y(use)e(the)h(storage)e(system)h(in)g(a)h(co)r(ordinated)e(w) -n(a)n(y)g(to)h(a)n(v)n(oid)f(in)n(terlea)n(ving)g(their)h(c)n(hanges)f -(in)i(a)f(nonsensical)f(w)n(a)n(y)-7 b(.)45 b(All)0 635 -y(mem)n(b)r(ers)19 b(of)h(a)f(cluster)g(m)n(ust)h(receiv)n(e)e(a)i -(consisten)n(t)f(view)g(of)h(p)r(ossibly)f(m)n(ultiple)h(snapshots,)g -(ev)n(en)g(while)f(other)h(mem)n(b)r(ers)0 734 y(of)28 -b(the)f(cluster)h(ma)n(y)e(b)r(e)i(sim)n(ultaneously)f(writing)g(to)g -(the)h(same)f(snapshots.)0 934 y(Net)n(w)n(ork)f(comm)n(unication)h(is) -g(required)g(b)r(et)n(w)n(een)g(cluster)h(mem)n(b)r(ers)f(for)g(three)g -(distinct)h(purp)r(oses:)101 1216 y(1.)42 b(Disco)n(v)n(ering)25 -b(whic)n(h)j(ph)n(ysical)e(data)h(blo)r(c)n(ks)g(b)r(elong)g(to)h(a)f -(giv)n(en)g(snapshot)101 1382 y(2.)42 b(Sync)n(hronizing)26 -b(access)g(to)h(blo)r(c)n(k)g(lev)n(el)h(data)f(shared)f(b)r(et)n(w)n -(een)i(snapshot)e(and)i(origin)101 1548 y(3.)42 b(Sync)n(hronizing)26 -b(access)g(to)h(snapshot)g(metadata)0 1830 y(A)34 b(traditional)f -(approac)n(h)f(w)n(ould)h(rely)g(on)h(a)f(distributed)h(lo)r(c)n(k)f -(manager)f(for)i(sync)n(hronization,)f(augmen)n(ted)g(with)h(a)0 -1930 y(message)j(passing)h(proto)r(col)f(to)i(implemen)n(t)g(the)g -(data)f(exc)n(hange)g(required)f(for)h((1))h(ab)r(o)n(v)n(e.)69 -b(I)39 b(elected)g(instead)f(to)0 2030 y(adopt)27 b(a)g(pure)g -(message-passing)e(approac)n(h)g(that)j(com)n(bines)f(sync)n -(hronization)e(and)j(data)f(exc)n(hange)f(in)n(to)h(a)g(single)g(set)0 -2129 y(of)32 b(messages;)h(after)f(all,)h(a)f(distributed)g(lo)r(c)n(k) -g(managers)e(implemen)n(ts)j(its)f(lo)r(c)n(ks,)h(in)f(the)h(end,)g -(with)g(messages.)49 b(This)0 2229 y(eliminates)27 b(an)g(en)n(tire)g -(la)n(y)n(er)f(of)h(net)n(w)n(ork)f(sync)n(hronization)f(messages,)h -(and)h(results)g(in)g(a)g(compact,)g(e\036cien)n(t)g(proto)r(col)0 -2328 y(that)h(is)f(easy)g(to)g(v)n(erify)-7 b(.)0 2660 -y Fg(1.5)112 b(Durabilit)m(y)35 b(and)k(P)m(erformance)d(Goals)0 -2913 y Ff(As)20 b(general)f(purp)r(ose)g(blo)r(c)n(k)h(devices,)h -(cluster)f(snapshots)f(need)h(to)g(op)r(erate)f(just)i(lik)n(e)f(real)f -(blo)r(c)n(k)g(devices.)34 b(In)20 b(particular,)0 3013 -y(p)r(erformance)30 b(should)h(not)g(b)r(e)h(noticeably)e(degraded)g -(and)h(data)f(written)i(to)f(a)f(snapshot)h(virtual)f(device)h(should)g -(not)0 3113 y(b)r(e)f(at)g(an)n(y)f(greater)f(risk)h(than)h(data)f -(written)h(to)g(a)f(real)g(disk.)43 b(The)30 b(latter)f(is)h(a)f(c)n -(hallenging)g(requiremen)n(t)g(in)h(view)f(of)0 3212 -y(the)j(fact)g(that)h(a)e(real)g(disk)h(is)g(not)f(required)g(to)h -(main)n(tain)g(complex)f(data)h(structures)f(to)g(do)h(its)g(w)n(ork.) -49 b(The)32 b(cluster)0 3312 y(snapshot)24 b(on)g(the)h(other)f(hand,)h -(m)n(ust)g(main)n(tain)f(complex)h(data)f(structures)g(durably)-7 -b(,)24 b(in)h(other)f(w)n(ords,)g(without)h(b)r(eing)0 -3411 y(sub)5 b(ject)30 b(to)g(corruption)f(in)h(the)g(ev)n(en)n(t)g(of) -g(sudden)g(in)n(terruption)f(suc)n(h)h(as)f(a)h(p)r(o)n(w)n(er)f -(failure.)43 b(W)-7 b(e)31 b(w)n(ould)e(not)h(exp)r(ect)g(a)0 -3511 y(real)g(disk)g(to)h(b)r(ecome)f(corrupted)g(in)g(that)h(case,)g -(and)f(so)g(ha)n(v)n(e)g(the)h(same)f(high)g(exp)r(ectations)g(of)h(a)f -(virtual)g(disk.)46 b(An)0 3611 y(additional)27 b(c)n(hallenge)f(is)i -(to)f(ac)n(hiev)n(e)f(this)i(durabilit)n(y)f(without)h(degrading)e(p)r -(erformance.)0 3810 y(The)d(main)g(tactic)g(brough)n(t)f(to)h(b)r(ear)g -(on)f(this)i(problem)e(is)h(batc)n(hing)g(together)f(of)h(data)f -(structure)h(up)r(dates.)35 b(A)24 b(lo)r(calized)0 3910 -y(group)e(of)h(writes)g(to)g(virtual)f(v)n(olume)h(data)f(should)h -(result)g(in)g(a)g(batc)n(h)g(of)g(lo)r(calized)f(up)r(dates)i(to)f -(the)g(v)n(olume)g(metadata,)0 4009 y(whic)n(h)28 b(can)g(b)r(e)h -(transferred)e(to)h(disk)g(as)g(a)f(single)h(transaction.)38 -b(A)28 b(journal)g(is)g(used)g(to)h(mak)n(e)e(the)i(transaction)e -(atomic)0 4109 y(and)g(durable.)37 b(The)27 b(batc)n(hing)g(mak)n(es)g -(it)h(e\036cien)n(t.)0 4441 y Fg(1.6)112 b(Wh)m(y)38 -b(a)f(Clien)m(t-Serv)m(er)f(Arc)m(hitecture?)0 4694 y -Ff(Question:)42 b(Ho)n(w)30 b(do)r(es)g(one)h(distribute)f(a)h -(database)e(across)f(m)n(ultiple)j(cluster)g(no)r(des?)45 -b(Answ)n(er:)d(With)32 b(m)n(uc)n(h)e(blo)r(o)r(d,)0 -4793 y(sw)n(eat)c(and)g(tears.)35 b(This)27 b(I)f(did)h(not)f(wish)h -(to)f(attempt.)37 b(Instead)26 b(I)g(decided)h(that)g(the)f(snapshot)g -(store)f(database)h(w)n(ould)0 4893 y(b)r(e)34 b(cen)n(trally)f -(managed)g(b)n(y)g(a)h(serv)n(er)e(pro)r(cess)h(running)g(on)h(one)f -(of)h(the)g(cluster)g(no)r(des,)h(and)f(that)g(sync)n(hronization)0 -4993 y(and)27 b(information)g(distribution)g(w)n(ould)g(b)r(e)h(b)n(y)f -(w)n(a)n(y)f(of)h(net)n(w)n(ork)f(messages,)g(taking)h(the)h(form)f(of) -g(queries)f(and)i(replies.)0 5092 y(Since)c(the)g(query)f(proto)r(col)g -(is)h(v)n(ery)e(e\036cien)n(t,)j(the)f(clien)n(t)g(serv)n(er)e(arc)n -(hitecture)h(do)r(es)g(not)h(imp)r(ose)g(a)f(large)f(net)n(w)n(ork)h -(load)0 5192 y(and)k(is)h(exp)r(ected)g(to)f(scale)g(readily)f(to)i -(sev)n(eral)e(h)n(undred)h(clien)n(ts.)p eop end -%%Page: 4 4 -TeXDict begin 4 3 bop 0 83 a Ff(F)-7 b(or)27 b(v)n(ery)g(large)g -(clusters,)g(the)i(clien)n(t-serv)n(er)c(arc)n(hitecture)i(will)h(no)g -(doubt)g(ev)n(en)n(tually)f(b)r(ecome)h(a)g(b)r(ottlenec)n(k.)38 -b(F)-7 b(ortu-)0 183 y(nately)29 b(there)g(remains)g(plen)n(t)n(y)g(of) -g(time)h(to)f(solv)n(e)f(that)i(problem,)f(and)g(there)g(are)f(no)h -(examples)g(y)n(et)g(of)g(\034lesystems)g(of)0 282 y(the)f(t)n(yp)r(e)g -(that)g(could)f(b)r(ene\034t)h(from)f(a)h(snapshot)e(blo)r(c)n(k)h -(device,)h(running)f(on)g(suc)n(h)g(large)g(clusters.)0 -614 y Fg(1.7)112 b(T)-9 b(erminology)0 867 y Ff(Here)27 -b(w)n(e)g(review)g(some)g(terminology)f(in)n(tro)r(duced)h(b)n(y)h(the) -g(original)e(L)-9 b(VM)27 b(snapshot)g(implemen)n(tation:)0 -1066 y Fd(Origin)k(v)m(olume)0 1166 y Ff(One)k(of)g(t)n(w)n(o)f(blo)r -(c)n(k)g(devices)h(underlying)f(a)h(virtual)f(snapshot)h(device.)59 -b(This)35 b(v)n(olume)f(is)h(mapp)r(ed)g(one-to-one)f(to)g(a)0 -1266 y(snapshot)j(origin)g(virtual)h(device.)67 b(The)39 -b(virtual)e(device)h(could)f(b)r(e)i(remo)n(v)n(ed)d(and)i(the)h -(underlying)e(origin)g(v)n(olume)0 1365 y(accessed)26 -b(directly)-7 b(,)28 b(at)f(the)h(risk)f(of)g(losing)g(the)h(in)n -(tegrit)n(y)f(of)g(an)n(y)g(snapshots)f(sharing)h(data)g(with)h(the)g -(origin.)0 1565 y Fd(Snapshot)k(store)0 1664 y Ff(One)24 -b(of)g(t)n(w)n(o)g(blo)r(c)n(k)f(devices)h(underlying)g(a)g(virtual)f -(snapshot)h(device.)35 b(This)24 b(v)n(olume)g(con)n(tains)f(data)h(c)n -(h)n(unks)g(that)g(w)n(ere)0 1764 y(copied)31 b(from)f(the)i(origin)e -(in)h(order)f(to)h(preserv)n(e)e(the)j(in)n(tegrit)n(y)e(of)h(snapshot) -f(data,)h(or)g(w)n(ere)f(written)h(directly)g(to)g(the)0 -1863 y(snapshot)d(store)f(via)h(a)g(snapshot)f(virtual)h(device.)39 -b(It)29 b(also)e(con)n(tains)g(all)i(metadata)e(required)h(to)g(k)n -(eep)g(trac)n(k)f(of)h(whic)n(h)0 1963 y(snapshot)f(store)f(c)n(h)n -(unks)h(b)r(elong)g(to)h(whic)n(h)f(snapshots,)g(among)f(other)h -(things.)0 2162 y Fd(Cop)m(y-out)0 2262 y Ff(The)h(act)f(of)g -(preserving)f(a)h(c)n(h)n(unk)h(of)f(origin)f(data)i(b)n(y)f(cop)n -(ying)f(it)i(to)g(snapshot)e(store.)0 2461 y Fd(Ch)m(unk)0 -2561 y Ff(The)i(gran)n(ularit)n(y)d(of)i(snapshot)g(cop)n(y-outs,)f(a)h -(user-de\034nable)f(binary)h(m)n(ultiple)h(of)g(4K)f(blo)r(c)n(k)g -(size.)0 2760 y Fd(Exceptio)p Ff(n)0 2860 y(A)h(c)n(h)n(unk)f(of)h -(data)f(in)g(the)h(snapshot)f(store,)g(b)r(elonging)g(to)g(one)g(or)g -(more)g(snapshots)0 3192 y Fg(1.8)112 b(History)0 3445 -y Ff(T)-7 b(o)38 b(the)g(b)r(est)g(of)g(m)n(y)g(kno)n(wledge,)h(the)f -(concept)g(of)g(a)f(cop)n(y-on-write)f(blo)r(c)n(k)h(device)h(lev)n(el) -f(snapshot)g(\034rst)h(arose)e(in)0 3544 y(discussions)c(b)r(et)n(w)n -(een)g(Heinz)i(Mauelshagen)d(and)i(Mic)n(hael)f(Marxmeier,)h(in)g(1999) -e(at)h(the)i(Cologne)d(Lin)n(ux)i(K)n(ongress)0 3644 -y(conference.)65 b(Heinz)37 b(created)f(a)h(functional)g(implemen)n -(tation)g(as)g(part)f(of)i(his)f(Lin)n(ux)g(L)-9 b(VM)37 -b(pro)5 b(ject)36 b(shortly)g(after.)0 3743 y(In)g(2002,)h(Jo)r(e)e -(Thorn)n(b)r(er)g(re\034ned)h(these)h(ideas)e(and)h(re-implemen)n(ted)g -(the)g(snapshot)g(target)f(as)h(a)f(Device)h(Mapp)r(er)0 -3843 y(virtual)24 b(device.)36 b(I)25 b(b)r(egan)g(design)f(w)n(ork)g -(for)g(a)h(cluster)g(snapshot)f(in)h(Septem)n(b)r(er,)h(2003.)34 -b(Once)24 b(a)h(design)f(w)n(as)g(a)n(v)-5 b(ailable,)0 -3943 y(a)37 b(protot)n(yp)r(e)f(k)n(ernel)h(clien)n(t)g(for)g(Lin)n(ux) -g(2.4)g(w)n(as)f(co)r(ded)h(in)h(\034v)n(e)f(da)n(ys)f(b)n(y)h(P)n -(atric)n(k)f(Caul\034eld)i(in)f(Decem)n(b)r(er,)j(2003.)0 -4042 y(Observing)31 b(that)h(a)g(simple)g(net)n(w)n(ork)f(ec)n(ho)g(is) -h(a)g(go)r(o)r(d)g(sim)n(ulation)f(of)i(a)e(cluster)h(snapshot)g(serv)n -(er)e(for)i(an)f(imp)r(ortan)n(t)0 4142 y(class)26 b(of)h(access)e -(patterns,)i(P)n(atric)n(k)f(w)n(as)g(able)g(to)h(obtain)g(early)e(b)r -(enc)n(hmark)h(n)n(um)n(b)r(ers)h(at)g(that)g(time.)37 -b(Encouraged)25 b(b)n(y)0 4242 y(the)30 b(excellen)n(t)f(p)r -(erformance,)g(I)h(b)r(egan)f(implemen)n(tation)h(w)n(ork)e(on)i(a)f -(user)g(space)g(snapshot)g(serv)n(er)f(early)g(in)i(the)g(new)0 -4341 y(y)n(ear,)c(bringing)h(it)h(to)f(a)g(testable)h(state)f(b)n(y)g -(June.)0 4540 y(In)38 b(July)-7 b(,)40 b(the)f(protot)n(yp)r(e)e(k)n -(ernel)g(clien)n(t)h(w)n(as)f(dev)n(elop)r(ed)g(in)n(to)h(a)f -(functional)h(clien)n(t)g(for)f(the)i(snapshot)e(origin,)i(and)0 -4640 y(b)r(enc)n(hmarks)32 b(of)h(a)f(functional)h(virtual)g(origin)e -(device)i(holding)g(a)f(snapshot)g(w)n(ere)g(obtained.)53 -b(These)32 b(con\034rmed)h(the)0 4740 y(predictions)26 -b(set)h(out)g(in)h(the)f(design)g(do)r(cumen)n(t,)g(nearly)f(a)g(y)n -(ear)g(earlier.)35 b(By)27 b(Monda)n(y)f(August)h(16th,)f(snapshot)h -(blo)r(c)n(k)0 4839 y(device)32 b(supp)r(ort)f(had)h(b)r(een)g(added)g -(to)g(the)g(k)n(ernel)f(clien)n(t,)i(completing)f(the)g(basic)f(blo)r -(c)n(k)h(device)f(functionalit)n(y)-7 b(.)50 b(Ben)0 -4939 y(Marzinski)27 b(p)r(orted)g(the)i(2.4)e(k)n(ernel)f(clien)n(t)i -(to)g(Lin)n(ux)g(2.6)f(later)g(that)h(w)n(eek,)f(in)h(three)g(da)n(ys.) -36 b(This)28 b(brings)f(us)h(to)g(to)r(da)n(y)-7 b(,)0 -5039 y(with)29 b(a)g(pre-alpha)e(cluster)i(snapshot)f(protot)n(yp)r(e)g -(ready)g(to)h(b)r(e)g(released)f(on)g(the)i(\020release)d(early)-7 -b(,)28 b(release)f(often\021)36 b(plan.)0 5138 y(Sev)n(eral)d(more)h -(mon)n(ths)h(of)g(hard)f(w)n(ork)g(is)g(required)g(to)h(complete)g(the) -g(fault)g(tolerance)f(and)h(cluster)f(infrastructure)0 -5238 y(in)n(tegration,)26 b(whic)n(h)i(will)f(bring)g(this)h(cluster)f -(snapshot)g(blo)r(c)n(k)g(device)h(to)f(a)g(usable)g(state.)p -eop end -%%Page: 5 5 -TeXDict begin 5 4 bop 0 83 a Fh(2)131 b(Ho)l(w)44 b(a)f(Blo)t(c)l(k)j -(Device)e(Snapshot)g(W)-11 b(orks)0 364 y Ff(Blo)r(c)n(k)31 -b(lev)n(el)g(snapshots)f(in)i(Lin)n(ux)f(are)g(implemen)n(ted)h(using)f -(a)g(cop)n(y-on-write)f(strategy)-7 b(.)47 b(When)32 -b(a)f(snapshot)g(is)g(\034rst)0 464 y(created,)c(it)g(is)g(exactly)g -(the)h(same)e(as)h(the)h(origin)e(v)n(olume.)36 b(Afterw)n(ards,)26 -b(an)n(y)h(attempted)h(write)f(to)g(the)h(origin)e(v)n(olume)0 -564 y(w)n(ould)f(also)f(b)r(e)i(a)f(write)g(to)g(the)h(snapshot,)f -(whic)n(h)g(w)n(ould)g(destro)n(y)f(the)h(in)n(tegrit)n(y)g(of)g(the)h -(snapshot,)f(and)g(isn't)g(allo)n(w)n(ed.)0 663 y(Before)31 -b(the)h(write)g(is)g(allo)n(w)n(ed)e(to)i(pro)r(ceed,)g(the)h(data)e -(that)h(w)n(ould)g(b)r(e)g(o)n(v)n(erwritten)e(is)i(copied)g(to)f(a)h -(snapshot)f(store.)0 763 y(Snapshot)25 b(metadata)f(is)h(also)f -(recorded)f(on)i(the)h(snapshot)e(store,)h(to)g(k)n(eep)f(trac)n(k)g -(of)h(the)g(parts)g(of)g(the)g(origin)f(that)h(ha)n(v)n(e)0 -863 y(b)r(een)e(preserv)n(ed)f(in)h(the)h(snapshot)e(store.)34 -b(This)23 b(metadata)g(is)g(consulted)g(on)f(eac)n(h)h(write)f(access)g -(to)h(determine)g(whether)0 962 y(or)28 b(not)g(origin)f(data)h(has)g -(already)f(b)r(een)i(preserv)n(ed)d(in)j(the)g(snapshot)e(store,)h(and) -g(th)n(us)h(is)f(no)g(longer)f(shared)h(with)h(the)0 -1062 y(origin.)0 1261 y(A)19 b(snapshot)g(is)g(presen)n(ted)f(to)h(the) -h(system)f(as)f(a)h(virtual)f(blo)r(c)n(k)h(device.)34 -b(An)n(y)19 b(read)f(or)g(write)h(to)g(this)g(device)g(is)g(in)n -(tercepted)0 1361 y(and)29 b(the)h(snapshot)e(store)g(metadata)h(is)g -(consulted)g(to)g(determine)g(whether)g(the)h(target)e(of)h(the)h(IO)f -(lies)g(on)g(the)g(origin)0 1460 y((i.e.,)d(hasn't)g(b)r(een)g -(written)f(to)h(y)n(et)f(b)n(y)g(an)n(y)g(\034lesystem)g(moun)n(ted)g -(on)g(the)h(origin)e(device))i(or)e(is)i(in)g(the)f(snapshot)g(store.) -0 1560 y(By)33 b(preserving)f(o)n(v)n(erwritten)g(data,)i(then)g -(remapping)f(eac)n(h)g(access)f(to)h(the)h(virtual)f(snapshot)g(device) -g(to)g(either)h(the)0 1660 y(origin)26 b(or)f(snapshot)h(store)g(as)g -(appropriate,)f(a)h(view)h(of)g(a)f(snapshot)g(can)g(b)r(e)h -(reconstructed)f(on)g(demand.)37 b(A)27 b(snapshot)0 -1759 y(view)g(can)h(b)r(e)g(accessed)e(through)h(its)h(virtual)f -(snapshot)g(device)g(sim)n(ultaneously)g(with)h(the)g(origin)f(v)n -(olume,)g(and)g(these)0 1859 y(t)n(w)n(o)h(virtual)h(devices)f(will)i -(b)r(eha)n(v)n(e)e(as)g(if)i(they)f(w)n(ere)f(completely)h(indep)r -(enden)n(t.)42 b(The)29 b(virtual)g(snapshot)f(device)h(tak)n(es)0 -1958 y(care)d(of)i(the)g(tric)n(ky)f(sync)n(hronization)e(required)i -(to)g(mak)n(e)g(this)h(w)n(ork.)0 2158 y(W)-7 b(riting)31 -b(to)g(a)f(snapshot)g(through)g(its)h(virtual)f(device)h(is)g(allo)n(w) -n(ed.)45 b(Data)31 b(to)f(b)r(e)i(o)n(v)n(erwritten)d(in)i(the)g -(snapshot)f(store)0 2257 y(do)r(es)f(not)h(need)g(to)f(b)r(e)h(preserv) -n(ed,)f(b)r(ecause)g(it)h(is)g(not)f(shared.)43 b(Ho)n(w)n(ev)n(er,)28 -b(if)i(a)f(write)h(to)f(the)h(snapshot)f(device)h(w)n(ould)0 -2357 y(o)n(v)n(erwrite)c(origin)i(data,)g(space)g(is)g(allo)r(cated)g -(for)g(the)h(write)f(in)h(the)g(snapshot)e(store)h(instead)g(and)g(the) -h(snapshot)f(store)0 2457 y(metadata)f(is)g(up)r(dated)h(to)g -(re\035ect)f(that.)0 2656 y(Multiple)d(snapshots)e(can)h(b)r(e)h(held)g -(against)e(an)h(origin)f(v)n(olume)h(sim)n(ultaneously)-7 -b(.)34 b(An)n(y)23 b(n)n(um)n(b)r(er)g(of)h(these)f(sim)n(ultaneous)0 -2756 y(snapshots)k(and)g(the)h(origin)e(can)h(b)r(e)h(accessed)f(as)g -(writable)g(blo)r(c)n(k)g(devices,)g(also)f(sim)n(ultaneously)-7 -b(.)0 3126 y Fh(3)131 b(Cluster)45 b(Sync)l(hronization)0 -3407 y Ff(What)23 b(m)n(ust)g(b)r(e)g(done)f(to)h(turn)g(a)f(single-no) -r(de)g(snapshot)f(device)i(in)n(to)f(a)h(cluster)f(snapshot)g(device?) -35 b(Surprisingly)21 b(little.)0 3507 y(A)31 b(relativ)n(ely)e(thin)j -(la)n(y)n(er)d(of)h(net)n(w)n(ork)g(sync)n(hronization)e(has)i(to)h(b)r -(e)g(added,)g(and)g(some)f(fail-o)n(v)n(er)e(ho)r(oks.)46 -b(Blo)r(c)n(k)30 b(data)0 3607 y(itself)f(is)f(written)h(to)f(or)f -(read)h(from)g(the)g(shared)g(blo)r(c)n(k)g(device)g(directly)g(b)n(y)g -(the)g(cluster)g(snapshot)g(clien)n(t)g(in)h(the)g(same)0 -3706 y(w)n(a)n(y)i(as)h(if)g(the)h(blo)r(c)n(k)f(device)g(w)n(ere)f(lo) -r(cal.)51 b(The)32 b(main)g(thing)h(that)f(is)g(new)h(for)e(a)h -(cluster)g(snapshot)g(clien)n(t)g(is)g(that)h(it)0 3806 -y(m)n(ust)f(decide)f(for)g(eac)n(h)g(IO)g(request)g(if)h(global)f(sync) -n(hronization)e(is)j(required,)f(and)h(query)e(the)i(snapshot)f(serv)n -(er)f(o)n(v)n(er)0 3906 y(the)e(net)n(w)n(ork)e(if)i(it)g(is.)0 -4105 y(The)33 b(essen)n(tial)f(questions)g(that)h(a)f(snapshot)g(clien) -n(t)g(m)n(ust)h(ask)f(are:)46 b(is)33 b(a)f(giv)n(en)g(logical)f(data)i -(c)n(h)n(unk)f(shared)f(b)n(y)i(an)n(y)0 4204 y(snapshot,)h(or)e(is)h -(it)g(unique?)53 b(Is)33 b(it)g(stored)g(on)f(the)i(origin)d(v)n -(olume,)j(or)e(in)h(the)h(snapshot)e(store,)h(and)g(if)h(so,)f(at)g -(what)0 4304 y(ph)n(ysical)28 b(address?)40 b(F)-7 b(or)29 -b(a)f(write,)i(either)f(to)g(the)g(origin)f(or)g(a)h(snapshot,)f(b)n(y) -h(the)h(time)f(the)h(serv)n(er)d(replies)h(to)h(a)g(query)0 -4404 y(ab)r(out)f(a)f(giv)n(en)g(logical)g(c)n(h)n(unk)g(the)h(c)n(h)n -(unk)g(is)g(alw)n(a)n(ys)e(unique,)i(b)r(ecause)f(the)h(serv)n(er)e -(will)j(mak)n(e)e(it)h(so)f(if)h(necessary)-7 b(.)36 -b(T)-7 b(o)0 4503 y(mak)n(e)34 b(a)g(c)n(h)n(unk)h(unique,)h(the)g -(serv)n(er)c(allo)r(cates)i(a)g(new)h(c)n(h)n(unk)f(in)h(snapshot)f -(store,)i(copies)e(the)h(shared)f(data)g(there,)0 4603 -y(and)28 b(up)r(dates)f(the)i(snapshot)e(metadata.)36 -b(Ha)n(ving)27 b(ensured)g(uniqueness,)h(the)g(serv)n(er)e(replies)h -(to)h(the)g(query)-7 b(,)27 b(the)h(clien)n(t)0 4703 -y(asso)r(ciates)i(the)j(reply)f(with)g(a)g(w)n(aiting)g(write)g -(request,)h(and)f(\034nally)g(the)g(device-lev)n(el)f(write)h(pro)r -(ceeds.)50 b(In)32 b(the)h(case)0 4802 y(of)27 b(a)g(snapshot)g(store)f -(write,)i(the)f(reply)g(includes)h(the)g(ph)n(ysical)e(address)g(of)i -(the)f(snapshot)g(store)f(c)n(h)n(unk,)h(whic)n(h)h(is)f(not)0 -4902 y(needed)h(in)g(the)f(origin)g(case)g(b)r(ecause)g(the)h(logical)e -(and)h(ph)n(ysical)g(addresses)f(are)g(the)i(same.)0 -5101 y(With)j(this)f(simple)g(sc)n(heme,)g(w)n(e)f(see)h(that)g(it)g -(is)g(nev)n(er)f(p)r(ossible)h(for)f(a)h(clien)n(t)f(no)r(de)h(to)g(o)n -(v)n(erwrite)e(origin)h(data)g(that)h(is)0 5201 y(shared)d(b)n(y)g(a)g -(snapshot,)g(or)f(a)i(shared)e(c)n(h)n(unk)h(in)h(the)g(snapshot)f -(store.)0 5400 y(Reading)i(from)h(the)g(origin)f(is)h(ev)n(en)f -(simpler:)41 b(no)30 b(sync)n(hronization)e(at)h(all)h(is)g(required)f -(on)g(the)h(part)g(of)g(the)g(snapshot)p eop end -%%Page: 6 6 -TeXDict begin 6 5 bop 0 83 a Ff(device.)53 b(This)33 -b(is)g(b)r(ecause)g(there)g(are)f(no)g(metadata)h(up)r(dates,)h(and)f -(an)n(y)g(p)r(ossible)f(races)g(w)n(ould)h(also)f(b)r(e)h(races)f(on)g -(a)0 183 y(ph)n(ysical)27 b(disk.)39 b(It)28 b(is)g(the)h(job)f(of)g(a) -g(higher)g(lev)n(el)f(application)h((i.e.,)h(\034lesystem)f(or)f -(database))g(to)h(prev)n(en)n(t)g(suc)n(h)f(races,)0 -282 y(not)h(the)g(snapshot)e(device.)0 482 y(Reading)c(from)h(a)f -(snapshot,)h(in)g(con)n(trast,)g(requires)e(the)j(most)e(in)n(tricate)g -(sync)n(hronization)f(of)i(all.)35 b(The)23 b(problem)f(is,)i(if)f(a)0 -581 y(snapshot)g(read)g(references)f(an)i(origin)e(c)n(h)n(unk,)i -(there)g(could)f(b)r(e)h(a)g(sim)n(ultaneous)f(origin)f(write)i(in)g -(progress)d(to)j(the)g(same)0 681 y(c)n(h)n(unk.)36 b(If)28 -b(nothing)e(is)h(done)g(to)g(prev)n(en)n(t)f(it,)h(the)h(snapshot)e -(data)g(could)h(b)r(e)g(o)n(v)n(erwritten)e(while)j(it)f(is)g(in)g(the) -g(pro)r(cess)f(of)0 780 y(b)r(eing)g(read.)35 b(The)26 -b(snapshot)f(device)g(is)h(supp)r(osed)f(to)h(act)f(lik)n(e)g(a)h(ph)n -(ysical)e(disk,)i(but)h(it)f(is)f(v)n(ery)g(unlik)n(e)g(a)h(ph)n -(ysical)e(disk)0 880 y(for)k(data)g(to)g(sp)r(on)n(taneously)f(c)n -(hange)g(while)i(b)r(eing)f(read.)39 b(There)28 b(is)g(no)g(help)h -(from)f(cluster)g(\034lesystem)g(or)g(application)0 980 -y(la)n(y)n(ers)h(either,)i(b)r(ecause)f(they)h(do)f(not)h(kno)n(w)f(ab) -r(out)h(the)g(p)r(ossible)f(in)n(teraction)g(of)g(origin)g(and)g -(snapshot)g(and)h(cannot)0 1079 y(b)r(e)d(exp)r(ected)g(to.)0 -1279 y(The)39 b(solution)f(to)h(this)g(race)e(is)i(to)g(pro)n(vide)e -(some)h(lo)r(c)n(king)g(b)r(et)n(w)n(een)h(origin)e(writes)i(and)f -(snapshot)g(reads.)70 b(When)0 1378 y(a)38 b(snapshot)f(read)g -(references)f(an)i(origin)f(c)n(h)n(unk,)j(the)e(serv)n(er)e(lo)r(c)n -(ks)h(the)i(c)n(h)n(unk)e(in)n(ternally)g(b)r(efore)h(replying.)67 -b(The)0 1478 y(snapshot)29 b(clien)n(t)g(then)h(initiates)f(the)h -(actual)f(read)f(and,)i(on)f(completion,)g(sends)g(a)g(message)f(to)h -(the)h(serv)n(er)d(to)j(release)0 1577 y(the)i(read)e(lo)r(c)n(k.)48 -b(Snapshot)31 b(reads)f(from)h(the)g(origin)g(th)n(us)g(use)g(a)g -(three)g(message)f(proto)r(col,)h(as)g(opp)r(osed)g(to)g(origin)f(or)0 -1677 y(snapshot)f(writes,)i(whic)n(h)f(use)g(t)n(w)n(o.)44 -b(This)30 b(also)f(means)g(that)i(there)f(are)f(t)n(w)n(o)g(p)r -(ossible)h(forms)f(of)i(reply)e(to)h(a)g(snapshot)0 1777 -y(read)22 b(query)-7 b(,)23 b(dep)r(ending)h(on)e(whether)h(the)g -(target)f(c)n(h)n(unk)h(resides)f(on)g(the)i(origin)d(or)i(in)g(the)g -(snapshot)f(store.)34 b(The)23 b(latter)0 1876 y(\035a)n(v)n(or)i(m)n -(ust)j(include)g(the)g(address)e(of)i(a)f(snapshot)g(store)f(c)n(h)n -(unk,)h(but)i(do)r(es)e(not)g(require)g(an)n(y)g(\034nal)g(release)f -(message.)0 2208 y Fg(3.1)112 b(Clien)m(t-side)36 b(Query)h(Cac)m(he)0 -2461 y Ff(An)c(in)n(teresting)e(fact)h(ab)r(out)g(the)h(shared)e(vs)h -(unique)g(state)g(of)g(an)n(y)g(giv)n(en)f(origin)g(c)n(h)n(unk)h(is)g -(that)g(it)h(is)f(a)g(latc)n(h:)46 b(once)0 2561 y(a)29 -b(c)n(h)n(unk)g(b)r(ecomes)g(unique,)h(it)g(will)g(sta)n(y)f(unique)g -(un)n(til)h(a)f(new)h(snapshot)e(is)i(created,)f(at)g(whic)n(h)h(p)r -(oin)n(t)f(all)h(c)n(h)n(unks)e(on)0 2660 y(the)g(origin)f(are)g -(shared)g(with)h(the)g(new)g(snapshot.)37 b(This)28 b(means)g(that)g -(an)f(origin)g(clien)n(t)h(can)g(cac)n(he)f(the)h(one-bit)f(result)0 -2760 y(of)34 b(an)n(y)f(write)g(query)-7 b(,)35 b(since)e(it)h(can)g(b) -r(e)g(relied)f(on)h(to)f(sta)n(y)g(unc)n(hanged,)i(except)e(when)h(a)g -(new)f(snapshot)g(is)h(created.)0 2860 y(The)27 b(serv)n(er)e -(broadcasts)g(a)i(message)f(to)h(all)f(origin)g(clien)n(ts)h(in)h(that) -f(case,)f(so)h(that)g(they)g(ma)n(y)g(clear)f(their)h(cac)n(hes.)35 -b(An)n(y)0 2959 y(uncac)n(hed)27 b(or)g(zero)f(bit)i(is)g(either)f -(shared)g(or)f('don't)i(kno)n(w',)f(the)h(distinction)g(b)r(eing)f -(immaterial.)0 3159 y(Snapshot)f(clien)n(ts)g(ma)n(y)g(also)g(cac)n(he) -f(query)h(results,)g(the)h(cac)n(hed)f(v)-5 b(alue)26 -b(b)r(eing)h(a)f(snapshot)g(store)f(address)h(rather)f(than)0 -3258 y(a)35 b(bit.)59 b(This)35 b(cac)n(he)g(nev)n(er)f(needs)g(to)h(b) -r(e)h(cleared)e(explicitly)-7 b(,)37 b(although)d(it)i(migh)n(t)f(b)r -(e)g(partially)f(or)g(fully)i(cleared)e(in)0 3358 y(resp)r(onse)26 -b(to)i(memory)f(pressure.)0 3732 y Fh(4)131 b(The)44 -b(A)l(CID)h(T)-11 b(est)0 4013 y Ff(The)32 b(snapshot)e(store)h -(metadata)f(is)i(a)f(simple)g(database,)h(and)f(as)g(suc)n(h,)h(should) -f(satisfy)g(the)h(A)n(CID)g(test:)45 b(atomicit)n(y)-7 -b(,)0 4113 y(consistency)g(,)32 b(isolation)f(and)h(durabilit)n(y)-7 -b(.)50 b(W)-7 b(e)32 b(consider)f(eac)n(h)g(of)h(these)g(requiremen)n -(ts)f(brie\035y)g(here,)i(to)f(see)f(ho)n(w)h(the)0 4213 -y(new)c(design)f(stac)n(ks)f(up.)0 4528 y Fd(A)m(tomicit)m(y)0 -4781 y Ff(A)34 b(write)g(query)f(that)i(c)n(hanges)d(the)i(state)g(of)g -(the)g(on)g(disk)g(metadata)f(is)h(alw)n(a)n(ys)e(handled)i(en)n -(tirely)f(within)i(a)f(single)0 4881 y(journal)27 b(transaction,)f -(whic)n(h)h(commits)h(the)g(c)n(hange)e(to)i(disk)f(atomically)-7 -b(.)p eop end -%%Page: 7 7 -TeXDict begin 7 6 bop 0 83 a Fd(Consistency)0 336 y Ff(Just)36 -b(as)f(with)i(a)f(ph)n(ysical)f(disk,)j(it)e(is)g(not)g(the)h(job)f(of) -g(the)g(snapshot)f(device)h(to)g(mak)n(e)f(an)n(y)h(guaran)n(tee)e(ab)r -(out)i(the)0 436 y(in)n(ternal)31 b(consistency)f(of)h(data)g(on)g(the) -h(device,)g(only)e(that)i(what)f(w)n(as)f(written)i(is)f(what)g(will)h -(b)r(e)f(read)g(bac)n(k,)g(for)g(an)n(y)0 535 y(and)24 -b(all)g(sim)n(ultaneously)g(accessed)f(snapshots)g(and)i(the)f(origin)g -(device.)35 b(In)25 b(other)f(w)n(ords,)f(its)i(only)f(resp)r -(onsibilit)n(y)g(here)0 635 y(is)j(to)h(k)n(eep)f(the)h(metadata)f -(straigh)n(t.)0 950 y Fd(Isolation)0 1203 y Ff(The)j(protot)n(yp)r(e)g -(implemen)n(tation)g(ac)n(hiev)n(es)f(transaction)g(isolation)g(b)n(y)h -(the)g(simple)h(exp)r(edien)n(t)f(of)h(a)f(single-threaded)0 -1303 y(serv)n(er)25 b(that)i(handles)f(incoming)h(queries)e(one)i(at)f -(a)h(time.)37 b(This)27 b(will)g(ev)n(en)n(tually)e(sho)n(w)h(up)h(as)f -(a)h(b)r(ottlenec)n(k)f(and)h(more)0 1402 y(elab)r(orate)f(sync)n -(hronization)g(will)i(b)r(e)g(needed.)0 1718 y Fd(Durabilit)m(y)0 -1971 y Ff(Thanks)35 b(to)g(the)h(journal,)h(the)f(en)n(tire)f(state)h -(of)f(the)h(metadata)f(serv)n(er)f((with)i(on)g(exception,)h(see)e(b)r -(elo)n(w))h(is)f(alw)n(a)n(ys)0 2070 y(completely)24 -b(recorded)f(on)h(disk)g(at)g(the)h(time)g(an)n(y)e(write)h(is)g(ac)n -(kno)n(wledged.)34 b(Th)n(us,)25 b(if)f(the)h(metadata)f(serv)n(er)e -(should)i(fail)0 2170 y(a)j(new)h(one)f(can)g(b)r(e)h(started,)f(read)g -(the)h(metadata)f(ro)r(ot)f(and)i(con)n(tin)n(ue)f(as)g(if)h(nothing)f -(had)h(happ)r(ened.)0 2369 y(The)h(one)g(exception)f(to)h(this)g(is)g -(that)h(lo)r(c)n(king)e(state)g(of)h(snapshot)f(read)h(requests)f -(against)f(origin)h(writes)h(is)g(k)n(ept)g(only)0 2469 -y(in)f(memory)e(on)h(the)h(serv)n(er.)34 b(While)28 b(it)g(is)f(enough) -g(to)g(simply)g(require)f(all)h(outstanding)g(reads)f(on)h(clien)n(ts)g -(to)g(complete)0 2568 y(b)r(efore)35 b(a)f(newly)h(started)g(metadata)f -(serv)n(er)f(can)i(resume)g(pro)r(cessing)e(requests,)j(there)f(could)g -(b)r(e)g(cases)f(where)h(this)0 2668 y(w)n(ould)25 b(cause)g(an)h -(unnecessary)e(dela)n(y)h(of)h(sev)n(eral)e(seconds)g(on)i(serv)n(er)e -(restart)g(where)i(there)f(is)h(a)f(hea)n(vy)g(bac)n(klog)f(of)h(IO.)0 -2768 y(Since)h(it)h(is)f(easy)-7 b(,)25 b(clien)n(ts)h(will)h(b)r(e)f -(ask)n(ed)f(to)h(upload)g(an)n(y)f(outstanding)h(lo)r(c)n(k)n(ed)f -(snapshot)g(reads)g(to)h(the)h(new)f(metadata)0 2867 -y(serv)n(er)f(b)r(efore)h(the)h(serv)n(er)e(resumes)h(pro)r(cessing)f -(requests.)35 b(This)27 b(should)f(only)h(tak)n(e)e(a)i(few)g(tens)f -(of)h(milliseconds.)36 b(The)0 2967 y(total)c(latency)g(of)h(starting)f -(a)g(new)g(metadata)g(serv)n(er)f(then)i(should)f(b)r(e)h(measured)f -(in)h(tens)g(of)f(milliseconds)g((though)0 3066 y(detecting)c(that)g -(a)f(serv)n(er)e(has)i(failed)h(could)f(easily)g(tak)n(e)g(m)n(uc)n(h)g -(longer).)0 3441 y Fh(5)131 b(Serv)l(er)45 b(Implemen)l(tation)f -(Details)0 3739 y Fg(5.1)112 b(Exception)36 b(BT)-9 b(ree)37 -b(F)-9 b(ormat)0 3991 y Ff(Exceptions)28 b(for)f(all)g(snapshots)g(are) -g(stored)g(in)h(a)f(single)g(btree)h(indexed)f(b)n(y)h(logical)e(c)n(h) -n(unk)h(address.)37 b(F)-7 b(or)27 b(eac)n(h)g(c)n(h)n(unk,)0 -4091 y(a)g(list)h(of)f(exceptions)g(is)g(stored.)36 b(Eac)n(h)27 -b(exception)g(consists)f(of)i(a)f(snapshot)f(address)g(and)h(a)g -(bitmap)h(sp)r(ecifying)f(whic)n(h)0 4191 y(snapshots)g(share)f(that)i -(exception.)0 4390 y(The)h(btree)g(is)g(mean)n(t)g(to)f(b)r(e)i(op)r -(erated)e(on)h(directly)g(b)n(y)f(the)i(snapshot)e(serv)n(er,)f(as)i -(opp)r(osed)f(to)h(b)r(eing)g(translated)f(in)n(to)0 -4490 y(some)j(more)g(e\036cien)n(t)g(cac)n(he)g(format.)48 -b(T)-7 b(o)32 b(supp)r(ort)f(alignmen)n(t-restricted)f(arc)n -(hitectures,)h(all)g(\034elds)h(in)g(btree)f(blo)r(c)n(ks)0 -4589 y(are)c(aligned)f(according)g(to)i(their)f(size.)1288 -4559 y Fc(1)0 4788 y Ff(An)22 b(attempt)f(has)g(b)r(een)g(made)g(to)g -(k)n(eep)g(the)g(btree)g(compact)f(b)n(y)h(designing)f(the)i(no)r(de)f -(formats)f(carefully)-7 b(,)22 b(without)f(going)0 4888 -y(to)k(extremes)f(suc)n(h)g(as)g(using)g(a)h(serial)e(compressed)h -(enco)r(ding)g(whic)n(h)g(is)h(unpac)n(k)n(ed)f(in)n(to)g(a)h(memory)e -(structure)i(in)f(order)0 4988 y(to)f(b)r(e)h(accessed.)35 -b(In)23 b(other)g(w)n(ords,)g(di\036cult)i(tradeo\033s)d(ha)n(v)n(e)h -(b)r(een)h(made)f(here)g(b)r(et)n(w)n(een)g(compactness,)h(simplicit)n -(y)f(and)0 5087 y(e\036ciency)-7 b(.)p 0 5157 1548 4 -v 92 5210 a Fb(1)127 5234 y Fa(This)30 b(p)r(osturing)i(ma)n(y)e(pro)n -(v)n(e)i(unnecessary)h(if)d(the)i(compiler's)e(abilit)n(y)g(to)h -(generate)j(alignmen)n(t-indep)r(enden)n(t)e(co)r(de)g(for)f(alignmen)n -(t-)0 5312 y(restricted)26 b(arc)n(hitectures)h(pro)n(v)n(es)e -(reliable.)p eop end -%%Page: 8 8 -TeXDict begin 8 7 bop 0 83 a Fd(Leaf)33 b(no)s(des)0 -336 y Ff(Leaf)i(blo)r(c)n(k)g(format)g(is)g(optimized)h(for)f(rapid)f -(lo)r(okup)h(and)h(e\036cien)n(t)f(insertion.)60 b(A)n(t)35 -b(the)h(b)r(ottom)g(of)f(eac)n(h)g(leaf)g(is)g(a)0 436 -y(header)25 b(and)i(a)e(directory)g(map)i(that)f(gro)n(ws)e(up)j(to)n -(w)n(ards)d(a)i(table)g(of)h(exceptions,)f(whic)n(h)g(gro)n(ws)e(do)n -(wn.)36 b(Eac)n(h)26 b(en)n(try)g(in)0 535 y(the)g(directory)f(map)h -(giv)n(es)e(the)i(logical)f(c)n(h)n(unk)g(address)g(relativ)n(e)g(to)g -(a)h(base)f(address)g(stored)g(in)h(the)g(header,)f(and)h(has)f(a)0 -635 y(p)r(oin)n(ter)i(to)h(one)f(of)g(the)h(exceptions)f(in)h(the)g -(table)f(at)h(the)g(top)f(of)h(the)g(blo)r(c)n(k.)36 -b(The)28 b(en)n(tries)f(are)f(stored)h(in)h(sorted)e(order)0 -734 y(according)g(to)h(logical)f(c)n(h)n(unk)i(address)e(and)h(the)h(p) -r(oin)n(ters)f(increase)f(monotonically)-7 b(.)0 934 -y(Using)28 b(relativ)n(e)f(addresses)f(allo)n(ws)h(the)h(map)g(en)n -(tries)g(to)g(b)r(e)g(more)g(compact.)38 b(In)28 b(the)g(curren)n(t)g -(protot)n(yp)r(e)f(map)h(en)n(tries)0 1033 y(consist)i(of)h(t)n(w)n(o)e -(32)h(bit)h(n)n(um)n(b)r(ers,)g(ho)n(w)n(ev)n(er)e(t)n(w)n(o)g(16)h -(bit)h(n)n(um)n(b)r(ers)f(migh)n(t)h(w)n(ork)e(just)i(as)f(w)n(ell)h -(and)f(sa)n(v)n(e)f(more)h(space,)0 1133 y(although)e(a)f(16)h(bit)h -(relativ)n(e)e(blo)r(c)n(k)h(n)n(um)n(b)r(er)g(migh)n(t)g(b)r(e)h(so)e -(small)h(as)g(to)g(cause)g(a)f(noticeable)h(increase)f(in)i(the)f(n)n -(um)n(b)r(er)0 1233 y(of)i(leaf)f(blo)r(c)n(ks)g(if)h(exceptions.are)e -(distributed)i(sparsely)-7 b(.)41 b(With)31 b(32)e(bit)h(map)f(n)n(um)n -(b)r(ers,)h(a)f(single)g(exception)g(requires)0 1332 -y(24)f(b)n(ytes;)h(with)h(16)e(bit)i(map)e(n)n(um)n(b)r(ers)h(that)g(w) -n(ould)g(fall)g(to)f(20)h(b)n(ytes,)g(a)f(16\045)g(sa)n(vings.)40 -b(The)29 b(\034nal)g(determination)f(of)0 1432 y(whic)n(h)f(is)h(b)r -(est)g(should)f(probably)g(b)r(e)h(determined)f(exp)r(erimen)n(tally)-7 -b(.)0 1631 y(The)32 b(di\033erence)g(b)r(et)n(w)n(een)g(eac)n(h)f(t)n -(w)n(o)h(p)r(oin)n(ters)f(in)i(the)f(map)g(giv)n(es)f(the)i(n)n(um)n(b) -r(er)e(of)h(exceptions)g(for)g(the)g(c)n(h)n(unk.)50 -b(The)0 1731 y(last)28 b(en)n(try)g(in)h(the)g(map)f(is)h(a)f(sen)n -(tinel)h(and)f(p)r(oin)n(ts)g(at)h(the)g(top)f(of)h(the)g(blo)r(c)n(k)f -((this)h(could)f(b)r(e)h(designed)f(out)h(to)g(sa)n(v)n(e)d(a)0 -1830 y(few)h(b)n(ytes).)37 b(Eac)n(h)27 b(en)n(try)f(in)h(the)h -(exception)e(table)h(has)g(the)g(64)f(bit)h(sector)f(address)g(of)h(an) -g(exception)f(in)i(the)f(snapshot)0 1930 y(store)g(and)g(a)g(bitmap)h -(to)f(indicate)h(whic)n(h)g(snapshots)e(share)g(the)i(exception.)0 -2129 y(The)k(basic)f(op)r(erations)g(to)h(lo)r(cate)f(and)h(determine)g -(sharing)f(of)h(exceptions)f(are)g(e\036cien)n(t.)50 -b(A)33 b(binary)e(searc)n(h)f(is)i(used)0 2229 y(to)i(lo)r(cate)f(the)h -(target)e(c)n(h)n(unk)i(address)e(in)i(the)g(map,)h(if)f(it)g(is)g -(presen)n(t.)54 b(This)34 b(yields)f(a)g(list)h(of)g(exceptions)f(on)g -(whic)n(h)0 2328 y(e\036cien)n(t)28 b(bit)n(wise)f(op)r(erations)g(can) -g(b)r(e)h(p)r(erformed)g(to)f(determine)h(sharing.)36 -b(F)-7 b(rom)28 b(the)g(p)r(oin)n(t)g(of)f(view)h(of)g(the)g(origin,)e -(a)0 2428 y(logical)i(c)n(h)n(unk)g(is)i(shared)e(unless)h(all)f(activ) -n(e)h(snapshots)f(ha)n(v)n(e)g(exceptions)g(for)h(that)g(c)n(h)n(unk.) -42 b(F)-7 b(rom)28 b(the)i(p)r(oin)n(t)f(of)g(view)0 -2528 y(of)g(a)g(snapshot,)h(a)f(logical)f(c)n(h)n(unk)h(is)g(shared)g -(if)h(it)g(has)e(no)i(exception)f((i.e.,)h(is)g(shared)e(with)i(the)g -(origin))e(or)h(it)h(has)f(the)0 2627 y(same)e(snapshot)g(store)f -(address)h(as)f(another)h(snapshot.)0 2827 y(A)36 b(sligh)n(t)f(dra)n -(wbac)n(k)f(of)i(this)g(leaf)g(format)f(is)g(that)h(insertion)g -(requires)e(memory)h(mo)n(v)n(es)f(in)i(order)f(to)g(main)n(tain)h(the) -0 2926 y(en)n(tries)26 b(in)g(sorted)g(order,)f(and)i(the)f(memory)g -(mo)n(v)n(es)f(get)h(longer)f(as)h(the)h(leaf)f(blo)r(c)n(k)g(\034lls)g -(up.)37 b(F)-7 b(or)26 b(relativ)n(ely)f(small)h(leaf)0 -3026 y(blo)r(c)n(ks,)j(i.e.)41 b(4K,)28 b(it)i(is)e(probably)g(not)h(a) -g(problem.)40 b(This)29 b(will)h(b)r(e)f(determined)g(exp)r(erimen)n -(tally)-7 b(.)41 b(Other,)29 b(equiv)-5 b(alen)n(tly)0 -3125 y(e\036cien)n(t)28 b(leaf)f(formats)g(are)f(certainly)h(p)r -(ossible,)g(though)h(p)r(erhaps)f(they)g(will)h(not)g(b)r(e)g(as)f -(simple.)0 3325 y(A)g(more)g(serious)f(dra)n(wbac)n(k)f(of)i(this)g -(leaf)g(format)g(is)g(that)g(as)g(the)g(n)n(um)n(b)r(er)g(of)g -(snapshots)f(increases,)g(up)r(date)h(o)n(v)n(erhead)0 -3424 y(of)f(the)h(btree)f(increases)f(more)g(or)h(less)f(linearly)-7 -b(,)26 b(alb)r(eit)h(with)g(a)e(gen)n(tle)h(slop)r(e.)36 -b(Nonetheless,)27 b(it)f(migh)n(t)h(pro)n(v)n(e)d(desirable)0 -3524 y(to)j(adopt)h(a)f(v)-5 b(arian)n(t)26 b(leaf)i(format)f(at)g -(some)g(p)r(oin)n(t)h(capable)f(of)g(enco)r(ding)g(runs)g(of)h(adjacen) -n(t)f(exceptions)g(e\036cien)n(tly)-7 b(.)0 3839 y Fd(Index)32 -b(no)s(des)0 4092 y Ff(An)e(index)g(no)r(de)f(con)n(tains)g(a)g(table)g -(of)h(en)n(tries)e(eac)n(h)h(of)h(whic)n(h)f(consists)g(of)g(a)g(64)g -(bit)h(logical)e(c)n(h)n(unk)h(address)f(k)n(ey)h(and)0 -4192 y(a)h(64)g(bit)h(sector)f(address)f(of)i(a)f(lo)n(w)n(er)f(lev)n -(el)h(index)h(no)r(de)g(or,)f(at)h(the)g(lo)n(w)n(est)e(index)i(lev)n -(el,)g(a)f(leaf.)47 b(The)30 b(en)n(tries)g(are)g(in)0 -4291 y(sorted)j(order)g(b)n(y)h(logical)f(c)n(h)n(unk)h(address.)56 -b(T)-7 b(w)n(o)33 b(successiv)n(e)g(k)n(eys)g(b)r(ound)i(the)g(range)d -(of)j(en)n(tries)e(con)n(tained)h(b)n(y)g(the)0 4391 -y(lo)n(w)n(er)26 b(lev)n(el)h(no)r(de.)0 4590 y(T)-7 -b(o)38 b(lo)r(cate)f(the)i(leaf)f(blo)r(c)n(k)f(in)h(whic)n(h)g -(exceptions,)i(if)f(an)n(y)-7 b(,)40 b(are)d(stored)g(for)h(a)f(giv)n -(en)g(logical)g(address,)j(w)n(e)d(descend)0 4690 y(recursiv)n(ely)22 -b(from)h(the)h(ro)r(ot,)g(doing)f(a)g(binary)g(searc)n(h)f(on)h(the)h -(address)f(k)n(ey)g(in)g(eac)n(h)g(blo)r(c)n(k)g(and)h(descending)f -(recursiv)n(ely)0 4790 y(in)n(to)k(the)h(no)r(de)g(referenced)f(b)n(y)g -(the)h(sector)e(address)h(lying)g(b)r(et)n(w)n(een)g(the)h(t)n(w)n(o)f -(k)n(eys)g(that)g(b)r(ound)h(the)g(target)f(k)n(ey)-7 -b(.)0 4989 y(W)g(e)22 b(searc)n(h)e(all)i(the)g(w)n(a)n(y)e(to)i(a)f -(leaf)h(no)r(de)f(ev)n(en)h(if)g(w)n(e)f(are)g(examining)g(a)g(region)g -(of)g(the)h(address)f(space)g(that)h(is)f(completely)0 -5088 y(empt)n(y)-7 b(.)47 b(F)-7 b(or)30 b(write)g(requests)g(this)h -(is)g(not)g(ine\036cien)n(t)g(b)r(ecause)f(w)n(e)h(will)g(immediately)g -(add)f(an)h(exception)f(to)h(the)g(leaf)0 5188 y(no)r(de)23 -b(w)n(e)f(found)h(if)g(one)f(is)h(not)g(presen)n(t.)34 -b(F)-7 b(or)22 b(read)g(requests)g(it's)g(a)h(little)g(more)f(w)n(ork)f -(than)i(necessary)e(but)i(w)n(e)f(probably)0 5288 y(do)27 -b(not)g(care)f(since)h(this)h(only)f(a\033ects)g(snapshot)f(reads,)h -(and)g(only)g(b)n(y)f(a)h(small)g(amoun)n(t)g((origin)f(reads)g(do)h -(not)h(in)n(v)n(olv)n(e)0 5387 y(the)g(serv)n(er).)p -eop end -%%Page: 9 9 -TeXDict begin 9 8 bop 0 83 a Fg(5.2)112 b(Journal)0 336 -y Ff(An)n(y)23 b(altered)f(metadata)h(blo)r(c)n(k,)g(i.e,)h(btree)f -(leaf)g(and)g(index)g(no)r(des,)h(allo)r(cation)e(bitmaps,)i(etc,)g -(are)e(written)h(to)g(a)g(journal)0 436 y(b)r(efore)j(b)r(eing)g -(written)g(to)g(their)g(\034nal)g(destinations.)36 b(This)26 -b(guaran)n(tees)e(that)i(the)h(metadata)e(can)h(b)r(e)g(restored)f -(reliably)0 535 y(to)i(the)h(state)g(of)f(the)h(most)g(recen)n(tly)e -(committed)i(exception)g(or)e(other)h(metadata)g(c)n(hange.)0 -734 y(The)e(size)g(and)g(lo)r(cation)f(of)h(the)g(journal)g(are)f -(determined)h(at)g(the)g(time)h(the)f(snapshot)f(store)g(is)h(created)f -(and)h(cannot)g(b)r(e)0 834 y(c)n(hanged.)0 1033 y(Eac)n(h)33 -b(journal)g(transaction)f(consists)g(of)i(an)f(arbitrary)e(n)n(um)n(b)r -(er)i(of)g(data)g(blo)r(c)n(ks)g(follo)n(w)n(ed)f(b)n(y)h(a)g(journal)g -(tag)g(blo)r(c)n(k.)0 1133 y(The)27 b(tag)g(blo)r(c)n(k)f(carries)f(a)i -(magic)f(n)n(um)n(b)r(er)h(allo)n(wing)f(it)h(to)g(b)r(e)h(iden)n -(ti\034ed)f(as)g(suc)n(h)f(for)h(the)g(purp)r(ose)g(of)g(journal)f -(repla)n(y)-7 b(,)0 1233 y(and)28 b(a)g(sequence)f(n)n(um)n(b)r(er)h -(used)g(to)g(lo)r(cate)g(the)h(starting)e(p)r(oin)n(t)h(for)g(journal)f -(repla)n(y)-7 b(.)38 b(An)n(y)28 b(data)g(blo)r(c)n(k)f(written)i(to)f -(the)0 1332 y(journal)g(that)h(happ)r(ens)g(to)f(ha)n(v)n(e)g(the)h -(same)f(n)n(um)n(b)r(er)g(at)h(the)g(same)f(lo)r(cation)g(m)n(ust)g(b)r -(e)i(escap)r(ed)e(b)n(y)g(writing)g(a)h(zero)e(to)0 1432 -y(that)e(lo)r(cation)g(in)g(a)g(cop)n(y)f(of)h(the)g(data.)36 -b(The)25 b(tag)g(blo)r(c)n(k)f(carries)f(a)i(list)g(of)g(snapshot)g -(store)f(sector)g(addresses)f(whic)n(h)i(are)0 1531 y(the)e(\034nal)f -(destinations)f(of)i(the)f(data)g(blo)r(c)n(ks.)34 b(The)22 -b(lo)n(w)g(bit)h(of)f(the)g(address)f(carries)g(a)g(bit)i(\035ag)f -(indicating)g(that)g(the)h(data)0 1631 y(blo)r(c)n(k)j(w)n(as)f(escap)r -(ed)h(and)g(the)g(magic)g(n)n(um)n(b)r(er)g(needs)g(to)g(b)r(e)h -(restored)d(b)r(efore)i(the)h(data)f(blo)r(c)n(k)f(is)h(\034nally)g -(written.)37 b(The)0 1731 y(tag)26 b(blo)r(c)n(k)g(carries)f(other)h -(miscellaneous)g(information)g(suc)n(h)g(as)g(partial)g(usage)f(status) -i(of)f(a)h(c)n(h)n(unk)f(recen)n(tly)g(allo)r(cated)0 -1830 y(for)h(metadata.)0 2162 y Fg(5.3)112 b(Allo)s(cation)35 -b(Bitmaps)0 2415 y Ff(F)-7 b(ree)36 b(space)f(in)i(the)f(snapshot)g -(store)f(is)h(managed)f(via)h(bitmaps)g(with)h(a)e(resolution)g(of)h -(one)g(bit)h(p)r(er)f(c)n(h)n(unk.)62 b(Eac)n(h)0 2515 -y(bitmap)33 b(is)g(one)f(4K)g(blo)r(c)n(k)g(in)h(size)g(and)f(maps)h -(2**15)d(c)n(h)n(unks.)52 b(The)32 b(bitmap)h(blo)r(c)n(ks)f(are)g -(indexed)h(via)f(a)h(radix)e(tree)0 2614 y(ro)r(oted)c(in)i(the)f -(header.)38 b(Eac)n(h)28 b(radix)f(tree)h(no)r(de)g(con)n(tains)f(512)g -(8-b)n(yte)g(sector)g(addresses.)37 b(As)28 b(a)g(sligh)n(t)f -(simpli\034cation)0 2714 y(this)i(tree)g(is)g(alw)n(a)n(ys)e(3)i(lev)n -(els)f(deep,)h(giving)f(2^27)g(*)g(2^15)g(=)g(4)h(trillion)g(c)n(h)n -(unks,)f(or)h(16)f(p)r(etab)n(ytes)g(v)n(olume)h(size)f(limit)0 -2814 y(with)d(a)g(minimal)g(4K)f(c)n(h)n(unk)g(size.)35 -b(It)26 b(is)e(alw)n(a)n(ys)f(fully)i(p)r(opulated,)h(i.e.,)f(the)h -(tree)e(is)h(created)f(at)g(the)h(time)h(the)f(snapshot)0 -2913 y(store)i(is)g(created)g(and)g(c)n(hanged)f(only)h(if)i(the)e -(snapshot)g(store)g(is)g(expanded.)37 b(The)27 b(second)g(lo)n(w)n(est) -f(lev)n(el)h(of)h(the)g(bitmap)0 3013 y(index)h(tree)f(is)h(loaded)f -(in)n(to)g(memory)g(when)h(the)g(v)n(olume)g(is)f(activ)-5 -b(ated,)29 b(this)g(will)g(b)r(e)g(ab)r(out)g(512)e(KB)i(p)r(er)f -(terab)n(yte)g(of)0 3113 y(snapshot)f(store.)0 3312 y(Bitmaps)35 -b(are)f(cac)n(hed)h(in)h(bu\033ers)f(and)g(accessed)f(via)h(getblk.)60 -b(A)35 b(p)r(oin)n(ter)g(is)h(k)n(ept)f(to)g(the)h(most)f(recen)n(tly)f -(accessed)0 3411 y(bitmap,)c(i.e.,)g(it)g(is)f(not)h(released)e(un)n -(til)i(a)f(di\033eren)n(t)g(bitmap)h(is)f(accessed,)g(whic)n(h)g -(eliminates)g(the)h(ma)5 b(jorit)n(y)28 b(of)h(getblk)0 -3511 y(lo)r(okups)i(assuming)g(reasonably)f(go)r(o)r(d)h(lo)r(calit)n -(y)g(of)h(allo)r(cation.)49 b(Lik)n(ewise,)32 b(a)f(p)r(oin)n(ter)h(is) -f(k)n(ept)h(to)g(the)g(most)g(recen)n(tly)0 3611 y(accessed)h(index)h -(blo)r(c)n(k.)55 b(Since)34 b(nearly)f(all)h(accesses)e(to)i(bitmaps)g -(are)f(asso)r(ciated)g(with)h(c)n(hanging)e(the)j(bitmap,)h(the)0 -3710 y(bitmaps)f(are)e(k)n(ept)i(near)f(the)h(journal)f(rather)f(than)i -(b)r(eing)g(distributed)g(throughout)f(the)h(snapshot)e(store.)58 -b(This)34 b(is)0 3810 y(purely)27 b(a)f(matter)h(of)g(allo)r(cation)e -(p)r(olicy)i(since)g(the)g(actual)g(lo)r(cations)f(of)g(bitmaps)h(are)f -(determined)h(b)n(y)g(the)g(radix)f(tree.)0 4009 y(Since)20 -b(metadata)e(is)i(allo)r(cated)f(in)g(blo)r(c)n(ks)g(but)h(allo)r -(cation)e(gran)n(ularit)n(y)f(is)j(c)n(h)n(unks,)g(some)f(c)n(h)n(unks) -g(allo)r(cated)f(to)i(metadata)0 4109 y(ma)n(y)32 b(b)r(e)h(only)f -(partially)f(full.)52 b(T)-7 b(o)32 b(a)n(v)n(oid)f(leak)-5 -b(age)31 b(of)i(this)f(unallo)r(cated)g(space)g(on)g(unexp)r(ected)h -(restart,)f(an)n(y)g(partial)0 4208 y(allo)r(cations)d(are)g(recorded)g -(in)i(the)f(journal)g(tag)f(blo)r(c)n(k.)45 b(As)30 b(a)g(side)g -(e\033ect,)i(this)e(means)g(that)h(a)f(few)g(metadata)g(blo)r(c)n(ks)0 -4308 y(can)d(b)r(e)h(allo)r(cated)f(b)r(efore)g(a)g(bitmap)h(needs)g -(to)f(b)r(e)h(mo)r(di\034ed,)g(sa)n(ving)e(some)h(journal)g(bandwidth.) -0 4640 y Fg(5.4)112 b(Allo)s(cation)35 b(P)m(olicy)0 -4893 y Ff(The)c(protot)n(yp)r(e)e(implemen)n(tation)h(uses)h(a)f -(simple,)h(wraparound)d(allo)r(cation)i(sc)n(heme)g(for)g(b)r(oth)g -(snapshot)g(store)g(data)0 4993 y(and)k(metadata.)55 -b(If)35 b(snapshots)e(are)g(held)h(o)n(v)n(er)e(extended)j(p)r(erio)r -(ds,)g(the)f(snapshot)g(store)f(will)h(b)r(ecome)g(fragmen)n(ted,)0 -5092 y(reducing)26 b(the)g(e\036ciency)h(of)f(IO)g(transfers.)35 -b(While)27 b(this)g(ma)n(y)e(not)i(b)r(e)g(a)f(serious)f(problem)g(for) -h(bac)n(kup)g(applications,)g(it)0 5192 y(certainly)i(will)h(b)r(e)g(a) -f(problem)g(for)g(a)g(user)g(that)h(wishes)g(to)f(use)h(a)f(snapshot)g -(in)h(place)f(of)g(the)h(origin)f(device.)40 b(T)-7 b(o)28 -b(cater)0 5291 y(to)34 b(this)g(t)n(yp)r(e)g(of)f(usage,)i(a)e(more)g -(sophisticated)g(allo)r(cator)f(will)i(b)r(e)g(needed.)56 -b(T)-7 b(o)33 b(facilitate)h(e\036cien)n(t)g(data)f(transfer,)0 -5391 y(exception)26 b(store)g(c)n(h)n(unks)g(that)i(are)d(logically)h -(close)g(together)g(should)g(b)r(e)i(stored)e(ph)n(ysically)f(close)i -(together.)35 b(Because)p eop end -%%Page: 10 10 -TeXDict begin 10 9 bop 0 83 a Ff(of)34 b(c)n(h)n(unk)g(sharing,)h(this) -g(can)f(not)h(b)r(e)g(done)f(p)r(erfectly)g(in)h(general;)i(rather,)e -(an)f(impro)n(v)n(ed)f(a)n(v)n(erage)f(case)h(should)i(b)r(e)0 -183 y(sough)n(t.)53 b(A)n(t)33 b(a)g(higher)g(lev)n(el,)h(man)n(y)f -(\034lesystems)f(implicitly)i(rely)f(on)g(details)g(of)g(la)n(y)n(out)f -(linearit)n(y)-7 b(,)34 b(for)e(p)r(erformance)0 282 -y(reasons.)40 b(Muc)n(h)29 b(e\033ort)g(is)h(required)e(b)n(y)h(the)g -(allo)r(cator)f(to)h(a)n(v)n(oid)f(violating)g(suc)n(h)h(assumptions)g -(to)r(o)f(sev)n(erely)-7 b(.)41 b(This)29 b(is)0 382 -y(w)n(ork)d(for)h(the)h(future.)0 714 y Fg(5.5)112 b(Lo)s(c)m(king)0 -967 y Ff(Sync)n(hronization)28 b(via)h(lo)r(c)n(king)g(is)g(only)h -(required)e(b)r(et)n(w)n(een)i(snapshot)f(reads)f(and)i(origin)e -(writes.)43 b(This)29 b(lo)r(c)n(king)g(tak)n(es)0 1066 -y(place)c(en)n(tirely)g(within)h(the)g(serv)n(er)e(so)g(no)i(cluster)f -(lo)r(c)n(k)g(manager)e(is)j(in)n(v)n(olv)n(ed.)34 b((In)26 -b(fact)g(the)g(serv)n(er)d(is)j(a)f(lo)r(c)n(k)g(manager)0 -1166 y(for)h(the)h(limited)h(case)d(of)i(snapshot)f(reads.))36 -b(The)26 b(lo)r(c)n(ks)g(are)g(simple,)h(hashed)f(lo)r(c)n(ks.)36 -b(The)26 b(cost)h(of)f(this)h(lo)r(c)n(king)f(will)h(b)r(e)0 -1266 y(one)22 b(hash)h(lo)r(okup)f(p)r(er)h(snapshot)f(read)g(or)g -(origin)g(write)g(of)h(a)g(shared)f(c)n(h)n(unk,)h(plus)g(the)g(unlo)r -(c)n(k)g(messages.)33 b(This)23 b(lo)r(c)n(king)0 1365 -y(is)28 b(only)f(required)g(when)h(snapshot)f(and)g(origin)g(virtual)g -(devices)g(are)g(activ)n(e)g(at)g(the)h(same)g(time;)g(e.g.,)f(the)i -(serv)n(er)c(do)r(es)0 1465 y(not)i(ha)n(v)n(e)f(to)h(tak)n(e)g(an)n(y) -f(lo)r(c)n(ks)h(to)g(service)f(origin)g(write)h(requests)f(if)i(no)f -(snapshot)f(device)h(is)g(activ)n(e,)g(ev)n(en)f(if)i(snapshots)0 -1565 y(are)f(b)r(eing)g(held.)0 1897 y Fg(5.6)112 b(Snapshot)39 -b(Deletion)0 2149 y Ff(Because)g(it)h(pac)n(ks)f(together)g -(information)h(for)f(m)n(ultiple)i(snapshots)e(in)h(eac)n(h)f(leaf)h -(no)r(de,)j(the)e(exception)e(btree)h(is)0 2249 y(optimized)30 -b(for)f(lo)r(okup)g(and)h(exception)f(insertion)g(as)g(it)h(should)f(b) -r(e.)44 b(Ho)n(w)n(ev)n(er,)28 b(snapshot)h(deletion)h(is)f(not)h(as)f -(simple)0 2349 y(an)e(op)r(eration)g(as)g(it)h(w)n(ould)f(b)r(e)h(if)g -(eac)n(h)f(snapshot)g(had)g(its)h(o)n(wn)f(tree.)36 b((But)28 -b(if)h(eac)n(h)d(snapshot)h(had)h(its)f(o)n(wn)g(tree)h(then)0 -2448 y(exception)g(creation)f(time)h(w)n(ould)g(increase)f(with)h(the)h -(n)n(um)n(b)r(er)f(of)g(snapshots,)f(m)n(uc)n(h)h(more)f(space)g(w)n -(ould)h(b)r(e)h(used)f(for)0 2548 y(m)n(ultiple)33 b(snapshots)f(and)g -(k)n(eeping)g(trac)n(k)f(of)i(exception)f(sharing)g(w)n(ould)g(b)r(e)h -(less)f(e\036cien)n(t.))52 b(In)33 b(general,)g(deleting)f(a)0 -2648 y(snapshot)c(requires)g(examining)g(the)h(en)n(tire)g(btree)g(and) -g(mo)r(difying)g(eac)n(h)f(leaf)h(blo)r(c)n(k)f(that)h(con)n(tains)f -(an)h(exception)g(for)0 2747 y(the)k(snapshot.)50 b(This)32 -b(could)g(amoun)n(t)g(to)g(quite)g(a)g(lot)g(of)g(IO)g(tra\036c)g(and)g -(tak)n(e)g(a)f(signi\034can)n(t)h(amoun)n(t)f(of)i(time.)51 -b(The)0 2847 y(snapshot)26 b(serv)n(er)e(will)j(therefore)e(simply)h -(log)g(the)g(status)g(of)h(the)f(snapshot)g(as)g("in)g(pro)r(cess)f(of) -h(deleting")g(and)g(indicate)0 2946 y(completion)d(immediately)g(to)g -(the)g(requesting)f(clien)n(t.)36 b(The)23 b(actual)f(deletion)h(will)g -(pro)r(ceed)g(in)g(the)g(bac)n(kground.)34 b(When)0 3046 -y(the)e(deletion)g(is)g(\034nished,)h(whic)n(h)f(could)f(require)g -(tens)h(of)g(seconds)f(for)g(a)h(large)e(v)n(olume,)i(the)g(snapshot)g -(is)f(logged)g(as)0 3146 y(a)n(v)-5 b(ailable)26 b(for)h(reuse.)0 -3345 y(A)j(p)r(ossible)e(optimization)h(is)g(to)g(defer)g(deletions)g -(un)n(til)h(sev)n(eral)d(snapshots)i(can)f(b)r(e)i(deleted)g(in)f(one)g -(pass,)g(whic)n(h)g(will)0 3445 y(require)20 b(less)h(time)h(than)f -(deleting)h(eac)n(h)e(individually)-7 b(.)35 b(Ho)n(w)21 -b(m)n(uc)n(h)g(less)g(dep)r(ends)g(on)g(ho)n(w)g(common)g(it)h(is)f -(for)g(exceptions)0 3544 y(of)j(sev)n(eral)e(snapshots)h(b)r(eing)i -(deleted)f(to)g(lie)g(in)h(the)f(same)g(btree)g(no)r(de.)35 -b(Another)24 b(p)r(ossible)g(optimization)g(is)g(to)g(include)0 -3644 y(in)34 b(eac)n(h)e(index)i(no)r(de)f(a)g(bitmap)h(indicating)f -(whic)n(h)h(snapshots)e(ha)n(v)n(e)g(exceptions)h(in)h(the)f(subtree)h -(descending)e(from)0 3743 y(that)c(no)r(de)f(so)g(that)h(en)n(tire)f -(subtrees)g(can)g(b)r(e)h(skipp)r(ed)g(during)f(the)h(tra)n(v)n(ersal)d -(if)j(they)g(do)f(not)h(need)f(to)h(b)r(e)g(mo)r(di\034ed.)0 -3943 y(A)33 b(more)f(aggressiv)n(e)e(and)j(considerably)e(more)i -(di\036cult)g(optimization)g(w)n(ould)f(in)n(v)n(olv)n(e)g(in)n(tro)r -(ducing)g(the)h(concept)g(of)0 4042 y(snapshot)28 b(set)h(generations)e -(and)i(tagging)e(eac)n(h)h(leaf)h(blo)r(c)n(k)f(with)i(a)e(the)h -(snapshot)f(generation)g(as)g(of)h(the)g(most)g(recen)n(t)0 -4142 y(alteration.)34 b(Then)23 b(a)g(snapshot)f(could)h(b)r(e)g -(deleted)h(b)n(y)e(creating)g(a)h(new)g(generation)e(that)i(do)r(es)g -(not)g(include)g(the)h(deleted)0 4242 y(snapshot.)44 -b(A)31 b(leaf)g(blo)r(c)n(k)e(tagged)h(with)h(an)f(earlier)f -(generation)f(w)n(ould)i(b)r(e)h(seen)f(as)g("stale")f(and)h(w)n(ould)g -(b)r(e)h(mo)r(di\034ed)0 4341 y(when)i(next)h(encoun)n(tered,)f(to)g -(remap)f(it)i(to)f(the)g(curren)n(t)g(generation,)g(remo)n(ving)e -(exceptions)h(b)r(elonging)h(to)g(deleted)0 4441 y(snapshots)38 -b(in)h(the)g(pro)r(cess.)69 b(The)39 b(complexit)n(y)f(of)h(this)g -(approac)n(h)e(mak)n(es)h(it)h(unattractiv)n(e,)i(ho)n(w)n(ev)n(er)c -(if)i(snapshot)0 4540 y(deletion)28 b(p)r(erformance)e(turns)h(out)h -(to)f(b)r(e)h(a)g(problem)f(it)h(migh)n(t)f(turn)h(out)f(to)h(b)r(e)g -(w)n(orth)e(the)i(e\033ort.)0 4872 y Fg(5.7)112 b(Expanding)38 -b(the)f(Snapshot)i(Store)0 5125 y Ff(The)30 b(only)f(tric)n(ky)g(part)g -(of)g(expanding)g(the)h(snapshot)f(store)f(is)i(increasing)e(the)i -(size)f(of)h(the)g(allo)r(cation)e(bitmap)i(table.)0 -5225 y(These)d(are)f(held)i(in)g(a)f(radix)f(tree)h(to)g(facilitate)h -(this.)37 b(New)27 b(index)h(and)f(bitmap)h(blo)r(c)n(ks)e(are)g(added) -i(on)f(the)g(righ)n(t.)36 b(Is)28 b(it)0 5325 y(b)r(est)e(to)f(k)n(eep) -f(the)i(bitmap)f(blo)r(c)n(ks)f(near)h(the)g(journal,)g(or)f(to)h(disp) -r(erse)g(them)h(throughout)e(the)h(snapshot)g(store,)f(nearb)n(y)p -eop end -%%Page: 11 11 -TeXDict begin 11 10 bop 0 83 a Ff(the)37 b(snapshot)e(store)g(areas)g -(that)h(they)h(map?)63 b(Curren)n(tly)-7 b(,)38 b(all)e(bitmap)g(blo)r -(c)n(ks)g(are)f(lo)r(cated)h(near)f(the)i(base)e(of)i(the)0 -183 y(snapshot)29 b(store,)h(whic)n(h)h(w)n(as)e(the)i(simplest)f -(thing)g(to)h(implemen)n(t.)45 b(But)31 b(if)f(the)h(snapshot)f(store)f -(is)h(expanded,)h(where)0 282 y(should)i(the)h(new)f(bitmap)h(blo)r(c)n -(ks)e(come)h(from?)54 b(Should)33 b(w)n(e)g(try)g(to)h(lea)n(v)n(e)e -(some)g(free)h(space)g(at)g(the)h(b)r(ottom)f(of)h(the)0 -382 y(snapshot)27 b(store?)36 b(Should)27 b(w)n(e)h(relo)r(cate)e(some) -h(data)g(blo)r(c)n(ks)g(to)g(mak)n(e)g(space?)36 b(These)28 -b(are)e(op)r(en)i(questions.)0 581 y(Once)35 b(the)g(bitmap)h(allo)r -(cation)e(table)h(is)g(expanded,)h(the)g(new)f(size)g(of)g(the)g -(snapshot)g(store)f(is)h(recorded)f(in)h(the)g(su-)0 -681 y(p)r(erblo)r(c)n(k,)27 b(and)g(that)h(is)g(that.)0 -1013 y Fg(5.8)112 b(User)38 b(Space)g(Serv)m(er)0 1266 -y Ff(Since)33 b(the)h(cluster)f(snapshot)f(clien)n(t)h(connects)g(to)g -(the)h(snapshot)e(serv)n(er)f(solely)i(b)n(y)g(means)f(of)i(a)e(net)n -(w)n(ork)g(so)r(c)n(k)n(et,)i(it)0 1365 y(w)n(as)c(natural)f(to)i -(implemen)n(t)g(the)g(serv)n(er)e(in)i(user)f(space)g(rather)f(than)i -(k)n(ernel.)45 b(Since)31 b(the)g(serv)n(er)d(is)j(rather)f(complex,)0 -1465 y(this)d(lik)n(ely)f(sa)n(v)n(ed)f(some)h(time,)h(and)f(certainly) -g(mak)n(es)f(the)i(co)r(de)f(accessible)g(to)g(a)g(wider)g(comm)n(unit) -n(y)g(of)h(programmers)0 1565 y(than)34 b(w)n(ould)e(b)r(e)i(the)g -(case)f(for)g(k)n(ernel)f(co)r(de.)54 b(On)33 b(the)h(other)f(hand,)i -(fully)f(async)n(hronous)d(IO)i(is)g(considerably)f(more)0 -1664 y(di\036cult)e(to)f(ac)n(hiev)n(e)f(in)h(user)g(space)f(than)h(in) -h(k)n(ernel)e(co)r(de,)i(and)f(certain)f(op)r(erations)g(could)h(w)n -(ell)g(b)r(e)g(less)g(e\036cien)n(t.)42 b(It)0 1764 y(is)32 -b(exp)r(ected)g(that)g(the)g(serv)n(er)e(will)j(b)r(e)f(p)r(orted)g(to) -f(k)n(ernel)g(space)h(at)f(some)h(p)r(oin)n(t,)h(if)f(only)g(to)g -(learn)f(the)h(truth)g(ab)r(out)0 1863 y(relativ)n(e)26 -b(p)r(erformance.)35 b(This)27 b(migh)n(t)g(also)f(b)r(e)i(desirable)e -(when)h(it)h(comes)e(time)i(to)f(implemen)n(t)g(a)g(single-no)r(de)f(v) --5 b(arian)n(t.)0 2179 y Fd(User)32 b(Space)g(Bu\033er)g(La)m(y)m(er)0 -2432 y Ff(Lik)n(e)h(man)n(y)f(problems)g(in)i(computer)f(science,)h -(the)f(snapshot)g(serv)n(er's)e(handling)i(of)g(its)g(disk-based)f -(btree)h(amoun)n(ts)0 2531 y(to)h(a)h(cac)n(hing)e(problem.)58 -b(As)34 b(suc)n(h,)i(the)f(classic)f(Unix)h(\020getblk\021)40 -b(pro)n(vides)34 b(an)g(elegan)n(t)g(mo)r(del.)58 b(It)35 -b(lends)f(itself)h(w)n(ell)0 2631 y(to)29 b(incremen)n(tal)g(up)r -(dating)g(of)h(the)g(btree,)f(bitmaps)h(and)f(other)g(\034le-bac)n(k)n -(ed)f(data)h(items.)42 b(It)30 b(supp)r(orts)f(async)n(hronous)0 -2731 y(writing)h(and)h(m)n(ulti-threaded)f(writing)h(w)n(ell.)46 -b(And)32 b(imp)r(ortan)n(tly)-7 b(,)31 b(it)g(will)g(greatly)f -(simplify)h(the)g(task)g(of)f(p)r(orting)h(the)0 2830 -y(serv)n(er)23 b(to)j(k)n(ernel)e(space.)35 b(An)26 b(analog)e(of)h -(Lin)n(ux's)g(bu\033er)g(la)n(y)n(er)f(w)n(as)g(therefore)g(implemen)n -(ted)i(in)g(user)e(space,)h(complete)0 2930 y(with)j(bu\033er)g(heads,) -g(ob)5 b(ject)28 b(referencing,)e(and)i(a)g(bu\033er)g(hash.)37 -b(This)28 b(is)g(recommended)f(reading)g(for)g(those)h(in)n(terested)0 -3029 y(in)g(ho)n(w)f(Lin)n(ux's)g(bu\033er)h(IO)f(mo)r(del)g(w)n(orks.) -0 3345 y Fd(Memory)j(In)m(v)m(ersion)i(Deadlo)s(c)m(k)0 -3598 y Ff(Implemen)n(ting)g(p)r(ortions)g(of)g(blo)r(c)n(k)g(devices)g -((or)g(\034lesystems)g(for)f(that)i(matter))f(in)h(user)f(space)f(in) -n(tro)r(duces)h(the)h(p)r(os-)0 3697 y(sibilit)n(y)i(of)h(memory)e(in)n -(v)n(ersion)g(deadlo)r(c)n(k.)59 b(This)36 b(o)r(ccurs)e(when)i(a)f -(user)g(space)f(program)g(exists)h(somewhere)f(in)i(the)0 -3797 y(virtual)d(memory)f(writeout)h(path,)i(whic)n(h)f(will)f(b)r(e)h -(the)g(case)e(for)h(an)n(y)g(blo)r(c)n(k)f(device)i(or)e(\034lesystem.) -54 b(When)34 b(the)g(VM)0 3897 y(system)24 b(tries)f(to)h(\035ush)h -(some)e(dirt)n(y)h(data)f(to)h(disk,)h(the)f(user)g(space)f(program)f -(ma)n(y)h(b)r(e)i(in)n(v)n(ok)n(ed)d(and)i(ma)n(y)f(kno)n(wingly)g(or)0 -3996 y(unkno)n(wingly)28 b(attempt)i(to)g(allo)r(cate)e(some)h(memory) --7 b(.)42 b(If)29 b(the)h(memory)f(a)n(v)-5 b(ailable)28 -b(for)h(non-critical)f(pro)r(cesses)g(suc)n(h)h(as)0 -4096 y(user)g(space)g(programs)e(is)j(nearly)f(exhausted,)g(the)h -(memory)f(allo)r(cation)g(request)g(ma)n(y)g(blo)r(c)n(k,)h(whic)n(h)f -(also)g(blo)r(c)n(ks)g(the)0 4195 y(memory)f(writeout)g(attempt,)h -(whic)n(h)g(can)f(ev)n(en)n(tually)g(deadlo)r(c)n(k)f(all)h(user)g -(space)g(programs)e(due)j(to)f(memory)g(exhaus-)0 4295 -y(tion.)40 b(This)29 b(problem)f(has)g(b)r(een)h(observ)n(ed)e(in)i -(practice.)40 b(The)28 b(standard)g(solution)g(is)h(to)f(run)h(an)n(y)f -(net)n(w)n(ork)f(serv)n(ers)f(on)0 4395 y(dedicated)c(serv)n(ers)d(so)i -(that)h(the)g(serv)n(er)e(is)i(not)f(in)h(an)n(y)f(VM)h(writeout)g -(path.)35 b(This)21 b(solution)g(is)h(not)g(en)n(tirely)f(satisfactory) -0 4494 y(b)r(ecause)27 b(it)h(requires)e(an)i(extra)e(serv)n(er,)g -(whic)n(h)h(ma)n(y)g(end)h(up)g(underutilized.)0 4694 -y(Suc)n(h)g(in)n(v)n(ersion)e(can)i(b)r(e)g(prev)n(en)n(ted)f(b)n(y)h -(running)f(the)i(user)e(space)g(pro)r(cess)g(in)h(\020PF_MEMALLOC\021) -35 b(mo)r(de,)28 b(in)g(whic)n(h)0 4793 y(a)36 b(sp)r(ecial)g(pro)r -(cess)e(\035ag)i(is)g(set)g(giving)f(the)i(pro)r(cess)e(privileged)g -(access)g(to)h(a)g(p)r(o)r(ol)g(of)g(system)g(memory)f(whic)n(h)h(will) -0 4893 y(automatically)31 b(b)r(e)i(tapp)r(ed)g(when)g(memory)f(runs)g -(lo)n(w.)51 b(In)33 b(this)f(mo)r(de,)i(a)f(pro)r(cess)e(m)n(ust)i(b)r -(e)g(sure)e(that)i(its)g(memory)0 4992 y(usage)27 b(is)h(strictly)g(b)r -(ounded)h(so)f(that)g(the)h(system)f(memory)g(p)r(o)r(ol)g(is)g(guaran) -n(teed)f(nev)n(er)g(to)h(b)r(e)h(exhausted.)38 b(Enforcing)0 -5092 y(suc)n(h)29 b(a)f(b)r(ound)h(is)g(p)r(ossible)g(with)g(the)h -(help)f(of)g(the)g(mlo)r(c)n(k)-5 b(all)29 b(system)f(call,)h(preallo)r -(cation)e(of)i(su\036cien)n(t)g(pro)r(cess)f(stac)n(k)0 -5192 y(space,)f(and)g(careful)f(analysis)g(of)h(the)h(user)e(space)h -(program)e(in)i(question.)36 b(While)28 b(some)f(details)g(remain)f(to) -h(b)r(e)h(w)n(ork)n(ed)0 5291 y(out,)g(it)h(is)f(an)n(ticipated)g(that) -h(a)f(w)n(ork)-5 b(able)26 b(solution)i(to)g(the)h(memory)e(in)n(v)n -(ersion)g(deadlo)r(c)n(k)g(problem)h(will)g(b)r(e)h(found,)g(so)0 -5391 y(that)e(this)g(problem)f(in)h(itself)g(will)g(not)f(b)r(ecome)h -(a)f(comp)r(elling)g(reason)f(to)i(p)r(ort)f(the)h(snapshot)f(serv)n -(er)f(to)h(k)n(ernel)g(space.)p eop end -%%Page: 12 12 -TeXDict begin 12 11 bop 0 83 a Fg(5.9)112 b(Messaging)0 -336 y Ff(The)39 b(snapshot)f(serv)n(er)e(uses)j(an)f(async)n(hronous)e -(stream)i(messaging)f(mo)r(del)i(o)n(v)n(er)e(a)h(so)r(c)n(k)n(et)g -(transp)r(ort.)69 b(A)39 b(simple)0 436 y(message)27 -b(formatting)h(mo)r(del)g(w)n(as)g(devised)g(in)h(whic)n(h)f(eac)n(h)g -(message)f(header)g(has)h(just)h(t)n(w)n(o)f(\034elds:)38 -b(co)r(de)29 b(and)f(length.)0 535 y(Since)19 b(the)h(messages)e -(themselv)n(es)g(tend)i(to)f(b)r(e)h(small)f(and)g(n)n(umerous,)h(the)f -(size)g(of)h(the)f(message)f(header)g(has)h(a)g(signi\034can)n(t)0 -635 y(e\033ect)26 b(on)e(net)n(w)n(ork)g(load.)35 b(The)25 -b(philosoph)n(y)f(is,)i(ev)n(ery)e(\034eld)h(that)g(can)g(b)r(e)g(mo)n -(v)n(ed)g(out)g(of)g(the)g(header)f(in)n(to)h(the)h(message)0 -734 y(b)r(o)r(dy)i(should)f(b)r(e.)37 b(This)28 b(w)n(a)n(y)-7 -b(,)26 b(messages)g(do)h(not)h(incur)f(size)h(p)r(enalties)f(for)g -(\034elds)h(they)g(do)f(not)g(require.)0 934 y(Generally)-7 -b(,)30 b(t)n(w)n(o)f(so)r(c)n(k)n(et)g(read)g(op)r(erations)f(are)h(p)r -(erformed)h(for)f(eac)n(h)g(incoming)h(message,)f(the)h(\034rst)g(to)g -(learn)f(the)h(size)0 1033 y(and)c(a)f(second)h(to)g(read)f(the)h -(message)f(b)r(o)r(dy)-7 b(.)36 b(The)26 b(size)g(of)g(the)g(message)f -(header)g(could)h(b)r(e)g(further)g(reduced,)g(since)g(the)0 -1133 y(size)j(of)g(man)n(y)f(messages)g(can)g(b)r(e)i(inferred)e(from)h -(the)g(message)f(co)r(de,)h(ho)n(w)n(ev)n(er)e(doing)i(so)f(w)n(ould)g -(require)g(three)h(reads)0 1233 y(instead)d(of)g(t)n(w)n(o)f(for)h(v)-5 -b(ariable)25 b(length)h(messages.)35 b(F)-7 b(or)25 b(the)i(time)f(b)r -(eing,)h(the)f(curren)n(t)g(eigh)n(t)f(b)n(yte)h(message)f(headers)g -(are)0 1332 y(deemed)j(satisfactory)-7 b(.)0 1531 y(Outgoing)40 -b(messages)g(are)g(t)n(ypically)h(sen)n(t)g(directly)g(from)g(a)g(pro)r -(cess)g(stac)n(k)f(in)i(a)f(single)g(so)r(c)n(k)n(et)f(write)h(op)r -(eration.)0 1631 y(Syn)n(tactic)19 b(macro)f(sugar)f(is)i(pro)n(vided)f -(that)i(allo)n(ws)e(\034xed-length)g(messages)g(to)h(b)r(e)g(expressed) -f(in)i(a)f(single-line)f(functional)0 1731 y(st)n(yle,)27 -b(using)g(sym)n(b)r(olic)g(\034elds)h(as)f(opp)r(osed)g(to)g(p)r -(ositional.)0 1930 y(Message)g(con)n(ten)n(ts)g(are)g(binary)-7 -b(,)28 b(whic)n(h)g(requires)e(careful)i(atten)n(tion)g(to)g -(considerations)e(of)i(\034eld)h(alignmen)n(t,)e(size)h(and)0 -2030 y(b)n(yte)23 b(order.)35 b(All)24 b(n)n(umeric)f(\034elds)h(are)e -(con)n(v)n(erted)g(to)i(net)n(w)n(ork)e(b)n(yte)h(order)g(on)g(sending) -g(and)h(nativ)n(e)f(order)f(on)h(receiving.)0 2129 y(Message)18 -b(format)h(is)g(de\034ned)g(using)g(gcc-sp)r(eci\034c)g(pac)n(k)n(ed)f -(structure)h(attributes,)h(whic)n(h)g(in)f(theory)g(pro)n(vides)f -(predictable)0 2229 y(\034eld)27 b(size)f(and)g(alignmen)n(t,)g(and)g -(alignmen)n(t)g(indep)r(endence)h(across)e(pro)r(cessor)f(arc)n -(hitectures.)35 b(W)-7 b(e)27 b(shall)f(see)g(ho)n(w)f(w)n(ell)0 -2328 y(this)j(w)n(orks)e(in)i(practice,)e(in)i(the)g(face)f(of)h(p)r -(ossible)f(compiler)g(bugs)g(in)h(this)g(relativ)n(ely)e(un)n(tested)i -(area.)0 2528 y(A)d(fully)f(async)n(hronous)e(message)h(mo)r(del)i(is)f -(used)g(in)h(whic)n(h)f(the)h(sender)e(nev)n(er)h(w)n(aits)f(for)h(a)g -(reply)-7 b(.)35 b(Instead,)25 b(the)g(sender)0 2627 -y(implemen)n(ts)d(an)g(incoming)g(message)e(handler)i(capable)f(of)h -(handling)g(an)n(y)f(message)g(that)h(migh)n(t)g(b)r(e)h(receiv)n(ed,)f -(including)0 2727 y(message)g(replies.)35 b(An)n(y)23 -b(required)g(state)g(transformations)f(are)g(implemen)n(ted)i(within)h -(the)f(incoming)f(message)f(handler,)0 2827 y(whic)n(h)d(runs)f(as)g -(its)h(o)n(wn)f(task.)33 b(Th)n(us,)20 b(sync)n(hronous)d(messages)g -(requiring)g(replies,)j(suc)n(h)e(as)g(the)h(clien)n(t's)g(initial)f -(\020iden)n(tify\021)0 2926 y(message,)i(m)n(ust)h(b)r(e)g(handled)f -(with)h(in)n(terpro)r(cess)e(comm)n(unication)h(while)h(the)f(common)g -(and)h(p)r(erformance-critical)d(case)0 3026 y(of)28 -b(async)n(hronous)d(messaging)g(is)j(the)g(default.)0 -3400 y Fh(6)131 b(Clien)l(t)45 b(Implemen)l(tation)g(Details)0 -3681 y Ff(Compared)40 b(to)g(the)h(serv)n(er,)i(the)e(snapshot)f(clien) -n(t)g(is)h(simple.)76 b(Implemen)n(ted)42 b(as)e(a)g(device)g(mapp)r -(er)h(target,)i(it)e(is)0 3781 y(resp)r(onsible)25 b(for)g(deferring)g -(IO)g(requests)g(as)g(appropriate,)f(querying)g(the)i(serv)n(er)e(for)h -(information)g(it)h(do)r(es)g(not)f(ha)n(v)n(e)g(in)0 -3881 y(cac)n(he,)k(receiving)g(replies,)g(and)h(submitting)g(requests)e -(to)i(the)g(correct)e(device.)43 b(It)29 b(m)n(ust)h(also)f(w)n(orry)e -(ab)r(out)j(releasing)0 3980 y(snapshot)39 b(read)f(lo)r(c)n(ks,)j(and) -f(a)e(handle)i(a)f(few)g(system)g(in)n(terface)g(details,)j(suc)n(h)d -(as)g(setting)g(up)g(a)g(net)n(w)n(ork)f(so)r(c)n(k)n(et)0 -4080 y(connection)21 b(to)g(the)g(snapshot)g(serv)n(er,)f(reconnecting) -h(if)g(the)h(connection)f(is)g(brok)n(en,)g(and)g(resp)r(onding)f(to)h -(the)h(o)r(ccasional)0 4180 y(message)i(to)i(clear)e(cac)n(he)h(b)r -(ecause)g(a)g(new)g(snapshot)g(w)n(as)g(created.)35 b(Essen)n(tially)-7 -b(,)26 b(the)g(clien)n(t)f(implemen)n(ts)h(some)f(simple)0 -4279 y(message)h(handling)h(and)h(a)f(cac)n(he,)g(the)h(latter)f(b)r -(eing)g(non-essen)n(tial.)0 4478 y(On)k(initialization,)i(the)f(clien)n -(t)f(is)h(passed)f(a)g(snapshot)g(n)n(um)n(b)r(er)g((-1)g(=)h -(origin))e(and)i(the)g(lo)r(cal)f(device)g(names)g(of)h(t)n(w)n(o)0 -4578 y(shared)39 b(storage)e(devices:)61 b(the)40 b(origin)f(and)g(the) -h(snapshot)f(store.)72 b(The)40 b(clien)n(t)g(starts)f(t)n(w)n(o)g(k)n -(ernel)g(daemons,)i(one)0 4678 y(b)r(eing)32 b(a)g(blo)r(c)n(king)f -(thread)h(to)g(handle)g(serv)n(er)e(replies)i(and)g(the)g(other,)h(a)f -(non)n(blo)r(c)n(king)e(w)n(ork)n(er)g(thread)i(to)g(tak)n(e)f(care)0 -4777 y(of)f(v)-5 b(arious)28 b(min)n(utiae.)43 b(A)n(t)30 -b(this)g(p)r(oin)n(t)g(the)g(clien)n(t)g(initialization)f(completes)g -(and)h(the)g(virtual)f(device)g(app)r(ears)g(in)h(the)0 -4877 y(/dev/mapp)r(er)d(directory)-7 b(.)38 b(It)29 b(can)f(receiv)n(e) -f(IO)h(requests,)g(but)h(not)f(complete)h(them)g(y)n(et,)f(b)r(ecause)g -(it)h(do)r(es)f(not)g(ha)n(v)n(e)f(a)0 4977 y(so)r(c)n(k)n(et)f -(connection)h(to)h(the)g(serv)n(er.)35 b(A)28 b(user)f(space)f(utilit)n -(y)i(supplies)g(this)g(later)f(via)g(an)g(io)r(ctl)h(on)f(the)h -(virtual)f(device.)0 5176 y(One)f(migh)n(t)g(argue)e(that)i(the)h(so)r -(c)n(k)n(et)e(connection)g(should)h(b)r(e)g(created)g(b)r(efore)f(the)i -(virtual)e(device)h(is)g(created,)f(ho)n(w)n(ev)n(er)0 -5275 y(the)j(virtual)f(device)g(needs)h(to)f(b)r(e)h(able)f(to)h(op)r -(erate)e(for)h(short)g(p)r(erio)r(ds)g(with)h(the)g(so)r(c)n(k)n(et)f -(disconnected)g(an)n(yw)n(a)n(y)-7 b(,)25 b(since)0 5375 -y(the)j(so)r(c)n(k)n(et)e(connection)h(migh)n(t)h(break)e(and)i(need)f -(to)h(b)r(e)g(reconnected.)p eop end -%%Page: 13 13 -TeXDict begin 13 12 bop 0 83 a Ff(Finally)-7 b(,)34 b(b)r(efore)f(it)h -(can)e(complete)h(an)n(y)g(IO)f(requests,)i(the)f(clien)n(t)h(iden)n -(ti\034es)f(itself)g(to)g(the)h(snapshot)e(serv)n(er,)h(stating)0 -183 y(whic)n(h)c(snapshot)f(it)i(is)f(a)g(clien)n(t)g(for.)41 -b(The)29 b(serv)n(er)f(informs)g(the)i(clien)n(t)f(of)g(the)h(c)n(h)n -(unk)f(size,)g(then)h(the)f(clien)n(t)g(initializes)0 -282 y(its)f(cac)n(he)e(and)i(pro)r(ceeds)e(to)i(send)f(queries,)g -(receiv)n(e)f(replies)h(and)h(retire)e(IO)i(requests.)0 -482 y(The)i(clien)n(t-side)g(query)f(cac)n(he)g(is)h(implemen)n(ted)h -(lazily)e(as)h(an)g(ino)r(de)g(address)f(space.)43 b(This)30 -b(has)g(the)g(adv)-5 b(an)n(tage)29 b(that)0 581 y(it)34 -b(is)f(managed)f(automatically)g(b)n(y)i(the)f(VM)h(system:)48 -b(when)34 b(there)f(is)g(no)g(memory)g(pressure,)g(the)h(cac)n(he)e -(will)i(gro)n(w)0 681 y(without)28 b(b)r(ound,)g(but)g(when)g(there)f -(is,)h(the)g(VM)g(system)f(can)g(easily)g(shrink)g(it.)0 -1055 y Fh(7)131 b(F)-11 b(ailure)45 b(T)-11 b(olerance)0 -1353 y Fg(7.1)112 b(Serv)m(er)38 b(Restart)0 1606 y Ff(Though)c(c)n -(hallenging)f(to)i(implemen)n(t)g(e\036cien)n(tly)-7 -b(,)36 b(the)f(A)n(CID)g(prop)r(erties)e(of)i(consistency)f(and)g -(durabilit)n(y)g(immedi-)0 1705 y(ately)e(yield)g(an)g(imp)r(ortan)n(t) -g(b)r(ene\034t:)47 b(fail-o)n(v)n(er)30 b(of)i(the)h(snapshot)e(serv)n -(er)f(is)i(trivial.)50 b(This)33 b(is)f(b)r(ecause)f(all)h(the)h(serv)n -(er)0 1805 y(state)c(information)f(connected)h(with)g(completed)g(IO)g -(requests)f(is)h(alw)n(a)n(ys)e(a)n(v)-5 b(ailable)28 -b(on)g(disk.)41 b(State)29 b(information)g(for)0 1905 -y(uncompleted)34 b(IO)f(requests)f(is)h(alw)n(a)n(ys)f(main)n(tained)h -(in)h(the)f(memory)g(of)g(clien)n(ts,)i(and)e(none)g(needs)h(to)f(b)r -(e)h(uploaded)0 2004 y(to)29 b(the)h(new)f(serv)n(er.)40 -b(Restarting)29 b(the)g(snapshot)g(serv)n(er)e(is)i(the)h(same)f(as)f -(starting)h(it)g(initially)-7 b(,)30 b(except)f(that)h(snapshot)0 -2104 y(clien)n(ts)f((but)h(not)g(origin)e(clien)n(ts))h(m)n(ust)h -(upload)f(their)g(p)r(ending)h(snapshot)e(read)h(lo)r(c)n(ks)f(b)r -(efore)h(the)h(serv)n(er)e(ma)n(y)g(allo)n(w)0 2204 y(an)n(y)g(origin)g -(writes)h(to)g(pro)r(ceed.)1048 2173 y Fc(2)1084 2204 -y Ff(Otherwise,)g(the)g(new)h(serv)n(er)d(need)i(only)g(load)f(the)i -(snapshot)e(store)g(sup)r(erblo)r(c)n(k)g(and)0 2303 -y(repla)n(y)g(the)j(journal.)43 b(Finally)-7 b(,)30 b(there)f(is)h(no)g -(requiremen)n(t)f(to)g(clear)g(clien)n(t)h(cac)n(he.)43 -b(So)29 b(serv)n(er)f(restart)h(is)g(v)n(ery)g(fast,)h(on)0 -2403 y(the)e(order)e(of)i(tens)f(of)h(milliseconds.)36 -b(Detecting)28 b(serv)n(er)e(failure)h(is)h(lik)n(ely)f(to)g(tak)n(e)g -(m)n(uc)n(h)g(longer.)36 b(There)27 b(will)h(b)r(e)g(some)0 -2502 y(sligh)n(t)h(p)r(erformance)f(degradation)f(due)j(to)f(the)g -(loss)g(of)g(serv)n(er)e(metadata)i(cac)n(he)f(and)h(the)h(need)f(for)g -(snapshot)f(clien)n(ts)0 2602 y(to)f(retry)g(p)r(ending)h(reads,)e(but) -j(it)f(is)f(unlik)n(ely)g(to)h(b)r(e)g(noticeable.)0 -2934 y Fg(7.2)112 b(Clien)m(t)36 b(failure)0 3187 y Ff(The)23 -b(serv)n(er)e(notices)i(that)g(a)g(clien)n(t)g(has)g(failed)g(when)g -(its)g(so)r(c)n(k)n(et)f(connection)h(breaks.)34 b(In)23 -b(resp)r(onse,)g(the)h(serv)n(er)d(releases)0 3287 y(an)n(y)27 -b(snapshot)g(read)f(lo)r(c)n(ks)h(held)h(b)n(y)f(that)h(clien)n(t,)g -(and)f(that)h(is)f(that.)0 3619 y Fg(7.3)112 b(F)-9 b(ailure)37 -b(Detection)0 3871 y Ff(Cluster)26 b(heartb)r(eating)f(in)h(itself)h -(is)e(insu\036cien)n(t)i(to)f(detect)g(some)f(common)h(failure)f -(conditions.)36 b(F)-7 b(or)26 b(example,)f(a)h(no)r(de)0 -3971 y(migh)n(t)38 b(con)n(tin)n(ue)g(resp)r(onding)f(to)h(heartb)r -(eat)g(messages,)h(ev)n(en)f(though)g(its)g(cluster)g(snapshot)f -(device)h(has)g(stopp)r(ed)0 4071 y(servicing)33 b(IO)h(requests)f(for) -h(one)g(reason)f(or)g(another,)j(e.g.,)f(a)f(memory)g(failure.)57 -b(If)34 b(that)h(clien)n(t)g(holds)f(crucial)f(read)0 -4170 y(lo)r(c)n(ks,)f(the)g(en)n(tire)g(cluster)f(could)h(lo)r(c)n(k)f -(up.)50 b(So)32 b(at)g(least)f(in)h(the)h(case)e(of)g(snapshot)h(clien) -n(ts,)g(the)h(serv)n(er)d(m)n(ust)i(detect)0 4270 y(timeouts)21 -b(and)g(ping)g(the)h(clien)n(t)f(for)g(liv)n(eness.)33 -b(If)22 b(the)g(clien)n(t)f(fails)g(the)g(test,)i(the)f(serv)n(er)d -(will)i(break)f(its)i(so)r(c)n(k)n(et)e(connection)0 -4370 y(and)28 b(release)e(its)i(lo)r(c)n(ks.)37 b(It)29 -b(is)e(p)r(ossible)h(that)g(the)g(clien)n(t)g(ma)n(y)g(ha)n(v)n(e)e -(simply)i(b)r(e)h(slo)n(w,)e(not)h(dead,)f(in)i(whic)n(h)e(case)h(it)g -(will)0 4469 y(reconnect)f(to)g(the)h(cluster)f(and)h(carry)e(on.)0 -4668 y(Similarly)-7 b(,)28 b(clien)n(ts)f(need)i(to)e(detect)i(serv)n -(er)d(problems)h(that)h(heartb)r(eating)g(ma)n(y)f(miss.)38 -b(If)28 b(a)g(snapshot)f(or)g(origin)g(clien)n(t)0 4768 -y(detects)k(a)f(timeout,)j(it)e(should)f(rep)r(ort)h(it)g(to)g(the)g -(cluster)f(infrastructure)g(so)g(that)h(further)g(remedial)f(action)h -(ma)n(y)f(b)r(e)0 4868 y(tak)n(en.)41 b(It)29 b(ma)n(y)g(b)r(e)g(that)h -(the)f(cluster)g(resource)e(manager)h(or)g(h)n(uman)h(administrator)e -(simply)j(assigned)d(the)j(serv)n(er)d(to)0 4967 y(an)k(under-p)r(o)n -(w)n(ered)f(or)h(o)n(v)n(erloaded)e(no)r(de,)k(in)f(whic)n(h)f(case)g -(the)h(correct)f(action)g(is)g(to)h(restart)e(the)i(serv)n(er)e(on)i(a) -f(more)0 5067 y(appropriate)26 b(no)r(de.)37 b(In)27 -b(an)n(y)g(ev)n(en)n(t,)g(this)h(is)g(not)f(a)g(problem)g(that)h -(heartb)r(eating)f(can)g(detect.)p 0 5136 1548 4 v 92 -5190 a Fb(2)127 5213 y Fa(A)f(future)i(optimization)f(to)g(eliminate)e -(cop)n(y-on-write)j(for)f(snapshot)h(writes)f(will)e(require)j(similar) -d(treatmen)n(t)j(in-progress)g(snapshot)0 5292 y(writes.)p -eop end -%%Page: 14 14 -TeXDict begin 14 13 bop 0 83 a Fh(8)131 b(Utilities)0 -364 y Ff(Sev)n(eral)26 b(utilities)i(programs)e(are)g(pro)n(vided)h(to) -g(supp)r(ort)g(the)h(use)g(of)f(the)h(cluster)f(blo)r(c)n(k)g(device:)0 -564 y Fd(mksnapstore)f Ff(-)i(Initialize)f(a)g(ph)n(ysical)g(v)n(olume) -g(as)g(a)g(snapshot)g(store)0 763 y Fd(csnap-connect)i -Ff(-)e(Connect)g(a)g(virtual)g(snapshot)g(device)g(to)h(a)f(snapshot)g -(serv)n(er)0 962 y Fd(csnap-create)i Ff(-)e(Create)g(a)g(new)h -(snapshot)0 1161 y Fd(csnap-delete)f Ff(-)g(Delete)h(a)g(snapshot)0 -1361 y(The)21 b(latter)g(t)n(w)n(o)f(functions)i(ha)n(v)n(e)e -(traditionally)g(b)r(een)h(p)r(erformed)g(via)f(an)h(io)r(ctl)g(on)g -(the)h(Device)f(Mapp)r(er)g(con)n(trol)e(device.)0 1460 -y(Ho)n(w)n(ev)n(er)i(it)j(mak)n(es)e(more)g(sense)h(for)g(a)g(cluster)g -(snapshot)f(implemen)n(tation)h(to)g(request)g(a)g(new)g(snapshot)g -(directly)f(from)0 1560 y(the)28 b(snapshot)f(serv)n(er)e(so)i(that)h -(the)g(device)f(itself)h(is)g(not)f(required)g(to)g(act)h(as)f(a)g -(mere)g(rela)n(y)-7 b(.)0 1934 y Fh(9)131 b(In)l(terface)45 -b(to)f(Cluster)g(Infrastructure)0 2216 y Ff(The)32 b(cluster)f -(snapshot)g(blo)r(c)n(k)g(device)g(w)n(as)g(designed)g(to)g(b)r(e)h(op) -r(erated)f(either)h(man)n(ually)e(or)h(under)h(the)g(con)n(trol)e(of)h -(a)0 2315 y(cluster)d(manager)f(system.)40 b(Its)29 b(needs)f(are)g(mo) -r(dest:)39 b(it)29 b(requires)e(a)i(so)r(c)n(k)n(et)e(connection)h(to)h -(a)f(snapshot)g(serv)n(er,)f(and)i(it)0 2415 y(needs)24 -b(a)g(w)n(a)n(y)f(of)h(rep)r(orting)f(errors)f(when)j(things)f(go)f -(wrong.)35 b(F)-7 b(or)23 b(example,)i(if)f(its)h(serv)n(er)d -(connection)i(breaks,)g(it)g(needs)0 2514 y(to)29 b(b)r(e)g(able)g(to)g -(request)f(a)g(new)h(one.)41 b(These)29 b(are)f(the)h(only)f(things)h -(it)h(requires)d(b)r(ey)n(ond)i(the)g(existing)g(Device)f(Mapp)r(er)0 -2614 y(infrastructure.)0 2813 y(A)d(user)e(space)h(program)e(connects)i -(a)g(so)r(c)n(k)n(et)f(to)h(the)g(virtual)g(device)g(after)g(Device)g -(Mapp)r(er)g(has)g(instan)n(tiated)g(it)h(via)e(an)0 -2913 y(io)r(ctl)30 b(on)f(the)h(virtual)f(device,)h(passing)f(the)h(FD) -g(n)n(um)n(b)r(er)f(of)h(a)f(so)r(c)n(k)n(et)g(it)h(has)f(op)r(ened.)43 -b(A)30 b(simple)g(utilit)n(y)g(is)f(pro)n(vided)0 3013 -y(so)f(that)g(this)h(ma)n(y)e(b)r(e)i(done)f(from)g(the)h(shell,)f(for) -g(the)g(purp)r(ose)g(of)g(running)g(the)h(snapshot)e(blo)r(c)n(k)h -(device)g(without)h(the)0 3112 y(aid)e(of)h(an)n(y)f(cluster)g -(infrastructure.)0 3311 y(A)d(simple)g(user)f(space)h(monitoring)e -(utilit)n(y)j(is)e(planned,)i(to)f(receiv)n(e)e(reconnection)h -(requests)g(from)h(the)g(snapshot)f(clien)n(t.)0 3411 -y(These)d(are)e(deliv)n(ered)h(o)n(v)n(er)g(a)g(second,)i(lo)r(cal)e -(so)r(c)n(k)n(et)g(connection.)34 b(So)19 b(the)i(snapshot)e(clien)n(t) -h(has)f(t)n(w)n(o)g(so)r(c)n(k)n(et)g(connections:)0 -3511 y(one)25 b(to)f(the)i(serv)n(er)d(o)n(v)n(er)g(the)i(net)n(w)n -(ork,)f(and)h(a)g(lo)r(cal)f(connection)g(to)h(a)g(monitor)f(daemon.)35 -b(If)26 b(b)r(oth)f(connections)f(break,)0 3610 y(the)k(snapshot)f -(target)f(will)i(giv)n(e)f(up)h(in)f(disgust)h(and)f(return)g(failure)g -(for)g(all)h(further)f(IO)g(requests.)0 3810 y(The)35 -b(snapshot)f(serv)n(er)g(m)n(ust)h(rely)f(on)h(the)g(cluster)g -(infrastructure)f(to)h(satisfy)f(the)i(requiremen)n(t)e(that)h(all)g -(snapshot)0 3909 y(clien)n(ts)25 b(reconnect)g(and)h(upload)f(their)g -(read)g(lo)r(c)n(ks)g(on)g(serv)n(er)f(restart.)35 b(A)25 -b(suitable)h(in)n(terface)f(to)g(supp)r(ort)h(this)f(requires)0 -4009 y(further)i(researc)n(h.)0 4383 y Fh(10)131 b(P)l(erformance)44 -b(Characteristics)0 4681 y Fg(10.1)112 b(Assumptions)0 -4934 y Ff(P)n(erformance)36 b(estimates)h(b)r(elo)n(w)g(are)f(based)h -(on)g(using)g(the)g(smallest)g(c)n(h)n(unk)g(size,)j(4K.)c(Eac)n(h)h -(new)h(exception)f(uses)0 5034 y(20)g(b)n(ytes)g((exception)g(store)f -(address,)j(sharing)d(bitmap)i(and)f(directory)f(en)n(try))h(so)g(eac) -n(h)g(btree)g(leaf)g(no)r(de)g(holds)g(a)0 5133 y(maxim)n(um)30 -b(of)h(ab)r(out)g(200)e(exceptions.)45 b(Due)31 b(to)g(splitting,)h -(leaf)e(no)r(des)h(are)e(normally)h(not)g(full.)78 b(In)31 -b(fact)g(w)n(orst)e(case)0 5233 y(fullness)37 b(of)g(50\045)f(is)h(exp) -r(ected)g(for)g(the)g(early)f(implemen)n(tations,)j(so)d(leaf)h(no)r -(des)f(will)i(hold)e(ab)r(out)h(100)f(exceptions)0 5332 -y(eac)n(h.)g(The)28 b(p)r(erformance)e(estimates)h(here)g(assume)g -(async)n(hronous)e(IO,)i(whic)n(h)h(for)f(user)g(space)g(is)g(not)h(y)n -(et)f(a)g(practical)p eop end -%%Page: 15 15 -TeXDict begin 15 14 bop 0 83 a Ff(p)r(ossibilit)n(y)30 -b(in)g(Lin)n(ux,)g(therefore)g(a)f(k)n(ernel)g(implemen)n(tation)h(is)g -(assumed.)44 b(The)30 b(initial)g(implemen)n(tation)g(ho)n(w)n(ev)n(er) -e(is)0 183 y(in)g(user)f(space;)f(without)i(async)n(hronous)d(IO)i(the) -h(user)f(space)g(implemen)n(tation)g(will)h(not)f(p)r(erform)g(as)g(w)n -(ell)g(as)g(a)g(k)n(ernel)0 282 y(implemen)n(tation.)36 -b(It)27 b(is)f(exp)r(ected)h(that)f(b)r(oth)h(implemen)n(tations)f -(will)h(b)r(e)f(dev)n(elop)r(ed)g(and)g(main)n(tained;)h(that)f(the)h -(user)0 382 y(implemen)n(tation)j(will)g(b)r(e)g(a)n(v)-5 -b(ailable)29 b(\034rst;)i(that)f(a)g(k)n(ernel)f(implemen)n(tation)h -(will)g(sup)r(ercede)g(it)g(in)g(p)r(erformance;)g(and)0 -482 y(that)38 b(the)f(user)g(space)f(implemen)n(tation)i(will)f(ev)n -(en)n(tually)f(pull)i(ev)n(en)f(with)h(the)f(k)n(ernel)g(implemen)n -(tation)g(b)n(y)g(taking)0 581 y(adv)-5 b(an)n(tage)26 -b(of)h(newly)h(a)n(v)-5 b(ailable)26 b(async)n(hronous)f(IO)i(and)h -(user)f(space)f(lo)r(c)n(king)h(facilities.)0 913 y Fg(10.2)112 -b(E\033ect)37 b(of)h(c)m(h)m(unk)f(size)0 1166 y Ff(Larger)d(c)n(h)n -(unk)h(size)g(will)i(help)f(p)r(erformance)e(for)i(sequen)n(tial)f(and) -g(h)n(urt)h(for)f(random)g(write)g(loads.)61 b(The)36 -b(total)f(size)0 1266 y(of)c(metadata)g(reduces)g(linearly)f(with)i -(the)f(c)n(h)n(unk)g(size,)h(sa)n(ving)e(space,)i(IO)f(bandwidth)g(and) -h(seeking.)47 b(On)31 b(the)h(other)0 1365 y(hand,)38 -b(larger)33 b(c)n(h)n(unks)i(increase)f(in)n(ternal)h(fragmen)n(tation) -g(of)g(the)h(snapshot)f(store,)i(esp)r(ecially)e(for)g(sparse,)h -(random)0 1465 y(access)27 b(loads,)h(and)h(the)g(o)n(v)n(erhead)e(of)h -(metadata)g(up)r(dating)h(is)g(supp)r(osed)f(to)h(b)r(e)g(small)f(in)h -(relation)f(to)g(data)g(transfers.)0 1565 y(Therefore)f(it)h(is)g(hop)r -(ed)f(that)i(the)f(p)r(erformance)e(and)i(metadata)f(size)h(cost)f(of)h -(small)f(c)n(h)n(unk)h(sizes)f(will)h(b)r(e)g(out)n(w)n(eighed)0 -1664 y(reduced)f(in)n(ternal)g(fragmen)n(tation,)f(sa)n(ving)g(space)h -(in)h(the)g(snapshot)f(store.)36 b(This)27 b(remains)g(to)g(b)r(e)h -(tested)g(in)g(practice.)0 1996 y Fg(10.3)112 b(E\033ect)37 -b(of)h(metadata)f(blo)s(c)m(k)g(size)0 2249 y Ff(Larger)22 -b(metadata)i(blo)r(c)n(ks)g(will)h(impro)n(v)n(e)e(p)r(erformance)g -(somewhat)h(on)g(largely)f(serial)g(write)i(loads)e(due)i(do)f -(requiring)f(a)0 2349 y(few)n(er)i(n)n(um)n(b)r(er)g(of)h(larger)e -(IOs,)h(esp)r(ecially)g(if)i(the)f(snapshot)f(metadata)g(is)g(fragmen)n -(ted.)36 b(Ho)n(w)n(ev)n(er,)24 b(for)h(the)h(time)g(b)r(eing)0 -2448 y(Lin)n(ux)f(do)r(es)h(not)f(supp)r(ort)h(IO)f(bu\033ers)g(larger) -f(than)i(ph)n(ysical)f(page)f(size,)i(so)f(it)h(is)g(exp)r(ected)f -(that)h(metadata)f(blo)r(c)n(k)g(size)0 2548 y(will)g(not)g(increase)e -(un)n(til)j(this)f(issue)f(is)h(addressed,)f(at)h(least)f(for)h(a)f(k)n -(ernel)g(implemen)n(tation)h(of)g(the)g(snapshot)f(metadata)0 -2648 y(serv)n(er.)34 b(F)-7 b(or)26 b(compatibilit)n(y)g(with)g(the)h -(exp)r(ected)f(k)n(ernel)f(metadata)g(serv)n(er,)g(the)h(user)g(space)f -(implemen)n(tation)h(will)g(use)0 2747 y(4K)h(blo)r(c)n(ks.)0 -2946 y(It)g(is)g(though)n(t)f(that)h(comm)n(unication)f(o)n(v)n(erhead) -e(and)j(serv)n(er)d(load)i(will)h(not)g(b)r(e)g(signi\034can)n(t)f(p)r -(erformance)f(factors,)h(due)0 3046 y(to)f(these)g(b)r(eing)g(highly)g -(optimized.)36 b(Con)n(ten)n(tion)24 b(on)h(large)f(clusters)g(with)h -(parallel)f(loads)g(should)h(not)g(b)r(e)g(a)g(signi\034can)n(t)0 -3146 y(factor)31 b(either,)j(since)e(a)f(single)h(serv)n(er)e(should)i -(b)r(e)h(able)f(to)g(handle)g(the)g(tra\036c)g(of)g(man)n(y)g(no)r(des) -g(of)g(similar)f(p)r(o)n(w)n(er)g(to)0 3245 y(itself.)k(The)21 -b(exception)f(to)h(this)g(is)g(cop)n(y-out)e(o)n(v)n(erhead)g(whic)n(h) -i(could)f(easily)g(saturate)g(a)g(serv)n(er's)f(bus;)k(a)e(simple)g -(solution)0 3345 y(is)27 b(a)n(v)-5 b(ailable:)36 b(farm)27 -b(out)h(the)g(cop)n(y-out)e(tra\036c)h(to)g(ligh)n(tly-loaded)f(no)r -(des)i(as)f(necessary)-7 b(.)0 3677 y Fg(10.4)112 b(E\033ect)37 -b(of)h(Holding)d(Multiple)h(Snapshots)0 3930 y Ff(The)d(more)f -(snapshots)h(that)g(are)f(held,)j(the)e(more)g(btree)g(leaf)g(no)r(des) -g(will)g(b)r(e)h(required)e(to)h(hold)g(them.)54 b(Journalling)0 -4029 y(the)30 b(extra)f(btree)h(lea)n(v)n(es)f(to)g(disk)h(consumes)f -(IO)h(bandwidth,)h(causes)e(more)g(seeking)g(and)h(generates)e(cac)n -(he)h(pressure.)0 4129 y(Reading)22 b(in)h(the)h(extra)e(btree)g(no)r -(des)h(increases)f(latency)-7 b(.)35 b(Ho)n(w)n(ev)n(er,)21 -b(b)r(ecause)i(exceptions)f(for)h(all)f(snapshots)g(are)g(stored)0 -4229 y(adjacen)n(t)27 b(in)h(the)g(btree,)f(the)h(o)n(v)n(erhead)e(is)h -(not)h(as)e(large)h(as)f(if)j(a)e(separate)f(map)h(had)h(to)f(b)r(e)h -(up)r(dated)g(on)f(disk)h(for)f(eac)n(h)0 4328 y(snapshot.)57 -b(Imp)r(ortan)n(tly)-7 b(,)36 b(the)f(pro)r(cess)e(of)i(determining)f -(whether)g(a)g(giv)n(en)g(c)n(h)n(unk)g(is)h(shared)e(nev)n(er)h -(requires)f(more)0 4428 y(than)28 b(a)f(single)g(leaf)g(no)r(de)h(to)f -(b)r(e)h(examined.)0 4627 y(Sharing)d(bitmaps)h(are)f(used)h(within)h -(leaf)e(no)r(des)h(to)g(a)n(v)n(oid)f(ha)n(ving)f(to)i(en)n(ter)g(an)n -(y)f(giv)n(en)g(snapshot)g(store)g(address)g(more)0 4727 -y(than)h(once)e(in)n(to)i(the)f(no)r(de,)h(and)g(also)e(p)r(erforms)h -(the)h(function)f(of)h(sp)r(ecifying)f(whic)n(h)h(snapshot)e(uses)h(a)g -(giv)n(en)g(snapshot)0 4826 y(store)d(address.)34 b(The)23 -b(w)n(orst)f(case)g(arises)f(when)j(a)e(giv)n(en)g(logical)g(c)n(h)n -(unk)h(is)f(written)i(at)e(least)h(once)g(after)f(ev)n(ery)g(snapshot.) -0 4926 y(Then)29 b(the)h(leaf)f(no)r(de)g(en)n(tries)f(for)h(that)g(c)n -(h)n(unk)g(ha)n(v)n(e)f(a)h(bitmap)g(and)g(a)g(snapshot)f(store)h -(address)e(for)i(ev)n(ery)f(snapshot.)0 5026 y(Since)23 -b(leaf)g(no)r(des)f(are)g(exp)r(ected)h(to)g(b)r(e)g(50\045)f(full)i -(in)f(the)g(initial)g(implemen)n(tation,)h(w)n(e)e(can)h(end)g(up)g -(with)g(one)f(exception)0 5125 y(stored)i(in)h(eac)n(h)g(leaf)f(no)r -(de.)36 b(Then)26 b(the)f(n)n(um)n(b)r(er)g(of)g(btree)f(no)r(des)h -(that)g(ha)n(v)n(e)f(to)h(b)r(e)h(journalled)e(is)h(equal)f(to)h(the)g -(n)n(um)n(b)r(er)0 5225 y(of)32 b(c)n(h)n(unks)f(written.)50 -b(The)32 b(journalled)g(no)r(de)g(has)f(to)h(b)r(e)g(written)g(t)n -(wice,)h(once)f(to)f(the)i(journal)e(and)h(once)f(to)h(its)g(true)0 -5325 y(destination.)j(So)23 b(the)g(w)n(orst)f(case)g(is)g(a)h(factor)f -(of)h(3)f(degradation)g(in)h(write)f(p)r(erformance)g(due)h(to)g(btree) -g(up)r(dating)g(alone.)p eop end -%%Page: 16 16 -TeXDict begin 16 15 bop 0 83 a Ff(T)-7 b(o)23 b(ameliorate)f(suc)n(h)i -(degradation)d(it)k(w)n(ould)e(b)r(e)h(wise)f(to)h(use)f(a)g(larger)f -(c)n(h)n(unk)h(size)g(when)h(large)e(n)n(um)n(b)r(ers)i(of)f(snapshots) -0 183 y(are)k(exp)r(ected.)0 382 y(The)34 b(w)n(orst)g(case)f -(degradation)g(ab)r(o)n(v)n(e)g(can)h(b)r(e)g(temp)r(ered)h(somewhat)f -(b)n(y)g(impro)n(ving)f(the)h(btree)h(up)r(date)f(algorithm)0 -482 y(to)28 b(use)g(a)f(b+tree)g(algorithm,)g(whic)n(h)h(guaran)n(tees) -e(2/3rds)g(leaf)i(fullness,)g(enough)f(to)h(hold)g(t)n(w)n(o)f -(exceptions)g(instead)h(of)0 581 y(one.)50 b(Larger)30 -b(metadata)h(blo)r(c)n(ks)h(will)g(help)g(reduce)g(seeking)f(o)n(v)n -(erhead,)g(when)h(they)g(b)r(ecome)g(practical.)50 b(Ev)n(en)n(tually)0 -681 y(though,)33 b(the)f(b)r(est)g(strategy)f(is)h(to)f(in)n(tro)r -(duce)h(v)-5 b(arian)n(t)31 b(leaf)g(no)r(de)h(formats)f(that)i -(optimize)f(for)f(the)h(man)n(y-snapshots)0 780 y(case)24 -b(b)n(y)g(represen)n(ting)g(ranges)f(of)i(snapshot)f(store)f(c)n(h)n -(unks)i(compactly)-7 b(,)24 b(esp)r(ecially)h(where)f(the)h(snapshot)f -(store)g(c)n(h)n(unks)0 880 y(are)j(allo)r(cated)f(sequen)n(tially)-7 -b(,)27 b(whic)n(h)h(is)f(something)g(w)n(e)g(w)n(an)n(t)g(to)h(ac)n -(hiev)n(e)e(an)n(yw)n(a)n(y)-7 b(.)0 1079 y(In)33 b(brief,)h(the)f -(metadata)g(up)r(date)g(comp)r(onen)n(t)f(of)h(origin)f(and)g(snapshot) -g(write)h(p)r(erformance)f(will)h(degrade)e(linearly)0 -1179 y(with)f(the)g(n)n(um)n(b)r(er)f(of)h(snapshots)e(held,)i(but)h -(with)f(a)f(m)n(uc)n(h)g(shallo)n(w)n(er)e(slop)r(e)j(than)f(if)h -(snapshot)f(store)g(data)g(w)n(ere)f(not)0 1279 y(shared)i(and)g -(metadata)g(w)n(ere)g(not)g(group)r(ed)g(together)g(b)n(y)g(logical)g -(address.)44 b(In)31 b(the)g(latter)f(case,)h(cop)n(y-out)e(o)n(v)n -(erhead)0 1378 y(w)n(ould)c(increase)f(directly)i(with)g(n)n(um)n(b)r -(er)f(of)h(snapshots.)35 b(Exception)26 b(table)f(up)r(date)h(o)n(v)n -(erhead)d(w)n(ould)j(increase)e(rapidly)0 1478 y(as)j(w)n(ell,)g -(though)h(the)g(exact)f(rate)f(is)i(harder)e(to)i(c)n(haracterize)d(b)r -(ecause)i(it)h(dep)r(ends)g(on)f(the)h(c)n(h)n(unk)f(sharing)f -(patterns.)0 1677 y(With)j(the)f(maxim)n(um)f(n)n(um)n(b)r(er)h(of)f -(snapshots)g(held)h((64))f(the)h(new)g(design)f(should)h(p)r(erform)f -(b)r(etter)h(than)g(the)g(old)f(one)0 1777 y(b)n(y)36 -b(a)g(factor)f(of)h(thirt)n(y)g(or)f(more.)62 b(F)-7 -b(urthermore,)37 b(some)f(fairly)f(straigh)n(tforw)n(ard)e(impro)n(v)n -(emen)n(ts)i(to)h(the)g(btree)g(leaf)0 1876 y(format)30 -b(can)g(mak)n(e)f(the)i(slop)r(e)f(m)n(uc)n(h)g(shallo)n(w)n(er,)f(to)i -(the)f(p)r(oin)n(t)h(where)f(the)h(o)n(v)n(erhead)d(of)i(holding)g(64)g -(snapshots)f(ma)n(y)0 1976 y(b)r(e)f(hard)f(to)g(notice.)0 -2175 y(With)e(a)f(single)f(snapshot)g(held,)j(the)e(new)g(design)g(not) -g(p)r(erform)f(quite)i(as)e(w)n(ell)h(as)f(the)i(existing)e -(device-mapp)r(er)h(design,)0 2275 y(but)29 b(only)e(b)r(ecause)h(the)g -(existing)g(design)f(do)r(es)h(not)g(pro)n(vide)f(durable)g(recording)f -(of)i(snapshot)f(store)g(up)r(dates.)39 b(In)28 b(an)n(y)0 -2374 y(case,)f(the)i(o)n(v)n(erhead)d(of)i(the)g(durable)g(snapshot)f -(recording)f(is)i(exp)r(ected)h(to)f(b)r(e)g(only)g(ab)r(out)g(2\045)g -(w)n(orst-case)d(o)n(v)n(erhead)0 2474 y(vs)g(ra)n(w)f(writing,)h(far)g -(less)g(than)g(the)g(200\045)f(w)n(orst-case)f(o)n(v)n(erhead)g(of)i -(cop)n(y-outs)f(when)h(a)g(single)g(snapshot)f(is)h(held,)h(and)0 -2574 y(shrinks)i(roughly)g(linearly)h(with)g(the)h(c)n(h)n(unk)e(size)h -((extra)g(seeking)f(in)i(the)f(metadata)g(region)f(mak)n(es)g(this)h -(relationship)0 2673 y(sligh)n(tly)f(more)f(complex).)39 -b(So)29 b(b)n(y)f(using)g(a)g(256K)e(c)n(h)n(unk)i(size,)h(metadata)e -(up)r(date)i(can)f(most)g(lik)n(ely)g(b)r(e)h(held)g(to)f(a)g(few)0 -2773 y(p)r(ercen)n(t)f(of)h(\034rst-time)f(write)h(o)n(v)n(erhead)d(ev) -n(en)i(when)h(the)g(maxim)n(um)f(n)n(um)n(b)r(er)g(of)h(snapshots)e -(are)h(held.)0 3105 y Fg(10.5)112 b(Origin)36 b(Read)i(P)m(erformance)0 -3358 y Ff(Origin)21 b(reads)h(are)g(passed)f(straigh)n(t)h(through)f -(to)i(the)g(underlying)f(v)n(olume.)34 b(Since)23 b(the)g(o)n(v)n -(erhead)e(of)h(the)h(device)f(mapp)r(er)0 3457 y(handling)27 -b(is)h(insigni\034can)n(t,)f(origin)f(read)h(p)r(erformance)f(is)i -(essen)n(tially)e(unc)n(hanged)0 3789 y Fg(10.6)112 b(Sequen)m(tial)37 -b(Origin)f(W)-9 b(rite)35 b(P)m(erformance)0 4042 y Ff(Origin)k(write)g -(throughput)h(is)f(a\033ected)h(mainly)f(b)n(y)h(the)g(frequency)f(of)h -(c)n(h)n(unk)f(cop)n(y-outs)f(and)i(metadata)f(up)r(date)0 -4142 y(o)n(v)n(erhead.)45 b(Cop)n(y-outs)30 b(require)g(reading)g(and)h -(writing,)g(requiring)f(a)h(minim)n(um)g(of)h(200\045)d(additional)i -(bandwidth)g(vs)0 4242 y(ra)n(w)26 b(write)h(and)g(additional)f -(seeking)g(as)h(w)n(ell,)g(esp)r(ecially)f(for)h(the)g(single-spindle)g -(case)f(where)g(the)i(origin)e(v)n(olume)g(and)0 4341 -y(snapshot)21 b(store)g(will)i(b)r(e)f(far)g(apart.)34 -b(Throughput)21 b(is)h(impro)n(v)n(ed)f(at)h(the)g(exp)r(ense)g(of)g -(latency)g(b)n(y)g(batc)n(hing)f(the)h(cop)n(y-out)0 -4441 y(reads)30 b(and)h(cop)n(y-out)e(writes,)j(whic)n(h)f(happ)r(ens)g -(naturally)f(with)h(async)n(hronous)e(IO.)h(There)h(will)g(th)n(us)g(b) -r(e)g(few)n(er)g(long)0 4540 y(seeks)c(b)r(et)n(w)n(een)g(the)h(origin) -f(and)g(snapshot)g(store.)0 4740 y(W)-7 b(orst)20 b(case)f(origin)g -(write)h(p)r(erformance)f(is)h(obtained)g(when)g(the)h(snapshot)e -(store)g(is)h(created)g(with)g(the)h(smallest)e(p)r(ossible)0 -4839 y(c)n(h)n(unk)25 b(size)g((4K))g(and)h(the)g(load)f(requires)f -(a)h(cop)n(y-out)f(for)h(ev)n(ery)f(c)n(h)n(unk)h(write.)36 -b(Suc)n(h)26 b(a)f(load)g(is)g(easy)g(to)g(generate,)g(for)0 -4939 y(example)30 b(b)n(y)g(setting)g(a)f(snapshot)h(and)g(then)h -(immediately)f(unpac)n(king)f(an)h(arc)n(hiv)n(e)e(in)n(to)i(the)h(v)n -(olume.)44 b(Required)29 b(IO)0 5039 y(bandwidth)f(will)g(triple,)h -(seeking)e(b)r(et)n(w)n(een)g(the)i(origin)d(and)i(snapshot)f(store)g -(will)h(increase,)f(and)h(metadata)f(up)r(dating)0 5138 -y(will)34 b(increase.)53 b(W)-7 b(riting)34 b(in)f(this)h(case)f -(should)g(b)r(e)h(largely)e(linear)g(and)i(batc)n(hing)f(amortizes)f -(the)i(seeking)e(o)n(v)n(erhead,)0 5238 y(so)g(the)h(dominan)n(t)g -(e\033ect)g(is)g(exp)r(ected)g(to)g(b)r(e)g(the)g(increased)f(IO)g -(bandwidth.)54 b(F)-7 b(or)32 b(this)h(load)f(w)n(e)h(should)f(exp)r -(ect)h(to)0 5337 y(see)g(a)h(3)f(times)h(slo)n(wdo)n(wn)e(v)n(ersus)h -(ra)n(w)f(v)n(olume)h(access.)54 b(F)-7 b(ragmen)n(tation)33 -b(of)g(the)i(snapshot)e(store)f(could)i(mak)n(e)f(this)p -eop end -%%Page: 17 17 -TeXDict begin 17 16 bop 0 83 a Ff(considerably)26 b(w)n(orse,)g(p)r -(erhaps)h(b)n(y)g(another)g(factor)f(of)i(three.)0 282 -y(Since)c(suc)n(h)g(a)f(load)g(is)h(easy)f(to)g(generate)g(it)h(is)g(w) -n(orrisome.)33 b(It)25 b(is)e(p)r(ossible)h(that)g(in)g(the)g(long)f -(run,)i(general)d(p)r(erformance)0 382 y(for)27 b(a)g(snapshot)g(v)n -(olume)g(could)g(b)r(ecome)h(b)r(etter)g(than)f(for)g(the)h(origin,)f -(see)g(b)r(elo)n(w.)0 581 y(F)-7 b(ragmen)n(tation)24 -b(of)i(the)h(snapshot)e(store)g(will)h(in)n(tro)r(duce)f(additional)g -(seeking)g(and)h(rotational)e(latency)i(p)r(enalties.)36 -b(Re-)0 681 y(ducing)21 b(suc)n(h)g(fragmen)n(tation)f(b)n(y)h(clev)n -(er)f(snapshot)h(store)f(allo)r(cation)g(p)r(olicy)h(will)h(yield)f -(signi\034can)n(t)g(p)r(erformance)f(gains,)0 780 y(ho)n(w)n(ev)n(er)32 -b(suc)n(h)h(allo)r(cation)g(p)r(olicy)h(impro)n(v)n(emen)n(ts)e -(require)h(considerable)f(time)i(to)g(dev)n(elop.)55 -b(A)34 b(highly)g(fragmen)n(ted)0 880 y(snapshot)k(store)f(could)i -(aggra)n(v)-5 b(ate)36 b(w)n(orst)h(case)h(write)g(p)r(erformance)f(b)n -(y)i(an)f(additional)g(factor)g(of)g(a)g(few)h(h)n(undred)0 -980 y(p)r(ercen)n(t.)0 1312 y Fg(10.7)112 b(Random)38 -b(Origin)d(W)-9 b(rite)36 b(P)m(erformance)0 1565 y Ff(A)28 -b(load)f(that)h(consists)f(of)g(100\045)g(single-sector)e(writes)i -(distributed)h(randomly)f(o)n(v)n(er)f(the)i(en)n(tire)f(v)n(olume)g -(immediately)0 1664 y(after)22 b(setting)h(a)f(snapshot)g(will)h(cause) -e(cop)n(y-out)h(bandwidth)h(to)f(b)r(e)h(m)n(uc)n(h)g(more)e(than)i -(200\045)e(of)i(ra)n(w)e(write)i(bandwidth,)0 1764 y(and)33 -b(will)h(also)f(cause)g(a)g(great)g(deal)g(of)h(additional)f(seeking.) -54 b(Metadata)33 b(o)n(v)n(erhead)e(will)j(also)f(increase)f -(signi\034can)n(tly)0 1863 y(since)g(t)n(ypically)f(only)h(a)f(single)h -(c)n(h)n(unk)g(on)f(eac)n(h)g(leaf)h(no)r(de)g(will)h(b)r(e)f(up)r -(dated)h(eac)n(h)e(time)h(the)h(no)r(de)f(is)g(journalled)f(to)0 -1963 y(disk;)d(rotational)e(latency)i(will)g(increase)e(signi\034can)n -(tly)h(during)h(metadata)f(access.)37 b(P)n(erformance)26 -b(under)i(this)g(random)0 2063 y(load)33 b(will)h(t)n(ypically)f(b)r(e) -h(dominated)g(b)n(y)f(seeking)g(rather)g(than)h(bandwidth.)56 -b(Analysis)33 b(is)h(complex,)g(ho)n(w)n(ev)n(er)e(I)i(will)0 -2162 y(sp)r(eculate)c(no)n(w)f(that)h(the)g(p)r(erformance)f(of)h(the)g -(snapshotted)g(v)n(olume)f(could)g(degrade)g(b)n(y)g(a)h(factor)f(of)h -(3)f(to)h(4)g(v)n(ersus)0 2262 y(the)e(ra)n(w)e(v)n(olume)h(due)h(to)f -(additional)g(seeking)g(and)g(rotational)f(latency)i(for)f(cop)n -(y-outs)f(and)h(metadata)g(up)r(dating.)0 2461 y(F)-7 -b(ragmen)n(tation)33 b(of)i(the)h(snapshot)e(store)g(can)g(and)h -(should)g(b)r(e)g(addressed)f(o)n(v)n(er)f(time.)60 b(F)-7 -b(or)34 b(origin)g(writes,)i(nothing)0 2561 y(that)30 -b(can)g(b)r(e)h(done)e(ab)r(out)h(the)h(cop)n(y-out)e(o)n(v)n(erhead.) -42 b(Snapshot)29 b(writes)h(on)g(the)g(other)g(hand)g(do)g(not)g(incur) -f(cop)n(y-out)0 2660 y(o)n(v)n(erhead.)41 b(They)29 b(do)g(incur)h -(seeking)e(and)i(rotational)e(p)r(enalties)h(due)h(to)g(fragmen)n -(tation)e(in)i(the)g(snapshot)e(store,)h(but)0 2760 y(so)34 -b(do)g(origin)f(writes.)57 b(F)-7 b(urthermore)33 b(snapshot)g(reads)h -(also)f(su\033er)h(from)g(fragmen)n(tation)f(p)r(enalties)h(whereas)f -(origin)0 2860 y(reads)g(do)g(not.)56 b(V)-7 b(ery)33 -b(go)r(o)r(d)g(snapshot)g(store)g(la)n(y)n(out)f(optimization)i(could)f -(reduce)h(b)r(oth)g(the)g(p)r(enalt)n(y)g(for)f(snapshot)0 -2959 y(reading)e(and)h(writing,)i(in)e(whic)n(h)h(case)e(general)g(p)r -(erformance)h(on)g(a)g(snapshot)f(v)n(olume)h(could)g(b)r(e)h(b)r -(etter)g(than)f(on)g(a)0 3059 y(snapshotted)27 b(origin)f(v)n(olume.)37 -b(Whether)27 b(this)h(can)f(b)r(e)h(realized)f(in)h(practice)f(remains) -f(to)i(b)r(e)g(seen.)0 3391 y Fg(10.8)112 b(Snapshot)39 -b(Read)f(P)m(erformance)0 3644 y Ff(Unlik)n(e)29 b(origin)f(reads,)g -(snapshot)h(read)f(throughput)h(is)g(a\033ected)g(b)n(y)g(snapshot)f -(store)g(fragmen)n(tation.)40 b(Snapshot)29 b(read)0 -3743 y(latency)k(is)g(increased)f(b)n(y)h(the)h(requiremen)n(t)f(of)g -(lo)r(c)n(king)f(against)g(origin)h(writes.)53 b(Read-ahead)32 -b(results)h(in)h(a)f(kind)g(of)0 3843 y(lo)r(c)n(k-ahead,)39 -b(so)f(under)g(loads)f(where)g(read-ahead)f(is)i(e\033ectiv)n(e,)j -(increased)c(snapshot)h(read)f(latency)h(will)g(not)g(h)n(urt)0 -3943 y(read)30 b(throughput.)45 b(The)31 b(predominan)n(t)f(visible)g -(e\033ect)h(is)g(exp)r(ected)f(to)h(b)r(e)g(read)f(fragmen)n(tation.)44 -b(With)31 b(large)f(c)n(h)n(unk)0 4042 y(sizes,)36 b(e.g.,)h(256K)c -(and)i(up,)i(mo)r(derate)d(fragmen)n(tation)g(should)h(cause)f(only)h -(sligh)n(t)f(degradation)f(in)j(snapshot)e(read)0 4142 -y(p)r(erformance.)i(Ho)n(w)n(ev)n(er,)26 b(without)i(sp)r(ecial)g -(atten)n(tion)f(to)h(snapshot)f(store)g(allo)r(cation)f(p)r(olicy)-7 -b(,)28 b(fragmen)n(tation)e(can)i(b)r(e)0 4242 y(exp)r(ected)g(to)f(b)r -(e)g(fairly)g(sev)n(ere,)f(so)g(snapshot)h(read)f(p)r(erformance)g(is)h -(not)h(exp)r(ected)f(to)g(b)r(e)h(stellar)e(in)i(early)e(implemen-)0 -4341 y(tations.)47 b(F)-7 b(ortunately)g(,)32 b(since)f(the)h(main)f -(purp)r(ose)g(of)g(reading)f(from)h(a)g(snapshot)f(is)h(to)g(bac)n(k)g -(it)g(up)h(or)e(restore)g(a)h(few)0 4441 y(\034les,)d(some)e(read)h(p)r -(erformance)g(degradation)e(is)j(acceptable)f(and)g(is)g(unlik)n(ely)h -(to)f(b)r(e)h(noticed.)0 4640 y(In)d(the)g(long)f(run)h(it)g(is)f -(desirable)g(to)h(impro)n(v)n(e)e(snapshot)h(read)g(p)r(erformance)f(b) -n(y)i(con)n(trolling)e(snapshot)h(store)f(fragmen-)0 -4740 y(tation)30 b(as)f(m)n(uc)n(h)h(as)f(p)r(ossible,)h(in)g(order)f -(to)g(tak)n(e)h(adv)-5 b(an)n(tage)28 b(of)i(the)g(inheren)n(tly)g(sup) -r(erior)e(p)r(erformance)h(of)h(snapshot)0 4839 y(writing)d(v)n(ersus)f -(origin)h(writing.)p eop end -%%Page: 18 18 -TeXDict begin 18 17 bop 0 83 a Fg(10.9)112 b(Snapshot)39 -b(W)-9 b(rite)35 b(P)m(erformance)0 336 y Ff(Snapshot)e(writes)g(to)g -(not)g(require)f(cop)n(y-outs;)j(if)e(an)g(origin)g(c)n(h)n(unk)f(or)h -(shared)f(snapshot)g(store)h(c)n(h)n(unk)f(needs)i(to)f(b)r(e)0 -436 y(written,)d(the)f(logical)f(c)n(h)n(unk)g(is)h(\034rst)g(remapp)r -(ed)g(to)g(a)f(new)h(c)n(h)n(unk)g(in)g(the)h(snapshot)e(store.)40 -b(With)30 b(some)f(t)n(w)n(eaking)e(of)0 535 y(the)d(message)f(proto)r -(col,)g(writing)h(to)f(the)i(c)n(h)n(unk)e(could)h(pro)r(ceed)f(as)g -(so)r(on)g(as)g(the)i(new)f(allo)r(cation)e(is)i(kno)n(wn,)g(in)g -(parallel)0 635 y(with)k(the)g(logging)e(of)h(the)h(new)g(exception.)36 -b(So)28 b(snapshot)f(writes)g(are)f(inheren)n(tly)h(quite)h(e\036cien)n -(t.)0 834 y(Snapshot)34 b(write)f(o)n(v)n(erhead)f(comes)h(from)h -(metadata)f(up)r(date)i(o)n(v)n(erhead)c(and)j(snapshot)f(store)g -(fragmen)n(tation.)55 b(The)0 934 y(former)25 b(is)h(supp)r(osed)g(to)f -(b)r(e)i(small,)f(on)f(the)i(order)d(of)i(a)g(few)g(p)r(ercen)n(t.)36 -b(The)26 b(latter)g(could)f(b)r(e)i(v)n(ery)e(large,)g(and)g(probably)0 -1033 y(will)32 b(b)r(e)g(in)g(initial)h(implemen)n(tation,)g(p)r -(erhaps)e(on)g(the)i(order)d(of)i(a)f(factor)g(of)h(10.)49 -b(Larger)30 b(c)n(h)n(unk)h(sizes)g(will)h(reduced)0 -1133 y(this)d(seeking)f(o)n(v)n(erhead,)f(roughly)h(linearly)g(with)h -(the)g(c)n(h)n(unk)g(size.)40 b(Careful)28 b(la)n(y)n(out)g -(optimization)g(could)h(conceiv)-5 b(ably)0 1233 y(reduce)27 -b(this)h(to)f(a)h(few)f(p)r(ercen)n(t,)h(ev)n(en)f(with)h(small)f(c)n -(h)n(unks.)36 b(W)-7 b(e)28 b(shall)f(see.)0 1565 y Fg(10.10)112 -b(Net)m(w)m(ork)37 b(P)m(erformance)0 1817 y Ff(The)24 -b(amoun)n(t)f(of)h(message)e(data)h(needed)h(for)f(eac)n(h)g(c)n(h)n -(unk)h(is)f(small,)i(esp)r(ecially)e(since)g(the)h(message)f(format)g -(is)h(designed)0 1917 y(from)f(the)h(outset)g(to)g(handle)f(ranges)f -(of)i(c)n(h)n(unks)f(and)h(m)n(ultiple)g(ranges)e(in)i(eac)n(h)f -(message.)34 b(Except)24 b(for)f(snapshot)g(reads,)0 -2017 y(eac)n(h)h(message)f(sequence)i(is)f(only)h(t)n(w)n(o)f(messages) -f(long)h((note:)36 b(appro)n(ximately)-7 b(.)34 b(Serv)n(er)23 -b(resp)r(onses)g(do)i(not)g(corresp)r(ond)0 2116 y(exactly)g(requests;) -h(e.g.,)g(an)n(y)g(unshared)f(c)n(h)n(unks)h(can)f(b)r(e)i(ac)n(kno)n -(wledged)d(immediately).)37 b(Message)24 b(tra\036c)i(is)g(exp)r -(ected)0 2216 y(to)21 b(b)r(e)h(less)f(than)h(1\045)f(of)h(disk)f(arra) -n(y)e(tra\036c.)35 b(Assuming)21 b(that)h(the)g(general)e(purp)r(ose)h -(net)n(w)n(ork)f(in)n(terconnect)h(and)g(storage)0 2316 -y(arra)n(y)30 b(in)n(terconnect)i(ha)n(v)n(e)g(similar)g(bandwidth,)i -(this)f(is)g(where)f(the)h(exp)r(ectation)g(that)g(this)g(arc)n -(hitecture)e(will)i(scale)0 2415 y(linearly)27 b(to)g(ab)r(out)h(100)e -(clien)n(ts)h(comes)g(from.)0 2747 y Fg(10.11)112 b(Ov)m(erall)36 -b(P)m(erformance)0 3000 y Ff(It)19 b(is)f(exp)r(ected)h(that)g(t)n -(ypical)f(usage)f(of)h(a)g(snapshotted)g(origin)g(v)n(olume)f(will)i -(sho)n(w)f(only)g(sligh)n(t)g(reduction)g(of)g(p)r(erformance)0 -3100 y(v)n(ersus)39 b(the)j(ra)n(w)d(origin)h(v)n(olume,)k(due)d(to)f -(reading)g(b)r(eing)h(more)f(common)g(than)h(writing.)77 -b(Rewriting)40 b(c)n(h)n(unks)g(is)0 3199 y(optimized)26 -b(b)n(y)f(the)h(clien)n(t's)g(bitmap)g(cac)n(he,)f(whic)n(h)h(is)g -(compact)f(and)g(probably)g(capable)g(of)g(cac)n(hing)g(all)g(the)i -(hot)e(sp)r(ots)0 3299 y(of)g(a)f(v)n(olume,)g(ev)n(en)g(for)g(large)f -(v)n(olumes.)35 b(So)24 b(rewriting)g(should)g(sho)n(w)g(no)n(w)g -(visible)g(degradation.)34 b(The)25 b(p)r(erformance)e(of)0 -3399 y(fresh)29 b(writes)f(to)h(snapshotted)g(c)n(h)n(unks)f(will)i -(degrade)d(signi\034can)n(tly)-7 b(,)29 b(due)g(to)g(cop)n(y-out)f -(bandwidth,)i(and)f(to)g(snapshot)0 3498 y(store)f(fragmen)n(tation,)f -(that)i(latter)g(b)r(eing)g(sub)5 b(ject)28 b(to)h(optimization)f -(while)h(the)g(former)f(is)h(una)n(v)n(oidable.)39 b(In)28 -b(general,)0 3598 y(more)g(frequen)n(t)h(snapshots)f(cause)g(more)h -(fresh)g(writes,)g(with)g(the)h(frequency)e(of)h(fresh)g(writes)g(p)r -(eaking)f(just)i(after)f(the)0 3697 y(snapshot)e(and)g(declining)h(o)n -(v)n(er)d(time,)j(till)h(the)f(next)f(snapshot.)0 3897 -y(So:)52 b(what)35 b(will)h(b)r(e)f(the)h(balance)f(of)g(fresh)g -(writes)g(vs)g(reads)f(and)h(rewrites?)59 b(Ho)n(w)35 -b(frequen)n(tly)g(will)g(w)n(e)g(see)g(will)g(w)n(e)0 -3996 y(see)29 b(the)h(balance)f(shift)h(for)f(a)g(short)g(time)h(in)g -(the)g(direction)f(of)g(the)h(w)n(orst)e(case?)43 b(Ho)n(w)29 -b(bad)g(is)g(the)h(w)n(orst)f(case?)42 b(Ho)n(w)0 4096 -y(lik)n(ely)24 b(is)g(it)h(that)g(the)g(user)f(will)g(notice)h(the)f -(shifts)h(in)g(write)f(p)r(erformance?)35 b(These)24 -b(all)g(a)n(w)n(ait)g(measuremen)n(t)f(under)h(liv)n(e)0 -4196 y(loads.)36 b(Ho)n(w)n(ev)n(er)26 b(at)i(this)g(p)r(oin)n(t)g(I)f -(will)h(sp)r(eculate)g(that)g(ev)n(en)f(a)h(relativ)n(ely)e(early)h -(implemen)n(tation)g(will)h(sho)n(w)f(a)n(v)n(erage)0 -4295 y(p)r(erformance)33 b(degradation)g(v)n(ersus)g(a)h(ra)n(w)g(v)n -(olume)g(of)g(less)g(than)h(ten)g(p)r(ercen)n(t,)h(and)e(that,)j(at)d -(w)n(orst,)h(p)r(erformance)0 4395 y(degradation)25 b(will)i(b)r(e)g -(limited)g(to)g(a)f(factor)g(of)g(four)h(or)e(so)h(just)i(after)e(a)g -(snapshot.)36 b(F)-7 b(or)26 b(man)n(y)g(users,)g(and)h(particularly)0 -4494 y(en)n(terprise)19 b(users,)h(the)g(b)r(ene\034ts)h(of)f -(snapshotting)f(will)h(out)n(w)n(eigh)f(the)h(p)r(erformance)f(loss:)32 -b(it)20 b(is)g(easy)f(to)h(buy)g(bandwidth,)0 4594 y(not)32 -b(as)e(easy)h(to)g(buy)h(liv)n(e)f(bac)n(kup)g(capabilit)n(y)-7 -b(.)48 b(F)-7 b(or)31 b(others,)h(the)g(una)n(v)n(oidable)e(p)r -(erformance)g(degradation)g(of)h(origin)0 4694 y(writing)h(will)h(mak)n -(e)f(snapshotting)f(unattractiv)n(e)h(enough)g(to)g(discourage)f(its)h -(use.)52 b(Ev)n(en)n(tually)32 b(w)n(e)g(ma)n(y)g(b)r(e)h(able)f(to)0 -4793 y(satisfy)d(this)h(group)e(as)h(w)n(ell,)h(b)n(y)f(impro)n(ving)f -(snapshot)h(store)g(allo)r(cation)f(p)r(olicy)h(to)h(the)g(p)r(oin)n(t) -f(where)g(the)h(origin)e(can)0 4893 y(b)r(e)g(made)f(optional)g(and)g -(all)h(IO)f(tak)n(e)g(place)g(in)h(the)g(snapshot)e(store.)0 -5092 y(The)38 b(p)r(essimism)h(in)f(this)h(section)f(should)g(b)r(e)h -(temp)r(ered)f(b)n(y)g(observing)f(that)h(in)h(man)n(y)f(resp)r(ects,)i -(p)r(erformance)d(is)0 5192 y(exp)r(ected)28 b(to)f(b)r(e)h(go)r(o)r -(d:)p eop end -%%Page: 19 19 -TeXDict begin 19 18 bop 138 83 a Fe(\001)42 b Ff(Large)25 -b(n)n(um)n(b)r(er)j(of)f(snapshots)g(can)g(b)r(e)h(held)g(without)g -(a\033ecting)f(p)r(erformance)f(m)n(uc)n(h)138 249 y -Fe(\001)42 b Ff(Snapshot)27 b(store)f(utilization)i(is)f(go)r(o)r(d)138 -415 y Fe(\001)42 b Ff(Net)n(w)n(ork)26 b(tra\036c)h(is)g(minimal)138 -581 y Fe(\001)42 b Ff(Rewrites)27 b(are)f(highly)i(optimized)0 -863 y(In)e(other)e(w)n(ords,)h(if)h(y)n(ou)f(need)g(snapshots)f(then)i -(this)g(implemen)n(tation)f(is)h(lik)n(ely)f(to)g(deliv)n(er)f(go)r(o)r -(d)h(p)r(erformance)g(v)n(ersus)0 963 y(alternativ)n(es.)35 -b(Plus)26 b(there)g(is)f(a)h(clear)f(path)h(forw)n(ard)e(to)h(ac)n -(hieving)g(near-optimal)f(p)r(erformance,)h(b)n(y)h(w)n(orking)e(to)n -(w)n(ards)0 1063 y(a)j(system)g(where)g(the)h(snapshot)f(store)g(can)g -(b)r(e)h(used)f(e\033ectiv)n(ely)h(alone,)f(with)h(no)f(origin)f(v)n -(olume.)0 1437 y Fh(11)131 b(F)-11 b(urther)44 b(W)-11 -b(ork)0 1735 y Fg(11.1)112 b(P)m(arallelizing)34 b(the)j(Arc)m -(hitecture)0 1988 y Ff(Normally)f(the)h(\034rst)f(question)g(I)h(am)f -(ask)n(ed)g(ab)r(out)g(this)h(clustered)f(snapshot)g(design)g(is)h(wh)n -(y)f(isn't)h(it)g(symmetric?)0 2087 y(The)32 b(answ)n(er:)45 -b(b)r(ecause)31 b(a))h(it)h(do)r(esn't)f(ha)n(v)n(e)f(to)h(b)r(e)h(in) -f(order)f(to)h(p)r(erform)g(w)n(ell)f(on)h(to)r(da)n(y's)g(t)n(ypical)f -(clusters)h(and)g(b))0 2187 y(distributing)h(a)f(tree)h(structure)f -(across)f(indep)r(enden)n(t)i(cac)n(hes)f(is)h(a)f(complex,)i -(error-prone)29 b(pro)r(cess,)k(and)g(in)n(tro)r(duces)0 -2287 y(o)n(v)n(erhead)25 b(of)j(its)g(o)n(wn.)36 b(A)n(t)28 -b(some)f(p)r(oin)n(t,)h(ho)n(w)n(ev)n(er,)d(the)j(single)f(no)r(de)h -(serv)n(er)d(arc)n(hitecture)i(will)h(b)r(ecome)f(a)g(b)r(ottlenec)n -(k,)0 2386 y(so)g(I)h(discuss)f(parallelizing)f(strategies)g(here.)0 -2585 y(The)32 b(easiest)f(thing)h(w)n(e)f(can)h(do,)g(and)g(with)g(the) -h(strongest)d(immediate)i(e\033ect)g(is)g(to)g(ha)n(v)n(e)e(the)j(serv) -n(er)d(distribute)i(the)0 2685 y(cop)n(y-out)26 b(w)n(ork)g(to)h -(underused)g(no)r(des.)37 b(This)27 b(will)h(tak)n(e)e(signi\034can)n -(t)h(IO)g(bandwidth)h(load)f(o\033)g(the)h(serv)n(er's)d(bus)i(at)h -(the)0 2785 y(exp)r(ense)g(of)f(a)h(little)g(messaging)e(latency)-7 -b(.)37 b(By)27 b(doing)g(this,)h(a)g(single)f(serv)n(er)f(can)h(lik)n -(ely)g(scale)g(to)h(handle)f(a)h(h)n(undred)f(or)0 2884 -y(so)f(busy)g(no)r(des)h(of)f(similar)g(p)r(o)n(w)n(er)f(to)i(itself:) -37 b(the)27 b(real)e(b)r(ottlenec)n(k)i(will)f(probably)g(b)r(e)h(the)g -(storage)d(arra)n(y)-7 b(.)35 b(A)27 b(user)e(who)0 2984 -y(can)e(a\033ord)g(to)h(upgrade)f(the)h(storage)e(arra)n(y)f(to)j -(handle)g(ev)n(en)f(larger)f(n)n(um)n(b)r(ers)h(of)h(clien)n(ts)g(can)f -(lik)n(ely)h(a\033ord)f(to)g(upgrade)0 3084 y(the)28 -b(snapshot)f(serv)n(er)e(as)i(w)n(ell.)0 3283 y(A)n(t)39 -b(some)e(p)r(oin)n(t,)k(p)r(erhaps)d(t)n(w)n(o)f(or)h(three)g(h)n -(undred)f(clien)n(ts,)k(the)e(snapshot)e(serv)n(er)g(b)r(ecomes)g(a)h -(b)r(ottlenec)n(k)g(again.)0 3383 y(F)-7 b(urther)26 -b(scaling)f(is)g(easily)g(ac)n(hiev)n(ed)g(b)n(y)h(dividing)g(up)g(the) -g(w)n(ork)f(b)r(et)n(w)n(een)g(a)h(n)n(um)n(b)r(er)g(of)f(snapshot)h -(serv)n(ers,)e(b)n(y)h(logical)0 3482 y(address)g(range.)36 -b(Eac)n(h)26 b(snapshot)g(serv)n(er)f(main)n(tains)h(a)g(separate)f -(btree)i(in)f(a)h(distinct)g(range)e(of)i(logical)e(addresses)g(and)0 -3582 y(op)r(erates)31 b(its)i(o)n(wn)f(journal.)50 b(Care)32 -b(m)n(ust)g(b)r(e)h(tak)n(en)f(that)g(allo)r(cation)g(bitmaps)g(are)f -(divided)i(up)g(cleanly;)h(this)f(is)f(not)0 3681 y(hard)j((e.g.,)i -(ev)n(en)e(if)h(a)f(logical)f(address)g(range)g(b)r(oundary)g(lies)h -(in)h(the)g(middle)f(of)h(a)f(bitmap)g(blo)r(c)n(k,)i(the)f(b)r -(oundary)0 3781 y(bitmap)24 b(can)f(b)r(e)g(replicated)g(b)r(et)n(w)n -(een)g(t)n(w)n(o)g(no)r(des,)h(with)f(logic)g(to)g(prev)n(en)n(t)f -(allo)r(cation)h(outside)g(the)g(b)r(oundary)g(-)g(needed)0 -3881 y(an)n(yw)n(a)n(y)g(for)i(error)e(c)n(hec)n(king).)35 -b(Shared)25 b(metadata)f(suc)n(h)h(as)g(the)h(curren)n(t)e(snapshot)g -(list,)i(sup)r(erblo)r(c)n(k,)f(etc.,)h(is)g(up)r(dated)0 -3980 y(using)k(a)h(R)-9 b(W)31 b(lo)r(c)n(king)f(strategy)f((i.e.,)j -(using)e(a)h(DLM).)g(Assuming)g(that)g(w)n(orkload)e(is)h(distributed) -h(relativ)n(ely)f(ev)n(enly)0 4080 y(across)f(the)i(logical)e(address)g -(range,)h(this)h(simple)g(parallelization)e(strategy)g(will)i(serv)n(e) -e(up)i(to)g(a)f(thousand)h(clien)n(ts)f(or)0 4180 y(so,)d(and)g(the)h -(disk)g(will)f(once)h(again)e(b)r(e)i(the)g(b)r(ottlenec)n(k.)0 -4379 y(If)i(w)n(e)g(w)n(an)n(t)f(to)h(scale)f(to)h(far)g(larger)e(n)n -(um)n(b)r(ers)h(of)h(clien)n(ts)g(w)n(e)g(probably)f(ha)n(v)n(e)f(to)i -(bite)h(the)f(bullet)h(and)e(distribute)i(the)0 4478 -y(btrees)25 b(and)g(allo)r(cation)g(bitmaps.)62 b(Ho)n(w)n(ev)n(er)23 -b(I)j(do)f(not)h(think)g(this)f(problem)g(is)h(imminen)n(t;)h(there)e -(is)g(plen)n(t)n(y)h(of)f(time)h(to)0 4578 y(think)i(ab)r(out)g(it.)0 -4910 y Fg(11.2)112 b(A)m(daptation)37 b(to)g(Single)f(No)s(de)i(Clien)m -(t)0 5163 y Ff(It)25 b(is)g(exp)r(ected)h(that)f(this)g(cluster)g -(snapshot)f(design)h(will)g(ev)n(en)n(tually)f(b)r(e)h(adapted)g(for)f -(single-no)r(de)h(use,)g(replacing)f(the)0 5263 y(curren)n(t)j -(snapshot)f(target,)h(with)h(the)g(follo)n(wing)f(b)r(ene\034ts:)p -eop end -%%Page: 20 20 -TeXDict begin 20 19 bop 138 83 a Fe(\001)42 b Ff(Cop)n(y-out)26 -b(o)n(v)n(erhead)f(will)j(no)f(longer)g(increase)f(linearly)g(with)i(n) -n(um)n(b)r(er)g(of)f(snapshots)g(held)138 249 y Fe(\001)42 -b Ff(Excessiv)n(e)26 b(memory)h(fo)r(otprin)n(t)g(for)g(large)f(v)n -(olumes)h(eliminated)138 415 y Fe(\001)42 b Ff(Clien)n(t)27 -b(cac)n(he)g(memory)g(shrinks)f(in)i(resp)r(onse)f(to)g(memory)g -(pressure)138 581 y Fe(\001)42 b Ff(Only)27 b(one)g(snapshot)g(store)f -(v)n(olume)h(to)h(manage)e(instead)h(of)h(one)f(p)r(er)g(snapshot)138 -747 y Fe(\001)42 b Ff(Sharing)26 b(exceptions)h(b)r(et)n(w)n(een)h -(snapshots)e(sa)n(v)n(es)g(disk)h(space)138 913 y Fe(\001)42 -b Ff(All)28 b(snapshots)e(allo)r(cate)h(disk)g(memory)g(from)g(common)g -(p)r(o)r(ol)138 1079 y Fe(\001)42 b Ff(Just)27 b(one)g(device)g(mapp)r -(er)h(target)e(to)i(kno)n(w)f(ab)r(out)g(instead)g(of)h(t)n(w)n(o)0 -1362 y(When)f(it)g(comes)f(time)h(to)g(tak)n(e)f(this)h(step,)g(a)f -(decision)g(m)n(ust)h(b)r(e)g(tak)n(en)f(whether)g(to)h((lazily))f(k) -n(eep)h(the)g(message-based)0 1461 y(in)n(terface)g(and)g(clien)n -(t-serv)n(er)e(factoring,)i(or)g(to)g(create)f(a)i(v)-5 -b(arian)n(t)26 b(where)h(the)h(serv)n(er)e(logic)g(is)i(in)n(tegrated)e -(directly)h(in)n(to)0 1561 y(the)h(clien)n(t.)0 1935 -y Fh(12)131 b(Conclusion)0 2216 y Ff(Blo)r(c)n(k)36 b(device)h -(snapshots)f(ha)n(v)n(e)g(a)h(n)n(um)n(b)r(er)f(of)h(in)n(teresting)g -(applications,)h(including)f(the)h(crucial)e(one)h(of)g(enabling)0 -2316 y(online)31 b(bac)n(kup)g(for)g(en)n(terprise)g(Lin)n(ux)g(users.) -48 b(With)33 b(the)e(imminen)n(t)i(addition)e(of)h(cluster)f -(\034lesystems)g(to)g(the)h(Lin)n(ux)0 2416 y(k)n(ernel,)f(cluster)f -(snapshot)g(capabilit)n(y)g(is)g(required.)46 b(This)30 -b(presen)n(ts)g(a)h(n)n(um)n(b)r(er)f(of)h(in)n(teresting)f(sync)n -(hronization)e(and)0 2515 y(structural)f(problems,)f(for)i(whic)n(h)f -(original)f(solutions)h(ha)n(v)n(e)f(b)r(een)i(devised)f(and)h(presen)n -(ted)f(in)g(this)h(pap)r(er.)0 2715 y(As)33 b(w)n(ell)h(as)e(extending) -i(snapshot)e(capabilit)n(y)h(to)g(clusters,)h(some)f(problems)g(with)g -(the)h(existing,)h(single)d(no)r(de)i(snap-)0 2814 y(shot)27 -b(design)g(w)n(ere)g(solv)n(ed,)f(yielding)h(signi\034can)n(t)g(impro)n -(v)n(emen)n(ts)f(in)i(IO)f(p)r(erformance,)f(disk)h(space)g -(consumption)g(and)0 2914 y(memory)e(usage.)36 b(A)26 -b(protot)n(yp)r(e)g(implemen)n(tation)g(exhibiting)g(go)r(o)r(d)g(p)r -(erformance)f(c)n(haracteristics)f(has)h(b)r(een)i(created.)0 -3013 y(F)-7 b(urther)22 b(w)n(ork)f(remains)g(to)h(b)r(e)g(done)g(to)g -(transform)f(the)h(protot)n(yp)r(e)g(in)n(to)g(a)f(fully)i(reliable,)f -(fault-toleran)n(t)f(facilit)n(y)h(ready)0 3113 y(to)27 -b(b)r(e)h(deplo)n(y)n(ed)f(in)h(a)f(pro)r(duction)g(en)n(vironmen)n(t.) -p eop end -%%Trailer - -userdict /end-hook known{end-hook}if -%%EOF diff --git a/csnap/list.h b/csnap/list.h deleted file mode 100644 index 8a28deb..0000000 --- a/csnap/list.h +++ /dev/null @@ -1,64 +0,0 @@ -/* List ops from include/linux/list.h */ - -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -struct list_head { struct list_head *next, *prev; }; - -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -static inline void __list_del(struct list_head *prev, struct list_head *next) -{ - next->prev = prev; - prev->next = next; -} - -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - diff --git a/csnap/patches/csnap-2.6.7-2.4.26 b/csnap/patches/csnap-2.6.7-2.4.26 deleted file mode 100644 index 589521e..0000000 --- a/csnap/patches/csnap-2.6.7-2.4.26 +++ /dev/null @@ -1,195 +0,0 @@ ---- /src/2.6.7.csnap/drivers/md/dm-csnap.c 2004-09-03 21:02:24.000000000 +0000 -+++ dm-csnap.c 2004-09-03 21:01:15.000000000 +0000 -@@ -6,7 +6,6 @@ - #include <linux/file.h> - #include <net/sock.h> - #include <asm/uaccess.h> --#include <linux/bio.h> - #include "dm.h" - #include "dm-csnap.h" - -@@ -19,12 +18,22 @@ - - #define trace trace_on - -+#define bio buffer_head -+#define bi_sector b_rsector -+#define bio_end_io_t bh_end_io_t -+#define bi_private b_private -+#define bi_end_io b_end_io -+#define bi_bdev b_rdev -+#define CLONE_KERNEL (CLONE_FS|CLONE_FILES|CLONE_SIGNAL) -+#define SOCKET_I(inode) (&inode->u.socket_i) -+#define bio_data_dir(bio) rw -+#define bi_size b_size -+ - /* Pipe helpers */ - - static int rwpipe(struct file *file, const void *buffer, unsigned int count, -- ssize_t (*op)(struct kiocb *, const char *, size_t, loff_t), int mode) -+ ssize_t (*op)(struct file *, const char *, size_t, loff_t *), int mode) - { -- struct kiocb iocb; - mm_segment_t oldseg; - int err = 0; - -@@ -33,12 +42,10 @@ - return -EBADF; - if (!op) - return -EINVAL; -- init_sync_kiocb(&iocb, file); // new in 2.5 (hmm) -- iocb.ki_pos = file->f_pos; - oldseg = get_fs(); - set_fs(get_ds()); - while (count) { -- int chunk = (*op)(&iocb, buffer, count, iocb.ki_pos); -+ int chunk = (*op)(file, buffer, count, &file->f_pos); - if (chunk <= 0) { - err = chunk? chunk: -EPIPE; - break; -@@ -48,18 +55,17 @@ - buffer += chunk; - } - set_fs(oldseg); -- file->f_pos = iocb.ki_pos; - return err; - } - - static inline int readpipe(struct file *file, void *buffer, unsigned int count) - { -- return rwpipe(file, buffer, count, (void *)file->f_op->aio_read, FMODE_READ); -+ return rwpipe(file, buffer, count, (void *)file->f_op->read, FMODE_READ); - } - - static inline int writepipe(struct file *file, void *buffer, unsigned int count) - { -- return rwpipe(file, buffer, count, file->f_op->aio_write, FMODE_WRITE); -+ return rwpipe(file, buffer, count, file->f_op->write, FMODE_WRITE); - } - - #define outbead(SOCK, CODE, STRUCT, VALUES...) ({ \ -@@ -167,6 +173,7 @@ - u64 chunk; - unsigned chunks; - unsigned id; -+ unsigned rw; - struct bio *bio; - list_t list; - }; -@@ -256,7 +263,7 @@ - list_t list; - }; - --static int snapshot_read_end_io(struct bio *bio, unsigned int done, int error) -+static void snapshot_read_end_io(struct bio *bio, int uptodate) - { - struct end_io_hook *hook = bio->bi_private; - struct snapinfo *info = hook->info; -@@ -269,7 +276,7 @@ - - bio->bi_private = hook->old_private; - bio->bi_end_io = hook->old_end_io; -- return bio->bi_end_io(bio, done, error); -+ bio->bi_end_io(bio, uptodate); - } - - /* This is the part that does all the work. */ -@@ -306,7 +313,7 @@ - if (chunks != pending->chunks) { - warn("Message mismatch, expected %x got %x", chunks, chunks); - kmem_cache_free(pending_cache, pending); -- bio_io_error(bio, bio->bi_size); -+ buffer_IO_error(bio); - return -1; - } - -@@ -317,7 +324,7 @@ - u64 logical = bio->bi_sector; - u64 physical = (*p2++ << shift) + (logical & mask); - trace(warn("logical %Lx = physical %Lx", logical, physical)); -- bio->bi_bdev = info->snapdev->bdev; -+ bio->bi_bdev = info->snapdev->dev; - bio->bi_sector = physical; - } - p = (struct chunk_range *)p2; -@@ -338,7 +345,7 @@ - bio->bi_private = hook; - } - -- generic_make_request(bio); -+ generic_make_request(rw, bio); - submitted++; - #ifdef CACHE - for (j = 0; j < p->chunks; j++) -@@ -347,13 +354,7 @@ - kmem_cache_free(pending_cache, pending); - } - if (submitted){ -- request_queue_t *q; -- q = bdev_get_queue(info->orgdev->bdev); -- if (q->unplug_fn) -- q->unplug_fn(q); -- q = bdev_get_queue(info->snapdev->bdev); -- if (q->unplug_fn) -- q->unplug_fn(q); -+ run_task_queue(&tq_disk); - } - return 0; - } -@@ -582,14 +583,14 @@ - * at the moment, or may not have been established yet, in which case we have - * to defer the request until the server becomes available. - */ --static int csnap_map(struct dm_target *target, struct bio *bio, union map_info *context) -+static int csnap_map(struct dm_target *target, struct bio *bio, int rw, union map_info *context) - { - struct snapinfo *info = target->private; - struct pending *pending; - chunk_t chunk; - unsigned id; - -- bio->bi_bdev = info->orgdev->bdev; -+ bio->bi_bdev = info->orgdev->dev; - if (bio_data_dir(bio) == READ && !is_snapshot(info)) - return 1; - -@@ -625,7 +626,7 @@ - - id = info->nextid; - info->nextid = (id + 1) & ~(-1 << ID_BITS); -- *pending = (struct pending){ .id = id, .bio = bio, .chunk = chunk, .chunks = 1 }; -+ *pending = (struct pending){ .id = id, .bio = bio, .rw = rw, .chunk = chunk, .chunks = 1 }; - spin_lock(&info->pending_lock); - list_add(&pending->list, info->pending_buckets + hash_pending(pending->id)); - spin_unlock(&info->pending_lock); -@@ -787,7 +788,6 @@ - if ((err = kernel_thread((void *)worker, target, CLONE_KERNEL)) < 0) - goto eek; - warn("Created snapshot device origin=%s snapstore=%s snapshot=%i", argv[0], argv[1], snap); -- target->split_io = 1 << info->chunkshift; // !!! lose this as soon as possible - return 0; - - eek: warn("Virtual device create error %i: %s!", err, error); -@@ -828,8 +828,6 @@ - - static int csnap_status(struct dm_target *target, status_type_t type, char *result, unsigned int maxlen) - { -- char orgbuffer[32]; -- char snapbuffer[32]; - struct snapinfo *info = target->private; - - switch (type) { -@@ -838,10 +836,10 @@ - break; - - case STATUSTYPE_TABLE: -- format_dev_t(orgbuffer, info->orgdev->bdev->bd_dev); -- format_dev_t(snapbuffer, info->snapdev->bdev->bd_dev); - snprintf(result, maxlen, "%s %s %u", -- orgbuffer, snapbuffer, 1 << info->chunksize_bits); -+ dm_kdevname(info->orgdev->dev), -+ dm_kdevname(info->snapdev->dev), -+ 1 << info->chunksize_bits); - break; - } - diff --git a/csnap/patches/csnap-2.6.8.1 b/csnap/patches/csnap-2.6.8.1 deleted file mode 100644 index 23c11a9..0000000 --- a/csnap/patches/csnap-2.6.8.1 +++ /dev/null @@ -1,1321 +0,0 @@ -diff -up --recursive 2.6.8.1.csnap.clean/drivers/md/Kconfig 2.6.8.1.csnap/drivers/md/Kconfig ---- 2.6.8.1.csnap.clean/drivers/md/Kconfig 2004-08-14 06:54:50.000000000 -0400 -+++ 2.6.8.1.csnap/drivers/md/Kconfig 2004-10-04 16:39:41.000000000 -0400 -@@ -200,5 +200,15 @@ config DM_ZERO - A target that discards writes, and returns all zeroes for - reads. Useful in some recovery situations. - -+config DM_CSNAP -+ tristate "Cluster snapshot target support" -+ depends on BLK_DEV_DM && EXPERIMENTAL -+ ---help--- -+ This device-mapper target allows you to create a virtual device -+ that can take snapshots of an underlying device. This device -+ can be accessed simultaneously by multiple nodes of a cluster. -+ -+ If unsure, say N. -+ - endmenu - -diff -up --recursive 2.6.8.1.csnap.clean/drivers/md/Makefile 2.6.8.1.csnap/drivers/md/Makefile ---- 2.6.8.1.csnap.clean/drivers/md/Makefile 2004-08-14 06:55:33.000000000 -0400 -+++ 2.6.8.1.csnap/drivers/md/Makefile 2004-10-23 23:43:09.000000000 -0400 -@@ -29,6 +29,8 @@ obj-$(CONFIG_DM_CRYPT) += dm-crypt.o - obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o - obj-$(CONFIG_DM_MIRROR) += dm-mirror.o - obj-$(CONFIG_DM_ZERO) += dm-zero.o -+obj-$(CONFIG_DM_CSNAP) += dm-csnap.o -+obj-$(CONFIG_DM_CSNAP) += dm-cmirror.o - - quiet_cmd_unroll = UNROLL $@ - cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \ -diff -up --recursive 2.6.8.1.csnap.clean/drivers/md/dm-csnap.c 2.6.8.1.csnap/drivers/md/dm-csnap.c ---- 2.6.8.1.csnap.clean/drivers/md/dm-csnap.c 2004-10-14 12:58:07.000000000 -0400 -+++ 2.6.8.1.csnap/drivers/md/dm-csnap.c 2004-12-08 13:13:02.000000000 -0500 -@@ -0,0 +1,1144 @@ -+#include <linux/fs.h> -+#include <linux/slab.h> -+#include <linux/mm.h> -+#include <linux/module.h> -+#include <linux/pagemap.h> -+#include <linux/file.h> -+#include <linux/syscalls.h> // recvmsg -+#include <linux/socket.h> -+#include <linux/un.h> -+#include <net/sock.h> -+#include <asm/uaccess.h> -+#include <linux/bio.h> -+#include "dm.h" -+#include "dm-csnap.h" -+ -+#define BREAK BUG() -+#define warn(string, args...) do { printk("%s: " string "\n", __func__, ##args); } while (0) -+#define error(string, args...) do { warn(string, ##args); BREAK; } while (0) -+#define assert(expr) do { if (!(expr)) error("Assertion " #expr " failed!\n"); } while (0) -+#define trace_on(args) args -+#define trace_off(args) -+ -+#define trace trace_off -+ -+/* -+ * To do: -+ * -+ * - variable length bios -+ * - unique cache -+ * - receive chunk size -+ * - make pending and hook a union -+ * - get rid of multiple ranges per message misfeature -+ * - rationalize sector vs chunk usage in messages -+ * - detect message id wrap -+ * - detect message timeout -+ */ -+ -+/* Useful gizmos */ -+ -+static int rwpipe(struct file *file, const void *buffer, unsigned int count, -+ ssize_t (*op)(struct kiocb *, const char *, size_t, loff_t), int mode) -+{ -+ struct kiocb iocb; -+ mm_segment_t oldseg; -+ int err = 0; -+ -+ trace_off(warn("%s %i bytes", mode == FMODE_READ? "read": "write", count);) -+ if (!(file->f_mode & mode)) -+ return -EBADF; -+ if (!op) -+ return -EINVAL; -+ init_sync_kiocb(&iocb, file); // new in 2.5 (hmm) -+ iocb.ki_pos = file->f_pos; -+ oldseg = get_fs(); -+ set_fs(get_ds()); -+ while (count) { -+ int chunk = (*op)(&iocb, buffer, count, iocb.ki_pos); -+ if (chunk <= 0) { -+ err = chunk? chunk: -EPIPE; -+ break; -+ } -+ BUG_ON(chunk > count); -+ count -= chunk; -+ buffer += chunk; -+ } -+ set_fs(oldseg); -+ file->f_pos = iocb.ki_pos; -+ return err; -+} -+ -+static inline int readpipe(struct file *file, void *buffer, unsigned int count) -+{ -+ return rwpipe(file, buffer, count, (void *)file->f_op->aio_read, FMODE_READ); -+} -+ -+static inline int writepipe(struct file *file, void *buffer, unsigned int count) -+{ -+ return rwpipe(file, buffer, count, file->f_op->aio_write, FMODE_WRITE); -+} -+ -+#define outbead(SOCK, CODE, STRUCT, VALUES...) ({ \ -+ struct { struct head head; STRUCT body; } PACKED message = \ -+ { { CODE, sizeof(STRUCT) }, { VALUES } }; \ -+ writepipe(SOCK, &message, sizeof(message)); }) -+ -+/* -+ * This gets the job done but it sucks as an internal interface: there -+ * is no reason to deal with fds at all, we just want to receive the -+ * (struct file *), we do not want to have to wrap the socket in a -+ * fd just to call recv_fd, and user space pointer for the (bogus) data -+ * payload is just silly. Never mind the danger of triggering some -+ * wierdo signal handling cruft deep in the socket layer. This kind of -+ * posturing - lathering layers of cruft upon cruft - is the stuff -+ * Windows is made of, Linux is not supposed to be like that. Fixing -+ * this requires delving into the SCM_RIGHTS path deep inside sys_recvmsg -+ * and breaking out the part that actually does the work, to be a usable -+ * internal interface. Put it on the list of things to do. -+ */ -+static int recv_fd(int sock, char *bogus, unsigned *len) -+{ -+ char payload[CMSG_SPACE(sizeof(int))]; -+ struct msghdr msg = { -+ .msg_control = payload, -+ .msg_controllen = sizeof(payload), -+ .msg_iov = &(struct iovec){ .iov_base = bogus, .iov_len = *len }, -+ .msg_iovlen = 1, -+ }; -+ mm_segment_t oldseg = get_fs(); -+ struct cmsghdr *cmsg; -+ int result; -+ -+ set_fs(get_ds()); -+ result = sys_recvmsg(sock, &msg, 0); -+ set_fs(oldseg); -+ -+ if (result <= 0) -+ return result; -+ if (!(cmsg = CMSG_FIRSTHDR(&msg))) -+ return -ENODATA; -+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || -+ cmsg->cmsg_level != SOL_SOCKET || -+ cmsg->cmsg_type != SCM_RIGHTS) -+ return -EBADMSG; -+ -+ *len = result; -+ return *((int *)CMSG_DATA(cmsg)); -+} -+ -+static void kick(struct block_device *dev) -+{ -+ request_queue_t *q = bdev_get_queue(dev); -+ if (q->unplug_fn) -+ q->unplug_fn(q); -+} -+ -+/* ...Useful gizmos */ -+ -+typedef u64 chunk_t; -+ -+#define SECTOR_SHIFT 9 -+#define IS_SNAP_FLAG (1 << 0) -+#define REPORT_BIT 1 -+#define RECOVER_FLAG (1 << 2) -+#define FINISH_FLAG (1 << 3) -+#define NUM_BUCKETS 64 -+#define MASK_BUCKETS (NUM_BUCKETS - 1) -+#define ID_BITS 16 -+ -+struct snapinfo { -+ u64 id; -+ unsigned long flags; -+ unsigned chunksize_bits; -+ unsigned chunkshift; -+// sector_t len; -+ int snap, nextid; -+ u32 *shared_bitmap; // !!! get rid of this, use the inode cache -+ struct inode *inode; /* the cache */ -+ struct dm_dev *orgdev; -+ struct dm_dev *snapdev; -+ struct file *sock; -+ struct file *control_socket; -+ struct semaphore server_in_sem; -+ struct semaphore server_out_sem; -+ struct semaphore more_work_sem; -+ struct semaphore recover_sem; -+ struct semaphore exit1_sem; -+ struct semaphore exit2_sem; -+ struct semaphore exit3_sem; -+ struct list_head pending[NUM_BUCKETS]; -+ struct list_head queries; -+ struct list_head releases; -+ struct list_head locked; -+ spinlock_t pending_lock; -+ spinlock_t end_io_lock; -+ int dont_switch_lists; -+}; -+ -+static inline int is_snapshot(struct snapinfo *info) -+{ -+ return !!(info->flags & IS_SNAP_FLAG); -+} -+ -+static inline int running(struct snapinfo *info) -+{ -+ return !(info->flags & FINISH_FLAG); -+} -+ -+static inline int worker_running(struct snapinfo *info) -+{ -+ return !(info->flags & (FINISH_FLAG|RECOVER_FLAG)); -+} -+ -+static void report_error(struct snapinfo *info) -+{ -+ if (test_and_set_bit(REPORT_BIT, &info->flags)) -+ return; -+ up(&info->more_work_sem); -+ down(&info->recover_sem); -+ info->flags |= RECOVER_FLAG; -+} -+ -+/* Static caches, shared by all csnap instances */ -+ -+static kmem_cache_t *pending_cache; -+static kmem_cache_t *end_io_cache; -+static struct super_block *snapshot_super; -+ -+/* We cache query results because we are greedy about speed */ -+ -+#ifdef CACHE -+static u64 *snap_map_cachep(struct address_space *mapping, chunk_t chunk, struct page **p) -+{ -+ u32 page_index; -+ u32 page_pos; -+ struct page *page; -+ u64 *exceptions; -+ -+ page_index = chunk / (PAGE_SIZE / sizeof(u64)); -+ page_pos = chunk % (PAGE_SIZE / sizeof(u64)); -+ -+ page = find_or_create_page(mapping, page_index, GFP_KERNEL); -+ if (page) { -+ /* Clean page if it's a new one */ -+ if (!Page_Uptodate(page)) { -+ memset(page_address(page), 0, PAGE_SIZE); -+ SetPageUptodate(page); -+ } -+ -+ exceptions = page_address(page); -+ *p = page; -+ return &exceptions[page_pos]; -+ } -+ return NULL; -+} -+ -+static inline int get_unshared_bit(struct snapinfo *info, chunk_t chunk) -+{ -+ return (info->shared_bitmap[chunk >> 5] >> (chunk & 31)) & 1; -+} -+ -+static inline void set_unshared_bit(struct snapinfo *info, chunk_t chunk) -+{ -+ info->shared_bitmap[chunk >> 5] |= 1 << (chunk & 31); -+} -+#endif -+ -+/* Hash table matches up query replies to pending requests */ -+ -+struct pending { -+ unsigned id; -+ u64 chunk; -+ unsigned chunks; -+ struct bio *bio; -+ struct list_head list; -+}; -+ -+static void show_pending(struct snapinfo *info) -+{ -+ unsigned i, total = 0; -+ -+ spin_lock(&info->pending_lock); -+ warn("Pending server queries..."); -+ for (i = 0; i < NUM_BUCKETS; i++) { -+ struct list_head *list; -+ list_for_each(list, info->pending + i) { -+ struct pending *pending = list_entry(list, struct pending, list); -+ if (!total) -+ printk("[%u]: ", i); -+ printk("%u:%Lx ", pending->id, pending->chunk); -+ total++; -+ } -+ } -+ printk("(%u)\n", total); -+ if (!list_empty(&info->queries)) { -+ struct list_head *list; -+ total = 0; -+ warn("Queued queries..."); -+ list_for_each(list, &info->queries) { -+ struct pending *pending = list_entry(list, struct pending, list); -+ printk("%Lx ", pending->chunk); -+ total++; -+ } -+ printk("(%u)\n", total); -+ } -+ spin_unlock(&info->pending_lock); -+} -+ -+static inline unsigned hash_pending(unsigned id) -+{ -+ return id & MASK_BUCKETS; -+} -+ -+/* Ah, now it gets interesting. Called in interrupt context */ -+ -+struct hook { -+ struct snapinfo *info; -+ sector_t sector; -+ /* needed only for end_io, make it a union */ -+ bio_end_io_t *old_end_io; -+ void *old_private; -+ /* needed after end_io, for release, make it a union */ -+ struct list_head list; -+}; -+ -+static int snapshot_read_end_io(struct bio *bio, unsigned int done, int error) -+{ -+ struct hook *hook = bio->bi_private; -+ struct snapinfo *info = hook->info; -+ -+ trace(warn("sector %Lx", (long long)hook->sector);) -+ spin_lock(&info->end_io_lock); -+ bio->bi_end_io = hook->old_end_io; -+ bio->bi_private = hook->old_private; -+ hook->old_end_io = NULL; -+ if (info->dont_switch_lists == 0) -+ list_move(&hook->list, &info->releases); -+ spin_unlock(&info->end_io_lock); -+ up(&info->more_work_sem); -+ -+ return bio->bi_end_io(bio, done, error); -+} -+ -+/* This is the part that does all the work. */ -+ -+int replied_rw(struct dm_target *target, struct rw_request *body, unsigned length, int rw, int snap) -+{ -+ struct snapinfo *info = target->private; -+ struct chunk_range *p = body->ranges; -+ unsigned shift = info->chunksize_bits - SECTOR_SHIFT, mask = (1 << shift) - 1; -+ int i, j, submitted = 0; -+ -+ trace(show_pending(info);) -+ trace(warn("id = %u, %u ranges, %s %s", body->id, body->count, -+ rw == READ? "read from": "write to", snap? "snapshot": "origin");) -+ -+ for (i = 0; i < body->count; i++) { // !!! check for length overrun -+ unsigned chunks = p->chunks, id = body->id; -+ struct list_head *list, *bucket = info->pending + hash_pending(id); -+ struct pending *pending; -+ struct bio *bio; -+ -+ trace(warn("[%Lx/%x]", p->chunk, chunks);) -+ assert(chunks == 1); -+ -+ spin_lock(&info->pending_lock); -+ list_for_each(list, bucket) -+ if ((pending = list_entry(list, struct pending, list))->id == id) -+ goto found; -+ warn("Can't find pending rw for chunk %u:%Lx", id, p->chunk); -+ spin_unlock(&info->pending_lock); -+ return -1; -+found: -+ list_del(&pending->list); -+ spin_unlock(&info->pending_lock); -+ -+ bio = pending->bio; -+ trace(warn("Handle pending IO sector %Lx", (long long)bio->bi_sector);) -+ -+ if (chunks != pending->chunks) { -+ warn("Message mismatch, expected %x got %x", chunks, chunks); -+ kmem_cache_free(pending_cache, pending); -+ bio_io_error(bio, bio->bi_size); -+ return -1; -+ } -+ -+ ++p; -+ if (snap) { -+ chunk_t *p2 = (chunk_t *)p; -+ for (j = 0; j < chunks; j++) { -+ u64 physical = (*p2++ << shift) + (bio->bi_sector & mask); -+ trace(warn("logical %Lx = physical %Lx", (u64)bio->bi_sector, physical)); -+ bio->bi_bdev = info->snapdev->bdev; -+ bio->bi_sector = physical; -+ } -+ p = (struct chunk_range *)p2; -+ } else if (rw == READ) { -+ /* snapshot read from origin */ -+ struct hook *hook; -+ trace(warn("hook end_io for %Lx", (long long)bio->bi_sector)); -+ hook = kmem_cache_alloc(end_io_cache, GFP_KERNEL|__GFP_NOFAIL); // !!! union with pending -+ *hook = (struct hook){ -+ .info = info, -+ .sector = bio->bi_sector, -+ .old_end_io = bio->bi_end_io, -+ .old_private = bio->bi_private }; -+ bio->bi_end_io = snapshot_read_end_io; -+ bio->bi_private = hook; -+ list_add(&hook->list, &info->locked); -+ } -+ -+ generic_make_request(bio); -+ submitted++; -+#ifdef CACHE -+ for (j = 0; j < p->chunks; j++) -+ set_unshared_bit(info, chunk + j); -+#endif -+ kmem_cache_free(pending_cache, pending); -+ } -+ if (submitted){ -+ kick(info->orgdev->bdev); -+ kick(info->snapdev->bdev); -+ } -+ return 0; -+} -+ -+/* -+ * There happen to be four flavors of server replies to rw queries, two -+ * write and two read, but the symmetry ends there. Only one flavor -+ * (write) is for origin IO, because origin reads do not need global -+ * synchronization. The remaining three flavors are for snapshot IO. -+ * Snapshot writes are always to the snapshot store, so there is only -+ * one flavor. On the other hand, snapshot reads can be from either -+ * the origin or the snapshot store. Only the server can know which. -+ * Either or both kinds of snapshot read reply are possible for a given -+ * query, which is where things get nasty. These two kinds of replies -+ * can be interleaved arbitrarily along the original read request, and -+ * to just to add a little more spice, the server may not send back the -+ * results for an entire query in one message (it may decide to service -+ * other queries first, or replly about the 'easiest' chunks first). The -+ * client has to match up all these reply fragments to the original -+ * request and decide what to do. Such bizarre fragmentation of the -+ * incoming request is unavoidable, it results from write access -+ * patterns to the origin. We just have to grin and deal with it. So -+ * without further ado, here is how the various reply flavors -+ * -+ * - Origin write replies just have logical ranges, since origin physical -+ * address is the same as logical. -+ * -+ * - Snapshot read replies come back in two separate messages, one for -+ * the origin reads (if any) and one for the snapstore reads (if any), -+ * the latter includes snapstore addresses. Origin reads are globally -+ * locked by the server, so we must send release messages on -+ * completion. -+ * -+ * - Snapshot writes are always to the snapstore, so snapstore write -+ * replies always include snapstore addresses. -+ * -+ * We know whether we're supposed to be a snapshot or origin client, -+ * but we only use that knowledge as a sanity check. The message codes -+ * tell us explicitly whether the IO target is origin or snapstore. -+ */ -+ -+/* -+ * For now, we just block on incoming message traffic, so this daemon -+ * can't do any other useful work. It could if we used nonblocking pipe -+ * IO but we have been too lazy to implement it so far. So we have one -+ * more daemon than we really need, and maybe we will get energetic one -+ * day soon and get rid of it. -+ * -+ * When it comes time to destroy things, the daemon has to be kicked -+ * out of its blocking wait, if it is in one, which it probably is. We -+ * do that by shutting down the socket. This unblocks the waiters and -+ * feeds them errors. Does this work for all flavors of sockets? I -+ * don't know. It obviously should, but we've seen some pretty silly -+ * limitations in our long life, so nothing would surprise us at this -+ * point. -+ */ -+static int incoming(struct dm_target *target) -+{ -+ struct snapinfo *info = target->private; -+ struct messagebuf message; // !!! have a buffer in the target->info -+ struct file *sock; -+ struct task_struct *task = current; -+ int err, length; -+ -+ strcpy(task->comm, "csnap-client"); -+ down(&info->exit2_sem); -+ trace(warn("Client thread started, pid=%i", current->pid);) -+connect: -+ trace(warn("Request socket connection");) -+ outbead(info->control_socket, NEED_SERVER, struct { }); -+ trace(warn("Wait for socket connection");) -+ down(&info->server_in_sem); -+ trace(warn("got socket %p", info->sock);) -+ sock = info->sock; -+ -+ while (running(info)) { // stop on module exit -+ int rw, to_snap; -+ -+ trace(warn("wait message");) -+ if ((err = readpipe(sock, &message.head, sizeof(message.head)))) -+ goto socket_error; -+ length = message.head.length; -+ if (length > maxbody) -+ goto message_too_long; -+ trace(warn("%x/%u", message.head.code, length);) -+ if ((err = readpipe(sock, &message.body, length))) -+ goto socket_error; -+ -+ switch (message.head.code) { -+ case REPLY_ORIGIN_WRITE: -+ rw = WRITE; -+ to_snap = 0; -+ break; -+ -+ case REPLY_SNAPSHOT_WRITE: -+ rw = WRITE; -+ to_snap = 1; -+ break; -+ -+ case REPLY_SNAPSHOT_READ_ORIGIN: -+ rw = READ; -+ to_snap = 0; -+ break; -+ -+ case REPLY_SNAPSHOT_READ: -+ rw = READ; -+ to_snap = 1; -+ break; -+ -+ case REPLY_IDENTIFY: -+ trace(warn("identify succeeded");) -+ up(&info->server_out_sem); -+ outbead(info->control_socket, REPLY_CONNECT_SERVER, struct { }); -+ continue; -+ -+ default: -+ warn("Unknown message %x", message.head.code); -+ continue; -+ } -+ if (length < sizeof(struct rw_request)) -+ goto message_too_short; -+ -+ replied_rw(target, (void *)message.body, length, rw, to_snap); -+ } -+out: -+ up(&info->exit2_sem); /* !!! will crash if module unloaded before ret executes */ -+ warn("%s exiting", task->comm); -+ return 0; -+message_too_long: -+ warn("message %x too long (%u bytes)", message.head.code, message.head.length); -+ goto out; -+message_too_short: -+ warn("message %x too short (%u bytes)", message.head.code, message.head.length); -+ goto out; -+socket_error: -+ warn("socket error %i", err); -+ if (!running(info)) -+ goto out; -+ -+ warn("halt worker"); -+ report_error(info); -+ goto connect; -+} -+ -+/* -+ * Here is our nonblocking worker daemon. It handles all events other -+ * than incoming socket traffic. At the moment, its only job is to -+ * send read release messages that can't be sent directly from the read -+ * end_io function, which executes in interrupt context. But soon its -+ * duties will be expanded to include submitting IO that was blocked -+ * because no server pipe is connected yet, or something broke the -+ * pipe. It may also have to resubmit some server queries, if the -+ * server dies for some reason and a new one is incarnated to take its -+ * place. We also want to check for timed-out queries here. Sure, we -+ * have heartbeating in the cluster, but why not have the guy who knows -+ * what to expect do the checking? When we do detect timeouts, we will -+ * punt the complaint upstairs using some interface that hasn't been -+ * invented yet, because nobody has thought too deeply about what you -+ * need to do, to detect faults really quickly and reliably. -+ * -+ * We throttle this daemon using a counting semaphore: each up on the -+ * semaphore causes the daemon to loop through its polling sequence -+ * once. So we make sure we up the daemon's semaphore every time we -+ * queue an event. The daemon may well process more than one event per -+ * cycle (we want that, actually, because then it can do some, e.g., -+ * message batching if it wants to) and will therefore end up looping -+ * a few times without doing any work. This is harmless, and much much -+ * less nasty than missing an event. When there are no pending events, -+ * the daemon sleeps peacefully. Killing the daemon is easy, we just -+ * pull down the running flag and up the work semaphore, which causes -+ * our faithful worker to drop out the bottom. -+ */ -+void upload_locks(struct snapinfo *info) -+{ -+ unsigned long irqflags; -+ struct hook *hook; -+ struct list_head *entry, *tmp; -+ -+ spin_lock_irqsave(&info->end_io_lock, irqflags); -+ info->dont_switch_lists = 1; -+ while(!list_empty(&info->releases)){ -+ entry = info->releases.prev; -+ hook = list_entry(entry, struct hook, list); -+ list_del(entry); -+ kmem_cache_free(end_io_cache, hook); -+ } -+ spin_unlock_irqrestore(&info->end_io_lock, irqflags); -+ list_for_each_safe(entry, tmp, &info->locked){ -+ chunk_t chunk; -+ -+ hook = list_entry(entry, struct hook, list); -+ spin_lock_irqsave(&info->end_io_lock, irqflags); -+ if (hook->old_end_io == NULL){ -+ list_del(entry); -+ kmem_cache_free(end_io_cache, hook); -+ spin_unlock_irqrestore(&info->end_io_lock, irqflags); -+ continue; -+ } -+ spin_unlock_irqrestore(&info->end_io_lock, irqflags); -+ chunk = hook->sector >> info->chunkshift; -+ outbead(info->sock, UPLOAD_LOCK, struct rw_request1, .count = 1, .ranges[0].chunk = chunk, .ranges[0].chunks = 1); -+ } -+ outbead(info->sock, FINISH_UPLOAD_LOCK, struct {}); -+ spin_lock_irqsave(&info->end_io_lock, irqflags); -+ list_for_each_safe(entry, tmp, &info->locked){ -+ hook = list_entry(entry, struct hook, list); -+ if (hook->old_end_io == NULL) -+ list_move(&hook->list, &info->releases); -+ } -+ info->dont_switch_lists = 0; -+ spin_unlock_irqrestore(&info->end_io_lock, irqflags); -+} -+ -+static void requeue_queries(struct snapinfo *info) -+{ -+ unsigned i; -+ -+ trace(show_pending(info);) -+ spin_lock(&info->pending_lock); -+ warn(""); -+ for (i = 0; i < NUM_BUCKETS; i++) { -+ struct list_head *bucket = info->pending + i; -+ -+ while (!list_empty(bucket)) { -+ struct list_head *entry = bucket->next; -+ struct pending *pending = list_entry(entry, struct pending, list); -+ trace_on(warn("requeue %u:%Lx", pending->id, pending->chunk);) -+ -+ list_move(entry, &info->queries); -+ up(&info->more_work_sem); -+ } -+ } -+ spin_unlock(&info->pending_lock); -+ trace(show_pending(info);) -+} -+ -+static int worker(struct dm_target *target) -+{ -+ struct snapinfo *info = target->private; -+ struct task_struct *task = current; -+ int err; -+ -+ strcpy(task->comm, "csnap-worker"); -+ trace(warn("Worker thread started, pid=%i", current->pid);) -+ down(&info->exit1_sem); -+ goto recover; /* just for now we'll always upload locks, even on fresh start */ -+restart: -+ while (worker_running(info)) { -+ unsigned long irqflags; -+ down(&info->more_work_sem); -+ -+ /* Send message for each pending request. */ -+ spin_lock(&info->pending_lock); -+ while (!list_empty(&info->queries) && worker_running(info)) { -+ struct list_head *entry = info->queries.prev; -+ struct pending *pending = list_entry(entry, struct pending, list); -+ -+ list_del(entry); -+ list_add(&pending->list, info->pending + hash_pending(pending->id)); -+ spin_unlock(&info->pending_lock); -+ trace(show_pending(info);) -+ -+ down(&info->server_out_sem); -+ trace(warn("Server query [%Lx/%x]", pending->chunk, pending->chunks);) -+ if ((err = outbead(info->sock, -+ bio_data_dir(pending->bio) == WRITE? QUERY_WRITE: QUERY_SNAPSHOT_READ, -+ struct rw_request1, -+ .id = pending->id, .count = 1, -+ .ranges[0].chunk = pending->chunk, -+ .ranges[0].chunks = pending->chunks))) -+ goto report; -+ up(&info->server_out_sem); -+ spin_lock(&info->pending_lock); -+ } -+ spin_unlock(&info->pending_lock); -+ -+ /* Send message for each pending read release. */ -+ spin_lock_irqsave(&info->end_io_lock, irqflags); -+ while (!list_empty(&info->releases) && worker_running(info)) { -+ struct list_head *entry = info->releases.prev; -+ struct hook *hook = list_entry(entry, struct hook, list); -+ chunk_t chunk = hook->sector >> info->chunkshift; -+ -+ list_del(entry); -+ spin_unlock_irqrestore(&info->end_io_lock, irqflags); -+ trace(warn("release sector %Lx, chunk %Lx", (long long)hook->sector, chunk);) -+ kmem_cache_free(end_io_cache, hook); -+ down(&info->server_out_sem); -+ if ((err = outbead(info->sock, FINISH_SNAPSHOT_READ, struct rw_request1, -+ .count = 1, .ranges[0].chunk = chunk, .ranges[0].chunks = 1))) -+ goto report; -+ up(&info->server_out_sem); -+ spin_lock_irqsave(&info->end_io_lock, irqflags); -+ } -+ spin_unlock_irqrestore(&info->end_io_lock, irqflags); -+ -+ trace(warn("Yowza! More work?");) -+ } -+ if ((info->flags & RECOVER_FLAG)) { -+ down(&info->server_out_sem); -+ up(&info->more_work_sem); -+ goto recover; -+ } -+finish: -+ up(&info->exit1_sem); /* !!! crashes if module unloaded before ret executes */ -+ trace_on(warn("%s exiting", task->comm);) -+ return 0; -+ -+report: -+ warn("worker socket error %i", err); -+ report_error(info); -+recover: -+ trace_on(warn("worker recovering");) -+ down(&info->recover_sem); -+ if ((info->flags & FINISH_FLAG)) -+ goto finish; -+ if (is_snapshot(info)) -+ upload_locks(info); -+ requeue_queries(info); -+ trace_on(warn("worker resuming");) -+ -+ info->flags &= ~(RECOVER_FLAG|(1 << REPORT_BIT)); -+ up(&info->recover_sem); -+ goto restart; -+} -+ -+/* -+ * Yikes, a third daemon, that makes four including the user space -+ * monitor. This daemon proliferation is due to not using poll, which -+ * we should fix at some point. Or maybe we should wait for aio to -+ * work properly for sockets, and use that instead. Either way, we -+ * can combine the two socket-waiting daemons into one, which will look -+ * nicer in ps. Practically speaking, it doesn't matter a whole lot -+ * though, if we just stay lazy and have too many daemons. -+ * -+ * At least, combine this code with incoming, with just the switches -+ * different. -+ */ -+static int control(struct dm_target *target) -+{ -+ struct task_struct *task = current; -+ struct snapinfo *info = target->private; -+ struct messagebuf message; // !!! have a buffer in the target->info -+ struct file *sock; -+ int err, length; -+ -+ strcpy(task->comm, "csnap-control"); -+ trace(warn("Control thread started, pid=%i", current->pid);) -+ sock = info->control_socket; -+ trace(warn("got socket %p", sock);) -+ -+ down(&info->exit3_sem); -+ while (running(info)) { -+ trace(warn("wait message");) -+ if ((err = readpipe(sock, &message.head, sizeof(message.head)))) -+ goto socket_error; -+ trace(warn("got message header code %x", message.head.code);) -+ length = message.head.length; -+ if (length > maxbody) -+ goto message_too_long; -+ trace(warn("%x/%u", message.head.code, length);) -+ if ((err = readpipe(sock, &message.body, length))) -+ goto socket_error; -+ -+ switch (message.head.code) { -+ case SET_IDENTITY: -+ info->id = ((struct set_id *)message.body)->id; -+ warn("id set: %Lu", info->id); -+ break; -+ case CONNECT_SERVER: { -+ unsigned len = 4; -+ char bogus[len]; -+ int sock_fd = get_unused_fd(), fd; -+ -+ if (sock_fd < 0) { -+ warn("Can't get fd, error %i", sock_fd); -+ break; -+ } -+ fd_install(sock_fd, sock); -+ if ((fd = recv_fd(sock_fd, bogus, &len)) < 0) { -+ warn("recv_fd failed, error %i", fd); -+ put_unused_fd(sock_fd); -+ break; -+ } -+ trace(warn("Received socket %i", fd);) -+ info->sock = fget(fd); -+ current->files->fd[fd] = NULL; /* this is sooo hokey */ -+ put_unused_fd(sock_fd); -+ sys_close(fd); -+ up(&info->server_in_sem); -+ outbead(info->sock, IDENTIFY, struct identify, .id = info->id, .snap = info->snap); -+ up(&info->recover_sem); /* worker uploads locks now */ -+ break; -+ } -+ default: -+ warn("Unknown message %x", message.head.code); -+ continue; -+ } -+ } -+out: -+ up(&info->exit3_sem); /* !!! will crash if module unloaded before ret executes */ -+ warn("%s exiting", task->comm); -+ return 0; -+message_too_long: -+ warn("message %x too long (%u bytes)", message.head.code, message.head.length); -+ goto out; -+socket_error: -+ warn("socket error %i", err); -+ goto out; -+} -+ -+/* -+ * This is the device mapper mapping method, which does one of three things: -+ * (1) tells device mapper to go ahead and submit the request with a default -+ * identity mapping (return 1) (2) tells device mapper to forget about the -+ * request (return 0), goes off and does its own thing, or (3) on a bad -+ * day, tells device mapper to fail the IO (return negative errnum). -+ * -+ * This is pretty simple: we just hand any origin reads back to device mapper -+ * after filling in the origin device. Then, we check the cache to see if -+ * if conditions are right to map the request locally, otherwise we need help -+ * from the server, so we remember the request in the pending hash and send -+ * off the appropriate server query. -+ * -+ * To make this a little more interesting, our server connection may be broken -+ * at the moment, or may not have been established yet, in which case we have -+ * to defer the request until the server becomes available. -+ */ -+static int csnap_map(struct dm_target *target, struct bio *bio, union map_info *context) -+{ -+ struct snapinfo *info = target->private; -+ struct pending *pending; -+ chunk_t chunk; -+ unsigned id; -+ -+ bio->bi_bdev = info->orgdev->bdev; -+ if (bio_data_dir(bio) == READ && !is_snapshot(info)) -+ return 1; -+ -+ chunk = bio->bi_sector >> info->chunkshift; -+ trace(warn("map %Lx/%x, chunk %Lx", (long long)bio->bi_sector, bio->bi_size, chunk);) -+ assert(bio->bi_size <= 1 << info->chunksize_bits); -+#ifdef CACHE -+ if (is_snapshot(info)) { // !!! use page cache for both -+ struct page *page; -+ u64 *exception = snap_map_cachep(info->inode->i_mapping, chunk, &page); -+ -+ if (!exception) { -+ printk("Failed to get a page for sector %ld\n", bio->bi_sector); -+ return -1; -+ } -+ -+ u64 exp_chunk = *exception; -+ UnlockPage(page); -+ if (exp_chunk) { -+ bio->bi_sector = bio->bi_sector + ((exp_chunk - chunk) << info->chunkshift); -+ return 1; -+ } -+ } else { -+ if (info->shared_bitmap && get_unshared_bit(info, chunk)) -+ return 1; -+ } -+#endif -+ id = info->nextid; -+ info->nextid = (id + 1) & ~(-1 << ID_BITS); -+ pending = kmem_cache_alloc(pending_cache, GFP_NOIO|__GFP_NOFAIL); -+ *pending = (struct pending){ .id = id, .bio = bio, .chunk = chunk, .chunks = 1 }; -+ spin_lock(&info->pending_lock); -+ list_add(&pending->list, &info->queries); -+ spin_unlock(&info->pending_lock); -+ up(&info->more_work_sem); -+ return 0; -+} -+ -+/* -+ * Carefully crafted not to care about how far we got in the process -+ * of instantiating our client. As such, it serves both for error -+ * abort and device unload destruction. We have to scour our little -+ * world for resources and give them all back, including any pending -+ * requests, context structures and daemons. The latter have to be -+ * convince to exit on demand, and we must be sure they have exited, -+ * so we synchronize that with semaphores. This isn't 100% foolproof' -+ * there is still the possibility that the destructor could gain -+ * control between the time a daemon ups its exit semaphore and when -+ * it has actually returned to its caller. In that case, the module -+ * could be unloaded and the exiting thread will segfault. This is -+ * a basic flaw in Linux that I hope to get around to fixing at some -+ * point, one way or another. -+ */ -+static int shutdown_socket(struct file *socket) -+{ -+ struct socket *sock = SOCKET_I(socket->f_dentry->d_inode); -+ return sock->ops->shutdown(sock, RCV_SHUTDOWN); -+} -+ -+static void csnap_destroy(struct dm_target *target) -+{ -+ struct snapinfo *info = target->private; -+ int err; /* I have no mouth but I must scream */ -+ -+ trace(warn("%p", target);) -+ if (!info) -+ return; -+ -+ /* Unblock helper threads */ -+ info->flags |= FINISH_FLAG; -+ up(&info->server_in_sem); // unblock incoming thread -+ up(&info->server_out_sem); // unblock io request threads -+ up(&info->recover_sem); // unblock worker recovery -+ -+ if (info->sock && (err = shutdown_socket(info->sock))) -+ warn("server socket shutdown error %i", err); -+ if (info->sock && (err = shutdown_socket(info->control_socket))) -+ warn("control socket shutdown error %i", err); -+ -+ up(&info->more_work_sem); -+ -+ // !!! wrong! the thread might be just starting, think about this some more -+ // ah, don't let csnap_destroy run while csnap_create is spawning threads -+ down(&info->exit1_sem); -+ warn("thread 1 exited"); -+ down(&info->exit2_sem); -+ warn("thread 2 exited"); -+ down(&info->exit3_sem); -+ warn("thread 3 exited"); -+ -+ if (info->sock) -+ fput(info->sock); -+ if (info->inode) -+ iput(info->inode); -+ if (info->shared_bitmap) -+ vfree(info->shared_bitmap); -+ if (info->snapdev) -+ dm_put_device(target, info->snapdev); -+ if (info->orgdev) -+ dm_put_device(target, info->orgdev); -+ kfree(info); -+} -+ -+/* -+ * Woohoo, we are going to instantiate a new cluster snapshot virtual -+ * device, what fun. -+ */ -+static int get_control_socket(char *sockname) -+{ -+ mm_segment_t oldseg = get_fs(); -+ struct sockaddr_un addr = { .sun_family = AF_UNIX }; -+ int addr_len = sizeof(addr) - sizeof(addr.sun_path) + strlen(sockname); // !!! check too long -+ int sock = sys_socket(AF_UNIX, SOCK_STREAM, 0), err = 0; -+ -+ trace(warn("Connect to control socket %s", sockname);) -+ if (sock <= 0) -+ return sock; -+ strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); -+ if (sockname[0] == '@') -+ addr.sun_path[0] = 0; -+ -+ set_fs(get_ds()); -+ while ((err = sys_connect(sock, (struct sockaddr *)&addr, addr_len)) == -ECONNREFUSED) -+ break; -+// yield(); -+ set_fs(oldseg); -+ -+ return err? err: sock; -+} -+ -+/* -+ * Round up to nearest 2**k boundary -+ * !!! lose this -+ */ -+static inline ulong round_up(ulong n, ulong size) -+{ -+ return (n + size - 1) & ~(size - 1); -+} -+ -+static int csnap_create(struct dm_target *target, unsigned argc, char **argv) -+{ -+ u64 chunksize_bits = 12; // !!! when chunksize isn't always 4K, have to move all this to identify reply handler -+ struct snapinfo *info; -+ int err, i, snap, flags = 0; -+ char *error; -+#ifdef CACHE -+ unsigned bm_size; -+#endif -+ -+ error = "csnap usage: orgdev snapdev sockname snapnum"; -+ err = -EINVAL; -+ if (argc != 4) -+ goto eek; -+ -+ snap = simple_strtol(argv[3], NULL, 0); -+ if (snap >= 0) -+ flags |= IS_SNAP_FLAG; -+ -+ err = -ENOMEM; -+ error = "can't get kernel memory"; -+ if (!(info = kmalloc(sizeof(struct snapinfo), GFP_KERNEL))) -+ goto eek; -+ -+ *info = (struct snapinfo){ -+ .flags = flags, .snap = snap, -+ .chunksize_bits = chunksize_bits, -+ .chunkshift = chunksize_bits - SECTOR_SHIFT}; -+ target->private = info; -+ sema_init(&info->server_in_sem, 0); -+ sema_init(&info->server_out_sem, 0); -+ sema_init(&info->recover_sem, 0); -+ sema_init(&info->exit1_sem, 1); -+ sema_init(&info->exit2_sem, 1); -+ sema_init(&info->exit3_sem, 1); -+ sema_init(&info->more_work_sem, 0); -+ spin_lock_init(&info->pending_lock); -+ spin_lock_init(&info->end_io_lock); -+ INIT_LIST_HEAD(&info->queries); -+ INIT_LIST_HEAD(&info->releases); -+ INIT_LIST_HEAD(&info->locked); -+ for (i = 0; i < NUM_BUCKETS; i++) -+ INIT_LIST_HEAD(&info->pending[i]); -+ -+ error = "Can't get snapshot device"; -+ if ((err = dm_get_device(target, argv[0], 0, target->len, dm_table_get_mode(target->table), &info->snapdev))) -+ goto eek; -+ error = "Can't get origin device"; -+ if ((err = dm_get_device(target, argv[1], 0, target->len, dm_table_get_mode(target->table), &info->orgdev))) -+ goto eek; -+ error = "Can't connect control socket"; -+ if ((err = get_control_socket(argv[2])) < 0) -+ goto eek; -+ info->control_socket = fget(err); -+ sys_close(err); -+ -+#ifdef CACHE -+ bm_size = round_up((target->len + 7) >> (chunksize_bits + 3), sizeof(u32)); // !!! wrong -+ error = "Can't allocate bitmap for origin"; -+ if (!(info->shared_bitmap = vmalloc(bm_size))) -+ goto eek; -+ memset(info->shared_bitmap, 0, bm_size); -+ if (!(info->inode = new_inode(snapshot_super))) -+ goto eek; -+#endif -+ -+ error = "Can't start daemon"; -+ if ((err = kernel_thread((void *)incoming, target, CLONE_KERNEL)) < 0) -+ goto eek; -+ if ((err = kernel_thread((void *)worker, target, CLONE_KERNEL)) < 0) -+ goto eek; -+ if ((err = kernel_thread((void *)control, target, CLONE_KERNEL)) < 0) -+ goto eek; -+ warn("Created snapshot device origin=%s snapstore=%s socket=%s snapshot=%i", argv[0], argv[1], argv[2], snap); -+ target->split_io = 1 << info->chunkshift; // !!! lose this as soon as possible -+ return 0; -+ -+eek: warn("Virtual device create error %i: %s!", err, error); -+ csnap_destroy(target); -+ target->error = error; -+ return err; -+ -+ { void *useme = show_pending; useme = useme; } -+} -+ -+/* Is this actually useful? It's really trying to be a message */ -+ -+static int csnap_status(struct dm_target *target, status_type_t type, char *result, unsigned int maxlen) -+{ -+ char orgbuffer[32]; -+ char snapbuffer[32]; -+ struct snapinfo *info = target->private; -+ -+ switch (type) { -+ case STATUSTYPE_INFO: -+ result[0] = '\0'; -+ break; -+ -+ case STATUSTYPE_TABLE: -+ format_dev_t(orgbuffer, info->orgdev->bdev->bd_dev); -+ format_dev_t(snapbuffer, info->snapdev->bdev->bd_dev); -+ snprintf(result, maxlen, "%s %s %u", -+ orgbuffer, snapbuffer, 1 << info->chunksize_bits); -+ break; -+ } -+ -+ return 0; -+} -+ -+static struct target_type csnap = { -+ .name = "csnapshot", -+ .version = {0, 0, 0}, -+ .module = THIS_MODULE, -+ .ctr = csnap_create, -+ .dtr = csnap_destroy, -+ .map = csnap_map, -+ .status = csnap_status, -+}; -+ -+int __init dm_csnap_init(void) -+{ -+ int err = -ENOMEM; -+ char *what = "Cache create"; -+ if (!(pending_cache = kmem_cache_create("csnap-pending", -+ sizeof(struct pending), __alignof__(struct pending), 0, NULL, NULL))) -+ goto bad1; -+ if (!(end_io_cache = kmem_cache_create("csnap-endio", -+ sizeof(struct hook), __alignof__(struct hook), 0, NULL, NULL))) -+ goto bad2; -+ what = "register"; -+ if ((err = dm_register_target(&csnap))) -+ goto bad3; -+#ifdef CACHE -+ err = -ENOMEM; -+ what = "create snapshot superblock"; -+ if (!(snapshot_super = alloc_super())) -+ goto bad4; -+#endif -+ return 0; -+ -+#ifdef CACHE -+bad4: -+ dm_unregister_target(&csnap); -+#endif -+bad3: -+ kmem_cache_destroy(end_io_cache); -+bad2: -+ kmem_cache_destroy(pending_cache); -+bad1: -+ DMERR("%s failed\n", what); -+ return err; -+} -+ -+void dm_csnap_exit(void) -+{ -+ int err; -+ trace_on(warn(">>> module exit");) -+ if ((err = dm_unregister_target(&csnap))) -+ DMERR("Snapshot unregister failed %d", err); -+ if (pending_cache) -+ kmem_cache_destroy(pending_cache); -+ if (end_io_cache) -+ kmem_cache_destroy(end_io_cache); -+ kfree(snapshot_super); -+} -+ -+module_init(dm_csnap_init); -+module_exit(dm_csnap_exit); -diff -up --recursive 2.6.8.1.csnap.clean/drivers/md/dm-csnap.h 2.6.8.1.csnap/drivers/md/dm-csnap.h ---- 2.6.8.1.csnap.clean/drivers/md/dm-csnap.h 2004-10-14 12:58:12.000000000 -0400 -+++ 2.6.8.1.csnap/drivers/md/dm-csnap.h 2004-12-01 23:11:46.000000000 -0500 -@@ -0,0 +1,90 @@ -+#define PACKED __attribute__ ((packed)) -+#define MAGIC 0xadbe -+ -+struct head { uint32_t code; uint32_t length; } PACKED; -+ -+enum csnap_codes -+{ -+ REPLY_ERROR = 0xbead0000, -+ IDENTIFY, -+ REPLY_IDENTIFY, -+ QUERY_WRITE, -+ REPLY_ORIGIN_WRITE, -+ REPLY_SNAPSHOT_WRITE, -+ QUERY_SNAPSHOT_READ, -+ REPLY_SNAPSHOT_READ, -+ REPLY_SNAPSHOT_READ_ORIGIN, -+ FINISH_SNAPSHOT_READ, -+ CREATE_SNAPSHOT, -+ REPLY_CREATE_SNAPSHOT, -+ DELETE_SNAPSHOT, -+ REPLY_DELETE_SNAPSHOT, -+ DUMP_TREE, -+ INITIALIZE_SNAPSTORE, -+ NEED_SERVER, -+ CONNECT_SERVER, -+ REPLY_CONNECT_SERVER, -+ CONTROL_SOCKET, -+ SERVER_READY, -+ START_SERVER, -+ SHUTDOWN_SERVER, -+ SET_IDENTITY, -+ UPLOAD_LOCK, -+ FINISH_UPLOAD_LOCK, -+ NEED_CLIENTS, -+ UPLOAD_CLIENT_ID, -+ FINISH_UPLOAD_CLIENT_ID, -+ REMOVE_CLIENT_IDS, -+}; -+ -+struct match_id { uint64_t id; uint64_t mask; } PACKED; -+struct set_id { uint64_t id; } PACKED; -+struct identify { uint64_t id; int32_t snap; } PACKED; -+struct create_snapshot { uint32_t snap; } PACKED; -+ -+typedef uint16_t shortcount; /* !!! what is this all about */ -+ -+struct rw_request -+{ -+ uint16_t id; -+ shortcount count; -+ struct chunk_range -+ { -+ uint64_t chunk; -+ shortcount chunks; -+ } PACKED ranges[]; -+} PACKED; -+ -+/* !!! can there be only one flavor of me please */ -+struct rw_request1 -+{ -+ uint16_t id; -+ shortcount count; -+ struct chunk_range PACKED ranges[1]; -+} PACKED; -+ -+/* decruft me... !!! */ -+#define maxbody 500 -+struct rwmessage { struct head head; struct rw_request body; }; -+struct messagebuf { struct head head; char body[maxbody]; }; -+/* ...decruft me */ -+ -+/* The endian conversions that libc forgot */ -+ -+static inline uint64_t ntohll(uint64_t n) -+{ -+#if __BYTE_ORDER == __LITTLE_ENDIAN -+ return (((uint64_t)ntohl(n)) << 32) | ntohl(n >> 32); -+#else -+ return n; -+#endif -+} -+ -+static inline uint64_t htonll(uint64_t n) -+{ -+#if __BYTE_ORDER == __LITTLE_ENDIAN -+ return (((uint64_t)htonl(n)) << 32) | htonl(n >> 32); -+#else -+ return n; -+#endif -+} -diff -up --recursive 2.6.8.1.csnap.clean/fs/super.c 2.6.8.1.csnap/fs/super.c ---- 2.6.8.1.csnap.clean/fs/super.c 2004-08-14 06:55:22.000000000 -0400 -+++ 2.6.8.1.csnap/fs/super.c 2004-10-04 16:39:41.000000000 -0400 -@@ -51,7 +51,7 @@ spinlock_t sb_lock = SPIN_LOCK_UNLOCKED; - * Allocates and initializes a new &struct super_block. alloc_super() - * returns a pointer new superblock or %NULL if allocation had failed. - */ --static struct super_block *alloc_super(void) -+struct super_block *alloc_super(void) - { - struct super_block *s = kmalloc(sizeof(struct super_block), GFP_USER); - static struct super_operations default_op; -@@ -87,6 +87,8 @@ out: - return s; - } - -+EXPORT_SYMBOL(alloc_super); -+ - /** - * destroy_super - frees a superblock - * @s: superblock to free -diff -up --recursive 2.6.8.1.csnap.clean/include/linux/fs.h 2.6.8.1.csnap/include/linux/fs.h ---- 2.6.8.1.csnap.clean/include/linux/fs.h 2004-10-14 13:10:56.000000000 -0400 -+++ 2.6.8.1.csnap/include/linux/fs.h 2004-10-12 02:09:03.000000000 -0400 -@@ -1122,6 +1122,7 @@ void generic_shutdown_super(struct super - void kill_block_super(struct super_block *sb); - void kill_anon_super(struct super_block *sb); - void kill_litter_super(struct super_block *sb); -+struct super_block *alloc_super(void); - void deactivate_super(struct super_block *sb); - int set_anon_super(struct super_block *s, void *data); - struct super_block *sget(struct file_system_type *type, -diff -up --recursive 2.6.8.1.csnap.clean/net/socket.c 2.6.8.1.csnap/net/socket.c ---- 2.6.8.1.csnap.clean/net/socket.c 2004-08-14 06:55:10.000000000 -0400 -+++ 2.6.8.1.csnap/net/socket.c 2004-11-01 23:10:54.000000000 -0500 -@@ -2086,6 +2086,12 @@ void socket_seq_show(struct seq_file *se - } - #endif /* CONFIG_PROC_FS */ - -+/* Cluster devices need these, or better: kernel interfaces */ -+ -+EXPORT_SYMBOL_GPL(sys_connect); -+EXPORT_SYMBOL_GPL(sys_recvmsg); -+EXPORT_SYMBOL_GPL(sys_socket); -+ - /* ABI emulation layers need these two */ - EXPORT_SYMBOL(move_addr_to_kernel); - EXPORT_SYMBOL(move_addr_to_user); diff --git a/csnap/sock.h b/csnap/sock.h deleted file mode 100644 index 2f3d2fe..0000000 --- a/csnap/sock.h +++ /dev/null @@ -1,55 +0,0 @@ -#include <sys/socket.h> -#include <netdb.h> - -/* - * Find and return the port number of a host:port pair, shortening - * the original string to include only the hostname. - */ -static inline int parse_port(char *s, unsigned *len) -{ - char *p = memchr(s, ':', *len); - if (!p || p == s || p - s == *len) - return -1; - *len = p - s; - return atoi(p + 1); -} - -/* - * Dumbed down interface for opening an IPv4 connection. - */ -static inline int open_socket(char *name, unsigned port) -{ - struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(port) }; - struct hostent *host; - int sock; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - error("Can't get socket"); - if (!(host = gethostbyname(name))) - -h_errno; - memcpy(&addr.sin_addr.s_addr, host->h_addr, host->h_length); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - return -errno; - return sock; -} - -/* - * Pass a fd over a local socket connection. You have to send some stream - * data as well, just to make an ugly interface even more irritating. - */ -int send_fd(int sock, int fd, char *bogus, unsigned len) -{ - char payload[CMSG_SPACE(sizeof(int))]; - struct msghdr msg = { - .msg_control = payload, - .msg_controllen = sizeof(payload), - .msg_iov = &(struct iovec){ .iov_base = bogus, .iov_len = len }, - .msg_iovlen = 1, - }; - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - - *cmsg = (struct cmsghdr){ CMSG_LEN(sizeof(int)), SOL_SOCKET, SCM_RIGHTS }; - *((int *)CMSG_DATA(cmsg)) = fd; // this is really an array, .cmsg_len gives count (??) - - return sendmsg(sock, &msg, 0) != len? -EIO: len; -} diff --git a/csnap/testclient.c b/csnap/testclient.c deleted file mode 100644 index b313e1b..0000000 --- a/csnap/testclient.c +++ /dev/null @@ -1,185 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <netinet/in.h> -#include <sys/poll.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netdb.h> -#include "csnap.h" -#include "../dm-csnap.h" -#include "trace.h" - -#define trace trace_off - -int open_socket(char *name, unsigned port) -{ - int sock; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - error("Can't get socket"); - - struct hostent *host; - if (!(host = gethostbyname(name))) - error("Unknown host '%s'", name); - - struct sockaddr_in sockaddr = { .sin_family = AF_INET, .sin_port = htons(port) }; - memcpy(&sockaddr.sin_addr.s_addr, host->h_addr, host->h_length); - if (connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) - error("Cannot connect to %s:%i", name, port); - - return sock; -} - -#if 0 -static unsigned seed = 0; - -unsigned myrand(void) -{ - return seed = seed * 1871923741 + 3298913417U; -} -#else -#define myrand rand -#endif - -int serviced = 0; - -int incoming(unsigned sock) -{ - struct messagebuf message; - int err, i, j; - - if ((err = readpipe(sock, &message.head, sizeof(message.head)))) - goto pipe_error; - if (message.head.length > maxbody) - goto message_too_long; - trace(warn("%x+%u", message.head.code, message.head.length);) - if ((err = readpipe(sock, &message.body, message.head.length))) - goto pipe_error; - - switch (message.head.code) { - case REPLY_ORIGIN_WRITE: - { - struct rw_request *body = (struct rw_request *)message.body; - struct chunk_range *p = body->ranges; - if (message.head.length < sizeof(*body)) - goto message_too_short; - trace(printf("origin write reply, %u ranges ", body->count);) - for (i = 0; i < body->count; i++, p++) - trace(printf("%llu/%u ", p->chunk, p->chunks);) - trace(printf("\n");) - serviced++; - break; - } - - case REPLY_SNAPSHOT_WRITE: - { - struct rw_request *body = (struct rw_request *)message.body; - struct chunk_range *p = body->ranges; - if (message.head.length < sizeof(*body)) - goto message_too_short; - trace(printf("snapshot write reply, %u ranges ", body->count);) - for (i = 0; i < body->count; i++) { - trace(printf("%llu/%u ", p->chunk, p->chunks);) - chunk_t *q = (chunk_t *)(p + 1); - for (j = 0; j < p->chunks; j++, q++) - trace(printf("%llu ", *q)); - p = (struct chunk_range *)q; - } - trace(printf("\n");) - serviced++; - break; - } - - case REPLY_CREATE_SNAPSHOT: - trace(warn("create snapshot succeeded");) - break; - - default: - warn("Unknown message %x", message.head.code); - } - return 0; - -message_too_long: - warn("message %x too long (%u bytes)\n", message.head.code, message.head.length); - return -1; -message_too_short: - warn("message %x too short (%u bytes)\n", message.head.code, message.head.length); - return -1; -pipe_error: - return -1; -} - -unsigned available(unsigned sock) -{ - unsigned bytes; - ioctl(sock, FIONREAD, &bytes); - trace(if (bytes) printf("%u bytes waiting\n", bytes);) - return bytes; -} - -static unsigned total_chunks; - -int main(int argc, char *argv[]) -{ - int err, snapdev, orgdev, iterations = 1; - -#if 0 - warn("rand = %u", myrand()); - warn("rand = %u", myrand()); - warn("rand = %u", myrand()); - warn("rand = %u", myrand()); - warn("rand = %u", myrand()); -return 0; -#endif - - if (argc < 5) - error("usage: %s dev/snapstore dev/origin hostname port [iterations]", argv[0]); - if (!(snapdev = open(argv[1], O_RDWR /*| O_DIRECT*/))) - error("Could not open snapshot store %s", argv[1]); - if (!(orgdev = open(argv[2], O_RDWR /*| O_DIRECT*/))) - error("Could not open origin volume %s", argv[2]); - if (argc > 5) - iterations = atoi(argv[5]); - - int sock = open_socket(argv[3], atoi(argv[4])); - unsigned length_range = 32; - unsigned chunk_range = (lseek(orgdev, 0, SEEK_END) >> 12) - length_range; - - outbead(sock, CREATE_SNAPSHOT, struct create_snapshot, 8); - outbead(sock, CREATE_SNAPSHOT, struct create_snapshot, 9); - outbead(sock, IDENTIFY, struct identify, .snap = -1); - trace_on(warn("start %u transfers", iterations);) - - int i; - for (i=0; i < iterations; i++) { - unsigned length = offsetof(struct rw_request, ranges) + sizeof(struct chunk_range); - struct { struct head head; struct rw_request body; char tail[maxbody]; } PACKED message; - message.head.code = QUERY_WRITE; - message.head.length = length; - message.body.count = 1; - message.body.ranges[0].chunk = 0? (myrand() % chunk_range): total_chunks; - message.body.ranges[0].chunks = 1; - total_chunks += message.body.ranges[0].chunks = 0? (myrand() % length_range + 1): 1; - - if (write(sock, &message, sizeof(struct head) + length) < 0) - error("Error writing to socket"); - - while (available(sock) >= sizeof(struct head)) - incoming(sock); - } - while (serviced < iterations) { - poll(NULL, 0, 100); - trace(warn("wait for %i responses", iterations - serviced);) - while (available(sock) >= sizeof(struct head)) - incoming(sock); - } -// outbead(sock, DUMP_TREE, struct { }); - close(sock); - return err; -} diff --git a/csnap/trace.h b/csnap/trace.h deleted file mode 100644 index 8815cb2..0000000 --- a/csnap/trace.h +++ /dev/null @@ -1,7 +0,0 @@ -#define BREAK asm("int3") -#define warn(string, args...) do { fprintf(stderr, "[%u] %s: " string "\n", getpid(), __func__, ##args); } while (0) -#define error(string, args...) do { warn(string, ##args); BREAK; } while (0) -#define assert(expr) do { if (!(expr)) error("Failed assertion "%s"\n", #expr); } while (0) - -#define trace_on(args) args -#define trace_off(args) diff --git a/dlm-kernel/Makefile b/dlm-kernel/Makefile deleted file mode 100644 index a1b0df5..0000000 --- a/dlm-kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: - cd src && ${MAKE} all - -clean: - cd src && ${MAKE} clean - -install: - cd src && ${MAKE} install - -uninstall: - cd src && ${MAKE} uninstall - -distclean: clean - rm -f make/defines.mk \ No newline at end of file diff --git a/dlm-kernel/configure b/dlm-kernel/configure deleted file mode 100755 index 430d161..0000000 --- a/dlm-kernel/configure +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$kernel_src) { - $kernel_src="/usr/src/linux-2.6"; -} -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -open VER, "<$kernel_src/include/linux/version.h" or die "Can't open $kernel_src/include/linux/version.h"; -while(<VER>){ - chomp; - if( $_ =~ /^#define\s*UTS_RELEASE\s*"(.*)"$/ ){ - $kernel_version = $1; - $module_dir = "${prefix}/lib/modules/$1/kernel"; - } -} - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@KERNEL_VERSION@/$kernel_version/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@MODULE_DIR@/$module_dir/; - $_ =~ s/@SBINDIR@/$sbindir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/dlm-kernel/make/defines.mk.input b/dlm-kernel/make/defines.mk.input deleted file mode 100644 index 0c2ea7a..0000000 --- a/dlm-kernel/make/defines.mk.input +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -module_dir ?= ${DESTDIR}/@MODULE_DIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ -KERNEL_VERSION = @KERNEL_VERSION@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/dlm-kernel/make/release.mk.input b/dlm-kernel/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/dlm-kernel/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/dlm-kernel/patches/2.6.9/00001.patch b/dlm-kernel/patches/2.6.9/00001.patch deleted file mode 100644 index f4359ab..0000000 --- a/dlm-kernel/patches/2.6.9/00001.patch +++ /dev/null @@ -1,62 +0,0 @@ -# Add DLM to the build system -diff -urN -p linux-2.6.8.1/cluster/Kconfig linux/cluster/Kconfig ---- linux-2.6.8.1/cluster/Kconfig 2004-08-24 13:23:09.000000000 +0800 -+++ linux/cluster/Kconfig 2004-08-24 13:23:32.000000000 +0800 -@@ -10,4 +10,22 @@ config CLUSTER - needed by all the other components. It provides membership services - for those other subsystems. - -+config CLUSTER_DLM -+ tristate "Distributed Lock Manager" -+ depends on CLUSTER -+ ---help--- -+ A fully distributed lock manager, providing cluster-wide locking services -+ and protected lock namespaces for kernel and userland applications. -+ -+config CLUSTER_DLM_PROCLOCKS -+ boolean "/proc/locks support for DLM" -+ depends on CLUSTER_DLM -+ depends on PROC_FS -+ ---help--- -+ If this option is enabled a file will appear in /proc/cluster/dlm_locks. -+ write into this "file" the name of a lockspace known to the DLM and then -+ read out a list of all the resources and locks in that lockspace that are -+ known to the local node. Note because the DLM is distributed this may not -+ be the full lock picture. -+ - endmenu -diff -urN -p linux-2.6.8.1/cluster/Makefile linux/cluster/Makefile ---- linux-2.6.8.1/cluster/Makefile 2004-08-24 13:23:09.000000000 +0800 -+++ linux/cluster/Makefile 2004-08-24 13:23:32.000000000 +0800 -@@ -1,3 +1,4 @@ - obj-y := nocluster.o - - obj-$(CONFIG_CLUSTER) += cman/ -+obj-$(CONFIG_CLUSTER_DLM) += dlm/ -diff -urN -p linux-2.6.8.1/cluster/dlm/Makefile linux/cluster/dlm/Makefile ---- linux-2.6.8.1/cluster/dlm/Makefile 1970-01-01 07:30:00.000000000 +0730 -+++ linux/cluster/dlm/Makefile 2004-08-24 13:23:32.000000000 +0800 -@@ -0,0 +1,23 @@ -+dlm-objs := ast.o \ -+ config.o \ -+ device.o \ -+ dir.o \ -+ lkb.o \ -+ locking.o \ -+ lockqueue.o \ -+ lockspace.o \ -+ lowcomms.o \ -+ main.o \ -+ memory.o \ -+ midcomms.o \ -+ nodes.o \ -+ proc.o \ -+ queries.o \ -+ rebuild.o \ -+ reccomms.o \ -+ recover.o \ -+ recoverd.o \ -+ rsb.o \ -+ util.o \ -+ -+obj-$(CONFIG_CLUSTER_DLM) += dlm.o diff --git a/dlm-kernel/scripts/uninstall.pl b/dlm-kernel/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/dlm-kernel/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/dlm-kernel/src/Makefile b/dlm-kernel/src/Makefile deleted file mode 100644 index d038c14..0000000 --- a/dlm-kernel/src/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = .. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/linux-orig -linux_patched = ${top_srcdir}/linux-patched - -TARGET = dlm.patch - -PWD := $(shell pwd) - -obj-m := dlm.o -dlm-objs := ast.o config.o device.o dir.o lkb.o locking.o lockqueue.o \ - lockspace.o lowcomms.o main.o memory.o midcomms.o nodes.o proc.o \ - queries.o rebuild.o reccomms.o recover.o recoverd.o rsb.o util.o - -EXTRA_CFLAGS += -I$(obj) -DCONFIG_CLUSTER_DLM_PROCLOCKS -DCONFIG_DLM_STATS - -all: - if [ ! -e cluster ]; then ln -s . cluster; fi - if [ ! -e service.h ]; then cp ${incdir}/cluster/service.h .; fi - if [ ! -e cnxman.h ]; then cp ${incdir}/cluster/cnxman.h .; fi - if [ ! -e cnxman-socket.h ]; then cp ${incdir}/cluster/cnxman-socket.h .; fi - ${MAKE} -C ${KERNEL_SRC} M=${PWD} modules USING_KBUILD=yes - -install: all - install -d ${module_dir}/cluster - install dlm.ko ${module_dir}/cluster - install -d ${incdir}/cluster - install dlm.h dlm_device.h ${incdir}/cluster - -uninstall: - ${UNINSTALL} dlm.ko ${module_dir}/cluster - ${UNINSTALL} dlm.h dlm_device.h ${incdir}/cluster - - - - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir} ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/cluster/dlm - mkdir -p ${linux_patched}/include/cluster - cp *.[ch] ${linux_patched}/cluster/dlm - mv ${linux_patched}/cluster/dlm/dlm.h ${linux_patched}/include/cluster - mv ${linux_patched}/cluster/dlm/dlm_device.h ${linux_patched}/include/cluster - -clean: - rm -rf cluster *.ko *.o *.mod.c *~ .*o.cmd .tmp_versions \ - service.h cnxman.h cnxman-socket.h diff --git a/dlm-kernel/src/ast.c b/dlm-kernel/src/ast.c deleted file mode 100644 index 34645a9..0000000 --- a/dlm-kernel/src/ast.c +++ /dev/null @@ -1,652 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * This delivers ASTs and checks for dead remote requests and deadlocks. - */ - -#include <linux/timer.h> - -#include "dlm_internal.h" -#include "rsb.h" -#include "lockqueue.h" -#include "dir.h" -#include "locking.h" -#include "lkb.h" -#include "lowcomms.h" -#include "midcomms.h" -#include "ast.h" -#include "nodes.h" -#include "config.h" -#include "util.h" - -/* Wake up flags for astd */ -#define WAKE_ASTS 1 -#define WAKE_TIMER 2 - -static struct list_head ast_queue; -static struct semaphore ast_queue_lock; -static struct task_struct * astd_task; -static unsigned long astd_wakeflags; -static struct semaphore astd_running; - -static struct list_head _deadlockqueue; -static struct semaphore _deadlockqueue_lock; -static struct list_head _lockqueue; -static struct semaphore _lockqueue_lock; -static struct timer_list _lockqueue_timer; - -void add_to_lockqueue(struct dlm_lkb *lkb) -{ - /* Time stamp the entry so we know if it's been waiting too long */ - lkb->lkb_lockqueue_time = jiffies; - - down(&_lockqueue_lock); - list_add(&lkb->lkb_lockqueue, &_lockqueue); - up(&_lockqueue_lock); -} - -void remove_from_lockqueue(struct dlm_lkb *lkb) -{ - down(&_lockqueue_lock); - list_del(&lkb->lkb_lockqueue); - up(&_lockqueue_lock); - -#ifdef CONFIG_DLM_STATS - dlm_stats.lockqueue_time[lkb->lkb_lockqueue_state] += (jiffies - lkb->lkb_lockqueue_time); - dlm_stats.lockqueue_locks[lkb->lkb_lockqueue_state]++; -#endif - lkb->lkb_lockqueue_state = 0; -} - -void add_to_deadlockqueue(struct dlm_lkb *lkb) -{ - if (test_bit(LSFL_NOTIMERS, &lkb->lkb_resource->res_ls->ls_flags)) - return; - lkb->lkb_duetime = jiffies; - down(&_deadlockqueue_lock); - list_add(&lkb->lkb_deadlockq, &_deadlockqueue); - up(&_deadlockqueue_lock); -} - -void remove_from_deadlockqueue(struct dlm_lkb *lkb) -{ - if (test_bit(LSFL_NOTIMERS, &lkb->lkb_resource->res_ls->ls_flags)) - return; - - down(&_deadlockqueue_lock); - list_del(&lkb->lkb_deadlockq); - up(&_deadlockqueue_lock); - - /* Invalidate the due time */ - memset(&lkb->lkb_duetime, 0, sizeof(lkb->lkb_duetime)); -} - -void remove_from_astqueue(struct dlm_lkb *lkb) -{ - down(&ast_queue_lock); - if (lkb->lkb_astflags & (AST_COMP | AST_BAST)) - list_del(&lkb->lkb_astqueue); - up(&ast_queue_lock); -} - -/* - * Queue an AST for delivery, this will only deal with - * kernel ASTs, usermode API will piggyback on top of this. - * - * This can be called in either the user or DLM context. - * ASTs are queued EVEN IF we are already running in dlm_astd - * context as we don't know what other locks are held (eg we could - * be being called from a lock operation that was called from - * another AST! - * If the AST is to be queued remotely then a message is sent to - * the target system via midcomms. - */ - -void queue_ast(struct dlm_lkb *lkb, uint16_t flags, uint8_t rqmode) -{ - struct dlm_request req; - - if (lkb->lkb_flags & GDLM_LKFLG_MSTCPY) { - /* - * Send a message to have an ast queued remotely. Note: we do - * not send remote completion asts, they are handled as part of - * remote lock granting. - */ - if (flags & AST_BAST) { - req.rr_header.rh_cmd = GDLM_REMCMD_SENDBAST; - req.rr_header.rh_length = sizeof(req); - req.rr_header.rh_flags = 0; - req.rr_header.rh_lkid = lkb->lkb_id; - req.rr_header.rh_lockspace = - lkb->lkb_resource->res_ls->ls_global_id; - req.rr_status = lkb->lkb_retstatus; - req.rr_remlkid = lkb->lkb_remid; - req.rr_rqmode = rqmode; - - midcomms_send_message(lkb->lkb_nodeid, &req.rr_header, - lkb->lkb_resource->res_ls->ls_allocation); - } else if (lkb->lkb_retstatus == -EDEADLOCK) { - /* - * We only queue remote Completion ASTs here for error - * completions that happen out of band. - * DEADLOCK is one such. - */ - req.rr_header.rh_cmd = GDLM_REMCMD_SENDCAST; - req.rr_header.rh_length = sizeof(req); - req.rr_header.rh_flags = 0; - req.rr_header.rh_lkid = lkb->lkb_id; - req.rr_header.rh_lockspace = - lkb->lkb_resource->res_ls->ls_global_id; - req.rr_status = lkb->lkb_retstatus; - req.rr_remlkid = lkb->lkb_remid; - req.rr_rqmode = rqmode; - - midcomms_send_message(lkb->lkb_nodeid, &req.rr_header, - lkb->lkb_resource->res_ls->ls_allocation); - } - } else { - /* - * Prepare info that will be returned in ast/bast. - */ - - if (flags & AST_BAST) { - lkb->lkb_bastmode = rqmode; - } else { - lkb->lkb_lksb->sb_status = lkb->lkb_retstatus; - lkb->lkb_lksb->sb_flags = 0; - if (lkb->lkb_flags & GDLM_LKFLG_DEMOTED) - lkb->lkb_lksb->sb_flags |= DLM_SBF_DEMOTED; - if (lkb->lkb_flags & GDLM_LKFLG_VALNOTVALID) - lkb->lkb_lksb->sb_flags |= DLM_SBF_VALNOTVALID; - if (lkb->lkb_flags & GDLM_LKFLG_ALTMODE) - lkb->lkb_lksb->sb_flags |= DLM_SBF_ALTMODE; - } - - down(&ast_queue_lock); - if (!(lkb->lkb_astflags & (AST_COMP | AST_BAST))) - list_add_tail(&lkb->lkb_astqueue, &ast_queue); - lkb->lkb_astflags |= flags; - up(&ast_queue_lock); - - /* It is the responsibility of the caller to call wake_astd() - * after it has finished other locking operations that request - * the ASTs to be delivered after */ - } -} - -/* - * Process any LKBs on the AST queue. - */ - -static void process_asts(void) -{ - struct dlm_ls *ls = NULL; - struct dlm_rsb *rsb = NULL; - struct dlm_lkb *lkb; - void (*cast) (long param); - void (*bast) (long param, int mode); - long astparam; - uint16_t flags = 0, found; - - for (;;) { - found = FALSE; - down(&ast_queue_lock); - list_for_each_entry(lkb, &ast_queue, lkb_astqueue) { - rsb = lkb->lkb_resource; - ls = rsb->res_ls; - - /* don't deliver ast's for locks in lockspaces - being recovered */ - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) - continue; - - /* the ast flags must be saved and cleared while - ast_queue_lock is held */ - list_del(&lkb->lkb_astqueue); - flags = lkb->lkb_astflags; - lkb->lkb_astflags = 0; - found = TRUE; - break; - } - up(&ast_queue_lock); - - if (!found) - break; - - cast = lkb->lkb_astaddr; - bast = lkb->lkb_bastaddr; - astparam = lkb->lkb_astparam; - - if (flags & AST_COMP) { - if (flags & AST_DEL) { - DLM_ASSERT(lkb->lkb_astflags == 0,); - release_lkb(ls, lkb); - release_rsb(rsb); - } - - if (cast) { -#ifdef CONFIG_DLM_STATS - dlm_stats.cast++; -#endif - cast(astparam); - } - } - - if (flags & AST_BAST && !(flags & AST_DEL)) { - int bmode = lkb->lkb_bastmode; - - /* gr or rq mode of the lock may have changed since the - ast was queued making the delivery unnecessary */ - - if (!bast || dlm_modes_compat(lkb->lkb_grmode, bmode)) - continue; - - if (lkb->lkb_rqmode == DLM_LOCK_IV || - !dlm_modes_compat(lkb->lkb_rqmode, bmode)) { - bast(astparam, bmode); -#ifdef CONFIG_DLM_STATS - dlm_stats.bast++; -#endif - } - } - - schedule(); - } -} - -void lockqueue_lkb_mark(struct dlm_ls *ls) -{ - struct dlm_lkb *lkb, *safe; - int count = 0; - - log_debug(ls, "mark waiting requests"); - - down(&_lockqueue_lock); - - list_for_each_entry_safe(lkb, safe, &_lockqueue, lkb_lockqueue) { - - if (lkb->lkb_resource->res_ls != ls) - continue; - - schedule(); - - log_debug(ls, "mark %x lq %d nodeid %d", lkb->lkb_id, - lkb->lkb_lockqueue_state, lkb->lkb_nodeid); - - /* - * These lkb's are new and the master is being looked up. Mark - * the lkb request to be resent. Even if the destination node - * for the request is still living and has our request, it will - * purge all resdir requests in purge_requestqueue. If there's - * a reply to the LOOKUP request in our requestqueue (the reply - * arrived after ls_stop), it is invalid and will be discarded - * in purge_requestqueue, too. - */ - - if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_RSB) { - DLM_ASSERT(lkb->lkb_nodeid == -1, - print_lkb(lkb); - print_rsb(lkb->lkb_resource);); - - lkb->lkb_flags |= GDLM_LKFLG_LQRESEND; - count++; - continue; - } - - /* - * We're waiting for an unlock reply and the master node from - * whom we're expecting the reply has failed. If there's a - * reply in the requestqueue do nothing and process it later in - * process_requestqueue. If there's no reply, don't rebuild - * the lkb on a new master, but just assume we've gotten an - * unlock completion reply from the prev master (this also - * means not resending the unlock request). If the unlock is - * for the last lkb on the rsb, the rsb has nodeid of -1 and - * the rsb won't be rebuilt on the new master either. - * - * If we're waiting for an unlock reply and the master node is - * still alive, we should either have a reply in the - * requestqueue from the master already, or we should get one - * from the master once recovery is complete. There is no - * rebuilding of the rsb/lkb in this case and no resending of - * the request. - */ - - if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_UNLOCK) { - if (in_nodes_gone(ls, lkb->lkb_nodeid)) { - if (reply_in_requestqueue(ls, lkb->lkb_id)) { - lkb->lkb_flags |= GDLM_LKFLG_NOREBUILD; - log_debug(ls, "mark %x unlock have rep", - lkb->lkb_id); - } else { - /* assume we got reply fr old master */ - lkb->lkb_flags |= GDLM_LKFLG_NOREBUILD; - lkb->lkb_flags |= GDLM_LKFLG_UNLOCKDONE; - log_debug(ls, "mark %x unlock no rep", - lkb->lkb_id); - } - } - count++; - continue; - } - - /* - * These lkb's have an outstanding request to a bygone node. - * The request will be redirected to the new master node in - * resend_cluster_requests(). Don't mark the request for - * resending if there's a reply for it saved in the - * requestqueue. - */ - - if (in_nodes_gone(ls, lkb->lkb_nodeid) && - !reply_in_requestqueue(ls, lkb->lkb_id)) { - - lkb->lkb_flags |= GDLM_LKFLG_LQRESEND; - - /* - * Don't rebuild this lkb on a new rsb in - * rebuild_rsbs_send(). - */ - - if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_CONDGRANT) { - DLM_ASSERT(lkb->lkb_status == GDLM_LKSTS_WAITING, - print_lkb(lkb); - print_rsb(lkb->lkb_resource);); - lkb->lkb_flags |= GDLM_LKFLG_NOREBUILD; - } - - /* - * This flag indicates to the new master that his lkb - * is in the midst of a convert request and should be - * placed on the granted queue rather than the convert - * queue. We will resend this convert request to the - * new master. - */ - - else if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_CONVERT) { - DLM_ASSERT(lkb->lkb_status == GDLM_LKSTS_CONVERT, - print_lkb(lkb); - print_rsb(lkb->lkb_resource);); - lkb->lkb_flags |= GDLM_LKFLG_LQCONVERT; - } - - count++; - } - } - up(&_lockqueue_lock); - - log_debug(ls, "marked %d requests", count); -} - -int resend_cluster_requests(struct dlm_ls *ls) -{ - struct dlm_lkb *lkb, *safe; - struct dlm_rsb *r; - int error = 0, state, count = 0; - - log_debug(ls, "resend marked requests"); - - down(&_lockqueue_lock); - - list_for_each_entry_safe(lkb, safe, &_lockqueue, lkb_lockqueue) { - - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) { - log_debug(ls, "resend_cluster_requests: aborted"); - error = -EINTR; - break; - } - - schedule(); - - r = lkb->lkb_resource; - - if (r->res_ls != ls) - continue; - - log_debug(ls, "resend %x lq %d flg %x node %d/%d "%s"", - lkb->lkb_id, lkb->lkb_lockqueue_state, lkb->lkb_flags, - lkb->lkb_nodeid, r->res_nodeid, r->res_name); - - if (lkb->lkb_flags & GDLM_LKFLG_UNLOCKDONE) { - log_debug(ls, "unlock done %x", lkb->lkb_id); - list_del(&lkb->lkb_lockqueue); - res_lkb_dequeue(lkb); - lkb->lkb_retstatus = -DLM_EUNLOCK; - queue_ast(lkb, AST_COMP | AST_DEL, 0); - count++; - continue; - } - - /* - * Resend/process the lockqueue lkb's (in-progres requests) - * that were flagged at the start of recovery in - * lockqueue_lkb_mark(). - */ - - if (lkb->lkb_flags & GDLM_LKFLG_LQRESEND) { - lkb->lkb_flags &= ~GDLM_LKFLG_LQRESEND; - lkb->lkb_flags &= ~GDLM_LKFLG_NOREBUILD; - lkb->lkb_flags &= ~GDLM_LKFLG_LQCONVERT; - - if (lkb->lkb_nodeid == -1) { - /* - * Send lookup to new resdir node. - */ - lkb->lkb_lockqueue_time = jiffies; - send_cluster_request(lkb, - lkb->lkb_lockqueue_state); - } - - else if (lkb->lkb_nodeid != 0) { - /* - * There's a new RSB master (that's not us.) - */ - lkb->lkb_lockqueue_time = jiffies; - send_cluster_request(lkb, - lkb->lkb_lockqueue_state); - } - - else { - /* - * We are the new RSB master for this lkb - * request. - */ - state = lkb->lkb_lockqueue_state; - lkb->lkb_lockqueue_state = 0; - /* list_del equals remove_from_lockqueue() */ - list_del(&lkb->lkb_lockqueue); - process_remastered_lkb(ls, lkb, state); - } - - count++; - } - } - up(&_lockqueue_lock); - - log_debug(ls, "resent %d requests", count); - return error; -} - -/* - * Process any LKBs on the Lock queue, this - * just looks at the entries to see if they have been - * on the queue too long and fails the requests if so. - */ - -static void process_lockqueue(void) -{ - struct dlm_lkb *lkb, *safe; - struct dlm_ls *ls; - int count = 0; - - down(&_lockqueue_lock); - - list_for_each_entry_safe(lkb, safe, &_lockqueue, lkb_lockqueue) { - ls = lkb->lkb_resource->res_ls; - - if (test_bit(LSFL_NOTIMERS, &ls->ls_flags)) - continue; - - /* Don't time out locks that are in transition */ - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) - continue; - - if (check_timeout(lkb->lkb_lockqueue_time, - dlm_config.lock_timeout)) { - count++; - list_del(&lkb->lkb_lockqueue); - up(&_lockqueue_lock); - cancel_lockop(lkb, -ETIMEDOUT); - down(&_lockqueue_lock); - } - } - up(&_lockqueue_lock); - - if (count) - wake_astd(); - - mod_timer(&_lockqueue_timer, - jiffies + ((dlm_config.lock_timeout >> 1) * HZ)); -} - -/* Look for deadlocks */ -static void process_deadlockqueue(void) -{ - struct dlm_lkb *lkb, *safe; - - down(&_deadlockqueue_lock); - - list_for_each_entry_safe(lkb, safe, &_deadlockqueue, lkb_deadlockq) { - struct dlm_lkb *kill_lkb; - - /* Only look at "due" locks */ - if (!check_timeout(lkb->lkb_duetime, dlm_config.deadlocktime)) - break; - - /* Don't look at locks that are in transition */ - if (!test_bit(LSFL_LS_RUN, - &lkb->lkb_resource->res_ls->ls_flags)) - continue; - - up(&_deadlockqueue_lock); - - /* Lock has hit due time, check for conversion deadlock */ - kill_lkb = conversion_deadlock_check(lkb); - if (kill_lkb) - cancel_conversion(kill_lkb, -EDEADLOCK); - - down(&_deadlockqueue_lock); - } - up(&_deadlockqueue_lock); -} - -static __inline__ int no_asts(void) -{ - int ret; - - down(&ast_queue_lock); - ret = list_empty(&ast_queue); - up(&ast_queue_lock); - return ret; -} - -static void lockqueue_timer_fn(unsigned long arg) -{ - set_bit(WAKE_TIMER, &astd_wakeflags); - wake_up_process(astd_task); -} - -/* - * DLM daemon which delivers asts. - */ - -static int dlm_astd(void *data) -{ - /* - * Set a timer to check the lockqueue for dead locks (and deadlocks). - */ - INIT_LIST_HEAD(&_lockqueue); - init_MUTEX(&_lockqueue_lock); - INIT_LIST_HEAD(&_deadlockqueue); - init_MUTEX(&_deadlockqueue_lock); - init_timer(&_lockqueue_timer); - _lockqueue_timer.function = lockqueue_timer_fn; - _lockqueue_timer.data = 0; - mod_timer(&_lockqueue_timer, - jiffies + ((dlm_config.lock_timeout >> 1) * HZ)); - - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - if (!test_bit(WAKE_ASTS, &astd_wakeflags)) - schedule(); - set_current_state(TASK_RUNNING); - - down(&astd_running); - if (test_and_clear_bit(WAKE_ASTS, &astd_wakeflags)) - process_asts(); - - if (test_and_clear_bit(WAKE_TIMER, &astd_wakeflags)) { - process_lockqueue(); - if (dlm_config.deadlocktime) - process_deadlockqueue(); - } - up(&astd_running); - } - - if (timer_pending(&_lockqueue_timer)) - del_timer(&_lockqueue_timer); - - return 0; -} - -void wake_astd(void) -{ - if (!no_asts()) { - set_bit(WAKE_ASTS, &astd_wakeflags); - wake_up_process(astd_task); - } -} - -int astd_start(void) -{ - struct task_struct *p; - int error = 0; - - INIT_LIST_HEAD(&ast_queue); - init_MUTEX(&ast_queue_lock); - init_MUTEX(&astd_running); - - p = kthread_run(dlm_astd, NULL, "dlm_astd"); - if (IS_ERR(p)) - error = PTR_ERR(p); - else - astd_task = p; - return error; -} - -void astd_stop(void) -{ - kthread_stop(astd_task); -} - -void astd_suspend(void) -{ - down(&astd_running); -} - -void astd_resume(void) -{ - up(&astd_running); -} - diff --git a/dlm-kernel/src/ast.h b/dlm-kernel/src/ast.h deleted file mode 100644 index 162959e..0000000 --- a/dlm-kernel/src/ast.h +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __AST_DOT_H__ -#define __AST_DOT_H__ - -void lockqueue_lkb_mark(struct dlm_ls *ls); -int resend_cluster_requests(struct dlm_ls *ls); -void add_to_lockqueue(struct dlm_lkb *lkb); -void remove_from_lockqueue(struct dlm_lkb *lkb); -void add_to_deadlockqueue(struct dlm_lkb *lkb); -void remove_from_deadlockqueue(struct dlm_lkb *lkb); -void remove_from_astqueue(struct dlm_lkb *lkb); -void queue_ast(struct dlm_lkb *lkb, uint16_t astflags, uint8_t rqmode); -void wake_astd(void); -int astd_start(void); -void astd_stop(void); -void astd_suspend(void); -void astd_resume(void); - -#endif /* __AST_DOT_H__ */ diff --git a/dlm-kernel/src/config.c b/dlm-kernel/src/config.c deleted file mode 100644 index a0554b1..0000000 --- a/dlm-kernel/src/config.c +++ /dev/null @@ -1,163 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/module.h> -#include <linux/proc_fs.h> - -#include "dlm_internal.h" -#include "lowcomms.h" -#include "config.h" - -/* Config file defaults */ -#define DEFAULT_TCP_PORT 21064 -#define DEFAULT_TCP_NODELAY 0 -#define DEFAULT_LOCK_TIMEOUT 120 -#define DEFAULT_BUFFER_SIZE 4096 -#define DEFAULT_RSBTBL_SIZE 256 -#define DEFAULT_LKBTBL_SIZE 1024 -#define DEFAULT_DIRTBL_SIZE 512 -#define DEFAULT_CONN_INCREMENT 32 -#define DEFAULT_DEADLOCKTIME 10 -#define DEFAULT_RECOVER_TIMER 5 -#define DEFAULT_USER_GRANT_NOW 1 -#define DEFAULT_CLOSE_PURGE 0 - -struct config_info dlm_config = { - .tcp_port = DEFAULT_TCP_PORT, - .tcp_nodelay = DEFAULT_TCP_NODELAY, - .lock_timeout = DEFAULT_LOCK_TIMEOUT, - .buffer_size = DEFAULT_BUFFER_SIZE, - .rsbtbl_size = DEFAULT_RSBTBL_SIZE, - .lkbtbl_size = DEFAULT_LKBTBL_SIZE, - .dirtbl_size = DEFAULT_DIRTBL_SIZE, - .conn_increment = DEFAULT_CONN_INCREMENT, - .deadlocktime = DEFAULT_DEADLOCKTIME, - .recover_timer = DEFAULT_RECOVER_TIMER, - .user_grant_now = DEFAULT_USER_GRANT_NOW, - .close_purge = DEFAULT_CLOSE_PURGE -}; - - -static struct config_proc_info { - char *name; - int *value; -} config_proc[] = { - { - .name = "tcp_port", - .value = &dlm_config.tcp_port, - }, - { - .name = "tcp_nodelay", - .value = &dlm_config.tcp_nodelay, - }, - { - .name = "lock_timeout", - .value = &dlm_config.lock_timeout, - }, - { - .name = "buffer_size", - .value = &dlm_config.buffer_size, - }, - { - .name = "rsbtbl_size", - .value = &dlm_config.rsbtbl_size, - }, - { - .name = "lkbtbl_size", - .value = &dlm_config.lkbtbl_size, - }, - { - .name = "dirtbl_size", - .value = &dlm_config.dirtbl_size, - }, - { - .name = "conn_increment", - .value = &dlm_config.conn_increment, - }, - { - .name = "deadlocktime", - .value = &dlm_config.deadlocktime, - }, - { - .name = "recover_timer", - .value = &dlm_config.recover_timer, - }, - { - .name = "user_grant_now", - .value = &dlm_config.user_grant_now, - }, - { - .name = "close_purge", - .value = &dlm_config.close_purge, - } -}; -static struct proc_dir_entry *dlm_dir; - -static int dlm_config_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct config_proc_info *cinfo = data; - return snprintf(page, count, "%d\n", *cinfo->value); -} - -static int dlm_config_write_proc(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - struct config_proc_info *cinfo = data; - char buff[11]; - int value; - int num; - char *end; - - num = (count < 10) ? count : 10; - if (copy_from_user(buff, buffer, num)) - return -EFAULT; - - buff[num] = '\0'; - value = simple_strtoul(buff, &end, 10); - if (*end) { - *cinfo->value = value; - } - return count; -} - -int dlm_config_init(void) -{ - int i; - struct proc_dir_entry *pde; - - dlm_dir = proc_mkdir("cluster/config/dlm", 0); - if (!dlm_dir) - return -1; - - dlm_dir->owner = THIS_MODULE; - - for (i=0; i<sizeof(config_proc)/sizeof(struct config_proc_info); i++) { - pde = create_proc_entry(config_proc[i].name, 0660, dlm_dir); - if (pde) { - pde->data = &config_proc[i]; - pde->write_proc = dlm_config_write_proc; - pde->read_proc = dlm_config_read_proc; - } - } - return 0; -} - -void dlm_config_exit(void) -{ - int i; - - for (i=0; i<sizeof(config_proc)/sizeof(struct config_proc_info); i++) - remove_proc_entry(config_proc[i].name, dlm_dir); - remove_proc_entry("cluster/config/dlm", NULL); -} diff --git a/dlm-kernel/src/config.h b/dlm-kernel/src/config.h deleted file mode 100644 index d8c92f0..0000000 --- a/dlm-kernel/src/config.h +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __CONFIG_DOT_H__ -#define __CONFIG_DOT_H__ - -struct config_info { - int tcp_port; - int tcp_nodelay; - int lock_timeout; - int buffer_size; - int rsbtbl_size; - int lkbtbl_size; - int dirtbl_size; - int conn_increment; - int deadlocktime; - int recover_timer; - int user_grant_now; - int close_purge; -}; - -extern struct config_info dlm_config; -extern int dlm_config_init(void); -extern void dlm_config_exit(void); - -#endif /* __CONFIG_DOT_H__ */ diff --git a/dlm-kernel/src/device.c b/dlm-kernel/src/device.c deleted file mode 100644 index 018ca03..0000000 --- a/dlm-kernel/src/device.c +++ /dev/null @@ -1,1374 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * device.c - * - * This is the userland interface to the DLM. - * - * The locking is done via a misc char device (find the - * registered minor number in /proc/misc). - * - * User code should not use this interface directly but - * call the library routines in libdlm.a instead. - * - */ - -#include <linux/miscdevice.h> -#include <linux/init.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/file.h> -#include <linux/fs.h> -#include <linux/poll.h> -#include <linux/signal.h> -#include <linux/spinlock.h> -#include <asm/ioctls.h> - -#include "dlm_internal.h" -#include "device.h" -#include "config.h" -#include "lockspace.h" -#include "rsb.h" -#include "lockqueue.h" -#include "nodes.h" - -extern struct dlm_lkb *dlm_get_lkb(struct dlm_ls *, int); -static struct file_operations _dlm_fops; -static const char *name_prefix="dlm"; -static struct list_head user_ls_list; -static struct semaphore user_ls_lock; - -/* Flags in li_flags */ -#define LI_FLAG_COMPLETE 1 -#define LI_FLAG_FIRSTLOCK 2 -#define LI_FLAG_ONLIST 3 - -/* flags in ls_flags */ -#define LS_FLAG_DELETED 1 -#define LS_FLAG_AUTOFREE 2 -#define LS_FLAG_DEFAULT 3 - - -#define LOCKINFO_MAGIC 0x53595324 - -struct lock_info { - uint32_t li_magic; - uint8_t li_cmd; - struct dlm_lksb li_lksb; - wait_queue_head_t li_waitq; - unsigned long li_flags; - void __user *li_castparam; - void __user *li_castaddr; - void __user *li_bastparam; - void __user *li_bastaddr; - void __user *li_pend_bastparam; - void __user *li_pend_bastaddr; - struct list_head li_ownerqueue; - struct file_info *li_file; - struct dlm_lksb __user *li_user_lksb; - struct semaphore li_firstlock; - struct dlm_queryinfo *li_queryinfo; - struct dlm_queryinfo __user *li_user_queryinfo; -}; - -/* A queued AST no less */ -struct ast_info { - struct dlm_lock_result result; - struct dlm_queryinfo *queryinfo; - struct dlm_queryinfo __user *user_queryinfo; - struct list_head list; - uint32_t lvb_updated; - uint32_t progress; /* How much has been read */ -}; - -/* One of these per userland lockspace */ -struct user_ls { - void *ls_lockspace; - atomic_t ls_refcnt; - long ls_flags; - - /* Passed into misc_register() */ - struct miscdevice ls_miscinfo; - struct list_head ls_list; -}; - -/* misc_device info for the control device */ -static struct miscdevice ctl_device; - -/* Bit 1 of this is set when we have a default ls */ -static long default_ls; - -/* - * Stuff we hang off the file struct. - * The first two are to cope with unlocking all the - * locks help by a process when it dies. - */ -struct file_info { - struct list_head fi_lkb_list; /* List of active lkbs */ - spinlock_t fi_lkb_lock; - struct list_head fi_ast_list; /* Queue of ASTs to be delivered */ - spinlock_t fi_ast_lock; - wait_queue_head_t fi_wait; - struct user_ls *fi_ls; - atomic_t fi_refcnt; /* Number of users */ - unsigned long fi_flags; /* Bit 1 means the device is open */ - int fi_pid; -}; - - -/* get and put ops for file_info. - Actually I don't really like "get" and "put", but everyone - else seems to use them and I can't think of anything - nicer at the moment */ -static void get_file_info(struct file_info *f) -{ - atomic_inc(&f->fi_refcnt); -} - -static void put_file_info(struct file_info *f) -{ - if (atomic_dec_and_test(&f->fi_refcnt)) - kfree(f); -} - -static void release_lockinfo(struct lock_info *li) -{ - put_file_info(li->li_file); - if (li->li_lksb.sb_lvbptr) - kfree(li->li_lksb.sb_lvbptr); - kfree(li); -} - -static struct user_ls *__find_lockspace(int minor) -{ - struct user_ls *lsinfo; - - list_for_each_entry(lsinfo, &user_ls_list, ls_list) { - - if (lsinfo->ls_miscinfo.minor == minor) - return lsinfo; - } - return NULL; -} - -/* Find a lockspace struct given the device minor number */ -static struct user_ls *find_lockspace(int minor) -{ - struct user_ls *lsinfo; - - down(&user_ls_lock); - lsinfo = __find_lockspace(minor); - up(&user_ls_lock); - - return lsinfo; -} - -static void add_lockspace_to_list(struct user_ls *lsinfo) -{ - down(&user_ls_lock); - list_add(&lsinfo->ls_list, &user_ls_list); - up(&user_ls_lock); -} - -/* Register a lockspace with the DLM and create a misc - device for userland to access it */ -static int register_lockspace(char *name, struct user_ls **ls, int flags) -{ - struct dlm_ls *dlmls; - struct user_ls *newls; - int status; - int namelen; - - namelen = strlen(name)+strlen(name_prefix)+2; - - newls = kmalloc(sizeof(struct user_ls), GFP_KERNEL); - if (!newls) - return -ENOMEM; - memset(newls, 0, sizeof(struct user_ls)); - - newls->ls_miscinfo.name = kmalloc(namelen, GFP_KERNEL); - if (!newls->ls_miscinfo.name) { - kfree(newls); - return -ENOMEM; - } - status = dlm_new_lockspace(name, strlen(name), - &newls->ls_lockspace, 0); - - if (status != 0) { - kfree(newls->ls_miscinfo.name); - kfree(newls); - return status; - } - - snprintf((char*)newls->ls_miscinfo.name, namelen, "%s_%s", name_prefix, name); - - newls->ls_miscinfo.fops = &_dlm_fops; - newls->ls_miscinfo.minor = MISC_DYNAMIC_MINOR; - - status = misc_register(&newls->ls_miscinfo); - if (status) { - log_print("failed to register misc device for %s", name); - dlm_release_lockspace(newls->ls_lockspace, 0); - kfree(newls->ls_miscinfo.name); - kfree(newls); - return status; - } - - if (flags & DLM_USER_LSFLG_AUTOFREE) - set_bit(LS_FLAG_AUTOFREE, &newls->ls_flags); - if (flags & DLM_USER_LSFLG_DEFAULTLS) - set_bit(LS_FLAG_DEFAULT, &newls->ls_flags); - - dlmls = find_lockspace_by_name(name, strlen(name)); - if (!dlmls) { - log_print("skip GRANT_NOW flag, lockspace not found"); - } else { - if (dlm_config.user_grant_now) - set_bit(LSFL_USER_GRANT_NOW, &dlmls->ls_flags); - } - - add_lockspace_to_list(newls); - *ls = newls; - return 0; -} - -/* Called with the user_ls_lock semaphore held */ -static int unregister_lockspace(struct user_ls *lsinfo, int force) -{ - int status = 0; - - if (atomic_read(&lsinfo->ls_refcnt) == 0) { - status = dlm_release_lockspace(lsinfo->ls_lockspace, force); - if (status) - return status; - - status = misc_deregister(&lsinfo->ls_miscinfo); - if (status) - return status; - - list_del(&lsinfo->ls_list); - set_bit(LS_FLAG_DELETED, &lsinfo->ls_flags); - lsinfo->ls_lockspace = NULL; - if (test_bit(LS_FLAG_DEFAULT, &lsinfo->ls_flags)) - clear_bit(1, &default_ls); - - - kfree(lsinfo->ls_miscinfo.name); - kfree(lsinfo); - } - else { - status = -EBUSY; - } - - return status; -} - -/* Add it to userland's AST queue */ -static void add_to_astqueue(struct lock_info *li, void *astaddr, void *astparam, - int lvb_updated) -{ - struct ast_info *ast = kmalloc(sizeof(struct ast_info), GFP_KERNEL); - if (!ast) - return; - - memset(ast, 0, sizeof(*ast)); - ast->result.user_astparam = astparam; - ast->result.user_astaddr = astaddr; - ast->result.user_lksb = li->li_user_lksb; - ast->result.user_qinfo = li->li_user_queryinfo; - memcpy(&ast->result.lksb, &li->li_lksb, sizeof(struct dlm_lksb)); - - ast->queryinfo = li->li_queryinfo; - ast->lvb_updated = lvb_updated; - - spin_lock(&li->li_file->fi_ast_lock); - list_add_tail(&ast->list, &li->li_file->fi_ast_list); - spin_unlock(&li->li_file->fi_ast_lock); - wake_up_interruptible(&li->li_file->fi_wait); -} - -static void bast_routine(void *param, int mode) -{ - struct lock_info *li = param; - - if (li && li->li_bastaddr) { - add_to_astqueue(li, li->li_bastaddr, li->li_bastparam, 0); - } -} - -/* - * This is the kernel's AST routine. - * All lock, unlock & query operations complete here. - * The only syncronous ops are those done during device close. - */ -static void ast_routine(void *param) -{ - struct lock_info *li = param; - - /* Param may be NULL if a persistent lock is unlocked by someone else */ - if (!li) - return; - - /* If this is a succesful conversion then activate the blocking ast - * args from the conversion request */ - if (!test_bit(LI_FLAG_FIRSTLOCK, &li->li_flags) && - li->li_lksb.sb_status == 0) { - - li->li_bastparam = li->li_pend_bastparam; - li->li_bastaddr = li->li_pend_bastaddr; - li->li_pend_bastaddr = NULL; - } - - /* If it's an async request then post data to the user's AST queue. */ - if (li->li_castaddr) { - int lvb_updated = 0; - struct dlm_lkb *lkb; - - /* See if the lvb has been updated */ - lkb = dlm_get_lkb(li->li_file->fi_ls->ls_lockspace, li->li_lksb.sb_lkid); - if (lkb && lkb->lkb_flags & GDLM_LKFLG_RETURNLVB) - lvb_updated = 1; - - /* Only queue AST if the device is still open */ - if (test_bit(1, &li->li_file->fi_flags)) - add_to_astqueue(li, li->li_castaddr, li->li_castparam, lvb_updated); - - /* If it's a new lock operation that failed, then - * remove it from the owner queue and free the - * lock_info. The DLM will not free the LKB until this - * AST has completed. - */ - if (test_and_clear_bit(LI_FLAG_FIRSTLOCK, &li->li_flags) && - li->li_lksb.sb_status != 0) { - struct dlm_lkb *lkb; - - /* Wait till dlm_lock() has finished */ - down(&li->li_firstlock); - up(&li->li_firstlock); - - /* If the LKB has been freed then we need to tidy up too */ - lkb = dlm_get_lkb(li->li_file->fi_ls->ls_lockspace, li->li_lksb.sb_lkid); - if (!lkb && test_bit(LI_FLAG_ONLIST, &li->li_flags)) { - spin_lock(&li->li_file->fi_lkb_lock); - list_del(&li->li_ownerqueue); - clear_bit(LI_FLAG_ONLIST, &li->li_flags); - spin_unlock(&li->li_file->fi_lkb_lock); - release_lockinfo(li); - } - return; - } - /* Free unlocks & queries */ - if ((li->li_lksb.sb_status == -DLM_EUNLOCK && !lkb) || - li->li_cmd == DLM_USER_QUERY) { - release_lockinfo(li); - } - } - else { - /* Synchronous request, just wake up the caller */ - set_bit(LI_FLAG_COMPLETE, &li->li_flags); - wake_up_interruptible(&li->li_waitq); - } -} - -/* - * Wait for the lock op to complete and return the status. - */ -static int wait_for_ast(struct lock_info *li) -{ - /* Wait for the AST routine to complete */ - set_task_state(current, TASK_INTERRUPTIBLE); - while (!test_bit(LI_FLAG_COMPLETE, &li->li_flags)) - schedule(); - - set_task_state(current, TASK_RUNNING); - - return li->li_lksb.sb_status; -} - - -/* Open on control device */ -static int dlm_ctl_open(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - return 0; -} - -/* Close on control device */ -static int dlm_ctl_close(struct inode *inode, struct file *file) -{ - return 0; -} - -/* Open on lockspace device */ -static int dlm_open(struct inode *inode, struct file *file) -{ - struct file_info *f; - struct user_ls *lsinfo; - - lsinfo = find_lockspace(iminor(inode)); - if (!lsinfo) - return -ENOENT; - - f = kmalloc(sizeof(struct file_info), GFP_KERNEL); - if (!f) - return -ENOMEM; - - atomic_inc(&lsinfo->ls_refcnt); - INIT_LIST_HEAD(&f->fi_lkb_list); - INIT_LIST_HEAD(&f->fi_ast_list); - spin_lock_init(&f->fi_ast_lock); - spin_lock_init(&f->fi_lkb_lock); - init_waitqueue_head(&f->fi_wait); - f->fi_ls = lsinfo; - atomic_set(&f->fi_refcnt, 1); - f->fi_flags = 0; - set_bit(1, &f->fi_flags); - f->fi_pid = 0; - - file->private_data = f; - - return 0; -} - -/* Check the user's version matches ours */ -static int check_version(struct dlm_write_request *req) -{ - if (req->version[0] != DLM_DEVICE_VERSION_MAJOR || - (req->version[0] == DLM_DEVICE_VERSION_MAJOR && - req->version[1] > DLM_DEVICE_VERSION_MINOR)) { - - log_print("version mismatch user (%d.%d.%d) kernel (%d.%d.%d)", - req->version[0], - req->version[1], - req->version[2], - DLM_DEVICE_VERSION_MAJOR, - DLM_DEVICE_VERSION_MINOR, - DLM_DEVICE_VERSION_PATCH); - return -EINVAL; - } - return 0; -} - -static int dlm_close_purge(struct inode *inode, struct file *file) -{ - struct file_info *f = file->private_data; - struct lock_info *old_li, *safe; - sigset_t tmpsig; - sigset_t allsigs; - struct user_ls *lsinfo; - struct dlm_ls *ls; - int lkb_count = 0, li_count = 0; - int pid = f->fi_pid; - int ournodeid = our_nodeid(); - - lsinfo = find_lockspace(iminor(inode)); - if (!lsinfo) - return -ENOENT; - - if (pid != current->pid) { - printk("close_purge by different pid %d first %d\n", - current->pid, pid); - } - - /* Mark this closed so that ASTs will not be delivered any more */ - clear_bit(1, &f->fi_flags); - - /* Block signals while we are doing this */ - sigfillset(&allsigs); - sigprocmask(SIG_BLOCK, &allsigs, &tmpsig); - - list_for_each_entry_safe(old_li, safe, &f->fi_lkb_list, li_ownerqueue) { - struct dlm_lkb *lkb; - - lkb = dlm_get_lkb(f->fi_ls->ls_lockspace, old_li->li_lksb.sb_lkid); - if (lkb) { - lkb->lkb_astparam = (long)NULL; - lkb_count++; - } - - list_del(&old_li->li_ownerqueue); - kfree(old_li); - put_file_info(f); - li_count++; - } - - printk("dlm_close_purge our_nodeid %d pid %d lkb_count %d li_count %d\n", - ournodeid, pid, lkb_count, li_count); - - ls = find_lockspace_by_local_id(lsinfo->ls_lockspace); - if (!ls) { - printk("dlm_purge: no lockspace found\n"); - goto out; - } - - send_purge_all(ls, ournodeid, pid); - dlm_purge(ls, ournodeid, pid, -1); - - /* must happen prior to dlm_release_lockspace() */ - put_lockspace(ls); - out: - /* - * If this is the last reference to the lockspace - * then free the struct. If it's an AUTOFREE lockspace - * then free the whole thing. - */ - down(&user_ls_lock); - if (atomic_dec_and_test(&lsinfo->ls_refcnt)) { - - if (lsinfo->ls_lockspace) { - if (test_bit(LS_FLAG_AUTOFREE, &lsinfo->ls_flags)) { - unregister_lockspace(lsinfo, 1); - } - } - else { - kfree(lsinfo->ls_miscinfo.name); - kfree(lsinfo); - } - } - up(&user_ls_lock); - put_file_info(f); - - /* Restore signals */ - sigprocmask(SIG_SETMASK, &tmpsig, NULL); - recalc_sigpending(); - - return 0; -} - -/* Close on lockspace device */ -static int dlm_close_unlock(struct inode *inode, struct file *file) -{ - struct file_info *f = file->private_data; - struct lock_info li; - struct lock_info *old_li, *safe; - sigset_t tmpsig; - sigset_t allsigs; - struct user_ls *lsinfo; - DECLARE_WAITQUEUE(wq, current); - - lsinfo = find_lockspace(iminor(inode)); - if (!lsinfo) - return -ENOENT; - - /* Mark this closed so that ASTs will not be delivered any more */ - clear_bit(1, &f->fi_flags); - - /* Block signals while we are doing this */ - sigfillset(&allsigs); - sigprocmask(SIG_BLOCK, &allsigs, &tmpsig); - - /* We use our own lock_info struct here, so that any - * outstanding "real" ASTs will be delivered with the - * corresponding "real" params, thus freeing the lock_info - * that belongs the lock. This catches the corner case where - * a lock is BUSY when we try to unlock it here - */ - memset(&li, 0, sizeof(li)); - clear_bit(LI_FLAG_COMPLETE, &li.li_flags); - init_waitqueue_head(&li.li_waitq); - add_wait_queue(&li.li_waitq, &wq); - - /* - * Free any outstanding locks, they are on the - * list in LIFO order so there should be no problems - * about unlocking parents before children. - * Although we don't remove the lkbs from the list here - * (what would be the point?), foreach_safe is needed - * because the lkbs are freed during dlm_unlock operations - */ - list_for_each_entry_safe(old_li, safe, &f->fi_lkb_list, li_ownerqueue) { - int status = 0; - int lock_status; - int flags = 0; - struct dlm_lkb *lkb; - - lkb = dlm_get_lkb(f->fi_ls->ls_lockspace, old_li->li_lksb.sb_lkid); - - /* Don't unlock persistent locks */ - if (lkb && lkb->lkb_flags & GDLM_LKFLG_PERSISTENT) { - list_del(&old_li->li_ownerqueue); - - /* Update master copy */ - if (lkb->lkb_resource->res_nodeid) { - li.li_lksb.sb_lkid = lkb->lkb_id; - status = dlm_lock(f->fi_ls->ls_lockspace, - lkb->lkb_grmode, &li.li_lksb, - DLM_LKF_CONVERT|DLM_LKF_ORPHAN, - NULL, 0, 0, ast_routine, &li, - NULL, NULL); - if (status == 0) - wait_for_ast(&li); - } - lkb->lkb_flags |= GDLM_LKFLG_ORPHAN; - - /* But tidy our references in it */ - kfree(old_li); - lkb->lkb_astparam = (long)NULL; - put_file_info(f); - - continue; - } - - clear_bit(LI_FLAG_COMPLETE, &li.li_flags); - - /* If the LKB has gone, then there's nothing to unlock */ - if (lkb) { - /* If it's not granted then cancel the request. - * If the lock was WAITING then it will be dropped, - * if it was converting then it will be reverted to GRANTED, - * then we will unlock it. - */ - lock_status = lkb->lkb_status; - - if (lock_status != GDLM_LKSTS_GRANTED) - flags = DLM_LKF_CANCEL; - - if (lkb->lkb_grmode >= DLM_LOCK_PW) - flags |= DLM_LKF_IVVALBLK; - - status = dlm_unlock(f->fi_ls->ls_lockspace, lkb->lkb_id, flags, &li.li_lksb, &li); - - /* Must wait for it to complete as the next lock could be its - * parent */ - if (status == 0) - wait_for_ast(&li); - - /* If it was waiting for a conversion, it will - now be granted so we can unlock it properly */ - if (lock_status == GDLM_LKSTS_CONVERT || status == -EBUSY) { - do { - flags &= ~DLM_LKF_CANCEL; - clear_bit(LI_FLAG_COMPLETE, &li.li_flags); - status = dlm_unlock(f->fi_ls->ls_lockspace, lkb->lkb_id, flags, &li.li_lksb, &li); - - if (status == 0) - wait_for_ast(&li); - - if (status == -EBUSY) - msleep(1); - - } while (status == -EBUSY); - } - } - - /* Unlock suceeded, free the lock_info struct. */ - if (status == 0) { - kfree(old_li); - put_file_info(f); - } - } - - remove_wait_queue(&li.li_waitq, &wq); - - /* - * If this is the last reference to the lockspace - * then free the struct. If it's an AUTOFREE lockspace - * then free the whole thing. - */ - down(&user_ls_lock); - if (atomic_dec_and_test(&lsinfo->ls_refcnt)) { - - if (lsinfo->ls_lockspace) { - if (test_bit(LS_FLAG_AUTOFREE, &lsinfo->ls_flags)) { - unregister_lockspace(lsinfo, 1); - } - } - else { - kfree(lsinfo->ls_miscinfo.name); - kfree(lsinfo); - } - } - up(&user_ls_lock); - put_file_info(f); - - /* Restore signals */ - sigprocmask(SIG_SETMASK, &tmpsig, NULL); - recalc_sigpending(); - - return 0; -} - -static int dlm_close(struct inode *inode, struct file *file) -{ - if (dlm_config.close_purge) - return dlm_close_purge(inode, file); - else - return dlm_close_unlock(inode, file); -} - -/* - * ioctls to create/remove lockspaces, and check how many - * outstanding ASTs there are against a particular LS. - */ -static int dlm_ioctl(struct inode *inode, struct file *file, - uint command, ulong u) -{ - struct file_info *fi = file->private_data; - int status = -EINVAL; - int count; - struct list_head *tmp_list; - - switch (command) { - - /* Are there any ASTs for us to read? - * Warning, this returns the number of messages (ASTs) - * in the queue, NOT the number of bytes to read - */ - case FIONREAD: - count = 0; - spin_lock(&fi->fi_ast_lock); - list_for_each(tmp_list, &fi->fi_ast_list) - count++; - spin_unlock(&fi->fi_ast_lock); - status = put_user(count, (int *)u); - break; - - default: - return -ENOTTY; - } - - return status; -} - -static int do_user_create_lockspace(struct file_info *fi, uint8_t cmd, - struct dlm_lspace_params *kparams) -{ - int status; - struct user_ls *lsinfo; - - if (!capable(CAP_SYS_ADMIN) && !(kparams->flags & DLM_USER_LSFLG_DEFAULTLS)) - return -EPERM; - - if (kparams->flags & DLM_USER_LSFLG_DEFAULTLS && test_and_set_bit(1, &default_ls)) - return -EEXIST; - - status = register_lockspace(kparams->name, &lsinfo, kparams->flags); - - /* If it succeeded then return the minor number */ - if (status == 0) - status = lsinfo->ls_miscinfo.minor; - - return status; -} - -static int do_user_remove_lockspace(struct file_info *fi, uint8_t cmd, - struct dlm_lspace_params *kparams) -{ - int status; - int force = 1; - struct user_ls *lsinfo; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - down(&user_ls_lock); - lsinfo = __find_lockspace(kparams->minor); - if (!lsinfo) { - up(&user_ls_lock); - return -EINVAL; - } - - if (kparams->flags & DLM_USER_LSFLG_FORCEFREE) - force = 2; - - status = unregister_lockspace(lsinfo, force); - up(&user_ls_lock); - - return status; -} - -/* Read call, might block if no ASTs are waiting. - * It will only ever return one message at a time, regardless - * of how many are pending. - */ -static ssize_t dlm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) -{ - struct file_info *fi = file->private_data; - struct ast_info *ast; - int data_size; - int offset; - DECLARE_WAITQUEUE(wait, current); - - if (count < sizeof(struct dlm_lock_result)) - return -EINVAL; - - spin_lock(&fi->fi_ast_lock); - if (list_empty(&fi->fi_ast_list)) { - - /* No waiting ASTs. - * Return EOF if the lockspace been deleted. - */ - if (test_bit(LS_FLAG_DELETED, &fi->fi_ls->ls_flags)) - return 0; - - if (file->f_flags & O_NONBLOCK) { - spin_unlock(&fi->fi_ast_lock); - return -EAGAIN; - } - - add_wait_queue(&fi->fi_wait, &wait); - - repeat: - set_current_state(TASK_INTERRUPTIBLE); - if (list_empty(&fi->fi_ast_list) && - !signal_pending(current)) { - - spin_unlock(&fi->fi_ast_lock); - schedule(); - spin_lock(&fi->fi_ast_lock); - goto repeat; - } - - current->state = TASK_RUNNING; - remove_wait_queue(&fi->fi_wait, &wait); - - if (signal_pending(current)) { - spin_unlock(&fi->fi_ast_lock); - return -ERESTARTSYS; - } - } - - ast = list_entry(fi->fi_ast_list.next, struct ast_info, list); - list_del(&ast->list); - spin_unlock(&fi->fi_ast_lock); - - /* Work out the size of the returned data */ - data_size = sizeof(struct dlm_lock_result); - if (ast->lvb_updated && ast->result.lksb.sb_lvbptr) - data_size += DLM_LVB_LEN; - if (ast->queryinfo) { - data_size += sizeof(struct dlm_queryinfo); - if (ast->queryinfo->gqi_resinfo) - data_size += sizeof(struct dlm_resinfo); - if (ast->queryinfo->gqi_lockinfo) - data_size += sizeof(struct dlm_lockinfo) * ast->queryinfo->gqi_lockcount; - } - - offset = sizeof(struct dlm_lock_result); - - /* Room for the extended data ? */ - if (count >= data_size) { - - if (ast->lvb_updated && ast->result.lksb.sb_lvbptr) { - if (copy_to_user(buffer+offset, ast->result.lksb.sb_lvbptr, DLM_LVB_LEN)) - return -EFAULT; - - ast->result.lvb_offset = offset; - offset += DLM_LVB_LEN; - } - if (ast->queryinfo) { - if (copy_to_user(buffer+offset, ast->queryinfo, sizeof(struct dlm_queryinfo))) - return -EFAULT; - ast->result.qinfo_offset = offset; - offset += sizeof(struct dlm_queryinfo); - - if (ast->queryinfo->gqi_resinfo) { - if (copy_to_user(buffer+offset, ast->queryinfo->gqi_resinfo, sizeof(struct dlm_resinfo))) - return -EFAULT; - ast->result.qresinfo_offset = offset; - offset += sizeof(struct dlm_resinfo); - kfree(ast->queryinfo->gqi_resinfo); - } - - if (ast->queryinfo->gqi_lockinfo) { - if (copy_to_user(buffer+offset, ast->queryinfo->gqi_lockinfo, - sizeof(struct dlm_lockinfo) * ast->queryinfo->gqi_lockcount)) - return -EFAULT; - ast->result.qlockinfo_offset = offset; - offset += sizeof(struct dlm_lockinfo) * ast->queryinfo->gqi_lockcount; - kfree(ast->queryinfo->gqi_lockinfo); - } - - kfree(ast->queryinfo); - } - } - - ast->result.length = data_size; - /* Copy the header now it has all the offsets in it */ - if (copy_to_user(buffer, &ast->result, sizeof(struct dlm_lock_result))) - offset = -EFAULT; - - /* If we only returned a header and there's more to come then put it back on the list */ - if (count < data_size) { - spin_lock(&fi->fi_ast_lock); - list_add(&ast->list, &fi->fi_ast_list); - spin_unlock(&fi->fi_ast_lock); - } - else { - kfree(ast); - } - return offset; -} - -static unsigned int dlm_poll(struct file *file, poll_table *wait) -{ - struct file_info *fi = file->private_data; - - poll_wait(file, &fi->fi_wait, wait); - - spin_lock(&fi->fi_ast_lock); - if (!list_empty(&fi->fi_ast_list)) { - spin_unlock(&fi->fi_ast_lock); - return POLLIN | POLLRDNORM; - } - - spin_unlock(&fi->fi_ast_lock); - return 0; -} - -static int do_user_query(struct file_info *fi, uint8_t cmd, struct dlm_query_params *kparams) -{ - struct lock_info *li; - int status; - - if (!kparams->castaddr) - return -EINVAL; - - if (!kparams->lksb) - return -EINVAL; - - li = kmalloc(sizeof(struct lock_info), GFP_KERNEL); - if (!li) - return -ENOMEM; - - get_file_info(fi); - li->li_user_lksb = kparams->lksb; - li->li_castparam = kparams->castparam; - li->li_castaddr = kparams->castaddr; - li->li_file = fi; - li->li_flags = 0; - li->li_cmd = cmd; - clear_bit(LI_FLAG_FIRSTLOCK, &li->li_flags); - - li->li_user_queryinfo = kparams->qinfo; - li->li_lksb.sb_lkid = kparams->lkid; - li->li_lksb.sb_lvbptr = NULL; - - /* Allocate kernel buffers for query results */ - status = -ENOMEM; - li->li_queryinfo = kmalloc(sizeof(struct dlm_queryinfo), GFP_KERNEL); - if (!li->li_queryinfo) - goto out1; - - memset(li->li_queryinfo, 0, sizeof(struct dlm_queryinfo)); - li->li_queryinfo->gqi_locksize = kparams->lockinfo_max; - - if (kparams->resinfo) { - li->li_queryinfo->gqi_resinfo = kmalloc(sizeof(struct dlm_resinfo), GFP_KERNEL); - if (!li->li_queryinfo->gqi_resinfo) - goto out1; - } - if (kparams->lockinfo) { - li->li_queryinfo->gqi_locksize = kparams->lockinfo_max; - li->li_queryinfo->gqi_lockinfo = - kmalloc(sizeof(struct dlm_lockinfo) * kparams->lockinfo_max, - GFP_KERNEL); - if (!li->li_queryinfo->gqi_lockinfo) - goto out2; - } - - return dlm_query(fi->fi_ls->ls_lockspace, &li->li_lksb, - kparams->query, - li->li_queryinfo, - ast_routine, li); - - out2: - kfree(li->li_queryinfo); - - out1: - kfree(li); - return status; -} - -static struct lock_info *allocate_lockinfo(struct file_info *fi, uint8_t cmd, - struct dlm_lock_params *kparams) -{ - struct lock_info *li; - - li = kmalloc(sizeof(struct lock_info), GFP_KERNEL); - if (li) { - li->li_magic = LOCKINFO_MAGIC; - li->li_file = fi; - li->li_cmd = cmd; - li->li_queryinfo = NULL; - li->li_flags = 0; - li->li_pend_bastparam = NULL; - li->li_pend_bastaddr = NULL; - li->li_lksb.sb_lvbptr = NULL; - li->li_bastaddr = kparams->bastaddr; - li->li_bastparam = kparams->bastparam; - - get_file_info(fi); - } - return li; -} - -static int do_user_lock(struct file_info *fi, uint8_t cmd, struct dlm_lock_params *kparams) -{ - struct lock_info *li; - int status; - - /* - * Validate things that we need to have correct. - */ - if (!kparams->castaddr) - return -EINVAL; - - if (!kparams->lksb) - return -EINVAL; - - /* Persistent child locks are not available yet */ - if ((kparams->flags & DLM_LKF_PERSISTENT) && kparams->parent) - return -EINVAL; - - if (dlm_config.close_purge && !fi->fi_pid) - fi->fi_pid = current->pid; - - /* For conversions, the lock will already have a lock_info - block squirelled away in astparam */ - if (kparams->flags & DLM_LKF_CONVERT) { - struct dlm_lkb *lkb = dlm_get_lkb(fi->fi_ls->ls_lockspace, kparams->lkid); - if (!lkb) { - return -EINVAL; - } - - li = (struct lock_info *)lkb->lkb_astparam; - - /* li may be NULL if the lock was persistent and the process went - away, so we need to allocate a new one */ - if (!li) { - li = allocate_lockinfo(fi, cmd, kparams); - if (li) { - spin_lock(&fi->fi_lkb_lock); - list_add(&li->li_ownerqueue, &fi->fi_lkb_list); - set_bit(LI_FLAG_ONLIST, &li->li_flags); - spin_unlock(&fi->fi_lkb_lock); - } - else { - return -ENOMEM; - } - } - - if (li->li_magic != LOCKINFO_MAGIC) - return -EINVAL; - - /* For conversions don't overwrite the current blocking AST - info so that: - a) if a blocking AST fires before the conversion is queued - it runs the current handler - b) if the conversion is cancelled, the original blocking AST - declaration is active - The pend_ info is made active when the conversion - completes. - */ - li->li_pend_bastaddr = kparams->bastaddr; - li->li_pend_bastparam = kparams->bastparam; - } - else { - li = allocate_lockinfo(fi, cmd, kparams); - if (!li) - return -ENOMEM; - - /* semaphore to allow us to complete our work before - the AST routine runs. In fact we only need (and use) this - when the initial lock fails */ - init_MUTEX_LOCKED(&li->li_firstlock); - set_bit(LI_FLAG_FIRSTLOCK, &li->li_flags); - } - - li->li_user_lksb = kparams->lksb; - li->li_castaddr = kparams->castaddr; - li->li_castparam = kparams->castparam; - li->li_lksb.sb_lkid = kparams->lkid; - - /* Copy in the value block */ - if (kparams->flags & DLM_LKF_VALBLK) { - if (!li->li_lksb.sb_lvbptr) { - li->li_lksb.sb_lvbptr = kmalloc(DLM_LVB_LEN, GFP_KERNEL); - if (!li->li_lksb.sb_lvbptr) { - status = -ENOMEM; - goto out_err; - } - } - - memcpy(li->li_lksb.sb_lvbptr, kparams->lvb, DLM_LVB_LEN); - } - - /* Lock it ... */ - status = dlm_lock(fi->fi_ls->ls_lockspace, - kparams->mode, &li->li_lksb, - kparams->flags, - kparams->name, kparams->namelen, - kparams->parent, - ast_routine, - li, - (li->li_pend_bastaddr || li->li_bastaddr) ? - bast_routine : NULL, - kparams->range.ra_end ? &kparams->range : NULL); - - if (status) - goto out_err; - - /* If it succeeded (this far) with a new lock then keep track of - it on the file's lkb list */ - if (!(kparams->flags & DLM_LKF_CONVERT)) { - - spin_lock(&fi->fi_lkb_lock); - list_add(&li->li_ownerqueue, &fi->fi_lkb_list); - set_bit(LI_FLAG_ONLIST, &li->li_flags); - spin_unlock(&fi->fi_lkb_lock); - - up(&li->li_firstlock); - } - - /* Return the lockid as the user needs it /now/ */ - return li->li_lksb.sb_lkid; - - out_err: - if (!(kparams->flags & DLM_LKF_CONVERT) && - test_bit(LI_FLAG_FIRSTLOCK, &li->li_flags)) { - release_lockinfo(li); - } - return status; -} - -static int do_user_unlock(struct file_info *fi, uint8_t cmd, struct dlm_lock_params *kparams) -{ - struct lock_info *li; - struct dlm_lkb *lkb; - int status; - int convert_cancel = 0; - - lkb = dlm_get_lkb(fi->fi_ls->ls_lockspace, kparams->lkid); - if (!lkb) { - return -EINVAL; - } - - /* Cancelling a conversion doesn't remove the lock...*/ - if (kparams->flags & DLM_LKF_CANCEL && - lkb->lkb_status == GDLM_LKSTS_CONVERT) { - convert_cancel = 1; - } - - li = (struct lock_info *)lkb->lkb_astparam; - if (!li) { - li = allocate_lockinfo(fi, cmd, kparams); - spin_lock(&fi->fi_lkb_lock); - list_add(&li->li_ownerqueue, &fi->fi_lkb_list); - set_bit(LI_FLAG_ONLIST, &li->li_flags); - spin_unlock(&fi->fi_lkb_lock); - } - if (!li) - return -ENOMEM; - - if (li->li_magic != LOCKINFO_MAGIC) - return -EINVAL; - - /* Wait until dlm_lock() has completed */ - if (!test_bit(LI_FLAG_ONLIST, &li->li_flags)) { - down(&li->li_firstlock); - up(&li->li_firstlock); - } - - li->li_user_lksb = kparams->lksb; - li->li_cmd = cmd; - - /* dlm_unlock() passes a 0 for castaddr which means don't overwrite - the existing li_castaddr as that's the completion routine for - unlocks. dlm_unlock_wait() specifies a new AST routine to be - executed when the unlock completes. */ - if (kparams->castaddr) - li->li_castaddr = kparams->castaddr; - if (kparams->castparam) - li->li_castparam = kparams->castparam; - - /* Have to do it here cos the lkb may not exist after - * dlm_unlock() */ - if (!convert_cancel) { - spin_lock(&fi->fi_lkb_lock); - list_del(&li->li_ownerqueue); - clear_bit(LI_FLAG_ONLIST, &li->li_flags); - spin_unlock(&fi->fi_lkb_lock); - } - - /* Use existing lksb & astparams */ - status = dlm_unlock(fi->fi_ls->ls_lockspace, - kparams->lkid, - kparams->flags, &li->li_lksb, li); - if (status && !convert_cancel) { - /* It failed, put it back on the list */ - spin_lock(&fi->fi_lkb_lock); - list_add(&li->li_ownerqueue, &fi->fi_lkb_list); - set_bit(LI_FLAG_ONLIST, &li->li_flags); - spin_unlock(&fi->fi_lkb_lock); - } - - return status; -} - -/* Write call, submit a locking request */ -static ssize_t dlm_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct file_info *fi = file->private_data; - struct dlm_write_request *kparams; - sigset_t tmpsig; - sigset_t allsigs; - int status; - - if (count < sizeof(struct dlm_write_request)-1) /* -1 because lock name is optional */ - return -EINVAL; - - /* Has the lockspace been deleted */ - if (fi && test_bit(LS_FLAG_DELETED, &fi->fi_ls->ls_flags)) - return -ENOENT; - - kparams = kmalloc(count + 1, GFP_KERNEL); - if (!kparams) - return -ENOMEM; - memset(kparams, 0, count + 1); - - status = -EFAULT; - /* Get the command info */ - if (copy_from_user(kparams, buffer, count)) - goto out_free; - - status = -EBADE; - if (check_version(kparams)) - goto out_free; - - /* Block signals while we are doing this */ - sigfillset(&allsigs); - sigprocmask(SIG_BLOCK, &allsigs, &tmpsig); - - status = -EINVAL; - switch (kparams->cmd) - { - case DLM_USER_LOCK: - if (!fi) goto out_sig; - status = do_user_lock(fi, kparams->cmd, &kparams->i.lock); - break; - - case DLM_USER_UNLOCK: - if (!fi) goto out_sig; - status = do_user_unlock(fi, kparams->cmd, &kparams->i.lock); - break; - - case DLM_USER_QUERY: - if (!fi) goto out_sig; - status = do_user_query(fi, kparams->cmd, &kparams->i.query); - break; - - case DLM_USER_CREATE_LOCKSPACE: - if (fi) goto out_sig; - status = do_user_create_lockspace(fi, kparams->cmd, &kparams->i.lspace); - break; - - case DLM_USER_REMOVE_LOCKSPACE: - if (fi) goto out_sig; - status = do_user_remove_lockspace(fi, kparams->cmd, &kparams->i.lspace); - break; - default: - printk("Unknown command passed to DLM device : %d\n", kparams->cmd); - break; - } - - out_sig: - /* Restore signals */ - sigprocmask(SIG_SETMASK, &tmpsig, NULL); - recalc_sigpending(); - - out_free: - kfree(kparams); - if (status == 0) - return count; - else - return status; -} - -/* Called when the cluster is shutdown uncleanly, all lockspaces - have been summarily removed */ -void dlm_device_free_devices() -{ - struct user_ls *tmp; - struct user_ls *lsinfo; - - down(&user_ls_lock); - list_for_each_entry_safe(lsinfo, tmp, &user_ls_list, ls_list) { - misc_deregister(&lsinfo->ls_miscinfo); - - /* Tidy up, but don't delete the lsinfo struct until - all the users have closed their devices */ - list_del(&lsinfo->ls_list); - set_bit(LS_FLAG_DELETED, &lsinfo->ls_flags); - lsinfo->ls_lockspace = NULL; - } - up(&user_ls_lock); -} - -static struct file_operations _dlm_fops = { - .open = dlm_open, - .release = dlm_close, - .ioctl = dlm_ioctl, - .read = dlm_read, - .write = dlm_write, - .poll = dlm_poll, - .owner = THIS_MODULE, -}; - -static struct file_operations _dlm_ctl_fops = { - .open = dlm_ctl_open, - .release = dlm_ctl_close, - .write = dlm_write, - .owner = THIS_MODULE, -}; - -/* - * Create control device - */ -int dlm_device_init(void) -{ - int r; - - INIT_LIST_HEAD(&user_ls_list); - init_MUTEX(&user_ls_lock); - - ctl_device.name = "dlm-control"; - ctl_device.fops = &_dlm_ctl_fops; - ctl_device.minor = MISC_DYNAMIC_MINOR; - - r = misc_register(&ctl_device); - if (r) { - log_print("misc_register failed for DLM control device"); - return r; - } - - return 0; -} - -void dlm_device_exit(void) -{ - misc_deregister(&ctl_device); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/dlm-kernel/src/device.h b/dlm-kernel/src/device.h deleted file mode 100644 index ab21824..0000000 --- a/dlm-kernel/src/device.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DEVICE_DOT_H__ -#define __DEVICE_DOT_H__ - -extern void dlm_device_free_devices(void); - -#endif /* __DEVICE_DOT_H__ */ diff --git a/dlm-kernel/src/dir.c b/dlm-kernel/src/dir.c deleted file mode 100644 index 8f72af1..0000000 --- a/dlm-kernel/src/dir.c +++ /dev/null @@ -1,471 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "dlm_internal.h" -#include "nodes.h" -#include "lockspace.h" -#include "lowcomms.h" -#include "reccomms.h" -#include "rsb.h" -#include "config.h" -#include "memory.h" -#include "recover.h" -#include "util.h" - -struct resmov { - uint32_t rm_nodeid; - uint16_t rm_length; - uint16_t rm_pad; -}; - -void print_name(char *b, int len) -{ - int i; - for (i = 0; i < len; i++) - printk("%c", b[i]); - printk("\n"); -} - -static void put_free_de(struct dlm_ls *ls, struct dlm_direntry *de) -{ - spin_lock(&ls->ls_recover_list_lock); - list_add(&de->list, &ls->ls_recover_list); - spin_unlock(&ls->ls_recover_list_lock); -} - -static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len) -{ - int found = FALSE; - struct dlm_direntry *de; - - spin_lock(&ls->ls_recover_list_lock); - list_for_each_entry(de, &ls->ls_recover_list, list) { - if (de->length == len) { - list_del(&de->list); - de->master_nodeid = 0; - memset(de->name, 0, len); - found = TRUE; - break; - } - } - spin_unlock(&ls->ls_recover_list_lock); - - if (!found) - de = allocate_direntry(ls, len); - return de; -} - -void clear_free_de(struct dlm_ls *ls) -{ - struct dlm_direntry *de; - - spin_lock(&ls->ls_recover_list_lock); - while (!list_empty(&ls->ls_recover_list)) { - de = list_entry(ls->ls_recover_list.next, struct dlm_direntry, - list); - list_del(&de->list); - free_direntry(de); - } - spin_unlock(&ls->ls_recover_list_lock); -} - -/* - * We use the upper 16 bits of the hash value to select the directory node. - * Low bits are used for distribution of rsb's among hash buckets on each node. - * - * To give the exact range wanted (0 to num_nodes-1), we apply a modulus of - * num_nodes to the hash value. This value in the desired range is used as an - * offset into the sorted list of nodeid's to give the particular nodeid of the - * directory node. - */ - -uint32_t name_to_directory_nodeid(struct dlm_ls *ls, char *name, int length) -{ - struct list_head *tmp; - struct dlm_csb *csb = NULL; - uint32_t hash, node, n = 0, nodeid; - - if (ls->ls_num_nodes == 1) { - nodeid = our_nodeid(); - goto out; - } - - hash = dlm_hash(name, length); - node = (hash >> 16) % ls->ls_num_nodes; - - if (ls->ls_node_array) { - nodeid = ls->ls_node_array[node]; - goto out; - } - - list_for_each(tmp, &ls->ls_nodes) { - if (n++ != node) - continue; - csb = list_entry(tmp, struct dlm_csb, list); - break; - } - - DLM_ASSERT(csb, printk("num_nodes=%u n=%u node=%u\n", - ls->ls_num_nodes, n, node);); - nodeid = csb->node->nodeid; - out: - return nodeid; -} - -uint32_t get_directory_nodeid(struct dlm_rsb *rsb) -{ - return name_to_directory_nodeid(rsb->res_ls, rsb->res_name, - rsb->res_length); -} - -static inline uint32_t dir_hash(struct dlm_ls *ls, char *name, int len) -{ - uint32_t val; - - val = dlm_hash(name, len); - val &= (ls->ls_dirtbl_size - 1); - - return val; -} - -static void add_entry_to_hash(struct dlm_ls *ls, struct dlm_direntry *de) -{ - uint32_t bucket; - - bucket = dir_hash(ls, de->name, de->length); - list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list); -} - -static struct dlm_direntry *search_bucket(struct dlm_ls *ls, char *name, - int namelen, uint32_t bucket) -{ - struct dlm_direntry *de; - - list_for_each_entry(de, &ls->ls_dirtbl[bucket].list, list) { - if (de->length == namelen && !memcmp(name, de->name, namelen)) - goto out; - } - de = NULL; - out: - return de; -} - -void dlm_dir_remove(struct dlm_ls *ls, uint32_t nodeid, char *name, int namelen) -{ - struct dlm_direntry *de; - uint32_t bucket; - - bucket = dir_hash(ls, name, namelen); - - write_lock(&ls->ls_dirtbl[bucket].lock); - - de = search_bucket(ls, name, namelen, bucket); - - if (!de) { - log_error(ls, "remove fr %u none", nodeid); - goto out; - } - - if (de->master_nodeid != nodeid) { - log_error(ls, "remove fr %u ID %u", nodeid, de->master_nodeid); - goto out; - } - - list_del(&de->list); - free_direntry(de); - out: - write_unlock(&ls->ls_dirtbl[bucket].lock); -} - -void dlm_dir_clear(struct dlm_ls *ls) -{ - struct list_head *head; - struct dlm_direntry *de; - int i; - - DLM_ASSERT(list_empty(&ls->ls_recover_list), ); - - for (i = 0; i < ls->ls_dirtbl_size; i++) { - write_lock(&ls->ls_dirtbl[i].lock); - head = &ls->ls_dirtbl[i].list; - while (!list_empty(head)) { - de = list_entry(head->next, struct dlm_direntry, list); - list_del(&de->list); - put_free_de(ls, de); - } - write_unlock(&ls->ls_dirtbl[i].lock); - } -} - -static void resmov_in(struct resmov *rm, char *buf) -{ - struct resmov tmp; - - memcpy(&tmp, buf, sizeof(struct resmov)); - - rm->rm_nodeid = be32_to_cpu(tmp.rm_nodeid); - rm->rm_length = be16_to_cpu(tmp.rm_length); -} - -int dlm_dir_rebuild_local(struct dlm_ls *ls) -{ - struct dlm_csb *csb; - struct dlm_direntry *de; - struct dlm_rcom *rc; - struct resmov mov, last_mov; - char *b, *last_name; - int error = -ENOMEM, count = 0; - - log_debug(ls, "rebuild resource directory"); - - dlm_dir_clear(ls); - - rc = allocate_rcom_buffer(ls); - if (!rc) - goto out; - - last_name = kmalloc(DLM_RESNAME_MAXLEN, GFP_KERNEL); - if (!last_name) - goto free_rc; - - list_for_each_entry(csb, &ls->ls_nodes, list) { - last_mov.rm_length = 0; - for (;;) { - error = dlm_recovery_stopped(ls); - if (error) - goto free_last; - - memcpy(rc->rc_buf, last_name, last_mov.rm_length); - rc->rc_datalen = last_mov.rm_length; - - error = rcom_send_message(ls, csb->node->nodeid, - RECCOMM_RECOVERNAMES, rc, 1); - if (error) - goto free_last; - - schedule(); - - /* - * pick each res out of buffer - */ - - b = rc->rc_buf; - - for (;;) { - resmov_in(&mov, b); - b += sizeof(struct resmov); - - /* Length of 0 with a non-zero nodeid marks the - * end of the list */ - if (!mov.rm_length && mov.rm_nodeid) - goto done; - - /* This is just the end of the block */ - if (!mov.rm_length) - break; - - DLM_ASSERT(mov.rm_nodeid == csb->node->nodeid,); - - error = -ENOMEM; - de = get_free_de(ls, mov.rm_length); - if (!de) - goto free_last; - - de->master_nodeid = mov.rm_nodeid; - de->length = mov.rm_length; - memcpy(de->name, b, mov.rm_length); - b += mov.rm_length; - - add_entry_to_hash(ls, de); - count++; - - last_mov = mov; - memset(last_name, 0, DLM_RESNAME_MAXLEN); - memcpy(last_name, de->name, de->length); - } - } - done: - ; - } - - set_bit(LSFL_RESDIR_VALID, &ls->ls_flags); - error = 0; - - log_debug(ls, "rebuilt %d resources", count); - - free_last: - kfree(last_name); - - free_rc: - free_rcom_buffer(rc); - - out: - clear_free_de(ls); - return error; -} - -/* - * The reply end of dlm_dir_rebuild_local/RECOVERNAMES. Collect and send as - * many resource names as can fit in the buffer. - */ - -int dlm_dir_rebuild_send(struct dlm_ls *ls, char *inbuf, int inlen, - char *outbuf, int outlen, uint32_t nodeid) -{ - struct list_head *list; - struct dlm_rsb *start_rsb = NULL, *rsb; - int offset = 0, start_namelen, error; - char *start_name; - struct resmov tmp; - uint32_t dir_nodeid; - - /* - * Find the rsb where we left off (or start again) - */ - - start_namelen = inlen; - start_name = inbuf; - - if (start_namelen > 1) { - error = find_rsb(ls, NULL, start_name, start_namelen, 0, - &start_rsb); - DLM_ASSERT(!error && start_rsb, printk("error %d\n", error);); - release_rsb(start_rsb); - } - - /* - * Send rsb names for rsb's we're master of and whose directory node - * matches the requesting node. - */ - - down_read(&ls->ls_root_lock); - if (start_rsb) - list = start_rsb->res_rootlist.next; - else - list = ls->ls_rootres.next; - - for (offset = 0; list != &ls->ls_rootres; list = list->next) { - rsb = list_entry(list, struct dlm_rsb, res_rootlist); - if (rsb->res_nodeid) - continue; - - dir_nodeid = get_directory_nodeid(rsb); - if (dir_nodeid != nodeid) - continue; - - if (offset + sizeof(struct resmov)*2 + rsb->res_length > outlen) { - /* Write end-of-block record */ - memset(&tmp, 0, sizeof(struct resmov)); - memcpy(outbuf + offset, &tmp, sizeof(struct resmov)); - offset += sizeof(struct resmov); - goto out; - } - - memset(&tmp, 0, sizeof(struct resmov)); - tmp.rm_nodeid = cpu_to_be32(our_nodeid()); - tmp.rm_length = cpu_to_be16(rsb->res_length); - - memcpy(outbuf + offset, &tmp, sizeof(struct resmov)); - offset += sizeof(struct resmov); - - memcpy(outbuf + offset, rsb->res_name, rsb->res_length); - offset += rsb->res_length; - } - - /* - * If we've reached the end of the list (and there's room) write a - * terminating record. - */ - - if ((list == &ls->ls_rootres) && - (offset + sizeof(struct resmov) <= outlen)) { - - memset(&tmp, 0, sizeof(struct resmov)); - /* This only needs to be non-zero */ - tmp.rm_nodeid = cpu_to_be32(1); - /* and this must be zero */ - tmp.rm_length = 0; - memcpy(outbuf + offset, &tmp, sizeof(struct resmov)); - offset += sizeof(struct resmov); - } - - out: - up_read(&ls->ls_root_lock); - return offset; -} - -static int get_entry(struct dlm_ls *ls, uint32_t nodeid, char *name, - int namelen, uint32_t *r_nodeid) -{ - struct dlm_direntry *de, *tmp; - uint32_t bucket; - - bucket = dir_hash(ls, name, namelen); - - write_lock(&ls->ls_dirtbl[bucket].lock); - de = search_bucket(ls, name, namelen, bucket); - if (de) { - *r_nodeid = de->master_nodeid; - write_unlock(&ls->ls_dirtbl[bucket].lock); - if (*r_nodeid == nodeid) - return -EEXIST; - return 0; - } - - write_unlock(&ls->ls_dirtbl[bucket].lock); - - de = allocate_direntry(ls, namelen); - if (!de) - return -ENOMEM; - - de->master_nodeid = nodeid; - de->length = namelen; - memcpy(de->name, name, namelen); - - write_lock(&ls->ls_dirtbl[bucket].lock); - tmp = search_bucket(ls, name, namelen, bucket); - if (tmp) { - free_direntry(de); - de = tmp; - } else { - list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list); - } - *r_nodeid = de->master_nodeid; - write_unlock(&ls->ls_dirtbl[bucket].lock); - return 0; -} - -int dlm_dir_lookup(struct dlm_ls *ls, uint32_t nodeid, char *name, int namelen, - uint32_t *r_nodeid) -{ - return get_entry(ls, nodeid, name, namelen, r_nodeid); -} - -/* - * The node with lowest id queries all nodes to determine when all are done. - * All other nodes query the low nodeid for this. - */ - -int dlm_dir_rebuild_wait(struct dlm_ls *ls) -{ - int error; - - if (ls->ls_low_nodeid == our_nodeid()) { - error = dlm_wait_status_all(ls, RESDIR_VALID); - if (!error) - set_bit(LSFL_ALL_RESDIR_VALID, &ls->ls_flags); - } else - error = dlm_wait_status_low(ls, RESDIR_ALL_VALID); - - return error; -} diff --git a/dlm-kernel/src/dir.h b/dlm-kernel/src/dir.h deleted file mode 100644 index e965d96..0000000 --- a/dlm-kernel/src/dir.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DIR_DOT_H__ -#define __DIR_DOT_H__ - -void print_name(char *b, int len); -uint32_t name_to_directory_nodeid(struct dlm_ls *ls, char *name, int length); -uint32_t get_directory_nodeid(struct dlm_rsb *rsb); - -int dlm_dir_lookup(struct dlm_ls *ls, uint32_t nodeid, char *name, int namelen, - uint32_t *r_nodeid); -void dlm_dir_remove(struct dlm_ls *ls, uint32_t nodeid, char *name, - int namelen); -int dlm_dir_rebuild_local(struct dlm_ls *ls); -int dlm_dir_rebuild_send(struct dlm_ls *ls, char *inbuf, int inlen, - char *outbuf, int outlen, uint32_t nodeid); -int dlm_dir_rebuild_wait(struct dlm_ls * ls); -void dlm_dir_clear(struct dlm_ls *ls); -void dlm_dir_dump(struct dlm_ls *ls); -void clear_free_de(struct dlm_ls *ls); - -#endif /* __DIR_DOT_H__ */ diff --git a/dlm-kernel/src/dlm.h b/dlm-kernel/src/dlm.h deleted file mode 100644 index d28ee8d..0000000 --- a/dlm-kernel/src/dlm.h +++ /dev/null @@ -1,421 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DLM_DOT_H__ -#define __DLM_DOT_H__ - -/* - * Interface to DLM - routines and structures to use DLM lockspaces. - */ - -/* - * Lock Modes - */ - -#define DLM_LOCK_IV (-1) /* invalid */ -#define DLM_LOCK_NL (0) /* null */ -#define DLM_LOCK_CR (1) /* concurrent read */ -#define DLM_LOCK_CW (2) /* concurrent write */ -#define DLM_LOCK_PR (3) /* protected read */ -#define DLM_LOCK_PW (4) /* protected write */ -#define DLM_LOCK_EX (5) /* exclusive */ - -/* - * Maximum size in bytes of a dlm_lock name - */ - -#define DLM_RESNAME_MAXLEN (64) - -/* - * Size in bytes of Lock Value Block - */ - -#define DLM_LVB_LEN (32) - -/* - * Flags to dlm_new_lockspace - * - * DLM_LSF_NOTIMERS - * - * Do not subject locks in this lockspace to time-outs. - */ - -#define DLM_LSF_NOTIMERS (1) - -/* - * Flags to dlm_lock - * - * DLM_LKF_NOQUEUE - * - * Do not queue the lock request on the wait queue if it cannot be granted - * immediately. If the lock cannot be granted because of this flag, DLM will - * either return -EAGAIN from the dlm_lock call or will return 0 from - * dlm_lock and -EAGAIN in the lock status block when the AST is executed. - * - * DLM_LKF_CONVERT - * - * Indicates a lock conversion request. For conversions the name and namelen - * are ignored and the lock ID in the LKSB is used to identify the lock. - * - * DLM_LKF_VALBLK - * - * Requests DLM to return the current contents of the lock value block in the - * lock status block. When this flag is set in a lock conversion from PW or EX - * modes, DLM assigns the value specified in the lock status block to the lock - * value block of the lock resource. The LVB is a DLM_LVB_LEN size array - * containing application-specific information. - * - * DLM_LKF_QUECVT - * - * Force a conversion request to be queued, even if it is compatible with - * the granted modes of other locks on the same resource. - * - * DLM_LKF_CANCEL - * - * Used to cancel a pending conversion (with dlm_unlock). Lock is returned to - * previously granted mode. - * - * DLM_LKF_IVVALBLK - * - * Invalidate/clear the lock value block. - * - * DLM_LKF_CONVDEADLK - * - * The granted mode of a lock being converted (from a non-NL mode) can be - * changed to NL in the process of acquiring the requested mode to avoid - * conversion deadlock. - * - * DLM_LKF_PERSISTENT - * - * Only relevant to locks originating in userspace. Signals to the ioctl.c code - * that this lock should not be unlocked when the process exits. - * - * DLM_LKF_NODLKWT - * - * This lock is not to be checked for conversion deadlocks. - * - * DLM_LKF_NODLCKBLK - * - * not yet implemented - * - * DLM_LKF_EXPEDITE - * - * Used only with new requests for NL mode locks. Tells the lock manager - * to grant the lock, ignoring other locks in convert and wait queues. - * - * DLM_LKF_NOQUEUEBAST - * - * Send blocking AST's before returning -EAGAIN to the caller. It is only - * used along with the NOQUEUE flag. Blocking AST's are not sent for failed - * NOQUEUE requests otherwise. - * - * DLM_LKF_HEADQUE - * - * Add a lock to the head of the convert or wait queue rather than the tail. - * - * DLM_LKF_NOORDER - * - * Disregard the standard grant order rules and grant a lock as soon as it - * is compatible with other granted locks. - */ - -#define DLM_LKF_NOQUEUE (0x00000001) -#define DLM_LKF_CANCEL (0x00000002) -#define DLM_LKF_CONVERT (0x00000004) -#define DLM_LKF_VALBLK (0x00000008) -#define DLM_LKF_QUECVT (0x00000010) -#define DLM_LKF_IVVALBLK (0x00000020) -#define DLM_LKF_CONVDEADLK (0x00000040) -#define DLM_LKF_PERSISTENT (0x00000080) -#define DLM_LKF_NODLCKWT (0x00000100) -#define DLM_LKF_NODLCKBLK (0x00000200) -#define DLM_LKF_EXPEDITE (0x00000400) -#define DLM_LKF_NOQUEUEBAST (0x00000800) -#define DLM_LKF_HEADQUE (0x00001000) -#define DLM_LKF_NOORDER (0x00002000) -#define DLM_LKF_ORPHAN (0x00004000) -#define DLM_LKF_ALTPR (0x00008000) -#define DLM_LKF_ALTCW (0x00010000) - -/* - * Some return codes that are not in errno.h - */ - -#define DLM_ECANCEL (0x10001) -#define DLM_EUNLOCK (0x10002) - -typedef void dlm_lockspace_t; - -/* - * Lock range structure - */ - -struct dlm_range { - uint64_t ra_start; - uint64_t ra_end; -}; - -/* - * Lock status block - * - * Use this structure to specify the contents of the lock value block. For a - * conversion request, this structure is used to specify the lock ID of the - * lock. DLM writes the status of the lock request and the lock ID assigned - * to the request in the lock status block. - * - * sb_lkid: the returned lock ID. It is set on new (non-conversion) requests. - * It is available when dlm_lock returns. - * - * sb_lvbptr: saves or returns the contents of the lock's LVB according to rules - * shown for the DLM_LKF_VALBLK flag. - * - * sb_flags: DLM_SBF_DEMOTED is returned if in the process of promoting a lock, - * it was first demoted to NL to avoid conversion deadlock. - * DLM_SBF_VALNOTVALID is returned if the resource's LVB is marked invalid. - * - * sb_status: the returned status of the lock request set prior to AST - * execution. Possible return values: - * - * 0 if lock request was successful - * -EAGAIN if request would block and is flagged DLM_LKF_NOQUEUE - * -ENOMEM if there is no memory to process request - * -EINVAL if there are invalid parameters - * -DLM_EUNLOCK if unlock request was successful - * -DLM_ECANCEL if a cancel completed successfully - */ - -#define DLM_SBF_DEMOTED (0x01) -#define DLM_SBF_VALNOTVALID (0x02) -#define DLM_SBF_ALTMODE (0x04) - -struct dlm_lksb { - int sb_status; - uint32_t sb_lkid; - char sb_flags; - char * sb_lvbptr; -}; - -/* - * These defines are the bits that make up the query code. - */ - -/* Bits 0, 1, 2, the lock mode or DLM_LOCK_THIS, see DLM_LOCK_NL etc in - * dlm.h Ignored for DLM_QUERY_LOCKS_ALL */ -#define DLM_LOCK_THIS 0x0007 -#define DLM_QUERY_MODE_MASK 0x0007 - -/* Bits 3, 4, 5 bitmap of queue(s) to query */ -#define DLM_QUERY_QUEUE_WAIT 0x0008 -#define DLM_QUERY_QUEUE_CONVERT 0x0010 -#define DLM_QUERY_QUEUE_GRANT 0x0020 -#define DLM_QUERY_QUEUE_GRANTED 0x0030 /* Shorthand */ -#define DLM_QUERY_QUEUE_ALL 0x0038 /* Shorthand */ - -/* Bit 6, Return only the information that can be established without a network - * round-trip. The caller must be aware of the implications of this. Useful for - * just getting the master node id or resource name. */ -#define DLM_QUERY_LOCAL 0x0040 - -/* Bits 8 up, query type */ -#define DLM_QUERY_LOCKS_HIGHER 0x0100 -#define DLM_QUERY_LOCKS_LOWER 0x0200 -#define DLM_QUERY_LOCKS_EQUAL 0x0300 -#define DLM_QUERY_LOCKS_BLOCKING 0x0400 -#define DLM_QUERY_LOCKS_NOTBLOCK 0x0500 -#define DLM_QUERY_LOCKS_ALL 0x0600 -#define DLM_QUERY_LOCKS_ORPHAN 0x0700 -#define DLM_QUERY_MASK 0x0F00 - -/* GRMODE is the default for mode comparisons, - RQMODE might also be handy */ -#define DLM_QUERY_GRMODE 0x0000 -#define DLM_QUERY_RQMODE 0x1000 - -/* Structures passed into and out of the query */ - -struct dlm_lockinfo { - int lki_lkid; /* Lock ID on originating node */ - int lki_mstlkid; /* Lock ID on master node */ - int lki_parent; - int lki_node; /* Originating node (not master) */ - int lki_ownpid; /* Owner pid on originating node */ - uint8_t lki_state; /* Queue the lock is on */ - uint8_t lki_grmode; /* Granted mode */ - uint8_t lki_rqmode; /* Requested mode */ - struct dlm_range lki_grrange; /* Granted range, if applicable */ - struct dlm_range lki_rqrange; /* Requested range, if applicable */ -}; - -struct dlm_resinfo { - int rsi_length; - int rsi_grantcount; /* No. of locks on grant queue */ - int rsi_convcount; /* No. of locks on convert queue */ - int rsi_waitcount; /* No. of locks on wait queue */ - int rsi_masternode; /* Master for this resource */ - char rsi_name[DLM_RESNAME_MAXLEN]; /* Resource name */ - char rsi_valblk[DLM_LVB_LEN]; /* Master's LVB contents, if applicable - */ -}; - -struct dlm_queryinfo { - struct dlm_resinfo *gqi_resinfo; - struct dlm_lockinfo *gqi_lockinfo; /* This points to an array - * of structs */ - int gqi_locksize; /* input */ - int gqi_lockcount; /* output */ -}; - -#ifdef __KERNEL__ -/* - * dlm_init - * - * Starts and initializes DLM threads and structures. Creation of the first - * lockspace will call this if it has not been called already. - * - * Returns: 0 if successful, -EXXX on error - */ - -int dlm_init(void); - -/* - * dlm_release - * - * Stops DLM threads. - * - * Returns: 0 if successful, -EXXX on error - */ - -int dlm_release(void); - -/* - * dlm_new_lockspace - * - * Starts a lockspace with the given name. If the named lockspace exists in - * the cluster, the calling node joins it. - */ - -int dlm_new_lockspace(char *name, int namelen, dlm_lockspace_t **lockspace, - int flags); - -/* - * dlm_release_lockspace - * - * Stop a lockspace. - */ - -int dlm_release_lockspace(dlm_lockspace_t *lockspace, int force); - -/* - * dlm_lock - * - * Make an asyncronous request to acquire or convert a lock on a named - * resource. - * - * lockspace: context for the request - * mode: the requested mode of the lock (DLM_LOCK_) - * lksb: lock status block for input and async return values - * flags: input flags (DLM_LKF_) - * name: name of the resource to lock, can be binary - * namelen: the length in bytes of the resource name (MAX_RESNAME_LEN) - * parent: the lock ID of a parent lock or 0 if none - * lockast: function DLM executes when it completes processing the request - * astarg: argument passed to lockast and bast functions - * bast: function DLM executes when this lock later blocks another request - * - * Returns: - * 0 if request is successfully queued for processing - * -EINVAL if any input parameters are invalid - * -EAGAIN if request would block and is flagged DLM_LKF_NOQUEUE - * -ENOMEM if there is no memory to process request - * -ENOTCONN if there is a communication error - * - * If the call to dlm_lock returns an error then the operation has failed and - * the AST routine will not be called. If dlm_lock returns 0 it is still - * possible that the lock operation will fail. The AST routine will be called - * when the locking is complete and the status is returned in the lksb. - * - * If the AST routines or parameter are passed to a conversion operation then - * they will overwrite those values that were passed to a previous dlm_lock - * call. - * - * AST routines should not block (at least not for long), but may make - * any locking calls they please. - */ - -int dlm_lock(dlm_lockspace_t *lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void (*lockast) (void *astarg), - void *astarg, - void (*bast) (void *astarg, int mode), - struct dlm_range *range); - -/* - * dlm_unlock - * - * Asynchronously release a lock on a resource. The AST routine is called - * when the resource is successfully unlocked. - * - * lockspace: context for the request - * lkid: the lock ID as returned in the lksb - * flags: input flags (DLM_LKF_) - * lksb: if NULL the lksb parameter passed to last lock request is used - * astarg: the arg used with the completion ast for the unlock - * - * Returns: - * 0 if request is successfully queued for processing - * -EINVAL if any input parameters are invalid - * -ENOTEMPTY if the lock still has sublocks - * -EBUSY if the lock is waiting for a remote lock operation - * -ENOTCONN if there is a communication error - */ - -int dlm_unlock(dlm_lockspace_t *lockspace, - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb, - void *astarg); - -/* Query interface - * - * Query the other holders of a resource, given a known lock ID - * - * lockspace: context for the request - * lksb: LKSB, sb_lkid contains the lock ID of a valid lock - * on the resource. sb_status will contain the status - * of the request on completion. - * query: query bitmap see DLM_QUERY_* above - * qinfo: pointer to dlm_queryinfo structure - * ast_routine: AST routine to call on completion - * artarg: argument to AST routine. It is "traditional" - * to put the qinfo pointer into lksb->sb_lvbptr - * and pass the lksb in here. - */ -int dlm_query(dlm_lockspace_t *lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (ast_routine(void *)), - void *astarg); - - -void dlm_debug_dump(void); -void dlm_locks_dump(void); - -#endif /* __KERNEL__ */ - -#endif /* __DLM_DOT_H__ */ diff --git a/dlm-kernel/src/dlm_device.h b/dlm-kernel/src/dlm_device.h deleted file mode 100644 index cff63bb..0000000 --- a/dlm-kernel/src/dlm_device.h +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* This is the device interface for dlm, most users will use a library - * interface. - */ - -/* Version of the device interface */ -#define DLM_DEVICE_VERSION_MAJOR 3 -#define DLM_DEVICE_VERSION_MINOR 0 -#define DLM_DEVICE_VERSION_PATCH 0 - -#ifndef __KERNEL -#define __user -#endif - -/* struct passed to the lock write */ -struct dlm_lock_params { - uint8_t mode; - uint16_t flags; - uint32_t lkid; - uint32_t parent; - struct dlm_range range; - uint8_t namelen; - void __user *castparam; - void __user *castaddr; - void __user *bastparam; - void __user *bastaddr; - struct dlm_lksb __user *lksb; - char lvb[DLM_LVB_LEN]; - char name[1]; -}; - -struct dlm_query_params { - uint32_t query; - struct dlm_queryinfo __user *qinfo; - struct dlm_resinfo __user *resinfo; - struct dlm_lockinfo __user *lockinfo; - void __user *castparam; - void __user *castaddr; - void __user *lksb; - uint32_t lkid; - int lockinfo_max; -}; - - -struct dlm_lspace_params { - uint32_t flags; - uint32_t minor; - char name[1]; -}; - -struct dlm_write_request { - uint32_t version[3]; - uint8_t cmd; - - union { - struct dlm_lock_params lock; - struct dlm_query_params query; - struct dlm_lspace_params lspace; - } i; -}; - -/* struct read from the "device" fd, - consists mainly of userspace pointers for the library to use */ -struct dlm_lock_result { - uint32_t length; - void __user *user_astaddr; - void __user *user_astparam; - struct dlm_lksb __user *user_lksb; - struct dlm_queryinfo __user *user_qinfo; - struct dlm_lksb lksb; - uint8_t bast_mode; - /* Offsets may be zero if no data is present */ - uint32_t lvb_offset; - uint32_t qinfo_offset; - uint32_t qresinfo_offset; - uint32_t qlockinfo_offset; -}; - -/* Commands passed to the device */ -#define DLM_USER_LOCK 1 -#define DLM_USER_UNLOCK 2 -#define DLM_USER_QUERY 3 -#define DLM_USER_CREATE_LOCKSPACE 4 -#define DLM_USER_REMOVE_LOCKSPACE 5 - -/* Arbitrary length restriction */ -#define MAX_LS_NAME_LEN 64 - -/* Lockspace flags */ -#define DLM_USER_LSFLG_AUTOFREE 1 -#define DLM_USER_LSFLG_FORCEFREE 2 -#define DLM_USER_LSFLG_DEFAULTLS 4 - diff --git a/dlm-kernel/src/dlm_internal.h b/dlm-kernel/src/dlm_internal.h deleted file mode 100644 index 3ed07ac..0000000 --- a/dlm-kernel/src/dlm_internal.h +++ /dev/null @@ -1,626 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DLM_INTERNAL_DOT_H__ -#define __DLM_INTERNAL_DOT_H__ - -/* - * This is the main header file to be included in each DLM source file. - */ - -#define DLM_RELEASE_NAME "<CVS>" - -#include <linux/slab.h> -#include <linux/sched.h> -#include <asm/semaphore.h> -#include <linux/types.h> -#include <linux/spinlock.h> -#include <linux/vmalloc.h> -#include <asm/uaccess.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/random.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/kthread.h> - -#include <cluster/dlm.h> -#include <cluster/dlm_device.h> -#include <cluster/service.h> - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#if (BITS_PER_LONG == 64) -#define PRIu64 "lu" -#define PRId64 "ld" -#define PRIo64 "lo" -#define PRIx64 "lx" -#define PRIX64 "lX" -#define SCNu64 "lu" -#define SCNd64 "ld" -#define SCNo64 "lo" -#define SCNx64 "lx" -#define SCNX64 "lX" -#else -#define PRIu64 "Lu" -#define PRId64 "Ld" -#define PRIo64 "Lo" -#define PRIx64 "Lx" -#define PRIX64 "LX" -#define SCNu64 "Lu" -#define SCNd64 "Ld" -#define SCNo64 "Lo" -#define SCNx64 "Lx" -#define SCNX64 "LX" -#endif - -#define wchan_cond_sleep_intr(chan, sleep_cond) \ -do \ -{ \ - DECLARE_WAITQUEUE(__wait_chan, current); \ - current->state = TASK_INTERRUPTIBLE; \ - add_wait_queue(&chan, &__wait_chan); \ - if ((sleep_cond)) \ - schedule(); \ - remove_wait_queue(&chan, &__wait_chan); \ - current->state = TASK_RUNNING; \ -} \ -while (0) - -static inline int check_timeout(unsigned long stamp, unsigned int seconds) -{ - return time_after(jiffies, stamp + seconds * HZ); -} - - -#define log_print(fmt, args...) printk("dlm: "fmt"\n", ##args) - -#define log_error(ls, fmt, args...) \ -do { \ - printk("dlm: %s: " fmt "\n", (ls)->ls_name, ##args); \ - dlm_debug_log(ls, fmt, ##args); \ -} while (0) - -#define DLM_DEBUG -#if defined(DLM_DEBUG) -#define log_debug(ls, fmt, args...) dlm_debug_log(ls, fmt, ##args) -#else -#define log_debug(ls, fmt, args...) -#endif - -#if defined(DLM_DEBUG1) -#define log_debug1(ls, fmt, args...) dlm_debug_log(ls, fmt, ##args) -#else -#define log_debug1(ls, fmt, args...) -#endif - -#if defined(DLM_DEBUG2) -#define log_debug2(fmt, args...) dlm_debug_log(ls, fmt, ##args) -#else -#define log_debug2(fmt, args...) -#endif - -#define DLM_ASSERT(x, do) \ -{ \ - if (!(x)) \ - { \ - dlm_debug_dump(); \ - printk("\nDLM: Assertion failed on line %d of file %s\n" \ - "DLM: assertion: "%s"\n" \ - "DLM: time = %lu\n", \ - __LINE__, __FILE__, #x, jiffies); \ - {do} \ - printk("\n"); \ - BUG(); \ - panic("DLM: Record message above and reboot.\n"); \ - } \ -} - - -struct dlm_ls; -struct dlm_lkb; -struct dlm_rsb; -struct dlm_csb; -struct dlm_node; -struct dlm_lkbtable; -struct dlm_rsbtable; -struct dlm_dirtable; -struct dlm_direntry; -struct dlm_recover; -struct dlm_header; -struct dlm_request; -struct dlm_reply; -struct dlm_rcom; -struct dlm_query_request; -struct dlm_query_reply; - - -struct dlm_direntry { - struct list_head list; - uint32_t master_nodeid; - uint16_t length; - char name[1]; -}; - -struct dlm_dirtable { - struct list_head list; - rwlock_t lock; -}; - -struct dlm_rsbtable { - struct list_head list; - rwlock_t lock; -}; - -struct dlm_lkbtable { - struct list_head list; - rwlock_t lock; - uint16_t counter; -}; - -/* - * Cluster node (per node in cluster) - */ - -struct dlm_node { - struct list_head list; - uint32_t nodeid; - atomic_t refcount; /* num csb's referencing */ -}; - -/* - * Cluster System Block (per node in a ls) - */ - -struct dlm_csb { - struct list_head list; /* per-lockspace node list */ - struct dlm_node * node; /* global node structure */ - int gone_event; /* event id when node removed */ -}; - -/* - * Used to save and manage recovery state for a lockspace. - */ - -struct dlm_recover { - struct list_head list; - uint32_t * nodeids; - int node_count; - int event_id; -}; - -/* - * Elements in the range array - */ - -#define GR_RANGE_START (0) -#define GR_RANGE_END (1) -#define RQ_RANGE_START (2) -#define RQ_RANGE_END (3) - -/* - * Lockspace structure - */ - -#define LSFL_WORK (0) -#define LSFL_LS_RUN (1) -#define LSFL_LS_STOP (2) -#define LSFL_LS_START (3) -#define LSFL_LS_FINISH (4) -#define LSFL_RECCOMM_READY (5) -#define LSFL_NOTIMERS (6) -#define LSFL_FINISH_RECOVERY (7) -#define LSFL_RESDIR_VALID (8) -#define LSFL_ALL_RESDIR_VALID (9) -#define LSFL_NODES_VALID (10) -#define LSFL_ALL_NODES_VALID (11) -#define LSFL_REQUEST_WARN (12) -#define LSFL_RECOVERD_EXIT (13) -#define LSFL_USER_GRANT_NOW (14) - -#define LSST_NONE (0) -#define LSST_INIT (1) -#define LSST_INIT_DONE (2) -#define LSST_CLEAR (3) -#define LSST_WAIT_START (4) -#define LSST_RECONFIG_DONE (5) - -struct dlm_ls { - struct list_head ls_list; /* list of lockspaces */ - uint32_t ls_local_id; /* local unique lockspace ID */ - uint32_t ls_global_id; /* global unique lockspace ID */ - int ls_allocation; /* Memory allocation policy */ - int ls_count; /* reference count */ - unsigned long ls_flags; /* LSFL_ */ - - struct dlm_rsbtable * ls_rsbtbl; - uint32_t ls_rsbtbl_size; - - struct dlm_lkbtable * ls_lkbtbl; - uint32_t ls_lkbtbl_size; - - struct dlm_dirtable * ls_dirtbl; - uint32_t ls_dirtbl_size; - - struct list_head ls_nodes; /* current nodes in ls */ - struct list_head ls_nodes_gone; /* dead node list, recovery */ - spinlock_t ls_nodes_gone_spin; - uint32_t ls_num_nodes; /* number of nodes in ls */ - uint32_t ls_low_nodeid; - uint32_t * ls_node_array; - - struct rw_semaphore ls_unlock_sem; /* To prevent unlock on a - parent lock racing with a - new child lock */ - - struct list_head ls_deadlockq; /* List of locks in conversion - ordered by duetime. for - deadlock detection */ - - /* recovery related */ - - struct task_struct * ls_recoverd_task; - struct semaphore ls_recoverd_active; - struct list_head ls_recover; /* dlm_recover structs */ - spinlock_t ls_recover_lock; - int ls_last_stop; - int ls_last_start; - int ls_last_finish; - int ls_state; /* recovery states */ - - struct rw_semaphore ls_in_recovery; /* block local requests */ - struct list_head ls_requestqueue;/* queue remote requests */ - struct semaphore ls_requestqueue_lock; - - struct dlm_rcom * ls_rcom; /* recovery comms */ - uint32_t ls_rcom_msgid; - struct semaphore ls_rcom_lock; - - struct list_head ls_recover_list; - spinlock_t ls_recover_list_lock; - int ls_recover_list_count; - wait_queue_head_t ls_wait_general; - - struct list_head ls_rootres; /* root resources */ - struct rw_semaphore ls_root_lock; /* protect rootres list */ - - struct list_head ls_rebuild_rootrsb_list; /* Root of lock trees - we're deserialising */ - int ls_namelen; - char ls_name[1]; -}; - -/* - * Resource block - */ - -#define RESFL_RECOVER_LIST (0) -#define RESFL_MASTER (1) -#define RESFL_NEW_MASTER (2) -#define RESFL_NEW_MASTER2 (3) -#define RESFL_VALNOTVALID (4) -#define RESFL_VALNOTVALID_PREV (5) - -struct dlm_rsb { - struct list_head res_hashchain; - uint32_t res_bucket; - - struct dlm_ls * res_ls; /* The owning lockspace */ - - struct list_head res_rootlist; /* List of root rsb's */ - - struct list_head res_subreslist; /* List of all sub-resources - for this root rsb */ - - uint8_t res_depth; /* Depth in resource tree */ - unsigned long res_flags; /* Flags, RESFL_ */ - - struct list_head res_grantqueue; - struct list_head res_convertqueue; - struct list_head res_waitqueue; - - uint32_t res_nodeid; /* nodeid of master node */ - - struct dlm_rsb * res_root; /* root rsb if a subresource */ - struct dlm_rsb * res_parent; /* parent rsb (if any) */ - - atomic_t res_ref; /* Number of lkb's */ - uint16_t res_remasterid; /* ID used during remaster */ - - struct list_head res_recover_list; /* General list for use - during recovery */ - int res_recover_msgid; - int res_newlkid_expect; - - struct rw_semaphore res_lock; - - uint32_t res_lvbseq; - char * res_lvbptr; /* Lock value block */ - - uint8_t res_length; - char res_name[1]; /* <res_length> bytes */ -}; - -/* - * Lock block. To avoid confusion, where flags mirror the public flags, they - * should have the same value. - * - * In general, DLM_LKF flags from dlm.h apply only to lkb_lockqueue_flags - * and GDLM_LKFLG flags from dlm_internal.h apply only to lkb_flags. - * The rr_flags field in the request struct is a copy of lkb_lockqueue_flags. - * There is one dangerous exception: GDLM_LKFLG_RANGE is set in rr_flags - * when sending a remote range lock request. This value is then copied into - * the remote lkb_lockqueue_flags field. This means GDLM_LKFLG_RANGE must - * not have the same value as any external DLM_LKF flag. - */ - -#define GDLM_LKSTS_NEW (0) -#define GDLM_LKSTS_WAITING (1) -#define GDLM_LKSTS_GRANTED (2) -#define GDLM_LKSTS_CONVERT (3) - -/* mirror external flags */ -#define GDLM_LKFLG_VALBLK (0x00000008) -#define GDLM_LKFLG_PERSISTENT (0x00000080) -#define GDLM_LKFLG_NODLCKWT (0x00000100) -#define GDLM_LKFLG_EXPEDITE (0x00000400) -#define GDLM_LKFLG_ORPHAN (0x00004000) -/* external flags now go up to: (0x00010000) DLM_LKF_ALTCW */ - -/* internal-only flags */ -#define GDLM_LKFLG_RANGE (0x00020000) -#define GDLM_LKFLG_MSTCPY (0x00040000) -#define GDLM_LKFLG_DELETED (0x00080000) -#define GDLM_LKFLG_LQCONVERT (0x00100000) -#define GDLM_LKFLG_LQRESEND (0x00200000) -#define GDLM_LKFLG_DEMOTED (0x00400000) -#define GDLM_LKFLG_RESENT (0x00800000) -#define GDLM_LKFLG_NOREBUILD (0x01000000) -#define GDLM_LKFLG_UNLOCKDONE (0x02000000) -#define GDLM_LKFLG_VALNOTVALID (0x04000000) -#define GDLM_LKFLG_RETURNLVB (0x08000000) -#define GDLM_LKFLG_ALTMODE (0x10000000) - -#define AST_COMP (1) -#define AST_BAST (2) -#define AST_DEL (4) - -struct dlm_lkb { - uint32_t lkb_flags; - uint16_t lkb_status; /* grant, wait, convert */ - int8_t lkb_rqmode; /* requested lock mode */ - int8_t lkb_grmode; /* granted lock mode */ - uint32_t lkb_retstatus; /* status to return in lksb */ - uint32_t lkb_id; /* our lock ID */ - struct dlm_lksb * lkb_lksb; /* status block of caller */ - struct list_head lkb_idtbl_list; /* lockidtbl */ - struct list_head lkb_statequeue; /* rsb's g/c/w queue */ - struct dlm_rsb * lkb_resource; - struct dlm_lkb * lkb_parent; /* parent lock if any */ - atomic_t lkb_childcnt; /* number of children */ - - struct list_head lkb_lockqueue; /* queue of locks waiting - for remote reply */ - int16_t lkb_lockqueue_state; /* reason on lockqueue */ - int16_t lkb_prev_lq_state; - uint32_t lkb_lockqueue_flags; /* as passed into - lock/unlock */ - int lkb_ownpid; /* pid of lock owner */ - unsigned long lkb_lockqueue_time; /* time lkb went on the - lockqueue */ - unsigned long lkb_duetime; /* for deadlock detection */ - - uint32_t lkb_remid; /* id on remote partner */ - uint32_t lkb_nodeid; /* id of remote partner */ - void * lkb_astaddr; - void * lkb_bastaddr; - long lkb_astparam; - struct list_head lkb_astqueue; /* locks with asts to deliver */ - uint16_t lkb_astflags; /* COMP, BAST, DEL */ - uint8_t lkb_bastmode; /* requested mode */ - uint8_t lkb_highbast; /* highest mode bast sent for */ - - struct dlm_request * lkb_request; - - struct list_head lkb_deadlockq; /* ls_deadlockq list */ - - uint32_t lkb_lvbseq; - char * lkb_lvbptr; /* points to lksb lvb on local - lock, allocated lvb on - on remote lock */ - uint64_t * lkb_range; /* Points to an array of 64 bit - numbers that represent the - requested and granted ranges - of the lock. NULL implies - 0-ffffffffffffffff */ -}; - -/* - * Header part of the mid-level comms system. All packets start with - * this header so we can identify them. The comms packet can - * contain many of these structs but the are split into individual - * work units before being passed to the lockqueue routines. - * below this are the structs that this is a header for - */ - -#define DLM_HEADER_MAJOR (0x00010000) -#define DLM_HEADER_MINOR (0x00000001) - -struct dlm_header { - uint32_t rh_version; - uint8_t rh_cmd; /* What we are */ - uint8_t rh_flags; /* maybe just a pad */ - uint16_t rh_length; /* Length of struct (so we can - send many in 1 message) */ - uint32_t rh_lkid; /* Lock ID tag: ie the local - (requesting) lock ID */ - uint32_t rh_lockspace; /* Lockspace ID */ -} __attribute__((packed)); - -/* - * This is the struct used in a remote lock/unlock/convert request - * The mid-level comms API should turn this into native byte order. - * Most "normal" lock operations will use these two structs for - * communications. Recovery operations use their own structs - * but still with the gd_req_header on the front. - */ - -struct dlm_request { - struct dlm_header rr_header; - uint32_t rr_remlkid; /* Remote lock ID */ - uint32_t rr_remparid; /* Parent's remote lock ID */ - uint32_t rr_flags; /* Flags from lock/convert req*/ - uint64_t rr_range_start; /* Yes, these are in the right - place... */ - uint64_t rr_range_end; - uint32_t rr_status; /* Status to return if this is - an AST request */ - uint32_t rr_pid; /* Owner PID of lock */ - uint32_t rr_lvbseq; - uint8_t rr_rqmode; /* Requested lock mode */ - uint8_t rr_asts; /* Whether the LKB has ASTs */ - char rr_lvb[DLM_LVB_LEN]; - char rr_name[1]; /* As long as needs be. Only - used for directory lookups. - The length of this can be - worked out from the packet - length */ -} __attribute__((packed)); - -/* - * This is the struct returned by a remote lock/unlock/convert request - * The mid-level comms API should turn this into native byte order. - */ - -struct dlm_reply { - struct dlm_header rl_header; - uint32_t rl_lockstate; /* Whether request was - queued/granted/waiting */ - uint32_t rl_nodeid; /* nodeid of lock master */ - uint32_t rl_status; /* Status to return to caller */ - uint32_t rl_lkid; /* Remote lkid */ - uint32_t rl_flags; - uint32_t rl_lvbseq; - char rl_lvb[DLM_LVB_LEN]; -} __attribute__((packed)); - -/* - * Recovery comms message - */ - -struct dlm_rcom { - struct dlm_header rc_header; /* 32 byte aligned */ - uint32_t rc_msgid; - uint16_t rc_datalen; - uint8_t rc_expanded; - uint8_t rc_subcmd; /* secondary command */ - char rc_buf[1]; /* first byte of data goes here - and extends beyond here for - another datalen - 1 bytes. - rh_length is set to sizeof - dlm_rcom + datalen - 1 */ -} __attribute__((packed)); - - -/* A remote query: GDLM_REMCMD_QUERY */ - -struct dlm_query_request { - struct dlm_header rq_header; - uint32_t rq_mstlkid; /* LockID on master node */ - uint32_t rq_query; /* query from the user */ - uint32_t rq_maxlocks; /* max number of locks we can - cope with */ -} __attribute__((packed)); - -/* First block of a reply query. cmd = GDLM_REMCMD_QUERY */ -/* There may be subsequent blocks of - lock info in GDLM_REMCMD_QUERYCONT messages which just have - a normal header. The last of these will have rh_flags set to - GDLM_REMFLAG_ENDQUERY - */ - -struct dlm_query_reply { - struct dlm_header rq_header; - uint32_t rq_numlocks; /* Number of locks in reply */ - uint32_t rq_startlock; /* Which lock this block starts - at (for multi-block replies) */ - uint32_t rq_status; - - /* Resource information */ - uint32_t rq_grantcount; /* No. of nodes on grantqueue */ - uint32_t rq_convcount; /* No. of nodes on convertq */ - uint32_t rq_waitcount; /* No. of nodes on waitqueue */ - char rq_valblk[DLM_LVB_LEN]; /* Master's LVB - contents, if - applicable */ -} __attribute__((packed)); - -/* - * Lockqueue wait lock states - */ - -#define GDLM_LQSTATE_WAIT_RSB 1 -#define GDLM_LQSTATE_WAIT_CONVERT 2 -#define GDLM_LQSTATE_WAIT_CONDGRANT 3 -#define GDLM_LQSTATE_WAIT_UNLOCK 4 - -/* Commands sent across the comms link */ -#define GDLM_REMCMD_LOOKUP 1 -#define GDLM_REMCMD_LOCKREQUEST 2 -#define GDLM_REMCMD_UNLOCKREQUEST 3 -#define GDLM_REMCMD_CONVREQUEST 4 -#define GDLM_REMCMD_LOCKREPLY 5 -#define GDLM_REMCMD_LOCKGRANT 6 -#define GDLM_REMCMD_SENDBAST 7 -#define GDLM_REMCMD_SENDCAST 8 -#define GDLM_REMCMD_REM_RESDATA 9 -#define GDLM_REMCMD_PURGE 10 -#define GDLM_REMCMD_RECOVERMESSAGE 20 -#define GDLM_REMCMD_RECOVERREPLY 21 -#define GDLM_REMCMD_QUERY 30 -#define GDLM_REMCMD_QUERYREPLY 31 - -/* Set in rh_flags when this is the last block of - query information. Note this could also be the first - block */ -#define GDLM_REMFLAG_ENDQUERY 1 - -#ifdef CONFIG_DLM_STATS -struct dlm_statinfo -{ - unsigned int cast; - unsigned int bast; - unsigned int lockops; - unsigned int unlockops; - unsigned int convertops; - unsigned long lockqueue_time[5]; - unsigned long lockqueue_locks[5]; -}; -extern struct dlm_statinfo dlm_stats; -#endif - -#ifndef BUG_ON -#define BUG_ON(x) -#endif - -void dlm_debug_log(struct dlm_ls *ls, const char *fmt, ...); -void dlm_debug_dump(void); -void dlm_locks_dump(void); - -#endif /* __DLM_INTERNAL_DOT_H__ */ diff --git a/dlm-kernel/src/lkb.c b/dlm-kernel/src/lkb.c deleted file mode 100644 index 9ee46a6..0000000 --- a/dlm-kernel/src/lkb.c +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * lkb.c - * - * Allocate and free locks on the lock ID table. - * - * This is slightly naff but I don't really like the - * VMS lockidtbl stuff as it uses a realloced array - * to hold the locks in. I think this is slightly better - * in some ways. - * - * Any better suggestions gratefully received. Patrick - * - */ - -#include "dlm_internal.h" -#include "lockqueue.h" -#include "lkb.h" -#include "config.h" -#include "rsb.h" -#include "memory.h" -#include "lockspace.h" -#include "util.h" - -/* - * Internal find lock by ID. Must be called with the lockidtbl spinlock held. - */ - -static struct dlm_lkb *__find_lock_by_id(struct dlm_ls *ls, uint32_t lkid) -{ - uint16_t bucket = lkid & 0xFFFF; - struct dlm_lkb *lkb; - - list_for_each_entry(lkb, &ls->ls_lkbtbl[bucket].list, lkb_idtbl_list){ - if (lkb->lkb_id == lkid) - return lkb; - } - return NULL; -} - -/* - * LKB lkid's are 32 bits and have two 16 bit parts. The bottom 16 bits are a - * random number between 0 and lockidtbl_size-1. This random number specifies - * the "bucket" for the lkb in lockidtbl. The upper 16 bits are a sequentially - * assigned per-bucket id. - * - * Because the 16 bit id's per bucket can roll over, a new lkid must be checked - * against the lkid of all lkb's in the bucket to avoid duplication. - * - */ - -struct dlm_lkb *create_lkb(struct dlm_ls *ls) -{ - struct dlm_lkb *lkb; - uint32_t lkid; - uint16_t bucket; - - lkb = allocate_lkb(ls); - if (!lkb) - goto out; - - retry: - get_random_bytes(&bucket, sizeof(bucket)); - bucket &= (ls->ls_lkbtbl_size - 1); - - write_lock(&ls->ls_lkbtbl[bucket].lock); - - lkid = bucket | (ls->ls_lkbtbl[bucket].counter++ << 16); - - if (!lkid) { - write_unlock(&ls->ls_lkbtbl[bucket].lock); - goto retry; - } - - if (__find_lock_by_id(ls, lkid)) { - write_unlock(&ls->ls_lkbtbl[bucket].lock); - goto retry; - } - - lkb->lkb_id = lkid; - list_add(&lkb->lkb_idtbl_list, &ls->ls_lkbtbl[bucket].list); - write_unlock(&ls->ls_lkbtbl[bucket].lock); - out: - return lkb; -} - -/* - * Free LKB and remove it from the lockidtbl. - * NB - this always frees the lkb whereas release_rsb doesn't free an - * rsb unless its reference count is zero. - */ - -void release_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb) -{ - uint16_t bucket = lkb->lkb_id & 0xFFFF; - - if (lkb->lkb_status) { - log_error(ls, "release lkb with status %u", lkb->lkb_status); - print_lkb(lkb); - return; - } - - if (lkb->lkb_parent) - atomic_dec(&lkb->lkb_parent->lkb_childcnt); - - write_lock(&ls->ls_lkbtbl[bucket].lock); - list_del(&lkb->lkb_idtbl_list); - write_unlock(&ls->ls_lkbtbl[bucket].lock); - - /* if this is not a master copy then lvbptr points into the user's - * lksb, so don't free it */ - if (lkb->lkb_lvbptr && lkb->lkb_flags & GDLM_LKFLG_MSTCPY) - free_lvb(lkb->lkb_lvbptr); - - if (lkb->lkb_range) - free_range(lkb->lkb_range); - - free_lkb(lkb); -} - -struct dlm_lkb *find_lock_by_id(struct dlm_ls *ls, uint32_t lkid) -{ - struct dlm_lkb *lkb; - uint16_t bucket = lkid & 0xFFFF; - - if (bucket >= ls->ls_lkbtbl_size) - return NULL; - - read_lock(&ls->ls_lkbtbl[bucket].lock); - lkb = __find_lock_by_id(ls, lkid); - read_unlock(&ls->ls_lkbtbl[bucket].lock); - - return lkb; -} - -struct dlm_lkb *dlm_get_lkb(void *lockspace, uint32_t lkid) -{ - struct dlm_ls *ls = find_lockspace_by_local_id(lockspace); - struct dlm_lkb *lkb = find_lock_by_id(ls, lkid); - put_lockspace(ls); - return lkb; -} - -/* - * Initialise the range parts of an LKB. - */ - -int lkb_set_range(struct dlm_ls *lspace, struct dlm_lkb *lkb, uint64_t start, uint64_t end) -{ - int ret = -ENOMEM; - - /* - * if this wasn't already a range lock, make it one - */ - if (!lkb->lkb_range) { - lkb->lkb_range = allocate_range(lspace); - if (!lkb->lkb_range) - goto out; - - /* - * This is needed for conversions that contain ranges where the - * original lock didn't but it's harmless for new locks too. - */ - lkb->lkb_range[GR_RANGE_START] = 0LL; - lkb->lkb_range[GR_RANGE_END] = 0xffffffffffffffffULL; - } - - lkb->lkb_range[RQ_RANGE_START] = start; - lkb->lkb_range[RQ_RANGE_END] = end; - - ret = 0; - - out: - return ret; -} diff --git a/dlm-kernel/src/lkb.h b/dlm-kernel/src/lkb.h deleted file mode 100644 index 1ee696d..0000000 --- a/dlm-kernel/src/lkb.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LKB_DOT_H__ -#define __LKB_DOT_H__ - -struct dlm_lkb *find_lock_by_id(struct dlm_ls *ls, uint32_t lkid); -struct dlm_lkb *create_lkb(struct dlm_ls *ls); -void release_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb); -struct dlm_lkb *dlm_get_lkb(void *ls, uint32_t lkid); -int lkb_set_range(struct dlm_ls *lspace, struct dlm_lkb *lkb, uint64_t start, uint64_t end); - -#endif /* __LKB_DOT_H__ */ diff --git a/dlm-kernel/src/locking.c b/dlm-kernel/src/locking.c deleted file mode 100644 index 73897e9..0000000 --- a/dlm-kernel/src/locking.c +++ /dev/null @@ -1,1583 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * locking.c - * - * This is where the main work of the DLM goes on - * - */ - -#include "dlm_internal.h" -#include "lockqueue.h" -#include "locking.h" -#include "lockspace.h" -#include "lkb.h" -#include "nodes.h" -#include "dir.h" -#include "ast.h" -#include "memory.h" -#include "rsb.h" -#include "util.h" -#include "lowcomms.h" - -extern struct list_head lslist; - -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -/* - * Lock compatibilty matrix - thanks Steve - * UN = Unlocked state. Not really a state, used as a flag - * PD = Padding. Used to make the matrix a nice power of two in size - * Other states are the same as the VMS DLM. - * Usage: matrix[grmode+1][rqmode+1] (although m[rq+1][gr+1] is the same) - */ - -#define modes_compat(gr, rq) \ - __dlm_compat_matrix[(gr)->lkb_grmode + 1][(rq)->lkb_rqmode + 1] - -const int __dlm_compat_matrix[8][8] = { - /* UN NL CR CW PR PW EX PD */ - {1, 1, 1, 1, 1, 1, 1, 0}, /* UN */ - {1, 1, 1, 1, 1, 1, 1, 0}, /* NL */ - {1, 1, 1, 1, 1, 1, 0, 0}, /* CR */ - {1, 1, 1, 1, 0, 0, 0, 0}, /* CW */ - {1, 1, 1, 0, 1, 0, 0, 0}, /* PR */ - {1, 1, 1, 0, 0, 0, 0, 0}, /* PW */ - {1, 1, 0, 0, 0, 0, 0, 0}, /* EX */ - {0, 0, 0, 0, 0, 0, 0, 0} /* PD */ -}; - -/* - * Compatibility matrix for conversions with QUECVT set. - * Granted mode is the row; requested mode is the column. - * Usage: matrix[grmode+1][rqmode+1] - */ - -const int __quecvt_compat_matrix[8][8] = { - /* UN NL CR CW PR PW EX PD */ - {0, 0, 0, 0, 0, 0, 0, 0}, /* UN */ - {0, 0, 1, 1, 1, 1, 1, 0}, /* NL */ - {0, 0, 0, 1, 1, 1, 1, 0}, /* CR */ - {0, 0, 0, 0, 1, 1, 1, 0}, /* CW */ - {0, 0, 0, 1, 0, 1, 1, 0}, /* PR */ - {0, 0, 0, 0, 0, 0, 1, 0}, /* PW */ - {0, 0, 0, 0, 0, 0, 0, 0}, /* EX */ - {0, 0, 0, 0, 0, 0, 0, 0} /* PD */ -}; - -/* - * This defines the direction of transfer of LVB data. - * Granted mode is the row; requested mode is the column. - * Usage: matrix[grmode+1][rqmode+1] - * 1 = LVB is returned to the caller - * 0 = LVB is written to the resource - * -1 = nothing happens to the LVB - */ - -const int __lvb_operations[8][8] = { - /* UN NL CR CW PR PW EX PD*/ - { -1, 1, 1, 1, 1, 1, 1, -1 }, /* UN */ - { -1, 1, 1, 1, 1, 1, 1, 0 }, /* NL */ - { -1, -1, 1, 1, 1, 1, 1, 0 }, /* CR */ - { -1, -1, -1, 1, 1, 1, 1, 0 }, /* CW */ - { -1, -1, -1, -1, 1, 1, 1, 0 }, /* PR */ - { -1, 0, 0, 0, 0, 0, 1, 0 }, /* PW */ - { -1, 0, 0, 0, 0, 0, 0, 0 }, /* EX */ - { -1, 0, 0, 0, 0, 0, 0, 0 } /* PD */ -}; - -static void grant_lock(struct dlm_lkb *lkb, int send_remote); -static void send_blocking_asts(struct dlm_rsb *rsb, struct dlm_lkb *lkb); -static void send_blocking_asts_all(struct dlm_rsb *rsb, struct dlm_lkb *lkb); -static int convert_lock(struct dlm_ls *ls, int mode, struct dlm_lksb *lksb, - uint32_t flags, void *ast, void *astarg, void *bast, - struct dlm_range *range); -static int dlm_lock_stage1(struct dlm_ls *ls, struct dlm_lkb *lkb, - uint32_t flags, char *name, int namelen); - - -inline int dlm_modes_compat(int mode1, int mode2) -{ - return __dlm_compat_matrix[mode1 + 1][mode2 + 1]; -} - -static inline int first_in_list(struct dlm_lkb *lkb, struct list_head *head) -{ - struct dlm_lkb *first = list_entry(head->next, struct dlm_lkb, lkb_statequeue); - - if (lkb->lkb_id == first->lkb_id) - return 1; - - return 0; -} - -/* - * Return 1 if the locks' ranges overlap - * If the lkb has no range then it is assumed to cover 0-ffffffff.ffffffff - */ - -static inline int ranges_overlap(struct dlm_lkb *lkb1, struct dlm_lkb *lkb2) -{ - if (!lkb1->lkb_range || !lkb2->lkb_range) - return 1; - - if (lkb1->lkb_range[RQ_RANGE_END] < lkb2->lkb_range[GR_RANGE_START] || - lkb1->lkb_range[RQ_RANGE_START] > lkb2->lkb_range[GR_RANGE_END]) - return 0; - - return 1; -} - -/* - * Check if the given lkb conflicts with another lkb on the queue. - */ - -static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb) -{ - struct dlm_lkb *this; - - list_for_each_entry(this, head, lkb_statequeue) { - if (this == lkb) - continue; - if (ranges_overlap(lkb, this) && !modes_compat(this, lkb)) - return TRUE; - } - return FALSE; -} - -/* - * "A conversion deadlock arises with a pair of lock requests in the converting - * queue for one resource. The granted mode of each lock blocks the requested - * mode of the other lock." - * - * Part 2: if the granted mode of lkb is preventing the first lkb in the - * convert queue from being granted, then demote lkb (set grmode to NL). - * This second form requires that we check for conv-deadlk even when - * now == 0 in _can_be_granted(). - * - * Example: - * Granted Queue: empty - * Convert Queue: NL->EX (first lock) - * PR->EX (second lock) - * - * The first lock can't be granted because of the granted mode of the second - * lock and the second lock can't be granted because it's not first in the - * list. We demote the granted mode of the second lock (the lkb passed to this - * function). - * - * After the resolution, the "grant pending" function needs to go back and try - * to grant locks on the convert queue again since the first lock can now be - * granted. - */ - -static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb) -{ - struct dlm_lkb *this, *first = NULL, *self = NULL; - - list_for_each_entry(this, &rsb->res_convertqueue, lkb_statequeue) { - if (!first) - first = this; - if (this == lkb) { - self = lkb; - continue; - } - - if (!ranges_overlap(lkb, this)) - continue; - - if (!modes_compat(this, lkb) && !modes_compat(lkb, this)) - return TRUE; - } - - /* if lkb is on the convert queue and is preventing the first - from being granted, then there's deadlock and we demote lkb. - multiple converting locks may need to do this before the first - converting lock can be granted. */ - - if (self && self != first) { - if (!modes_compat(lkb, first) && - !queue_conflict(&rsb->res_grantqueue, first)) - return TRUE; - } - - return FALSE; -} - -/* - * Return 1 if the lock can be granted, 0 otherwise. - * Also detect and resolve conversion deadlocks. - * - * lkb is the lock to be granted - * - * now is 1 if the function is being called in the context of the - * immediate request, it is 0 if called later, after the lock has been - * queued. - * - * References are from chapter 6 of "VAXcluster Principles" by Roy Davis - */ - -static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) -{ - struct dlm_ls *ls = r->res_ls; - int8_t conv = (lkb->lkb_grmode != DLM_LOCK_IV); - - /* - * 6-10: Version 5.4 introduced an option to address the phenomenon of - * a new request for a NL mode lock being blocked. - * - * 6-11: If the optional EXPEDITE flag is used with the new NL mode - * request, then it would be granted. In essence, the use of this flag - * tells the Lock Manager to expedite theis request by not considering - * what may be in the CONVERTING or WAITING queues... As of this - * writing, the EXPEDITE flag can be used only with new requests for NL - * mode locks. This flag is not valid for conversion requests. - * - * A shortcut. Earlier checks return an error if EXPEDITE is used in a - * conversion or used with a non-NL requested mode. We also know an - * EXPEDITE request is always granted immediately, so now must always - * be 1. The full condition to grant an expedite request: (now && - * !conv && lkb->rqmode == DLM_LOCK_NL && (flags & EXPEDITE)) can - * therefore be shortened to just checking the flag. - */ - - if (lkb->lkb_lockqueue_flags & DLM_LKF_EXPEDITE) - return TRUE; - - /* - * A shortcut. Without this, !queue_conflict(grantqueue, lkb) would be - * added to the remaining conditions. - */ - - if (queue_conflict(&r->res_grantqueue, lkb)) - goto out; - - /* - * 6-3: By default, a conversion request is immediately granted if the - * requested mode is compatible with the modes of all other granted - * locks - */ - - if (queue_conflict(&r->res_convertqueue, lkb)) - goto out; - - /* - * 6-5: But the default algorithm for deciding whether to grant or - * queue conversion requests does not by itself guarantee that such - * requests are serviced on a "first come first serve" basis. This, in - * turn, can lead to a phenomenon known as "indefinate postponement". - * - * 6-7: This issue is dealt with by using the optional QUECVT flag with - * the system service employed to request a lock conversion. This flag - * forces certain conversion requests to be queued, even if they are - * compatible with the granted modes of other locks on the same - * resource. Thus, the use of this flag results in conversion requests - * being ordered on a "first come first servce" basis. - * - * DCT: This condition is all about new conversions being able to occur - * "in place" while the lock remains on the granted queue (assuming - * nothing else conflicts.) IOW if QUECVT isn't set, a conversion - * doesn't _have_ to go onto the convert queue where it's processed in - * order. The "now" variable is necessary to distinguish converts - * being received and processed for the first time now, because once a - * convert is moved to the conversion queue the condition below applies - * requiring fifo granting. - */ - - if (now && conv && !(lkb->lkb_lockqueue_flags & DLM_LKF_QUECVT)) - return TRUE; - - /* - * When using range locks the NOORDER flag is set to avoid the standard - * vms rules on grant order. - */ - - if (lkb->lkb_lockqueue_flags & DLM_LKF_NOORDER) - return TRUE; - - /* - * 6-3: Once in that queue [CONVERTING], a conversion request cannot be - * granted until all other conversion requests ahead of it are granted - * and/or canceled. - */ - - if (!now && conv && first_in_list(lkb, &r->res_convertqueue)) - return TRUE; - - /* - * 6-4: By default, a new request is immediately granted only if all - * three of the following conditions are satisfied when the request is - * issued: - * - The queue of ungranted conversion requests for the resource is - * empty. - * - The queue of ungranted new requests for the resource is empty. - * - The mode of the new request is compatible with the most - * restrictive mode of all granted locks on the resource. - */ - - if (now && !conv && list_empty(&r->res_convertqueue) && - list_empty(&r->res_waitqueue)) - return TRUE; - - /* - * 6-4: Once a lock request is in the queue of ungranted new requests, - * it cannot be granted until the queue of ungranted conversion - * requests is empty, all ungranted new requests ahead of it are - * granted and/or canceled, and it is compatible with the granted mode - * of the most restrictive lock granted on the resource. - */ - - if (!now && !conv && list_empty(&r->res_convertqueue) && - first_in_list(lkb, &r->res_waitqueue)) - return TRUE; - - /* special case for - https://bugzilla.redhat.com/show_bug.cgi?id=483685 */ - - if (test_bit(LSFL_USER_GRANT_NOW, &ls->ls_flags) && - now && !conv && list_empty(&r->res_convertqueue) && - list_empty(&r->res_grantqueue)) - return TRUE; - - out: - /* - * The following, enabled by CONVDEADLK, departs from VMS. - */ - - if (conv && (lkb->lkb_lockqueue_flags & DLM_LKF_CONVDEADLK) && - conversion_deadlock_detect(r, lkb)) { - lkb->lkb_grmode = DLM_LOCK_NL; - lkb->lkb_flags |= GDLM_LKFLG_DEMOTED; - } - - return FALSE; -} - -static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) -{ - uint32_t flags = lkb->lkb_lockqueue_flags; - int rv; - int8_t alt = 0, rqmode = lkb->lkb_rqmode; - - rv = _can_be_granted(r, lkb, now); - if (rv) - goto out; - - if (lkb->lkb_flags & GDLM_LKFLG_DEMOTED) - goto out; - - if (rqmode != DLM_LOCK_PR && flags & DLM_LKF_ALTPR) - alt = DLM_LOCK_PR; - else if (rqmode != DLM_LOCK_CW && flags & DLM_LKF_ALTCW) - alt = DLM_LOCK_CW; - - if (alt) { - lkb->lkb_rqmode = alt; - rv = _can_be_granted(r, lkb, now); - if (rv) - lkb->lkb_flags |= GDLM_LKFLG_ALTMODE; - else - lkb->lkb_rqmode = rqmode; - } - out: - return rv; -} - -int dlm_lock(void *lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void (*ast) (void *astarg), - void *astarg, - void (*bast) (void *astarg, int mode), - struct dlm_range *range) -{ - struct dlm_ls *ls; - struct dlm_lkb *lkb = NULL, *parent_lkb = NULL; - int ret = -EINVAL; - - ls = find_lockspace_by_local_id(lockspace); - if (!ls) { - log_print("dlm_lock: no lockspace"); - return ret; - } - - if (mode < 0 || mode > DLM_LOCK_EX) { - log_error(ls, "dlm_lock: bad mode %u", mode); - goto out; - } - - if (!(flags & DLM_LKF_CONVERT) && (namelen > DLM_RESNAME_MAXLEN)) { - log_error(ls, "dlm_lock: bad name length %u", namelen); - goto out; - } - - if (flags & DLM_LKF_CANCEL) { - log_error(ls, "dlm_lock: cancel not allowed"); - goto out; - } - - if (flags & DLM_LKF_QUECVT && !(flags & DLM_LKF_CONVERT)) { - log_error(ls, "dlm_lock: bad quecvt use %x", flags); - goto out; - } - - if (flags & DLM_LKF_CONVDEADLK && !(flags & DLM_LKF_CONVERT)) { - log_error(ls, "dlm_lock: bad convdeadlk/convert use %x", flags); - goto out; - } - - if (flags & DLM_LKF_CONVDEADLK && flags & DLM_LKF_NOQUEUE) { - log_error(ls, "dlm_lock: bad convdeadlk/noqueue use %x", flags); - goto out; - } - - if (flags & DLM_LKF_EXPEDITE && flags & DLM_LKF_CONVERT) { - log_error(ls, "dlm_lock: bad expedite/convert use %x", flags); - goto out; - } - - if (flags & DLM_LKF_EXPEDITE && flags & DLM_LKF_QUECVT) { - log_error(ls, "dlm_lock: bad expedite/quecvt use %x", flags); - goto out; - } - - if (flags & DLM_LKF_EXPEDITE && flags & DLM_LKF_NOQUEUE) { - log_error(ls, "dlm_lock: bad expedite/noqueue use %x", flags); - goto out; - } - - if (flags & DLM_LKF_EXPEDITE && (mode != DLM_LOCK_NL)) { - log_error(ls, "dlm_lock: bad mode %u flags %x", mode, flags); - goto out; - } - - if (!ast || !lksb) { - if (!ast) - log_error(ls, "dlm_lock: no ast param"); - if (!lksb) - log_error(ls, "dlm_lock: no lksb param"); - goto out; - } - - if ((flags & DLM_LKF_VALBLK) && !lksb->sb_lvbptr) { - log_error(ls, "dlm_lock: no lvbptr flags %x", flags); - goto out; - } - - /* - * Take conversion path. - */ - - if (flags & DLM_LKF_CONVERT) { - ret = convert_lock(ls, mode, lksb, flags, ast, astarg, - bast, range); - goto out; - } - -#ifdef CONFIG_DLM_STATS - dlm_stats.lockops++; -#endif - /* - * Take new lock path. - */ - - if (parent) { - down_read(&ls->ls_unlock_sem); - - parent_lkb = find_lock_by_id(ls, parent); - - if (!parent_lkb || - parent_lkb->lkb_flags & GDLM_LKFLG_DELETED || - parent_lkb->lkb_flags & GDLM_LKFLG_MSTCPY || - parent_lkb->lkb_status != GDLM_LKSTS_GRANTED) { - up_read(&ls->ls_unlock_sem); - goto out; - } - - atomic_inc(&parent_lkb->lkb_childcnt); - up_read(&ls->ls_unlock_sem); - } - - down_read(&ls->ls_in_recovery); - - ret = -ENOMEM; - - lkb = create_lkb(ls); - if (!lkb) - goto fail_dec; - lkb->lkb_astaddr = ast; - lkb->lkb_astparam = (long) astarg; - lkb->lkb_bastaddr = bast; - lkb->lkb_rqmode = mode; - lkb->lkb_grmode = DLM_LOCK_IV; - lkb->lkb_nodeid = -1; - lkb->lkb_lksb = lksb; - lkb->lkb_parent = parent_lkb; - lkb->lkb_lockqueue_flags = flags; - lkb->lkb_lvbptr = lksb->sb_lvbptr; - - if (!in_interrupt() && current) - lkb->lkb_ownpid = (int) current->pid; - else - lkb->lkb_ownpid = 0; - - if (range) { - if (range->ra_start > range->ra_end) { - log_error(ls, "dlm_lock bad range"); - ret = -EINVAL; - goto fail_free; - } - - if (lkb_set_range(ls, lkb, range->ra_start, range->ra_end)) - goto fail_free; - } - - /* Convert relevant flags to internal numbers */ - if (flags & DLM_LKF_VALBLK) - lkb->lkb_flags |= GDLM_LKFLG_VALBLK; - if (flags & DLM_LKF_PERSISTENT) - lkb->lkb_flags |= GDLM_LKFLG_PERSISTENT; - if (flags & DLM_LKF_NODLCKWT) - lkb->lkb_flags |= GDLM_LKFLG_NODLCKWT; - - lksb->sb_lkid = lkb->lkb_id; - - ret = dlm_lock_stage1(ls, lkb, flags, name, namelen); - if (ret) - goto fail_free; - - up_read(&ls->ls_in_recovery); - - wake_astd(); - - put_lockspace(ls); - return 0; - - fail_free: - release_lkb(ls, lkb); - goto fail_unlock; - - fail_dec: - if (parent_lkb) - atomic_dec(&parent_lkb->lkb_childcnt); - - fail_unlock: - up_read(&ls->ls_in_recovery); - - out: - put_lockspace(ls); - return ret; -} - -int dlm_lock_stage1(struct dlm_ls *ls, struct dlm_lkb *lkb, uint32_t flags, - char *name, int namelen) -{ - struct dlm_rsb *rsb, *parent_rsb = NULL; - struct dlm_lkb *parent_lkb = lkb->lkb_parent; - uint32_t nodeid; - int error, dir_error = 0; - - if (parent_lkb) - parent_rsb = parent_lkb->lkb_resource; - - error = find_rsb(ls, parent_rsb, name, namelen, CREATE, &rsb); - if (error) - return error; - lkb->lkb_resource = rsb; - down_write(&rsb->res_lock); - - log_debug1(ls, "(%d) rq %u %x "%s"", lkb->lkb_ownpid, lkb->lkb_rqmode, - lkb->lkb_id, rsb->res_name); - /* - * Next stage, do we need to find the master or can - * we get on with the real locking work ? - */ - - retry: - if (rsb->res_nodeid == -1) { - if (get_directory_nodeid(rsb) != our_nodeid()) { - up_write(&rsb->res_lock); - remote_stage(lkb, GDLM_LQSTATE_WAIT_RSB); - return 0; - } - - error = dlm_dir_lookup(ls, our_nodeid(), rsb->res_name, - rsb->res_length, &nodeid); - if (error) { - DLM_ASSERT(error == -EEXIST,); - msleep(500); - dir_error = error; - goto retry; - } - - if (nodeid == our_nodeid()) { - set_bit(RESFL_MASTER, &rsb->res_flags); - rsb->res_nodeid = 0; - } else { - clear_bit(RESFL_MASTER, &rsb->res_flags); - rsb->res_nodeid = nodeid; - } - - if (dir_error) { - log_debug(ls, "dir lookup retry %x %u", lkb->lkb_id, - nodeid); - } - } - - lkb->lkb_nodeid = rsb->res_nodeid; - up_write(&rsb->res_lock); - - error = dlm_lock_stage2(ls, lkb, rsb, flags); - - return error; -} - -/* - * Locking routine called after we have an RSB, either a copy of a remote one - * or a local one, or perhaps a shiny new one all of our very own - */ - -int dlm_lock_stage2(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_rsb *rsb, - uint32_t flags) -{ - int error = 0; - - DLM_ASSERT(rsb->res_nodeid != -1, print_lkb(lkb); print_rsb(rsb);); - - if (rsb->res_nodeid) { - res_lkb_enqueue(rsb, lkb, GDLM_LKSTS_WAITING); - error = remote_stage(lkb, GDLM_LQSTATE_WAIT_CONDGRANT); - } else { - dlm_lock_stage3(lkb); - } - - return error; -} - -/* - * Called on an RSB's master node to do stage2 locking for a remote lock - * request. Returns a proper lkb with rsb ready for lock processing. - * This is analagous to sections of dlm_lock() and dlm_lock_stage1(). - */ - -struct dlm_lkb *remote_stage2(int remote_nodeid, struct dlm_ls *ls, - struct dlm_request *freq) -{ - struct dlm_rsb *rsb = NULL, *parent_rsb = NULL; - struct dlm_lkb *lkb = NULL, *parent_lkb = NULL; - int error, namelen; - - if (freq->rr_remparid) { - parent_lkb = find_lock_by_id(ls, freq->rr_remparid); - if (!parent_lkb) - goto fail; - - atomic_inc(&parent_lkb->lkb_childcnt); - parent_rsb = parent_lkb->lkb_resource; - } - - /* - * A new MSTCPY lkb. Initialize lkb fields including the real lkid and - * node actually holding the (non-MSTCPY) lkb. AST address are just - * flags in the master copy. - */ - - lkb = create_lkb(ls); - if (!lkb) - goto fail_dec; - lkb->lkb_grmode = DLM_LOCK_IV; - lkb->lkb_rqmode = freq->rr_rqmode; - lkb->lkb_parent = parent_lkb; - lkb->lkb_astaddr = (void *) (long) (freq->rr_asts & AST_COMP); - lkb->lkb_bastaddr = (void *) (long) (freq->rr_asts & AST_BAST); - lkb->lkb_nodeid = remote_nodeid; - lkb->lkb_remid = freq->rr_header.rh_lkid; - lkb->lkb_flags = GDLM_LKFLG_MSTCPY; - lkb->lkb_lockqueue_flags = freq->rr_flags; - - if (lkb->lkb_lockqueue_flags & DLM_LKF_VALBLK) { - lkb->lkb_flags |= GDLM_LKFLG_VALBLK; - allocate_and_copy_lvb(ls, &lkb->lkb_lvbptr, freq->rr_lvb); - if (!lkb->lkb_lvbptr) - goto fail_free; - } - - if (lkb->lkb_lockqueue_flags & GDLM_LKFLG_RANGE) { - error = lkb_set_range(ls, lkb, freq->rr_range_start, - freq->rr_range_end); - if (error) - goto fail_free; - } - - /* - * Get the RSB which this lock is for. Create a new RSB if this is a - * new lock on a new resource. We must be the master of any new rsb. - */ - - namelen = freq->rr_header.rh_length - sizeof(*freq) + 1; - - error = find_rsb(ls, parent_rsb, freq->rr_name, namelen, MASTER, &rsb); - if (error) - goto fail_free; - - if (!rsb) { - log_debug(ls, "send einval to %u", remote_nodeid); - /* print_name(freq->rr_name, namelen); */ - lkb->lkb_retstatus = -EINVAL; - goto out; - } - - lkb->lkb_resource = rsb; - - log_debug1(ls, "(%d) rq %u from %u %x "%s"", - lkb->lkb_ownpid, lkb->lkb_rqmode, remote_nodeid, - lkb->lkb_id, rsb->res_name); - - out: - return lkb; - - fail_free: - /* release_lkb handles parent */ - release_lkb(ls, lkb); - parent_lkb = NULL; - - fail_dec: - if (parent_lkb) - atomic_dec(&parent_lkb->lkb_childcnt); - fail: - return NULL; -} - -/* - * The final bit of lock request processing on the master node. Here the lock - * is granted and the completion ast is queued, or the lock is put on the - * waitqueue and blocking asts are sent. - */ - -void dlm_lock_stage3(struct dlm_lkb *lkb) -{ - struct dlm_rsb *rsb = lkb->lkb_resource; - - /* - * This is a locally mastered lock on a resource that already exists, - * see if it can be granted or if it must wait. When this function is - * called for a remote lock request (process_cluster_request, - * REMCMD_LOCKREQUEST), the result from grant_lock is returned to the - * requesting node at the end of process_cluster_request, not at the - * end of grant_lock. - */ - - down_write(&rsb->res_lock); - - if (can_be_granted(rsb, lkb, TRUE)) { - grant_lock(lkb, 0); - goto out; - } - - /* - * This request is not a conversion, so the lkb didn't exist other than - * for this request and should be freed after EAGAIN is returned in the - * ast. - */ - - if (lkb->lkb_lockqueue_flags & DLM_LKF_NOQUEUE) { - lkb->lkb_retstatus = -EAGAIN; - if (lkb->lkb_lockqueue_flags & DLM_LKF_NOQUEUEBAST) - send_blocking_asts_all(rsb, lkb); - /* - * up the res_lock before queueing ast, since the AST_DEL will - * cause the rsb to be released and that can happen anytime. - */ - up_write(&rsb->res_lock); - queue_ast(lkb, AST_COMP | AST_DEL, 0); - return; - } - - /* - * The requested lkb must wait. Because the rsb of the requested lkb - * is mastered here, send blocking asts for the lkb's blocking the - * request. - */ - - log_debug2("w %x %d %x %d,%d %d %s", lkb->lkb_id, lkb->lkb_nodeid, - lkb->lkb_remid, lkb->lkb_grmode, lkb->lkb_rqmode, - lkb->lkb_status, rsb->res_name); - - lkb->lkb_retstatus = 0; - lkb_enqueue(rsb, lkb, GDLM_LKSTS_WAITING); - - send_blocking_asts(rsb, lkb); - - out: - up_write(&rsb->res_lock); -} - -int dlm_unlock(void *lockspace, - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb, - void *astarg) -{ - struct dlm_ls *ls = find_lockspace_by_local_id(lockspace); - struct dlm_lkb *lkb; - struct dlm_rsb *rsb; - int ret = -EINVAL; - - if (!ls) { - log_print("dlm_unlock: lkid %x lockspace not found", lkid); - return ret; - } - - lkb = find_lock_by_id(ls, lkid); - if (!lkb) { - log_error(ls, "dlm_unlock: unknown lkid %x", lkid); - goto out; - } - - /* Can't dequeue a master copy (a remote node's mastered lock) */ - if (lkb->lkb_flags & GDLM_LKFLG_MSTCPY) { - log_error(ls, "(%d) dlm_unlock: %x invalid lkb_flags %x", - lkb->lkb_ownpid, lkid, lkb->lkb_flags); - goto out; - } - - /* Already waiting for a remote lock operation */ - if (lkb->lkb_lockqueue_state) { - log_error(ls, "(%d) dlm_unlock: %x busy %d", - lkb->lkb_ownpid, lkid, lkb->lkb_lockqueue_state); - if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_UNLOCK) - ret = -EINPROGRESS; - else - ret = -EBUSY; - goto out; - } - -#ifdef CONFIG_DLM_STATS - dlm_stats.unlockops++; -#endif - /* Can only cancel WAITING or CONVERTing locks. - * This is just a quick check - it is also checked in unlock_stage2() - * (which may be on the master) under the semaphore. - */ - if ((flags & DLM_LKF_CANCEL) && - (lkb->lkb_status == GDLM_LKSTS_GRANTED)) { - log_error(ls, "(%d) dlm_unlock: id %x flags %x status %d", - lkb->lkb_ownpid, lkid, flags, lkb->lkb_status); - goto out; - } - - /* "Normal" unlocks must operate on a granted lock */ - if (!(flags & DLM_LKF_CANCEL) && - (lkb->lkb_status != GDLM_LKSTS_GRANTED)) { - log_error(ls, "(%d) dlm_unlock: id %x flags %x status %d", - lkb->lkb_ownpid, lkid, flags, lkb->lkb_status); - goto out; - } - - if (lkb->lkb_flags & GDLM_LKFLG_DELETED) { - log_debug(ls, "(%d) dlm_unlock: deleted id %x flags %x sts %d", - lkb->lkb_ownpid, lkid, flags, lkb->lkb_status); - goto out; - } - - down_write(&ls->ls_unlock_sem); - /* Can't dequeue a lock with sublocks */ - if (atomic_read(&lkb->lkb_childcnt)) { - up_write(&ls->ls_unlock_sem); - ret = -ENOTEMPTY; - goto out; - } - /* Mark it as deleted so we can't use it as a parent in dlm_lock() */ - if (!(flags & DLM_LKF_CANCEL)) - lkb->lkb_flags |= GDLM_LKFLG_DELETED; - up_write(&ls->ls_unlock_sem); - - down_read(&ls->ls_in_recovery); - rsb = find_rsb_to_unlock(ls, lkb); - - log_debug1(ls, "(%d) un %x %x %d %d "%s"", - lkb->lkb_ownpid, - lkb->lkb_id, - lkb->lkb_flags, - lkb->lkb_nodeid, - rsb->res_nodeid, - rsb->res_name); - - /* Save any new params */ - if (lksb) - lkb->lkb_lksb = lksb; - lkb->lkb_astparam = (long) astarg; - lkb->lkb_lockqueue_flags = flags; - - if (lkb->lkb_nodeid) - ret = remote_stage(lkb, GDLM_LQSTATE_WAIT_UNLOCK); - else { - dlm_unlock_stage2(lkb, rsb, flags); - ret = 0; - } - up_read(&ls->ls_in_recovery); - - wake_astd(); - - out: - put_lockspace(ls); - return ret; -} - -int dlm_unlock_stage2(struct dlm_lkb *lkb, struct dlm_rsb *rsb, uint32_t flags) -{ - int remote = lkb->lkb_flags & GDLM_LKFLG_MSTCPY; - int old_status, rv = 0; - - down_write(&rsb->res_lock); - - if ((flags & DLM_LKF_CANCEL) && lkb->lkb_status == GDLM_LKSTS_GRANTED) { - log_print("cancel granted %x", lkb->lkb_id); - rv = lkb->lkb_retstatus = -EINVAL; - up_write(&rsb->res_lock); - if (!remote) - queue_ast(lkb, AST_COMP, 0); - goto out; - } - - log_debug2("u %x %d %x %d,%d %d %s", lkb->lkb_id, lkb->lkb_nodeid, - lkb->lkb_remid, lkb->lkb_grmode, lkb->lkb_rqmode, - lkb->lkb_status, rsb->res_name); - - old_status = lkb_dequeue(lkb); - - if (flags & DLM_LKF_CANCEL) { - if (old_status == GDLM_LKSTS_CONVERT) { - /* VMS semantics say we should send blocking ASTs - again here */ - send_blocking_asts(rsb, lkb); - - /* Remove from deadlock detection */ - if (lkb->lkb_duetime) - remove_from_deadlockqueue(lkb); - - lkb_enqueue(rsb, lkb, GDLM_LKSTS_GRANTED); - lkb->lkb_rqmode = DLM_LOCK_IV; - - /* Was it blocking any other locks? */ - if (first_in_list(lkb, &rsb->res_convertqueue)) - grant_pending_locks(rsb); - - rv = lkb->lkb_retstatus = -DLM_ECANCEL; - up_write(&rsb->res_lock); - if (!remote) - queue_ast(lkb, AST_COMP, 0); - } else if (old_status == GDLM_LKSTS_WAITING) { - lkb->lkb_rqmode = DLM_LOCK_IV; - rv = lkb->lkb_retstatus = -DLM_ECANCEL; - up_write(&rsb->res_lock); - if (!remote) - queue_ast(lkb, AST_COMP | AST_DEL, 0); - else { - /* frees the lkb */ - release_lkb(rsb->res_ls, lkb); - release_rsb(rsb); - } - } else - log_print("unlock cancel status %d", old_status); - } else { - if (old_status != GDLM_LKSTS_GRANTED) { - log_print("unlock ungranted %d", old_status); - rv = lkb->lkb_retstatus = -EINVAL; - up_write(&rsb->res_lock); - if (!remote) - queue_ast(lkb, AST_COMP, 0); - } else { - if (lkb->lkb_grmode >= DLM_LOCK_PW) { - if (!rsb->res_lvbptr) - rsb->res_lvbptr = allocate_lvb(rsb->res_ls); - if ((flags & DLM_LKF_VALBLK) && lkb->lkb_lvbptr) { - memcpy(rsb->res_lvbptr, lkb->lkb_lvbptr, - DLM_LVB_LEN); - rsb->res_lvbseq++; - clear_bit(RESFL_VALNOTVALID, &rsb->res_flags); - } - if (flags & DLM_LKF_IVVALBLK) - set_bit(RESFL_VALNOTVALID, &rsb->res_flags); - } - grant_pending_locks(rsb); - rv = lkb->lkb_retstatus = -DLM_EUNLOCK; - up_write(&rsb->res_lock); - if (!remote) - queue_ast(lkb, AST_COMP | AST_DEL, 0); - else { - /* frees the lkb */ - release_lkb(rsb->res_ls, lkb); - release_rsb(rsb); - } - } - } - - out: - if (!remote) - wake_astd(); - return rv; -} - -/* - * Lock conversion - */ - -static int convert_lock(struct dlm_ls *ls, int mode, struct dlm_lksb *lksb, - uint32_t flags, void *ast, void *astarg, void *bast, - struct dlm_range *range) -{ - struct dlm_lkb *lkb; - struct dlm_rsb *rsb; - int ret = -EINVAL; - - lkb = find_lock_by_id(ls, lksb->sb_lkid); - if (!lkb) { - log_error(ls, "dlm_lock: convert unknown lkid %x", - lksb->sb_lkid); - goto out; - } - - if (lkb->lkb_status != GDLM_LKSTS_GRANTED) { - log_error(ls, "dlm_lock: convert busy lock id %x status %d", - lksb->sb_lkid, lkb->lkb_status); - ret = -EBUSY; - goto out; - } - - if (lkb->lkb_flags & GDLM_LKFLG_MSTCPY) { - log_error(ls, "dlm_lock: convert mstcpy flags %x id %x", - lkb->lkb_flags, lksb->sb_lkid); - goto out; - } - - if ((flags & DLM_LKF_QUECVT) && - !__quecvt_compat_matrix[lkb->lkb_grmode + 1][mode + 1]) { - log_error(ls, "dlm_lock: convert id %x flags %x modes %d %d", - lksb->sb_lkid, flags, lkb->lkb_grmode, mode); - goto out; - } - - if (!lksb->sb_lvbptr && (flags & DLM_LKF_VALBLK)) { - log_error(ls, "dlm_lock: convert %x no lvbptr %x", - lksb->sb_lkid, flags); - goto out; - } - -#ifdef CONFIG_DLM_STATS - dlm_stats.convertops++; -#endif - /* Set up the ranges as appropriate */ - if (range) { - if (range->ra_start > range->ra_end) { - log_error(ls, "dlm_lock: convert bad range"); - goto out; - } - - if (lkb_set_range(ls, lkb, range->ra_start, range->ra_end)) { - ret = -ENOMEM; - goto out; - } - } - - rsb = lkb->lkb_resource; - down_read(&ls->ls_in_recovery); - - log_debug1(ls, "(%d) cv %u %x "%s"", lkb->lkb_ownpid, mode, - lkb->lkb_id, rsb->res_name); - - lkb->lkb_flags &= ~(GDLM_LKFLG_VALBLK | GDLM_LKFLG_DEMOTED | - GDLM_LKFLG_RETURNLVB | GDLM_LKFLG_VALNOTVALID | - GDLM_LKFLG_ALTMODE); - - if (flags & DLM_LKF_NODLCKWT) - lkb->lkb_flags |= GDLM_LKFLG_NODLCKWT; - if (flags & DLM_LKF_VALBLK) - lkb->lkb_flags |= GDLM_LKFLG_VALBLK; - lkb->lkb_astaddr = ast; - lkb->lkb_astparam = (long) astarg; - lkb->lkb_bastaddr = bast; - lkb->lkb_rqmode = mode; - lkb->lkb_lockqueue_flags = flags; - lkb->lkb_lvbptr = lksb->sb_lvbptr; - - if (rsb->res_nodeid) { - res_lkb_swqueue(rsb, lkb, GDLM_LKSTS_CONVERT); - ret = remote_stage(lkb, GDLM_LQSTATE_WAIT_CONVERT); - } else { - ret = dlm_convert_stage2(lkb, FALSE); - } - - up_read(&ls->ls_in_recovery); - - wake_astd(); - - out: - return ret; -} - -/* - * For local conversion requests on locally mastered locks this is called - * directly from dlm_lock/convert_lock. This function is also called for - * remote conversion requests of MSTCPY locks (from process_cluster_request). - */ - -int dlm_convert_stage2(struct dlm_lkb *lkb, int do_ast) -{ - struct dlm_rsb *rsb = lkb->lkb_resource; - int ret = 0; - - down_write(&rsb->res_lock); - - if (can_be_granted(rsb, lkb, TRUE)) { - grant_lock(lkb, 0); - grant_pending_locks(rsb); - goto out; - } - - if (lkb->lkb_lockqueue_flags & DLM_LKF_NOQUEUE) { - ret = lkb->lkb_retstatus = -EAGAIN; - if (do_ast) - queue_ast(lkb, AST_COMP, 0); - if (lkb->lkb_lockqueue_flags & DLM_LKF_NOQUEUEBAST) - send_blocking_asts_all(rsb, lkb); - goto out; - } - - log_debug2("c %x %d %x %d,%d %d %s", lkb->lkb_id, lkb->lkb_nodeid, - lkb->lkb_remid, lkb->lkb_grmode, lkb->lkb_rqmode, - lkb->lkb_status, rsb->res_name); - - lkb->lkb_retstatus = 0; - lkb_swqueue(rsb, lkb, GDLM_LKSTS_CONVERT); - - /* - * The granted mode may have been reduced to NL by conversion deadlock - * avoidance in can_be_granted(). If so, try to grant other locks. - */ - - if (lkb->lkb_flags & GDLM_LKFLG_DEMOTED) - grant_pending_locks(rsb); - - send_blocking_asts(rsb, lkb); - - if (!(lkb->lkb_flags & GDLM_LKFLG_NODLCKWT)) - add_to_deadlockqueue(lkb); - - out: - up_write(&rsb->res_lock); - return ret; -} - -/* - * Remove lkb from any queue it's on, add it to the granted queue, and queue a - * completion ast. rsb res_lock must be held in write when this is called. - */ - -static void grant_lock(struct dlm_lkb *lkb, int send_remote) -{ - struct dlm_rsb *rsb = lkb->lkb_resource; - - if (lkb->lkb_duetime) - remove_from_deadlockqueue(lkb); - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) { - int b; - DLM_ASSERT(lkb->lkb_lvbptr,); - - if (!rsb->res_lvbptr) - rsb->res_lvbptr = allocate_lvb(rsb->res_ls); - - lkb->lkb_flags &= ~GDLM_LKFLG_RETURNLVB; - - b = __lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1]; - if (b == 1) { - memcpy(lkb->lkb_lvbptr, rsb->res_lvbptr, DLM_LVB_LEN); - lkb->lkb_flags |= GDLM_LKFLG_RETURNLVB; - lkb->lkb_lvbseq = rsb->res_lvbseq; - } - if (b == 0) { - memcpy(rsb->res_lvbptr, lkb->lkb_lvbptr, DLM_LVB_LEN); - clear_bit(RESFL_VALNOTVALID, &rsb->res_flags); - rsb->res_lvbseq++; - lkb->lkb_lvbseq = rsb->res_lvbseq; - } - } - - if (test_bit(RESFL_VALNOTVALID, &rsb->res_flags)) - lkb->lkb_flags |= GDLM_LKFLG_VALNOTVALID; - - if (lkb->lkb_range) { - lkb->lkb_range[GR_RANGE_START] = lkb->lkb_range[RQ_RANGE_START]; - lkb->lkb_range[GR_RANGE_END] = lkb->lkb_range[RQ_RANGE_END]; - } - - log_debug2("g %x %d %x %d,%d %d %x %s", lkb->lkb_id, lkb->lkb_nodeid, - lkb->lkb_remid, lkb->lkb_grmode, lkb->lkb_rqmode, - lkb->lkb_status, lkb->lkb_flags, rsb->res_name); - - if (lkb->lkb_grmode != lkb->lkb_rqmode) { - lkb->lkb_grmode = lkb->lkb_rqmode; - lkb_swqueue(rsb, lkb, GDLM_LKSTS_GRANTED); - } - lkb->lkb_rqmode = DLM_LOCK_IV; - lkb->lkb_highbast = 0; - lkb->lkb_retstatus = 0; - queue_ast(lkb, AST_COMP, 0); - - /* - * A remote conversion request has been granted, either immediately - * upon being requested or after waiting a bit. In the former case, - * reply_and_grant() is called. In the later case send_remote is 1 and - * remote_grant() is called. - * - * The "send_remote" flag is set only for locks which are granted "out - * of band" - ie by another lock being converted or unlocked. - * - * The second case occurs when this lkb is granted right away as part - * of processing the initial request. In that case, we send a single - * message in reply_and_grant which combines the request reply with the - * grant message. - */ - - if ((lkb->lkb_flags & GDLM_LKFLG_MSTCPY) && lkb->lkb_nodeid) { - if (send_remote) - remote_grant(lkb); - else if (lkb->lkb_request) - reply_and_grant(lkb); - } - -} - -static void send_bast_queue(struct list_head *head, struct dlm_lkb *lkb) -{ - struct dlm_lkb *gr; - - list_for_each_entry(gr, head, lkb_statequeue) { - if (gr->lkb_bastaddr && - gr->lkb_highbast < lkb->lkb_rqmode && - ranges_overlap(lkb, gr) && !modes_compat(gr, lkb)) { - queue_ast(gr, AST_BAST, lkb->lkb_rqmode); - gr->lkb_highbast = lkb->lkb_rqmode; - } - } -} - -/* - * Notify granted locks if they are blocking a newly forced-to-wait lock. - */ - -static void send_blocking_asts(struct dlm_rsb *rsb, struct dlm_lkb *lkb) -{ - send_bast_queue(&rsb->res_grantqueue, lkb); - /* check if the following improves performance */ - /* send_bast_queue(&rsb->res_convertqueue, lkb); */ -} - -static void send_blocking_asts_all(struct dlm_rsb *rsb, struct dlm_lkb *lkb) -{ - send_bast_queue(&rsb->res_grantqueue, lkb); - send_bast_queue(&rsb->res_convertqueue, lkb); -} - -/* - * When we go through the convert queue trying to grant locks, we may grant or - * demote some lkb's later in the list that would allow lkb's earlier in the - * list to be granted when they weren't before. When this happens we need to - * go through the list again. - */ - -static int grant_pending_convert(struct dlm_rsb *r, int high) -{ - struct dlm_lkb *lkb, *s; - int hi, demoted, quit, grant_restart, demote_restart; - - quit = 0; - restart: - grant_restart = 0; - demote_restart = 0; - hi = DLM_LOCK_IV; - - list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) { - demoted = lkb->lkb_flags & GDLM_LKFLG_DEMOTED; - if (can_be_granted(r, lkb, FALSE)) { - grant_lock(lkb, 1); - grant_restart = 1; - } else { - hi = MAX(lkb->lkb_rqmode, hi); - if (!demoted && lkb->lkb_flags & GDLM_LKFLG_DEMOTED) - demote_restart = 1; - } - } - - if (grant_restart) - goto restart; - if (demote_restart && !quit) { - quit = 1; - goto restart; - } - - return MAX(high, hi); -} - -static int grant_pending_wait(struct dlm_rsb *r, int high) -{ - struct dlm_lkb *lkb, *s; - - list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) { - if (lkb->lkb_lockqueue_state) - continue; - - if (can_be_granted(r, lkb, FALSE)) - grant_lock(lkb, 1); - else - high = MAX(lkb->lkb_rqmode, high); - } - - return high; -} - -/* - * Called when a lock has been dequeued. Look for any locks to grant that are - * waiting for conversion or waiting to be granted. - * The rsb res_lock must be held in write when this function is called. - */ - -int grant_pending_locks(struct dlm_rsb *r) -{ - struct dlm_lkb *lkb, *s; - int high = DLM_LOCK_IV; - - high = grant_pending_convert(r, high); - high = grant_pending_wait(r, high); - - if (high == DLM_LOCK_IV) - return 0; - - /* - * If there are locks left on the wait/convert queue then send blocking - * ASTs to granted locks that are blocking. FIXME: This might generate - * some spurious blocking ASTs for range locks. - */ - - list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) { - if (lkb->lkb_bastaddr && (lkb->lkb_highbast < high) && - !__dlm_compat_matrix[lkb->lkb_grmode+1][high+1]) { - queue_ast(lkb, AST_BAST, high); - lkb->lkb_highbast = high; - } - } - - return 0; -} - -/* - * Called to cancel a locking operation that failed due to some internal - * reason. - * - * Waiting locks will be removed, converting locks will be reverted to their - * granted status, unlocks will be left where they are. - * - * A completion AST will be delivered to the caller. - */ - -int cancel_lockop(struct dlm_lkb *lkb, int status) -{ - int state = lkb->lkb_lockqueue_state; - uint16_t astflags = AST_COMP; - - lkb->lkb_lockqueue_state = 0; - - switch (state) { - case GDLM_LQSTATE_WAIT_RSB: - astflags |= AST_DEL; - break; - - case GDLM_LQSTATE_WAIT_CONDGRANT: - res_lkb_dequeue(lkb); - astflags |= AST_DEL; - break; - - case GDLM_LQSTATE_WAIT_CONVERT: - res_lkb_swqueue(lkb->lkb_resource, lkb, GDLM_LKSTS_GRANTED); - - /* Remove from deadlock detection */ - if (lkb->lkb_duetime) - remove_from_deadlockqueue(lkb); - break; - - case GDLM_LQSTATE_WAIT_UNLOCK: - /* We can leave this. I think.... */ - break; - } - - lkb->lkb_retstatus = status; - queue_ast(lkb, astflags, 0); - - return 0; -} - -/* - * Check for conversion deadlock. If a deadlock was found - * return lkb to kill, else return NULL - */ - -struct dlm_lkb *conversion_deadlock_check(struct dlm_lkb *lkb) -{ - struct dlm_rsb *rsb = lkb->lkb_resource; - struct list_head *entry; - - if (lkb->lkb_status != GDLM_LKSTS_CONVERT) - return NULL; - - /* Work our way up to the head of the queue looking for locks that - * conflict with us */ - - down_read(&rsb->res_lock); - - entry = lkb->lkb_statequeue.prev; - while (entry != &rsb->res_convertqueue) { - struct dlm_lkb *lkb2 = list_entry(entry, struct dlm_lkb, lkb_statequeue); - - if (ranges_overlap(lkb, lkb2) && !modes_compat(lkb2, lkb)) { - up_read(&rsb->res_lock); - return lkb; - } - entry = entry->prev; - } - up_read(&rsb->res_lock); - - return 0; -} - -/* - * Conversion operation was cancelled by us (not the user). - * ret contains the return code to pass onto the user - */ - -void cancel_conversion(struct dlm_lkb *lkb, int ret) -{ - struct dlm_rsb *rsb = lkb->lkb_resource; - - /* Stick it back on the granted queue */ - res_lkb_swqueue(rsb, lkb, GDLM_LKSTS_GRANTED); - lkb->lkb_rqmode = lkb->lkb_grmode; - - remove_from_deadlockqueue(lkb); - - lkb->lkb_retstatus = ret; - queue_ast(lkb, AST_COMP, 0); - wake_astd(); -} - -/* - * As new master of the rsb for this lkb, we need to handle these requests - * removed from the lockqueue and originating from local processes: - * GDLM_LQSTATE_WAIT_RSB, GDLM_LQSTATE_WAIT_CONDGRANT, - * GDLM_LQSTATE_WAIT_UNLOCK, GDLM_LQSTATE_WAIT_CONVERT. - */ - -void process_remastered_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb, int state) -{ - struct dlm_rsb *rsb; - - switch (state) { - case GDLM_LQSTATE_WAIT_RSB: - dlm_lock_stage1(lkb->lkb_resource->res_ls, lkb, - lkb->lkb_lockqueue_flags, - lkb->lkb_resource->res_name, - lkb->lkb_resource->res_length); - break; - - case GDLM_LQSTATE_WAIT_CONDGRANT: - res_lkb_dequeue(lkb); - dlm_lock_stage3(lkb); - break; - - case GDLM_LQSTATE_WAIT_UNLOCK: - rsb = find_rsb_to_unlock(ls, lkb); - dlm_unlock_stage2(lkb, rsb, lkb->lkb_lockqueue_flags); - break; - - case GDLM_LQSTATE_WAIT_CONVERT: - /* The lkb is on the local convert queue while waiting for - the remote conversion. dlm_convert_stage2() assumes - the lkb is still on the grant queue. */ - res_lkb_swqueue(lkb->lkb_resource, lkb, GDLM_LKSTS_GRANTED); - dlm_convert_stage2(lkb, TRUE); - break; - - default: - DLM_ASSERT(0,); - } -} - -static void dump_queue(struct list_head *head, char *qname) -{ - struct dlm_lkb *lkb; - - list_for_each_entry(lkb, head, lkb_statequeue) { - printk("%s %08x gr %d rq %d flg %x sts %u node %u remid %x " - "lq %d,%x\n", - qname, - lkb->lkb_id, - lkb->lkb_grmode, - lkb->lkb_rqmode, - lkb->lkb_flags, - lkb->lkb_status, - lkb->lkb_nodeid, - lkb->lkb_remid, - lkb->lkb_lockqueue_state, - lkb->lkb_lockqueue_flags); - } -} - -static void dump_rsb(struct dlm_rsb *rsb) -{ - printk("name "%s" flags %lx nodeid %d ref %u\n", - rsb->res_name, rsb->res_flags, rsb->res_nodeid, - atomic_read(&rsb->res_ref)); - - if (!list_empty(&rsb->res_grantqueue)) - dump_queue(&rsb->res_grantqueue, "G"); - - if (!list_empty(&rsb->res_convertqueue)) - dump_queue(&rsb->res_convertqueue, "C"); - - if (!list_empty(&rsb->res_waitqueue)) - dump_queue(&rsb->res_waitqueue, "W"); -} - -/* This is only called from DLM_ASSERT */ -void dlm_locks_dump(void) -{ - struct dlm_ls *ls; - struct dlm_rsb *rsb; - struct list_head *head; - int i; - - lowcomms_stop_accept(); - - list_for_each_entry(ls, &lslist, ls_list) { - for (i = 0; i < ls->ls_rsbtbl_size; i++) { - head = &ls->ls_rsbtbl[i].list; - list_for_each_entry(rsb, head, res_hashchain) - dump_rsb(rsb); - } - } -} - diff --git a/dlm-kernel/src/locking.h b/dlm-kernel/src/locking.h deleted file mode 100644 index 7f49447..0000000 --- a/dlm-kernel/src/locking.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOCKING_DOT_H__ -#define __LOCKING_DOT_H__ - -int dlm_modes_compat(int mode1, int mode2); -void process_remastered_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb, int state); -void dlm_lock_stage3(struct dlm_lkb *lkb); -int dlm_convert_stage2(struct dlm_lkb *lkb, int do_ast); -int dlm_unlock_stage2(struct dlm_lkb *lkb, struct dlm_rsb *rsb, uint32_t flags); -int dlm_lock_stage2(struct dlm_ls *lspace, struct dlm_lkb *lkb, struct dlm_rsb *rsb, uint32_t flags); -struct dlm_rsb *create_rsb(struct dlm_ls *lspace, struct dlm_lkb *lkb, char *name, int namelen); -int free_rsb_if_unused(struct dlm_rsb *rsb); -struct dlm_lkb *remote_stage2(int remote_csid, struct dlm_ls *lspace, - struct dlm_request *freq); -int cancel_lockop(struct dlm_lkb *lkb, int status); -int dlm_remove_lock(struct dlm_lkb *lkb, uint32_t flags); -int grant_pending_locks(struct dlm_rsb *rsb); -void cancel_conversion(struct dlm_lkb *lkb, int ret); -struct dlm_lkb *conversion_deadlock_check(struct dlm_lkb *lkb); - -#endif /* __LOCKING_DOT_H__ */ diff --git a/dlm-kernel/src/lockqueue.c b/dlm-kernel/src/lockqueue.c deleted file mode 100644 index 9e3db73..0000000 --- a/dlm-kernel/src/lockqueue.c +++ /dev/null @@ -1,1342 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * lockqueue.c - * - * This controls the lock queue, which is where locks - * come when they need to wait for a remote operation - * to complete. - * - * This could also be thought of as the "high-level" comms - * layer. - * - */ - -#include "dlm_internal.h" -#include "lockqueue.h" -#include "dir.h" -#include "locking.h" -#include "lkb.h" -#include "lowcomms.h" -#include "midcomms.h" -#include "reccomms.h" -#include "nodes.h" -#include "lockspace.h" -#include "ast.h" -#include "memory.h" -#include "rsb.h" -#include "queries.h" -#include "util.h" - -static void add_reply_lvb(struct dlm_lkb * lkb, struct dlm_reply *reply); -static void add_request_lvb(struct dlm_lkb * lkb, struct dlm_request *req); - -/* - * format of an entry on the request queue - */ -struct rq_entry { - struct list_head rqe_list; - uint32_t rqe_nodeid; - char rqe_request[1]; -}; - -/* - * Add a new request (if appropriate) to the request queue and send the remote - * request out. - runs in the context of the locking caller - * - * Recovery of a remote_stage request if the remote end fails while the lkb - * is still on the lockqueue: - * - * o lkbs on the lockqueue are flagged with GDLM_LKFLG_LQRESEND in - * lockqueue_lkb_mark() at the start of recovery. - * - * o Some lkb's will be rebuilt on new master rsb's during recovery. - * (depends on the type of request, see below). - * - * o At the end of recovery, resend_cluster_requests() looks at these - * LQRESEND lkb's and either: - * - * i) resends the request to the new master for the rsb where the - * request is processed as usual. The lkb remains on the lockqueue until - * the new master replies and we run process_lockqueue_reply(). - * - * ii) if we've become the rsb master, remove the lkb from the lockqueue - * and processes the request locally via process_remastered_lkb(). - * - * GDLM_LQSTATE_WAIT_RSB (1) - these lockqueue lkb's are not on any rsb queue - * and the request should be resent if dest node is failed. - * - * GDLM_LQSTATE_WAIT_CONDGRANT (3) - this lockqueue lkb is on a local rsb's - * wait queue. Don't rebuild this lkb on a new master rsb (the NOREBUILD flag - * makes send_lkb_queue() skip it). Resend this request to the new master. - * - * GDLM_LQSTATE_WAIT_UNLOCK (4) - this lkb is on a local rsb's queue. It will - * be rebuilt on the rsb on the new master (restbl_lkb_send/send_lkb_queue). - * Resend this request to the new master. - * - * GDLM_LQSTATE_WAIT_CONVERT (2) - this lkb is on a local rsb convert queue. - * It will be rebuilt on the new master rsb's granted queue. Resend this - * request to the new master. - */ - -int remote_stage(struct dlm_lkb *lkb, int state) -{ - int error; - - lkb->lkb_lockqueue_state = state; - add_to_lockqueue(lkb); - - error = send_cluster_request(lkb, state); - if (error < 0) { - log_error(lkb->lkb_resource->res_ls, "remote_stage error %d %x", - error, lkb->lkb_id); - /* Leave on lockqueue, it will be resent to correct node during - * recovery. */ - } - return 0; -} - -/* - * Requests received while the lockspace is in recovery get added to the - * request queue and processed when recovery is complete. - */ - -int add_to_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) -{ - struct rq_entry *entry; - int length = hd->rh_length; - int rv; - - if (test_bit(LSFL_REQUEST_WARN, &ls->ls_flags)) - log_error(ls, "request during recovery from %u", nodeid); - - if (in_nodes_gone(ls, nodeid)) - return 0; - - entry = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); - if (!entry) { - // TODO something better - printk("dlm: add_to_requestqueue: out of memory\n"); - return 0; - } - - log_debug(ls, "add_to_requestq cmd %d fr %d", hd->rh_cmd, nodeid); - entry->rqe_nodeid = nodeid; - memcpy(entry->rqe_request, hd, length); - - down(&ls->ls_requestqueue_lock); - - /* We need to check LS_RUN after taking the mutex to - avoid a race where dlm_recoverd enables locking and runs - process_requestqueue between our earlier LS_RUN check - and this addition to the requestqueue. (From RHEL5 code). */ - - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) { - list_add_tail(&entry->rqe_list, &ls->ls_requestqueue); - rv = 0; - } else { - log_debug(ls, "add_to_requestq skip fr %d", nodeid); - kfree(entry); - rv = -EAGAIN; - } - up(&ls->ls_requestqueue_lock); - return rv; -} - -int process_requestqueue(struct dlm_ls *ls) -{ - int error = 0, count = 0; - struct rq_entry *entry; - struct dlm_header *hd; - - log_debug(ls, "process held requests"); - - down(&ls->ls_requestqueue_lock); - - for (;;) { - if (list_empty(&ls->ls_requestqueue)) { - up(&ls->ls_requestqueue_lock); - error = 0; - break; - } - - entry = list_entry(ls->ls_requestqueue.next, struct rq_entry, - rqe_list); - up(&ls->ls_requestqueue_lock); - hd = (struct dlm_header *) entry->rqe_request; - - log_debug(ls, "process_requestq cmd %d fr %u", hd->rh_cmd, - entry->rqe_nodeid); - - error = process_cluster_request(entry->rqe_nodeid, hd, TRUE); - if (error == -EINTR) { - /* entry is left on requestqueue */ - log_debug(ls, "process_requestqueue abort eintr"); - break; - } - - down(&ls->ls_requestqueue_lock); - list_del(&entry->rqe_list); - kfree(entry); - count++; - - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) { - log_debug(ls, "process_requestqueue abort ls_run"); - up(&ls->ls_requestqueue_lock); - error = -EINTR; - break; - } - schedule(); - } - - log_debug(ls, "processed %d requests", count); - return error; -} - -void wait_requestqueue(struct dlm_ls *ls) -{ - for (;;) { - down(&ls->ls_requestqueue_lock); - if (list_empty(&ls->ls_requestqueue)) - break; - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) - break; - up(&ls->ls_requestqueue_lock); - schedule(); - } - up(&ls->ls_requestqueue_lock); -} - -/* - * Resdir requests (lookup or remove) and replies from before recovery are - * invalid since the resdir was rebuilt. Clear them. Requests from nodes now - * gone are also invalid. - */ - -void purge_requestqueue(struct dlm_ls *ls) -{ - int count = 0; - struct rq_entry *entry, *safe; - struct dlm_header *hd; - struct dlm_lkb *lkb; - - log_debug(ls, "purge requests"); - - down(&ls->ls_requestqueue_lock); - - list_for_each_entry_safe(entry, safe, &ls->ls_requestqueue, rqe_list) { - hd = (struct dlm_header *) entry->rqe_request; - - if (hd->rh_cmd == GDLM_REMCMD_REM_RESDATA || - hd->rh_cmd == GDLM_REMCMD_LOOKUP || - in_nodes_gone(ls, entry->rqe_nodeid)) { - - list_del(&entry->rqe_list); - kfree(entry); - count++; - - } else if (hd->rh_cmd == GDLM_REMCMD_LOCKREPLY) { - - /* - * Replies to resdir lookups are invalid and must be - * purged. The lookup requests are marked in - * lockqueue_lkb_mark and will be resent in - * resend_cluster_requests. The only way to check if - * this is a lookup reply is to look at the - * lockqueue_state of the lkb. - */ - - lkb = find_lock_by_id(ls, hd->rh_lkid); - if (!lkb) { - log_error(ls, "purge %x from %d no lkb", - hd->rh_lkid, entry->rqe_nodeid); - list_del(&entry->rqe_list); - kfree(entry); - count++; - } else if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_RSB) { - list_del(&entry->rqe_list); - kfree(entry); - count++; - } - } - - schedule(); - } - up(&ls->ls_requestqueue_lock); - - log_debug(ls, "purged %d requests", count); -} - -/* - * Check if there's a reply for the given lkid in the requestqueue. - */ - -int reply_in_requestqueue(struct dlm_ls *ls, int lkid) -{ - int rv = FALSE; - struct rq_entry *entry; - struct dlm_header *hd; - - down(&ls->ls_requestqueue_lock); - - list_for_each_entry(entry, &ls->ls_requestqueue, rqe_list) { - hd = (struct dlm_header *) entry->rqe_request; - if (hd->rh_cmd == GDLM_REMCMD_LOCKREPLY && hd->rh_lkid == lkid){ - log_debug(ls, "reply_in_requestq cmd %d fr %d id %x", - hd->rh_cmd, entry->rqe_nodeid, lkid); - rv = TRUE; - break; - } - } - up(&ls->ls_requestqueue_lock); - - return rv; -} - -void allocate_and_copy_lvb(struct dlm_ls *ls, char **lvbptr, char *src) -{ - if (!*lvbptr) - *lvbptr = allocate_lvb(ls); - if (*lvbptr) - memcpy(*lvbptr, src, DLM_LVB_LEN); -} - -/* - * Process a lockqueue LKB after it has had it's remote processing complete and - * been pulled from the lockqueue. Runs in the context of the DLM recvd thread - * on the machine that requested the lock. - */ - -static void process_lockqueue_reply(struct dlm_lkb *lkb, - struct dlm_reply *reply, - uint32_t nodeid) -{ - struct dlm_rsb *rsb = lkb->lkb_resource; - struct dlm_ls *ls = rsb->res_ls; - int oldstate, state = lkb->lkb_lockqueue_state; - - /* hack to work around bug - https://bugzilla.redhat.com/show_bug.cgi?id=495600 */ - - if (state == GDLM_LQSTATE_WAIT_UNLOCK && reply->rl_status == 0) { - log_error(ls, "ignore zero unlock reply from %d %x %s", - nodeid, lkb->lkb_id, lkb->lkb_resource->res_name); - return; - } - - if (state) { - remove_from_lockqueue(lkb); - lkb->lkb_prev_lq_state = state; - } - - switch (state) { - case GDLM_LQSTATE_WAIT_RSB: - - if (reply->rl_status) { - DLM_ASSERT(reply->rl_status == -EEXIST,); - if (rsb->res_nodeid == -1) { - msleep(500); - remote_stage(lkb, GDLM_LQSTATE_WAIT_RSB); - break; - } - } else { - if (reply->rl_nodeid == our_nodeid()) { - set_bit(RESFL_MASTER, &rsb->res_flags); - rsb->res_nodeid = 0; - } else { - clear_bit(RESFL_MASTER, &rsb->res_flags); - rsb->res_nodeid = reply->rl_nodeid; - } - } - - log_debug1(ls, "(%d) lu rep %x fr %u %u", lkb->lkb_ownpid, - lkb->lkb_id, nodeid, - rsb->res_nodeid); - - lkb->lkb_nodeid = rsb->res_nodeid; - dlm_lock_stage2(ls, lkb, rsb, lkb->lkb_lockqueue_flags); - break; - - case GDLM_LQSTATE_WAIT_CONVERT: - case GDLM_LQSTATE_WAIT_CONDGRANT: - - /* - * the destination wasn't the master - * this implies the request was a CONDGRANT - */ - - if (reply->rl_status == -EINVAL) { - int master_nodeid; - - DLM_ASSERT(state == GDLM_LQSTATE_WAIT_CONDGRANT, ); - - log_debug(ls, "(%d) req reply einval %x fr %d r %d %s", - lkb->lkb_ownpid, lkb->lkb_id, nodeid, - rsb->res_nodeid, rsb->res_name); - - res_lkb_dequeue(lkb); - - if (rsb->res_nodeid == lkb->lkb_nodeid || rsb->res_nodeid == -1){ - /* - * We need to re-lookup the master and resend our - * request to it. - */ - - lkb->lkb_nodeid = -1; - rsb->res_nodeid = -1; - - if (get_directory_nodeid(rsb) != our_nodeid()) - remote_stage(lkb, GDLM_LQSTATE_WAIT_RSB); - else { - int error = dlm_dir_lookup(ls, our_nodeid(), - rsb->res_name, - rsb->res_length, - &master_nodeid); - if (error == -EEXIST) { - /* don't expect this will happen */ - log_error(ls, "EEXIST %x", lkb->lkb_id); - print_lkb(lkb); - print_rsb(rsb); - } - - if (master_nodeid == our_nodeid()) { - set_bit(RESFL_MASTER, &rsb->res_flags); - master_nodeid = 0; - } else - clear_bit(RESFL_MASTER,&rsb->res_flags); - - rsb->res_nodeid = master_nodeid; - lkb->lkb_nodeid = master_nodeid; - - dlm_lock_stage2(ls, lkb, rsb, - lkb->lkb_lockqueue_flags); - } - } else { - /* - * Another request on this rsb has since found - * the master, we'll use that one although it too - * may be invalid requiring us to retry again. - */ - - lkb->lkb_nodeid = rsb->res_nodeid; - dlm_lock_stage2(ls, lkb, rsb, - lkb->lkb_lockqueue_flags); - } - - break; - } - - - /* - * After a remote lock/conversion/grant request we put the lock - * on the right queue and send an AST if appropriate. Any lock - * shuffling (eg newly granted locks because this one was - * converted downwards) will be dealt with in seperate messages - * (which may be in the same network message) - */ - - if (!lkb->lkb_remid) - lkb->lkb_remid = reply->rl_lkid; - - /* - * The remote request failed (we assume because of NOQUEUE). - * If this is a new request (non-conv) the lkb was created just - * for it so the lkb should be freed. If this was a - * conversion, the lkb already existed so we should put it back - * on the grant queue. - */ - - if (reply->rl_status != 0) { - DLM_ASSERT(reply->rl_status == -EAGAIN,); - - if (state == GDLM_LQSTATE_WAIT_CONDGRANT) { - res_lkb_dequeue(lkb); - lkb->lkb_retstatus = reply->rl_status; - queue_ast(lkb, AST_COMP | AST_DEL, 0); - } else { - res_lkb_swqueue(rsb, lkb, GDLM_LKSTS_GRANTED); - lkb->lkb_retstatus = reply->rl_status; - queue_ast(lkb, AST_COMP, 0); - } - break; - } - - /* - * The remote request was successful in granting the request or - * queuing it to be granted later. Add the lkb to the - * appropriate rsb queue. - */ - - switch (reply->rl_lockstate) { - case GDLM_LKSTS_GRANTED: - - /* Compact version of grant_lock(). */ - - down_write(&rsb->res_lock); - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK && - reply->rl_flags & GDLM_LKFLG_RETURNLVB) { - lkb->lkb_flags |= GDLM_LKFLG_RETURNLVB; - memcpy(lkb->lkb_lvbptr, reply->rl_lvb, - DLM_LVB_LEN); - lkb->lkb_lvbseq = reply->rl_lvbseq; - } - - if (reply->rl_flags & GDLM_LKFLG_ALTMODE) { - lkb->lkb_flags |= GDLM_LKFLG_ALTMODE; - if (lkb->lkb_rqmode == DLM_LOCK_PR) - lkb->lkb_grmode = DLM_LOCK_CW; - else if (lkb->lkb_rqmode == DLM_LOCK_CW) - lkb->lkb_grmode = DLM_LOCK_PR; - } else - lkb->lkb_grmode = lkb->lkb_rqmode; - - lkb->lkb_rqmode = DLM_LOCK_IV; - lkb_swqueue(rsb, lkb, GDLM_LKSTS_GRANTED); - - if (lkb->lkb_range) { - lkb->lkb_range[GR_RANGE_START] = - lkb->lkb_range[RQ_RANGE_START]; - lkb->lkb_range[GR_RANGE_END] = - lkb->lkb_range[RQ_RANGE_END]; - } - - if (reply->rl_flags & GDLM_LKFLG_DEMOTED) - lkb->lkb_flags |= GDLM_LKFLG_DEMOTED; - if (reply->rl_flags & GDLM_LKFLG_VALNOTVALID) - lkb->lkb_flags |= GDLM_LKFLG_VALNOTVALID; - - up_write(&rsb->res_lock); - - lkb->lkb_retstatus = 0; - queue_ast(lkb, AST_COMP, 0); - break; - - case GDLM_LKSTS_WAITING: - - if (lkb->lkb_status != GDLM_LKSTS_GRANTED) - res_lkb_swqueue(rsb, lkb, GDLM_LKSTS_WAITING); - else - log_error(ls, "wait reply for granted %x %u", - lkb->lkb_id, lkb->lkb_nodeid); - break; - - case GDLM_LKSTS_CONVERT: - - if (lkb->lkb_status != GDLM_LKSTS_GRANTED) - res_lkb_swqueue(rsb, lkb, GDLM_LKSTS_CONVERT); - else - log_error(ls, "convert reply for granted %x %u", - lkb->lkb_id, lkb->lkb_nodeid); - break; - - default: - log_error(ls, "process_lockqueue_reply state %d", - reply->rl_lockstate); - } - - break; - - case GDLM_LQSTATE_WAIT_UNLOCK: - - /* - * Unlocks should never fail, but cancels can. Update local - * lock info. This always sends completion AST with status in - * lksb - */ - - oldstate = res_lkb_dequeue(lkb); - lkb->lkb_retstatus = reply->rl_status; - - if (reply->rl_status == -DLM_ECANCEL) { - DLM_ASSERT(lkb->lkb_lockqueue_flags & DLM_LKF_CANCEL,); - if (oldstate == GDLM_LKSTS_CONVERT) { - res_lkb_enqueue(lkb->lkb_resource, lkb, - GDLM_LKSTS_GRANTED); - lkb->lkb_rqmode = DLM_LOCK_IV; - queue_ast(lkb, AST_COMP, 0); - } else if (oldstate == GDLM_LKSTS_WAITING) { - lkb->lkb_rqmode = DLM_LOCK_IV; - queue_ast(lkb, AST_COMP | AST_DEL, 0); - } else - log_error(ls, "cancel reply %d", oldstate); - - } else if (reply->rl_status == -DLM_EUNLOCK) { - DLM_ASSERT(oldstate == GDLM_LKSTS_GRANTED, - print_lkb(lkb);); - queue_ast(lkb, AST_COMP | AST_DEL, 0); - } else { - /* should not get here due to hack at top */ - log_error(ls, "cancel reply ret %d %x", - reply->rl_status, lkb->lkb_id); - queue_ast(lkb, AST_COMP, 0); - } - break; - - default: - log_error(ls, "process_lockqueue_reply id %x state %d %d %d %d", - lkb->lkb_id, state, lkb->lkb_prev_lq_state, - reply->rl_status, lkb->lkb_retstatus); - } -} - -/* - * Tell a remote node to grant a lock. This happens when we are the master - * copy for a lock that is actually held on a remote node. The remote end is - * also responsible for sending the completion AST. - */ - -void remote_grant(struct dlm_lkb *lkb) -{ - struct writequeue_entry *e; - struct dlm_request *req; - - // TODO Error handling - e = lowcomms_get_buffer(lkb->lkb_nodeid, - sizeof(struct dlm_request), - lkb->lkb_resource->res_ls->ls_allocation, - (char **) &req); - if (!e) - return; - - req->rr_header.rh_cmd = GDLM_REMCMD_LOCKGRANT; - req->rr_header.rh_length = sizeof(struct dlm_request); - req->rr_header.rh_flags = 0; - req->rr_header.rh_lkid = lkb->lkb_id; - req->rr_header.rh_lockspace = lkb->lkb_resource->res_ls->ls_global_id; - req->rr_remlkid = lkb->lkb_remid; - - /* This is a confusing non-standard use of rr_flags which is - usually used to pass lockqueue_flags. Here it's necessary to get - DEMOTED, VALNOTVALID & RETURNLVB flags back to the other node.*/ - - req->rr_flags = lkb->lkb_flags; - req->rr_lvbseq = lkb->lkb_lvbseq; - add_request_lvb(lkb, req); - - /* prevent a convert reply that hasn't been sent yet, the grant message - will serve as an implicit convert reply */ - if (lkb->lkb_request) { - log_debug(lkb->lkb_resource->res_ls, "skip convert reply %x " - "gr %d\n", lkb->lkb_id, lkb->lkb_grmode); - lkb->lkb_request = NULL; - } - - midcomms_send_buffer(&req->rr_header, e); -} - -void reply_and_grant(struct dlm_lkb *lkb) -{ - struct dlm_request *req = lkb->lkb_request; - struct dlm_reply *reply; - struct writequeue_entry *e; - - // TODO Error handling - e = lowcomms_get_buffer(lkb->lkb_nodeid, - sizeof(struct dlm_reply), - lkb->lkb_resource->res_ls->ls_allocation, - (char **) &reply); - if (!e) - return; - - reply->rl_header.rh_cmd = GDLM_REMCMD_LOCKREPLY; - reply->rl_header.rh_flags = 0; - reply->rl_header.rh_length = sizeof(struct dlm_reply); - reply->rl_header.rh_lkid = req->rr_header.rh_lkid; - reply->rl_header.rh_lockspace = req->rr_header.rh_lockspace; - - reply->rl_status = lkb->lkb_retstatus; - reply->rl_lockstate = lkb->lkb_status; - reply->rl_lkid = lkb->lkb_id; - reply->rl_flags = lkb->lkb_flags; - reply->rl_lvbseq = lkb->lkb_lvbseq; - add_reply_lvb(lkb, reply); - - DLM_ASSERT(!(lkb->lkb_flags & GDLM_LKFLG_DEMOTED),); - - lkb->lkb_request = NULL; - - midcomms_send_buffer(&reply->rl_header, e); -} - -/* - * Request removal of a dead entry in the resource directory - */ - -void remote_remove_direntry(struct dlm_ls *ls, int nodeid, char *name, - int namelen) -{ - struct writequeue_entry *e; - struct dlm_request *req; - - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) { - struct dlm_rcom *rc = allocate_rcom_buffer(ls); - - memcpy(rc->rc_buf, name, namelen); - rc->rc_datalen = namelen; - - rcom_send_message(ls, nodeid, RECCOMM_REMRESDATA, rc, 0); - - free_rcom_buffer(rc); - return; - } - // TODO Error handling - e = lowcomms_get_buffer(nodeid, - sizeof(struct dlm_request) + namelen - 1, - ls->ls_allocation, (char **) &req); - if (!e) - return; - - memset(req, 0, sizeof(struct dlm_request) + namelen - 1); - req->rr_header.rh_cmd = GDLM_REMCMD_REM_RESDATA; - req->rr_header.rh_length = - sizeof(struct dlm_request) + namelen - 1; - req->rr_header.rh_flags = 0; - req->rr_header.rh_lkid = 0; - req->rr_header.rh_lockspace = ls->ls_global_id; - req->rr_remlkid = 0; - memcpy(req->rr_name, name, namelen); - - midcomms_send_buffer(&req->rr_header, e); -} - -static int send_purge(struct dlm_ls *ls, int to_nodeid, int pid) -{ - struct writequeue_entry *e; - struct dlm_request *req; - - printk("dlm: send_purge to nodeid %d pid %d\n", to_nodeid, pid); - - e = lowcomms_get_buffer(to_nodeid, - sizeof(struct dlm_request), - ls->ls_allocation, - (char **) &req); - if (!e) { - printk("send_purge get_buffer error\n"); - return -1; - } - memset(req, 0, sizeof(struct dlm_request)); - - req->rr_header.rh_cmd = GDLM_REMCMD_PURGE; - req->rr_header.rh_length = sizeof(struct dlm_request); - req->rr_header.rh_lockspace = ls->ls_global_id; - req->rr_pid = pid; - midcomms_send_buffer(&req->rr_header, e); - return 0; -} - -void send_purge_all(struct dlm_ls *ls, int ournodeid, int pid) -{ - struct dlm_csb *csb; - - list_for_each_entry(csb, &ls->ls_nodes, list) { - if (csb->node->nodeid != ournodeid) - send_purge(ls, csb->node->nodeid, pid); - } -} - -/* - * Send remote cluster request to directory or master node before the request - * is put on the lock queue. Runs in the context of the locking caller. - */ - -int send_cluster_request(struct dlm_lkb *lkb, int state) -{ - uint32_t target_nodeid; - struct dlm_rsb *rsb = lkb->lkb_resource; - struct dlm_ls *ls = rsb->res_ls; - struct dlm_request *req; - struct writequeue_entry *e; - - if (state == GDLM_LQSTATE_WAIT_RSB) - target_nodeid = get_directory_nodeid(rsb); - else - target_nodeid = lkb->lkb_nodeid; - - /* during recovery it's valid for target_nodeid to equal our own; - resend_cluster_requests does this to get requests back on track */ - - DLM_ASSERT(target_nodeid && target_nodeid != -1, - print_lkb(lkb); - print_rsb(rsb); - printk("target_nodeid %u\n", target_nodeid);); - - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) { - /* this may happen when called by resend_cluster_request */ - log_error(ls, "send_cluster_request to %u state %d recovery", - target_nodeid, state); - } - - e = lowcomms_get_buffer(target_nodeid, - sizeof(struct dlm_request) + - rsb->res_length - 1, ls->ls_allocation, - (char **) &req); - if (!e) - return -ENOBUFS; - memset(req, 0, sizeof(struct dlm_request) + rsb->res_length - 1); - - /* Common stuff, some are just defaults */ - - if (lkb->lkb_bastaddr) - req->rr_asts = AST_BAST; - if (lkb->lkb_astaddr) - req->rr_asts |= AST_COMP; - if (lkb->lkb_parent) - req->rr_remparid = lkb->lkb_parent->lkb_remid; - - req->rr_flags = lkb->lkb_lockqueue_flags; - req->rr_rqmode = lkb->lkb_rqmode; - req->rr_remlkid = lkb->lkb_remid; - req->rr_pid = lkb->lkb_ownpid; - req->rr_header.rh_length = - sizeof(struct dlm_request) + rsb->res_length - 1; - req->rr_header.rh_flags = 0; - req->rr_header.rh_lkid = lkb->lkb_id; - req->rr_header.rh_lockspace = ls->ls_global_id; - - switch (state) { - - case GDLM_LQSTATE_WAIT_RSB: - - DLM_ASSERT(!lkb->lkb_parent, - print_lkb(lkb); - print_rsb(rsb);); - - log_debug1(ls, "(%d) send lu %x to %u", - lkb->lkb_ownpid, lkb->lkb_id, target_nodeid); - - req->rr_header.rh_cmd = GDLM_REMCMD_LOOKUP; - memcpy(req->rr_name, rsb->res_name, rsb->res_length); - break; - - case GDLM_LQSTATE_WAIT_CONVERT: - - DLM_ASSERT(lkb->lkb_nodeid == rsb->res_nodeid, - print_lkb(lkb); - print_rsb(rsb);); - - log_debug1(ls, "(%d) send cv %x to %u", - lkb->lkb_ownpid, lkb->lkb_id, target_nodeid); - - req->rr_header.rh_cmd = GDLM_REMCMD_CONVREQUEST; - if (lkb->lkb_range) { - req->rr_flags |= GDLM_LKFLG_RANGE; - req->rr_range_start = lkb->lkb_range[RQ_RANGE_START]; - req->rr_range_end = lkb->lkb_range[RQ_RANGE_END]; - } - break; - - case GDLM_LQSTATE_WAIT_CONDGRANT: - - log_debug1(ls, "(%d) send rq %x to %u", - lkb->lkb_ownpid, lkb->lkb_id, target_nodeid); - - req->rr_header.rh_cmd = GDLM_REMCMD_LOCKREQUEST; - memcpy(req->rr_name, rsb->res_name, rsb->res_length); - if (lkb->lkb_range) { - req->rr_flags |= GDLM_LKFLG_RANGE; - req->rr_range_start = lkb->lkb_range[RQ_RANGE_START]; - req->rr_range_end = lkb->lkb_range[RQ_RANGE_END]; - } - break; - - case GDLM_LQSTATE_WAIT_UNLOCK: - - log_debug1(ls, "(%d) send un %x to %u", - lkb->lkb_ownpid, lkb->lkb_id, target_nodeid); - - req->rr_header.rh_cmd = GDLM_REMCMD_UNLOCKREQUEST; - break; - - default: - DLM_ASSERT(0, printk("Unknown cluster request\n");); - } - - add_request_lvb(lkb, req); - midcomms_send_buffer(&req->rr_header, e); - - return 0; -} - -/* - * We got a request from another cluster node, process it and return an info - * structure with the lock state/LVB etc as required. Executes in the DLM's - * recvd thread. - */ - -int process_cluster_request(int nodeid, struct dlm_header *req, int recovery) -{ - struct dlm_ls *lspace; - struct dlm_lkb *lkb = NULL; - struct dlm_rsb *rsb; - int send_reply = 0, status = 0, namelen; - struct dlm_request *freq = (struct dlm_request *) req; - struct dlm_reply *rp = (struct dlm_reply *) req; - struct dlm_reply reply; - int error; - - lspace = find_lockspace_by_global_id(req->rh_lockspace); - - if (!lspace) { - log_print("process_cluster_request invalid lockspace %x " - "from %d req %u", req->rh_lockspace, nodeid, - req->rh_cmd); - return -EINVAL; - } - - /* wait for recoverd to drain requestqueue */ - if (!recovery) - wait_requestqueue(lspace); - - /* - * If we're in recovery then queue the request for later. Otherwise, - * we still need to get the "in_recovery" lock to make sure the - * recovery itself doesn't start until we are done. - */ - retry: - if (!test_bit(LSFL_LS_RUN, &lspace->ls_flags)) { - if (!recovery) { - error = add_to_requestqueue(lspace, nodeid, req); - if (error == -EAGAIN) - goto retry; - } - status = -EINTR; - goto out; - } - if (!down_read_trylock(&lspace->ls_in_recovery)) { - schedule(); - goto retry; - } - - - /* - * Process the request. - */ - - switch (req->rh_cmd) { - - case GDLM_REMCMD_LOOKUP: - { - uint32_t dir_nodeid, r_nodeid; - int status; - - namelen = freq->rr_header.rh_length - sizeof(*freq) + 1; - - dir_nodeid = name_to_directory_nodeid(lspace, - freq->rr_name, - namelen); - if (dir_nodeid != our_nodeid()) - log_debug(lspace, "ignoring directory lookup"); - - status = dlm_dir_lookup(lspace, nodeid, freq->rr_name, - namelen, &r_nodeid); - reply.rl_status = status; - reply.rl_lockstate = 0; - reply.rl_nodeid = r_nodeid; - } - send_reply = 1; - break; - - case GDLM_REMCMD_PURGE: - dlm_purge(lspace, our_nodeid(), freq->rr_pid, nodeid); - break; - - case GDLM_REMCMD_REM_RESDATA: - - namelen = freq->rr_header.rh_length - sizeof(*freq) + 1; - dlm_dir_remove(lspace, nodeid, freq->rr_name, namelen); - break; - - case GDLM_REMCMD_LOCKREQUEST: - - lkb = remote_stage2(nodeid, lspace, freq); - if (lkb) { - lkb->lkb_request = freq; - lkb->lkb_ownpid = freq->rr_pid; - if (lkb->lkb_retstatus != -EINVAL) - dlm_lock_stage3(lkb); - - /* - * If the request was granted in lock_stage3, then a - * reply message was already sent in combination with - * the grant message and lkb_request is NULL. - */ - - if (lkb->lkb_request) { - lkb->lkb_request = NULL; - send_reply = 1; - reply.rl_status = lkb->lkb_retstatus; - reply.rl_lockstate = lkb->lkb_status; - reply.rl_lkid = lkb->lkb_id; - - /* - * If the request could not be granted and the - * user won't wait, then free up the LKB - */ - - if (lkb->lkb_retstatus == -EAGAIN) { - rsb = lkb->lkb_resource; - release_lkb(lspace, lkb); - release_rsb(rsb); - lkb = NULL; - } - else if (lkb->lkb_retstatus == -EINVAL) { - release_lkb(lspace, lkb); - lkb = NULL; - } - } - } else { - reply.rl_status = -ENOMEM; - send_reply = 1; - } - break; - - case GDLM_REMCMD_CONVREQUEST: - - lkb = find_lock_by_id(lspace, freq->rr_remlkid); - - if (!lkb) { - log_error(lspace, "convert from %d no lock", nodeid); - print_request(freq); - break; - } - - rsb = lkb->lkb_resource; - - if (!rsb) { - log_error(lspace, "convert from %d no rsb", nodeid); - print_request(freq); - print_lkb(lkb); - break; - } - - if (rsb->res_nodeid) { - log_error(lspace, "convert from %d not master", nodeid); - print_request(freq); - print_lkb(lkb); - print_rsb(rsb); - break; - } - - if (!(lkb->lkb_flags & GDLM_LKFLG_MSTCPY)) { - log_error(lspace, "convert from %d not MSTCPY", nodeid); - print_request(freq); - print_lkb(lkb); - print_rsb(rsb); - break; - } - - if (lkb->lkb_status != GDLM_LKSTS_GRANTED) { - log_error(lspace, "convert from %d ungranted", nodeid); - print_request(freq); - print_lkb(lkb); - print_rsb(rsb); - break; - } - - /* Update orphan lock status */ - if (freq->rr_flags & DLM_LKF_ORPHAN) { - lkb->lkb_flags |= GDLM_LKFLG_ORPHAN; - } - - lkb->lkb_rqmode = freq->rr_rqmode; - lkb->lkb_lockqueue_flags = freq->rr_flags; - lkb->lkb_request = freq; - lkb->lkb_flags &= ~GDLM_LKFLG_DEMOTED; - lkb->lkb_flags &= ~GDLM_LKFLG_VALNOTVALID; - lkb->lkb_flags &= ~GDLM_LKFLG_ALTMODE; - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK || - freq->rr_flags & DLM_LKF_VALBLK) { - lkb->lkb_flags |= GDLM_LKFLG_VALBLK; - allocate_and_copy_lvb(lspace, &lkb->lkb_lvbptr, - freq->rr_lvb); - lkb->lkb_lvbseq = freq->rr_lvbseq; - } - - if (freq->rr_flags & GDLM_LKFLG_RANGE) { - if (lkb_set_range(lspace, lkb, freq->rr_range_start, - freq->rr_range_end)) { - reply.rl_status = -ENOMEM; - send_reply = 1; - goto out; - } - } - - log_debug1(lspace, "(%d) cv %u from %u %x "%s"", - lkb->lkb_ownpid, lkb->lkb_rqmode, nodeid, - lkb->lkb_id, rsb->res_name); - - dlm_convert_stage2(lkb, FALSE); - - /* - * If the conv request was granted in stage2, then a reply - * message was already sent in combination with the grant - * message. - */ - - if (lkb->lkb_request) { - lkb->lkb_request = NULL; - send_reply = 1; - reply.rl_status = lkb->lkb_retstatus; - reply.rl_lockstate = lkb->lkb_status; - reply.rl_lkid = lkb->lkb_id; - } - break; - - case GDLM_REMCMD_LOCKREPLY: - - lkb = find_lock_by_id(lspace, req->rh_lkid); - - if (!lkb) { - log_error(lspace, "reply from %d no lock", nodeid); - print_reply(rp); - break; - } - - if (lkb->lkb_flags & GDLM_LKFLG_MSTCPY) { - log_error(lspace, "reply from %d for MSTCPY", nodeid); - print_reply(rp); - print_lkb(lkb); - print_rsb(lkb->lkb_resource); - break; - } - - process_lockqueue_reply(lkb, rp, nodeid); - break; - - case GDLM_REMCMD_LOCKGRANT: - - /* - * Remote lock has been granted asynchronously. Do a compact - * version of what grant_lock() does. - */ - - lkb = find_lock_by_id(lspace, freq->rr_remlkid); - - if (!lkb) { - log_error(lspace, "grant from %d no lock", nodeid); - print_request(freq); - break; - } - - rsb = lkb->lkb_resource; - - if (!rsb) { - log_error(lspace, "grant from %d no rsb", nodeid); - print_request(freq); - print_lkb(lkb); - break; - } - - if (lkb->lkb_flags & GDLM_LKFLG_MSTCPY) { - log_error(lspace, "grant from %d for MSTCPY", nodeid); - print_request(freq); - print_lkb(lkb); - print_rsb(rsb); - break; - } - - if (!rsb->res_nodeid) { - log_error(lspace, "grant from %d on master", nodeid); - print_request(freq); - print_lkb(lkb); - print_rsb(rsb); - break; - } - - if (lkb->lkb_lockqueue_state) { - log_debug(rsb->res_ls, "grant lock on lockqueue %d", - lkb->lkb_lockqueue_state); - - /* Don't grant locks that are waiting for an unlock */ - if (lkb->lkb_lockqueue_state == GDLM_LQSTATE_WAIT_UNLOCK) - break; - - remove_from_lockqueue(lkb); - if (!lkb->lkb_remid) - lkb->lkb_remid = req->rh_lkid; - } - - down_write(&rsb->res_lock); - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK && - freq->rr_flags & GDLM_LKFLG_RETURNLVB) { - lkb->lkb_flags |= GDLM_LKFLG_RETURNLVB; - allocate_and_copy_lvb(lspace, &lkb->lkb_lvbptr, freq->rr_lvb); - } - - if (freq->rr_flags & GDLM_LKFLG_ALTMODE) { - lkb->lkb_flags |= GDLM_LKFLG_ALTMODE; - if (lkb->lkb_rqmode == DLM_LOCK_PR) - lkb->lkb_grmode = DLM_LOCK_CW; - else if (lkb->lkb_rqmode == DLM_LOCK_CW) - lkb->lkb_grmode = DLM_LOCK_PR; - } else - lkb->lkb_grmode = lkb->lkb_rqmode; - - lkb->lkb_rqmode = DLM_LOCK_IV; - - if (lkb->lkb_range) { - lkb->lkb_range[GR_RANGE_START] = - lkb->lkb_range[RQ_RANGE_START]; - lkb->lkb_range[GR_RANGE_END] = - lkb->lkb_range[RQ_RANGE_END]; - } - - lkb_swqueue(rsb, lkb, GDLM_LKSTS_GRANTED); - up_write(&rsb->res_lock); - - if (freq->rr_flags & GDLM_LKFLG_DEMOTED) - lkb->lkb_flags |= GDLM_LKFLG_DEMOTED; - if (freq->rr_flags & GDLM_LKFLG_VALNOTVALID) - lkb->lkb_flags |= GDLM_LKFLG_VALNOTVALID; - - lkb->lkb_retstatus = 0; - queue_ast(lkb, AST_COMP, 0); - break; - - case GDLM_REMCMD_SENDBAST: - - lkb = find_lock_by_id(lspace, freq->rr_remlkid); - - if (!lkb) { - log_error(lspace, "sendbast from %d no lock", nodeid); - print_request(freq); - break; - } - - /* We don't need to do the bast if the lock is - being converted (and won't fail due to NOQUEUE); - if the new mode (after conversion) still blocks, - the lock will get another bast. */ - - if ((lkb->lkb_status == GDLM_LKSTS_CONVERT) && - !(lkb->lkb_lockqueue_flags & DLM_LKF_NOQUEUE)) - break; - if (lkb->lkb_flags & GDLM_LKFLG_DELETED) - break; - - queue_ast(lkb, AST_BAST, freq->rr_rqmode); - break; - - case GDLM_REMCMD_SENDCAST: - - /* This is only used for some error completion ASTs */ - - lkb = find_lock_by_id(lspace, freq->rr_remlkid); - - if (!lkb) { - log_error(lspace, "sendcast from %d no lock", nodeid); - print_request(freq); - break; - } - - /* Return the lock to granted status */ - res_lkb_swqueue(lkb->lkb_resource, lkb, GDLM_LKSTS_GRANTED); - lkb->lkb_retstatus = freq->rr_status; - queue_ast(lkb, AST_COMP, 0); - break; - - case GDLM_REMCMD_UNLOCKREQUEST: - - lkb = find_lock_by_id(lspace, freq->rr_remlkid); - - if (!lkb && freq->rr_flags & DLM_LKF_CANCEL) { - reply.rl_status = -EINVAL; - send_reply = 1; - break; - } - - if (!lkb) { - log_error(lspace, "unlock from %d no lock", nodeid); - print_request(freq); - break; - } - - if (!(lkb->lkb_flags & GDLM_LKFLG_MSTCPY)) { - log_error(lspace, "unlock from %d not MSTCPY", nodeid); - print_request(freq); - print_lkb(lkb); - if (lkb->lkb_resource); - print_rsb(lkb->lkb_resource); - break; - } - - if (lkb->lkb_nodeid != nodeid) { - log_error(lspace, "unlock from %d not holder", nodeid); - print_request(freq); - print_lkb(lkb); - if (lkb->lkb_resource); - print_rsb(lkb->lkb_resource); - break; - } - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK || - freq->rr_flags & DLM_LKF_VALBLK) { - lkb->lkb_flags |= GDLM_LKFLG_VALBLK; - allocate_and_copy_lvb(lspace, &lkb->lkb_lvbptr, - freq->rr_lvb); - } - - rsb = find_rsb_to_unlock(lspace, lkb); - - log_debug1(lspace, "(%d) un from %u %x "%s"", lkb->lkb_ownpid, - nodeid, lkb->lkb_id, rsb->res_name); - - reply.rl_status = dlm_unlock_stage2(lkb, rsb, freq->rr_flags); - send_reply = 1; - break; - - case GDLM_REMCMD_QUERY: - remote_query(nodeid, lspace, req); - break; - - case GDLM_REMCMD_QUERYREPLY: - remote_query_reply(nodeid, lspace, req); - break; - - default: - log_error(lspace, "process_cluster_request cmd %d",req->rh_cmd); - } - - up_read(&lspace->ls_in_recovery); - - out: - if (send_reply) { - reply.rl_header.rh_cmd = GDLM_REMCMD_LOCKREPLY; - reply.rl_header.rh_flags = 0; - reply.rl_header.rh_length = sizeof(reply); - reply.rl_header.rh_lkid = freq->rr_header.rh_lkid; - reply.rl_header.rh_lockspace = freq->rr_header.rh_lockspace; - - status = midcomms_send_message(nodeid, &reply.rl_header, - GFP_KERNEL); - } - - wake_astd(); - put_lockspace(lspace); - return status; -} - -static void add_reply_lvb(struct dlm_lkb *lkb, struct dlm_reply *reply) -{ - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) - memcpy(reply->rl_lvb, lkb->lkb_lvbptr, DLM_LVB_LEN); -} - -static void add_request_lvb(struct dlm_lkb *lkb, struct dlm_request *req) -{ - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) - memcpy(req->rr_lvb, lkb->lkb_lvbptr, DLM_LVB_LEN); -} diff --git a/dlm-kernel/src/lockqueue.h b/dlm-kernel/src/lockqueue.h deleted file mode 100644 index 91d8502..0000000 --- a/dlm-kernel/src/lockqueue.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOCKQUEUE_DOT_H__ -#define __LOCKQUEUE_DOT_H__ - -void remote_grant(struct dlm_lkb * lkb); -void reply_and_grant(struct dlm_lkb * lkb); -int remote_stage(struct dlm_lkb * lkb, int state); -int process_cluster_request(int csid, struct dlm_header *req, int recovery); -int send_cluster_request(struct dlm_lkb * lkb, int state); -void purge_requestqueue(struct dlm_ls * ls); -int process_requestqueue(struct dlm_ls * ls); -int reply_in_requestqueue(struct dlm_ls * ls, int lkid); -void remote_remove_direntry(struct dlm_ls * ls, int nodeid, char *name, - int namelen); -void allocate_and_copy_lvb(struct dlm_ls * ls, char **lvbptr, char *src); -void send_purge_all(struct dlm_ls *ls, int ournodeid, int pid); - -#endif /* __LOCKQUEUE_DOT_H__ */ diff --git a/dlm-kernel/src/lockspace.c b/dlm-kernel/src/lockspace.c deleted file mode 100644 index b36fd02..0000000 --- a/dlm-kernel/src/lockspace.c +++ /dev/null @@ -1,760 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/module.h> - -#include "dlm_internal.h" -#include "recoverd.h" -#include "ast.h" -#include "lkb.h" -#include "nodes.h" -#include "dir.h" -#include "lowcomms.h" -#include "config.h" -#include "memory.h" -#include "lockspace.h" -#include "device.h" - -#define GDST_NONE (0) -#define GDST_RUNNING (1) - -static int dlmstate; -static int dlmcount; -static struct semaphore dlmstate_lock; -struct list_head lslist; -spinlock_t lslist_lock; -struct kcl_service_ops ls_ops; - -static int new_lockspace(char *name, int namelen, void **lockspace, int flags); - - -void dlm_lockspace_init(void) -{ - dlmstate = GDST_NONE; - dlmcount = 0; - init_MUTEX(&dlmstate_lock); - INIT_LIST_HEAD(&lslist); - spin_lock_init(&lslist_lock); -} - -struct dlm_ls *find_lockspace_by_name(char *name, int namelen) -{ - struct dlm_ls *ls; - - spin_lock(&lslist_lock); - - list_for_each_entry(ls, &lslist, ls_list) { - if (ls->ls_namelen == namelen && - memcmp(ls->ls_name, name, namelen) == 0) - goto out; - } - ls = NULL; - out: - spin_unlock(&lslist_lock); - return ls; -} - -struct dlm_ls *find_lockspace_by_global_id(uint32_t id) -{ - struct dlm_ls *ls; - - spin_lock(&lslist_lock); - - list_for_each_entry(ls, &lslist, ls_list) { - if (ls->ls_global_id == id) { - ls->ls_count++; - goto out; - } - } - ls = NULL; - out: - spin_unlock(&lslist_lock); - return ls; -} - -struct dlm_ls *find_lockspace_by_local_id(void *id) -{ - struct dlm_ls *ls; - - spin_lock(&lslist_lock); - - list_for_each_entry(ls, &lslist, ls_list) { - if (ls->ls_local_id == (uint32_t)(long)id) { - ls->ls_count++; - goto out; - } - } - ls = NULL; - out: - spin_unlock(&lslist_lock); - return ls; -} - -/* must be called with lslist_lock held */ -void hold_lockspace(struct dlm_ls *ls) -{ - ls->ls_count++; -} - -void put_lockspace(struct dlm_ls *ls) -{ - spin_lock(&lslist_lock); - ls->ls_count--; - spin_unlock(&lslist_lock); -} - -static void remove_lockspace(struct dlm_ls *ls) -{ - for (;;) { - spin_lock(&lslist_lock); - if (ls->ls_count == 0) { - list_del(&ls->ls_list); - spin_unlock(&lslist_lock); - return; - } - spin_unlock(&lslist_lock); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - } -} - -/* - * Called from dlm_init. These are the general threads which are not - * lockspace-specific and work for all dlm lockspaces. - */ - -static int threads_start(void) -{ - int error; - - /* Thread which process lock requests for all ls's */ - error = astd_start(); - if (error) { - log_print("cannot start ast thread %d", error); - goto fail; - } - - /* Thread for sending/receiving messages for all ls's */ - error = lowcomms_start(); - if (error) { - log_print("cannot start lowcomms %d", error); - goto astd_fail; - } - - return 0; - - astd_fail: - astd_stop(); - - fail: - return error; -} - -static void threads_stop(void) -{ - lowcomms_stop(); - astd_stop(); -} - -static int init_internal(void) -{ - int error = 0; - - if (dlmstate == GDST_RUNNING) - dlmcount++; - else { - error = threads_start(); - if (error) - goto out; - - dlmstate = GDST_RUNNING; - dlmcount = 1; - } - - out: - return error; -} - -/* - * Called after dlm module is loaded and before any lockspaces are created. - * Starts and initializes global threads and structures. These global entities - * are shared by and independent of all lockspaces. - * - * There should be a dlm-specific user command which a person can run which - * calls this function. If a user hasn't run that command and something - * creates a new lockspace, this is called first. - * - * This also starts the default lockspace. - */ - -int dlm_init(void) -{ - int error; - - down(&dlmstate_lock); - error = init_internal(); - up(&dlmstate_lock); - - return error; -} - -int dlm_release(void) -{ - int error = 0; - - down(&dlmstate_lock); - - if (dlmstate == GDST_NONE) - goto out; - - if (dlmcount) - dlmcount--; - - if (dlmcount) - goto out; - - spin_lock(&lslist_lock); - if (!list_empty(&lslist)) { - spin_unlock(&lslist_lock); - log_print("cannot stop threads, lockspaces still exist"); - goto out; - } - spin_unlock(&lslist_lock); - - threads_stop(); - dlmstate = GDST_NONE; - - out: - up(&dlmstate_lock); - - return error; -} - -struct dlm_ls *allocate_ls(int namelen) -{ - struct dlm_ls *ls; - - ls = kmalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL); - if (ls) - memset(ls, 0, sizeof(struct dlm_ls) + namelen); - - return ls; -} - -static int new_lockspace(char *name, int namelen, void **lockspace, int flags) -{ - struct dlm_ls *ls; - int i, size, error = -ENOMEM; - uint32_t local_id = 0; - - if (namelen > MAX_SERVICE_NAME_LEN) - return -EINVAL; - - if (!try_module_get(THIS_MODULE)) - return -EINVAL; - - ls = find_lockspace_by_name(name, namelen); - if (ls) { - log_error(ls, "lockspace already in use"); - *lockspace = (void *)(long) ls->ls_local_id; - module_put(THIS_MODULE); - return -EEXIST; - } - - /* - * Initialize ls fields - */ - - ls = allocate_ls(namelen); - if (!ls) - goto out; - - memcpy(ls->ls_name, name, namelen); - ls->ls_namelen = namelen; - - ls->ls_allocation = GFP_KERNEL; - ls->ls_count = 0; - ls->ls_flags = 0; - - size = dlm_config.rsbtbl_size; - ls->ls_rsbtbl_size = size; - - ls->ls_rsbtbl = kmalloc(sizeof(struct dlm_rsbtable) * size, GFP_KERNEL); - if (!ls->ls_rsbtbl) - goto out_lsfree; - for (i = 0; i < size; i++) { - INIT_LIST_HEAD(&ls->ls_rsbtbl[i].list); - rwlock_init(&ls->ls_rsbtbl[i].lock); - } - - size = dlm_config.lkbtbl_size; - ls->ls_lkbtbl_size = size; - - ls->ls_lkbtbl = kmalloc(sizeof(struct dlm_lkbtable) * size, GFP_KERNEL); - if (!ls->ls_lkbtbl) - goto out_rsbfree; - for (i = 0; i < size; i++) { - INIT_LIST_HEAD(&ls->ls_lkbtbl[i].list); - rwlock_init(&ls->ls_lkbtbl[i].lock); - ls->ls_lkbtbl[i].counter = 1; - } - - size = dlm_config.dirtbl_size; - ls->ls_dirtbl_size = size; - - ls->ls_dirtbl = kmalloc(sizeof(struct dlm_dirtable) * size, GFP_KERNEL); - if (!ls->ls_dirtbl) - goto out_lkbfree; - for (i = 0; i < size; i++) { - INIT_LIST_HEAD(&ls->ls_dirtbl[i].list); - rwlock_init(&ls->ls_dirtbl[i].lock); - } - - INIT_LIST_HEAD(&ls->ls_nodes); - INIT_LIST_HEAD(&ls->ls_nodes_gone); - spin_lock_init(&ls->ls_nodes_gone_spin); - ls->ls_num_nodes = 0; - ls->ls_node_array = NULL; - ls->ls_recoverd_task = NULL; - init_MUTEX(&ls->ls_recoverd_active); - INIT_LIST_HEAD(&ls->ls_recover); - spin_lock_init(&ls->ls_recover_lock); - INIT_LIST_HEAD(&ls->ls_recover_list); - ls->ls_recover_list_count = 0; - spin_lock_init(&ls->ls_recover_list_lock); - init_waitqueue_head(&ls->ls_wait_general); - INIT_LIST_HEAD(&ls->ls_rootres); - INIT_LIST_HEAD(&ls->ls_requestqueue); - INIT_LIST_HEAD(&ls->ls_rebuild_rootrsb_list); - ls->ls_last_stop = 0; - ls->ls_last_start = 0; - ls->ls_last_finish = 0; - ls->ls_rcom_msgid = 0; - init_MUTEX(&ls->ls_requestqueue_lock); - init_MUTEX(&ls->ls_rcom_lock); - init_rwsem(&ls->ls_unlock_sem); - init_rwsem(&ls->ls_root_lock); - init_rwsem(&ls->ls_in_recovery); - - down_write(&ls->ls_in_recovery); - - if (flags & DLM_LSF_NOTIMERS) - set_bit(LSFL_NOTIMERS, &ls->ls_flags); - - error = dlm_recoverd_start(ls); - if (error) { - log_error(ls, "can't start dlm_recoverd %d", error); - goto out_dirfree; - } - - /* - * Connect this lockspace with the cluster manager - */ - - error = kcl_register_service(name, namelen, SERVICE_LEVEL_GDLM, - &ls_ops, TRUE, (void *) ls, &local_id); - if (error) - goto out_recoverd; - - ls->ls_state = LSST_INIT; - ls->ls_local_id = local_id; - - spin_lock(&lslist_lock); - list_add(&ls->ls_list, &lslist); - spin_unlock(&lslist_lock); - - error = kcl_join_service(local_id); - if (error) { - log_error(ls, "service manager join error %d", error); - goto out_reg; - } - - /* The ls isn't actually running until it receives a start() from CMAN. - Neither does it have a global ls id until started. */ - - /* Return the local ID as the lockspace handle. I've left this - cast to a void* as it allows us to replace it with pretty much - anything at a future date without breaking clients. But returning - the address of the lockspace is a bad idea as it could get - forcibly removed, leaving client with a dangling pointer */ - - *lockspace = (void *)(long) local_id; - return 0; - - out_reg: - kcl_unregister_service(ls->ls_local_id); - out_recoverd: - dlm_recoverd_stop(ls); - out_dirfree: - kfree(ls->ls_dirtbl); - out_lkbfree: - kfree(ls->ls_lkbtbl); - out_rsbfree: - kfree(ls->ls_rsbtbl); - out_lsfree: - kfree(ls); - out: - return error; -} - -/* - * Called by a system like GFS which wants independent lock spaces. - */ - -int dlm_new_lockspace(char *name, int namelen, void **lockspace, int flags) -{ - int error = -ENOSYS; - - down(&dlmstate_lock); - error = init_internal(); - if (error) { - up(&dlmstate_lock); - goto out; - } - - error = new_lockspace(name, namelen, lockspace, flags); - up(&dlmstate_lock); - - if (error) - dlm_release(); - out: - - return error; -} - -/* Return 1 if the lockspace still has active remote locks, - * 2 if the lockspace still has active local locks. - */ -static int lockspace_busy(struct dlm_ls *ls) -{ - int i, lkb_found = 0; - struct dlm_lkb *lkb; - - /* NOTE: We check the lockidtbl here rather than the resource table. - This is because there may be LKBs queued as ASTs that have been - unlinked from their RSBs and are pending deletion once the AST has - been delivered */ - - for (i = 0; i < ls->ls_lkbtbl_size; i++) { - read_lock(&ls->ls_lkbtbl[i].lock); - if (!list_empty(&ls->ls_lkbtbl[i].list)) { - lkb_found = 1; - list_for_each_entry(lkb, &ls->ls_lkbtbl[i].list, - lkb_idtbl_list) { - if (!lkb->lkb_nodeid) { - read_unlock(&ls->ls_lkbtbl[i].lock); - return 2; - } - } - } - read_unlock(&ls->ls_lkbtbl[i].lock); - } - return lkb_found; -} - -static int release_lockspace(struct dlm_ls *ls, int force) -{ - struct dlm_lkb *lkb; - struct dlm_rsb *rsb; - struct dlm_recover *rv; - struct list_head *head; - int i; - int busy = lockspace_busy(ls); - - /* Don't destroy a busy lockspace */ - if (busy > force) - return -EBUSY; - - if (force < 3) { - kcl_leave_service(ls->ls_local_id); - kcl_unregister_service(ls->ls_local_id); - } - - dlm_recoverd_stop(ls); - - remove_lockspace(ls); - - /* - * Suspend astd before doing the dlm_dir_clear() and kfree(), - * otherwise astd can be processing an ast which can call release_rsb() - * and then dlm_dir_remove() which references ls_dirtbl after - * it has been freed. - */ - astd_suspend(); - - /* - * Free direntry structs. - */ - - dlm_dir_clear(ls); - kfree(ls->ls_dirtbl); - - /* - * Free all lkb's on lkbtbl[] lists. - */ - - for (i = 0; i < ls->ls_lkbtbl_size; i++) { - head = &ls->ls_lkbtbl[i].list; - while (!list_empty(head)) { - lkb = list_entry(head->next, struct dlm_lkb, - lkb_idtbl_list); - list_del(&lkb->lkb_idtbl_list); - - if (lkb->lkb_lockqueue_state) - remove_from_lockqueue(lkb); - - remove_from_astqueue(lkb); - - if (lkb->lkb_lvbptr && lkb->lkb_flags & GDLM_LKFLG_MSTCPY) - free_lvb(lkb->lkb_lvbptr); - - free_lkb(lkb); - } - } - astd_resume(); - - kfree(ls->ls_lkbtbl); - - /* - * Free all rsb's on rsbtbl[] lists - */ - - for (i = 0; i < ls->ls_rsbtbl_size; i++) { - head = &ls->ls_rsbtbl[i].list; - while (!list_empty(head)) { - rsb = list_entry(head->next, struct dlm_rsb, - res_hashchain); - list_del(&rsb->res_hashchain); - - if (rsb->res_lvbptr) - free_lvb(rsb->res_lvbptr); - - free_rsb(rsb); - } - } - - kfree(ls->ls_rsbtbl); - - /* - * Free structures on any other lists - */ - - head = &ls->ls_recover; - while (!list_empty(head)) { - rv = list_entry(head->next, struct dlm_recover, list); - list_del(&rv->list); - kfree(rv); - } - - clear_free_de(ls); - - ls_nodes_clear(ls); - ls_nodes_gone_clear(ls); - if (ls->ls_node_array) - kfree(ls->ls_node_array); - - kfree(ls); - dlm_release(); - module_put(THIS_MODULE); - return 0; -} - - -/* - * Called when a system has released all its locks and is not going to use the - * lockspace any longer. We blindly free everything we're managing for this - * lockspace. Remaining nodes will go through the recovery process as if we'd - * died. The lockspace must continue to function as usual, participating in - * recoveries, until kcl_leave_service returns. - * - * Force has 4 possible values: - * 0 - don't destroy locksapce if it has any LKBs - * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs - * 2 - destroy lockspace regardless of LKBs - * 3 - destroy lockspace as part of a forced shutdown - */ - -int dlm_release_lockspace(void *lockspace, int force) -{ - struct dlm_ls *ls; - - ls = find_lockspace_by_local_id(lockspace); - if (!ls) - return -EINVAL; - put_lockspace(ls); - return release_lockspace(ls, force); -} - - -/* Called when the cluster is being shut down dirtily */ -void dlm_emergency_shutdown() -{ - struct dlm_ls *ls; - struct dlm_ls *tmp; - int count = 0; - - printk("WARNING: dlm_emergency_shutdown\n"); - - /* Shut lowcomms down to prevent any socket activity */ - lowcomms_stop_accept(); - - /* Delete the devices that belong the the userland - lockspaces to be deleted. */ - dlm_device_free_devices(); - - /* Now try to clean the lockspaces */ - spin_lock(&lslist_lock); - - /* prevent unloading since we cannot guarantee that slab - * caches are empty here. This prevents a warning when our - * module_exit tries to destroy the slab caches and - * possible oopsen if something accesses /proc/slabinfo - */ - if (!list_empty(&lslist)) - __module_get(THIS_MODULE); - - list_for_each_entry_safe(ls, tmp, &lslist, ls_list) { - spin_unlock(&lslist_lock); - release_lockspace(ls, 3); - spin_lock(&lslist_lock); - count++; - } - - spin_unlock(&lslist_lock); - - printk("WARNING: dlm_emergency_shutdown finished %d\n", count); -} - -struct dlm_recover *allocate_dlm_recover(void) -{ - struct dlm_recover *rv; - - rv = kmalloc(sizeof(struct dlm_recover), GFP_KERNEL); - if (rv) - memset(rv, 0, sizeof(struct dlm_recover)); - return rv; -} - -/* - * Called by CMAN on a specific ls. "stop" means set flag which while set - * causes all new requests to ls to be queued and not submitted until flag is - * cleared. stop on a ls also needs to cancel any prior starts on the ls. - * The recoverd thread carries out any work called for by this event. - */ - -static int dlm_ls_stop(void *servicedata) -{ - struct dlm_ls *ls = (struct dlm_ls *) servicedata; - int new; - - spin_lock(&ls->ls_recover_lock); - ls->ls_last_stop = ls->ls_last_start; - set_bit(LSFL_LS_STOP, &ls->ls_flags); - new = test_and_clear_bit(LSFL_LS_RUN, &ls->ls_flags); - spin_unlock(&ls->ls_recover_lock); - - /* - * This in_recovery lock does two things: - * - * 1) Keeps this function from returning until all threads are out - * of locking routines and locking is truely stopped. - * 2) Keeps any new requests from being processed until it's unlocked - * when recovery is complete. - */ - - if (new) - down_write(&ls->ls_in_recovery); - - /* - * The recoverd suspend/resume makes sure that dlm_recoverd (if - * running) has noticed the clearing of LS_RUN above and quit - * processing the previous recovery. This will be true for all nodes - * before any nodes get the start. - */ - - dlm_recoverd_suspend(ls); - clear_bit(LSFL_RESDIR_VALID, &ls->ls_flags); - clear_bit(LSFL_ALL_RESDIR_VALID, &ls->ls_flags); - clear_bit(LSFL_NODES_VALID, &ls->ls_flags); - clear_bit(LSFL_ALL_NODES_VALID, &ls->ls_flags); - dlm_recoverd_resume(ls); - dlm_recoverd_kick(ls); - - return 0; -} - -/* - * Called by CMAN on a specific ls. "start" means enable the lockspace to do - * request processing which first requires that the recovery procedure be - * stepped through with all nodes sharing the lockspace (nodeids). The first - * start on the ls after it's created is a special case and requires some extra - * work like figuring out our own local nodeid. We can't do all this in the - * calling CMAN context, so we must pass this work off to the recoverd thread - * which was created in dlm_init(). The recoverd thread carries out any work - * called for by this event. - */ - -static int dlm_ls_start(void *servicedata, uint32_t *nodeids, int count, - int event_id, int type) -{ - struct dlm_ls *ls = (struct dlm_ls *) servicedata; - struct dlm_recover *rv; - int error = -ENOMEM; - - rv = allocate_dlm_recover(); - if (!rv) - goto out; - - rv->nodeids = nodeids; - rv->node_count = count; - rv->event_id = event_id; - - spin_lock(&ls->ls_recover_lock); - if (ls->ls_last_start == event_id) - log_debug(ls, "repeated start %d stop %d finish %d", - event_id, ls->ls_last_stop, ls->ls_last_finish); - ls->ls_last_start = event_id; - list_add_tail(&rv->list, &ls->ls_recover); - set_bit(LSFL_LS_START, &ls->ls_flags); - spin_unlock(&ls->ls_recover_lock); - - dlm_recoverd_kick(ls); - error = 0; - - out: - return error; -} - -/* - * Called by CMAN on a specific ls. "finish" means that all nodes which - * received a "start" have completed the start and called kcl_start_done. - * The recoverd thread carries out any work called for by this event. - */ - -static void dlm_ls_finish(void *servicedata, int event_id) -{ - struct dlm_ls *ls = (struct dlm_ls *) servicedata; - - spin_lock(&ls->ls_recover_lock); - ls->ls_last_finish = event_id; - set_bit(LSFL_LS_FINISH, &ls->ls_flags); - spin_unlock(&ls->ls_recover_lock); - - dlm_recoverd_kick(ls); -} - -struct kcl_service_ops ls_ops = { - .stop = dlm_ls_stop, - .start = dlm_ls_start, - .finish = dlm_ls_finish -}; diff --git a/dlm-kernel/src/lockspace.h b/dlm-kernel/src/lockspace.h deleted file mode 100644 index 9cf0ce2..0000000 --- a/dlm-kernel/src/lockspace.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOCKSPACE_DOT_H__ -#define __LOCKSPACE_DOT_H__ - -void dlm_lockspace_init(void); -int dlm_init(void); -int dlm_release(void); -int dlm_new_lockspace(char *name, int namelen, void **ls, int flags); -int dlm_release_lockspace(void *ls, int force); -void dlm_emergency_shutdown(void); -struct dlm_ls *find_lockspace_by_global_id(uint32_t id); -struct dlm_ls *find_lockspace_by_local_id(void *id); -struct dlm_ls *find_lockspace_by_name(char *name, int namelen); -void hold_lockspace(struct dlm_ls *ls); -void put_lockspace(struct dlm_ls *ls); - -#endif /* __LOCKSPACE_DOT_H__ */ diff --git a/dlm-kernel/src/lowcomms.c b/dlm-kernel/src/lowcomms.c deleted file mode 100644 index 8ea83dd..0000000 --- a/dlm-kernel/src/lowcomms.c +++ /dev/null @@ -1,1447 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * lowcomms.c - * - * This is the "low-level" comms layer. - * - * It is responsible for sending/receiving messages - * from other nodes in the cluster. - * - * Cluster nodes are referred to by their nodeids. nodeids are - * simply 32 bit numbers to the locking module - if they need to - * be expanded for the cluster infrastructure then that is it's - * responsibility. It is this layer's - * responsibility to resolve these into IP address or - * whatever it needs for inter-node communication. - * - * The comms level is two kernel threads that deal mainly with - * the receiving of messages from other nodes and passing them - * up to the mid-level comms layer (which understands the - * message format) for execution by the locking core, and - * a send thread which does all the setting up of connections - * to remote nodes and the sending of data. Threads are not allowed - * to send their own data because it may cause them to wait in times - * of high load. Also, this way, the sending thread can collect together - * messages bound for one node and send them in one block. - * - * I don't see any problem with the recv thread executing the locking - * code on behalf of remote processes as the locking code is - * short, efficient and never waits. - * - */ - - -#include <asm/ioctls.h> -#include <net/sock.h> -#include <net/tcp.h> -#include <linux/pagemap.h> -#include <cluster/cnxman.h> - -#include "dlm_internal.h" -#include "lowcomms.h" -#include "midcomms.h" -#include "config.h" - -struct cbuf { - unsigned base; - unsigned len; - unsigned mask; -}; - -#define CBUF_INIT(cb, size) do { (cb)->base = (cb)->len = 0; (cb)->mask = ((size)-1); } while(0) -#define CBUF_ADD(cb, n) do { (cb)->len += n; } while(0) -#define CBUF_EMPTY(cb) ((cb)->len == 0) -#define CBUF_MAY_ADD(cb, n) (((cb)->len + (n)) < ((cb)->mask + 1)) -#define CBUF_EAT(cb, n) do { (cb)->len -= (n); \ - (cb)->base += (n); (cb)->base &= (cb)->mask; } while(0) -#define CBUF_DATA(cb) (((cb)->base + (cb)->len) & (cb)->mask) - -/* Maximum number of incoming messages to process before - doing a schedule() -*/ -#define MAX_RX_MSG_COUNT 25 - -struct connection { - struct socket *sock; /* NULL if not connected */ - uint32_t nodeid; /* So we know who we are in the list */ - struct rw_semaphore sock_sem; /* Stop connect races */ - struct list_head read_list; /* On this list when ready for reading */ - struct list_head write_list; /* On this list when ready for writing */ - struct list_head state_list; /* On this list when ready to connect */ - unsigned long flags; /* bit 1,2 = We are on the read/write lists */ -#define CF_READ_PENDING 1 -#define CF_WRITE_PENDING 2 -#define CF_CONNECT_PENDING 3 -#define CF_IS_OTHERCON 4 - struct list_head writequeue; /* List of outgoing writequeue_entries */ - struct list_head listenlist; /* List of allocated listening sockets */ - spinlock_t writequeue_lock; - int (*rx_action) (struct connection *); /* What to do when active */ - struct page *rx_page; - struct cbuf cb; - int retries; - atomic_t waiting_requests; -#define MAX_CONNECT_RETRIES 3 - struct connection *othercon; -}; -#define sock2con(x) ((struct connection *)(x)->sk_user_data) - -/* An entry waiting to be sent */ -struct writequeue_entry { - struct list_head list; - struct page *page; - int offset; - int len; - int end; - int users; - struct connection *con; -}; - -/* "Template" structure for IPv4 and IPv6 used to fill - * in the missing bits when converting between cman (which knows - * nothing about sockaddr structs) and real life where we actually - * have to connect to these addresses. Also one of these structs - * will hold the cached "us" address. - * - * It's an in6 sockaddr just so there's enough space for anything - * we're likely to see here. - */ -static struct sockaddr_in6 local_addr; -static int our_nodeid = 0; - -/* Manage daemons */ -static struct task_struct *recv_task; -static struct task_struct *send_task; - -static wait_queue_t lowcomms_send_waitq_head; -static wait_queue_head_t lowcomms_send_waitq; -static wait_queue_t lowcomms_recv_waitq_head; -static wait_queue_head_t lowcomms_recv_waitq; - -/* An array of pointers to connections, indexed by NODEID */ -static struct connection **connections; -static struct semaphore connections_lock; -static kmem_cache_t *con_cache; -static int conn_array_size; -static atomic_t accepting; - -/* List of sockets that have reads pending */ -static struct list_head read_sockets; -static spinlock_t read_sockets_lock; - -/* List of sockets which have writes pending */ -static struct list_head write_sockets; -static spinlock_t write_sockets_lock; - -/* List of sockets which have connects pending */ -static struct list_head state_sockets; -static spinlock_t state_sockets_lock; - -/* List of allocated listen sockets */ -static struct list_head listen_sockets; - -static int lowcomms_ipaddr_from_nodeid(int nodeid, struct sockaddr *retaddr); -static int lowcomms_nodeid_from_ipaddr(struct sockaddr *addr, int addr_len); - -static struct connection *nodeid2con(int nodeid, int allocation) -{ - struct connection *con = NULL; - - down(&connections_lock); - if (nodeid >= conn_array_size) { - int new_size = nodeid + dlm_config.conn_increment; - struct connection **new_conns; - - new_conns = kmalloc(sizeof(struct connection *) * - new_size, allocation); - if (!new_conns) - goto finish; - - memset(new_conns, 0, sizeof(struct connection *) * new_size); - memcpy(new_conns, connections, sizeof(struct connection *) * conn_array_size); - conn_array_size = new_size; - kfree(connections); - connections = new_conns; - - } - - con = connections[nodeid]; - if (con == NULL && allocation) { - con = kmem_cache_alloc(con_cache, allocation); - if (!con) - goto finish; - - memset(con, 0, sizeof(*con)); - con->nodeid = nodeid; - init_rwsem(&con->sock_sem); - INIT_LIST_HEAD(&con->writequeue); - spin_lock_init(&con->writequeue_lock); - - connections[nodeid] = con; - } - - finish: - up(&connections_lock); - return con; -} - -/* Data available on socket or listen socket received a connect */ -static void lowcomms_data_ready(struct sock *sk, int count_unused) -{ - struct connection *con = sock2con(sk); - - atomic_inc(&con->waiting_requests); - if (test_and_set_bit(CF_READ_PENDING, &con->flags)) - return; - - spin_lock_bh(&read_sockets_lock); - list_add_tail(&con->read_list, &read_sockets); - spin_unlock_bh(&read_sockets_lock); - - wake_up_interruptible(&lowcomms_recv_waitq); -} - -static void lowcomms_write_space(struct sock *sk) -{ - struct connection *con = sock2con(sk); - - if (test_and_set_bit(CF_WRITE_PENDING, &con->flags)) - return; - - spin_lock_bh(&write_sockets_lock); - list_add_tail(&con->write_list, &write_sockets); - spin_unlock_bh(&write_sockets_lock); - - wake_up_interruptible(&lowcomms_send_waitq); -} - -static inline void lowcomms_connect_sock(struct connection *con) -{ - if (test_and_set_bit(CF_CONNECT_PENDING, &con->flags)) - return; - if (!atomic_read(&accepting)) - return; - - spin_lock_bh(&state_sockets_lock); - list_add_tail(&con->state_list, &state_sockets); - spin_unlock_bh(&state_sockets_lock); - - wake_up_interruptible(&lowcomms_send_waitq); -} - -static void lowcomms_state_change(struct sock *sk) -{ -/* struct connection *con = sock2con(sk); */ - - switch (sk->sk_state) { - case TCP_ESTABLISHED: - lowcomms_write_space(sk); - break; - - case TCP_FIN_WAIT1: - case TCP_FIN_WAIT2: - case TCP_TIME_WAIT: - case TCP_CLOSE: - case TCP_CLOSE_WAIT: - case TCP_LAST_ACK: - case TCP_CLOSING: - /* FIXME: I think this causes more trouble than it solves. - lowcomms wil reconnect anyway when there is something to - send. This just attempts reconnection if a node goes down! - */ - /* lowcomms_connect_sock(con); */ - break; - - default: - printk("dlm: lowcomms_state_change: state=%d\n", sk->sk_state); - break; - } -} - -/* Make a socket active */ -static int add_sock(struct socket *sock, struct connection *con) -{ - con->sock = sock; - - /* Install a data_ready callback */ - con->sock->sk->sk_data_ready = lowcomms_data_ready; - con->sock->sk->sk_write_space = lowcomms_write_space; - con->sock->sk->sk_state_change = lowcomms_state_change; - - return 0; -} - -/* Add the port number to an IP6 or 4 sockaddr and return the address - length */ -static void make_sockaddr(struct sockaddr_in6 *saddr, uint16_t port, - int *addr_len) -{ - saddr->sin6_family = local_addr.sin6_family; - if (local_addr.sin6_family == AF_INET) { - struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr; - in4_addr->sin_port = cpu_to_be16(port); - *addr_len = sizeof(struct sockaddr_in); - } - else { - saddr->sin6_port = cpu_to_be16(port); - *addr_len = sizeof(struct sockaddr_in6); - } -} - -/* Close a remote connection and tidy up */ -static void close_connection(struct connection *con, int and_other) -{ - down_write(&con->sock_sem); - - if (con->sock) { - sock_release(con->sock); - con->sock = NULL; - } - if (con->othercon && and_other) { - /* Argh! recursion in kernel code! - Actually, this isn't a list so it - will only re-enter once. - */ - close_connection(con->othercon, FALSE); - } - if (con->rx_page) { - __free_page(con->rx_page); - con->rx_page = NULL; - } - - con->retries = 0; - up_write(&con->sock_sem); -} - -/* Data received from remote end */ -static int receive_from_sock(struct connection *con) -{ - int ret = 0; - struct msghdr msg; - struct iovec iov[2]; - mm_segment_t fs; - unsigned len; - int r; - int call_again_soon = 0; - - down_read(&con->sock_sem); - - if (con->sock == NULL) - goto out; - if (con->rx_page == NULL) { - /* - * This doesn't need to be atomic, but I think it should - * improve performance if it is. - */ - con->rx_page = alloc_page(GFP_ATOMIC); - if (con->rx_page == NULL) - goto out_resched; - CBUF_INIT(&con->cb, PAGE_CACHE_SIZE); - } - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_flags = 0; - - /* - * iov[0] is the bit of the circular buffer between the current end - * point (cb.base + cb.len) and the end of the buffer. - */ - iov[0].iov_len = con->cb.base - CBUF_DATA(&con->cb); - iov[0].iov_base = page_address(con->rx_page) + CBUF_DATA(&con->cb); - iov[1].iov_len = 0; - - /* - * iov[1] is the bit of the circular buffer between the start of the - * buffer and the start of the currently used section (cb.base) - */ - if (CBUF_DATA(&con->cb) >= con->cb.base) { - iov[0].iov_len = PAGE_CACHE_SIZE - CBUF_DATA(&con->cb); - iov[1].iov_len = con->cb.base; - iov[1].iov_base = page_address(con->rx_page); - msg.msg_iovlen = 2; - } - len = iov[0].iov_len + iov[1].iov_len; - - fs = get_fs(); - set_fs(get_ds()); - r = ret = sock_recvmsg(con->sock, &msg, len, - MSG_DONTWAIT | MSG_NOSIGNAL); - set_fs(fs); - - if (ret <= 0) - goto out_close; - if (ret == len) - call_again_soon = 1; - CBUF_ADD(&con->cb, ret); - ret = midcomms_process_incoming_buffer(con->nodeid, - page_address(con->rx_page), - con->cb.base, con->cb.len, - PAGE_CACHE_SIZE); - if (ret == -EBADMSG) { - printk(KERN_INFO "dlm: lowcomms: addr=%p, base=%u, len=%u, " - "iov_len=%u, iov_base[0]=%p, read=%d\n", - page_address(con->rx_page), con->cb.base, con->cb.len, - len, iov[0].iov_base, r); - } - if (ret < 0) - goto out_close; - CBUF_EAT(&con->cb, ret); - - if (CBUF_EMPTY(&con->cb) && !call_again_soon) { - __free_page(con->rx_page); - con->rx_page = NULL; - } - - out: - if (call_again_soon) - goto out_resched; - up_read(&con->sock_sem); - ret = 0; - goto out_ret; - - out_resched: - lowcomms_data_ready(con->sock->sk, 0); - up_read(&con->sock_sem); - ret = 0; - schedule(); - goto out_ret; - - out_close: - up_read(&con->sock_sem); - if (ret != -EAGAIN) { - close_connection(con, FALSE); - /* Reconnect when there is something to send */ - } - - out_ret: - return ret; -} - -/* Listening socket is busy, accept a connection */ -static int accept_from_sock(struct connection *con) -{ - int result; - struct sockaddr_in6 peeraddr; - struct socket *newsock; - int len; - int nodeid; - struct connection *newcon; - - memset(&peeraddr, 0, sizeof(peeraddr)); - result = sock_create_kern(local_addr.sin6_family, SOCK_STREAM, IPPROTO_TCP, &newsock); - if (result < 0) - return -ENOMEM; - - down_read(&con->sock_sem); - - result = -ENOTCONN; - if (con->sock == NULL) - goto accept_err; - - newsock->type = con->sock->type; - newsock->ops = con->sock->ops; - - result = con->sock->ops->accept(con->sock, newsock, O_NONBLOCK); - if (result < 0) - goto accept_err; - - /* Get the connected socket's peer */ - if (newsock->ops->getname(newsock, (struct sockaddr *)&peeraddr, - &len, 2)) { - result = -ECONNABORTED; - goto accept_err; - } - - /* Get the new node's NODEID */ - nodeid = lowcomms_nodeid_from_ipaddr((struct sockaddr *)&peeraddr, len); - if (nodeid == 0) { - printk("dlm: connect from non cluster node\n"); - sock_release(newsock); - up_read(&con->sock_sem); - return -1; - } - - log_debug2("got connection from %d", nodeid); - - /* Check to see if we already have a connection to this node. This - * could happen if the two nodes initiate a connection at roughly - * the same time and the connections cross on the wire. - * TEMPORARY FIX: - * In this case we store the incoming one in "othercon" - */ - newcon = nodeid2con(nodeid, GFP_KERNEL); - if (!newcon) { - result = -ENOMEM; - goto accept_err; - } - down_write(&newcon->sock_sem); - if (newcon->sock) { - struct connection *othercon = newcon->othercon; - - if (!othercon) { - othercon = kmem_cache_alloc(con_cache, GFP_KERNEL); - if (!othercon) { - printk("dlm: failed to allocate incoming socket\n"); - up_write(&newcon->sock_sem); - result = -ENOMEM; - goto accept_err; - } - memset(othercon, 0, sizeof(*othercon)); - othercon->nodeid = nodeid; - othercon->rx_action = receive_from_sock; - init_rwsem(&othercon->sock_sem); - set_bit(CF_IS_OTHERCON, &othercon->flags); - newcon->othercon = othercon; - } - if (!othercon->sock) { - othercon->sock = newsock; - newsock->sk->sk_user_data = othercon; - add_sock(newsock, othercon); - } - else { - printk("Extra connection from node %d attempted\n", nodeid); - result = -EAGAIN; - up_write(&newcon->sock_sem); - goto accept_err; - } - } - else { - newsock->sk->sk_user_data = newcon; - newcon->rx_action = receive_from_sock; - add_sock(newsock, newcon); - - } - - up_write(&newcon->sock_sem); - - /* - * Add it to the active queue in case we got data - * beween processing the accept adding the socket - * to the read_sockets list - */ - lowcomms_data_ready(newsock->sk, 0); - up_read(&con->sock_sem); - - return 0; - - accept_err: - up_read(&con->sock_sem); - sock_release(newsock); - - if (result != -EAGAIN) - printk("dlm: error accepting connection from node: %d\n", result); - return result; -} - -/* Connect a new socket to its peer */ -static int connect_to_sock(struct connection *con) -{ - int result = -EHOSTUNREACH; - struct sockaddr_in6 saddr; - struct sockaddr_in6 my_addr; - int addr_len; - struct socket *sock; - - if (con->nodeid == 0) { - log_print("attempt to connect sock 0 foiled"); - return 0; - } - - down_write(&con->sock_sem); - if (con->retries++ > MAX_CONNECT_RETRIES) - goto out; - - /* Some odd races can cause double-connects, ignore them */ - if (con->sock) { - result = 0; - goto out; - } - - /* Create a socket to communicate with */ - result = sock_create_kern(local_addr.sin6_family, SOCK_STREAM, IPPROTO_TCP, &sock); - if (result < 0) - goto out_err; - - memset(&saddr, 0, sizeof(saddr)); - if (lowcomms_ipaddr_from_nodeid(con->nodeid, (struct sockaddr *)&saddr) < 0) - goto out_err; - - sock->sk->sk_user_data = con; - con->rx_action = receive_from_sock; - - /* Bind to local address before send */ - memcpy(&my_addr, &local_addr, sizeof(my_addr)); - make_sockaddr(&my_addr, 0, &addr_len); - result = sock->ops->bind(sock, (struct sockaddr *) &my_addr, - (int) sizeof(my_addr)); - if (result < 0) { - printk("dlm: could not bind for connect: %d\n", result); - } - - /* Set up for connect */ - make_sockaddr(&saddr, dlm_config.tcp_port, &addr_len); - - if (dlm_config.tcp_nodelay) { - int one = 1; - mm_segment_t fs; - - fs = get_fs(); - set_fs(get_ds()); - - tcp_setsockopt(sock->sk, SOL_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); - set_fs(fs); - } - add_sock(sock, con); - - log_debug2("connecting to %d", con->nodeid); - result = - sock->ops->connect(sock, (struct sockaddr *) &saddr, addr_len, - O_NONBLOCK); - if (result == -EINPROGRESS) - result = 0; - if (result != 0) - goto out_err; - - out: - up_write(&con->sock_sem); - /* - * Returning an error here means we've given up trying to connect to - * a remote node, otherwise we return 0 and reschedule the connetion - * attempt - */ - return result; - - out_err: - if (con->sock) { - sock_release(con->sock); - con->sock = NULL; - } - /* - * Some errors are fatal and this list might need adjusting. For other - * errors we try again until the max number of retries is reached. - */ - if (result != -EHOSTUNREACH && result != -ENETUNREACH && - result != -ENETDOWN && result != EINVAL - && result != -EPROTONOSUPPORT) { - lowcomms_connect_sock(con); - result = 0; - } - goto out; -} - -static struct socket *create_listen_sock(struct connection *con, char *addr, int addr_len) -{ - struct socket *sock = NULL; - mm_segment_t fs; - int result = 0; - int one = 1; - struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)addr; - - /* Create a socket to communicate with */ - result = sock_create_kern(local_addr.sin6_family, SOCK_STREAM, IPPROTO_TCP, &sock); - if (result < 0) { - printk("dlm: Can't create listening comms socket\n"); - goto create_out; - } - - fs = get_fs(); - set_fs(get_ds()); - - if (dlm_config.tcp_nodelay) - result = tcp_setsockopt(sock->sk, SOL_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); - - result = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); - set_fs(fs); - if (result < 0) { - printk("dlm: Failed to set SO_REUSEADDR on socket: result=%d\n",result); - } - sock->sk->sk_user_data = con; - con->rx_action = accept_from_sock; - con->sock = sock; - - /* Bind to our port */ - make_sockaddr(saddr, dlm_config.tcp_port, &addr_len); - result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len); - if (result < 0) { - printk("dlm: Can't bind to port %d\n", dlm_config.tcp_port); - sock_release(sock); - sock = NULL; - con->sock = NULL; - goto create_out; - } - - fs = get_fs(); - set_fs(get_ds()); - - result = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sizeof(one)); - set_fs(fs); - if (result < 0) { - printk("dlm: Set keepalive failed: %d\n", result); - } - - result = sock->ops->listen(sock, 5); - if (result < 0) { - printk("dlm: Can't listen on port %d\n", dlm_config.tcp_port); - sock_release(sock); - sock = NULL; - goto create_out; - } - - create_out: - return sock; -} - - -/* Listen on all interfaces */ -static int listen_for_all(void) -{ - int result = 0; - int nodeid; - struct socket *sock = NULL; - struct list_head *addr_list; - struct connection *con = nodeid2con(0, GFP_KERNEL); - struct cluster_node_addr *node_addr; - char local_addr[sizeof(struct sockaddr_in6)]; - - /* This will also fill in local_addr */ - nodeid = lowcomms_our_nodeid(); - - addr_list = kcl_get_node_addresses(nodeid); - if (!addr_list) { - printk("dlm: cannot initialise comms layer\n"); - result = -ENOTCONN; - goto create_out; - } - - list_for_each_entry(node_addr, addr_list, list) { - - if (!con) { - con = kmem_cache_alloc(con_cache, GFP_KERNEL); - if (!con) { - printk("dlm: failed to allocate listen socket\n"); - result = -ENOMEM; - goto create_out; - } - memset(con, 0, sizeof(*con)); - init_rwsem(&con->sock_sem); - spin_lock_init(&con->writequeue_lock); - INIT_LIST_HEAD(&con->writequeue); - set_bit(CF_IS_OTHERCON, &con->flags); - } - - memcpy(local_addr, node_addr->addr, node_addr->addr_len); - sock = create_listen_sock(con, local_addr, - node_addr->addr_len); - if (sock) { - add_sock(sock, con); - - /* Keep a list of dynamically allocated listening sockets - so we can free them at shutdown */ - if (test_bit(CF_IS_OTHERCON, &con->flags)) { - list_add_tail(&con->listenlist, &listen_sockets); - } - } - else { - result = -EADDRINUSE; - if (test_bit(CF_IS_OTHERCON, &con->flags)) - kmem_cache_free(con_cache, con); - goto create_out; - } - - con = NULL; - } - - create_out: - return result; -} - - - -static struct writequeue_entry *new_writequeue_entry(struct connection *con, - int allocation) -{ - struct writequeue_entry *entry; - - entry = kmalloc(sizeof(struct writequeue_entry), allocation); - if (!entry) - return NULL; - - entry->page = alloc_page(allocation); - if (!entry->page) { - kfree(entry); - return NULL; - } - - entry->offset = 0; - entry->len = 0; - entry->end = 0; - entry->users = 0; - entry->con = con; - - return entry; -} - -struct writequeue_entry *lowcomms_get_buffer(int nodeid, int len, - int allocation, char **ppc) -{ - struct connection *con; - struct writequeue_entry *e; - int offset = 0; - int users = 0; - - if (!atomic_read(&accepting)) - return NULL; - - con = nodeid2con(nodeid, allocation); - if (!con) - return NULL; - - spin_lock(&con->writequeue_lock); - e = list_entry(con->writequeue.prev, struct writequeue_entry, list); - if (((struct list_head *) e == &con->writequeue) || - (PAGE_CACHE_SIZE - e->end < len)) { - e = NULL; - } else { - offset = e->end; - e->end += len; - users = e->users++; - } - spin_unlock(&con->writequeue_lock); - - if (e) { - got_one: - if (users == 0) - kmap(e->page); - *ppc = page_address(e->page) + offset; - return e; - } - - e = new_writequeue_entry(con, allocation); - if (e) { - spin_lock(&con->writequeue_lock); - offset = e->end; - e->end += len; - users = e->users++; - list_add_tail(&e->list, &con->writequeue); - spin_unlock(&con->writequeue_lock); - goto got_one; - } - return NULL; -} - -void lowcomms_commit_buffer(struct writequeue_entry *e) -{ - struct connection *con = e->con; - int users; - - if (!atomic_read(&accepting)) - return; - - spin_lock(&con->writequeue_lock); - users = --e->users; - if (users) - goto out; - e->len = e->end - e->offset; - kunmap(e->page); - spin_unlock(&con->writequeue_lock); - - if (test_and_set_bit(CF_WRITE_PENDING, &con->flags) == 0) { - spin_lock_bh(&write_sockets_lock); - list_add_tail(&con->write_list, &write_sockets); - spin_unlock_bh(&write_sockets_lock); - - wake_up_interruptible(&lowcomms_send_waitq); - } - return; - - out: - spin_unlock(&con->writequeue_lock); - return; -} - -static void free_entry(struct writequeue_entry *e) -{ - __free_page(e->page); - kfree(e); -} - -/* Send a message */ -static int send_to_sock(struct connection *con) -{ - int ret = 0; - ssize_t(*sendpage) (struct socket *, struct page *, int, size_t, int); - const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; - struct writequeue_entry *e; - int len, offset; - - down_read(&con->sock_sem); - if (con->sock == NULL) - goto out_connect; - - sendpage = con->sock->ops->sendpage; - - spin_lock(&con->writequeue_lock); - for (;;) { - e = list_entry(con->writequeue.next, struct writequeue_entry, - list); - if ((struct list_head *) e == &con->writequeue) - break; - - len = e->len; - offset = e->offset; - BUG_ON(len == 0 && e->users == 0); - spin_unlock(&con->writequeue_lock); - - ret = 0; - if (len) { - ret = sendpage(con->sock, e->page, offset, len, - msg_flags); - if (ret == -EAGAIN || ret == 0) - goto out; - if (ret <= 0) - goto send_error; - } - else { - /* Don't starve people filling buffers */ - schedule(); - } - - spin_lock(&con->writequeue_lock); - e->offset += ret; - e->len -= ret; - - if (e->len == 0 && e->users == 0) { - list_del(&e->list); - free_entry(e); - continue; - } - } - spin_unlock(&con->writequeue_lock); - out: - up_read(&con->sock_sem); - return ret; - - send_error: - up_read(&con->sock_sem); - close_connection(con, FALSE); - lowcomms_connect_sock(con); - return ret; - - out_connect: - up_read(&con->sock_sem); - lowcomms_connect_sock(con); - return 0; -} - -static void clean_one_writequeue(struct connection *con) -{ - struct list_head *list; - struct list_head *temp; - - spin_lock(&con->writequeue_lock); - list_for_each_safe(list, temp, &con->writequeue) { - struct writequeue_entry *e = - list_entry(list, struct writequeue_entry, list); - list_del(&e->list); - free_entry(e); - } - spin_unlock(&con->writequeue_lock); -} - -/* Called from recovery when it knows that a node has - left the cluster */ -int lowcomms_close(int nodeid) -{ - struct connection *con; - - if (!connections) - goto out; - - log_debug2("closing connection to node %d", nodeid); - con = nodeid2con(nodeid, 0); - if (con) { - clean_one_writequeue(con); - close_connection(con, TRUE); - atomic_set(&con->waiting_requests, 0); - } - return 0; - - out: - return -1; -} - -/* API send message call, may queue the request */ -/* N.B. This is the old interface - use the new one for new calls */ -int lowcomms_send_message(int nodeid, char *buf, int len, int allocation) -{ - struct writequeue_entry *e; - char *b; - - e = lowcomms_get_buffer(nodeid, len, allocation, &b); - if (e) { - memcpy(b, buf, len); - lowcomms_commit_buffer(e); - return 0; - } - return -ENOBUFS; -} - -/* Look for activity on active sockets */ -static void process_sockets(void) -{ - struct list_head *list; - struct list_head *temp; - int count = 0; - - spin_lock_bh(&read_sockets_lock); - list_for_each_safe(list, temp, &read_sockets) { - - struct connection *con = - list_entry(list, struct connection, read_list); - list_del(&con->read_list); - clear_bit(CF_READ_PENDING, &con->flags); - - spin_unlock_bh(&read_sockets_lock); - - /* This can reach zero if we are processing requests - * as they come in. - */ - if (atomic_read(&con->waiting_requests) == 0) { - spin_lock_bh(&read_sockets_lock); - continue; - } - - do { - con->rx_action(con); - - /* Don't starve out everyone else */ - if (++count >= MAX_RX_MSG_COUNT) { - schedule(); - count = 0; - } - - } while (!atomic_dec_and_test(&con->waiting_requests) && - !kthread_should_stop()); - - spin_lock_bh(&read_sockets_lock); - } - spin_unlock_bh(&read_sockets_lock); -} - -/* Try to send any messages that are pending - */ -static void process_output_queue(void) -{ - struct list_head *list; - struct list_head *temp; - int ret; - - spin_lock_bh(&write_sockets_lock); - list_for_each_safe(list, temp, &write_sockets) { - struct connection *con = - list_entry(list, struct connection, write_list); - clear_bit(CF_WRITE_PENDING, &con->flags); - list_del(&con->write_list); - - spin_unlock_bh(&write_sockets_lock); - - ret = send_to_sock(con); - if (ret < 0) { - } - spin_lock_bh(&write_sockets_lock); - } - spin_unlock_bh(&write_sockets_lock); -} - -static void process_state_queue(void) -{ - struct list_head *list; - struct list_head *temp; - int ret; - - spin_lock_bh(&state_sockets_lock); - list_for_each_safe(list, temp, &state_sockets) { - struct connection *con = - list_entry(list, struct connection, state_list); - list_del(&con->state_list); - clear_bit(CF_CONNECT_PENDING, &con->flags); - spin_unlock_bh(&state_sockets_lock); - - ret = connect_to_sock(con); - if (ret < 0) { - } - spin_lock_bh(&state_sockets_lock); - } - spin_unlock_bh(&state_sockets_lock); -} - - -/* Discard all entries on the write queues */ -static void clean_writequeues(void) -{ - int nodeid; - - for (nodeid = 1; nodeid < conn_array_size; nodeid++) { - struct connection *con = nodeid2con(nodeid, 0); - - if (con) - clean_one_writequeue(con); - } -} - -static int read_list_empty(void) -{ - int status; - - spin_lock_bh(&read_sockets_lock); - status = list_empty(&read_sockets); - spin_unlock_bh(&read_sockets_lock); - - return status; -} - -/* DLM Transport comms receive daemon */ -static int dlm_recvd(void *data) -{ - init_waitqueue_head(&lowcomms_recv_waitq); - init_waitqueue_entry(&lowcomms_recv_waitq_head, current); - add_wait_queue(&lowcomms_recv_waitq, &lowcomms_recv_waitq_head); - - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - if (read_list_empty()) - schedule(); - set_current_state(TASK_RUNNING); - - process_sockets(); - } - - return 0; -} - -static int write_and_state_lists_empty(void) -{ - int status; - - spin_lock_bh(&write_sockets_lock); - status = list_empty(&write_sockets); - spin_unlock_bh(&write_sockets_lock); - - spin_lock_bh(&state_sockets_lock); - if (list_empty(&state_sockets) == 0) - status = 0; - spin_unlock_bh(&state_sockets_lock); - - return status; -} - -/* DLM Transport send daemon */ -static int dlm_sendd(void *data) -{ - init_waitqueue_head(&lowcomms_send_waitq); - init_waitqueue_entry(&lowcomms_send_waitq_head, current); - add_wait_queue(&lowcomms_send_waitq, &lowcomms_send_waitq_head); - - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - if (write_and_state_lists_empty()) - schedule(); - set_current_state(TASK_RUNNING); - - process_state_queue(); - process_output_queue(); - } - - return 0; -} - -static void daemons_stop(void) -{ - kthread_stop(recv_task); - kthread_stop(send_task); -} - -static int daemons_start(void) -{ - struct task_struct *p; - int error; - - p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); - error = IS_ERR(p); - if (error) { - log_print("can't start dlm_recvd %d", error); - return error; - } - recv_task = p; - - p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); - error = IS_ERR(p); - if (error) { - log_print("can't start dlm_sendd %d", error); - kthread_stop(recv_task); - return error; - } - send_task = p; - - return 0; -} - -/* - * Return the largest buffer size we can cope with. - */ -int lowcomms_max_buffer_size(void) -{ - return PAGE_CACHE_SIZE; -} - -void lowcomms_stop(void) -{ - int i; - struct connection *temp; - struct connection *lcon; - - atomic_set(&accepting, 0); - - /* Set all the activity flags to prevent any - socket activity. - */ - for (i = 0; i < conn_array_size; i++) { - if (connections[i]) - connections[i]->flags |= 0x7; - } - daemons_stop(); - clean_writequeues(); - - for (i = 0; i < conn_array_size; i++) { - if (connections[i]) { - close_connection(connections[i], TRUE); - kmem_cache_free(con_cache, connections[i]); - if (connections[i]->othercon) - kmem_cache_free(con_cache, connections[i]->othercon); - } - } - - kfree(connections); - connections = NULL; - - /* Free up any dynamically allocated listening sockets */ - list_for_each_entry_safe(lcon, temp, &listen_sockets, listenlist) { - sock_release(lcon->sock); - kmem_cache_free(con_cache, lcon); - } - - kmem_cache_destroy(con_cache); - kcl_releaseref_cluster(); - our_nodeid = 0; -} - -/* This is quite likely to sleep... */ -int lowcomms_start(void) -{ - int error = 0; - struct connection *temp; - struct connection *lcon; - - INIT_LIST_HEAD(&read_sockets); - INIT_LIST_HEAD(&write_sockets); - INIT_LIST_HEAD(&state_sockets); - INIT_LIST_HEAD(&listen_sockets); - - spin_lock_init(&read_sockets_lock); - spin_lock_init(&write_sockets_lock); - spin_lock_init(&state_sockets_lock); - init_MUTEX(&connections_lock); - - error = -ENOTCONN; - if (kcl_addref_cluster()) - goto out; - - /* - * Temporarily initialise the waitq head so that lowcomms_send_message - * doesn't crash if it gets called before the thread is fully - * initialised - */ - init_waitqueue_head(&lowcomms_send_waitq); - - error = -ENOMEM; - connections = kmalloc(sizeof(struct connection *) * - dlm_config.conn_increment, GFP_KERNEL); - if (!connections) - goto out; - - memset(connections, 0, - sizeof(struct connection *) * dlm_config.conn_increment); - - conn_array_size = dlm_config.conn_increment; - - con_cache = kmem_cache_create("dlm_conn", sizeof(struct connection), - __alignof__(struct connection), 0, NULL, NULL); - if (!con_cache) - goto fail_free_conn; - - - /* Start listening */ - error = listen_for_all(); - if (error) - goto fail_unlisten; - - error = daemons_start(); - if (error) - goto fail_unlisten; - - atomic_set(&accepting, 1); - - return 0; - - fail_unlisten: - close_connection(connections[0], 0); - kmem_cache_free(con_cache, connections[0]); - list_for_each_entry_safe(lcon, temp, &listen_sockets, listenlist) { - sock_release(lcon->sock); - kmem_cache_free(con_cache, lcon); - } - - kmem_cache_destroy(con_cache); - - fail_free_conn: - kcl_releaseref_cluster(); - kfree(connections); - - out: - return error; -} - -/* Don't accept any more outgoing work */ -void lowcomms_stop_accept() -{ - atomic_set(&accepting, 0); -} - -/* Cluster Manager interface functions for looking up - nodeids and IP addresses by each other -*/ - -/* Return the IP address of a node given its NODEID */ -static int lowcomms_ipaddr_from_nodeid(int nodeid, struct sockaddr *retaddr) -{ - struct list_head *addrs; - struct cluster_node_addr *node_addr; - struct cluster_node_addr *current_addr = NULL; - struct sockaddr_in6 *saddr; - int interface; - int i; - - addrs = kcl_get_node_addresses(nodeid); - if (!addrs) - return -1; - - interface = kcl_get_current_interface(); - - /* Look for address number <interface> */ - i=0; /* i/f numbers start at 1 */ - list_for_each_entry(node_addr, addrs, list) { - if (interface == ++i) { - current_addr = node_addr; - break; - } - } - - /* If that failed then just use the first one */ - if (!current_addr) - current_addr = (struct cluster_node_addr *)addrs->next; - - saddr = (struct sockaddr_in6 *)current_addr->addr; - - /* Extract the IP address */ - if (local_addr.sin6_family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *)saddr; - struct sockaddr_in *ret4 = (struct sockaddr_in *)retaddr; - ret4->sin_addr.s_addr = in4->sin_addr.s_addr; - } - else { - struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *)retaddr; - memcpy(&ret6->sin6_addr, &saddr->sin6_addr, sizeof(saddr->sin6_addr)); - } - - return 0; -} - -/* Return the NODEID for a node given its sockaddr */ -static int lowcomms_nodeid_from_ipaddr(struct sockaddr *addr, int addr_len) -{ - struct kcl_cluster_node node; - struct sockaddr_in6 ipv6_addr; - struct sockaddr_in ipv4_addr; - - if (local_addr.sin6_family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *)addr; - memcpy(&ipv4_addr, &local_addr, addr_len); - memcpy(&ipv4_addr.sin_addr, &in4->sin_addr, sizeof(ipv4_addr.sin_addr)); - - addr = (struct sockaddr *)&ipv4_addr; - } - else { - struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; - memcpy(&ipv6_addr, &local_addr, addr_len); - memcpy(&ipv6_addr.sin6_addr, &in6->sin6_addr, sizeof(ipv6_addr.sin6_addr)); - - addr = (struct sockaddr *)&ipv6_addr; - } - - if (kcl_get_node_by_addr((char *)addr, addr_len, &node) == 0) - return node.node_id; - else - return 0; -} - -int lowcomms_our_nodeid(void) -{ - struct kcl_cluster_node node; - struct list_head *addrs; - struct cluster_node_addr *first_addr; - - if (our_nodeid) - return our_nodeid; - - if (kcl_get_node_by_nodeid(0, &node) == -1) - return 0; - - our_nodeid = node.node_id; - - /* Fill in the "template" structure */ - addrs = kcl_get_node_addresses(our_nodeid); - if (!addrs) - return 0; - - first_addr = (struct cluster_node_addr *) addrs->next; - memcpy(&local_addr, &first_addr->addr, first_addr->addr_len); - - return node.node_id; -} -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/dlm-kernel/src/lowcomms.h b/dlm-kernel/src/lowcomms.h deleted file mode 100644 index f705b98..0000000 --- a/dlm-kernel/src/lowcomms.h +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOWCOMMS_DOT_H__ -#define __LOWCOMMS_DOT_H__ - -/* The old interface */ -int lowcomms_send_message(int csid, char *buf, int len, int allocation); - -/* The new interface */ -struct writequeue_entry; -extern struct writequeue_entry *lowcomms_get_buffer(int nodeid, int len, - int allocation, char **ppc); -extern void lowcomms_commit_buffer(struct writequeue_entry *e); - -int lowcomms_start(void); -void lowcomms_stop(void); -void lowcomms_stop_accept(void); -int lowcomms_close(int nodeid); -int lowcomms_max_buffer_size(void); - -int lowcomms_our_nodeid(void); - -#endif /* __LOWCOMMS_DOT_H__ */ diff --git a/dlm-kernel/src/main.c b/dlm-kernel/src/main.c deleted file mode 100644 index 85483d6..0000000 --- a/dlm-kernel/src/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#define EXPORT_SYMTAB - -#include <linux/init.h> -#include <linux/proc_fs.h> -#include <linux/ctype.h> -#include <linux/module.h> -#include <net/sock.h> - -#include <cluster/cnxman.h> - -#include "dlm_internal.h" -#include "lockspace.h" -#include "ast.h" -#include "lkb.h" -#include "nodes.h" -#include "locking.h" -#include "config.h" -#include "memory.h" -#include "recover.h" -#include "lowcomms.h" - -int dlm_device_init(void); -void dlm_device_exit(void); -void dlm_proc_init(void); -void dlm_proc_exit(void); - - -/* Cluster manager callbacks, we want to know if a node dies - N.B. this is independent of lockspace-specific event callbacks from SM */ - -static void cman_callback(kcl_callback_reason reason, long arg) -{ - /* This is unconditional. so do what we can to tidy up */ - if (reason == LEAVING) { - dlm_emergency_shutdown(); - } -} - -int __init init_dlm(void) -{ - dlm_proc_init(); - dlm_lockspace_init(); - dlm_nodes_init(); - dlm_device_init(); - dlm_memory_init(); - dlm_config_init(); - - kcl_add_callback(cman_callback); - - printk("DLM %s (built %s %s) installed\n", - DLM_RELEASE_NAME, __DATE__, __TIME__); - - return 0; -} - -void __exit exit_dlm(void) -{ - kcl_remove_callback(cman_callback); - - dlm_device_exit(); - dlm_memory_exit(); - dlm_config_exit(); - dlm_proc_exit(); -} - -MODULE_DESCRIPTION("Distributed Lock Manager " DLM_RELEASE_NAME); -MODULE_AUTHOR("Red Hat, Inc."); -MODULE_LICENSE("GPL"); - -module_init(init_dlm); -module_exit(exit_dlm); - -EXPORT_SYMBOL(dlm_init); -EXPORT_SYMBOL(dlm_release); -EXPORT_SYMBOL(dlm_new_lockspace); -EXPORT_SYMBOL(dlm_release_lockspace); -EXPORT_SYMBOL(dlm_lock); -EXPORT_SYMBOL(dlm_unlock); -EXPORT_SYMBOL(dlm_debug_dump); -EXPORT_SYMBOL(dlm_locks_dump); diff --git a/dlm-kernel/src/memory.c b/dlm-kernel/src/memory.c deleted file mode 100644 index 176b9dc..0000000 --- a/dlm-kernel/src/memory.c +++ /dev/null @@ -1,238 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* memory.c - * - * memory allocation routines - * - */ - -#include "dlm_internal.h" -#include "memory.h" -#include "config.h" - -/* as the man says...Shouldn't this be in a header file somewhere? */ -#define BYTES_PER_WORD sizeof(void *) - -static kmem_cache_t *rsb_cache_small; -static kmem_cache_t *rsb_cache_large; -static kmem_cache_t *lkb_cache; -static kmem_cache_t *lvb_cache; -static kmem_cache_t *resdir_cache_large; -static kmem_cache_t *resdir_cache_small; - -/* The thresholds above which we allocate large RSBs/direntry rather than small - * ones. This must make the resultant structure end on a word boundary */ -#define LARGE_RSB_NAME 28 -#define LARGE_RES_NAME 28 - -int dlm_memory_init() -{ - int ret = -ENOMEM; - - - rsb_cache_small = - kmem_cache_create("dlm_rsb(small)", - (sizeof(struct dlm_rsb) + LARGE_RSB_NAME + BYTES_PER_WORD-1) & ~(BYTES_PER_WORD-1), - __alignof__(struct dlm_rsb), 0, NULL, NULL); - if (!rsb_cache_small) - goto out; - - rsb_cache_large = - kmem_cache_create("dlm_rsb(large)", - sizeof(struct dlm_rsb) + DLM_RESNAME_MAXLEN, - __alignof__(struct dlm_rsb), 0, NULL, NULL); - if (!rsb_cache_large) - goto out_free_rsbs; - - lkb_cache = kmem_cache_create("dlm_lkb", sizeof(struct dlm_lkb), - __alignof__(struct dlm_lkb), 0, NULL, NULL); - if (!lkb_cache) - goto out_free_rsbl; - - resdir_cache_large = - kmem_cache_create("dlm_resdir(l)", - sizeof(struct dlm_direntry) + DLM_RESNAME_MAXLEN, - __alignof__(struct dlm_direntry), 0, NULL, NULL); - if (!resdir_cache_large) - goto out_free_lkb; - - resdir_cache_small = - kmem_cache_create("dlm_resdir(s)", - (sizeof(struct dlm_direntry) + LARGE_RES_NAME + BYTES_PER_WORD-1) & ~(BYTES_PER_WORD-1), - __alignof__(struct dlm_direntry), 0, NULL, NULL); - if (!resdir_cache_small) - goto out_free_resl; - - /* LVB cache also holds ranges, so should be 64bit aligned */ - lvb_cache = kmem_cache_create("dlm_lvb/range", DLM_LVB_LEN, - __alignof__(uint64_t), 0, NULL, NULL); - if (!lkb_cache) - goto out_free_ress; - - ret = 0; - goto out; - - out_free_ress: - kmem_cache_destroy(resdir_cache_small); - - out_free_resl: - kmem_cache_destroy(resdir_cache_large); - - out_free_lkb: - kmem_cache_destroy(lkb_cache); - - out_free_rsbl: - kmem_cache_destroy(rsb_cache_large); - - out_free_rsbs: - kmem_cache_destroy(rsb_cache_small); - - out: - return ret; -} - -void dlm_memory_exit() -{ - kmem_cache_destroy(rsb_cache_large); - kmem_cache_destroy(rsb_cache_small); - kmem_cache_destroy(lkb_cache); - kmem_cache_destroy(resdir_cache_small); - kmem_cache_destroy(resdir_cache_large); - kmem_cache_destroy(lvb_cache); -} - -struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen) -{ - struct dlm_rsb *r; - - DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,); - - if (namelen >= LARGE_RSB_NAME) - r = kmem_cache_alloc(rsb_cache_large, ls->ls_allocation); - else - r = kmem_cache_alloc(rsb_cache_small, ls->ls_allocation); - - if (r) - memset(r, 0, sizeof(struct dlm_rsb) + namelen); - - return r; -} - -void free_rsb(struct dlm_rsb *r) -{ - int length = r->res_length; - -#ifdef POISON - memset(r, 0x55, sizeof(struct dlm_rsb) + r->res_length); -#endif - - if (length >= LARGE_RSB_NAME) - kmem_cache_free(rsb_cache_large, r); - else - kmem_cache_free(rsb_cache_small, r); -} - -struct dlm_lkb *allocate_lkb(struct dlm_ls *ls) -{ - struct dlm_lkb *l; - - l = kmem_cache_alloc(lkb_cache, ls->ls_allocation); - if (l) - memset(l, 0, sizeof(struct dlm_lkb)); - - return l; -} - -void free_lkb(struct dlm_lkb *l) -{ -#ifdef POISON - memset(l, 0xAA, sizeof(struct dlm_lkb)); -#endif - kmem_cache_free(lkb_cache, l); -} - -struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen) -{ - struct dlm_direntry *rd; - - DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,); - - if (namelen >= LARGE_RES_NAME) - rd = kmem_cache_alloc(resdir_cache_large, ls->ls_allocation); - else - rd = kmem_cache_alloc(resdir_cache_small, ls->ls_allocation); - - if (rd) - memset(rd, 0, sizeof(struct dlm_direntry)); - - return rd; -} - -void free_direntry(struct dlm_direntry *de) -{ - if (de->length >= LARGE_RES_NAME) - kmem_cache_free(resdir_cache_large, de); - else - kmem_cache_free(resdir_cache_small, de); -} - -char *allocate_lvb(struct dlm_ls *ls) -{ - char *l; - - l = kmem_cache_alloc(lvb_cache, ls->ls_allocation); - if (l) - memset(l, 0, DLM_LVB_LEN); - - return l; -} - -void free_lvb(char *l) -{ - kmem_cache_free(lvb_cache, l); -} - -/* Ranges are allocated from the LVB cache as they are the same size (4x64 - * bits) */ -uint64_t *allocate_range(struct dlm_ls * ls) -{ - uint64_t *l; - - l = kmem_cache_alloc(lvb_cache, ls->ls_allocation); - if (l) - memset(l, 0, DLM_LVB_LEN); - - return l; -} - -void free_range(uint64_t *l) -{ - kmem_cache_free(lvb_cache, l); -} - -struct dlm_rcom *allocate_rcom_buffer(struct dlm_ls *ls) -{ - struct dlm_rcom *rc; - - rc = kmalloc(dlm_config.buffer_size, ls->ls_allocation); - if (rc) - memset(rc, 0, dlm_config.buffer_size); - - return rc; -} - -void free_rcom_buffer(struct dlm_rcom *rc) -{ - kfree(rc); -} diff --git a/dlm-kernel/src/memory.h b/dlm-kernel/src/memory.h deleted file mode 100644 index 4722cb4..0000000 --- a/dlm-kernel/src/memory.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __MEMORY_DOT_H__ -#define __MEMORY_DOT_H__ - -int dlm_memory_init(void); -void dlm_memory_exit(void); -struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen); -void free_rsb(struct dlm_rsb *r); -struct dlm_lkb *allocate_lkb(struct dlm_ls *ls); -void free_lkb(struct dlm_lkb *l); -struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen); -void free_direntry(struct dlm_direntry *de); -char *allocate_lvb(struct dlm_ls *ls); -void free_lvb(char *l); -struct dlm_rcom *allocate_rcom_buffer(struct dlm_ls *ls); -void free_rcom_buffer(struct dlm_rcom *rc); -uint64_t *allocate_range(struct dlm_ls *ls); -void free_range(uint64_t *l); - -#endif /* __MEMORY_DOT_H__ */ diff --git a/dlm-kernel/src/midcomms.c b/dlm-kernel/src/midcomms.c deleted file mode 100644 index 992dc61..0000000 --- a/dlm-kernel/src/midcomms.c +++ /dev/null @@ -1,380 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * midcomms.c - * - * This is the appallingly named "mid-level" comms layer. - * - * Its purpose is to take packets from the "real" comms layer, - * split them up into packets and pass them to the interested - * part of the locking mechanism. - * - * It also takes messages from the locking layer, formats them - * into packets and sends them to the comms layer. - * - * It knows the format of the mid-level messages used and nodeidss - * but it does not know how to resolve a nodeid into an IP address - * or any of the comms channel details - * - */ - -#include "dlm_internal.h" -#include "lowcomms.h" -#include "midcomms.h" -#include "lockqueue.h" -#include "nodes.h" -#include "reccomms.h" -#include "config.h" - -/* Byteorder routines */ - -static void host_to_network(void *msg) -{ - struct dlm_header *head = msg; - struct dlm_request *req = msg; - struct dlm_reply *rep = msg; - struct dlm_query_request *qreq = msg; - struct dlm_query_reply *qrep= msg; - struct dlm_rcom *rc = msg; - - /* Force into network byte order */ - - /* - * Do the common header first - */ - - head->rh_version = cpu_to_le32(head->rh_version); - head->rh_length = cpu_to_le16(head->rh_length); - head->rh_lockspace = cpu_to_le32(head->rh_lockspace); - /* Leave the lkid alone as it is transparent at the remote end */ - - /* - * Do the fields in the remlockrequest or remlockreply structs - */ - - switch (req->rr_header.rh_cmd) { - - case GDLM_REMCMD_PURGE: - req->rr_pid = cpu_to_le32(req->rr_pid); - break; - case GDLM_REMCMD_LOCKREQUEST: - case GDLM_REMCMD_CONVREQUEST: - req->rr_range_start = cpu_to_le64(req->rr_range_start); - req->rr_range_end = cpu_to_le64(req->rr_range_end); - /* Deliberate fall through */ - case GDLM_REMCMD_UNLOCKREQUEST: - case GDLM_REMCMD_LOOKUP: - case GDLM_REMCMD_LOCKGRANT: - case GDLM_REMCMD_SENDBAST: - case GDLM_REMCMD_SENDCAST: - case GDLM_REMCMD_REM_RESDATA: - req->rr_flags = cpu_to_le32(req->rr_flags); - req->rr_status = cpu_to_le32(req->rr_status); - req->rr_lvbseq = cpu_to_le32(req->rr_lvbseq); - break; - - case GDLM_REMCMD_LOCKREPLY: - rep->rl_lockstate = cpu_to_le32(rep->rl_lockstate); - rep->rl_nodeid = cpu_to_le32(rep->rl_nodeid); - rep->rl_status = cpu_to_le32(rep->rl_status); - rep->rl_flags = cpu_to_le32(rep->rl_flags); - rep->rl_lvbseq = cpu_to_le32(rep->rl_lvbseq); - break; - - case GDLM_REMCMD_RECOVERMESSAGE: - case GDLM_REMCMD_RECOVERREPLY: - rc->rc_msgid = cpu_to_le32(rc->rc_msgid); - rc->rc_datalen = cpu_to_le16(rc->rc_datalen); - break; - - case GDLM_REMCMD_QUERY: - qreq->rq_mstlkid = cpu_to_le32(qreq->rq_mstlkid); - qreq->rq_query = cpu_to_le32(qreq->rq_query); - qreq->rq_maxlocks = cpu_to_le32(qreq->rq_maxlocks); - break; - - case GDLM_REMCMD_QUERYREPLY: - qrep->rq_numlocks = cpu_to_le32(qrep->rq_numlocks); - qrep->rq_status = cpu_to_le32(qrep->rq_status); - qrep->rq_grantcount = cpu_to_le32(qrep->rq_grantcount); - qrep->rq_waitcount = cpu_to_le32(qrep->rq_waitcount); - qrep->rq_convcount = cpu_to_le32(qrep->rq_convcount); - break; - - default: - printk("dlm: warning, unknown REMCMD type %u\n", - req->rr_header.rh_cmd); - } -} - -static void network_to_host(void *msg) -{ - struct dlm_header *head = msg; - struct dlm_request *req = msg; - struct dlm_reply *rep = msg; - struct dlm_query_request *qreq = msg; - struct dlm_query_reply *qrep = msg; - struct dlm_rcom *rc = msg; - - /* Force into host byte order */ - - /* - * Do the common header first - */ - - head->rh_version = le32_to_cpu(head->rh_version); - - if ((head->rh_version & 0xFFFF0000) != DLM_HEADER_MAJOR) { - printk("dlm: midcomms: bad header version %x\n", - head->rh_version); - head->rh_cmd = 0; - return; - } - - head->rh_length = le16_to_cpu(head->rh_length); - head->rh_lockspace = le32_to_cpu(head->rh_lockspace); - /* Leave the lkid alone as it is transparent at the remote end */ - - /* - * Do the fields in the remlockrequest or remlockreply structs - */ - - switch (req->rr_header.rh_cmd) { - - case GDLM_REMCMD_PURGE: - req->rr_pid = le32_to_cpu(req->rr_pid); - break; - - case GDLM_REMCMD_LOCKREQUEST: - case GDLM_REMCMD_CONVREQUEST: - req->rr_range_start = le64_to_cpu(req->rr_range_start); - req->rr_range_end = le64_to_cpu(req->rr_range_end); - case GDLM_REMCMD_LOOKUP: - case GDLM_REMCMD_UNLOCKREQUEST: - case GDLM_REMCMD_LOCKGRANT: - case GDLM_REMCMD_SENDBAST: - case GDLM_REMCMD_SENDCAST: - case GDLM_REMCMD_REM_RESDATA: - /* Actually, not much to do here as the remote lock IDs are - * transparent too */ - req->rr_flags = le32_to_cpu(req->rr_flags); - req->rr_status = le32_to_cpu(req->rr_status); - req->rr_lvbseq = le32_to_cpu(req->rr_lvbseq); - break; - - case GDLM_REMCMD_LOCKREPLY: - rep->rl_lockstate = le32_to_cpu(rep->rl_lockstate); - rep->rl_nodeid = le32_to_cpu(rep->rl_nodeid); - rep->rl_status = le32_to_cpu(rep->rl_status); - rep->rl_flags = le32_to_cpu(rep->rl_flags); - rep->rl_lvbseq = le32_to_cpu(rep->rl_lvbseq); - break; - - case GDLM_REMCMD_RECOVERMESSAGE: - case GDLM_REMCMD_RECOVERREPLY: - rc->rc_msgid = le32_to_cpu(rc->rc_msgid); - rc->rc_datalen = le16_to_cpu(rc->rc_datalen); - break; - - - case GDLM_REMCMD_QUERY: - qreq->rq_mstlkid = le32_to_cpu(qreq->rq_mstlkid); - qreq->rq_query = le32_to_cpu(qreq->rq_query); - qreq->rq_maxlocks = le32_to_cpu(qreq->rq_maxlocks); - break; - - case GDLM_REMCMD_QUERYREPLY: - qrep->rq_numlocks = le32_to_cpu(qrep->rq_numlocks); - qrep->rq_status = le32_to_cpu(qrep->rq_status); - qrep->rq_grantcount = le32_to_cpu(qrep->rq_grantcount); - qrep->rq_waitcount = le32_to_cpu(qrep->rq_waitcount); - qrep->rq_convcount = le32_to_cpu(qrep->rq_convcount); - break; - - default: - printk("dlm: warning, unknown REMCMD type %u\n", - req->rr_header.rh_cmd); - } -} - -static void copy_from_cb(void *dst, const void *base, unsigned offset, - unsigned len, unsigned limit) -{ - unsigned copy = len; - - if ((copy + offset) > limit) - copy = limit - offset; - memcpy(dst, base + offset, copy); - len -= copy; - if (len) - memcpy(dst + copy, base, len); -} - -static void khexdump(const unsigned char *c, int len) -{ - while (len > 16) { - printk(KERN_INFO - "%02x %02x %02x %02x %02x %02x %02x %02x-%02x %02x %02x %02x %02x %02x %02x %02x\n", - c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], - c[9], c[10], c[11], c[12], c[13], c[14], c[15]); - len -= 16; - c += 16; - } - while (len > 4) { - printk(KERN_INFO "%02x %02x %02x %02x\n", c[0], c[1], c[2], - c[3]); - len -= 4; - c += 4; - } - while (len > 0) { - printk(KERN_INFO "%02x\n", c[0]); - len--; - c++; - } -} - -/* - * Called from the low-level comms layer to process a buffer of - * commands. - * - * Only complete messages are processed here, any "spare" bytes from - * the end of a buffer are saved and tacked onto the front of the next - * message that comes in. I doubt this will happen very often but we - * need to be able to cope with it and I don't want the task to be waiting - * for packets to come in when there is useful work to be done. - * - */ -int midcomms_process_incoming_buffer(int nodeid, const void *base, - unsigned offset, unsigned len, - unsigned limit) -{ - unsigned char __tmp[sizeof(struct dlm_header) + 64]; - struct dlm_header *msg = (struct dlm_header *) __tmp; - int ret = 0; - int err = 0; - unsigned msglen; - __u32 id, space; - - while (len > sizeof(struct dlm_header)) { - /* Get message header and check it over */ - copy_from_cb(msg, base, offset, sizeof(struct dlm_header), - limit); - msglen = le16_to_cpu(msg->rh_length); - id = msg->rh_lkid; - space = msg->rh_lockspace; - - /* Check message size */ - err = -EINVAL; - if (msglen < sizeof(struct dlm_header)) - break; - err = -E2BIG; - if (msglen > dlm_config.buffer_size) { - printk("dlm: message size from %d too big %d(pkt len=%d)\n", nodeid, msglen, len); - khexdump((const unsigned char *) msg, len); - break; - } - err = 0; - - /* Not enough in buffer yet? wait for some more */ - if (msglen > len) - break; - - /* Make sure our temp buffer is large enough */ - if (msglen > sizeof(__tmp) && - msg == (struct dlm_header *) __tmp) { - msg = kmalloc(dlm_config.buffer_size, GFP_KERNEL); - if (msg == NULL) - return ret; - } - - copy_from_cb(msg, base, offset, msglen, limit); - BUG_ON(id != msg->rh_lkid); - BUG_ON(space != msg->rh_lockspace); - ret += msglen; - offset += msglen; - offset &= (limit - 1); - len -= msglen; - network_to_host(msg); - - if ((msg->rh_cmd > 32) || - (msg->rh_cmd == 0) || - (msg->rh_length < sizeof(struct dlm_header)) || - (msg->rh_length > dlm_config.buffer_size)) { - - printk("dlm: midcomms: cmd=%u, flags=%u, length=%hu, " - "lkid=%u, lockspace=%u\n", - msg->rh_cmd, msg->rh_flags, msg->rh_length, - msg->rh_lkid, msg->rh_lockspace); - - printk("dlm: midcomms: base=%p, offset=%u, len=%u, " - "ret=%u, limit=%08x newbuf=%d\n", - base, offset, len, ret, limit, - ((struct dlm_header *) __tmp == msg)); - - khexdump((const unsigned char *) msg, msg->rh_length); - - return -EBADMSG; - } - - switch (msg->rh_cmd) { - case GDLM_REMCMD_RECOVERMESSAGE: - case GDLM_REMCMD_RECOVERREPLY: - process_recovery_comm(nodeid, msg); - break; - default: - process_cluster_request(nodeid, msg, FALSE); - } - } - - if (msg != (struct dlm_header *) __tmp) - kfree(msg); - - return err ? err : ret; -} - -/* - * Send a lowcomms buffer - */ - -void midcomms_send_buffer(struct dlm_header *msg, struct writequeue_entry *e) -{ - msg->rh_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR); - host_to_network(msg); - lowcomms_commit_buffer(e); -} - -/* - * Make the message into network byte order and send it - */ - -int midcomms_send_message(uint32_t nodeid, struct dlm_header *msg, - int allocation) -{ - int len = msg->rh_length; - - msg->rh_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR); - host_to_network(msg); - - /* - * Loopback. In fact, the locking code pretty much prevents this from - * being needed but it can happen when the directory node is also the - * local node. - */ - - if (nodeid == our_nodeid()) - return midcomms_process_incoming_buffer(nodeid, (char *) msg, 0, - len, len); - - return lowcomms_send_message(nodeid, (char *) msg, len, allocation); -} diff --git a/dlm-kernel/src/midcomms.h b/dlm-kernel/src/midcomms.h deleted file mode 100644 index d31dde2..0000000 --- a/dlm-kernel/src/midcomms.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __MIDCOMMS_DOT_H__ -#define __MIDCOMMS_DOT_H__ - -int midcomms_send_message(uint32_t csid, struct dlm_header *msg, - int allocation); -int midcomms_process_incoming_buffer(int csid, const void *buf, unsigned offset, - unsigned len, unsigned limit); -void midcomms_send_buffer(struct dlm_header *msg, - struct writequeue_entry *e); - -#endif /* __MIDCOMMS_DOT_H__ */ diff --git a/dlm-kernel/src/nodes.c b/dlm-kernel/src/nodes.c deleted file mode 100644 index a3fd690..0000000 --- a/dlm-kernel/src/nodes.c +++ /dev/null @@ -1,366 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <net/sock.h> -#include <cluster/cnxman.h> - -#include "dlm_internal.h" -#include "lowcomms.h" -#include "nodes.h" -#include "recover.h" -#include "reccomms.h" -#include "util.h" - -static struct list_head cluster_nodes; -static spinlock_t node_lock; - - -void dlm_nodes_init(void) -{ - INIT_LIST_HEAD(&cluster_nodes); - spin_lock_init(&node_lock); -} - -static struct dlm_node *search_node(uint32_t nodeid) -{ - struct dlm_node *node; - - list_for_each_entry(node, &cluster_nodes, list) { - if (node->nodeid == nodeid) - goto out; - } - node = NULL; - out: - return node; -} - -static void put_node(struct dlm_node *node) -{ - spin_lock(&node_lock); - if (atomic_dec_and_test(&node->refcount)) { - list_del(&node->list); - spin_unlock(&node_lock); - lowcomms_close(node->nodeid); - kfree(node); - return; - } - spin_unlock(&node_lock); -} - -static int get_node(uint32_t nodeid, struct dlm_node **ndp) -{ - struct dlm_node *node, *node2; - int error = -ENOMEM; - - spin_lock(&node_lock); - node = search_node(nodeid); - if (node) - atomic_inc(&node->refcount); - spin_unlock(&node_lock); - - if (node) - goto out; - - node = kmalloc(sizeof(struct dlm_node), GFP_KERNEL); - if (!node) - goto fail; - - memset(node, 0, sizeof(struct dlm_node)); - node->nodeid = nodeid; - - spin_lock(&node_lock); - node2 = search_node(nodeid); - if (node2) { - atomic_inc(&node2->refcount); - spin_unlock(&node_lock); - kfree(node); - node = node2; - goto out; - } - - atomic_set(&node->refcount, 1); - list_add_tail(&node->list, &cluster_nodes); - spin_unlock(&node_lock); - - out: - *ndp = node; - return 0; - fail: - return error; -} - -int init_new_csb(uint32_t nodeid, struct dlm_csb **ret_csb) -{ - struct dlm_csb *csb; - struct dlm_node *node; - int error = -ENOMEM; - - csb = kmalloc(sizeof(struct dlm_csb), GFP_KERNEL); - if (!csb) - goto fail; - - memset(csb, 0, sizeof(struct dlm_csb)); - - error = get_node(nodeid, &node); - if (error) - goto fail_free; - - csb->node = node; - *ret_csb = csb; - return 0; - - fail_free: - kfree(csb); - fail: - return error; -} - -void release_csb(struct dlm_csb *csb) -{ - put_node(csb->node); - kfree(csb); -} - -uint32_t our_nodeid(void) -{ - return lowcomms_our_nodeid(); -} - -static void make_node_array(struct dlm_ls *ls) -{ - struct dlm_csb *csb; - uint32_t *array; - int i = 0; - - if (ls->ls_node_array) { - kfree(ls->ls_node_array); - ls->ls_node_array = NULL; - } - - array = kmalloc(sizeof(uint32_t) * ls->ls_num_nodes, GFP_KERNEL); - if (!array) - return; - - list_for_each_entry(csb, &ls->ls_nodes, list) - array[i++] = csb->node->nodeid; - - ls->ls_node_array = array; -} - -int nodes_reconfig_wait(struct dlm_ls *ls) -{ - int error; - - if (ls->ls_low_nodeid == our_nodeid()) { - error = dlm_wait_status_all(ls, NODES_VALID); - if (!error) - set_bit(LSFL_ALL_NODES_VALID, &ls->ls_flags); - - /* Experimental: this delay should allow any final messages - * from the previous node to be received before beginning - * recovery. */ - - if (ls->ls_num_nodes == 1) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout((2) * HZ); - } - - } else - error = dlm_wait_status_low(ls, NODES_ALL_VALID); - - return error; -} - -static void add_ordered_node(struct dlm_ls *ls, struct dlm_csb *new) -{ - struct dlm_csb *csb = NULL; - struct list_head *tmp; - struct list_head *newlist = &new->list; - struct list_head *head = &ls->ls_nodes; - - list_for_each(tmp, head) { - csb = list_entry(tmp, struct dlm_csb, list); - - if (new->node->nodeid < csb->node->nodeid) - break; - } - - if (!csb) - list_add_tail(newlist, head); - else { - /* FIXME: can use list macro here */ - newlist->prev = tmp->prev; - newlist->next = tmp; - tmp->prev->next = newlist; - tmp->prev = newlist; - } -} - -int ls_nodes_reconfig(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) -{ - struct dlm_csb *csb, *safe; - int error, i, found, pos = 0, neg = 0; - uint32_t low = (uint32_t) (-1); - - /* - * Remove (and save) departed nodes from lockspace's nodes list - */ - - list_for_each_entry_safe(csb, safe, &ls->ls_nodes, list) { - found = FALSE; - for (i = 0; i < rv->node_count; i++) { - if (csb->node->nodeid == rv->nodeids[i]) { - found = TRUE; - break; - } - } - - if (!found) { - neg++; - csb->gone_event = rv->event_id; - spin_lock(&ls->ls_nodes_gone_spin); - list_del(&csb->list); - list_add_tail(&csb->list, &ls->ls_nodes_gone); - spin_unlock(&ls->ls_nodes_gone_spin); - ls->ls_num_nodes--; - log_debug(ls, "remove node %u", csb->node->nodeid); - } - } - - /* - * Add new nodes to lockspace's nodes list - */ - - for (i = 0; i < rv->node_count; i++) { - found = FALSE; - list_for_each_entry(csb, &ls->ls_nodes, list) { - if (csb->node->nodeid == rv->nodeids[i]) { - found = TRUE; - break; - } - } - - if (!found) { - pos++; - - error = init_new_csb(rv->nodeids[i], &csb); - DLM_ASSERT(!error,); - - add_ordered_node(ls, csb); - ls->ls_num_nodes++; - log_debug(ls, "add node %u", csb->node->nodeid); - } - } - - list_for_each_entry(csb, &ls->ls_nodes, list) { - if (csb->node->nodeid < low) - low = csb->node->nodeid; - } - - ls->ls_low_nodeid = low; - *neg_out = neg; - make_node_array(ls); - set_bit(LSFL_NODES_VALID, &ls->ls_flags); - - error = nodes_reconfig_wait(ls); - - log_debug(ls, "total nodes %d", ls->ls_num_nodes); - - return error; -} - -static void nodes_clear(struct list_head *head) -{ - struct dlm_csb *csb; - - while (!list_empty(head)) { - csb = list_entry(head->next, struct dlm_csb, list); - list_del(&csb->list); - release_csb(csb); - } -} - -void ls_nodes_clear(struct dlm_ls *ls) -{ - nodes_clear(&ls->ls_nodes); - ls->ls_num_nodes = 0; -} - -void ls_nodes_gone_clear(struct dlm_ls *ls) -{ - struct dlm_csb *csb; - - retry: - spin_lock(&ls->ls_nodes_gone_spin); - if (list_empty(&ls->ls_nodes_gone)) - goto out; - csb = list_entry(ls->ls_nodes_gone.next, struct dlm_csb, list); - list_del(&csb->list); - spin_unlock(&ls->ls_nodes_gone_spin); - release_csb(csb); - goto retry; - out: - spin_unlock(&ls->ls_nodes_gone_spin); -} - -int ls_nodes_init(struct dlm_ls *ls, struct dlm_recover *rv) -{ - struct dlm_csb *csb; - int i, error; - uint32_t low = (uint32_t) (-1); - - /* nodes may be left from a previous failed start */ - ls_nodes_clear(ls); - - log_debug(ls, "add nodes"); - - for (i = 0; i < rv->node_count; i++) { - error = init_new_csb(rv->nodeids[i], &csb); - if (error) - goto fail; - - add_ordered_node(ls, csb); - ls->ls_num_nodes++; - - if (csb->node->nodeid < low) - low = csb->node->nodeid; - } - - ls->ls_low_nodeid = low; - set_bit(LSFL_NODES_VALID, &ls->ls_flags); - make_node_array(ls); - - error = nodes_reconfig_wait(ls); - - log_debug(ls, "total nodes %d", ls->ls_num_nodes); - return error; - fail: - ls_nodes_clear(ls); - return error; -} - -int in_nodes_gone(struct dlm_ls *ls, uint32_t nodeid) -{ - struct dlm_csb *csb; - - spin_lock(&ls->ls_nodes_gone_spin); - list_for_each_entry(csb, &ls->ls_nodes_gone, list) { - if (csb->node->nodeid == nodeid) { - spin_unlock(&ls->ls_nodes_gone_spin); - return TRUE; - } - } - spin_unlock(&ls->ls_nodes_gone_spin); - return FALSE; -} - diff --git a/dlm-kernel/src/nodes.h b/dlm-kernel/src/nodes.h deleted file mode 100644 index fd06cdb..0000000 --- a/dlm-kernel/src/nodes.h +++ /dev/null @@ -1,27 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __NODES_DOT_H__ -#define __NODES_DOT_H__ - -void dlm_nodes_init(void); -int init_new_csb(uint32_t nodeid, struct dlm_csb ** ret_csb); -void release_csb(struct dlm_csb * csb); -uint32_t our_nodeid(void); -int ls_nodes_reconfig(struct dlm_ls * ls, struct dlm_recover * gr, int *neg); -int ls_nodes_init(struct dlm_ls * ls, struct dlm_recover * gr); -int in_nodes_gone(struct dlm_ls * ls, uint32_t nodeid); -void ls_nodes_clear(struct dlm_ls *ls); -void ls_nodes_gone_clear(struct dlm_ls *ls); - -#endif /* __NODES_DOT_H__ */ diff --git a/dlm-kernel/src/proc.c b/dlm-kernel/src/proc.c deleted file mode 100644 index c7d9816..0000000 --- a/dlm-kernel/src/proc.c +++ /dev/null @@ -1,683 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/init.h> -#include <linux/proc_fs.h> -#include <linux/ctype.h> -#include <linux/seq_file.h> -#include <linux/module.h> - -#include "dlm_internal.h" -#include "rsb.h" -#include "lockspace.h" - -#if defined(DLM_DEBUG) -#define DLM_DEBUG_SIZE (1024) -#define MAX_DEBUG_MSG_LEN (64) -#else -#define DLM_DEBUG_SIZE (0) -#define MAX_DEBUG_MSG_LEN (0) -#endif - -static char * debug_buf; -static unsigned int debug_size; -static unsigned int debug_point; -static int debug_wrap; -static spinlock_t debug_lock; -static struct proc_dir_entry * debug_proc_entry = NULL; -static char proc_ls_name[255] = ""; - -#ifdef CONFIG_CLUSTER_DLM_PROCLOCKS -static struct proc_dir_entry * locks_proc_entry = NULL; -static struct seq_operations locks_info_op; -static struct proc_dir_entry * dir_proc_entry = NULL; -static struct seq_operations dir_info_op; - - -/* - * /proc/cluster/dlm_locks - dump resources and locks - */ - -static int locks_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &locks_info_op); -} - -/* Write simply sets the lockspace to use */ -static ssize_t locks_write(struct file *file, const char *buf, - size_t count, loff_t * ppos) -{ - int error; - - if (count < sizeof(proc_ls_name)) { - error = copy_from_user(proc_ls_name, buf, count); - if (error) - return error; - proc_ls_name[count] = '\0'; - - /* Remove any trailing LF so that lazy users - can just echo "lsname" > /proc/cluster/dlm_locks */ - if (proc_ls_name[count - 1] == '\n') - proc_ls_name[count - 1] = '\0'; - - return count; - } - return 0; -} - -static struct file_operations locks_fops = { - open:locks_open, - write:locks_write, - read:seq_read, - llseek:seq_lseek, - release:seq_release, -}; - -struct ls_dumpinfo { - int entry; - struct list_head *next; - struct dlm_ls *ls; - struct dlm_rsb *rsb; - struct dlm_direntry *de; -}; - -static int print_resource(struct dlm_rsb * res, struct seq_file *s); - -static struct ls_dumpinfo *next_rsb(struct ls_dumpinfo *di) -{ - int i; - - if (!di->next) { - /* Find the next non-empty hash bucket */ - for (i = di->entry; i < di->ls->ls_rsbtbl_size; i++) { - read_lock(&di->ls->ls_rsbtbl[i].lock); - if (!list_empty(&di->ls->ls_rsbtbl[i].list)) { - di->next = di->ls->ls_rsbtbl[i].list.next; - di->rsb = list_entry(di->next, struct dlm_rsb, - res_hashchain); - hold_rsb(di->rsb); - read_unlock(&di->ls->ls_rsbtbl[i].lock); - break; - } - read_unlock(&di->ls->ls_rsbtbl[i].lock); - } - di->entry = i; - - if (di->entry >= di->ls->ls_rsbtbl_size) - return NULL; /* End of hash list */ - } else { /* Find the next entry in the list */ - struct dlm_rsb *old = di->rsb; - i = di->entry; - read_lock(&di->ls->ls_rsbtbl[i].lock); - di->next = di->next->next; - if (di->next->next == di->ls->ls_rsbtbl[i].list.next) { - /* End of list - move to next bucket */ - di->next = NULL; - di->entry++; - read_unlock(&di->ls->ls_rsbtbl[i].lock); - release_rsb(old); - return next_rsb(di); /* do the top half of this conditional */ - } - di->rsb = list_entry(di->next, struct dlm_rsb, res_hashchain); - hold_rsb(di->rsb); - read_unlock(&di->ls->ls_rsbtbl[i].lock); - release_rsb(old); - } - - return di; -} - -static void *s_start(struct seq_file *m, loff_t *pos) -{ - struct ls_dumpinfo *di; - struct dlm_ls *ls; - int i; - - ls = find_lockspace_by_name(proc_ls_name, strlen(proc_ls_name)); - if (!ls) - return NULL; - - if (!m->private) { - di = kmalloc(sizeof(struct ls_dumpinfo), GFP_KERNEL); - m->private = di; - if (!di) - return NULL; - } - else - di = m->private; - if (*pos == 0) - seq_printf(m, "DLM lockspace '%s'\n", proc_ls_name); - - di->entry = 0; - di->next = NULL; - di->ls = ls; - di->de = NULL; - - for (i = 0; i < *pos; i++) - if (next_rsb(di) == NULL) - return NULL; - - return next_rsb(di); -} - -static void *s_next(struct seq_file *m, void *p, loff_t *pos) -{ - struct ls_dumpinfo *di = p; - - *pos += 1; - - return next_rsb(di); -} - -static int s_show(struct seq_file *m, void *p) -{ - struct ls_dumpinfo *di = p; - return print_resource(di->rsb, m); -} - -static void s_stop(struct seq_file *m, void *p) -{ - if (m->private) { - kfree(m->private); - m->private = NULL; - } -} - -static struct seq_operations locks_info_op = { - start:s_start, - next:s_next, - stop:s_stop, - show:s_show -}; - -static char *print_lockmode(int mode) -{ - switch (mode) { - case DLM_LOCK_IV: - return "--"; - case DLM_LOCK_NL: - return "NL"; - case DLM_LOCK_CR: - return "CR"; - case DLM_LOCK_CW: - return "CW"; - case DLM_LOCK_PR: - return "PR"; - case DLM_LOCK_PW: - return "PW"; - case DLM_LOCK_EX: - return "EX"; - default: - return "??"; - } -} - -static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, - struct dlm_rsb *res) -{ - - seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode)); - - if (lkb->lkb_status == GDLM_LKSTS_CONVERT - || lkb->lkb_status == GDLM_LKSTS_WAITING) - seq_printf(s, " (%s)", print_lockmode(lkb->lkb_rqmode)); - - seq_printf(s, " %u", lkb->lkb_ownpid); - - if (lkb->lkb_range) { - /* This warns on Alpha. Tough. Only I see it */ - if (lkb->lkb_status == GDLM_LKSTS_CONVERT - || lkb->lkb_status == GDLM_LKSTS_GRANTED) - seq_printf(s, " %" PRIx64 "-%" PRIx64, - lkb->lkb_range[GR_RANGE_START], - lkb->lkb_range[GR_RANGE_END]); - if (lkb->lkb_status == GDLM_LKSTS_CONVERT - || lkb->lkb_status == GDLM_LKSTS_WAITING) - seq_printf(s, " (%" PRIx64 "-%" PRIx64 ")", - lkb->lkb_range[RQ_RANGE_START], - lkb->lkb_range[RQ_RANGE_END]); - } - - if (lkb->lkb_nodeid) { - if (lkb->lkb_nodeid != res->res_nodeid) - seq_printf(s, " Remote: %3d %08x", lkb->lkb_nodeid, - lkb->lkb_remid); - else - seq_printf(s, " Master: %08x", lkb->lkb_remid); - } - - if (lkb->lkb_status != GDLM_LKSTS_GRANTED) - seq_printf(s, " LQ: %d,0x%x", lkb->lkb_lockqueue_state, - lkb->lkb_lockqueue_flags); - - seq_printf(s, "\n"); -} - -static int print_resource(struct dlm_rsb *res, struct seq_file *s) -{ - int i; - struct list_head *locklist; - - seq_printf(s, "\nResource %p (parent %p). Name (len=%d) "", res, - res->res_parent, res->res_length); - for (i = 0; i < res->res_length; i++) { - if (isprint(res->res_name[i])) - seq_printf(s, "%c", res->res_name[i]); - else - seq_printf(s, "%c", '.'); - } - if (res->res_nodeid) - seq_printf(s, "" \nLocal Copy, Master is node %d\n", - res->res_nodeid); - else - seq_printf(s, "" \nMaster Copy\n"); - - /* Print the LVB: */ - if (res->res_lvbptr) { - seq_printf(s, "LVB: "); - for (i = 0; i < DLM_LVB_LEN; i++) { - if (i == DLM_LVB_LEN / 2) - seq_printf(s, "\n "); - seq_printf(s, "%02x ", - (unsigned char) res->res_lvbptr[i]); - } - if (test_bit(RESFL_VALNOTVALID, &res->res_flags)) - seq_printf(s, " (INVALID)"); - seq_printf(s, "\n"); - } - - /* Print the locks attached to this resource */ - seq_printf(s, "Granted Queue\n"); - list_for_each(locklist, &res->res_grantqueue) { - struct dlm_lkb *this_lkb = - list_entry(locklist, struct dlm_lkb, lkb_statequeue); - print_lock(s, this_lkb, res); - } - - seq_printf(s, "Conversion Queue\n"); - list_for_each(locklist, &res->res_convertqueue) { - struct dlm_lkb *this_lkb = - list_entry(locklist, struct dlm_lkb, lkb_statequeue); - print_lock(s, this_lkb, res); - } - - seq_printf(s, "Waiting Queue\n"); - list_for_each(locklist, &res->res_waitqueue) { - struct dlm_lkb *this_lkb = - list_entry(locklist, struct dlm_lkb, lkb_statequeue); - print_lock(s, this_lkb, res); - } - - return 0; -} - - -/* - * /proc/cluster/dlm_dir - dump resource directory - */ - -static int print_de(struct dlm_direntry *de, struct seq_file *s) -{ - char strname[DLM_RESNAME_MAXLEN+1]; - - memset(strname, 0, DLM_RESNAME_MAXLEN+1); - memcpy(strname, de->name, de->length); - - seq_printf(s, "%s %u\n", strname, de->master_nodeid); - return 0; -} - -static int dir_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &dir_info_op); -} - -static ssize_t dir_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - return locks_write(file, buf, count, ppos); -} - -static struct file_operations dir_fops = { - .open = dir_open, - .write = dir_write, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, - .owner = THIS_MODULE, -}; - -static struct ls_dumpinfo *next_de(struct ls_dumpinfo *di) -{ - int i; - - if (!di->next) { - /* Find the next non-empty hash bucket */ - for (i = di->entry; i < di->ls->ls_dirtbl_size; i++) { - read_lock(&di->ls->ls_dirtbl[i].lock); - if (!list_empty(&di->ls->ls_dirtbl[i].list)) { - di->next = di->ls->ls_dirtbl[i].list.next; - read_unlock(&di->ls->ls_dirtbl[i].lock); - break; - } - read_unlock(&di->ls->ls_dirtbl[i].lock); - } - di->entry = i; - - if (di->entry >= di->ls->ls_dirtbl_size) - return NULL; /* End of hash list */ - } else { /* Find the next entry in the list */ - i = di->entry; - read_lock(&di->ls->ls_dirtbl[i].lock); - di->next = di->next->next; - if (di->next->next == di->ls->ls_dirtbl[i].list.next) { - /* End of list - move to next bucket */ - di->next = NULL; - di->entry++; - read_unlock(&di->ls->ls_dirtbl[i].lock); - return next_de(di); /* do the top half of this conditional */ - } - read_unlock(&di->ls->ls_dirtbl[i].lock); - } - di->de = list_entry(di->next, struct dlm_direntry, list); - - return di; -} - -static void *dir_start(struct seq_file *m, loff_t *pos) -{ - struct ls_dumpinfo *di; - struct dlm_ls *ls; - int i; - - ls = find_lockspace_by_name(proc_ls_name, strlen(proc_ls_name)); - if (!ls) - return NULL; - - if (!m->private) { - di = kmalloc(sizeof(struct ls_dumpinfo), GFP_KERNEL); - m->private = di; - if (!di) - return NULL; - } - else - di = m->private; - - if (*pos == 0) - seq_printf(m, "DLM lockspace '%s'\n", proc_ls_name); - - di->entry = 0; - di->next = NULL; - di->ls = ls; - - for (i = 0; i < *pos; i++) - if (next_de(di) == NULL) - return NULL; - - return next_de(di); -} - -static void *dir_next(struct seq_file *m, void *p, loff_t *pos) -{ - struct ls_dumpinfo *di = p; - - *pos += 1; - - return next_de(di); -} - -static int dir_show(struct seq_file *m, void *p) -{ - struct ls_dumpinfo *di = p; - return print_de(di->de, m); -} - -static void dir_stop(struct seq_file *m, void *p) -{ - if (m->private) { - kfree(m->private); - m->private = NULL; - } -} - -static struct seq_operations dir_info_op = { - .start = dir_start, - .next = dir_next, - .stop = dir_stop, - .show = dir_show, -}; -#endif /* CONFIG_CLUSTER_DLM_PROCLOCKS */ - -void dlm_debug_log(struct dlm_ls *ls, const char *fmt, ...) -{ - va_list va; - int i, n, size, len; - char buf[MAX_DEBUG_MSG_LEN+1]; - - spin_lock(&debug_lock); - - if (!debug_buf) - goto out; - - size = MAX_DEBUG_MSG_LEN; - memset(buf, 0, size+1); - - n = snprintf(buf, size, "%s ", ls->ls_name); - size -= n; - - va_start(va, fmt); - vsnprintf(buf+n, size, fmt, va); - va_end(va); - - len = strlen(buf); - if (len > MAX_DEBUG_MSG_LEN-1) - len = MAX_DEBUG_MSG_LEN-1; - buf[len] = '\n'; - buf[len+1] = '\0'; - - for (i = 0; i < strlen(buf); i++) { - debug_buf[debug_point++] = buf[i]; - - if (debug_point == debug_size) { - debug_point = 0; - debug_wrap = 1; - } - } - out: - spin_unlock(&debug_lock); -} - -void dlm_debug_dump(void) -{ - int i; - - spin_lock(&debug_lock); - if (debug_wrap) { - for (i = debug_point; i < debug_size; i++) - printk("%c", debug_buf[i]); - } - for (i = 0; i < debug_point; i++) - printk("%c", debug_buf[i]); - spin_unlock(&debug_lock); -} - -void dlm_debug_setup(int size) -{ - char *b = NULL; - - if (size > PAGE_SIZE) - size = PAGE_SIZE; - if (size) - b = kmalloc(size, GFP_KERNEL); - - spin_lock(&debug_lock); - if (debug_buf) - kfree(debug_buf); - if (!size || !b) - goto out; - debug_size = size; - debug_point = 0; - debug_wrap = 0; - debug_buf = b; - memset(debug_buf, 0, debug_size); - out: - spin_unlock(&debug_lock); -} - -static void dlm_debug_init(void) -{ - debug_buf = NULL; - debug_size = 0; - debug_point = 0; - debug_wrap = 0; - spin_lock_init(&debug_lock); - - dlm_debug_setup(DLM_DEBUG_SIZE); -} - -#ifdef CONFIG_PROC_FS -int dlm_debug_info(char *b, char **start, off_t offset, int length) -{ - int i, n = 0; - - spin_lock(&debug_lock); - - if (debug_wrap) { - for (i = debug_point; i < debug_size; i++) - n += sprintf(b + n, "%c", debug_buf[i]); - } - for (i = 0; i < debug_point; i++) - n += sprintf(b + n, "%c", debug_buf[i]); - - spin_unlock(&debug_lock); - - return n; -} -#endif - -#ifdef CONFIG_DLM_STATS -struct dlm_statinfo dlm_stats; -static struct proc_dir_entry *stats_proc_entry = NULL; -static int dlm_stats_info(char *b, char **start, off_t offset, int length) -{ - int n=0; - int i; - long lq_locks = 0; - unsigned long lq_time = 0; - - n += sprintf(b+n, "DLM stats (HZ=%d)\n\n", HZ); - n += sprintf(b+n, "Lock operations: %7d\n", dlm_stats.lockops); - n += sprintf(b+n, "Unlock operations: %7d\n", dlm_stats.unlockops); - n += sprintf(b+n, "Convert operations: %7d\n", dlm_stats.convertops); - n += sprintf(b+n, "Completion ASTs: %7d\n", dlm_stats.cast); - n += sprintf(b+n, "Blocking ASTs: %7d\n", dlm_stats.bast); - n += sprintf(b+n, "\n"); - n += sprintf(b+n, "Lockqueue num waittime ave\n"); - for (i=1; i<=4 ; i++) { - char *lq_reason="???"; - switch (i){ - case 1: lq_reason = "WAIT_RSB "; - break; - case 2: lq_reason = "WAIT_CONV "; - break; - case 3: lq_reason = "WAIT_GRANT "; - break; - case 4: lq_reason = "WAIT_UNLOCK"; - break; - } - if (dlm_stats.lockqueue_locks[i]) - n += sprintf(b+n, "%s %6lu %7lu %3lu\n", - lq_reason, - dlm_stats.lockqueue_locks[i], - dlm_stats.lockqueue_time[i], - dlm_stats.lockqueue_time[i]/ - dlm_stats.lockqueue_locks[i]); - - lq_locks += dlm_stats.lockqueue_locks[i]; - lq_time += dlm_stats.lockqueue_time[i]; - } - if (lq_locks) - n += sprintf(b+n, "Total %6lu %7lu %3lu\n", - lq_locks, lq_time, lq_time/lq_locks); - return n; -} - -static int dlm_stats_clear(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - memset(&dlm_stats, 0, sizeof(dlm_stats)); - return count; -} -#endif /* CONFIG_DLM_STATS */ - -void dlm_proc_init(void) -{ -#ifdef CONFIG_PROC_FS - debug_proc_entry = create_proc_entry("cluster/dlm_debug", S_IRUGO, - NULL); - if (!debug_proc_entry) - return; - - debug_proc_entry->get_info = &dlm_debug_info; -#endif - -#ifdef CONFIG_DLM_STATS - stats_proc_entry = create_proc_entry("cluster/dlm_stats", - S_IRUSR | S_IWUSR, NULL); - if (!stats_proc_entry) - return; - - stats_proc_entry->get_info = &dlm_stats_info; - stats_proc_entry->write_proc = &dlm_stats_clear; -#endif - - dlm_debug_init(); - -#ifdef CONFIG_CLUSTER_DLM_PROCLOCKS - locks_proc_entry = create_proc_read_entry("cluster/dlm_locks", - S_IFREG | 0400, - NULL, NULL, NULL); - if (!locks_proc_entry) - return; - locks_proc_entry->proc_fops = &locks_fops; - - dir_proc_entry = create_proc_read_entry("cluster/dlm_dir", - S_IFREG | 0400, - NULL, NULL, NULL); - if (!dir_proc_entry) - return; - dir_proc_entry->proc_fops = &dir_fops; -#endif -} - -void dlm_proc_exit(void) -{ -#ifdef CONFIG_PROC_FS - if (debug_proc_entry) { - remove_proc_entry("cluster/dlm_debug", NULL); - dlm_debug_setup(0); - } -#endif - -#ifdef CONFIG_DLM_STATS - if (stats_proc_entry) - remove_proc_entry("cluster/dlm_stats", NULL); -#endif - -#ifdef CONFIG_CLUSTER_DLM_PROCLOCKS - if (locks_proc_entry) - remove_proc_entry("cluster/dlm_locks", NULL); - if (dir_proc_entry) - remove_proc_entry("cluster/dlm_dir", NULL); -#endif -} diff --git a/dlm-kernel/src/queries.c b/dlm-kernel/src/queries.c deleted file mode 100644 index b32aa1d..0000000 --- a/dlm-kernel/src/queries.c +++ /dev/null @@ -1,713 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * queries.c - * - * This file provides the kernel query interface to the DLM. - * - */ - -#define EXPORT_SYMTAB -#include <linux/module.h> - -#include "dlm_internal.h" -#include "lockspace.h" -#include "lockqueue.h" -#include "locking.h" -#include "lkb.h" -#include "nodes.h" -#include "dir.h" -#include "ast.h" -#include "memory.h" -#include "lowcomms.h" -#include "midcomms.h" -#include "rsb.h" - -static int query_resource(struct dlm_rsb *rsb, struct dlm_resinfo *resinfo); -static int query_locks(int query, struct dlm_lkb *lkb, struct dlm_queryinfo *qinfo); - -/* - * API entry point. - */ -int dlm_query(void *lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (ast_routine(void *)), - void *astarg) -{ - int status = -EINVAL; - struct dlm_lkb *target_lkb; - struct dlm_lkb *query_lkb = NULL; /* Our temporary LKB */ - struct dlm_ls *ls = find_lockspace_by_local_id(lockspace); - - if (!ls) - return -EINVAL; - if (!qinfo) - goto out; - if (!ast_routine) - goto out; - if (!lksb) - goto out; - - if (!qinfo->gqi_lockinfo) - qinfo->gqi_locksize = 0; - - /* Find the lkid */ - target_lkb = find_lock_by_id(ls, lksb->sb_lkid); - if (!target_lkb) - goto out; - - /* If the user wants a list of locks that are blocking or - not blocking this lock, then it must be waiting - for something - */ - if (((query & DLM_QUERY_MASK) == DLM_QUERY_LOCKS_BLOCKING || - (query & DLM_QUERY_MASK) == DLM_QUERY_LOCKS_NOTBLOCK) && - target_lkb->lkb_status == GDLM_LKSTS_GRANTED) - goto out; - - /* We now allocate an LKB for our own use (so we can hang - * things like the AST routine and the lksb from it) */ - lksb->sb_status = -EBUSY; - query_lkb = create_lkb(ls); - if (!query_lkb) { - status = -ENOMEM; - goto out; - } - query_lkb->lkb_astaddr = ast_routine; - query_lkb->lkb_astparam = (long)astarg; - query_lkb->lkb_resource = target_lkb->lkb_resource; - query_lkb->lkb_lksb = lksb; - - /* Don't free the resource while we are querying it. This ref - * will be dropped when the LKB is freed */ - hold_rsb(query_lkb->lkb_resource); - - /* Fill in the stuff that's always local */ - if (qinfo->gqi_resinfo) { - if (target_lkb->lkb_resource->res_nodeid) - qinfo->gqi_resinfo->rsi_masternode = - target_lkb->lkb_resource->res_nodeid; - else - qinfo->gqi_resinfo->rsi_masternode = our_nodeid(); - qinfo->gqi_resinfo->rsi_length = - target_lkb->lkb_resource->res_length; - memcpy(qinfo->gqi_resinfo->rsi_name, - target_lkb->lkb_resource->res_name, - qinfo->gqi_resinfo->rsi_length); - } - - /* If the master is local (or the user doesn't want the overhead of a - * remote call) - fill in the details here */ - if (target_lkb->lkb_resource->res_nodeid == 0 || - (query & DLM_QUERY_LOCAL)) { - - status = 0; - /* Resource info */ - if (qinfo->gqi_resinfo) { - query_resource(target_lkb->lkb_resource, - qinfo->gqi_resinfo); - } - - /* Lock lists */ - if (qinfo->gqi_lockinfo) { - status = query_locks(query, target_lkb, qinfo); - } - - query_lkb->lkb_retstatus = status; - queue_ast(query_lkb, AST_COMP | AST_DEL, 0); - wake_astd(); - - /* An AST will be delivered so we must return success here */ - status = 0; - goto out; - } - - /* Remote master */ - if (target_lkb->lkb_resource->res_nodeid != 0) - { - struct dlm_query_request *remquery; - struct writequeue_entry *e; - - /* Clear this cos the receiving end adds to it with - each incoming packet */ - qinfo->gqi_lockcount = 0; - - /* Squirrel a pointer to the query info struct - somewhere illegal */ - query_lkb->lkb_request = (struct dlm_request *) qinfo; - - e = lowcomms_get_buffer(query_lkb->lkb_resource->res_nodeid, - sizeof(struct dlm_query_request), - ls->ls_allocation, - (char **) &remquery); - if (!e) { - status = -ENOBUFS; - goto out; - } - - /* Build remote packet */ - memset(remquery, 0, sizeof(struct dlm_query_request)); - - remquery->rq_maxlocks = qinfo->gqi_locksize; - remquery->rq_query = query; - remquery->rq_mstlkid = target_lkb->lkb_remid; - if (qinfo->gqi_lockinfo) - remquery->rq_maxlocks = qinfo->gqi_locksize; - - remquery->rq_header.rh_cmd = GDLM_REMCMD_QUERY; - remquery->rq_header.rh_flags = 0; - remquery->rq_header.rh_length = sizeof(struct dlm_query_request); - remquery->rq_header.rh_lkid = query_lkb->lkb_id; - remquery->rq_header.rh_lockspace = ls->ls_global_id; - - midcomms_send_buffer(&remquery->rq_header, e); - status = 0; - } - - out: - put_lockspace(ls); - return status; -} - -static inline int valid_range(struct dlm_range *r) -{ - if (r->ra_start != 0ULL || - r->ra_end != 0xFFFFFFFFFFFFFFFFULL) - return 1; - else - return 0; -} - -static void put_int(int x, char *buf, int *offp) -{ - x = cpu_to_le32(x); - memcpy(buf + *offp, &x, sizeof(int)); - *offp += sizeof(int); -} - -static void put_int64(uint64_t x, char *buf, int *offp) -{ - x = cpu_to_le64(x); - memcpy(buf + *offp, &x, sizeof(uint64_t)); - *offp += sizeof(uint64_t); -} - -static int get_int(char *buf, int *offp) -{ - int value; - memcpy(&value, buf + *offp, sizeof(int)); - *offp += sizeof(int); - return le32_to_cpu(value); -} - -static uint64_t get_int64(char *buf, int *offp) -{ - uint64_t value; - - memcpy(&value, buf + *offp, sizeof(uint64_t)); - *offp += sizeof(uint64_t); - return le64_to_cpu(value); -} - -#define LOCK_LEN (sizeof(int)*5 + sizeof(uint8_t)*4) - -/* Called from recvd to get lock info for a remote node */ -int remote_query(int nodeid, struct dlm_ls *ls, struct dlm_header *msg) -{ - struct dlm_query_request *query = (struct dlm_query_request *) msg; - struct dlm_query_reply *reply; - struct dlm_resinfo resinfo; - struct dlm_queryinfo qinfo; - struct writequeue_entry *e; - char *buf; - struct dlm_lkb *lkb; - int status = 0; - int bufidx; - int finished = 0; - int cur_lock = 0; - int start_lock = 0; - - lkb = find_lock_by_id(ls, query->rq_mstlkid); - if (!lkb) { - status = -EINVAL; - goto send_error; - } - - qinfo.gqi_resinfo = &resinfo; - qinfo.gqi_locksize = query->rq_maxlocks; - - /* Get the resource bits */ - query_resource(lkb->lkb_resource, &resinfo); - - /* Now get the locks if wanted */ - if (query->rq_maxlocks) { - qinfo.gqi_lockinfo = kmalloc(sizeof(struct dlm_lockinfo) * query->rq_maxlocks, - GFP_KERNEL); - if (!qinfo.gqi_lockinfo) { - status = -ENOMEM; - goto send_error; - } - - status = query_locks(query->rq_query, lkb, &qinfo); - if (status && status != -E2BIG) { - kfree(qinfo.gqi_lockinfo); - goto send_error; - } - } - else { - qinfo.gqi_lockinfo = NULL; - qinfo.gqi_lockcount = 0; - } - - /* Send as many blocks as needed for all the locks */ - do { - int i; - int msg_len = sizeof(struct dlm_query_reply); - int last_msg_len = msg_len; /* keeps compiler quiet */ - int last_lock; - - /* First work out how many locks we can fit into a block */ - for (i=cur_lock; i < qinfo.gqi_lockcount && msg_len < PAGE_SIZE; i++) { - - last_msg_len = msg_len; - - msg_len += LOCK_LEN; - if (valid_range(&qinfo.gqi_lockinfo[i].lki_grrange) || - valid_range(&qinfo.gqi_lockinfo[i].lki_rqrange)) { - - msg_len += sizeof(uint64_t) * 4; - } - } - - /* There must be a neater way of doing this... */ - if (msg_len > PAGE_SIZE) { - last_lock = i-1; - msg_len = last_msg_len; - } - else { - last_lock = i; - } - - e = lowcomms_get_buffer(nodeid, - msg_len, - ls->ls_allocation, - (char **) &reply); - if (!e) { - kfree(qinfo.gqi_lockinfo); - status = -ENOBUFS; - goto out; - } - - reply->rq_header.rh_cmd = GDLM_REMCMD_QUERYREPLY; - reply->rq_header.rh_length = msg_len; - reply->rq_header.rh_lkid = msg->rh_lkid; - reply->rq_header.rh_lockspace = msg->rh_lockspace; - - reply->rq_status = status; - reply->rq_startlock = cur_lock; - reply->rq_grantcount = qinfo.gqi_resinfo->rsi_grantcount; - reply->rq_convcount = qinfo.gqi_resinfo->rsi_convcount; - reply->rq_waitcount = qinfo.gqi_resinfo->rsi_waitcount; - memcpy(reply->rq_valblk, qinfo.gqi_resinfo->rsi_valblk, DLM_LVB_LEN); - - buf = (char *)reply; - bufidx = sizeof(struct dlm_query_reply); - - for (; cur_lock < last_lock; cur_lock++) { - - buf[bufidx++] = qinfo.gqi_lockinfo[cur_lock].lki_state; - buf[bufidx++] = qinfo.gqi_lockinfo[cur_lock].lki_grmode; - buf[bufidx++] = qinfo.gqi_lockinfo[cur_lock].lki_rqmode; - put_int(qinfo.gqi_lockinfo[cur_lock].lki_lkid, buf, &bufidx); - put_int(qinfo.gqi_lockinfo[cur_lock].lki_mstlkid, buf, &bufidx); - put_int(qinfo.gqi_lockinfo[cur_lock].lki_parent, buf, &bufidx); - put_int(qinfo.gqi_lockinfo[cur_lock].lki_node, buf, &bufidx); - put_int(qinfo.gqi_lockinfo[cur_lock].lki_ownpid, buf, &bufidx); - - if (valid_range(&qinfo.gqi_lockinfo[cur_lock].lki_grrange) || - valid_range(&qinfo.gqi_lockinfo[cur_lock].lki_rqrange)) { - - buf[bufidx++] = 1; - put_int64(qinfo.gqi_lockinfo[cur_lock].lki_grrange.ra_start, buf, &bufidx); - put_int64(qinfo.gqi_lockinfo[cur_lock].lki_grrange.ra_end, buf, &bufidx); - put_int64(qinfo.gqi_lockinfo[cur_lock].lki_rqrange.ra_start, buf, &bufidx); - put_int64(qinfo.gqi_lockinfo[cur_lock].lki_rqrange.ra_end, buf, &bufidx); - } - else { - buf[bufidx++] = 0; - } - } - - if (cur_lock == qinfo.gqi_lockcount) { - reply->rq_header.rh_flags = GDLM_REMFLAG_ENDQUERY; - finished = 1; - } - else { - reply->rq_header.rh_flags = 0; - } - - reply->rq_numlocks = cur_lock - start_lock; - start_lock = cur_lock; - - midcomms_send_buffer(&reply->rq_header, e); - } while (!finished); - - kfree(qinfo.gqi_lockinfo); - out: - return status; - - send_error: - e = lowcomms_get_buffer(nodeid, - sizeof(struct dlm_query_reply), - ls->ls_allocation, - (char **) &reply); - if (!e) { - status = -ENOBUFS; - goto out; - } - reply->rq_header.rh_cmd = GDLM_REMCMD_QUERYREPLY; - reply->rq_header.rh_flags = GDLM_REMFLAG_ENDQUERY; - reply->rq_header.rh_length = sizeof(struct dlm_query_reply); - reply->rq_header.rh_lkid = msg->rh_lkid; - reply->rq_header.rh_lockspace = msg->rh_lockspace; - reply->rq_status = status; - reply->rq_numlocks = 0; - reply->rq_startlock = 0; - reply->rq_grantcount = 0; - reply->rq_convcount = 0; - reply->rq_waitcount = 0; - - midcomms_send_buffer(&reply->rq_header, e); - - return status; -} - -/* Reply to a remote query */ -int remote_query_reply(int nodeid, struct dlm_ls *ls, struct dlm_header *msg) -{ - struct dlm_lkb *query_lkb; - struct dlm_queryinfo *qinfo; - struct dlm_query_reply *reply; - char *buf; - int i; - int bufidx; - - query_lkb = find_lock_by_id(ls, msg->rh_lkid); - if (!query_lkb) - return -EINVAL; - - qinfo = (struct dlm_queryinfo *) query_lkb->lkb_request; - reply = (struct dlm_query_reply *) msg; - - /* Copy the easy bits first */ - qinfo->gqi_lockcount += reply->rq_numlocks; - if (qinfo->gqi_resinfo) { - qinfo->gqi_resinfo->rsi_grantcount = reply->rq_grantcount; - qinfo->gqi_resinfo->rsi_convcount = reply->rq_convcount; - qinfo->gqi_resinfo->rsi_waitcount = reply->rq_waitcount; - memcpy(qinfo->gqi_resinfo->rsi_valblk, reply->rq_valblk, - DLM_LVB_LEN); - } - - /* Now unpack the locks */ - bufidx = sizeof(struct dlm_query_reply); - buf = (char *) msg; - - DLM_ASSERT(reply->rq_startlock + reply->rq_numlocks <= qinfo->gqi_locksize, - printk("start = %d, num + %d. Max= %d\n", - reply->rq_startlock, reply->rq_numlocks, qinfo->gqi_locksize);); - - for (i = reply->rq_startlock; - i < reply->rq_startlock + reply->rq_numlocks; i++) { - qinfo->gqi_lockinfo[i].lki_state = buf[bufidx++]; - qinfo->gqi_lockinfo[i].lki_grmode = buf[bufidx++]; - qinfo->gqi_lockinfo[i].lki_rqmode = buf[bufidx++]; - qinfo->gqi_lockinfo[i].lki_lkid = get_int(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_mstlkid = get_int(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_parent = get_int(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_node = get_int(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_ownpid = get_int(buf, &bufidx); - if (buf[bufidx++]) { - qinfo->gqi_lockinfo[i].lki_grrange.ra_start = get_int64(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_grrange.ra_end = get_int64(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_rqrange.ra_start = get_int64(buf, &bufidx); - qinfo->gqi_lockinfo[i].lki_rqrange.ra_end = get_int64(buf, &bufidx); - } - else { - qinfo->gqi_lockinfo[i].lki_grrange.ra_start = 0ULL; - qinfo->gqi_lockinfo[i].lki_grrange.ra_end = 0xFFFFFFFFFFFFFFFFULL; - qinfo->gqi_lockinfo[i].lki_rqrange.ra_start = 0ULL; - qinfo->gqi_lockinfo[i].lki_rqrange.ra_end = 0xFFFFFFFFFFFFFFFFULL; - } - } - - /* If this was the last block then now tell the user */ - if (msg->rh_flags & GDLM_REMFLAG_ENDQUERY) { - query_lkb->lkb_retstatus = reply->rq_status; - queue_ast(query_lkb, AST_COMP | AST_DEL, 0); - wake_astd(); - } - - return 0; -} - -/* Aggregate resource information */ -static int query_resource(struct dlm_rsb *rsb, struct dlm_resinfo *resinfo) -{ - struct list_head *tmp; - - if (rsb->res_lvbptr) - memcpy(resinfo->rsi_valblk, rsb->res_lvbptr, DLM_LVB_LEN); - - down_read(&rsb->res_lock); - resinfo->rsi_grantcount = 0; - list_for_each(tmp, &rsb->res_grantqueue) { - resinfo->rsi_grantcount++; - } - - resinfo->rsi_waitcount = 0; - list_for_each(tmp, &rsb->res_waitqueue) { - resinfo->rsi_waitcount++; - } - - resinfo->rsi_convcount = 0; - list_for_each(tmp, &rsb->res_convertqueue) { - resinfo->rsi_convcount++; - } - up_read(&rsb->res_lock); - - return 0; -} - -static int add_lock(struct dlm_lkb *lkb, struct dlm_queryinfo *qinfo) -{ - int entry; - - /* Don't fill it in if the buffer is full */ - if (qinfo->gqi_lockcount == qinfo->gqi_locksize) - return -E2BIG; - - /* gqi_lockcount contains the number of locks we have returned */ - entry = qinfo->gqi_lockcount++; - - /* Fun with master copies */ - if (lkb->lkb_flags & GDLM_LKFLG_MSTCPY) { - qinfo->gqi_lockinfo[entry].lki_lkid = lkb->lkb_remid; - qinfo->gqi_lockinfo[entry].lki_mstlkid = lkb->lkb_id; - } - else { - qinfo->gqi_lockinfo[entry].lki_lkid = lkb->lkb_id; - qinfo->gqi_lockinfo[entry].lki_mstlkid = lkb->lkb_remid; - } - - /* Also make sure we always have a valid nodeid in there, the - calling end may not know which node "0" is */ - if (lkb->lkb_nodeid) - qinfo->gqi_lockinfo[entry].lki_node = lkb->lkb_nodeid; - else - qinfo->gqi_lockinfo[entry].lki_node = our_nodeid(); - - if (lkb->lkb_parent) - qinfo->gqi_lockinfo[entry].lki_parent = lkb->lkb_parent->lkb_id; - else - qinfo->gqi_lockinfo[entry].lki_parent = 0; - - qinfo->gqi_lockinfo[entry].lki_state = lkb->lkb_status; - qinfo->gqi_lockinfo[entry].lki_rqmode = lkb->lkb_rqmode; - qinfo->gqi_lockinfo[entry].lki_grmode = lkb->lkb_grmode; - qinfo->gqi_lockinfo[entry].lki_ownpid = lkb->lkb_ownpid; - - if (lkb->lkb_range) { - qinfo->gqi_lockinfo[entry].lki_grrange.ra_start = - lkb->lkb_range[GR_RANGE_START]; - qinfo->gqi_lockinfo[entry].lki_grrange.ra_end = - lkb->lkb_range[GR_RANGE_END]; - qinfo->gqi_lockinfo[entry].lki_rqrange.ra_start = - lkb->lkb_range[RQ_RANGE_START]; - qinfo->gqi_lockinfo[entry].lki_rqrange.ra_end = - lkb->lkb_range[RQ_RANGE_END]; - } else { - qinfo->gqi_lockinfo[entry].lki_grrange.ra_start = 0ULL; - qinfo->gqi_lockinfo[entry].lki_grrange.ra_start = 0xffffffffffffffffULL; - qinfo->gqi_lockinfo[entry].lki_rqrange.ra_start = 0ULL; - qinfo->gqi_lockinfo[entry].lki_rqrange.ra_start = 0xffffffffffffffffULL; - } - return 0; -} - -static int query_lkb_queue(struct dlm_rsb *rsb, - struct list_head *queue, int query, - struct dlm_queryinfo *qinfo) -{ - struct list_head *tmp; - int status = 0; - int mode = query & DLM_QUERY_MODE_MASK; - - down_read(&rsb->res_lock); - list_for_each(tmp, queue) { - struct dlm_lkb *lkb = list_entry(tmp, struct dlm_lkb, lkb_statequeue); - int lkmode; - - if (query & DLM_QUERY_RQMODE) - lkmode = lkb->lkb_rqmode; - else - lkmode = lkb->lkb_grmode; - - /* Add the LKB info to the list if it matches the criteria in - * the query bitmap */ - switch (query & DLM_QUERY_MASK) { - case DLM_QUERY_LOCKS_ALL: - status = add_lock(lkb, qinfo); - break; - - case DLM_QUERY_LOCKS_HIGHER: - if (lkmode > mode) - status = add_lock(lkb, qinfo); - break; - - case DLM_QUERY_LOCKS_EQUAL: - if (lkmode == mode) - status = add_lock(lkb, qinfo); - break; - - case DLM_QUERY_LOCKS_LOWER: - if (lkmode < mode) - status = add_lock(lkb, qinfo); - - case DLM_QUERY_LOCKS_ORPHAN: - if (lkb->lkb_flags & GDLM_LKFLG_ORPHAN) - status = add_lock(lkb, qinfo); - break; - } - } - up_read(&rsb->res_lock); - return status; -} - -/* - * Return 1 if the locks' ranges overlap - * If the lkb has no range then it is assumed to cover 0-ffffffff.ffffffff - */ -static inline int ranges_overlap(struct dlm_lkb *lkb1, struct dlm_lkb *lkb2) -{ - if (!lkb1->lkb_range || !lkb2->lkb_range) - return 1; - - if (lkb1->lkb_range[RQ_RANGE_END] <= lkb2->lkb_range[GR_RANGE_START] || - lkb1->lkb_range[RQ_RANGE_START] >= lkb2->lkb_range[GR_RANGE_END]) - return 0; - - return 1; -} -extern const int __dlm_compat_matrix[8][8]; - - -static int get_blocking_locks(struct dlm_lkb *qlkb, struct dlm_queryinfo *qinfo) -{ - struct list_head *tmp; - int status = 0; - - down_read(&qlkb->lkb_resource->res_lock); - list_for_each(tmp, &qlkb->lkb_resource->res_grantqueue) { - struct dlm_lkb *lkb = list_entry(tmp, struct dlm_lkb, lkb_statequeue); - - if (ranges_overlap(lkb, qlkb) && - !__dlm_compat_matrix[lkb->lkb_grmode + 1][qlkb->lkb_rqmode + 1]) - status = add_lock(lkb, qinfo); - } - up_read(&qlkb->lkb_resource->res_lock); - - return status; -} - -static int get_nonblocking_locks(struct dlm_lkb *qlkb, struct dlm_queryinfo *qinfo) -{ - struct list_head *tmp; - int status = 0; - - down_read(&qlkb->lkb_resource->res_lock); - list_for_each(tmp, &qlkb->lkb_resource->res_grantqueue) { - struct dlm_lkb *lkb = list_entry(tmp, struct dlm_lkb, lkb_statequeue); - - if (!(ranges_overlap(lkb, qlkb) && - !__dlm_compat_matrix[lkb->lkb_grmode + 1][qlkb->lkb_rqmode + 1])) - status = add_lock(lkb, qinfo); - } - up_read(&qlkb->lkb_resource->res_lock); - - return status; -} - -/* Gather a list of appropriate locks */ -static int query_locks(int query, struct dlm_lkb *lkb, struct dlm_queryinfo *qinfo) -{ - int status = 0; - - - /* Mask in the actual granted/requsted mode of the lock if LOCK_THIS - * was requested as the mode - */ - if ((query & DLM_QUERY_MODE_MASK) == DLM_LOCK_THIS) { - query &= ~DLM_QUERY_MODE_MASK; - if (query & DLM_QUERY_RQMODE) - query |= lkb->lkb_rqmode; - else - query |= lkb->lkb_grmode; - } - - qinfo->gqi_lockcount = 0; - - /* BLOCKING/NOTBLOCK only look at the granted queue */ - if ((query & DLM_QUERY_MASK) == DLM_QUERY_LOCKS_BLOCKING) - return get_blocking_locks(lkb, qinfo); - - if ((query & DLM_QUERY_MASK) == DLM_QUERY_LOCKS_NOTBLOCK) - return get_nonblocking_locks(lkb, qinfo); - - /* Do the lock queues that were requested */ - if (query & DLM_QUERY_QUEUE_GRANT) { - status = query_lkb_queue(lkb->lkb_resource, - &lkb->lkb_resource->res_grantqueue, - query, qinfo); - } - - if (!status && (query & DLM_QUERY_QUEUE_CONVERT)) { - status = query_lkb_queue(lkb->lkb_resource, - &lkb->lkb_resource->res_convertqueue, - query, qinfo); - } - - if (!status && (query & DLM_QUERY_QUEUE_WAIT)) { - status = query_lkb_queue(lkb->lkb_resource, - &lkb->lkb_resource->res_waitqueue, - query, qinfo); - } - - - return status; -} - -EXPORT_SYMBOL(dlm_query); -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/dlm-kernel/src/queries.h b/dlm-kernel/src/queries.h deleted file mode 100644 index 3f03d60..0000000 --- a/dlm-kernel/src/queries.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __QUERIES_DOT_H__ -#define __QUERIES_DOT_H__ - -extern int remote_query(int nodeid, struct dlm_ls *ls, struct dlm_header *msg); -extern int remote_query_reply(int nodeid, struct dlm_ls *ls, struct dlm_header *msg); - -#endif /* __QUERIES_DOT_H__ */ diff --git a/dlm-kernel/src/rebuild.c b/dlm-kernel/src/rebuild.c deleted file mode 100644 index 03be358..0000000 --- a/dlm-kernel/src/rebuild.c +++ /dev/null @@ -1,1291 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * Rebuild RSB's on new masters. Functions for transferring locks and - * subresources to new RSB masters during recovery. - */ - -#include "dlm_internal.h" -#include "reccomms.h" -#include "lkb.h" -#include "rsb.h" -#include "nodes.h" -#include "config.h" -#include "memory.h" -#include "recover.h" - - -/* Types of entity serialised in remastering messages */ -#define REMASTER_ROOTRSB 1 -#define REMASTER_RSB 2 -#define REMASTER_LKB 3 - -struct rcom_fill { - char * outbuf; /* Beginning of data */ - int offset; /* Current offset into outbuf */ - int maxlen; /* Max value of offset */ - int remasterid; - int count; - struct dlm_rsb * rsb; - struct dlm_rsb * subrsb; - struct dlm_lkb * lkb; - struct list_head * lkbqueue; - char more; -}; -typedef struct rcom_fill rcom_fill_t; - - -struct rebuild_node { - struct list_head list; - int nodeid; - struct dlm_rsb * rootrsb; -}; -typedef struct rebuild_node rebuild_node_t; - - -/* - * Root rsb passed in for which all lkb's (own and subrsbs) will be sent to new - * master. The rsb will be "done" with recovery when the new master has - * replied with all the new remote lockid's for this rsb's lkb's. - */ - -void expect_new_lkids(struct dlm_rsb *rsb) -{ - rsb->res_newlkid_expect = 0; - recover_list_add(rsb); -} - -/* - * This function is called on root rsb or subrsb when another lkb is being sent - * to the new master for which we expect to receive a corresponding remote lkid - */ - -void need_new_lkid(struct dlm_rsb *rsb) -{ - struct dlm_rsb *root = rsb; - - if (rsb->res_parent) - root = rsb->res_root; - - if (!root->res_newlkid_expect) - recover_list_add(root); - else - DLM_ASSERT(test_bit(RESFL_RECOVER_LIST, &root->res_flags),); - - root->res_newlkid_expect++; -} - -/* - * This function is called for each lkb for which a new remote lkid is - * received. Decrement the expected number of remote lkids expected for the - * root rsb. - */ - -void have_new_lkid(struct dlm_lkb *lkb) -{ - struct dlm_rsb *root = lkb->lkb_resource; - - if (root->res_parent) - root = root->res_root; - - down_write(&root->res_lock); - - DLM_ASSERT(root->res_newlkid_expect, - printk("newlkid_expect=%d\n", root->res_newlkid_expect);); - - root->res_newlkid_expect--; - - if (!root->res_newlkid_expect) { - clear_bit(RESFL_NEW_MASTER, &root->res_flags); - recover_list_del(root); - } - up_write(&root->res_lock); -} - -/* - * Return the rebuild struct for a node - will create an entry on the rootrsb - * list if necessary. - * - * Currently no locking is needed here as it all happens in the dlm_recvd - * thread - */ - -static rebuild_node_t *find_rebuild_root(struct dlm_ls *ls, int nodeid) -{ - rebuild_node_t *node = NULL; - - list_for_each_entry(node, &ls->ls_rebuild_rootrsb_list, list) { - if (node->nodeid == nodeid) - return node; - } - - /* Not found, add one */ - node = kmalloc(sizeof(rebuild_node_t), GFP_KERNEL); - if (!node) - return NULL; - - node->nodeid = nodeid; - node->rootrsb = NULL; - list_add(&node->list, &ls->ls_rebuild_rootrsb_list); - - return node; -} - -static void free_rebuild_root(rebuild_node_t *rnode) -{ - list_del(&rnode->list); - kfree(rnode); -} - -/* - * Tidy up after a rebuild run. Called when all recovery has finished - */ - -void rebuild_freemem(struct dlm_ls *ls) -{ - rebuild_node_t *node = NULL, *s; - - list_for_each_entry_safe(node, s, &ls->ls_rebuild_rootrsb_list, list) { - list_del(&node->list); - kfree(node); - } -} - -static void put_int(int x, char *buf, int *offp) -{ - x = cpu_to_le32(x); - memcpy(buf + *offp, &x, sizeof(int)); - *offp += sizeof(int); -} - -static void put_int64(uint64_t x, char *buf, int *offp) -{ - x = cpu_to_le64(x); - memcpy(buf + *offp, &x, sizeof(uint64_t)); - *offp += sizeof(uint64_t); -} - -static void put_bytes(char *x, int len, char *buf, int *offp) -{ - put_int(len, buf, offp); - memcpy(buf + *offp, x, len); - *offp += len; -} - -static void put_char(char x, char *buf, int *offp) -{ - buf[*offp] = x; - *offp += 1; -} - -static int get_int(char *buf, int *offp) -{ - int value; - memcpy(&value, buf + *offp, sizeof(int)); - *offp += sizeof(int); - return le32_to_cpu(value); -} - -static uint64_t get_int64(char *buf, int *offp) -{ - uint64_t value; - - memcpy(&value, buf + *offp, sizeof(uint64_t)); - *offp += sizeof(uint64_t); - return le64_to_cpu(value); -} - -static char get_char(char *buf, int *offp) -{ - char x = buf[*offp]; - - *offp += 1; - return x; -} - -static void get_bytes(char *bytes, int *len, char *buf, int *offp) -{ - *len = get_int(buf, offp); - memcpy(bytes, buf + *offp, *len); - *offp += *len; -} - -static int lkb_length(struct dlm_lkb *lkb) -{ - int len = 0; - - len += sizeof(int); /* lkb_id */ - len += sizeof(int); /* lkb_resource->res_reamasterid */ - len += sizeof(int); /* lkb_flags */ - len += sizeof(int); /* lkb_lockqueue_flags */ - len += sizeof(int); /* lkb_status */ - len += sizeof(char); /* lkb_rqmode */ - len += sizeof(char); /* lkb_grmode */ - len += sizeof(int); /* lkb_childcnt */ - len += sizeof(int); /* lkb_parent->lkb_id */ - len += sizeof(int); /* lkb_bastaddr */ - len += sizeof(int); /* lkb_ownpid */ - len += sizeof(int); /* lkb_lvbseq */ - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) { - len += sizeof(int); /* number of lvb bytes */ - len += DLM_LVB_LEN; - } - - if (lkb->lkb_range) { - len += sizeof(uint64_t); - len += sizeof(uint64_t); - if (lkb->lkb_status == GDLM_LKSTS_CONVERT) { - len += sizeof(uint64_t); - len += sizeof(uint64_t); - } - } - - return len; -} - -/* - * It's up to the caller to be sure there's enough space in the buffer. - */ - -static void serialise_lkb(struct dlm_lkb *lkb, char *buf, int *offp) -{ - int flags; - - /* Need to tell the remote end if we have a range */ - flags = lkb->lkb_flags; - if (lkb->lkb_range) - flags |= GDLM_LKFLG_RANGE; - - /* - * See lkb_length() - * Total: 30 (no lvb) or 66 (with lvb) bytes - */ - - put_int(lkb->lkb_id, buf, offp); - put_int(lkb->lkb_resource->res_remasterid, buf, offp); - put_int(flags, buf, offp); - put_int(lkb->lkb_lockqueue_flags, buf, offp); - put_int(lkb->lkb_status, buf, offp); - put_char(lkb->lkb_rqmode, buf, offp); - put_char(lkb->lkb_grmode, buf, offp); - put_int(atomic_read(&lkb->lkb_childcnt), buf, offp); - - if (lkb->lkb_parent) - put_int(lkb->lkb_parent->lkb_id, buf, offp); - else - put_int(0, buf, offp); - - if (lkb->lkb_bastaddr) - put_int(1, buf, offp); - else - put_int(0, buf, offp); - put_int(lkb->lkb_ownpid, buf, offp); - put_int(lkb->lkb_lvbseq, buf, offp); - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) { - DLM_ASSERT(lkb->lkb_lvbptr,); - put_bytes(lkb->lkb_lvbptr, DLM_LVB_LEN, buf, offp); - } - - /* Only send the range we actually need */ - if (lkb->lkb_range) { - switch (lkb->lkb_status) { - case GDLM_LKSTS_CONVERT: - put_int64(lkb->lkb_range[RQ_RANGE_START], buf, offp); - put_int64(lkb->lkb_range[RQ_RANGE_END], buf, offp); - put_int64(lkb->lkb_range[GR_RANGE_START], buf, offp); - put_int64(lkb->lkb_range[GR_RANGE_END], buf, offp); - break; - case GDLM_LKSTS_WAITING: - put_int64(lkb->lkb_range[RQ_RANGE_START], buf, offp); - put_int64(lkb->lkb_range[RQ_RANGE_END], buf, offp); - break; - case GDLM_LKSTS_GRANTED: - put_int64(lkb->lkb_range[GR_RANGE_START], buf, offp); - put_int64(lkb->lkb_range[GR_RANGE_END], buf, offp); - break; - default: - DLM_ASSERT(0,); - } - } -} - -static int rsb_length(struct dlm_rsb *rsb) -{ - int len = 0; - - len += sizeof(int); /* number of res_name bytes */ - len += rsb->res_length; /* res_name */ - len += sizeof(int); /* res_remasterid */ - len += sizeof(int); /* res_parent->res_remasterid */ - - return len; -} - -static inline struct dlm_rsb *next_subrsb(struct dlm_rsb *subrsb) -{ - struct list_head *tmp; - struct dlm_rsb *r; - - tmp = subrsb->res_subreslist.next; - r = list_entry(tmp, struct dlm_rsb, res_subreslist); - - return r; -} - -static inline int last_in_list(struct dlm_rsb *r, struct list_head *head) -{ - struct dlm_rsb *last; - last = list_entry(head->prev, struct dlm_rsb, res_subreslist); - if (last == r) - return 1; - return 0; -} - -static int lkbs_to_remaster_list(struct list_head *head) -{ - struct dlm_lkb *lkb; - - list_for_each_entry(lkb, head, lkb_statequeue) { - if (lkb->lkb_flags & GDLM_LKFLG_NOREBUILD) - continue; - return TRUE; - } - return FALSE; -} - -/* - * Used to decide if an rsb should be rebuilt on a new master. An rsb only - * needs to be rebuild if we have lkb's queued on it. NOREBUILD lkb's are not - * rebuilt. - */ - -static int lkbs_to_remaster(struct dlm_rsb *r) -{ - struct dlm_rsb *sub; - - if (lkbs_to_remaster_list(&r->res_grantqueue)) - return TRUE; - if (lkbs_to_remaster_list(&r->res_convertqueue)) - return TRUE; - if (lkbs_to_remaster_list(&r->res_waitqueue)) - return TRUE; - - list_for_each_entry(sub, &r->res_subreslist, res_subreslist) { - if (lkbs_to_remaster_list(&sub->res_grantqueue)) - return TRUE; - if (lkbs_to_remaster_list(&sub->res_convertqueue)) - return TRUE; - if (lkbs_to_remaster_list(&sub->res_waitqueue)) - return TRUE; - } - - return FALSE; -} - -static void serialise_rsb(struct dlm_rsb *rsb, char *buf, int *offp) -{ - /* - * See rsb_length() - * Total: 36 bytes (4 + 24 + 4 + 4) - */ - - put_bytes(rsb->res_name, rsb->res_length, buf, offp); - put_int(rsb->res_remasterid, buf, offp); - - if (rsb->res_parent) - put_int(rsb->res_parent->res_remasterid, buf, offp); - else - put_int(0, buf, offp); - - DLM_ASSERT(!rsb->res_lvbptr,); -} - -/* - * Flatten an LKB into a buffer for sending to the new RSB master. As a - * side-effect the nodeid of the lock is set to the nodeid of the new RSB - * master. - */ - -static int pack_one_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb, - rcom_fill_t *fill) -{ - if (fill->offset + 1 + lkb_length(lkb) > fill->maxlen) - goto nospace; - - lkb->lkb_nodeid = r->res_nodeid; - - put_char(REMASTER_LKB, fill->outbuf, &fill->offset); - serialise_lkb(lkb, fill->outbuf, &fill->offset); - - fill->count++; - need_new_lkid(r); - return 0; - - nospace: - return -ENOSPC; -} - -/* - * Pack all LKB's from a given queue, except for those with the NOREBUILD flag. - */ - -static int pack_lkb_queue(struct dlm_rsb *r, struct list_head *queue, - rcom_fill_t *fill) -{ - struct dlm_lkb *lkb; - int error; - - list_for_each_entry(lkb, queue, lkb_statequeue) { - if (lkb->lkb_flags & GDLM_LKFLG_NOREBUILD) - continue; - - error = pack_one_lkb(r, lkb, fill); - if (error) - goto nospace; - } - - return 0; - - nospace: - fill->lkb = lkb; - fill->lkbqueue = queue; - - return error; -} - -static int pack_lkb_queues(struct dlm_rsb *r, rcom_fill_t *fill) -{ - int error; - - error = pack_lkb_queue(r, &r->res_grantqueue, fill); - if (error) - goto nospace; - - error = pack_lkb_queue(r, &r->res_convertqueue, fill); - if (error) - goto nospace; - - error = pack_lkb_queue(r, &r->res_waitqueue, fill); - - nospace: - return error; -} - -/* - * Pack remaining lkb's for rsb or subrsb. This may include a partial lkb - * queue and full lkb queues. - */ - -static int pack_lkb_remaining(struct dlm_rsb *r, rcom_fill_t *fill) -{ - struct list_head *tmp, *start, *end; - struct dlm_lkb *lkb; - int error; - - /* - * Beginning with fill->lkb, pack remaining lkb's on fill->lkbqueue. - */ - - error = pack_one_lkb(r, fill->lkb, fill); - if (error) - goto out; - - start = fill->lkb->lkb_statequeue.next; - end = fill->lkbqueue; - - for (tmp = start; tmp != end; tmp = tmp->next) { - lkb = list_entry(tmp, struct dlm_lkb, lkb_statequeue); - - error = pack_one_lkb(r, lkb, fill); - if (error) { - fill->lkb = lkb; - goto out; - } - } - - /* - * Pack all lkb's on r's queues following fill->lkbqueue. - */ - - if (fill->lkbqueue == &r->res_waitqueue) - goto out; - if (fill->lkbqueue == &r->res_convertqueue) - goto skip; - - DLM_ASSERT(fill->lkbqueue == &r->res_grantqueue,); - - error = pack_lkb_queue(r, &r->res_convertqueue, fill); - if (error) - goto out; - skip: - error = pack_lkb_queue(r, &r->res_waitqueue, fill); - - out: - return error; -} - -static int pack_one_subrsb(struct dlm_rsb *rsb, struct dlm_rsb *subrsb, - rcom_fill_t *fill) -{ - int error; - - down_write(&subrsb->res_lock); - - if (fill->offset + 1 + rsb_length(subrsb) > fill->maxlen) - goto nospace; - - subrsb->res_nodeid = rsb->res_nodeid; - subrsb->res_remasterid = ++fill->remasterid; - - put_char(REMASTER_RSB, fill->outbuf, &fill->offset); - serialise_rsb(subrsb, fill->outbuf, &fill->offset); - - error = pack_lkb_queues(subrsb, fill); - if (error) - goto nospace; - - up_write(&subrsb->res_lock); - - return 0; - - nospace: - up_write(&subrsb->res_lock); - fill->subrsb = subrsb; - - return -ENOSPC; -} - -static int pack_subrsbs(struct dlm_rsb *rsb, struct dlm_rsb *in_subrsb, - rcom_fill_t *fill) -{ - struct dlm_rsb *subrsb; - int error = 0; - - /* - * When an initial subrsb is given, we know it needs to be packed. - * When no initial subrsb is given, begin with the first (if any exist). - */ - - if (!in_subrsb) { - if (list_empty(&rsb->res_subreslist)) - goto out; - - subrsb = list_entry(rsb->res_subreslist.next, struct dlm_rsb, - res_subreslist); - } else - subrsb = in_subrsb; - - for (;;) { - error = pack_one_subrsb(rsb, subrsb, fill); - if (error) - goto out; - - if (last_in_list(subrsb, &rsb->res_subreslist)) - break; - - subrsb = next_subrsb(subrsb); - } - - out: - return error; -} - -/* - * Finish packing whatever is left in an rsb tree. If space runs out while - * finishing, save subrsb/lkb and this will be called again for the same rsb. - * - * !subrsb && lkb, we left off part way through root rsb's lkbs. - * subrsb && !lkb, we left off just before starting a new subrsb. - * subrsb && lkb, we left off part way through a subrsb's lkbs. - * !subrsb && !lkb, we shouldn't be in this function, but starting - * a new rsb in pack_rsb_tree(). - */ - -static int pack_rsb_tree_remaining(struct dlm_ls *ls, struct dlm_rsb *rsb, - rcom_fill_t *fill) -{ - struct dlm_rsb *subrsb = NULL; - int error = 0; - - if (!fill->subrsb && fill->lkb) { - error = pack_lkb_remaining(rsb, fill); - if (error) - goto out; - - error = pack_subrsbs(rsb, NULL, fill); - if (error) - goto out; - } - - else if (fill->subrsb && !fill->lkb) { - error = pack_subrsbs(rsb, fill->subrsb, fill); - if (error) - goto out; - } - - else if (fill->subrsb && fill->lkb) { - error = pack_lkb_remaining(fill->subrsb, fill); - if (error) - goto out; - - if (last_in_list(fill->subrsb, &fill->rsb->res_subreslist)) - goto out; - - subrsb = next_subrsb(fill->subrsb); - - error = pack_subrsbs(rsb, subrsb, fill); - if (error) - goto out; - } - - fill->subrsb = NULL; - fill->lkb = NULL; - - out: - return error; -} - -/* - * Pack an RSB, all its LKB's, all its subrsb's and all their LKB's into a - * buffer. When the buffer runs out of space, save the place to restart (the - * queue+lkb, subrsb, or subrsb+queue+lkb which wouldn't fit). - */ - -static int pack_rsb_tree(struct dlm_ls *ls, struct dlm_rsb *rsb, - rcom_fill_t *fill) -{ - int error = -ENOSPC; - - fill->remasterid = 0; - - /* - * Pack the root rsb itself. A 1 byte type precedes the serialised - * rsb. Then pack the lkb's for the root rsb. - */ - - down_write(&rsb->res_lock); - - if (fill->offset + 1 + rsb_length(rsb) > fill->maxlen) - goto out; - - rsb->res_remasterid = ++fill->remasterid; - put_char(REMASTER_ROOTRSB, fill->outbuf, &fill->offset); - serialise_rsb(rsb, fill->outbuf, &fill->offset); - - error = pack_lkb_queues(rsb, fill); - if (error) - goto out; - - up_write(&rsb->res_lock); - - /* - * Pack subrsb/lkb's under the root rsb. - */ - - error = pack_subrsbs(rsb, NULL, fill); - - return error; - - out: - up_write(&rsb->res_lock); - return error; -} - -/* - * Given an RSB, return the next RSB that should be sent to a new master. - */ - -static struct dlm_rsb *next_remastered_rsb(struct dlm_ls *ls, - struct dlm_rsb *rsb) -{ - struct list_head *tmp, *start, *end; - struct dlm_rsb *r; - - if (!rsb) - start = ls->ls_rootres.next; - else - start = rsb->res_rootlist.next; - - end = &ls->ls_rootres; - - for (tmp = start; tmp != end; tmp = tmp->next) { - r = list_entry(tmp, struct dlm_rsb, res_rootlist); - - if (test_bit(RESFL_NEW_MASTER, &r->res_flags)) { - if (r->res_nodeid && lkbs_to_remaster(r)) { - expect_new_lkids(r); - return r; - } else - clear_bit(RESFL_NEW_MASTER, &r->res_flags); - } - } - - return NULL; -} - -/* - * Given an rcom buffer, fill it with RSB's that need to be sent to a single - * new master node. In the case where all the data to send to one node - * requires multiple messages, this function needs to resume filling each - * successive buffer from the point where it left off when the previous buffer - * filled up. - */ - -static void fill_rcom_buffer(struct dlm_ls *ls, rcom_fill_t *fill, - uint32_t *nodeid) -{ - struct dlm_rsb *rsb, *prev_rsb = fill->rsb; - int error; - - fill->offset = 0; - - if (!prev_rsb) { - - /* - * The first time this function is called. - */ - - rsb = next_remastered_rsb(ls, NULL); - if (!rsb) - goto no_more; - - } else if (fill->subrsb || fill->lkb) { - - /* - * Continue packing an rsb tree that was partially packed last - * time (fill->subrsb/lkb indicates where packing of last block - * left off) - */ - - rsb = prev_rsb; - *nodeid = rsb->res_nodeid; - - error = pack_rsb_tree_remaining(ls, rsb, fill); - if (error == -ENOSPC) - goto more; - - rsb = next_remastered_rsb(ls, prev_rsb); - if (!rsb) - goto no_more; - - if (rsb->res_nodeid != prev_rsb->res_nodeid) - goto more; - } else { - rsb = prev_rsb; - } - - /* - * Pack rsb trees into the buffer until we run out of space, run out of - * new rsb's or hit a new nodeid. - */ - - *nodeid = rsb->res_nodeid; - - for (;;) { - error = pack_rsb_tree(ls, rsb, fill); - if (error == -ENOSPC) - goto more; - - prev_rsb = rsb; - - rsb = next_remastered_rsb(ls, prev_rsb); - if (!rsb) - goto no_more; - - if (rsb->res_nodeid != prev_rsb->res_nodeid) - goto more; - } - - more: - fill->more = 1; - fill->rsb = rsb; - return; - - no_more: - fill->more = 0; -} - -/* - * Send lkb's (and subrsb/lkbs) for remastered root rsbs to new masters. - */ - -int rebuild_rsbs_send(struct dlm_ls *ls) -{ - struct dlm_rcom *rc; - rcom_fill_t fill; - uint32_t nodeid; - int error; - - DLM_ASSERT(recover_list_empty(ls),); - - log_debug(ls, "rebuild locks"); - - error = -ENOMEM; - rc = allocate_rcom_buffer(ls); - if (!rc) - goto ret; - - down_read(&ls->ls_root_lock); - - error = 0; - memset(&fill, 0, sizeof(rcom_fill_t)); - fill.outbuf = rc->rc_buf; - fill.maxlen = dlm_config.buffer_size - sizeof(struct dlm_rcom); - - do { - fill_rcom_buffer(ls, &fill, &nodeid); - if (!fill.offset) - break; - - rc->rc_datalen = fill.offset; - error = rcom_send_message(ls, nodeid, RECCOMM_NEWLOCKS, rc, 0); - if (error) { - up_read(&ls->ls_root_lock); - goto out; - } - - schedule(); - error = dlm_recovery_stopped(ls); - if (error) { - up_read(&ls->ls_root_lock); - goto out; - } - } - while (fill.more); - - up_read(&ls->ls_root_lock); - - error = dlm_wait_function(ls, &recover_list_empty); - - log_debug(ls, "rebuilt %d locks", fill.count); - - out: - free_rcom_buffer(rc); - - ret: - if (error) - recover_list_clear(ls); - return error; -} - -static struct dlm_rsb *find_by_remasterid(struct dlm_ls *ls, int remasterid, - struct dlm_rsb *rootrsb) -{ - struct dlm_rsb *rsb; - - DLM_ASSERT(rootrsb,); - - if (rootrsb->res_remasterid == remasterid) { - rsb = rootrsb; - goto out; - } - - list_for_each_entry(rsb, &rootrsb->res_subreslist, res_subreslist) { - if (rsb->res_remasterid == remasterid) - goto out; - } - rsb = NULL; - - out: - return rsb; -} - -/* - * Search a queue for the given remote lock id (remlkid). - */ - -static struct dlm_lkb *search_remlkid(struct list_head *statequeue, int nodeid, - int remid) -{ - struct dlm_lkb *lkb; - - list_for_each_entry(lkb, statequeue, lkb_statequeue) { - if (lkb->lkb_nodeid == nodeid && lkb->lkb_remid == remid) { - return lkb; - } - } - - return NULL; -} - -/* - * Given a remote lock ID (and a parent resource), return the local LKB for it - * Hopefully we dont need to do this too often on deep lock trees. This is - * VERY suboptimal for anything but the smallest lock trees. It searches the - * lock tree for an LKB with the remote id "remid" and the node "nodeid" and - * returns the LKB address. OPTIMISATION: we should keep a list of these while - * we are building up the remastered LKBs - */ - -static struct dlm_lkb *find_by_remlkid(struct dlm_rsb *rootrsb, int nodeid, - int remid) -{ - struct dlm_lkb *lkb; - struct dlm_rsb *rsb; - - lkb = search_remlkid(&rootrsb->res_grantqueue, nodeid, remid); - if (lkb) - goto out; - - lkb = search_remlkid(&rootrsb->res_convertqueue, nodeid, remid); - if (lkb) - goto out; - - lkb = search_remlkid(&rootrsb->res_waitqueue, nodeid, remid); - if (lkb) - goto out; - - list_for_each_entry(rsb, &rootrsb->res_subreslist, res_subreslist) { - lkb = search_remlkid(&rsb->res_grantqueue, nodeid, remid); - if (lkb) - goto out; - - lkb = search_remlkid(&rsb->res_convertqueue, nodeid, remid); - if (lkb) - goto out; - - lkb = search_remlkid(&rsb->res_waitqueue, nodeid, remid); - if (lkb) - goto out; - } - lkb = NULL; - - out: - return lkb; -} - -/* - * Unpack an LKB from a remaster operation - */ - -static int deserialise_lkb(struct dlm_ls *ls, int rem_nodeid, - struct dlm_rsb *rootrsb, char *buf, int *ptr, - char *outbuf, int *outoffp) -{ - struct dlm_lkb *lkb, *exist_lkb = NULL; - struct dlm_rsb *rsb; - int error = -ENOMEM, parentid, rsb_rmid, remote_lkid, status, temp; - - remote_lkid = get_int(buf, ptr); - - rsb_rmid = get_int(buf, ptr); - rsb = find_by_remasterid(ls, rsb_rmid, rootrsb); - DLM_ASSERT(rsb, printk("no RSB for remasterid %d\n", rsb_rmid);); - - /* - * We could have received this lkb already from a previous recovery - * that was interrupted. We still need to advance ptr so read in - * lkb and then release it. FIXME: verify this is valid. - */ - lkb = find_by_remlkid(rsb, rem_nodeid, remote_lkid); - if (lkb) - exist_lkb = lkb; - - lkb = create_lkb(ls); - if (!lkb) - goto out; - - lkb->lkb_remid = remote_lkid; - lkb->lkb_flags = get_int(buf, ptr); - lkb->lkb_lockqueue_flags = get_int(buf, ptr); - status = get_int(buf, ptr); - lkb->lkb_rqmode = get_char(buf, ptr); - lkb->lkb_grmode = get_char(buf, ptr); - atomic_set(&lkb->lkb_childcnt, get_int(buf, ptr)); - - parentid = get_int(buf, ptr); - lkb->lkb_bastaddr = (void *) (long) get_int(buf, ptr); - lkb->lkb_ownpid = get_int(buf, ptr); - lkb->lkb_lvbseq = get_int(buf, ptr); - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) { - lkb->lkb_lvbptr = allocate_lvb(ls); - if (!lkb->lkb_lvbptr) - goto out; - get_bytes(lkb->lkb_lvbptr, &temp, buf, ptr); - } - - if (lkb->lkb_flags & GDLM_LKFLG_RANGE) { - uint64_t start, end; - - /* Don't need to keep the range flag, for comms use only */ - lkb->lkb_flags &= ~GDLM_LKFLG_RANGE; - start = get_int64(buf, ptr); - end = get_int64(buf, ptr); - - lkb->lkb_range = allocate_range(ls); - if (!lkb->lkb_range) - goto out; - - switch (status) { - case GDLM_LKSTS_CONVERT: - lkb->lkb_range[RQ_RANGE_START] = start; - lkb->lkb_range[RQ_RANGE_END] = end; - start = get_int64(buf, ptr); - end = get_int64(buf, ptr); - lkb->lkb_range[GR_RANGE_START] = start; - lkb->lkb_range[GR_RANGE_END] = end; - - case GDLM_LKSTS_WAITING: - lkb->lkb_range[RQ_RANGE_START] = start; - lkb->lkb_range[RQ_RANGE_END] = end; - break; - - case GDLM_LKSTS_GRANTED: - lkb->lkb_range[GR_RANGE_START] = start; - lkb->lkb_range[GR_RANGE_END] = end; - break; - default: - DLM_ASSERT(0,); - } - } - - if (exist_lkb) { - /* verify lkb and exist_lkb values match? */ - release_lkb(ls, lkb); - lkb = exist_lkb; - goto put_lkid; - } - - /* Resolve local lock LKB address from parent ID */ - if (parentid) - lkb->lkb_parent = find_by_remlkid(rootrsb, rem_nodeid, - parentid); - - atomic_inc(&rsb->res_ref); - lkb->lkb_resource = rsb; - - lkb->lkb_flags |= GDLM_LKFLG_MSTCPY; - lkb->lkb_nodeid = rem_nodeid; - - /* - * Put the lkb on an RSB queue. An lkb that's in the midst of a - * conversion request (on the requesting node's lockqueue and has - * LQCONVERT set) should be put on the granted queue. The convert - * request will be resent by the requesting node. - */ - - if (lkb->lkb_flags & GDLM_LKFLG_LQCONVERT) { - lkb->lkb_flags &= ~GDLM_LKFLG_LQCONVERT; - DLM_ASSERT(status == GDLM_LKSTS_CONVERT, - printk("status=%d\n", status);); - lkb->lkb_rqmode = DLM_LOCK_IV; - status = GDLM_LKSTS_GRANTED; - } - - lkb_enqueue(rsb, lkb, status); - - /* - * Clear flags that may have been sent over that are only relevant in - * the context of the sender. - */ - - lkb->lkb_flags &= ~(GDLM_LKFLG_DELETED | GDLM_LKFLG_LQRESEND | - GDLM_LKFLG_NOREBUILD | GDLM_LKFLG_DEMOTED); - - if (lkb->lkb_flags & GDLM_LKFLG_VALBLK) - rsb_lvb_recovery(rsb); - - put_lkid: - /* Return the new LKID to the caller's buffer */ - put_int(lkb->lkb_id, outbuf, outoffp); - put_int(lkb->lkb_remid, outbuf, outoffp); - error = 0; - - out: - return error; -} - -static struct dlm_rsb *deserialise_rsb(struct dlm_ls *ls, int nodeid, - struct dlm_rsb *rootrsb, char *buf, - int *ptr) -{ - int length; - int remasterid; - int parent_remasterid; - char name[DLM_RESNAME_MAXLEN]; - int error; - struct dlm_rsb *parent = NULL; - struct dlm_rsb *rsb; - - get_bytes(name, &length, buf, ptr); - remasterid = get_int(buf, ptr); - parent_remasterid = get_int(buf, ptr); - - if (parent_remasterid) - parent = find_by_remasterid(ls, parent_remasterid, rootrsb); - - /* - * The rsb reference from this find_or_create_rsb() will keep the rsb - * around while we add new lkb's to it from deserialise_lkb. Each of - * the lkb's will add an rsb reference. The reference added here is - * removed by release_rsb() after all lkb's are added. - */ - - error = find_rsb(ls, parent, name, length, CREATE, &rsb); - DLM_ASSERT(!error,); - - set_bit(RESFL_MASTER, &rsb->res_flags); - - /* There is a case where the above needs to create the RSB. */ - if (rsb->res_nodeid == -1) - rsb->res_nodeid = our_nodeid(); - - rsb->res_remasterid = remasterid; - rsb->res_parent = parent; - - return rsb; -} - -/* - * Processing at the receiving end of a NEWLOCKS message from a node in - * rebuild_rsbs_send(). Rebuild a remastered lock tree. Nodeid is the remote - * node whose locks we are now mastering. For a reply we need to send back the - * new lockids of the remastered locks so that remote ops can find them. - */ - -int rebuild_rsbs_recv(struct dlm_ls *ls, int nodeid, char *buf, int len) -{ - struct dlm_rcom *rc; - struct dlm_rsb *rsb = NULL; - rebuild_node_t *rnode; - char *outbuf; - int outptr, ptr = 0, error = -ENOMEM; - - rnode = find_rebuild_root(ls, nodeid); - if (!rnode) - goto out; - - /* - * Allocate a buffer for the reply message which is a list of remote - * lock IDs and their (new) local lock ids. It will always be big - * enough to fit <n> ID pairs if it already fit <n> LKBs. - */ - - rc = allocate_rcom_buffer(ls); - if (!rc) - goto out; - outbuf = rc->rc_buf; - outptr = 0; - - /* - * Unpack RSBs and LKBs, saving new LKB id's in outbuf as they're - * created. Each deserialise_rsb adds an rsb reference that must be - * removed with release_rsb once all new lkb's for an rsb have been - * added. - */ - - while (ptr < len) { - int type; - - type = get_char(buf, &ptr); - - switch (type) { - case REMASTER_ROOTRSB: - if (rsb) - release_rsb(rsb); - rsb = deserialise_rsb(ls, nodeid, rnode->rootrsb, buf, - &ptr); - rnode->rootrsb = rsb; - break; - - case REMASTER_RSB: - if (rsb) - release_rsb(rsb); - rsb = deserialise_rsb(ls, nodeid, rnode->rootrsb, buf, - &ptr); - break; - - case REMASTER_LKB: - if (!rnode->rootrsb) { - log_error(ls, "null rootrsb %d", nodeid); - free_rebuild_root(rnode); - free_rcom_buffer(rc); - goto out; - } - deserialise_lkb(ls, nodeid, rnode->rootrsb, buf, &ptr, - outbuf, &outptr); - break; - - default: - DLM_ASSERT(0, printk("type=%d nodeid=%u ptr=%d " - "len=%d\n", type, nodeid, ptr, - len);); - } - - schedule(); - } - - if (rsb) - release_rsb(rsb); - - /* - * Reply with the new lock IDs. - */ - - rc->rc_datalen = outptr; - error = rcom_send_message(ls, nodeid, RECCOMM_NEWLOCKIDS, rc, 0); - - free_rcom_buffer(rc); - - out: - return error; -} - -/* - * Processing for a NEWLOCKIDS message. Called when we get the reply from the - * new master telling us what the new remote lock IDs are for the remastered - * locks - */ - -int rebuild_rsbs_lkids_recv(struct dlm_ls *ls, int nodeid, char *buf, int len) -{ - int offset = 0; - - if (len == 1) - len = 0; - - while (offset < len) { - int remote_id; - int local_id; - struct dlm_lkb *lkb; - - if (offset + 8 > len) { - log_error(ls, "rebuild_rsbs_lkids_recv: bad data " - "length nodeid=%d offset=%d len=%d", - nodeid, offset, len); - break; - } - - remote_id = get_int(buf, &offset); - local_id = get_int(buf, &offset); - - lkb = find_lock_by_id(ls, local_id); - if (lkb) { - lkb->lkb_remid = remote_id; - have_new_lkid(lkb); - } else { - log_error(ls, "rebuild_rsbs_lkids_recv: unknown lkid " - "nodeid=%d id=%x remid=%x offset=%d len=%d", - nodeid, local_id, remote_id, offset, len); - } - } - - if (recover_list_empty(ls)) - wake_up(&ls->ls_wait_general); - - return 0; -} diff --git a/dlm-kernel/src/rebuild.h b/dlm-kernel/src/rebuild.h deleted file mode 100644 index 738488c..0000000 --- a/dlm-kernel/src/rebuild.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __REBUILD_DOT_H__ -#define __REBUILD_DOT_H__ - -int rebuild_rsbs_send(struct dlm_ls *ls); -int rebuild_rsbs_recv(struct dlm_ls *ls, int nodeid, char *buf, int len); -int rebuild_rsbs_lkids_recv(struct dlm_ls *ls, int nodeid, char *buf, int len); -int rebuild_freemem(struct dlm_ls *ls); - -#endif /* __REBUILD_DOT_H__ */ diff --git a/dlm-kernel/src/reccomms.c b/dlm-kernel/src/reccomms.c deleted file mode 100644 index d3837d1..0000000 --- a/dlm-kernel/src/reccomms.c +++ /dev/null @@ -1,430 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "dlm_internal.h" -#include "lowcomms.h" -#include "midcomms.h" -#include "reccomms.h" -#include "nodes.h" -#include "lockspace.h" -#include "recover.h" -#include "dir.h" -#include "config.h" -#include "rebuild.h" -#include "memory.h" - -/* Running on the basis that only a single recovery communication will be done - * at a time per lockspace */ - -static void rcom_process_message(struct dlm_ls *ls, uint32_t nodeid, struct dlm_rcom *rc); - -static int rcom_response(struct dlm_ls *ls) -{ - return test_bit(LSFL_RECCOMM_READY, &ls->ls_flags); -} - -/** - * rcom_send_message - send or request recovery data - * @ls: the lockspace - * @nodeid: node to which the message is sent - * @type: type of recovery message - * @rc: the rc buffer to send - * @need_reply: wait for reply if this is set - * - * Using this interface - * i) Allocate an rc buffer: - * rc = allocate_rcom_buffer(ls); - * ii) Copy data to send beginning at rc->rc_buf: - * memcpy(rc->rc_buf, mybuf, mylen); - * iii) Set rc->rc_datalen to the number of bytes copied in (ii): - * rc->rc_datalen = mylen - * iv) Submit the rc to this function: - * rcom_send_message(rc); - * - * The max value of "mylen" is dlm_config.buffer_size - sizeof(struct - * dlm_rcom). If more data must be passed in one send, use - * rcom_expand_buffer() which incrementally increases the size of the rc buffer - * by dlm_config.buffer_size bytes. - * - * Any data returned for the message (when need_reply is set) will saved in - * rc->rc_buf when this function returns and rc->rc_datalen will be set to the - * number of bytes copied into rc->rc_buf. - * - * Returns: 0 on success, -EXXX on failure - */ - -int rcom_send_message(struct dlm_ls *ls, uint32_t nodeid, int type, - struct dlm_rcom *rc, int need_reply) -{ - int error = 0; - - if (!rc->rc_datalen) - rc->rc_datalen = 1; - - /* - * Fill in the header. - * FIXME: set msgid's differently, rsb_master_lookup needs to - * set and remember the msgid before calling here. - */ - - rc->rc_header.rh_cmd = GDLM_REMCMD_RECOVERMESSAGE; - rc->rc_header.rh_lockspace = ls->ls_global_id; - rc->rc_header.rh_length = sizeof(struct dlm_rcom) + rc->rc_datalen - 1; - rc->rc_subcmd = type; - rc->rc_msgid = ++ls->ls_rcom_msgid; - - /* - * When a reply is received, the reply data goes back into this buffer. - * Synchronous rcom requests (need_reply=1) are serialised because of - * the single ls_rcom. After sending the message we'll wait at the end - * of this function to get a reply. The READY flag will be set when - * the reply has been received and requested data has been copied into - * ls->ls_rcom->rc_buf; - */ - - if (need_reply) { - down(&ls->ls_rcom_lock); - ls->ls_rcom = rc; - DLM_ASSERT(!test_bit(LSFL_RECCOMM_READY, &ls->ls_flags),); - } - - /* - * Process the message locally. - */ - - if (nodeid == our_nodeid()) { - rcom_process_message(ls, nodeid, rc); - goto out; - } - - /* - * Send the message. - */ - - error = midcomms_send_message(nodeid, (struct dlm_header *) rc, - GFP_KERNEL); - if (error > 0) - error = 0; - else if (error < 0) { - log_debug(ls, "send message %d to %u failed %d", - type, nodeid, error); - goto out; - } - - /* - * Wait for a reply. Once a reply is processed from midcomms, the - * READY bit will be set and we'll be awoken (dlm_wait_function will - * return 0). - */ - - if (need_reply) { - error = dlm_wait_function(ls, &rcom_response); - if (error) - log_debug(ls, "wait message %d to %u failed %d", - type, nodeid, error); - } - - out: - if (need_reply) { - clear_bit(LSFL_RECCOMM_READY, &ls->ls_flags); - up(&ls->ls_rcom_lock); - } - - return error; -} - -/* - * Runs in same context as midcomms. - */ - -static void rcom_process_message(struct dlm_ls *ls, uint32_t nodeid, struct dlm_rcom *rc) -{ - struct dlm_rcom rc_stack; - struct dlm_rcom *reply = NULL; - int status, datalen, maxlen; - uint32_t r_nodeid, be_nodeid; - - if (!ls) - return; - - if (dlm_recovery_stopped(ls) && (rc->rc_subcmd != RECCOMM_STATUS)) { - log_debug(ls, "ignoring recovery message %x from %u", - rc->rc_subcmd, nodeid); - return; - } - - switch (rc->rc_subcmd) { - - case RECCOMM_STATUS: - - memset(&rc_stack, 0, sizeof(struct dlm_rcom)); - reply = &rc_stack; - - reply->rc_header.rh_cmd = GDLM_REMCMD_RECOVERREPLY; - reply->rc_header.rh_lockspace = rc->rc_header.rh_lockspace; - reply->rc_subcmd = rc->rc_subcmd; - reply->rc_msgid = rc->rc_msgid; - reply->rc_buf[0] = 0; - - if (test_bit(LSFL_RESDIR_VALID, &ls->ls_flags)) - reply->rc_buf[0] |= RESDIR_VALID; - - if (test_bit(LSFL_ALL_RESDIR_VALID, &ls->ls_flags)) - reply->rc_buf[0] |= RESDIR_ALL_VALID; - - if (test_bit(LSFL_NODES_VALID, &ls->ls_flags)) - reply->rc_buf[0] |= NODES_VALID; - - if (test_bit(LSFL_ALL_NODES_VALID, &ls->ls_flags)) - reply->rc_buf[0] |= NODES_ALL_VALID; - - reply->rc_datalen = 1; - reply->rc_header.rh_length = - sizeof(struct dlm_rcom) + reply->rc_datalen - 1; - break; - - case RECCOMM_RECOVERNAMES: - - /* - * We can't run dlm_dir_rebuild_send (which uses ls_nodes) - * while dlm_recoverd is running ls_nodes_reconfig (which - * changes ls_nodes). It could only happen in rare cases where - * we get a late RECOVERNAMES message from a previous instance - * of recovery. - */ - if (!test_bit(LSFL_NODES_VALID, &ls->ls_flags)) { - log_debug(ls, "ignoring RECOVERNAMES from %u", nodeid); - return; - } - - reply = allocate_rcom_buffer(ls); - DLM_ASSERT(reply,); - maxlen = dlm_config.buffer_size - sizeof(struct dlm_rcom); - - reply->rc_header.rh_cmd = GDLM_REMCMD_RECOVERREPLY; - reply->rc_header.rh_lockspace = rc->rc_header.rh_lockspace; - reply->rc_subcmd = rc->rc_subcmd; - reply->rc_msgid = rc->rc_msgid; - - /* - * The other node wants a bunch of resource names. The name of - * the resource to begin with is in rc->rc_buf. - */ - - datalen = dlm_dir_rebuild_send(ls, rc->rc_buf, rc->rc_datalen, - reply->rc_buf, maxlen, nodeid); - - reply->rc_datalen = datalen; - reply->rc_header.rh_length = - sizeof(struct dlm_rcom) + reply->rc_datalen - 1; - break; - - case RECCOMM_GETMASTER: - - reply = allocate_rcom_buffer(ls); - DLM_ASSERT(reply,); - - reply->rc_header.rh_cmd = GDLM_REMCMD_RECOVERREPLY; - reply->rc_header.rh_lockspace = rc->rc_header.rh_lockspace; - reply->rc_subcmd = rc->rc_subcmd; - reply->rc_msgid = rc->rc_msgid; - - /* - * The other node wants to know the master of a named resource. - */ - - status = dlm_dir_lookup(ls, nodeid, rc->rc_buf, rc->rc_datalen, - &r_nodeid); - if (status != 0) { - log_error(ls, "rcom lookup error %d", status); - free_rcom_buffer(reply); - reply = NULL; - return; - } - be_nodeid = cpu_to_be32(r_nodeid); - memcpy(reply->rc_buf, &be_nodeid, sizeof(uint32_t)); - reply->rc_datalen = sizeof(uint32_t); - reply->rc_header.rh_length = - sizeof(struct dlm_rcom) + reply->rc_datalen - 1; - break; - - /* - * These RECCOMM messages don't need replies. - */ - - case RECCOMM_NEWLOCKS: - - /* - * This should prevent us from processing any NEWLOCKS - * messages sent during a previous recovery instance. - */ - if (!test_bit(LSFL_RESDIR_VALID, &ls->ls_flags)) { - log_debug(ls, "ignoring NEWLOCKS from %u", nodeid); - return; - } - - rebuild_rsbs_recv(ls, nodeid, rc->rc_buf, rc->rc_datalen); - break; - - case RECCOMM_NEWLOCKIDS: - - if (!test_bit(LSFL_RESDIR_VALID, &ls->ls_flags)) { - log_debug(ls, "ignoring NEWLOCKIDS from %u", nodeid); - return; - } - - rebuild_rsbs_lkids_recv(ls, nodeid, rc->rc_buf, rc->rc_datalen); - break; - - case RECCOMM_REMRESDATA: - dlm_dir_remove(ls, nodeid, rc->rc_buf, rc->rc_datalen); - break; - - default: - DLM_ASSERT(0, printk("cmd=%x\n", rc->rc_subcmd);); - } - - if (reply) { - if (nodeid == our_nodeid()) { - DLM_ASSERT(rc == ls->ls_rcom,); - memcpy(rc->rc_buf, reply->rc_buf, reply->rc_datalen); - rc->rc_datalen = reply->rc_datalen; - } else { - midcomms_send_message(nodeid, - (struct dlm_header *) reply, - GFP_KERNEL); - } - - if (reply != &rc_stack) - free_rcom_buffer(reply); - } -} - -static void process_reply_sync(struct dlm_ls *ls, uint32_t nodeid, - struct dlm_rcom *reply) -{ - struct dlm_rcom *rc = ls->ls_rcom; - - if (reply->rc_msgid != le32_to_cpu(rc->rc_msgid)) { - log_error(ls, "unexpected rcom msgid %x/%x nodeid=%u", - reply->rc_msgid, le32_to_cpu(rc->rc_msgid), nodeid); - return; - } - - memcpy(rc->rc_buf, reply->rc_buf, reply->rc_datalen); - rc->rc_datalen = reply->rc_datalen; - - /* - * Tell the thread waiting in rcom_send_message() that it can go ahead. - */ - - set_bit(LSFL_RECCOMM_READY, &ls->ls_flags); - wake_up(&ls->ls_wait_general); -} - -static void process_reply_async(struct dlm_ls *ls, uint32_t nodeid, - struct dlm_rcom *reply) -{ - restbl_rsb_update_recv(ls, nodeid, reply->rc_buf, reply->rc_datalen, - reply->rc_msgid); -} - -/* - * Runs in same context as midcomms. - */ - -static void rcom_process_reply(struct dlm_ls *ls, uint32_t nodeid, - struct dlm_rcom *reply) -{ - if (dlm_recovery_stopped(ls)) { - log_debug(ls, "ignoring recovery reply %x from %u", - reply->rc_subcmd, nodeid); - return; - } - - switch (reply->rc_subcmd) { - case RECCOMM_GETMASTER: - process_reply_async(ls, nodeid, reply); - break; - case RECCOMM_STATUS: - case RECCOMM_NEWLOCKS: - case RECCOMM_NEWLOCKIDS: - case RECCOMM_RECOVERNAMES: - process_reply_sync(ls, nodeid, reply); - break; - default: - log_error(ls, "unknown rcom reply subcmd=%x nodeid=%u", - reply->rc_subcmd, nodeid); - } -} - - -static int send_ls_not_ready(uint32_t nodeid, struct dlm_header *header) -{ - struct writequeue_entry *wq; - struct dlm_rcom *rc = (struct dlm_rcom *) header; - struct dlm_rcom *reply; - - wq = lowcomms_get_buffer(nodeid, sizeof(struct dlm_rcom), GFP_KERNEL, - (char **)&reply); - if (!wq) - return -ENOMEM; - - reply->rc_header.rh_cmd = GDLM_REMCMD_RECOVERREPLY; - reply->rc_header.rh_lockspace = rc->rc_header.rh_lockspace; - reply->rc_subcmd = rc->rc_subcmd; - reply->rc_msgid = rc->rc_msgid; - reply->rc_buf[0] = 0; - - reply->rc_datalen = 1; - reply->rc_header.rh_length = sizeof(struct dlm_rcom) + reply->rc_datalen - 1; - - midcomms_send_buffer((struct dlm_header *)reply, wq); - return 0; -} - - -/* - * Runs in same context as midcomms. Both recovery requests and recovery - * replies come through this function. - */ - -void process_recovery_comm(uint32_t nodeid, struct dlm_header *header) -{ - struct dlm_ls *ls = find_lockspace_by_global_id(header->rh_lockspace); - struct dlm_rcom *rc = (struct dlm_rcom *) header; - - /* If the lockspace doesn't exist then still send a status message - back; it's possible that it just doesn't have its global_id yet. */ - - if (!ls) { - send_ls_not_ready(nodeid, header); - return; - } - - switch (header->rh_cmd) { - case GDLM_REMCMD_RECOVERMESSAGE: - rcom_process_message(ls, nodeid, rc); - break; - - case GDLM_REMCMD_RECOVERREPLY: - rcom_process_reply(ls, nodeid, rc); - break; - - default: - DLM_ASSERT(0, printk("cmd=%x\n", header->rh_cmd);); - } - - put_lockspace(ls); -} - diff --git a/dlm-kernel/src/reccomms.h b/dlm-kernel/src/reccomms.h deleted file mode 100644 index fead7b2..0000000 --- a/dlm-kernel/src/reccomms.h +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __RECCOMMS_DOT_H__ -#define __RECCOMMS_DOT_H__ - -/* Bit flags */ - -#define RESDIR_VALID (1) -#define RESDIR_ALL_VALID (2) -#define NODES_VALID (4) -#define NODES_ALL_VALID (8) - -#define RECCOMM_STATUS (1) -#define RECCOMM_RECOVERNAMES (2) -#define RECCOMM_GETMASTER (3) -#define RECCOMM_BULKLOOKUP (4) -#define RECCOMM_NEWLOCKS (5) -#define RECCOMM_NEWLOCKIDS (6) -#define RECCOMM_REMRESDATA (7) - -int rcom_send_message(struct dlm_ls *ls, uint32_t nodeid, int type, - struct dlm_rcom *rc, int need_reply); -void process_recovery_comm(uint32_t nodeid, struct dlm_header *header); - -#endif diff --git a/dlm-kernel/src/recover.c b/dlm-kernel/src/recover.c deleted file mode 100644 index f72090f..0000000 --- a/dlm-kernel/src/recover.c +++ /dev/null @@ -1,701 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "dlm_internal.h" -#include "reccomms.h" -#include "dir.h" -#include "locking.h" -#include "rsb.h" -#include "lockspace.h" -#include "lkb.h" -#include "nodes.h" -#include "config.h" -#include "ast.h" -#include "memory.h" - -/* - * Called in recovery routines to check whether the recovery process has been - * interrupted/stopped by another transition. A recovery in-process will abort - * if the lockspace is "stopped" so that a new recovery process can start from - * the beginning when the lockspace is "started" again. - */ - -int dlm_recovery_stopped(struct dlm_ls *ls) -{ - return test_bit(LSFL_LS_STOP, &ls->ls_flags); -} - -static void dlm_wait_timer_fn(unsigned long data) -{ - struct dlm_ls *ls = (struct dlm_ls *) data; - - wake_up(&ls->ls_wait_general); -} - -/* - * Wait until given function returns non-zero or lockspace is stopped (LS_STOP - * set due to failure of a node in ls_nodes). When another function thinks it - * could have completed the waited-on task, they should wake up ls_wait_general - * to get an immediate response rather than waiting for the timer to detect the - * result. A timer wakes us up periodically while waiting to see if we should - * abort due to a node failure. - */ - -int dlm_wait_function(struct dlm_ls *ls, int (*testfn) (struct dlm_ls *ls)) -{ - struct timer_list timer; - int error = 0; - - init_timer(&timer); - timer.function = dlm_wait_timer_fn; - timer.data = (long) ls; - - for (;;) { - mod_timer(&timer, jiffies + (dlm_config.recover_timer * HZ)); - - wchan_cond_sleep_intr(ls->ls_wait_general, - !testfn(ls) && - !test_bit(LSFL_LS_STOP, &ls->ls_flags)); - - if (timer_pending(&timer)) - del_timer(&timer); - - if (testfn(ls)) - break; - - if (test_bit(LSFL_LS_STOP, &ls->ls_flags)) { - error = -1; - break; - } - } - - return error; -} - -int dlm_wait_status_all(struct dlm_ls *ls, unsigned int wait_status) -{ - struct dlm_rcom rc_stack, *rc; - struct dlm_csb *csb; - int status; - int error = 0; - - memset(&rc_stack, 0, sizeof(struct dlm_rcom)); - rc = &rc_stack; - rc->rc_datalen = 0; - - list_for_each_entry(csb, &ls->ls_nodes, list) { - for (;;) { - error = dlm_recovery_stopped(ls); - if (error) - goto out; - - error = rcom_send_message(ls, csb->node->nodeid, - RECCOMM_STATUS, rc, 1); - if (error) - goto out; - - status = rc->rc_buf[0]; - if (status & wait_status) - break; - else { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ >> 1); - } - } - } - - out: - return error; -} - -int dlm_wait_status_low(struct dlm_ls *ls, unsigned int wait_status) -{ - struct dlm_rcom rc_stack, *rc; - uint32_t nodeid = ls->ls_low_nodeid; - int status; - int error = 0; - - memset(&rc_stack, 0, sizeof(struct dlm_rcom)); - rc = &rc_stack; - rc->rc_datalen = 0; - - for (;;) { - error = dlm_recovery_stopped(ls); - if (error) - goto out; - - error = rcom_send_message(ls, nodeid, RECCOMM_STATUS, rc, 1); - if (error) - break; - - status = rc->rc_buf[0]; - if (status & wait_status) - break; - else { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ >> 1); - } - } - - out: - return error; -} - -static int purge_queue(struct dlm_ls *ls, struct list_head *queue) -{ - struct dlm_lkb *lkb, *safe; - struct dlm_rsb *rsb; - int count = 0; - - list_for_each_entry_safe(lkb, safe, queue, lkb_statequeue) { - if (!lkb->lkb_nodeid) - continue; - - DLM_ASSERT(lkb->lkb_flags & GDLM_LKFLG_MSTCPY,); - - if (in_nodes_gone(ls, lkb->lkb_nodeid)) { - list_del(&lkb->lkb_statequeue); - - rsb = lkb->lkb_resource; - lkb->lkb_status = 0; - - if (lkb->lkb_status == GDLM_LKSTS_CONVERT - && &lkb->lkb_duetime) - remove_from_deadlockqueue(lkb); - - release_lkb(ls, lkb); - release_rsb_locked(rsb); - count++; - } - } - - return count; -} - -/* - * Go through local restbl and for each rsb we're master of, clear out any - * lkb's held by departed nodes. - */ - -int restbl_lkb_purge(struct dlm_ls *ls) -{ - struct list_head *tmp2, *safe2; - int count = 0; - struct dlm_rsb *rootrsb, *safe, *rsb; - - log_debug(ls, "purge locks of departed nodes"); - down_write(&ls->ls_root_lock); - - list_for_each_entry_safe(rootrsb, safe, &ls->ls_rootres, res_rootlist) { - - if (rootrsb->res_nodeid) - continue; - - hold_rsb(rootrsb); - down_write(&rootrsb->res_lock); - - /* This traverses the subreslist in reverse order so we purge - * the children before their parents. */ - - for (tmp2 = rootrsb->res_subreslist.prev, safe2 = tmp2->prev; - tmp2 != &rootrsb->res_subreslist; - tmp2 = safe2, safe2 = safe2->prev) { - rsb = list_entry(tmp2, struct dlm_rsb, res_subreslist); - - hold_rsb(rsb); - purge_queue(ls, &rsb->res_grantqueue); - purge_queue(ls, &rsb->res_convertqueue); - purge_queue(ls, &rsb->res_waitqueue); - release_rsb_locked(rsb); - } - count += purge_queue(ls, &rootrsb->res_grantqueue); - count += purge_queue(ls, &rootrsb->res_convertqueue); - count += purge_queue(ls, &rootrsb->res_waitqueue); - - up_write(&rootrsb->res_lock); - release_rsb_locked(rootrsb); - - schedule(); - } - - up_write(&ls->ls_root_lock); - log_debug(ls, "purged %d locks", count); - - return 0; -} - -/* - * Grant any locks that have become grantable after a purge - */ - -int restbl_grant_after_purge(struct dlm_ls *ls) -{ - struct dlm_rsb *root, *rsb, *safe; - int error = 0; - - down_read(&ls->ls_root_lock); - - list_for_each_entry_safe(root, safe, &ls->ls_rootres, res_rootlist) { - /* only the rsb master grants locks */ - if (root->res_nodeid) - continue; - - if (!test_bit(LSFL_LS_RUN, &ls->ls_flags)) { - log_debug(ls, "restbl_grant_after_purge aborted"); - error = -EINTR; - up_read(&ls->ls_root_lock); - goto out; - } - - down_write(&root->res_lock); - grant_pending_locks(root); - up_write(&root->res_lock); - - list_for_each_entry(rsb, &root->res_subreslist, res_subreslist){ - down_write(&rsb->res_lock); - grant_pending_locks(rsb); - up_write(&rsb->res_lock); - } - } - up_read(&ls->ls_root_lock); - wake_astd(); - out: - return error; -} - -/* - * Set the lock master for all LKBs in a lock queue - */ - -static void set_lock_master(struct list_head *queue, int nodeid) -{ - struct dlm_lkb *lkb; - - list_for_each_entry(lkb, queue, lkb_statequeue) { - /* Don't muck around with pre-exising sublocks */ - if (!(lkb->lkb_flags & GDLM_LKFLG_MSTCPY)) - lkb->lkb_nodeid = nodeid; - } -} - -static void set_master_lkbs(struct dlm_rsb *rsb) -{ - set_lock_master(&rsb->res_grantqueue, rsb->res_nodeid); - set_lock_master(&rsb->res_convertqueue, rsb->res_nodeid); - set_lock_master(&rsb->res_waitqueue, rsb->res_nodeid); -} - -/* - * Propogate the new master nodeid to locks, subrsbs, sublocks. - * The NEW_MASTER flag tells rebuild_rsbs_send() which rsb's to consider. - * The NEW_MASTER2 flag tells rsb_lvb_recovery() which rsb's to consider. - */ - -static void set_new_master(struct dlm_rsb *rsb, uint32_t nodeid) -{ - struct dlm_rsb *subrsb; - - down_write(&rsb->res_lock); - - if (nodeid == our_nodeid()) { - set_bit(RESFL_MASTER, &rsb->res_flags); - rsb->res_nodeid = 0; - } else - rsb->res_nodeid = nodeid; - - set_master_lkbs(rsb); - - list_for_each_entry(subrsb, &rsb->res_subreslist, res_subreslist) { - subrsb->res_nodeid = rsb->res_nodeid; - set_master_lkbs(subrsb); - } - - up_write(&rsb->res_lock); - - set_bit(RESFL_NEW_MASTER, &rsb->res_flags); - set_bit(RESFL_NEW_MASTER2, &rsb->res_flags); -} - -/* - * The recover_list contains all the rsb's for which we've requested the new - * master nodeid. As replies are returned from the resource directories the - * rsb's are removed from the list. When the list is empty we're done. - * - * The recover_list is later similarly used for all rsb's for which we've sent - * new lkb's and need to receive new corresponding lkid's. - */ - -int recover_list_empty(struct dlm_ls *ls) -{ - int empty; - - spin_lock(&ls->ls_recover_list_lock); - empty = list_empty(&ls->ls_recover_list); - spin_unlock(&ls->ls_recover_list_lock); - - return empty; -} - -int recover_list_count(struct dlm_ls *ls) -{ - int count; - - spin_lock(&ls->ls_recover_list_lock); - count = ls->ls_recover_list_count; - spin_unlock(&ls->ls_recover_list_lock); - - return count; -} - -void recover_list_add(struct dlm_rsb *rsb) -{ - struct dlm_ls *ls = rsb->res_ls; - - spin_lock(&ls->ls_recover_list_lock); - if (!test_and_set_bit(RESFL_RECOVER_LIST, &rsb->res_flags)) { - list_add_tail(&rsb->res_recover_list, &ls->ls_recover_list); - ls->ls_recover_list_count++; - hold_rsb(rsb); - } - spin_unlock(&ls->ls_recover_list_lock); -} - -void recover_list_del(struct dlm_rsb *rsb) -{ - struct dlm_ls *ls = rsb->res_ls; - - spin_lock(&ls->ls_recover_list_lock); - clear_bit(RESFL_RECOVER_LIST, &rsb->res_flags); - list_del(&rsb->res_recover_list); - ls->ls_recover_list_count--; - spin_unlock(&ls->ls_recover_list_lock); - - release_rsb(rsb); -} - -static struct dlm_rsb *recover_list_find(struct dlm_ls *ls, int msgid) -{ - struct dlm_rsb *rsb = NULL; - - spin_lock(&ls->ls_recover_list_lock); - - list_for_each_entry(rsb, &ls->ls_recover_list, res_recover_list) { - if (rsb->res_recover_msgid == msgid) - goto rec_found; - } - rsb = NULL; - - rec_found: - spin_unlock(&ls->ls_recover_list_lock); - return rsb; -} - -void recover_list_clear(struct dlm_ls *ls) -{ - struct dlm_rsb *r, *s; - - spin_lock(&ls->ls_recover_list_lock); - list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { - list_del(&r->res_recover_list); - clear_bit(RESFL_RECOVER_LIST, &r->res_flags); - release_rsb(r); - ls->ls_recover_list_count--; - } - - if (ls->ls_recover_list_count != 0) { - log_error(ls, "warning: recover_list_count %d", - ls->ls_recover_list_count); - ls->ls_recover_list_count = 0; - } - spin_unlock(&ls->ls_recover_list_lock); -} - -static int rsb_master_lookup(struct dlm_rsb *rsb, struct dlm_rcom *rc) -{ - struct dlm_ls *ls = rsb->res_ls; - uint32_t dir_nodeid, r_nodeid; - int error; - - dir_nodeid = get_directory_nodeid(rsb); - - if (dir_nodeid == our_nodeid()) { - error = dlm_dir_lookup(ls, dir_nodeid, rsb->res_name, - rsb->res_length, &r_nodeid); - if (error == -EEXIST) { - log_error(ls, "rsb_master_lookup %u EEXIST %s", - r_nodeid, rsb->res_name); - } else if (error) - goto fail; - - set_new_master(rsb, r_nodeid); - } else { - /* NEW_MASTER2 may have been set by set_new_master() in the - previous recovery cycle. */ - - clear_bit(RESFL_NEW_MASTER2, &rsb->res_flags); - - /* As we are the only thread doing recovery this - should be safe. if not then we need to use a different - ID somehow. We must set it in the RSB before rcom_send_msg - completes cos we may get a reply quite quickly. */ - - rsb->res_recover_msgid = ls->ls_rcom_msgid + 1; - - recover_list_add(rsb); - - memcpy(rc->rc_buf, rsb->res_name, rsb->res_length); - rc->rc_datalen = rsb->res_length; - - error = rcom_send_message(ls, dir_nodeid, RECCOMM_GETMASTER, - rc, 0); - if (error) - goto fail; - } - - fail: - return error; -} - -static int needs_update(struct dlm_ls *ls, struct dlm_rsb *r) -{ - if (!r->res_nodeid) - return FALSE; - - if (r->res_nodeid == -1) - return FALSE; - - if (in_nodes_gone(ls, r->res_nodeid)) - return TRUE; - - return FALSE; -} - -/* - * Go through local root resources and for each rsb which has a master which - * has departed, get the new master nodeid from the resdir. The resdir will - * assign mastery to the first node to look up the new master. That means - * we'll discover in this lookup if we're the new master of any rsb's. - * - * We fire off all the resdir requests individually and asynchronously to the - * correct resdir node. The replies are processed in rsb_master_recv(). - */ - -int restbl_rsb_update(struct dlm_ls *ls) -{ - struct dlm_rsb *rsb, *safe; - struct dlm_rcom *rc; - int error = -ENOMEM; - int count = 0; - - log_debug(ls, "update remastered resources"); - - rc = allocate_rcom_buffer(ls); - if (!rc) - goto out; - - down_read(&ls->ls_root_lock); - - list_for_each_entry_safe(rsb, safe, &ls->ls_rootres, res_rootlist) { - error = dlm_recovery_stopped(ls); - if (error) { - up_read(&ls->ls_root_lock); - goto out_free; - } - - if (test_bit(RESFL_VALNOTVALID, &rsb->res_flags)) - set_bit(RESFL_VALNOTVALID_PREV, &rsb->res_flags); - else - clear_bit(RESFL_VALNOTVALID_PREV, &rsb->res_flags); - - if (needs_update(ls, rsb)) { - error = rsb_master_lookup(rsb, rc); - if (error) { - up_read(&ls->ls_root_lock); - goto out_free; - } - count++; - } - schedule(); - } - up_read(&ls->ls_root_lock); - - error = dlm_wait_function(ls, &recover_list_empty); - - log_debug(ls, "updated %d resources", count); - out_free: - if (error) - recover_list_clear(ls); - free_rcom_buffer(rc); - out: - return error; -} - -int restbl_rsb_update_recv(struct dlm_ls *ls, uint32_t nodeid, char *buf, - int length, int msgid) -{ - struct dlm_rsb *rsb; - uint32_t be_nodeid; - - rsb = recover_list_find(ls, msgid); - if (!rsb) { - log_error(ls, "restbl_rsb_update_recv rsb not found %d", msgid); - goto out; - } - - memcpy(&be_nodeid, buf, sizeof(uint32_t)); - set_new_master(rsb, be32_to_cpu(be_nodeid)); - recover_list_del(rsb); - - if (recover_list_empty(ls)) - wake_up(&ls->ls_wait_general); - - out: - return 0; -} - -/* - * This routine is called on all master rsb's by dlm_recoverd. It is also - * called on an rsb when a new lkb is received during the rebuild recovery - * stage (implying we are the new master for it.) So, a newly mastered rsb - * will often have this function called on it by dlm_recoverd and by dlm_recvd - * when a new lkb is received. - * - * This function is in charge of making sure the rsb's VALNOTVALID flag is - * set correctly and that the lvb contents are set correctly. - * - * RESFL_VALNOTVALID is set if: - * - it was set prior to recovery, OR - * - there are only NL/CR locks on the rsb - * - * RESFL_VALNOTVALID is cleared if: - * - it was not set prior to recovery, AND - * - there are locks > CR on the rsb - * - * (We'll only be clearing VALNOTVALID in this function if it - * was set in a prior call to this function when there were - * only NL/CR locks.) - * - * Whether this node is a new or old master of the rsb is not a factor - * in the decision to set/clear VALNOTVALID. - * - * The LVB contents are only considered for changing when this is a new master - * of the rsb (NEW_MASTER2). Then, the rsb's lvb is taken from any lkb with - * mode > CR. If no lkb's exist with mode above CR, the lvb contents are taken - * from the lkb with the largest lvb sequence nubmer. - */ - -void rsb_lvb_recovery(struct dlm_rsb *r) -{ - struct dlm_lkb *lkb, *high_lkb = NULL; - uint32_t high_seq = 0; - int lock_lvb_exists = FALSE; - int big_lock_exists = FALSE; - - down_write(&r->res_lock); - - list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) { - if (!(lkb->lkb_flags & GDLM_LKFLG_VALBLK)) - continue; - - if (lkb->lkb_flags & GDLM_LKFLG_DELETED) - continue; - - lock_lvb_exists = TRUE; - - if (lkb->lkb_grmode > DLM_LOCK_CR) { - big_lock_exists = TRUE; - goto setflag; - } - - if (((int)lkb->lkb_lvbseq - (int)high_seq) >= 0) { - high_lkb = lkb; - high_seq = lkb->lkb_lvbseq; - } - } - - list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) { - if (!(lkb->lkb_flags & GDLM_LKFLG_VALBLK)) - continue; - - if (lkb->lkb_flags & GDLM_LKFLG_DELETED) - continue; - - lock_lvb_exists = TRUE; - - if (lkb->lkb_grmode > DLM_LOCK_CR) { - big_lock_exists = TRUE; - goto setflag; - } - - if (((int)lkb->lkb_lvbseq - (int)high_seq) >= 0) { - high_lkb = lkb; - high_seq = lkb->lkb_lvbseq; - } - } - - setflag: - /* there are no locks with lvb's */ - if (!lock_lvb_exists) - goto out; - - /* don't clear valnotvalid if it was already set */ - if (test_bit(RESFL_VALNOTVALID_PREV, &r->res_flags)) - goto setlvb; - - if (big_lock_exists) - clear_bit(RESFL_VALNOTVALID, &r->res_flags); - else - set_bit(RESFL_VALNOTVALID, &r->res_flags); - - setlvb: - /* don't mess with the lvb unless we're the new master */ - if (!test_bit(RESFL_NEW_MASTER2, &r->res_flags)) - goto out; - - if (!r->res_lvbptr) - r->res_lvbptr = allocate_lvb(r->res_ls); - - if (big_lock_exists) { - r->res_lvbseq = lkb->lkb_lvbseq; - memcpy(r->res_lvbptr, lkb->lkb_lvbptr, DLM_LVB_LEN); - } else if (high_lkb) { - r->res_lvbseq = high_lkb->lkb_lvbseq; - memcpy(r->res_lvbptr, high_lkb->lkb_lvbptr, DLM_LVB_LEN); - } else { - r->res_lvbseq = 0; - memset(r->res_lvbptr, 0, DLM_LVB_LEN); - } - - out: - up_write(&r->res_lock); -} - -int dlm_lvb_recovery(struct dlm_ls *ls) -{ - struct dlm_rsb *root; - struct dlm_rsb *subrsb; - - down_read(&ls->ls_root_lock); - list_for_each_entry(root, &ls->ls_rootres, res_rootlist) { - if (root->res_nodeid) - continue; - - rsb_lvb_recovery(root); - list_for_each_entry(subrsb, &root->res_subreslist, res_subreslist) { - rsb_lvb_recovery(subrsb); - } - } - up_read(&ls->ls_root_lock); - return 0; -} - diff --git a/dlm-kernel/src/recover.h b/dlm-kernel/src/recover.h deleted file mode 100644 index 8c5c0b8..0000000 --- a/dlm-kernel/src/recover.h +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __RECOVER_DOT_H__ -#define __RECOVER_DOT_H__ - -int dlm_wait_function(struct dlm_ls *ls, int (*testfn) (struct dlm_ls * ls)); -int dlm_wait_status_all(struct dlm_ls *ls, unsigned int wait_status); -int dlm_wait_status_low(struct dlm_ls *ls, unsigned int wait_status); -int dlm_recovery_stopped(struct dlm_ls *ls); -int recover_list_empty(struct dlm_ls *ls); -int recover_list_count(struct dlm_ls *ls); -void recover_list_add(struct dlm_rsb *rsb); -void recover_list_del(struct dlm_rsb *rsb); -void recover_list_clear(struct dlm_ls *ls); -int restbl_lkb_purge(struct dlm_ls *ls); -void restbl_grant_after_purge(struct dlm_ls *ls); -int restbl_rsb_update(struct dlm_ls *ls); -int restbl_rsb_update_recv(struct dlm_ls *ls, int nodeid, char *buf, int len, - int msgid); -int dlm_lvb_recovery(struct dlm_ls *ls); -void rsb_lvb_recovery(struct dlm_rsb *r); - -#endif /* __RECOVER_DOT_H__ */ diff --git a/dlm-kernel/src/recoverd.c b/dlm-kernel/src/recoverd.c deleted file mode 100644 index 2ffd615..0000000 --- a/dlm-kernel/src/recoverd.c +++ /dev/null @@ -1,718 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "dlm_internal.h" -#include "nodes.h" -#include "dir.h" -#include "ast.h" -#include "recover.h" -#include "lockspace.h" -#include "lowcomms.h" -#include "lockqueue.h" -#include "lkb.h" -#include "rebuild.h" - -/* - * next_move actions - */ - -#define DO_STOP (1) -#define DO_START (2) -#define DO_FINISH (3) -#define DO_FINISH_STOP (4) -#define DO_FINISH_START (5) - -/* - * Queue of lockspaces (dlm_recover structs) which need to be - * started/recovered - */ - -static int enable_locking(struct dlm_ls *ls, int event_id) -{ - int error = 0; - - spin_lock(&ls->ls_recover_lock); - if (ls->ls_last_stop < event_id) { - set_bit(LSFL_LS_RUN, &ls->ls_flags); - up_write(&ls->ls_in_recovery); - } else { - error = -EINTR; - log_debug(ls, "enable_locking: abort %d", event_id); - } - spin_unlock(&ls->ls_recover_lock); - return error; -} - -static int ls_first_start(struct dlm_ls *ls, struct dlm_recover *rv) -{ - int error; - - log_debug(ls, "recover event %u (first)", rv->event_id); - - down(&ls->ls_recoverd_active); - - kcl_global_service_id(ls->ls_local_id, &ls->ls_global_id); - - error = ls_nodes_init(ls, rv); - if (error) { - log_error(ls, "nodes_init failed %d", error); - goto out; - } - - error = dlm_dir_rebuild_local(ls); - if (error) { - log_error(ls, "dlm_dir_rebuild_local failed %d", error); - goto out; - } - - error = dlm_dir_rebuild_wait(ls); - if (error) { - log_error(ls, "dlm_dir_rebuild_wait failed %d", error); - goto out; - } - - log_debug(ls, "recover event %u done", rv->event_id); - kcl_start_done(ls->ls_local_id, rv->event_id); - - out: - up(&ls->ls_recoverd_active); - return error; -} - -/* - * We are given here a new group of nodes which are in the lockspace. We first - * figure out the differences in ls membership from when we were last running. - * If nodes from before are gone, then there will be some lock recovery to do. - * If there are only nodes which have joined, then there's no lock recovery. - * - * note: cman requires an rc to finish starting on an revent (where nodes die) - * before it allows an sevent (where nodes join) to be processed. This means - * that we won't get start1 with nodeA gone, stop/cancel, start2 with nodeA - * joined. - */ - -static int ls_reconfig(struct dlm_ls *ls, struct dlm_recover *rv) -{ - int error, neg = 0; - - log_debug(ls, "recover event %u", rv->event_id); - - down(&ls->ls_recoverd_active); - - /* - * Suspending and resuming dlm_astd ensures that no lkb's from this ls - * will be processed by dlm_astd during recovery. - */ - - astd_suspend(); - astd_resume(); - - /* - * this list may be left over from a previous aborted recovery - */ - - rebuild_freemem(ls); - - /* - * Add or remove nodes from the lockspace's ls_nodes list. - */ - - error = ls_nodes_reconfig(ls, rv, &neg); - if (error) { - log_error(ls, "nodes_reconfig failed %d", error); - goto fail; - } - - /* - * Rebuild our own share of the resdir by collecting from all other - * nodes rsb name/master pairs for which the name hashes to us. - */ - - error = dlm_dir_rebuild_local(ls); - if (error) { - log_error(ls, "dlm_dir_rebuild_local failed %d", error); - goto fail; - } - - /* - * Purge resdir-related requests that are being held in requestqueue. - * All resdir requests from before recovery started are invalid now due - * to the resdir rebuild and will be resent by the requesting nodes. - */ - - purge_requestqueue(ls); - set_bit(LSFL_REQUEST_WARN, &ls->ls_flags); - - /* - * Wait for all nodes to complete resdir rebuild. - */ - - error = dlm_dir_rebuild_wait(ls); - if (error) { - log_error(ls, "dlm_dir_rebuild_wait failed %d", error); - goto fail; - } - - /* - * Mark our own lkb's waiting in the lockqueue for remote replies from - * nodes that are now departed. These will be resent to the new - * masters in resend_cluster_requests. Also mark resdir lookup - * requests for resending. - */ - - lockqueue_lkb_mark(ls); - - error = dlm_recovery_stopped(ls); - if (error) - goto fail; - - if (neg) { - /* - * Clear lkb's for departed nodes. This can't fail since it - * doesn't involve communicating with other nodes. - */ - - restbl_lkb_purge(ls); - - /* - * Get new master id's for rsb's of departed nodes. This fails - * if we can't communicate with other nodes. - */ - - error = restbl_rsb_update(ls); - if (error) { - log_error(ls, "restbl_rsb_update failed %d", error); - goto fail; - } - - /* - * Send our lkb info to new masters. This fails if we can't - * communicate with a node. - */ - - error = rebuild_rsbs_send(ls); - if (error) { - log_error(ls, "rebuild_rsbs_send failed %d", error); - goto fail; - } - - dlm_lvb_recovery(ls); - } - - clear_bit(LSFL_REQUEST_WARN, &ls->ls_flags); - - log_debug(ls, "recover event %u done", rv->event_id); - kcl_start_done(ls->ls_local_id, rv->event_id); - up(&ls->ls_recoverd_active); - return 0; - - fail: - log_debug(ls, "recover event %d error %d", rv->event_id, error); - up(&ls->ls_recoverd_active); - return error; -} - -static void clear_finished_nodes(struct dlm_ls *ls, int finish_event) -{ - struct dlm_csb *csb, *safe; - - restart: - spin_lock(&ls->ls_nodes_gone_spin); - list_for_each_entry_safe(csb, safe, &ls->ls_nodes_gone, list) { - if (csb->gone_event <= finish_event) { - list_del(&csb->list); - spin_unlock(&ls->ls_nodes_gone_spin); - release_csb(csb); - goto restart; - } - } - spin_unlock(&ls->ls_nodes_gone_spin); -} - -/* - * Between calls to this routine for a ls, there can be multiple stop/start - * events from cman where every start but the latest is cancelled by stops. - * There can only be a single finish from cman because every finish requires us - * to call start_done. A single finish event could be followed by multiple - * stop/start events. This routine takes any combination of events from cman - * and boils them down to one course of action. - */ - -static int next_move(struct dlm_ls *ls, struct dlm_recover **rv_out, - int *finish_out) -{ - LIST_HEAD(events); - unsigned int cmd = 0, stop, start, finish; - unsigned int last_stop, last_start, last_finish; - struct dlm_recover *rv = NULL, *start_rv = NULL; - - /* - * Grab the current state of cman/sm events. - */ - - spin_lock(&ls->ls_recover_lock); - - stop = test_and_clear_bit(LSFL_LS_STOP, &ls->ls_flags) ? 1 : 0; - start = test_and_clear_bit(LSFL_LS_START, &ls->ls_flags) ? 1 : 0; - finish = test_and_clear_bit(LSFL_LS_FINISH, &ls->ls_flags) ? 1 : 0; - - last_stop = ls->ls_last_stop; - last_start = ls->ls_last_start; - last_finish = ls->ls_last_finish; - - while (!list_empty(&ls->ls_recover)) { - rv = list_entry(ls->ls_recover.next, struct dlm_recover, list); - list_del(&rv->list); - list_add_tail(&rv->list, &events); - } - - /* - * There are two cases where we need to adjust these event values: - * 1. - we get a first start - * - we get a stop - * - we process the start + stop here and notice this special case - * - * 2. - we get a first start - * - we process the start - * - we get a stop - * - we process the stop here and notice this special case - * - * In both cases, the first start we received was aborted by a - * stop before we received a finish. last_finish being zero is the - * indication that this is the "first" start, i.e. we've not yet - * finished a start; if we had, last_finish would be non-zero. - * Part of the problem arises from the fact that when we initially - * get start/stop/start, SM uses the same event id for both starts - * (since the first was cancelled). - * - * In both cases, last_start and last_stop will be equal. - * In both cases, finish=0. - * In the first case start=1 && stop=1. - * In the second case start=0 && stop=1. - * - * In both cases, we need to make adjustments to values so: - * - we process the current event (now) as a normal stop - * - the next start we receive will be processed normally - * (taking into account the assertions below) - * - * In the first case, dlm_ls_start() will have printed the - * "repeated start" warning. - * - * In the first case we need to get rid of the recover event struct. - * - * - set stop=1, start=0, finish=0 for case 4 below - * - last_stop and last_start must be set equal per the case 4 assert - * - ls_last_stop = 0 so the next start will be larger - * - ls_last_start = 0 not really necessary (avoids dlm_ls_start print) - */ - - if (!last_finish && (last_start == last_stop)) { - log_debug(ls, "move reset %u,%u,%u ids %u,%u,%u", stop, - start, finish, last_stop, last_start, last_finish); - stop = 1; - start = 0; - finish = 0; - last_stop = 0; - last_start = 0; - ls->ls_last_stop = 0; - ls->ls_last_start = 0; - - while (!list_empty(&events)) { - rv = list_entry(events.next, struct dlm_recover, list); - list_del(&rv->list); - kfree(rv->nodeids); - kfree(rv); - } - } - spin_unlock(&ls->ls_recover_lock); - - log_debug(ls, "move flags %u,%u,%u ids %u,%u,%u", stop, start, finish, - last_stop, last_start, last_finish); - - /* - * Toss start events which have since been cancelled. - */ - - while (!list_empty(&events)) { - DLM_ASSERT(start,); - rv = list_entry(events.next, struct dlm_recover, list); - list_del(&rv->list); - - if (rv->event_id <= last_stop) { - log_debug(ls, "move skip event %u", rv->event_id); - kfree(rv->nodeids); - kfree(rv); - rv = NULL; - } else { - log_debug(ls, "move use event %u", rv->event_id); - DLM_ASSERT(!start_rv,); - start_rv = rv; - } - } - - /* - * Eight possible combinations of events. - */ - - /* 0 */ - if (!stop && !start && !finish) { - DLM_ASSERT(!start_rv,); - cmd = 0; - goto out; - } - - /* 1 */ - if (!stop && !start && finish) { - DLM_ASSERT(!start_rv,); - DLM_ASSERT(last_start > last_stop,); - DLM_ASSERT(last_finish == last_start,); - cmd = DO_FINISH; - *finish_out = last_finish; - goto out; - } - - /* 2 */ - if (!stop && start && !finish) { - DLM_ASSERT(start_rv,); - DLM_ASSERT(last_start > last_stop,); - cmd = DO_START; - *rv_out = start_rv; - goto out; - } - - /* 3 */ - if (!stop && start && finish) { - DLM_ASSERT(0, printk("finish and start with no stop\n");); - } - - /* 4 */ - if (stop && !start && !finish) { - DLM_ASSERT(!start_rv,); - DLM_ASSERT(last_start == last_stop,); - cmd = DO_STOP; - goto out; - } - - /* 5 */ - if (stop && !start && finish) { - DLM_ASSERT(!start_rv,); - DLM_ASSERT(last_finish == last_start,); - DLM_ASSERT(last_stop == last_start,); - cmd = DO_FINISH_STOP; - *finish_out = last_finish; - goto out; - } - - /* 6 */ - if (stop && start && !finish) { - if (start_rv) { - DLM_ASSERT(last_start > last_stop,); - cmd = DO_START; - *rv_out = start_rv; - } else { - DLM_ASSERT(last_stop == last_start,); - cmd = DO_STOP; - } - goto out; - } - - /* 7 */ - if (stop && start && finish) { - if (start_rv) { - DLM_ASSERT(last_start > last_stop,); - DLM_ASSERT(last_start > last_finish,); - cmd = DO_FINISH_START; - *finish_out = last_finish; - *rv_out = start_rv; - } else { - DLM_ASSERT(last_start == last_stop,); - DLM_ASSERT(last_start > last_finish,); - cmd = DO_FINISH_STOP; - *finish_out = last_finish; - } - goto out; - } - - out: - return cmd; -} - -/* - * This function decides what to do given every combination of current - * lockspace state and next lockspace state. - */ - -static void do_ls_recovery(struct dlm_ls *ls) -{ - struct dlm_recover *rv = NULL; - int error, cur_state, next_state = 0, do_now, finish_event = 0; - - do_now = next_move(ls, &rv, &finish_event); - if (!do_now) - goto out; - - cur_state = ls->ls_state; - next_state = 0; - - DLM_ASSERT(!test_bit(LSFL_LS_RUN, &ls->ls_flags), - log_error(ls, "curstate=%d donow=%d", cur_state, do_now);); - - /* - * LSST_CLEAR - we're not in any recovery state. We can get a stop or - * a stop and start which equates with a START. - */ - - if (cur_state == LSST_CLEAR) { - switch (do_now) { - case DO_STOP: - next_state = LSST_WAIT_START; - break; - - case DO_START: - error = ls_reconfig(ls, rv); - if (error) - next_state = LSST_WAIT_START; - else - next_state = LSST_RECONFIG_DONE; - break; - - case DO_FINISH: /* invalid */ - case DO_FINISH_STOP: /* invalid */ - case DO_FINISH_START: /* invalid */ - default: - DLM_ASSERT(0,); - } - goto out; - } - - /* - * LSST_WAIT_START - we're not running because of getting a stop or - * failing a start. We wait in this state for another stop/start or - * just the next start to begin another reconfig attempt. - */ - - if (cur_state == LSST_WAIT_START) { - switch (do_now) { - case DO_STOP: - break; - - case DO_START: - error = ls_reconfig(ls, rv); - if (error) - next_state = LSST_WAIT_START; - else - next_state = LSST_RECONFIG_DONE; - break; - - case DO_FINISH: /* invalid */ - case DO_FINISH_STOP: /* invalid */ - case DO_FINISH_START: /* invalid */ - default: - DLM_ASSERT(0,); - } - goto out; - } - - /* - * LSST_RECONFIG_DONE - we entered this state after successfully - * completing ls_reconfig and calling kcl_start_done. We expect to get - * a finish if everything goes ok. A finish could be followed by stop - * or stop/start before we get here to check it. Or a finish may never - * happen, only stop or stop/start. - */ - - if (cur_state == LSST_RECONFIG_DONE) { - switch (do_now) { - case DO_FINISH: - rebuild_freemem(ls); - - clear_finished_nodes(ls, finish_event); - next_state = LSST_CLEAR; - - error = enable_locking(ls, finish_event); - if (error) - break; - - error = process_requestqueue(ls); - if (error) - break; - - error = resend_cluster_requests(ls); - if (error) - break; - - restbl_grant_after_purge(ls); - - wake_astd(); - - log_debug(ls, "recover event %u finished", finish_event); - break; - - case DO_STOP: - next_state = LSST_WAIT_START; - break; - - case DO_FINISH_STOP: - clear_finished_nodes(ls, finish_event); - next_state = LSST_WAIT_START; - break; - - case DO_FINISH_START: - clear_finished_nodes(ls, finish_event); - /* fall into DO_START */ - - case DO_START: - error = ls_reconfig(ls, rv); - if (error) - next_state = LSST_WAIT_START; - else - next_state = LSST_RECONFIG_DONE; - break; - - default: - DLM_ASSERT(0,); - } - goto out; - } - - /* - * LSST_INIT - state after ls is created and before it has been - * started. A start operation will cause the ls to be started for the - * first time. A failed start will cause to just wait in INIT for - * another stop/start. - */ - - if (cur_state == LSST_INIT) { - switch (do_now) { - case DO_START: - error = ls_first_start(ls, rv); - if (!error) - next_state = LSST_INIT_DONE; - break; - - case DO_STOP: - break; - - case DO_FINISH: /* invalid */ - case DO_FINISH_STOP: /* invalid */ - case DO_FINISH_START: /* invalid */ - default: - DLM_ASSERT(0,); - } - goto out; - } - - /* - * LSST_INIT_DONE - after the first start operation is completed - * successfully and kcl_start_done() called. If there are no errors, a - * finish will arrive next and we'll move to LSST_CLEAR. - */ - - if (cur_state == LSST_INIT_DONE) { - switch (do_now) { - case DO_STOP: - case DO_FINISH_STOP: - next_state = LSST_WAIT_START; - break; - - case DO_START: - case DO_FINISH_START: - error = ls_reconfig(ls, rv); - if (error) - next_state = LSST_WAIT_START; - else - next_state = LSST_RECONFIG_DONE; - break; - - case DO_FINISH: - next_state = LSST_CLEAR; - - enable_locking(ls, finish_event); - - process_requestqueue(ls); - - wake_astd(); - - log_debug(ls, "recover event %u finished", finish_event); - break; - - default: - DLM_ASSERT(0,); - } - goto out; - } - - out: - if (next_state) - ls->ls_state = next_state; - - if (rv) { - kfree(rv->nodeids); - kfree(rv); - } -} - -int dlm_recoverd(void *arg) -{ - struct dlm_ls *ls = arg; - - hold_lockspace(ls); - - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - if (!test_bit(LSFL_WORK, &ls->ls_flags)) - schedule(); - set_current_state(TASK_RUNNING); - - if (test_and_clear_bit(LSFL_WORK, &ls->ls_flags)) - do_ls_recovery(ls); - } - - put_lockspace(ls); - return 0; -} - -void dlm_recoverd_kick(struct dlm_ls *ls) -{ - set_bit(LSFL_WORK, &ls->ls_flags); - wake_up_process(ls->ls_recoverd_task); -} - -int dlm_recoverd_start(struct dlm_ls *ls) -{ - struct task_struct *p; - int error = 0; - - p = kthread_run(dlm_recoverd, ls, "dlm_recoverd"); - if (IS_ERR(p)) - error = PTR_ERR(p); - else - ls->ls_recoverd_task = p; - return error; -} - -void dlm_recoverd_stop(struct dlm_ls *ls) -{ - kthread_stop(ls->ls_recoverd_task); -} - -void dlm_recoverd_suspend(struct dlm_ls *ls) -{ - down(&ls->ls_recoverd_active); -} - -void dlm_recoverd_resume(struct dlm_ls *ls) -{ - up(&ls->ls_recoverd_active); -} - diff --git a/dlm-kernel/src/recoverd.h b/dlm-kernel/src/recoverd.h deleted file mode 100644 index 12a56be..0000000 --- a/dlm-kernel/src/recoverd.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __RECOVERD_DOT_H__ -#define __RECOVERD_DOT_H__ - -void dlm_recoverd_kick(struct dlm_ls *ls); -void dlm_recoverd_stop(struct dlm_ls *ls); -int dlm_recoverd_start(struct dlm_ls *ls); -void dlm_recoverd_suspend(struct dlm_ls *ls); -void dlm_recoverd_resume(struct dlm_ls *ls); - -#endif /* __RECOVERD_DOT_H__ */ diff --git a/dlm-kernel/src/rsb.c b/dlm-kernel/src/rsb.c deleted file mode 100644 index 68fbff7..0000000 --- a/dlm-kernel/src/rsb.c +++ /dev/null @@ -1,471 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "dlm_internal.h" -#include "locking.h" -#include "memory.h" -#include "lockqueue.h" -#include "nodes.h" -#include "dir.h" -#include "util.h" -#include "rsb.h" -#include "ast.h" -#include "lkb.h" - -static int purge_queue(struct dlm_ls *ls, struct dlm_rsb *r, - struct list_head *queue, int pid, - int pid_is_local, int rsb_is_master) -{ - struct dlm_lkb *lkb, *lkb2; - int purge, total = 0; - - list_for_each_entry_safe(lkb, lkb2, queue, lkb_statequeue) { - - /* the one general rule can be factored out of checks below */ - - if (lkb->lkb_ownpid != pid) - continue; - - purge = 0; - - /* local copy lkb on locally mastered rsb */ - - if (pid_is_local && rsb_is_master && lkb->lkb_nodeid == 0) - purge = 1; - - /* process copy lkb on remotely mastered rsb */ - - if (pid_is_local && !rsb_is_master && lkb->lkb_nodeid != 0) - purge = 1; - - /* master copy lkb on locally mastered rsb */ - - if (!pid_is_local && rsb_is_master && lkb->lkb_nodeid > 0) - purge = 1; - - if (!purge) - continue; - - printk("dlm: purge lkid %x pid %d nodeid %d ast %x lqs %d sts %d gr %d rq %d pil %d rim %d r_nodeid %d r_name %s\n", - lkb->lkb_id, - lkb->lkb_ownpid, - lkb->lkb_nodeid, - lkb->lkb_astflags, - lkb->lkb_lockqueue_state, - lkb->lkb_status, - lkb->lkb_grmode, - lkb->lkb_rqmode, - pid_is_local, - rsb_is_master, - r->res_nodeid, - r->res_name); - - if (!lkb->lkb_status) { - printk("dlm: purge lkid %x zero status\n", lkb->lkb_id); - continue; - } - - if (lkb->lkb_astflags) - remove_from_astqueue(lkb); - - if (lkb->lkb_lockqueue_state) - remove_from_lockqueue(lkb); - - if (lkb->lkb_duetime) - remove_from_deadlockqueue(lkb); - - list_del(&lkb->lkb_statequeue); - lkb->lkb_status = 0; - release_lkb(ls, lkb); - release_rsb(r); - total++; - } - - return total; -} - -/* - * if from_nodeid is -1, the pid is local, - * - if an rsb has a remote master we need to send_purge to it so the - * master copy lkb can be removed, in addition to the process copy - * removed here directly. - * - if an rsb is mastered locally, we remove the local copy lkb's - * here directly - * - * if from_nodeid is > 0, the pid is remote, so we are are looking for - * master copy lkb's with lkb_nodeid equal to from_nodeid and matching pid - */ - -void dlm_purge(struct dlm_ls *ls, int ournodeid, int pid, int from_nodeid) -{ - struct dlm_rsb *r, *r2; - int pid_is_local, rsb_is_master; - int purged, total_purged = 0; - - printk("dlm: purge our_nodeid %d pid %d from_nodeid %d\n", - ournodeid, pid, from_nodeid); - - if (from_nodeid == -1) { - /* - * pid is local, we're looking for either: - * . local copy lkbs on locally mastered rsbs - * . process copy lkbs on remotely mastered rsbs - * (and send purge to the rsb master) - */ - pid_is_local = 1; - } else { - /* - * pid is remote, we're just looking for master copy - * lkbs on locally mastered rsbs - */ - pid_is_local = 0; - } - - down_write(&ls->ls_root_lock); - - list_for_each_entry_safe(r, r2, &ls->ls_rootres, res_rootlist) { - hold_rsb(r); - down_write(&r->res_lock); - - rsb_is_master = (r->res_nodeid == 0) ? 1 : 0; - - purged = 0; - - purged += purge_queue(ls, r, &r->res_waitqueue, pid, - pid_is_local, rsb_is_master); - purged += purge_queue(ls, r, &r->res_convertqueue, pid, - pid_is_local, rsb_is_master); - purged += purge_queue(ls, r, &r->res_grantqueue, pid, - pid_is_local, rsb_is_master); - - total_purged += purged; - - if (rsb_is_master && purged) - grant_pending_locks(r); - - up_write(&r->res_lock); - release_rsb_locked(r); - } - - up_write(&ls->ls_root_lock); - - printk("dlm: purged %d pid %d\n", total_purged, pid); -} - -static struct dlm_rsb *search_hashchain(struct list_head *head, - struct dlm_rsb *parent, - char *name, int namelen) -{ - struct dlm_rsb *r; - - list_for_each_entry(r, head, res_hashchain) { - if ((parent == r->res_parent) && (namelen == r->res_length) && - (memcmp(name, r->res_name, namelen) == 0)) { - return r; - } - } - - return NULL; -} - -/* - * A way to arbitrarily hold onto an rsb which we already have a reference to - * to make sure it doesn't go away. Opposite of release_rsb(). - */ - -void hold_rsb(struct dlm_rsb *r) -{ - atomic_inc(&r->res_ref); -} - -/* - * release_rsb() - Decrement reference count on rsb struct. Free the rsb - * struct when there are zero references. Every lkb for the rsb adds a - * reference. When ref is zero there can be no more lkb's for the rsb, on the - * queue's or anywhere else. - */ - -static void _release_rsb(struct dlm_rsb *r, int locked) -{ - struct dlm_ls *ls = r->res_ls; - uint32_t nodeid; - int removed = FALSE; - - write_lock(&ls->ls_rsbtbl[r->res_bucket].lock); - if (atomic_dec_and_test(&r->res_ref)) { - DLM_ASSERT(list_empty(&r->res_grantqueue), print_rsb(r);); - DLM_ASSERT(list_empty(&r->res_waitqueue), print_rsb(r);); - DLM_ASSERT(list_empty(&r->res_convertqueue), print_rsb(r);); - removed = TRUE; - list_del(&r->res_hashchain); - } - write_unlock(&ls->ls_rsbtbl[r->res_bucket].lock); - - if (!removed) - return; - - if (!locked) - down_write(&ls->ls_root_lock); - if (r->res_parent) - list_del(&r->res_subreslist); - else - list_del(&r->res_rootlist); - if (!locked) - up_write(&ls->ls_root_lock); - - if (r->res_parent || !test_bit(RESFL_MASTER, &r->res_flags)) - goto out; - - nodeid = get_directory_nodeid(r); - - if (nodeid != our_nodeid()) - remote_remove_direntry(ls, nodeid, r->res_name, r->res_length); - else - dlm_dir_remove(ls, nodeid, r->res_name, r->res_length); - out: - if (r->res_lvbptr) - free_lvb(r->res_lvbptr); - - free_rsb(r); -} - -void release_rsb(struct dlm_rsb *r) -{ - _release_rsb(r, 0); -} - -void release_rsb_locked(struct dlm_rsb *r) -{ - _release_rsb(r, 1); -} - -struct dlm_rsb *find_rsb_to_unlock(struct dlm_ls *ls, struct dlm_lkb *lkb) -{ - struct dlm_rsb *r = lkb->lkb_resource; - return r; -} - -/* - * find_or_create_rsb() - Get an rsb struct, or create one if it doesn't exist. - * If the rsb exists, its ref count is incremented by this function. If it - * doesn't exist, it's created with a ref count of one. - */ - -int find_rsb(struct dlm_ls *ls, struct dlm_rsb *parent, char *name, int len, - int flags, struct dlm_rsb **rp) -{ - uint32_t bucket; - struct dlm_rsb *r, *tmp; - int error = -ENOMEM; - - DLM_ASSERT(len <= DLM_RESNAME_MAXLEN,); - - bucket = dlm_hash(name, len); - bucket &= (ls->ls_rsbtbl_size - 1); - - read_lock(&ls->ls_rsbtbl[bucket].lock); - r = search_hashchain(&ls->ls_rsbtbl[bucket].list, parent, name, len); - if (r) { - if (r->res_nodeid != 0 && (flags & MASTER)) - r = NULL; - else - atomic_inc(&r->res_ref); - } - read_unlock(&ls->ls_rsbtbl[bucket].lock); - - if (r) - goto out_set; - - /* Always create sublocks */ - if (!(flags & CREATE) && !parent) { - *rp = NULL; - goto out; - } - - r = allocate_rsb(ls, len); - if (!r) - goto fail; - - INIT_LIST_HEAD(&r->res_subreslist); - INIT_LIST_HEAD(&r->res_grantqueue); - INIT_LIST_HEAD(&r->res_convertqueue); - INIT_LIST_HEAD(&r->res_waitqueue); - - memcpy(r->res_name, name, len); - r->res_length = len; - r->res_ls = ls; - init_rwsem(&r->res_lock); - atomic_set(&r->res_ref, 1); - r->res_bucket = bucket; - - if (parent) { - r->res_parent = parent; - r->res_depth = parent->res_depth + 1; - r->res_root = parent->res_root; - r->res_nodeid = parent->res_nodeid; - } else { - r->res_parent = NULL; - r->res_depth = 1; - r->res_root = r; - r->res_nodeid = -1; - } - - write_lock(&ls->ls_rsbtbl[bucket].lock); - tmp = search_hashchain(&ls->ls_rsbtbl[bucket].list, parent, name, len); - if (tmp) { - atomic_inc(&tmp->res_ref); - write_unlock(&ls->ls_rsbtbl[bucket].lock); - free_rsb(r); - r = tmp; - } else { - list_add(&r->res_hashchain, &ls->ls_rsbtbl[bucket].list); - write_unlock(&ls->ls_rsbtbl[bucket].lock); - - down_write(&ls->ls_root_lock); - if (parent) - list_add_tail(&r->res_subreslist, - &r->res_root->res_subreslist); - else - list_add(&r->res_rootlist, &ls->ls_rootres); - up_write(&ls->ls_root_lock); - } - - out_set: - *rp = r; - - out: - error = 0; - - fail: - return error; -} - -/* - * Add a LKB to a resource's grant/convert/wait queue. in order - */ - -void lkb_add_ordered(struct list_head *new, struct list_head *head, int mode) -{ - struct dlm_lkb *lkb = NULL; - - list_for_each_entry(lkb, head, lkb_statequeue) { - if (lkb->lkb_rqmode < mode) - break; - } - - if (!lkb) { - /* No entries in the queue, we are alone */ - list_add_tail(new, head); - } else { - __list_add(new, lkb->lkb_statequeue.prev, &lkb->lkb_statequeue); - } -} - -/* - * The rsb res_lock must be held in write when this function is called. - */ - -void lkb_enqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type) -{ - DLM_ASSERT(!lkb->lkb_status, - print_lkb(lkb); - print_rsb(r);); - - lkb->lkb_status = type; - - switch (type) { - case GDLM_LKSTS_WAITING: - if (lkb->lkb_lockqueue_flags & DLM_LKF_HEADQUE) - list_add(&lkb->lkb_statequeue, &r->res_waitqueue); - else - list_add_tail(&lkb->lkb_statequeue, &r->res_waitqueue); - break; - - case GDLM_LKSTS_GRANTED: - lkb_add_ordered(&lkb->lkb_statequeue, &r->res_grantqueue, - lkb->lkb_grmode); - break; - - case GDLM_LKSTS_CONVERT: - if (lkb->lkb_lockqueue_flags & DLM_LKF_HEADQUE) - list_add(&lkb->lkb_statequeue, &r->res_convertqueue); - else - list_add_tail(&lkb->lkb_statequeue, - &r->res_convertqueue); - break; - - default: - DLM_ASSERT(0,); - } -} - -void res_lkb_enqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type) -{ - down_write(&r->res_lock); - lkb_enqueue(r, lkb, type); - up_write(&r->res_lock); -} - -/* - * The rsb res_lock must be held in write when this function is called. - */ - -int lkb_dequeue(struct dlm_lkb *lkb) -{ - int status = lkb->lkb_status; - - if (!status) - goto out; - - lkb->lkb_status = 0; - list_del(&lkb->lkb_statequeue); - - out: - return status; -} - -int res_lkb_dequeue(struct dlm_lkb *lkb) -{ - int status; - - down_write(&lkb->lkb_resource->res_lock); - status = lkb_dequeue(lkb); - up_write(&lkb->lkb_resource->res_lock); - - return status; -} - -/* - * The rsb res_lock must be held in write when this function is called. - */ - -int lkb_swqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type) -{ - int status; - - status = lkb_dequeue(lkb); - lkb_enqueue(r, lkb, type); - - return status; -} - -int res_lkb_swqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type) -{ - int status; - - down_write(&r->res_lock); - status = lkb_swqueue(r, lkb, type); - up_write(&r->res_lock); - - return status; -} diff --git a/dlm-kernel/src/rsb.h b/dlm-kernel/src/rsb.h deleted file mode 100644 index d1d1a2f..0000000 --- a/dlm-kernel/src/rsb.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __RSB_DOT_H__ -#define __RSB_DOT_H__ - -#define CREATE 1 -#define MASTER 2 - -void lkb_add_ordered(struct list_head *new, struct list_head *head, int mode); -void release_rsb(struct dlm_rsb *r); -void release_rsb_locked(struct dlm_rsb *r); -void hold_rsb(struct dlm_rsb *r); -int find_rsb(struct dlm_ls *ls, struct dlm_rsb *parent, char *name, - int namelen, int flags, struct dlm_rsb **rp); -struct dlm_rsb *find_rsb_to_unlock(struct dlm_ls *ls, struct dlm_lkb *lkb); -void lkb_enqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type); -void res_lkb_enqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type); -int lkb_dequeue(struct dlm_lkb *lkb); -int res_lkb_dequeue(struct dlm_lkb *lkb); -int lkb_swqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type); -int res_lkb_swqueue(struct dlm_rsb *r, struct dlm_lkb *lkb, int type); -void dlm_purge(struct dlm_ls *ls, int ournodeid, int pid, int from_nodeid); - -#endif /* __RSB_DOT_H__ */ diff --git a/dlm-kernel/src/util.c b/dlm-kernel/src/util.c deleted file mode 100644 index 15169b8..0000000 --- a/dlm-kernel/src/util.c +++ /dev/null @@ -1,183 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "dlm_internal.h" - -static const uint32_t crc_32_tab[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, - 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, - 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, - 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, - 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, - 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, - 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, - 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, - 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, - 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, - 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, - 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, - 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, - 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, - 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, - 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, - 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, - 0x5a05df1b, 0x2d02ef8d -}; - -/** - * dlm_hash - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * Copied from GFS. - * - * Take some data and convert it to a 32-bit hash. - * - * The hash function is a 32-bit CRC of the data. The algorithm uses - * the crc_32_tab table above. - * - * This may not be the fastest hash function, but it does a fair bit better - * at providing uniform results than the others I've looked at. That's - * really important for efficient directories. - * - * Returns: the hash - */ - -uint32_t dlm_hash(const char *data, int len) -{ - uint32_t hash = 0xFFFFFFFF; - - for (; len--; data++) - hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); - - hash = ~hash; - - return hash; -} - -void print_lkb(struct dlm_lkb *lkb) -{ - printk("dlm: lkb\n" - "id %x\n" - "remid %x\n" - "flags %x\n" - "status %x\n" - "rqmode %d\n" - "grmode %d\n" - "nodeid %d\n" - "lqstate %x\n" - "lqflags %x\n", - lkb->lkb_id, - lkb->lkb_remid, - lkb->lkb_flags, - lkb->lkb_status, - lkb->lkb_rqmode, - lkb->lkb_grmode, - lkb->lkb_nodeid, - lkb->lkb_lockqueue_state, - lkb->lkb_lockqueue_flags); -} - -void print_rsb(struct dlm_rsb *r) -{ - printk("dlm: rsb\n" - "name "%s"\n" - "nodeid %d\n" - "flags %lx\n" - "ref %u\n", - r->res_name, - r->res_nodeid, - r->res_flags, - atomic_read(&r->res_ref)); -} - -void print_request(struct dlm_request *req) -{ - printk("dlm: request\n" - "rh_cmd %u\n" - "rh_lkid %x\n" - "remlkid %x\n" - "flags %x\n" - "status %u\n" - "rqmode %u\n", - req->rr_header.rh_cmd, - req->rr_header.rh_lkid, - req->rr_remlkid, - req->rr_flags, - req->rr_status, - req->rr_rqmode); -} - -void print_reply(struct dlm_reply *rp) -{ - printk("dlm: reply\n" - "rh_cmd %u\n" - "rh_lkid %x\n" - "lockstate %u\n" - "nodeid %u\n" - "status %u\n" - "lkid %x\n", - rp->rl_header.rh_cmd, - rp->rl_header.rh_lkid, - rp->rl_lockstate, - rp->rl_nodeid, - rp->rl_status, - rp->rl_lkid); -} - diff --git a/dlm-kernel/src/util.h b/dlm-kernel/src/util.h deleted file mode 100644 index a1b31cc..0000000 --- a/dlm-kernel/src/util.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UTIL_DOT_H__ -#define __UTIL_DOT_H__ - -uint32_t dlm_hash(const char *data, int len); - -void print_lkb(struct dlm_lkb *lkb); -void print_rsb(struct dlm_rsb *r); -void print_request(struct dlm_request *req); -void print_reply(struct dlm_reply *rp); - -#endif diff --git a/dlm/Makefile b/dlm/Makefile deleted file mode 100644 index 72e91af..0000000 --- a/dlm/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd lib && ${MAKE} all - cd tool && ${MAKE} all - -copytobin: - cd lib && ${MAKE} copytobin - cd tool && ${MAKE} copytobin - -install: - cd lib && ${MAKE} install - cd tool && ${MAKE} install - cd man && ${MAKE} install - -uninstall: - cd lib && ${MAKE} uninstall - cd tool && ${MAKE} uninstall - cd man && ${MAKE} uninstall - -clean: - cd lib && ${MAKE} clean - cd tool && ${MAKE} clean - rm -f *~ - -distclean: clean - rm -f make/defines.mk - diff --git a/dlm/configure b/dlm/configure deleted file mode 100755 index dd4d532..0000000 --- a/dlm/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/dlm/doc/example.c b/dlm/doc/example.c deleted file mode 100644 index b7b301e..0000000 --- a/dlm/doc/example.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <stdlib.h> -#include <unistd.h> -#include <stdint.h> -#include <errno.h> -#include <string.h> -#include <stdio.h> -#include <signal.h> -#include <libdlm.h> - -/* - * Simple libdlm locking demo - * - * Daniel Phillips, phillips@redhat.com - * - * (c) 2004, Redhat Software Inc. - */ - -#define error(string, args...) do { printf(string, ##args); exit(1); } while (0) - -void my_ast(void *arg) -{ - printf("ast got arg %p\n", arg); -} - -int main(void) -{ - int fd, child; - struct dlm_lksb lksb; - - if ((fd = dlm_get_fd()) < 0) - error("dlm error %i, %s\n", errno, strerror(errno)); - - switch (child = fork()) { - case -1: - error("fork error %i, %s\n", errno, strerror(errno)); - case 0: - while (1) - dlm_dispatch(fd); - } - - if (dlm_lock(LKM_PWMODE, &lksb, LKF_NOQUEUE, "foo", 3, - 0, my_ast, (void *)&fd, NULL, NULL) < 0) - error("dlm error %i, %s\n", errno, strerror(errno)); - sleep(1); - - if (dlm_unlock(lksb.sb_lkid, 0, &lksb, NULL) < 0) - error("dlm error %i, %s\n", errno, strerror(errno)); - sleep(1); - - kill(child, SIGTERM); - return 0; -} - diff --git a/dlm/doc/libdlm.txt b/dlm/doc/libdlm.txt deleted file mode 100644 index 18d44f9..0000000 --- a/dlm/doc/libdlm.txt +++ /dev/null @@ -1,533 +0,0 @@ -User-space interface to DLM ---------------------------- -#include <sys/types.h> -#include <sys/stat.h> -#include <stdint.h> -#include <libdlm.h> - -cc -D_REENTRANT prog.c -ldlm -lpthread - -cc prog.c -ldlm_lt - - -There are basically two interfaces to libdlm. The first is the "dead simple" -one that has limited functionality and assumes that the application is linked -with pthreads. The second is the full-featured DLM interface that looks -identical to the kernel interface. - -See CVS dlm/tests/usertest for examples of use of both these APIs. - -The simple one --------------- -This provides two API calls, lock_resource() and unlock_resource(). Both of -these calls block until the lock operation has completed - using a worker -thread to deal with the callbacks that come from the kernel. - -int lock_resource(const char *resource, int mode, int flags, int *lockid); - - This function locks a named (NUL-terminated) resource and returns the - lockid if successful. The mode may be any of - - LKM_NLMODE LKM_CRMODE LKM_CWMODE LKM_PRMODE LKM_PWMODE LKM_EXMODE - - Flags may be any combination of - - LKF_NOQUEUE - Don't wait if the lock cannot be granted immediately, - will return EAGAIN if this is so. - - LKF_CONVERT - Convert lock to new mode. *lockid must be valid, - resource name is ignored. - - LKF_QUECVT - Add conversion to the back of the convert queue - only - valid for some convert operations - - LKF_PERSISTENT - Don't automatically unlock this lock when the process - exits (must be root). - - -int unlock_resource(int lockid); - - Unlocks the resource. - - - -The complicated one -------------------- -This interface is identical to the kernel interface with the exception of -the lockspace argument. All userland locks sit in the same lockspace by default. - -libdlm can be used in pthread or non-pthread applications. For pthread -applications simply call the following function before doing any lock -operations. If you're using pthreads, remember to define _REENTRANT at the -top of the program or using -D_REENTRANT on the compile line. - -int dlm_pthread_init() - - Creates a thread to receive all lock ASTs. The AST callback function - for lock operations will be called in the context of this thread. - If there is a potential for local resource access conflicts you must - provide your own pthread-based locking in the AST routine. - - -int dlm_pthread_cleanup() - - Cleans up the default lockspace threads after use. Normally you - don't need to call this, but if the locking code is in a - dynamically loadable shared library this will probably be necessary. - - -For non-pthread based applications the DLM provides a file descriptor -that the program can feed into poll/select. If activity is detected -on that FD then a dispatch function should be called: - -int dlm_get_fd() - - Returns a file-descriptor for the DLM suitable for passing in to - poll() or select(). - -int dlm_dispatch(int fd) - - Reads from the DLM and calls any AST routines that may be needed. - This routine runs in the context of the caller so no extra locking - is needed to protect local resources. - - -int dlm_lock(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - struct dlm_range *range); - - -mode lock mode: - LKM_NLMODE NULL Lock - LKM_CRMODE Concurrent read - LKM_CWMODE Concurrent write - LKM_PRMODE Protected read - LKM_PWMODE Protected write - LKM_EXMODE Exclusive - -flags LKF_NOQUEUE Don't queue the lock. If it cannot be - granted return -EAGAIN - LKF_CONVERT Convert an existing lock - LKF_VALBLK Lock has a value block - LKF_QUECVT Put conversion to the back of the queue - LKF_EXPEDITE Grant a NL lock immediately regardless of - other locks on the conversion queue - LKF_PERSISTENT Specifies a lock that will - not be unlocked when the process exits. - -lksb Lock status block. - This structure contains the returned lock ID, the actual - status of the lock operation (all lock ops are asynchronous) - and the value block if LKF_VALBLK is set. - -name Name of the lock. Can be binary, max 64 bytes. Ignored for lock - conversions. - -namelen Length of the above name. Ignored for lock conversions. - -parent ID of parent lock or NULL if this is a top-level lock - -ast Address of AST routine to be called when the lock operation - completes. The final completion status of the lock will be - in the lksb. the AST routine must not be NULL. - -astargs Argument to pass to the AST routine (most people pass the lksb - in here but it can be anything you like.) - -bast Blocking AST routine. address of a function to call if this - lock is blocking another. The function will be called with - astargs. - -range an optional structure of two uint64_t that indicate the range - of the lock. Locks with overlapping ranges will be granted only - if the lock modes are compatible. locks with non-overlapping - ranges (on the same resource) do not conflict. A lock with no - range is assumed to have a range emcompassing the largest - possible range. ie. 0-0xFFFFFFFFFFFFFFFF. Note that is is more - efficient to specify no range than to specify the full range - above. - - -dlm_lock operations are asynchronous. If the call to dlm_lock returns an error -then the operation has failed and the AST routine will not be called. If -dlm_lock returns 0 it is still possible that the lock operation will fail. The -AST routine will be called when the locking is complete or has failed and the -status is returned in the lksb. - -For conversion operations the name and namelen are ignored and the lock ID in -the LKSB is used to identify the lock. - -If a lock value block is specified then in general, a grant or a conversion to -an equal-level or higher-level lock mode reads the lock value from the resource -into the caller's lock value block. When a lock conversion from EX or PW -to an equal-level or lower-level lock mode occurs, the contents of -the caller's lock value block are written into the resource. - -If the AST routines or parameter are passed to a conversion operation then they -will overwrite those values that were passed to a previous dlm_lock call. - -int dlm_lock_wait(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - struct dlm_range *range); - - -As above except that the call will block until the lock is -granted or has failed. The return from the function is -the final status of the lock request (ie that was returned -in the lksb after the AST routine was called). - - - -int dlm_unlock(uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb, - void *astarg) - -lkid Lock ID as returned in the lksb - -flags flags affecting the unlock operation: - LKF_CANCEL CANCEL a pending lock or conversion. - This returns the lock to it's - previously granted mode (in case of a - conversion) or unlocks it (in case of a - waiting lock). - - LKF_IVVALBLK Invalidate value block - -lksb LKSB to return status and value block information. - -astarg New parameter to be passed to the completion AST. - The completion AST routine is the - last completion AST routine specified in a dlm_lock call. - If dlm_lock_wait() was the last routine to issue a lock, - dlm_unlock_wait() must be used to release the lock. If dlm_lock() - was the last routine to issue a lock then either dlm_unlock() - or dlm_unlock_wait() may be called. - -Unlocks are also asynchronous. The AST routine is called when the resource is -successfully unlocked (see below). - - -Extra status returns to the completion AST (apart from those already -defined in errno.h) - -ECANCEL - A lock conversion was successfully cancelled - -EUNLOCK - An Unlock operation completed successfully - -EDEADLOCK - The lock operation is causing a deadlock and has been cancelled. If this - was a conversion then the lock is reverted to its previously granted state. - If it was a new lock then it has not been granted. - (NB Only conversion deadlocks are currently detected) - -int dlm_unlock_wait(uint32_t lkid, - uint32 flags, - struct dlm_lksb *lksb) - -As above but returns when the unlock operation is complete either because it -finished or because an error was detected. In the case where -the unlock operation was succesful no error is returned. - -The return value of the function call is the status of issuing -the unlock operation. The status of the unlock operation itself -is in the lock status block. Both of these must be checked to -verify that the unlock has completed succesfully. - -Lock Query Operations ---------------------- -int dlm_query(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*ast_routine(void *astarg)), - void *astarg); - -The operation is asynchronous, the ultimate status and data will be returned into the -dlm_query_info structure which should be checked when the ast_routine is -called. The lksb must contain a valid lock ID in sb_lkid which is used to -identify the resource to be queried, status will be returned in sb_status; -As with the locking calls an AST woutine will be called when the query completes -if the call itself returns 0. - -int dlm_query_wait(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo) - -Same as dlm_query() except that it waits for the operation to complete. -When the operation is complete the status of will be in the lksb. Both -the return value from the function call and the condition code in the -lksb must be evaluated. - -If the provided lock list is too short to hold all the locks, then sb_status -in the lksb will contain -E2BIG but the list will be filled in as far as possible. -Either gqi_lockinfo or gqi_resinfo may be NULL if that information is not required. - -/* Structures passed into and out of the query */ - -struct gdlm_lockinfo -{ - int lki_lkid; /* Lock ID on originating node */ - int lki_parent; - int lki_node; /* Originating node (not master) */ - int lki_ownpid; /* Owner pid on the originating node */ - uint8 lki_state; /* Queue the lock is on */ - int8 lki_grmode /* Granted mode */ - int8 lki_rqmode; /* Requested mode */ - struct dlm_range lki_grrange /* Granted range, if applicable */ - struct dlm_range lki_rqrange /* Requested range, if applicable */ -}; - -struct gdlm_resinfo -{ - int rsi_length; - int rsi_grantcount; /* No. of nodes on grant queue */ - int rsi_convcount; /* No. of nodes on convert queue */ - int rsi_waitcount; /* No. of nodes on wait queue */ - int rsi_masternode; /* Master for this resource */ - char rsi_name[DLM_RESNAME_MAXLEN]; /* Resource name */ - char rsi_valblk[DLM_LVB_LEN]; /* Master's LVB contents, if applicable */ -}; - -struct dlm_queryinfo -{ - struct dlm_resinfo *gqi_resinfo; /* Points to a single resinfo struct */ - struct dlm_lockinfo *gqi_lockinfo; /* This points to an array of structs */ - int gqi_locksize; /* input */ - int gqi_lockcount; /* output */ -}; - -The query is made up of several blocks of bits as follows: - - 9 8 6 5 3 0 -+----------------+---+-------+---+-------+-----------+ -| reserved | Q | query | F | queue | lock mode | -+----------------+---+-------+---+-------+-----------+ - -lock mode is a normal DLM lock mode or DLM_LOCK_THIS -to use the mode of the lock in sb_lkid. - -queue is a bitmap of - DLM_QUERY_QUEUE_WAIT - DLM_QUERY_QUEUE_CONVERT - DLM_QUERY_QUEUE_GRANT - -or one of the two shorthands: - DLM_QUERY_QUEUE_GRANTED (for WAIT+GRANT) - DLM_QUERY_QUEUE_ALL (for all queues) - - F is a flag DLM_QUERY_LOCAL -which specifies that a remote access should not -happen. Only lock information that can -be gleaned from the local node will be returned so -be aware that it may not be complete. - -The query is one of the following: - DLM_QUERY_LOCKS_HIGHER - DLM_QUERY_LOCKS_LOWER - DLM_QUERY_LOCKS_EQUAL - DLM_QUERY_LOCKS_BLOCKING - DLM_QUERY_LOCKS_NOTBLOCK - DLM_QUERY_LOCKS_ALL - -which specifies which locks to look for by mode, -either the lockmode is lower, equal or higher -to the mode at the bottom of the query. -DLM_QUERY_ALL will return all locks on the -resource. - -DLM_QUERY_LOCKS_BLOCKING returns only locks -that are blocking the current lock. The lock -must not be waiting for grant or conversion -for this to be a valid query, the other flags -are ignored. - -DLM_QUERY_LOCKS_NOTBLOCKING returns only locks -that are granted but NOT blocking the current lock. - -Q specifies which lock queue to compare. By default -the granted queue is used. If the flags -DLM_QUERY_RQMODE is set then the requested mode -will be used instead. - - -The "normal" way to call dlm_query is to put the -address of the dlm_queryinfo struct into -lksb.sb_lvbptr and pass the lksb as the AST param, -that way all the information is available to you -in the AST routine. - -Lockspace Operations --------------------- -The DLM allows locks to be partitioned into "lockspaces", and these can be -manipulated by userspace calls. It is possible (though not recommended) for -an application to have multiple lockspaces open at one time. - -All the above calls work on the "default" lockspace, which should be -fine for most users. The calls below allow you to isolate your -application from all others running in the cluster. Remember, lockspaces -are a cluster-wide resource, so if you create a lockspace called "myls" it -will share locks with a lockspace called "myls" on all nodes. - - -dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode); - - This creates a lockspace called <name> and the mode of the file - user to access it wil be <mode> (subject to umask as usual). - The lockspace must not already exist on this node, if it does -1 - will be returned and errno will be set to EEXIST. If you really - want to use this lockspace you can then user dlm_open_lockspace() - below. The name is the name of a misc device that will be created - in /dev/misc. - - On success a handle to the lockspace is returned, which can be used - to pass into subsequent dlm_ls_lock/unlock calls. Make no assumptions - as to the content of this handle as it's content may change in future. - - The caller must have CAP_SYSADMIN privileges to do this operation. - - -int dlm_release_lockspace(const char *name, dlm_lshandle_t lockspace, int force) - - Deletes a lockspace. If the lockspace still has active locks then -1 will be - returned and errno set to EBUSY. Both the lockspace handle /and/ the name - must be specified. This call also closes the lockspace and stops the thread - associated with the lockspace, if any. - - Note that other nodes in the cluster may still have locks open on this - lockspace. - This call only removes the lockspace from the current node. - - If the force flag is set then the lockspace will be removed even if another - user on this node has active locks in it. Existing users will NOT - be notified if you do this, so be careful. - - -dlm_lshandle_t dlm_open_lockspace(const char *name) - - Opens an already existing lockspace and returns a handle to it. - - -int dlm_close_lockspace(dlm_lshandle_t lockspace) - - Close the lockspace. Any locks held by this process will be freed. - If a thread is associated with this lockspace then it will be stopped. - - -int dlm_ls_get_fd(dlm_lshandle_t lockspace) - - Returns the file descriptor associated with the lockspace so that the - user call use it as input to poll/select. - - -int dlm_ls_pthread_init(dlm_lshandle_t lockspace) - - Initialise threaded environment for this lockspace, similar - to dlm_pthread_init() above. - - -int dlm_ls_lock(dlm_lshandle_t lockspace, - int mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void (*ast) (void *astarg), - void *astarg, - void (*bast) (void *astarg), - struct dlm_range *range) - - Same as dlm_lock() above but takes a lockspace argument. - -int dlm_ls_lock_wait(dlm_lshandle_t lockspace, - int mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bast) (void *bastarg), - struct dlm_range *range) - - Same as dlm_lock_wait() above but takes a lockspace argument. - - -int dlm_ls_unlock(dlm_lshandle_t lockspace, - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb, - void *astarg) - - - Same as dlm_unlock above but takes a lockspace argument. - -int dlm_ls_unlock_wait(dlm_lshandle_t lockspace, - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb) - - - Same as dlm_unlock_wait above but takes a lockspace argument. - - -int dlm_ls_query(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*ast_routine(void *astarg)), - void *astarg); - - Same as dlm_query above but takes a lockspace argument. - -int dlm_ls_query_wait(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo) - - Same as dlm_query_wait above but takes a lockspace argument. - - -One further point about lockspace operations is that there is no locking -on the creating/destruction of lockspaces in the library so it is up to the -application to only call dlm_*_lockspace when it is sure that -no other locking operations are likely to be happening within that process. - -Libraries ---------- -There are two DLM libraries, one that uses pthreads (libdlm) to deliver ASTs -and a light one one that doesn't (libdlm_lt). - -The "light" library contains only the following calls. - -- dlm_lock -- dlm_unlock -- dlm_query -- dlm_get_fd -- dlm_dispatch -- dlm_ls_lock -- dlm_ls_unlock -- dlm_ls_query -- dlm_ls_get_fd -- dlm_create_lockspace -- dlm_open_lockspace -- dlm_release_lockspace -- dlm_close_lockspace - -Note that libdlm (the pthreads one) also contains the non-threaded calls -so you can choose at runtime if you need to. diff --git a/dlm/doc/user-dlm-overview.txt b/dlm/doc/user-dlm-overview.txt deleted file mode 100644 index bda3aea..0000000 --- a/dlm/doc/user-dlm-overview.txt +++ /dev/null @@ -1,325 +0,0 @@ - -There are five ways to request a dlm lock (and five corresponding ways to -unlock). - -- lock_resource -- dlm_lock -- dlm_ls_lock -- dlm_lock_wait -- dlm_ls_lock_wait - -- unlock_resource -- dlm_unlock -- dlm_ls_unlock -- dlm_unlock_wait -- dlm_ls_unlock_wait - -There is also a set of "administrative" functions that are used along with -some of the lock/unlock requests. Which are used depends on which locking -method is used or whether the application is threaded. - -- dlm_pthread_init -- dlm_ls_pthread_init -- dlm_pthread_cleanup -- dlm_get_fd -- dlm_ls_get_fd -- dlm_dispatch -- dlm_create_lockspace -- dlm_open_lockspace -- dlm_release_lockspace -- dlm_close_lockspace - - -Overview of lock request methods --------------------------------- - -- synchronous, default lockspace - use dlm_pthread_init/dlm_pthread_cleanup if app is threaded - use dlm_get_fd/dlm_dispatch if app is not threaded - use unlock_resource to unlock - -int lock_resource( - const char *resource, - uint32_t mode, - uint32_t flags, - uint32_t *lkid); - - -- asynchronous, default lockspace - use dlm_pthread_init/dlm_pthread_cleanup if app is threaded - use dlm_get_fd/dlm_dispatch if app is not threaded - use dlm_unlock/dlm_unlock_wait to unlock - -int dlm_lock( - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void (*ast) (void *astarg), - void *astarg, - void (*bast) (void *astarg), - struct dlm_range *range); - - -- synchronous, default lockspace - use dlm_pthread_init/dlm_pthread_cleanup if app is threaded - use dlm_get_fd/dlm_dispatch if app is not threaded - use dlm_unlock/dlm_unlock_wait to unlock - -int dlm_lock_wait( - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bast) (void *bastarg), - struct dlm_range *range); - - -- asynchronous, any lockspace - use dlm_ls_pthread_init/dlm_pthread_cleanup if app is threaded - use dlm_ls_get_fd/dlm_dispatch if app is not threaded - use dlm_create_lockspace/dlm_open_lockspace to start - use dlm_release_lockspace/dlm_close_lockspace to finish - use dlm_ls_unlock/dlm_ls_unlock_wait to unlock - -int dlm_ls_lock( - dlm_lshandle_t lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void (*ast) (void *astarg), - void *astarg, - void (*bast) (void *astarg), - struct dlm_range *range); - - -- synchronous, any lockspace - use dlm_ls_pthread_init/dlm_pthread_cleanup if app is threaded - use dlm_ls_get_fd/dlm_dispatch if app is not threaded - use dlm_create_lockspace/dlm_open_lockspace to start - use dlm_release_lockspace/dlm_close_lockspace to finish - use dlm_ls_unlock/dlm_ls_unlock_wait to unlock - -int dlm_ls_lock_wait( - dlm_lshandle_t lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bast) (void *bastarg), - struct dlm_range *range); - - - -Corresponding unlock requests ------------------------------ - -int unlock_resource( - uint32_t lkid); - -int dlm_unlock( - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb, - void *astarg); - -int dlm_unlock_wait( - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb); - -int dlm_ls_unlock( - dlm_lshandle_t lockspace, - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb, - void *astarg); - -int dlm_ls_unlock_wait( - dlm_lshandle_t lockspace, - uint32_t lkid, - uint32_t flags, - struct dlm_lksb *lksb); - - - -Common to all of the above --------------------------- - -#define DLM_RESNAME_MAXLEN (64) -#define DLM_LVB_LEN (32) - -#define LKM_NLMODE 0 /* null lock */ -#define LKM_CRMODE 1 /* concurrent read */ -#define LKM_CWMODE 2 /* concurrent write */ -#define LKM_PRMODE 3 /* protected read */ -#define LKM_PWMODE 4 /* protected write */ -#define LKM_EXMODE 5 /* exclusive */ - -#define LKF_NOQUEUE (0x00000001) -#define LKF_CANCEL (0x00000002) -#define LKF_CONVERT (0x00000004) -#define LKF_VALBLK (0x00000008) -#define LKF_QUECVT (0x00000010) -#define LKF_IVVALBLK (0x00000020) -#define LKF_CONVDEADLK (0x00000040) -#define LKF_PERSISTENT (0x00000080) -#define LKF_NODLCKWT (0x00000100) -#define LKF_NODLCKBLK (0x00000200) -#define LKF_EXPEDITE (0x00000400) -#define LKF_NOQUEUEBAST (0x00000800) -#define LKF_HEADQUE (0x00001000) -#define LKF_NOORDER (0x00002000) - -#define ECANCEL (0x10001) -#define EUNLOCK (0x10002) -#define EINPROG (0x10003) - -struct dlm_lksb { - int sb_status; - uint32_t sb_lkid; - char sb_flags; - char *sb_lvbptr; -}; - -struct dlm_range { - uint64_t ra_start; - uint64_t ra_end; -}; - - - - -Overview of administrative functions ------------------------------------- - -- dlm_pthread_init -- dlm_ls_pthread_init -- dlm_pthread_cleanup -- dlm_get_fd -- dlm_ls_get_fd -- dlm_dispatch -- dlm_create_lockspace -- dlm_open_lockspace -- dlm_release_lockspace -- dlm_close_lockspace - - -typedef void * dlm_lshandle_t; - -dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode); - -int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force); - -dlm_lshandle_t dlm_open_lockspace(const char *name); - -int dlm_close_lockspace(dlm_lshandle_t ls); - -int dlm_pthread_init(); - -int dlm_ls_pthread_init(dlm_lshandle_t lockspace); - -int dlm_pthread_cleanup(); - -int dlm_get_fd(); - -int dlm_ls_get_fd(dlm_lshandle_t ls); - -int dlm_dispatch(int fd); - - - -Query functions ---------------- - -Query functions follow the same pattern as the lock and unlock functions. - -int dlm_query( - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*astaddr) (void *astarg), - void *astarg); - -int dlm_query_wait( - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo); - -int dlm_ls_query( - dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*astaddr) (void *astarg), - void *astarg); - -int dlm_ls_query_wait( - dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo); - -#define DLM_LOCK_THIS 0x0007 -#define DLM_QUERY_MODE_MASK 0x0007 - -#define DLM_QUERY_QUEUE_WAIT 0x0008 -#define DLM_QUERY_QUEUE_CONVERT 0x0010 -#define DLM_QUERY_QUEUE_GRANT 0x0020 -#define DLM_QUERY_QUEUE_GRANTED 0x0030 -#define DLM_QUERY_QUEUE_ALL 0x0038 - -#define DLM_QUERY_LOCKS_HIGHER 0x0100 -#define DLM_QUERY_LOCKS_LOWER 0x0200 -#define DLM_QUERY_LOCKS_EQUAL 0x0300 -#define DLM_QUERY_LOCKS_BLOCKING 0x0400 -#define DLM_QUERY_LOCKS_NOTBLOCK 0x0500 -#define DLM_QUERY_LOCKS_ALL 0x0600 -#define DLM_QUERY_MASK 0x0F00 - -#define DLM_QUERY_GRMODE 0x0000 -#define DLM_QUERY_RQMODE 0x1000 - -struct dlm_lockinfo { - int lki_lkid; - int lki_mstlkid; - int lki_parent; - int lki_node; - int lki_ownpid; - uint8_t lki_state; - uint8_t lki_grmode; - uint8_t lki_rqmode; - struct dlm_range lki_grrange; - struct dlm_range lki_rqrange; -}; - -struct dlm_resinfo { - int rsi_length; - int rsi_grantcount; - int rsi_convcount; - int rsi_waitcount; - int rsi_masternode; - char rsi_name[DLM_RESNAME_MAXLEN]; - char rsi_valblk[DLM_LVB_LEN]; -}; - -struct dlm_queryinfo { - struct dlm_resinfo *gqi_resinfo; - struct dlm_lockinfo *gqi_lockinfo; - int gqi_locksize; - int gqi_lockcount; -}; - - - diff --git a/dlm/lib/Makefile b/dlm/lib/Makefile deleted file mode 100644 index f8bcc40..0000000 --- a/dlm/lib/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2004 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE=libdlm.c - -LIBNAME=libdlm -SHAREDLIB=$(LIBNAME).so.${RELEASE_MAJOR}.${RELEASE_MINOR} $(LIBNAME)_lt.so.${RELEASE_MAJOR}.${RELEASE_MINOR} -STATICLIB=$(LIBNAME).a $(LIBNAME)_lt.a - -top_srcdir=.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -CFLAGS += -g -O -I. -fPIC - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -CFLAGS += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -CFLAGS += -I${incdir}/cluster -endif - - -all: $(STATICLIB) $(SHAREDLIB) - -$(LIBNAME).a: libdlm.o - ${AR} r libdlm.a libdlm.o - ${RANLIB} libdlm.a - -$(LIBNAME)_lt.a: libdlm_lt.o - ${AR} r libdlm_lt.a libdlm_lt.o - ${RANLIB} libdlm_lt.a - -$(LIBNAME).so.${RELEASE_MAJOR}.${RELEASE_MINOR}: libdlm.po - $(CC) -shared -o $@ -Wl,-soname=$(LIBNAME).so.$(RELEASE_MAJOR) $^ - -$(LIBNAME)_lt.so.${RELEASE_MAJOR}.${RELEASE_MINOR}: libdlm_lt.po - $(CC) -shared -o $@ -Wl,-soname=$(LIBNAME)_lt.so.$(RELEASE_MAJOR) $^ - -libdlm.po: libdlm.c - $(CC) $(CFLAGS) -D_REENTRANT -c -o $@ $< - -libdlm.o: libdlm.c - $(CC) $(CFLAGS) -D_REENTRANT -c -o $@ $< - -libdlm_lt.po: libdlm.c - $(CC) $(CFLAGS) -c -o $@ $< - -libdlm_lt.o: libdlm.c - $(CC) $(CFLAGS) -c -o $@ $< - -copytobin: all - - -install: all - install -d ${incdir} - install -m644 libdlm.h ${incdir} - install -d ${DESTDIR}/etc/udev/rules.d - install -m644 ../scripts/51-dlm.rules ${DESTDIR}/etc/udev/rules.d - install -d ${libdir} - install $(LIBNAME).a ${libdir} - install $(LIBNAME)_lt.a ${libdir} - install $(LIBNAME).so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir} - install $(LIBNAME)_lt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir} - ln -sf $(LIBNAME).so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir}/$(LIBNAME).so - ln -sf $(LIBNAME).so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir}/$(LIBNAME).so.$(RELEASE_MAJOR) - ln -sf $(LIBNAME)_lt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir}/$(LIBNAME)_lt.so - ln -sf $(LIBNAME)_lt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir}/$(LIBNAME)_lt.so.$(RELEASE_MAJOR) - -uninstall: - ${UNINSTALL} libdlm.h ${incdir} - ${UNINSTALL} \ - ${LIBNAME}.a \ - ${LIBNAME}_lt.a \ - $(LIBNAME).so \ - $(LIBNAME)_lt.so \ - $(LIBNAME).so.$(RELEASE_MAJOR) \ - ${LIBNAME}.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir} \ - $(LIBNAME)_lt.so.$(RELEASE_MAJOR) \ - ${LIBNAME}_lt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) ${libdir} - rm -f /lib/${LIBNAME}.* - -clean: - rm -f *.o *.a *.so *.so.* *.po - rm -f *~ diff --git a/dlm/lib/dlm32.c b/dlm/lib/dlm32.c deleted file mode 100644 index dd5fd35..0000000 --- a/dlm/lib/dlm32.c +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with this library; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -** -******************************************************************************* -******************************************************************************/ - -/* Convert 32 bit userland reads & writes to something suitable for - a 64 bit kernel */ - - -/* 64 bit versions of the structs */ -struct dlm_lock_params64 { - uint8_t mode; - uint16_t flags; - uint32_t lkid; - uint32_t parent; - struct dlm_range range; - uint8_t namelen; - uint64_t castparam; - uint64_t castaddr; - uint64_t bastparam; - uint64_t bastaddr; - uint64_t lksb; - char lvb[DLM_LVB_LEN]; - char name[1]; -}; - -struct dlm_query_params64 { - uint32_t query; - uint64_t qinfo; - uint64_t resinfo; - uint64_t lockinfo; - uint64_t castparam; - uint64_t castaddr; - uint64_t lksb; - uint32_t lkid; - int lockinfo_max; -}; - - -struct dlm_lspace_params64 { - uint32_t flags; - uint32_t minor; - char name[1]; -}; - -struct dlm_write_request64 { - uint32_t version[3]; - uint8_t cmd; - - union { - struct dlm_lock_params64 lock; - struct dlm_query_params64 query; - struct dlm_lspace_params64 lspace; - } i; -}; - -struct dlm_lksb64 -{ - int sb_status; - uint32_t sb_lkid; - char sb_flags; - uint64_t sb_lvbptr; -}; - -/* struct read from the "device" fd, - consists mainly of userspace pointers for the library to use */ -struct dlm_lock_result64 { - uint32_t length; - uint64_t user_astaddr; - uint64_t user_astparam; - uint64_t user_lksb; - uint64_t user_qinfo; - struct dlm_lksb64 lksb; - uint8_t bast_mode; - /* Offsets may be zero if no data is present */ - uint32_t lvb_offset; - uint32_t qinfo_offset; - uint32_t qresinfo_offset; - uint32_t qlockinfo_offset; -}; - -struct dlm_queryinfo64 { - uint64_t gqi_resinfo; - uint64_t gqi_lockinfo; - - int gqi_locksize; /* input */ - int gqi_lockcount; /* output */ -}; - - -int dlm_write(int fd, void *buf, int len) -{ - char buf64[sizeof(struct dlm_write_request64) + DLM_RESNAME_MAXLEN]; - struct dlm_write_request64 *req64; - struct dlm_write_request *req32; - int len64; - int ret; - - req32 = (struct dlm_write_request *)buf; - req64 = (struct dlm_write_request64 *)buf64; - len64 = sizeof(struct dlm_write_request64); - - req64->version[0] = req32->version[0]; - req64->version[1] = req32->version[1]; - req64->version[2] = req32->version[2]; - req64->cmd = req32->cmd; - switch (req32->cmd) - { - case DLM_USER_LOCK: - case DLM_USER_UNLOCK: - req64->i.lock.mode = req32->i.lock.mode; - req64->i.lock.flags = req32->i.lock.flags; - req64->i.lock.lkid = req32->i.lock.lkid; - req64->i.lock.parent = req32->i.lock.parent; - req64->i.lock.range.ra_start = req32->i.lock.range.ra_start; - req64->i.lock.range.ra_end = req32->i.lock.range.ra_end; - req64->i.lock.namelen = req32->i.lock.namelen; - req64->i.lock.castparam = (uint64_t)(uint32_t)req32->i.lock.castparam; - req64->i.lock.castaddr = (uint64_t)(uint32_t)req32->i.lock.castaddr; - req64->i.lock.bastparam = (uint64_t)(uint32_t)req32->i.lock.bastparam; - req64->i.lock.bastaddr = (uint64_t)(uint32_t)req32->i.lock.bastaddr; - req64->i.lock.lksb = (uint64_t)(uint32_t)req32->i.lock.lksb; - memcpy(req64->i.lock.lvb, req32->i.lock.lvb, DLM_LVB_LEN); - memcpy(req64->i.lock.name, req32->i.lock.name, req64->i.lock.namelen); - len64 = sizeof(struct dlm_write_request64) + req64->i.lock.namelen; - break; - - case DLM_USER_QUERY: - req64->i.query.query = req32->i.query.query; - req64->i.query.qinfo = (uint64_t)(uint32_t)req32->i.query.qinfo; - req64->i.query.resinfo = (uint64_t)(uint32_t)req32->i.query.resinfo; - req64->i.query.lockinfo = (uint64_t)(uint32_t)req32->i.query.lockinfo; - req64->i.query.castparam = (uint64_t)(uint32_t)req32->i.query.castparam; - req64->i.query.castaddr = (uint64_t)(uint32_t)req32->i.query.castaddr; - req64->i.query.lksb = (uint64_t)(uint32_t)req32->i.query.lksb; - req64->i.query.lkid = req32->i.query.lkid; - req64->i.query.lockinfo_max = req32->i.query.lockinfo_max; - break; - - case DLM_USER_CREATE_LOCKSPACE: - case DLM_USER_REMOVE_LOCKSPACE: - req64->i.lspace.flags = req32->i.lspace.flags; - req64->i.lspace.minor = req32->i.lspace.minor; - strcpy(req64->i.lspace.name, req32->i.lspace.name); - len64 = sizeof(struct dlm_write_request64) + strlen(req64->i.lspace.name); - break; - } - - ret = write(fd, buf64, len64); - - /* Fake the return length */ - if (ret == len64) - ret = len; - - return ret; -} - - -int dlm_read(int fd, void *buf, int len) -{ - int ret; - int len64; - struct dlm_lock_result *res32; - struct dlm_lock_result64 *res64; - struct dlm_lock_result64 buf64; - - res32 = (struct dlm_lock_result *)buf; - - /* There are two types of read done here, the first just gets the structure, for that - we need our own buffer because the 64 bit one is larger than the 32bit. - When the user wants the extended information it has already been told the full (64bit) - size of the buffer by the kernel so we can use that buffer for reading, that - also avoids the need to copy the extended data blocks too. - */ - if (len == sizeof(struct dlm_lock_result)) - { - len64 = sizeof(struct dlm_lock_result64); - res64 = &buf64; - } - else - { - len64 = len; - res64 = (struct dlm_lock_result64 *)buf; - } - - ret = read(fd, res64, len64); - if (ret > 0) - { - res32->length = res64->length; - res32->user_astaddr = (void *)(long)res64->user_astaddr; - res32->user_astparam = (void *)(long)res64->user_astparam; - res32->user_lksb = (void *)(long)res64->user_lksb; - res32->user_qinfo = (void *)(long)res64->user_qinfo; - res32->lksb.sb_status = res64->lksb.sb_status; - res32->lksb.sb_flags = res64->lksb.sb_flags; - res32->lksb.sb_lkid = res64->lksb.sb_lkid; - res32->bast_mode = res64->bast_mode; - res32->lvb_offset = res64->lvb_offset; - res32->qinfo_offset = res64->qinfo_offset; - res32->qresinfo_offset = res64->qresinfo_offset; - res32->qlockinfo_offset = res64->qlockinfo_offset; - - if (res32->qinfo_offset) - { - struct dlm_queryinfo64 *qinfo64; - struct dlm_queryinfo *qinfo32; - - qinfo64 = (struct dlm_queryinfo64 *)(buf+res32->qinfo_offset); - qinfo32 = (struct dlm_queryinfo *)(buf+res32->qinfo_offset); - qinfo32->gqi_lockcount = qinfo64->gqi_lockcount; - } - } - return ret; -} diff --git a/dlm/lib/libdlm.c b/dlm/lib/libdlm.c deleted file mode 100644 index 1623151..0000000 --- a/dlm/lib/libdlm.c +++ /dev/null @@ -1,1118 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with this library; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -** -******************************************************************************* -******************************************************************************/ - - -#ifdef _REENTRANT -#include <pthread.h> -#endif -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <stdint.h> -#include <stdlib.h> -#include <inttypes.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <stdio.h> -#include <linux/major.h> -#ifdef HAVE_SELINUX -#include <selinux/selinux.h> -#endif -#include "dlm.h" -#define BUILDING_LIBDLM -#include "libdlm.h" -#include "dlm_device.h" - -/* Add other grotesqueries here as they arise */ -#if defined(__sparc__) && __WORDSIZE == 32 -#include "dlm32.c" -#else -#define dlm_write write -#define dlm_read read -#endif - - -#define MISC_PREFIX "/dev/misc/" -#define PROC_MISC "/proc/misc" -#define DLM_PREFIX "dlm_" -#define DLM_MISC_PREFIX MISC_PREFIX DLM_PREFIX -#define DLM_CONTROL_DEV "dlm-control" -#define DEFAULT_LOCKSPACE "default" - -/* This is the name of the control device */ -#define DLM_CTL_DEVICE_NAME MISC_PREFIX DLM_CONTROL_DEV - -/* One of these per lockspace in use by the application */ -struct dlm_ls_info -{ - int fd; -#ifdef _REENTRANT - pthread_t tid; -#else - int tid; -#endif -}; - -/* The default lockspace. - I've resisted putting locking around this as the user should be - "sensible" and only do lockspace operations either in the - main thread or ... carefully... -*/ -static struct dlm_ls_info *default_ls = NULL; -static int control_fd = -1; - -static void ls_dev_name(const char *lsname, char *devname, int devlen) -{ - snprintf(devname, devlen, DLM_MISC_PREFIX "%s", lsname); -} - -#ifdef HAVE_SELINUX -static int set_selinux_context(const char *path) -{ - security_context_t scontext; - - if (is_selinux_enabled() <= 0) - return 1; - - if (matchpathcon(path, 0, &scontext) < 0) { - return 0; - } - - if ((lsetfilecon(path, scontext) < 0) && (errno != ENOTSUP)) { - freecon(scontext); - return 0; - } - - free(scontext); - return 1; -} -#endif - - -#ifdef _REENTRANT -/* Used for the synchronous and "simplified, synchronous" API routines */ -struct lock_wait -{ - pthread_cond_t cond; - pthread_mutex_t mutex; - struct dlm_lksb lksb; -}; - -static void dummy_ast_routine(void *arg) -{ -} - -static void sync_ast_routine(void *arg) -{ - struct lock_wait *lwait = arg; - - pthread_mutex_lock(&lwait->mutex); - pthread_cond_signal(&lwait->cond); - pthread_mutex_unlock(&lwait->mutex); -} - -/* lock_resource & unlock_resource - * are the simplified, synchronous API. - * Aways uses the default lockspace. - */ -int lock_resource(const char *resource, int mode, int flags, int *lockid) -{ - int status; - struct lock_wait lwait; - - if (default_ls == NULL) - { - if (dlm_pthread_init()) - { - return -1; - } - } - - if (!lockid) - { - errno = EINVAL; - return -1; - } - - /* Conversions need the lockid in the LKSB */ - if (flags & LKF_CONVERT) - lwait.lksb.sb_lkid = *lockid; - - pthread_cond_init(&lwait.cond, NULL); - pthread_mutex_init(&lwait.mutex, NULL); - pthread_mutex_lock(&lwait.mutex); - - status = dlm_lock(mode, - &lwait.lksb, - flags, - resource, - strlen(resource), - 0, - sync_ast_routine, - &lwait, - NULL, - NULL); - if (status) - return status; - - /* Wait for it to complete */ - pthread_cond_wait(&lwait.cond, &lwait.mutex); - pthread_mutex_unlock(&lwait.mutex); - - *lockid = lwait.lksb.sb_lkid; - - errno = lwait.lksb.sb_status; - if (lwait.lksb.sb_status) - return -1; - else - return 0; -} - - -int unlock_resource(int lockid) -{ - int status; - struct lock_wait lwait; - - if (default_ls == NULL) - { - errno = -ENOTCONN; - return -1; - } - - pthread_cond_init(&lwait.cond, NULL); - pthread_mutex_init(&lwait.mutex, NULL); - pthread_mutex_lock(&lwait.mutex); - - status = dlm_unlock(lockid, 0, &lwait.lksb, &lwait); - - if (status) - return status; - - /* Wait for it to complete */ - pthread_cond_wait(&lwait.cond, &lwait.mutex); - pthread_mutex_unlock(&lwait.mutex); - - errno = lwait.lksb.sb_status; - if (lwait.lksb.sb_status != DLM_EUNLOCK) - return -1; - else - return 0; -} - -/* Tidy up threads after a lockspace is closed */ -static int ls_pthread_cleanup(struct dlm_ls_info *lsinfo) -{ - int status = 0; - int fd; - - /* Must close the fd after the thread has finished */ - fd = lsinfo->fd; - if (lsinfo->tid) - { - status = pthread_cancel(lsinfo->tid); - if (!status) - pthread_join(lsinfo->tid, NULL); - } - if (!status) - { - free(lsinfo); - close(fd); - } - - return status; -} - -/* Cleanup default lockspace */ -int dlm_pthread_cleanup() -{ - struct dlm_ls_info *lsinfo = default_ls; - - /* Protect users from their own stupidity */ - if (!lsinfo) - return 0; - - default_ls = NULL; - - return ls_pthread_cleanup(lsinfo); -} -#else - -/* Non-pthread version of cleanup */ -static int ls_pthread_cleanup(struct dlm_ls_info *lsinfo) -{ - close(lsinfo->fd); - free(lsinfo); - return 0; -} -#endif - -static void set_version(struct dlm_write_request *req) -{ - req->version[0] = DLM_DEVICE_VERSION_MAJOR; - req->version[1] = DLM_DEVICE_VERSION_MINOR; - req->version[2] = DLM_DEVICE_VERSION_PATCH; -} - -/* Open the default lockspace */ -static int open_default_lockspace() -{ - if (!default_ls) - { - dlm_lshandle_t ls; - - /* This isn't the race it looks, create_lockspace will - * do the right thing if the lockspace has already been - * created. - */ - ls = dlm_open_lockspace(DEFAULT_LOCKSPACE); - if (!ls) - ls = dlm_create_lockspace(DEFAULT_LOCKSPACE, 0600); - if (!ls) - return -1; - - default_ls = (struct dlm_ls_info *)ls; - } - return 0; -} - -static int create_control_device() -{ - FILE *pmisc; - int minor; - char name[256]; - int status = 0; - int saved_errno = 0; - mode_t oldmode; - - /* Make sure the parent directory exists */ - oldmode = umask(0); - status = mkdir(MISC_PREFIX, 0755); - umask(oldmode); - if (status != 0 && errno != EEXIST) - { - return status; - } - - pmisc = fopen(PROC_MISC, "r"); - if (!pmisc) - return -1; - - while (!feof(pmisc)) - { - fscanf(pmisc, "%d %s\n", &minor, name); - if (strcmp(name, DLM_CONTROL_DEV) == 0) - { - status = mknod(DLM_CTL_DEVICE_NAME, S_IFCHR | 0600, makedev(MISC_MAJOR, minor)); - saved_errno = errno; -#ifdef HAVE_SELINUX - if (status == 0) - set_selinux_context(DLM_CTL_DEVICE_NAME); -#endif - break; - } - } - fclose(pmisc); - - errno = saved_errno; - return status; -} - -static int find_minor_from_proc(const char *prefix, const char *lsname) -{ - FILE *f = fopen(PROC_MISC, "r"); - char miscname[strlen(lsname)+strlen(prefix)+1]; - char name[256]; - int minor; - - sprintf(miscname, "%s%s", prefix, lsname); - - if (f) - { - while (!feof(f)) - { - if (fscanf(f, "%d %s", &minor, name) == 2 && - strcmp(name, miscname) == 0) - { - fclose(f); - return minor; - } - } - } - - fclose(f); - return 0; -} - -static int open_control_device() -{ - int minor; - struct stat st; - int stat_ret; - - if (control_fd == -1) - { - stat_ret = stat(DLM_CTL_DEVICE_NAME, &st); - - if (!stat_ret) - { - minor = find_minor_from_proc("",DLM_CONTROL_DEV); - if (S_ISCHR(st.st_mode) && st.st_rdev != makedev(MISC_MAJOR, minor)) - unlink(DLM_CTL_DEVICE_NAME); - } - - control_fd = open(DLM_CTL_DEVICE_NAME, O_RDWR); - - if (control_fd == -1) - { - create_control_device(); - control_fd = open(DLM_CTL_DEVICE_NAME, O_RDWR); - if (control_fd == -1) - return -1; - } - fcntl(control_fd, F_SETFD, 1); - } - return 0; -} - -static int do_dlm_dispatch(int fd) -{ - char resultbuf[sizeof(struct dlm_lock_result)]; - struct dlm_lock_result *result = (struct dlm_lock_result *)resultbuf; - char *fullresult=NULL; - int status; - void (*astaddr)(void *astarg); - - /* Just read the header first */ - status = dlm_read(fd, result, sizeof(struct dlm_lock_result)); - if (status <= 0) - return -1; - - if (result->length != status) - { - int newstat; - - fullresult = malloc(result->length); - if (!fullresult) - return -1; - - newstat = dlm_read(fd, fullresult, result->length); - - /* If it read OK then use the new data. otherwise we can - still deliver the AST, it just might not have all the - info in it...hmmm */ - if (newstat == result->length) - result = (struct dlm_lock_result *)fullresult; - } - - /* Copy lksb to user's buffer - except the LVB ptr */ - memcpy(result->user_lksb, &result->lksb, sizeof(struct dlm_lksb) - sizeof(char*)); - - /* Flip the status. Kernel space likes negative return codes, - userspace positive ones */ - result->user_lksb->sb_status = -result->user_lksb->sb_status; - - /* Copy optional items */ - if (result->lvb_offset) - memcpy(result->user_lksb->sb_lvbptr, fullresult+result->lvb_offset, DLM_LVB_LEN); - - if (result->qinfo_offset) - { - /* Just need the lockcount written out here */ - struct dlm_queryinfo *qi = (struct dlm_queryinfo *)(fullresult+result->qinfo_offset); - result->user_qinfo->gqi_lockcount = qi->gqi_lockcount; - } - - if (result->qresinfo_offset) - memcpy(result->user_qinfo->gqi_resinfo, fullresult+result->qresinfo_offset, - sizeof(struct dlm_resinfo)); - - if (result->qlockinfo_offset) - memcpy(result->user_qinfo->gqi_lockinfo, fullresult+result->qlockinfo_offset, - sizeof(struct dlm_lockinfo) * result->user_qinfo->gqi_lockcount); - - /* Call AST */ - if (result->user_astaddr) - { - astaddr = result->user_astaddr; - astaddr(result->user_astparam); - } - - if (fullresult) - free(fullresult); - return 0; -} - -#ifdef _REENTRANT - -/* Helper routine which supports the synchronous DLM calls. This - writes a parameter block down to the DLM and waits for the - operation to complete. This hides the different completion mechanism - used when called from the main thread or the DLM 'AST' thread. -*/ -static int sync_write(struct dlm_ls_info *lsinfo, struct dlm_write_request *req, int len) -{ - int status; - struct lock_wait lwait; - - if (pthread_self() == lsinfo->tid) - { - /* This is the DLM worker thread, don't use lwait to sync */ - req->i.lock.castaddr = dummy_ast_routine; - req->i.lock.castparam = NULL; - - status = dlm_write(lsinfo->fd, req, len); - if (status < 0) - return -1; - - while (req->i.lock.lksb->sb_status == EINPROG) { - do_dlm_dispatch(lsinfo->fd); - } - } - else - { - pthread_cond_init(&lwait.cond, NULL); - pthread_mutex_init(&lwait.mutex, NULL); - pthread_mutex_lock(&lwait.mutex); - - req->i.lock.castaddr = sync_ast_routine; - req->i.lock.castparam = &lwait; - - status = dlm_write(lsinfo->fd, req, len); - if (status < 0) - return -1; - - pthread_cond_wait(&lwait.cond, &lwait.mutex); - pthread_mutex_unlock(&lwait.mutex); - } - return status; /* lock status is in the lksb */ -} -#endif - -/* Lock on default lockspace*/ -int dlm_lock(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - struct dlm_range *range) -{ - if (open_default_lockspace()) - return -1; - - return dlm_ls_lock(default_ls, mode, lksb, flags, name, namelen, parent, - astaddr, astarg, bastaddr, range); -} - - -/* - * This is the full-fat, aynchronous DLM call - */ -int dlm_ls_lock(dlm_lshandle_t ls, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - struct dlm_range *range) -{ - int len; - char param_buf[sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN]; - struct dlm_write_request *req = (struct dlm_write_request *)param_buf; - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls; - int status; - - set_version(req); - - req->cmd = DLM_USER_LOCK; - req->i.lock.mode = mode; - req->i.lock.flags = flags; - req->i.lock.lkid = lksb->sb_lkid; - req->i.lock.parent = parent; - req->i.lock.lksb = lksb; - req->i.lock.castaddr = astaddr; - req->i.lock.bastaddr = bastaddr; - req->i.lock.castparam = astarg; /* completion and blocking ast arg are the same */ - req->i.lock.bastparam = astarg; - if (range) - { - req->i.lock.range.ra_start = range->ra_start; - req->i.lock.range.ra_end = range->ra_end; - } - else - { - req->i.lock.range.ra_start = 0L; - req->i.lock.range.ra_end = 0L; - } - if (flags & LKF_CONVERT) - { - req->i.lock.namelen = 0; - } - else - { - if (namelen > DLM_RESNAME_MAXLEN) - { - errno = EINVAL; - return -1; - } - req->i.lock.namelen = namelen; - memcpy(req->i.lock.name, name, namelen); - } - if (flags & LKF_VALBLK) - { - memcpy(req->i.lock.lvb, lksb->sb_lvbptr, DLM_LVB_LEN); - } - len = sizeof(struct dlm_write_request) + namelen - 1; - lksb->sb_status = EINPROG; - -#ifdef _REENTRANT - if (flags & LKF_WAIT) - status = sync_write(lsinfo, req, len); - else -#endif - status = dlm_write(lsinfo->fd, req, len); - - if (status < 0) - { - return -1; - } - else - { - if (status > 0) - lksb->sb_lkid = status; - return 0; - } -} - -#ifdef _REENTRANT -int dlm_lock_wait(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - struct dlm_range *range) -{ - if (open_default_lockspace()) - return -1; - - return dlm_ls_lock(default_ls, mode, lksb, flags | LKF_WAIT, - name, namelen, parent, NULL, bastarg, - bastaddr, range); -} - -/* - * This is the full-fat, synchronous DLM call - */ -int dlm_ls_lock_wait(dlm_lshandle_t ls, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - struct dlm_range *range) -{ - - return dlm_ls_lock(ls, mode, lksb, flags | LKF_WAIT, - name, namelen, parent, NULL, bastarg, - bastaddr, range); -} - -int dlm_ls_unlock_wait(dlm_lshandle_t ls, uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb) -{ - - return dlm_ls_unlock(ls, lkid, flags | LKF_WAIT, - lksb, NULL); -} - -int dlm_ls_query_wait(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo) -{ - struct dlm_write_request req; - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)lockspace; - int status; - - if (lockspace == NULL) - { - errno = ENOTCONN; - return -1; - } - - if (!lksb) - { - errno = EINVAL; - return -1; - } - - if (!lksb->sb_lkid) - { - errno = EINVAL; - return -1; - } - - set_version(&req); - req.cmd = DLM_USER_QUERY; - req.i.query.query = query; - req.i.query.lksb = lksb; - req.i.query.lkid = lksb->sb_lkid; - req.i.query.qinfo = qinfo; - req.i.query.lockinfo_max = qinfo->gqi_locksize; - req.i.query.lockinfo = qinfo->gqi_lockinfo; - req.i.query.lockinfo_max = qinfo->gqi_locksize; - lksb->sb_status = EINPROG; - - status = sync_write(lsinfo, &req, sizeof(req)); - return (status >= 0); -} - -int dlm_unlock_wait(uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb) -{ - return dlm_ls_unlock_wait(default_ls, lkid, flags | LKF_WAIT, lksb); -} - -int dlm_query_wait(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo) -{ - return dlm_ls_query_wait(default_ls, lksb, query, qinfo); -} - -#endif - -/* Unlock on default lockspace*/ -int dlm_unlock(uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb, void *astarg) -{ - return dlm_ls_unlock(default_ls, lkid, flags, lksb, astarg); -} - - -int dlm_ls_unlock(dlm_lshandle_t ls, uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb, void *astarg) -{ - struct dlm_write_request req; - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls; - int status; - - if (ls == NULL) - { - errno = ENOTCONN; - return -1; - } - - if (!lkid) - { - errno = EINVAL; - return -1; - } - - set_version(&req); - req.cmd = DLM_USER_UNLOCK; - req.i.lock.lkid = lkid; - req.i.lock.flags = flags; - req.i.lock.lksb = lksb; - req.i.lock.castparam = astarg; - /* DLM_USER_UNLOCK will default to existing completion AST */ - req.i.lock.castaddr = 0; - lksb->sb_status = EINPROG; - -#ifdef _REENTRANT - if (flags & LKF_WAIT) - status = sync_write(lsinfo, &req, sizeof(req)); - else -#endif - status = dlm_write(lsinfo->fd, &req, sizeof(req)); - - if (status < 0) - return -1; - else - return 0; -} - - -int dlm_ls_query(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*astaddr) (void *astarg), - void *astarg) -{ - struct dlm_write_request req; - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)lockspace; - int status; - - if (lockspace == NULL) - { - errno = ENOTCONN; - return -1; - } - - if (!lksb) - { - errno = EINVAL; - return -1; - } - - if (!lksb->sb_lkid) - { - errno = EINVAL; - return -1; - } - - set_version(&req); - req.cmd = DLM_USER_QUERY; - req.i.query.query = query; - req.i.query.lksb = lksb; - req.i.query.lkid = lksb->sb_lkid; - req.i.query.castparam = astarg; - req.i.query.castaddr = astaddr; - req.i.query.qinfo = qinfo; - req.i.query.resinfo = qinfo->gqi_resinfo; - req.i.query.lockinfo = qinfo->gqi_lockinfo; - req.i.query.lockinfo_max = qinfo->gqi_locksize; - lksb->sb_status = EINPROG; - - status = dlm_write(lsinfo->fd, &req, sizeof(req)); - if (status != sizeof(req)) - return -1; - else - return 0; -} - -int dlm_query(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*astaddr) (void *astarg), - void *astarg) -{ - return dlm_ls_query(default_ls, lksb, query, qinfo, astaddr, astarg); -} - - -/* These two routines for for users that want to - * do their own fd handling. - * This allows a non-threaded app to use the DLM. - */ -int dlm_get_fd() -{ - if (default_ls) - { - return default_ls->fd; - } - else - { - if (open_default_lockspace()) - return -1; - else - return default_ls->fd; - } -} - -int dlm_dispatch(int fd) -{ - int status; - int fdflags; - - fdflags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, fdflags | O_NONBLOCK); - do - { - status = do_dlm_dispatch(fd); - } while (status == 0); - - /* EAGAIN is not an error */ - if (status < 0 && errno == EAGAIN) - status = 0; - - fcntl(fd, F_SETFL, fdflags); - return status; -} - -/* Converts a lockspace handle into a file descriptor */ -int dlm_ls_get_fd(dlm_lshandle_t lockspace) -{ - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)lockspace; - - return lsinfo->fd; -} - -#ifdef _REENTRANT -static void *dlm_recv_thread(void *lsinfo) -{ - struct dlm_ls_info *lsi = lsinfo; - - for (;;) - do_dlm_dispatch(lsi->fd); -} - -/* Multi-threaded callers normally use this */ -int dlm_pthread_init() -{ - if (open_default_lockspace()) - return -1; - - if (default_ls->tid) - { - errno = EEXIST; - return -1; - } - - if (pthread_create(&default_ls->tid, NULL, dlm_recv_thread, default_ls)) - { - int saved_errno = errno; - close(default_ls->fd); - free(default_ls); - default_ls = NULL; - errno = saved_errno; - return -1; - } - return 0; -} - -/* And same, for those with their own lockspace */ -int dlm_ls_pthread_init(dlm_lshandle_t ls) -{ - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls; - - if (lsinfo->tid) - { - errno = EEXIST; - return -1; - } - - return pthread_create(&lsinfo->tid, NULL, dlm_recv_thread, (void *)ls); -} -#endif - -/* - * Lockspace manipulation functions - */ - -/* - * Privileged users (checked by the kernel) - * can create/release lockspaces - */ -dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode) -{ - int status; - int minor; - int i; - struct stat st; - int stat_ret; - int create_dev = 1; - char dev_name[PATH_MAX]; - struct dlm_ls_info *newls; - char reqbuf[sizeof(struct dlm_write_request) + strlen(name)]; - struct dlm_write_request *req = (struct dlm_write_request *)reqbuf; - - /* We use the control device for creating lockspaces. */ - if (open_control_device()) - return NULL; - - newls = malloc(sizeof(struct dlm_ls_info)); - if (!newls) - return NULL; - - ls_dev_name(name, dev_name, sizeof(dev_name)); - - req->cmd = DLM_USER_CREATE_LOCKSPACE; - set_version(req); - - /* Make the default lockspace free itself when all users have released it */ - if (strcmp(name, DEFAULT_LOCKSPACE) == 0) - req->i.lspace.flags = DLM_USER_LSFLG_AUTOFREE | DLM_USER_LSFLG_DEFAULTLS; - else - req->i.lspace.flags = 0; - strcpy(req->i.lspace.name, name); - minor = dlm_write(control_fd, req, sizeof(*req) + strlen(name)); - - if (minor < 0 && errno != EEXIST) - { - free(newls); - return NULL; - } - - /* Wait for udev to create the device */ - for (i=1; i<10; i++) { - if (stat(dev_name, &st) == 0) - break; - sleep(1); - } - - /* If the lockspace already exists, we don't get the minor - * number returned. If the device exists we check the minor number. - * If the device doesn't exist then we have to look in /proc/misc - * to find the minor number. - */ - stat_ret = stat(dev_name, &st); - - /* Check if the device exists and has the right modes */ - if (!stat_ret) { - if (S_ISCHR(st.st_mode) && st.st_rdev == makedev(MISC_MAJOR, minor)) - create_dev = 0; - } - else { - if (minor <= 0) - minor = find_minor_from_proc(DLM_PREFIX,name); - } - - if (create_dev && minor > 0) { - - unlink(dev_name); - - /* Now try to create the device, EEXIST is OK cos it must have - been devfs or udev that created it */ - status = mknod(dev_name, S_IFCHR | mode, makedev(MISC_MAJOR, minor)); - if (status == -1 && errno != EEXIST) - { - /* Try to remove it */ - req->cmd = DLM_USER_REMOVE_LOCKSPACE; - req->i.lspace.minor = minor; - dlm_write(control_fd, req, sizeof(*req)); - free(newls); - return NULL; - } -#ifdef HAVE_SELINUX - set_selinux_context(dev_name); -#endif - } - - /* Open it and return the struct as a handle */ - newls->fd = open(dev_name, O_RDWR); - if (newls->fd == -1) - { - int saved_errno = errno; - free(newls); - errno = saved_errno; - return NULL; - } - newls->tid = 0; - fcntl(newls->fd, F_SETFD, 1); - if (mode) - fchmod(newls->fd, mode); - - return (dlm_lshandle_t)newls; -} - - -int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force) -{ - int status; - char dev_name[PATH_MAX]; - struct stat st; - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls; - struct dlm_write_request req; - - /* We need the minor number */ - if (fstat(lsinfo->fd, &st)) - return -1; - - /* Close the lockspace first if it's in use */ - ls_pthread_cleanup(lsinfo); - - if (open_control_device()) - return -1; - - if (force) - req.i.lspace.flags = DLM_USER_LSFLG_FORCEFREE; - else - req.i.lspace.flags = 0; - - set_version(&req); - req.cmd = DLM_USER_REMOVE_LOCKSPACE; - req.i.lspace.minor = minor(st.st_rdev); - - status = dlm_write(control_fd, &req, sizeof(req)); - if (status < 0) - return status; - - /* Remove the device */ - ls_dev_name(name, dev_name, sizeof(dev_name)); - - status = unlink(dev_name); - - /* ENOENT is OK here if devfs has cleaned up */ - if (status == 0 || - (status == -1 && errno == ENOENT)) - return 0; - else - return -1; -} - -/* - * Normal users just open/close lockspaces - */ -dlm_lshandle_t dlm_open_lockspace(const char *name) -{ - char dev_name[PATH_MAX]; - struct dlm_ls_info *newls; - int saved_errno; - - newls = malloc(sizeof(struct dlm_ls_info)); - if (!newls) - return NULL; - - newls->tid = 0; - ls_dev_name(name, dev_name, sizeof(dev_name)); - - newls->fd = open(dev_name, O_RDWR); - saved_errno = errno; - - if (newls->fd == -1) - { - free(newls); - errno = saved_errno; - return NULL; - } - fcntl(newls->fd, F_SETFD, 1); - - return (dlm_lshandle_t)newls; -} - -int dlm_close_lockspace(dlm_lshandle_t ls) -{ - struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls; - - ls_pthread_cleanup(lsinfo); - return 0; -} diff --git a/dlm/lib/libdlm.h b/dlm/lib/libdlm.h deleted file mode 100644 index 8e85ee7..0000000 --- a/dlm/lib/libdlm.h +++ /dev/null @@ -1,297 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with this library; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LIBDLM_H -#define __LIBDLM_H - -typedef void * dlm_lshandle_t; - -/* Typedefs for things that are compatible with the kernel - * but replicated here so that users only need the libdlm include file. - * libdlm itself needs the full kernel file so shouldn't use these. - */ -#ifndef BUILDING_LIBDLM -#define DLM_RESNAME_MAXLEN (64) -#define DLM_LVB_LEN (32) - -struct dlm_lksb { - int sb_status; - uint32_t sb_lkid; - char sb_flags; - char *sb_lvbptr; -}; - -struct dlm_range { - uint64_t ra_start; - uint64_t ra_end; -}; - - -/* - * These defines are the bits that make up the - * query code. - */ - -/* Bits 0, 1, 2, the lock mode or DLM_LOCK_THIS, see DLM_LOCK_NL etc in - * dlm.h Ignored for DLM_QUERY_LOCKS_ALL */ -#define DLM_LOCK_THIS 0x0007 -#define DLM_QUERY_MODE_MASK 0x0007 - -/* Bits 3, 4, 5 bitmap of queue(s) to query */ -#define DLM_QUERY_QUEUE_WAIT 0x0008 -#define DLM_QUERY_QUEUE_CONVERT 0x0010 -#define DLM_QUERY_QUEUE_GRANT 0x0020 -#define DLM_QUERY_QUEUE_GRANTED 0x0030 /* Shorthand */ -#define DLM_QUERY_QUEUE_ALL 0x0038 /* Shorthand */ - -/* Bit 6, Return only the information that can be established without a network - * round-trip. The caller must be aware of the implications of this. Useful for - * just getting the master node id or resource name. */ -#define DLM_QUERY_LOCAL 0x0040 - -/* Bits 8 up, query type */ -#define DLM_QUERY_LOCKS_HIGHER 0x0100 -#define DLM_QUERY_LOCKS_LOWER 0x0200 -#define DLM_QUERY_LOCKS_EQUAL 0x0300 -#define DLM_QUERY_LOCKS_BLOCKING 0x0400 -#define DLM_QUERY_LOCKS_NOTBLOCK 0x0500 -#define DLM_QUERY_LOCKS_ALL 0x0600 -#define DLM_QUERY_LOCKS_ORPHAN 0x0700 -#define DLM_QUERY_MASK 0x0F00 - -/* GRMODE is the default for mode comparisons, - RQMODE might also be handy */ -#define DLM_QUERY_GRMODE 0x0000 -#define DLM_QUERY_RQMODE 0x1000 - -/* Structures passed into and out of the query */ - -struct dlm_lockinfo { - int lki_lkid; /* Lock ID on originating node */ - int lki_mstlkid; /* Lock ID on master node */ - int lki_parent; - int lki_node; /* Originating node (not master) */ - int lki_ownpid; /* Owner pid on originating node */ - uint8_t lki_state; /* Queue the lock is on */ - uint8_t lki_grmode; /* Granted mode */ - uint8_t lki_rqmode; /* Requested mode */ - struct dlm_range lki_grrange; /* Granted range, if applicable */ - struct dlm_range lki_rqrange; /* Requested range, if applicable */ -}; - -struct dlm_resinfo { - int rsi_length; - int rsi_grantcount; /* No. of locks on grant queue */ - int rsi_convcount; /* No. of locks on convert queue */ - int rsi_waitcount; /* No. of locks on wait queue */ - int rsi_masternode; /* Master for this resource */ - char rsi_name[DLM_RESNAME_MAXLEN]; /* Resource name */ - char rsi_valblk[DLM_LVB_LEN]; /* Master's LVB contents, if applicable - */ -}; - -struct dlm_queryinfo { - struct dlm_resinfo *gqi_resinfo; - struct dlm_lockinfo *gqi_lockinfo; /* This points to an array - * of structs */ - int gqi_locksize; /* input */ - int gqi_lockcount; /* output */ -}; - -#endif - -#ifdef _REENTRANT -/* These synchronous functions require pthreads */ -extern int lock_resource(const char *resource, int mode, int flags, int *lockid); -extern int unlock_resource(int lockid); -#endif - -extern int dlm_lock(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - struct dlm_range *range); - -extern int dlm_unlock(uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb, void *astarg); - -extern int dlm_query(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*astaddr) (void *astarg), - void *astarg); - - -#ifdef _REENTRANT -extern int dlm_lock_wait(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - struct dlm_range *range); - - -extern int dlm_unlock_wait(uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb); - -extern int dlm_query_wait(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo); -#endif - -/* These two are for users that want to do their - * own FD handling - */ -extern int dlm_get_fd(); -extern int dlm_dispatch(int fd); - -/* Lockspace manipulation calls - dlm_create_lockspace() also opens the lockspace and returns - a handle to it. privileges are required to create/release - lockspaces. - dlm_open_lockspace() simply returns a handle an already - created lockspace and may be called by ordinary users. - - NOTE: that if you dlm_create_lockspace() then dlm_open_lockspace() - you will have two open files on the same device. Hardly a major problem - but I thought it worth pointing out. -*/ -extern dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode); -extern int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force); -extern dlm_lshandle_t dlm_open_lockspace(const char *name); -extern int dlm_close_lockspace(dlm_lshandle_t ls); -extern int dlm_ls_get_fd(dlm_lshandle_t ls); - -/* Lockspace-specific locking calls */ -extern int dlm_ls_lock(dlm_lshandle_t lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - struct dlm_range *range); - -#ifdef _REENTRANT -extern int dlm_ls_lock_wait(dlm_lshandle_t lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - struct dlm_range *range); - -extern int dlm_ls_unlock_wait(dlm_lshandle_t lockspace, - uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb); - -extern int dlm_ls_query_wait(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo); -#endif - -extern int dlm_ls_unlock(dlm_lshandle_t lockspace, - uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb, void *astarg); - -extern int dlm_ls_query(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*astaddr) (void *astarg), - void *astarg); - - -/* This is for threaded applications. call this - * before any locking operations and the ASTs will - * be delivered in their own thread. - * - * Call the cleanup routine at application exit (optional) - * or, if the locking functions are in a shared library that - * is to be unloaded. - * - * dlm_close/release_lockspace() will tidy the threads for - * a non-default lockspace. - */ -#ifdef _REENTRANT -extern int dlm_pthread_init(); -extern int dlm_ls_pthread_init(dlm_lshandle_t lockspace); -extern int dlm_pthread_cleanup(); -#endif - -/* Lock modes: */ -#define LKM_NLMODE 0 /* null lock */ -#define LKM_CRMODE 1 /* concurrent read */ -#define LKM_CWMODE 2 /* concurrent write */ -#define LKM_PRMODE 3 /* protected read */ -#define LKM_PWMODE 4 /* protected write */ -#define LKM_EXMODE 5 /* exclusive */ - - -/* Locking flags - these match the ones - * in dlm.h - */ -#define LKF_NOQUEUE (0x00000001) -#define LKF_CANCEL (0x00000002) -#define LKF_CONVERT (0x00000004) -#define LKF_VALBLK (0x00000008) -#define LKF_QUECVT (0x00000010) -#define LKF_IVVALBLK (0x00000020) -#define LKF_CONVDEADLK (0x00000040) -#define LKF_PERSISTENT (0x00000080) -#define LKF_NODLCKWT (0x00000100) -#define LKF_NODLCKBLK (0x00000200) -#define LKF_EXPEDITE (0x00000400) -#define LKF_NOQUEUEBAST (0x00000800) -#define LKF_HEADQUE (0x00001000) -#define LKF_NOORDER (0x00002000) - -/* Userspace flag only, for synchronous API calls */ -#ifdef _REENTRANT -#define LKF_WAIT (0x80000000) -#endif -/* - * Extra return codes used by the DLM - */ -#define ECANCEL (0x10001) -#define EUNLOCK (0x10002) -#define EINPROG (0x10003) /* lock operation is in progress */ - -/* lksb flags */ -#define DLM_SBF_VALNOTVALID (0x02) -#endif diff --git a/dlm/make/defines.mk.input b/dlm/make/defines.mk.input deleted file mode 100644 index 19f85ab..0000000 --- a/dlm/make/defines.mk.input +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/dlm/make/flags.mk b/dlm/make/flags.mk deleted file mode 100644 index 7dcb8d8..0000000 --- a/dlm/make/flags.mk +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -# Architecture independant flags... - diff --git a/dlm/make/release.mk.input b/dlm/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/dlm/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/dlm/man/Makefile b/dlm/man/Makefile deleted file mode 100644 index dfcb0e8..0000000 --- a/dlm/man/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl -TARGETS = dlm_cleanup.3 dlm_lock_wait.3 dlm_open_lockspace.3 \ - dlm_close_lockspace.3 dlm_ls_lock.3 dlm_pthread_init.3 \ - dlm_create_lockspace.3 dlm_ls_lock_wait.3 dlm_release_lockspace.3\ - dlm_dispatch.3 dlm_ls_pthread_init.3 dlm_unlock.3 \ - dlm_get_fd.3 dlm_ls_unlock.3 dlm_unlock_wait.3 \ - dlm_lock.3 dlm_ls_unlock_wait.3 libdlm.3 \ - dlm_query.3 dlm_ls_query.3 dlm_query_wait.3 \ - dlm_ls_query_wait.3 - - -include ${top_srcdir}/make/defines.mk - -all: - - -install: - install -d ${mandir}/man3 - install ${TARGETS} ${mandir}/man3 - -uninstall: - ${UNINSTALL} ${TARGETS} ${mandir}/man3 diff --git a/dlm/man/dlm_cleanup.3 b/dlm/man/dlm_cleanup.3 deleted file mode 100644 index db4a9cf..0000000 --- a/dlm/man/dlm_cleanup.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/libdlm.3 diff --git a/dlm/man/dlm_close_lockspace.3 b/dlm/man/dlm_close_lockspace.3 deleted file mode 100644 index e5db408..0000000 --- a/dlm/man/dlm_close_lockspace.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_create_lockspace.3 diff --git a/dlm/man/dlm_create_lockspace.3 b/dlm/man/dlm_create_lockspace.3 deleted file mode 100644 index 1adb4d7..0000000 --- a/dlm/man/dlm_create_lockspace.3 +++ /dev/null @@ -1,81 +0,0 @@ -.TH DLM_CREATE_LOCKSPACE 3 "July 5, 2007" "libdlm functions" -.SH NAME -dlm_create_lockspace, dlm_open_lockspace, dlm_close_lockspace, dlm_releas_lockspace - manipulate DLM lockspaces -.SH SYNOPSIS -.nf - #include <libdlm.h> - -dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode); -dlm_lshandle_t dlm_open_lockspace(const char *name); -int dlm_close_lockspace(dlm_lshandle_t lockspace); -int dlm_release_lockspace(const char *name, dlm_lshandle_t lockspace, int force) - -.fi -.SH DESCRIPTION -The DLM allows locks to be partitioned into "lockspaces", and these can be manipulated by userspace calls. It is possible (though not recommended) for an application to have multiple lockspaces open at one time. - -Many of the DLM calls work on the "default" lockspace, which should be fine for most users. The calls with _ls_ in them allow you to isolate your application from all others running in the cluster. Remember, lockspaces are a cluster-wide resource, so if you create a lockspace called "myls" it will share locks with a lockspace called "myls" on all nodes. These calls allow users to create & remove lockspaces, and users to connect to existing lockspace to store their locks there. -.PP -.SS -dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode); -.br -This creates a lockspace called <name> and the mode of the file user to access it will be <mode> (subject to umask as usual). The lockspace must not already exist on this node, if it does -1 will be returned and errno will be set to EEXIST. If you really want to use this lockspace you can then user dlm_open_lockspace() below. The name is the name of a misc device that will be created in /dev/misc. -.br -On success a handle to the lockspace is returned, which can be used to pass into subsequent dlm_ls_lock/unlock calls. Make no assumptions as to the content of this handle as it's content may change in future. -.br -The caller must have CAP_SYSADMIN privileges to do this operation. -.PP -Return codes: -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following: -.nf -EINVAL An invalid parameter was passed to the call -ENOMEM A (kernel) memory allocation failed -EEXIST The lockspace already exists -EPERM Process does not have capability to create lockspaces -ENOSYS A fatal error occurred initialising the DLM -Any error returned by the open() system call -.fi -.SS -int dlm_release_lockspace(const char *name, dlm_lshandle_t lockspace, int force) -.PP -Deletes a lockspace. If the lockspace still has active locks then -1 will be returned and errno set to EBUSY. Both the lockspace handle /and/ the name must be specified. This call also closes the lockspace and stops the thread associated with the lockspace, if any. -.br -Note that other nodes in the cluster may still have locks open on this lockspace. This call only removes the lockspace from the current node. If the force flag is set then the lockspace will be removed even if another user on this node has active locks in it. Existing users will NOT be notified if you do this, so be careful. -.br -The caller must have CAP_SYSADMIN privileges to do this operation. -.PP -Return codes: -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following: -.nf -EINVAL An invalid parameter was passed to the call -EPERM Process does not have capability to release lockspaces -EBUSY The lockspace could not be freed because it still contains locks - and force was not set. -.fi - -.SS -dlm_lshandle_t dlm_open_lockspace(const char *name) -.PP -Opens an already existing lockspace and returns a handle to it. -.br -Return codes: -.br -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to an error returned by the open() system call -.SS -int dlm_close_lockspace(dlm_lshandle_t lockspace) -.br -Close the lockspace. Any locks held by this process will be freed. If a thread is associated with this lockspace then it will be stopped. -.PP -Return codes: -.br -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following: -.nf -EINVAL lockspace was not a valid lockspace handle -.fi - - -.SH SEE ALSO - -.BR libdlm (3), -.BR dlm_unlock (3), -.BR dlm_lock (3), diff --git a/dlm/man/dlm_dispatch.3 b/dlm/man/dlm_dispatch.3 deleted file mode 100644 index db4a9cf..0000000 --- a/dlm/man/dlm_dispatch.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/libdlm.3 diff --git a/dlm/man/dlm_get_fd.3 b/dlm/man/dlm_get_fd.3 deleted file mode 100644 index db4a9cf..0000000 --- a/dlm/man/dlm_get_fd.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/libdlm.3 diff --git a/dlm/man/dlm_lock.3 b/dlm/man/dlm_lock.3 deleted file mode 100644 index be79596..0000000 --- a/dlm/man/dlm_lock.3 +++ /dev/null @@ -1,205 +0,0 @@ -.TH DLM_LOCK 3 "July 5, 2007" "libdlm functions" -.SH NAME -dlm_lock - acquire or convert a DLM lock -.SH SYNOPSIS -.nf - #include <libdlm.h> - -int dlm_lock(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - struct dlm_range *range); - -int dlm_lock_wait(uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - void *range); - -int dlm_ls_lock(dlm_lshandle_t lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void (*astaddr) (void *astarg), - void *astarg, - void (*bastaddr) (void *astarg), - void *range); - -int dlm_ls_lock_wait(dlm_lshandle_t lockspace, - uint32_t mode, - struct dlm_lksb *lksb, - uint32_t flags, - const void *name, - unsigned int namelen, - uint32_t parent, - void *bastarg, - void (*bastaddr) (void *bastarg), - void *range); - - -.fi -.SH DESCRIPTION -dlm_lock and its variants acquire and convert locks in the DLM. -.PP -dlm_lock() operations are asynchronous. If the call to dlm_lock returns an error then the operation has failed and the AST routine will not be called. If dlm_lock returns 0 it is still possible that the lock operation will fail. The AST routine will be called when the locking is complete or has failed and the status is returned in the lksb. -.B dlm_lock_wait() -will wait until the lock operation has completed and returns the final completion status. -.B dlm_ls_lock() -is the same as -.B dlm_lock() -but takes a lockspace argument. This lockspace must have been previously opened by -.B dlm_lockspace_open() or -.B dlm_lockspace_create(). -.PP -For conversion operations the name and namelen are ignored and the lock ID in the LKSB is used to identify the lock to be converted. -.PP -If a lock value block is specified then in general, a grant or a conversion to an equal-level or higher-level lock mode reads the lock value from the resource into the caller's lock value block. When a lock conversion from EX or PW to an equal-level or lower-level lock mode occurs, the contents of the caller's lock value block are written into the resource. If the LVB is invalidated the lksb.sb_flags member will be set to DLM_SBF_VALNOTVALID. Lock values blocks are always 32 bytes long. -.PP -If the AST routines or parameter are passed to a conversion operation then they will overwrite those values that were passed to a previous dlm_lock call. -.PP -.B mode -Lock mode to acquire or convert to. -.nf - LKM_NLMODE NULL Lock - LKM_CRMODE Concurrent read - LKM_CWMODE Concurrent write - LKM_PRMODE Protected read - LKM_PWMODE Protected write - LKM_EXMODE Exclusive -.fi -.PP -.B flags -Affect the operation of the lock call: -.nf - LKF_NOQUEUE Don't queue the lock. If it cannot be granted return -EAGAIN - LKF_CONVERT Convert an existing lock - LKF_VALBLK Lock has a value block - LKF_QUECVT Put conversion to the back of the queue - LKF_EXPEDITE Grant a NL lock immediately regardless of other locks on the conversion queue - LKF_PERSISTENT Specifies a lock that will not be unlocked when the process exits. - LKF_CONVDEADLK Enable conversion deadlock - LKF_NODLCKWT Do not consider this lock when trying to detect deadlock conditions - LKF_NODLCKBLK Do not consider this lock as blocking other locks when trying to detect deadlock conditions. - LKF_NOQUEUEBAST Send blocking ASTs even for NOQUEUE operations - LKF_HEADQUE Add locks to the head of the convert or waiting queue - LKF_NOORDER Avoid the VMS rules on grant order when using range locks - -.fi -.PP -.B lksb -Lock Status block -.br -This structure contains the returned lock ID, the actual -status of the lock operation (all lock ops are asynchronous) -and the value block if LKF_VALBLK is set. -.PP -.B name -.br -Name of the lock. Can be binary, max 64 bytes. Ignored for lock -conversions. -.PP -.B namelen -.br -Length of the above name. Ignored for lock conversions. -.PP -.B parent -.br -ID of parent lock or NULL if this is a top-level lock -.PP -.B ast -.br -Address of AST routine to be called when the lock operation -completes. The final completion status of the lock will be -in the lksb. the AST routine must not be NULL. -.PP -.B astargs -.br -Argument to pass to the AST routine (most people pass the lksb -in here but it can be anything you like.) -.PP -.B bast -.br -Blocking AST routine. address of a function to call if this -lock is blocking another. The function will be called with -astargs. -.PP -.B range -.br -an optional structure of two uint64_t that indicate the range -of the lock. Locks with overlapping ranges will be granted only -if the lock modes are compatible. locks with non-overlapping -ranges (on the same resource) do not conflict. A lock with no -range is assumed to have a range encompassing the largest -possible range. ie. 0-0xFFFFFFFFFFFFFFFF. Note that is is more -efficient to specify no range than to specify the full range -above. -.PP -.SS Return values -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following: -.PP -.nf -EINVAL An invalid parameter was passed to the call (eg bad lock mode or flag) -ENOMEM A (kernel) memory allocation failed -EAGAIN LKF_NOQUEUE was requested and the lock could not be granted -EBUSY The lock is currently being locked or converted -EFAULT The userland buffer could not be read/written by the kernel (this indicates a library problem) -EDEADLOCK The lock operation is causing a deadlock and has been cancelled. If this was a conversion then the lock is reverted to its previously granted state. If it was a new lock then it has not been granted. (NB Only conversion deadlocks are currently detected) -.PP -If an error is returned in the AST, then lksb.sb_status is set to the one of the above values instead of zero. -.SS Structures -.nf -struct dlm_lksb { - int sb_status; /* Final status of lock operation */ - uint32_t sb_lkid; /* ID of lock. Returned from dlm_lock() - on first use. Used as input to - dlm_lock() for a conversion operation */ - char sb_flags; /* Completion flags, see above */ - char sb_lvbptr; /* Optional pointer to lock value block */ -}; - -struct dlm_range { - uint64_t ra_start; - uint64_t ra_end; -}; -.fi -.SH EXAMPLE -.nf -int status; -struct dlm_lksb lksb; - -status = dlm_lock_wait(LKM_EXMODE, - &lksb, - LKF_NOQUEUE, - "MyLock", - strlen("MyLock"), - 0, // Parent, - NULL, // bast arg - NULL, // bast routine, - NULL); // Range - -if (status == 0) - dlm_unlock_wait(lksb.sb_lkid, 0, &lksb); - -.fi - -.SH SEE ALSO - -.BR libdlm (3), -.BR dlm_unlock (3), -.BR dlm_open_lockspace (3), -.BR dlm_create_lockspace (3), -.BR dlm_close_lockspace (3), -.BR dlm_release_lockspace (3) diff --git a/dlm/man/dlm_lock_wait.3 b/dlm/man/dlm_lock_wait.3 deleted file mode 100644 index a99225c..0000000 --- a/dlm/man/dlm_lock_wait.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_lock.3 diff --git a/dlm/man/dlm_ls_lock.3 b/dlm/man/dlm_ls_lock.3 deleted file mode 100644 index a99225c..0000000 --- a/dlm/man/dlm_ls_lock.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_lock.3 diff --git a/dlm/man/dlm_ls_lock_wait.3 b/dlm/man/dlm_ls_lock_wait.3 deleted file mode 100644 index a99225c..0000000 --- a/dlm/man/dlm_ls_lock_wait.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_lock.3 diff --git a/dlm/man/dlm_ls_pthread_init.3 b/dlm/man/dlm_ls_pthread_init.3 deleted file mode 100644 index db4a9cf..0000000 --- a/dlm/man/dlm_ls_pthread_init.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/libdlm.3 diff --git a/dlm/man/dlm_ls_query.3 b/dlm/man/dlm_ls_query.3 deleted file mode 100644 index 33c3f3a..0000000 --- a/dlm/man/dlm_ls_query.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_query.3 diff --git a/dlm/man/dlm_ls_query_wait.3 b/dlm/man/dlm_ls_query_wait.3 deleted file mode 100644 index 33c3f3a..0000000 --- a/dlm/man/dlm_ls_query_wait.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_query.3 diff --git a/dlm/man/dlm_ls_unlock.3 b/dlm/man/dlm_ls_unlock.3 deleted file mode 100644 index 91babd2..0000000 --- a/dlm/man/dlm_ls_unlock.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_unlock.3 diff --git a/dlm/man/dlm_ls_unlock_wait.3 b/dlm/man/dlm_ls_unlock_wait.3 deleted file mode 100644 index 91babd2..0000000 --- a/dlm/man/dlm_ls_unlock_wait.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_unlock.3 diff --git a/dlm/man/dlm_open_lockspace.3 b/dlm/man/dlm_open_lockspace.3 deleted file mode 100644 index e5db408..0000000 --- a/dlm/man/dlm_open_lockspace.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_create_lockspace.3 diff --git a/dlm/man/dlm_pthread_init.3 b/dlm/man/dlm_pthread_init.3 deleted file mode 100644 index db4a9cf..0000000 --- a/dlm/man/dlm_pthread_init.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/libdlm.3 diff --git a/dlm/man/dlm_query.3 b/dlm/man/dlm_query.3 deleted file mode 100644 index 11601e8..0000000 --- a/dlm/man/dlm_query.3 +++ /dev/null @@ -1,196 +0,0 @@ -.TH DLM_QUERY 3 "July 5, 2007" "libdlm functions" -.SH NAME -dlm_query - query DLM for locks on a resource -.SH SYNOPSIS -.nf - #include <libdlm.h> - -int dlm_query(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*ast_routine(void *astarg)), - void *astarg) - - -int dlm_query_wait(struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo) - -int dlm_ls_query(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo, - void (*ast_routine(void *astarg)), - void *astarg) - -int dlm_ls_query_wait(dlm_lshandle_t lockspace, - struct dlm_lksb *lksb, - int query, - struct dlm_queryinfo *qinfo) - -.fi -.br -.SS DESCRIPTION -The dlm query API is a method of getting information about other locks that are held (or pending) on a resource that you already hold a lock for.If you don't have a lock on a known resource then a getting a NL lock on it will allow you to query it without affecting ether locking operations (much). -.br -It is not a method of getting a list of resources in a lockspace, use dlm_tool or similar for that purpose. -.br -Once you have a lock ID, you can use these calls to find out (eg) which locks are waiting to be granted, or which locks are blocking your lock, including which cluster node and PID of the process (if relevant). You can also get general information about the lock such as the resource name (if you've forgotten it!), LVB state and value and the node where it is mastered. -.br -The main structure passed into dlm_query() is the dlm_queryinfo struct (see below). The main constituents of this are two pointers, one to a gdlm_resinfo structure which will be filled in with information about the resource, and an array of gdlm_lockinfo structures which contains information about all the locks that match the requested criteria; or, at least, as many as will fit int the allocated space. -.PP -.B dlm_query() -is asynchronous, the ultimate status and data will be returned into the dlm_query_info structure which should be checked when the ast_routine is called. The lksb must contain a valid lock ID in sb_lkid which is used to identify the resource to be queried, status will be returned in sb_status; As with the locking calls an AST routine will be called when the query completes if the call itself returns 0. See below for full details of the query call. -.PP -.B dlm_query_wait() -is the same as dlm_query() except that it waits for the operation to complete. When the operation is complete the status will be in the lksb. Both the return value from the function call and the condition code in the lksb must be evaluated. -.PP -If the provided lock list is too short to hold all the locks, then sb_status in the lksb will contain E2BIG but the list will be filled in as far as possible. Either gqi_lockinfo or gqi_resinfo may be specified as NULL if that information is not required. -.PP -.B dlm_ls_query() -and -.B dlm_ls_query_wait() -are the same as above, but also take a lockspace argument. -.PP -Structures passed into and out of the query: -.nf -struct gdlm_lockinfo -{ - int lki_lkid; /* Lock ID on originating node */ - int lki_parent; - int lki_node; /* Originating node (not master) */ - int lki_ownpid; /* Owner pid on the originating node */ - uint8 lki_state; /* Queue the lock is on */ - int8 lki_grmode /* Granted mode */ - int8 lki_rqmode; /* Requested mode */ - struct dlm_range lki_grrange /* Granted range, if applicable */ - struct dlm_range lki_rqrange /* Requested range, if applicable */ -}; - -struct gdlm_resinfo -{ - int rsi_length; - int rsi_grantcount; /* No. of locks on grant queue */ - int rsi_convcount; /* No. of locks on convert queue */ - int rsi_waitcount; /* No. of locks on wait queue */ - int rsi_masternode; /* Master node for this resource */ - char rsi_name[DLM_RESNAME_MAXLEN]; /* Resource name */ - char rsi_valblk[DLM_LVB_LEN]; /* Master's LVB contents, if applicable */ -}; - -struct dlm_queryinfo -{ - struct dlm_resinfo *gqi_resinfo; /* Points to a single resinfo struct */ - struct dlm_lockinfo *gqi_lockinfo;/* This points to an array of structs */ - int gqi_locksize; /* input */ - int gqi_lockcount; /* output */ -}; -.fi -PP -The query is made up of several blocks of bits as follows: -.nf - 9 8 6 5 3 0 -+----------------+---+-------+---+-------+-----------+ -| reserved | Q | query | L | queue | lock mode | -+----------------+---+-------+---+-------+-----------+ -.fi -.PP -lock mode is a normal DLM lock mode or DLM_LOCK_THIS to use the mode of the lock in sb_lkid. -.PP -queue is a bitmap of -.br DLM_QUERY_QUEUE_WAIT -.br DLM_QUERY_QUEUE_CONVERT -.br DLM_QUERY_QUEUE_GRANT -.PP -or one of the two shorthands: -.br DLM_QUERY_QUEUE_GRANTED (for WAIT+GRANT) -.br DLM_QUERY_QUEUE_ALL (for all queues) -.PP -L is an optional flag DLM_QUERY_LOCAL which specifies that a remote access should not happen. Only lock information that can be gleaned from the local node will be returned so be aware that it may not be complete. It's useful for getting the master node ID or the resource name perhaps. -.PP -The query is one of the following: -.br DLM_QUERY_LOCKS_HIGHER -.br DLM_QUERY_LOCKS_LOWER -.br DLM_QUERY_LOCKS_EQUAL -.br DLM_QUERY_LOCKS_BLOCKING -.br DLM_QUERY_LOCKS_NOTBLOCK -.br DLM_QUERY_LOCKS_ALL -.PP -which specifies which locks to look for by mode, either the lockmode is lower, equal or higher to the mode at the bottom of the query. DLM_QUERY_ALL will return all locks on the resource. -.PP -DLM_QUERY_LOCKS_BLOCKING returns only locks that are blocking the current lock. The lock must not be waiting for grant or conversion for this to be a valid query, the other flags are ignored. -.PP -DLM_QUERY_LOCKS_NOTBLOCKING returns only locks that are granted but NOT blocking the current lock. -.PP -Q specifies which lock queue to compare. By default the granted queue is used. If the flags DLM_QUERY_RQMODE is set then the requested mode will be used instead. -.PP -The "usual" way to call dlm_query is to put the address of the dlm_queryinfo struct into lksb.sb_lvbptr and pass the lksb as the AST param, that way all the information is available to you in the AST routine. -.PP -.SS Return codes: -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following: -.nf -EINVAL An invalid parameter was passed to the call (eg bad lock mode or flag) -ENOMEM A (kernel) memory allocation failed -ENOBUFS A (kernel) comms buffer allocation failed -E2BIG The ggi_lockinfo array is too small to hold all the results. -EFAULT The userland buffer could not be read/written by the kernel -.fi -If an error is returned in the AST, then lksb.sb_status is set to the one of the above numbers instead of zero. - -.SH EXAMPLE -.nf -This example display all other locks that are held against the resource, up to a maximum of 100. - - #define MAX_QUERY_LOCKS 100 - - int status; - struct dlm_lksb tmplksb; - struct dlm_queryinfo qinfo; - struct dlm_resinfo resinfo; - - lksb.sb_lkid = <lockid>; - qinfo.gqi_resinfo = &resinfo; - qinfo.gqi_lockinfo = malloc(sizeof(struct dlm_lockinfo) * MAX_QUERY_LOCKS); - qinfo.gqi_locksize = MAX_QUERY_LOCKS; - - status = dlm_query_wait(&tmplksb, - DLM_QUERY_QUEUE_ALL | DLM_QUERY_LOCKS_ALL, - &qinfo); - if (status) - perror("Query failed"); - - /* Dump resource info */ - printf("lockinfo: status = %d\n", lksb->sb_status); - printf("lockinfo: resource = '%s'\n", qi->gqi_resinfo->rsi_name); - printf("lockinfo: grantcount = %d\n", qi->gqi_resinfo->rsi_grantcount); - printf("lockinfo: convcount = %d\n", qi->gqi_resinfo->rsi_convcount); - printf("lockinfo: waitcount = %d\n", qi->gqi_resinfo->rsi_waitcount); - printf("lockinfo: masternode = %d\n", qi->gqi_resinfo->rsi_masternode); - printf("\n"); - - /* Dump all the locks */ - for (i = 0; i < qi->gqi_lockcount; i++) - { - struct dlm_lockinfo *li = &qi->gqi_lockinfo[i]; - - printf("lockinfo: lock: lkid = %x\n", li->lki_lkid); - printf("lockinfo: lock: master lkid = %x\n", li->lki_mstlkid); - printf("lockinfo: lock: parent lkid = %x\n", li->lki_parent); - printf("lockinfo: lock: node = %d\n", li->lki_node); - printf("lockinfo: lock: pid = %d\n", li->lki_ownpid); - printf("lockinfo: lock: state = %d\n", li->lki_state); - printf("lockinfo: lock: grmode = %d\n", li->lki_grmode); - printf("lockinfo: lock: rqmode = %d\n", li->lki_rqmode); - printf("\n"); - } -.nf - - -.SH SEE ALSO - -.BR libdlm (3), -.BR dlm_unlock (3), -.BR dlm_open_lockspace (3), -.BR dlm_create_lockspace (3), -.BR dlm_close_lockspace (3), -.BR dlm_release_lockspace (3) diff --git a/dlm/man/dlm_query_wait.3 b/dlm/man/dlm_query_wait.3 deleted file mode 100644 index 33c3f3a..0000000 --- a/dlm/man/dlm_query_wait.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_query.3 diff --git a/dlm/man/dlm_release_lockspace.3 b/dlm/man/dlm_release_lockspace.3 deleted file mode 100644 index e5db408..0000000 --- a/dlm/man/dlm_release_lockspace.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_create_lockspace.3 diff --git a/dlm/man/dlm_unlock.3 b/dlm/man/dlm_unlock.3 deleted file mode 100644 index 184c1ef..0000000 --- a/dlm/man/dlm_unlock.3 +++ /dev/null @@ -1,89 +0,0 @@ -.TH DLM_UNLOCK 3 "July 5, 2007" "libdlm functions" -.SH NAME -dlm_unlock - unlock a DLM lock -.SH SYNOPSIS -.nf -#include <libdlm.h> - -int dlm_unlock(uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb, void *astarg); - -int dlm_unlock_wait(uint32_t lkid, - uint32_t flags, struct dlm_lksb *lksb); - -.fi -.SH DESCRIPTION -.B dlm_unlock() -unlocks a lock previously acquired by dlm_lock and its variants. -.PP -Unless -.B dlm_unlock_wait() -is used unlocks are also asynchronous. The AST routine is called when the resource is successfully unlocked (see below). -.PP -.B lkid -Lock ID as returned in the lksb -.PP -.B flags -flags affecting the unlock operation: -.nf - LKF_CANCEL Cancel a pending lock or conversion. - This returns the lock to it's - previously granted mode (in case of a - conversion) or unlocks it (in case of a waiting lock). - LKF_IVVALBLK Invalidate value block -.fi -.PP -.B lksb -LKSB to return status and value block information. -.PP -.B astarg -New parameter to be passed to the completion AST. -The completion AST routine is the -last completion AST routine specified in a dlm_lock call. -If dlm_lock_wait() was the last routine to issue a lock, -dlm_unlock_wait() must be used to release the lock. If dlm_lock() -was the last routine to issue a lock then either dlm_unlock() -or dlm_unlock_wait() may be called. -.PP - -.SS Return values -0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following: -.PP -.nf -EINVAL An invalid parameter was passed to the call (eg bad lock mode or flag) -EINPROGRESS The lock is already being unlocked -EBUSY The lock is currently being locked or converted -ENOTEMPTY An attempt to made to unlock a parent lock that still has child locks. -ECANCEL A lock conversion was successfully cancelled -EUNLOCK An unlock operation completed successfully (sb_status only) -EFAULT The userland buffer could not be read/written by the kernel -.fi -If an error is returned in the AST, then lksb.sb_status is set to the one of the above numbers instead of zero. -.SH EXAMPLE -.nf -int status; -struct dlm_lksb lksb; - -status = dlm_lock_wait(LKM_EXMODE, - &lksb, - LKF_NOQUEUE, - "MyLock", - strlen("MyLock"), - 0, // Parent, - NULL, // bast arg - NULL, // bast routine, - NULL); // Range - -if (status == 0) - dlm_unlock_wait(lksb.sb_lkid, 0, &lksb); - -.fi - -.SH SEE ALSO - -.BR libdlm (3), -.BR dlm_lock (3), -.BR dlm_open_lockspace (3), -.BR dlm_create_lockspace (3), -.BR dlm_close_lockspace (3), -.BR dlm_release_lockspace (3) diff --git a/dlm/man/dlm_unlock_wait.3 b/dlm/man/dlm_unlock_wait.3 deleted file mode 100644 index 91babd2..0000000 --- a/dlm/man/dlm_unlock_wait.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/dlm_unlock.3 diff --git a/dlm/man/libdlm.3 b/dlm/man/libdlm.3 deleted file mode 100644 index 496748c..0000000 --- a/dlm/man/libdlm.3 +++ /dev/null @@ -1,101 +0,0 @@ -.TH LIBDLM 3 "July 5, 2007" "libdlm functions" -.SH NAME -libdlm, dlm_get_fd, dlm_dispatch, dlm_pthread_init, dlm_ls_pthread_init, dlm_cleanup -.SH SYNOPSIS -.nf -#include <libdlm.h> -.nf -int dlm_pthread_init(); -int dlm_ls_pthread_init(dlm_lshandle_t lockspace); -int dlm_pthread_cleanup(); -int dlm_get_fd(void); -int dlm_dispatch(int fd); - -link with -ldlm -.fi -.SH DESCRIPTION -libdlm provides the programmatic userspace interface to the Distributed Lock manager. It provides all the calls you need to maniupulate locks & lockspaces -.br -libdlm can be used in pthread or non-pthread applications. For pthread applications simply call the following function before doing any lock operations. If you're using pthreads, remember to define _REENTRANT at the top of the program or using -D_REENTRANT on the compile line. -.br -pthreads is the normal way of using the DLM. This way you simply initialise the DLM's thread and all the AST routines will be delivered in that thread. You just call the dlm_lock() etc routines in the main line of your program. -.br -If you don't want to use pthreads or you want to handle the dlm callback ASTs yourself then you can get an FD handle to the DLM device and call -.B dlm_dispatch() on it whenever it becomes active. That was ASTs will be delivered in the context of the thread/process that called -.B dlm_dispatch(). - - -.SS int dlm_pthread_init() -.br -Creates a thread to receive all lock ASTs. The AST callback function for lock operations will be called in the context of this thread. If there is a potential for local resource access conflicts you must provide your own pthread-based locking in the AST routine. -.PP -.SS int dlm_ls_pthread_init(dlm_lshandle_t lockspace) -.br -As dlm_pthread_init but initialises a thread for the specified lockspace. -.PP -.SS int dlm_pthread_cleanup() -.br -Cleans up the default lockspace threads after use. Normally you don't need to call this, but if the locking code is in a dynamically loadable shared library this will probably be necessary. -.br -For non-pthread based applications the DLM provides a file descriptor that the program can feed into poll/select. If activity is detected on that FD then a dispatch function should be called: -.PP -.SS int dlm_get_fd() -Returns a file-descriptor for the DLM suitable for passing in to poll() or select(). -.PP -.SS int dlm_dispatch(int fd) -.br -Reads from the DLM and calls any AST routines that may be needed. This routine runs in the context of the caller so no extra locking is needed to protect local resources. -.PP - - -.SH EXAMPLES - -Create a lockspace and start a thread to deliver its callbacks: -.nf -dlm_lshandle_t ls; - -ls = dlm_create_lockspace("myLS", 0660); -dlm_ls_pthread_init(ls); - -... - -status = dlm_ls_lock(ls, - ... ); - - -.fi -.PP - Using poll(2) to wait for and dispatch ASTs -.nf - - -static int poll_for_ast(dlm_lshandle_t ls) -{ - struct pollfd pfd; - - pfd.fd = dlm_ls_get_fd(ls); - pfd.events = POLLIN; - while (!ast_called) - { - if (poll(&pfd, 1, 0) < 0) - { - perror("poll"); - return -1; - } - dlm_dispatch(dlm_ls_get_fd(ls)); - } - ast_called = 0; - return 0; -} -.fi - - -.SH SEE ALSO - -.BR libdlm (3), -.BR dlm_lock (3), -.BR dlm_unlock (3), -.BR dlm_open_lockspace (3), -.BR dlm_create_lockspace (3), -.BR dlm_close_lockspace (3), -.BR dlm_release_lockspace (3) diff --git a/dlm/scripts/51-dlm.rules b/dlm/scripts/51-dlm.rules deleted file mode 100644 index 8126655..0000000 --- a/dlm/scripts/51-dlm.rules +++ /dev/null @@ -1,3 +0,0 @@ -KERNEL="dlm-control", NAME="misc/dlm-control" MODE="0666" -KERNEL="dlm_default", NAME="misc/dlm_default" MODE="0666" -KERNEL="*dlm_*", NAME="misc/%k" MODE="0660" diff --git a/dlm/scripts/uninstall.pl b/dlm/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/dlm/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/dlm/tests/locktest/lockrange.c b/dlm/tests/locktest/lockrange.c deleted file mode 100644 index d503bad..0000000 --- a/dlm/tests/locktest/lockrange.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Test the locking interface */ - -/* Creates a file called /proc/gtest that you can echo the following commands into: - - lock <name> <mode> [<parent-id>] [<range start>] [<range end>] - unlock <id> [force] - convert <id> <mode> [<range start>] [<range end>] - - Lock IDs must be in hex. - - cat /proc/gtest will show the locks known to this module - -*/ - - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/string.h> -#include <linux/sockios.h> -#include <linux/net.h> -#include <linux/netdevice.h> -#include <linux/capability.h> -#include <linux/inet.h> -#include <linux/file.h> -#include <linux/route.h> -#include <linux/interrupt.h> -#include <net/sock.h> -#include <net/scm.h> -#include <asm/segment.h> -#include <asm/system.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/proc_fs.h> -#include <linux/stat.h> -#include <linux/init.h> -#include <linux/poll.h> -#include <net/dst.h> - -#include "osi.h" -#include "osi_list.h" -#include "gdlm.h" - - -#define atoi(x) simple_strtoul(x, NULL, 16) - -struct my_lock -{ - osi_list_t list; - char name[GDLM_RESNAME_MAXLEN]; - int rqmode; - int grmode; - int parent; - int bastmode; - gdlm_lksb_t lksb; - gdlm_range_t range; -}; -static osi_list_t our_locks; - -/* A "spare" lksb for unlocking other peoples locks with */ -static gdlm_lksb_t spare_lksb; - -static gdlm_lockspace_t *lockspace; -char *ls = "gtest"; /* Lockspace name */ -char *procname = "gtest"; /* proc file name */ - -static void compast_routine(void *arg); -static void blockast_routine(void *arg, int mode); - -struct proc_dir_entry *gdlm_proc_entry = NULL; - -static int modetonum(char *modestr) -{ - int mode = GDLM_LOCK_EX; - - if (strnicmp(modestr, "NL", 2) == 0) mode = GDLM_LOCK_NL; - if (strnicmp(modestr, "CR", 2) == 0) mode = GDLM_LOCK_CR; - if (strnicmp(modestr, "CW", 2) == 0) mode = GDLM_LOCK_CW; - if (strnicmp(modestr, "PR", 2) == 0) mode = GDLM_LOCK_PR; - if (strnicmp(modestr, "PW", 2) == 0) mode = GDLM_LOCK_PW; - if (strnicmp(modestr, "EX", 2) == 0) mode = GDLM_LOCK_EX; - - return mode; -} - -static char *numtomode(int mode) -{ - switch (mode) - { - case GDLM_LOCK_NL: return "NL"; - case GDLM_LOCK_CR: return "CR"; - case GDLM_LOCK_CW: return "CW"; - case GDLM_LOCK_PR: return "PR"; - case GDLM_LOCK_PW: return "PW"; - case GDLM_LOCK_EX: return "EX"; - default: return "??"; - } -} - -static struct my_lock *find_mylock(int id) -{ - osi_list_t *l; - osi_list_foreach(l, &our_locks) { - struct my_lock *mlk = osi_list_entry(l, struct my_lock, list); - if (mlk->lksb.sb_lkid == id) - return mlk; - } - return NULL; -} - -static int show_locks(char *buf, int maxlen) -{ - osi_list_t *l; - int len = 0; - - len += sprintf(buf+len, " lkid parent rq gr name\n"); - osi_list_foreach(l, &our_locks) { - struct my_lock *mlk = osi_list_entry(l, struct my_lock, list); - - len += sprintf(buf+len, "%8x %8x %s %s %-32s %llx-%llx\n", - mlk->lksb.sb_lkid, - mlk->parent, - numtomode(mlk->rqmode), - numtomode(mlk->grmode), - mlk->name, - mlk->range.ra_start, mlk->range.ra_end); - } - return len; -} - -static void compast_routine(void *arg) -{ - struct my_lock *lki = (struct my_lock *)arg; - - printk("locktest: Completion AST for %x, status = %d\n", lki->lksb.sb_lkid, lki->lksb.sb_status); - /* Lock or convert suceeded */ - if (lki->lksb.sb_status == 0) { - lki->grmode = lki->rqmode; - } - - /* Convert failed */ - if (lki->lksb.sb_status != 0 && lki->grmode != -1) { - lki->rqmode = lki->grmode; - } - - /* Lock failed - remove it */ - if (lki->lksb.sb_status != 0 && lki->grmode == -1) { - osi_list_del(&lki->list); - osi_free(lki->lksb.sb_lvbptr, GDLM_LVB_LEN); - osi_free(lki, sizeof(struct my_lock)); - MOD_DEC_USE_COUNT; - - } - - /* Unlock suceeded */ - if (lki->lksb.sb_status == -GDLM_EUNLOCK) { - osi_list_del(&lki->list); - osi_free(lki->lksb.sb_lvbptr, GDLM_LVB_LEN); - osi_free(lki, sizeof(struct my_lock)); - MOD_DEC_USE_COUNT; - } - -} - -static void blockast_routine(void *arg, int mode) -{ - struct my_lock *lki = (struct my_lock *)arg; - int status; - - printk("locktest: Blocking AST for %x\n", lki->lksb.sb_lkid); - if (lki->bastmode != -1) { - /* convert lock to bastmode */ - lki->rqmode = lki->bastmode; - - status = gdlm_lock(lockspace, - lki->bastmode, - &lki->lksb, - GDLM_LKF_CONVERT, - NULL, - 0, - 0, - compast_routine, - lki, - blockast_routine, NULL); - if (status == 0) { - lki->rqmode = lki->bastmode; - lki->bastmode = -1; - } - } -} - - -static int lock_command(char *cmd) -{ - char *str; - int i = 1; - struct my_lock *newlock; - int status; - - newlock = osi_malloc(sizeof(struct my_lock)); - if (!newlock) - return -ENOMEM; - - memset(newlock, 0, sizeof(*newlock)); - - newlock->lksb.sb_lvbptr = osi_malloc(GDLM_LVB_LEN); - if (!newlock->lksb.sb_lvbptr) - { - osi_free(newlock, sizeof(struct my_lock)); - return -ENOMEM; - } - memset(newlock->lksb.sb_lvbptr, 0, GDLM_LVB_LEN); - - newlock->bastmode = -1; - newlock->grmode = -1; - - str = strtok(cmd, " "); - while (str) { - switch (i) { - case 1: - strcpy(newlock->name, str); - break; - - case 2: - newlock->rqmode = modetonum(str); - break; - - case 3: - newlock->parent = atoi(str); - break; - - case 4: - newlock->range.ra_start = atoi(str); - newlock->range.ra_end = 0xffffffffffffffffULL; - break; - - case 5: - newlock->range.ra_end = atoi(str); - break; - } - i++; - str = strtok(NULL, " "); - } - - status = gdlm_lock(lockspace, - newlock->rqmode, - &newlock->lksb, - 0, - newlock->name, - strlen(newlock->name)+1, - newlock->parent, - compast_routine, - newlock, - blockast_routine, - (i>4)?&newlock->range:NULL); - - if (status < 0) { - osi_free(newlock->lksb.sb_lvbptr, GDLM_LVB_LEN); - osi_free(newlock, sizeof(struct my_lock)); - } - else { - MOD_INC_USE_COUNT; - osi_list_add(&newlock->list, &our_locks); - } - - return status; -} - - -static int unlock_command(char *cmd) -{ - struct my_lock *lockstruct=NULL; - char *str; - int i=1; - int status; - int lkid = 0; - int force = 0; - - str = strtok(cmd, " "); - while (str) { - switch (i) { - case 1: - lkid = atoi(str); - lockstruct = find_mylock(lkid); - break; - - case 2: - if (strcmp(str, "force") == 0) - force = 1; - break; - } - i++; - str = strtok(NULL, " "); - } - - /* Must have "force" if it's not our lock */ - if (!lockstruct && !force) return -EINVAL; - - if (!lockstruct) - { - /* Force out a lock */ - status = gdlm_unlock(lockspace, - lkid, - 0, - &spare_lksb, - NULL); - } - else - { - status = gdlm_unlock(lockspace, - lockstruct->lksb.sb_lkid, - i>1? GDLM_LKF_VALBLK: 0, - &lockstruct->lksb, - NULL); - } - return status; -} - -static int convert_command(char *cmd) -{ - struct my_lock *lockstruct = NULL; - char *str; - int i=1; - int status; - int flags; - - str = strtok(cmd, " "); - while (str) { - switch (i) { - case 1: - lockstruct = find_mylock(atoi(str)); - if (!lockstruct) return -EINVAL; - break; - - case 2: - lockstruct->rqmode = modetonum(str); - break; - - case 3: - lockstruct->range.ra_start = atoi(str); - lockstruct->range.ra_end = 0xffffffffffffffffULL; - break; - - case 4: - lockstruct->range.ra_end = atoi(str); - break; - } - i++; - str = strtok(NULL, " "); - } - if (lockstruct->rqmode > lockstruct->grmode) flags = GDLM_LKF_QUECVT; - status = gdlm_lock(lockspace, - lockstruct->rqmode, - &lockstruct->lksb, - GDLM_LKF_CONVERT, - NULL, - 0, - 0, - compast_routine, - lockstruct, - blockast_routine, - (i>3)?&lockstruct->range:NULL); - - return status; -} - -static int gdlm_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - return show_locks(page, count); -} - -static int gdlm_proc_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int error = -EINVAL, n = count; - char proc_buf[132]; - - MOD_INC_USE_COUNT; - - error = -EFAULT; - memset(proc_buf, 0, sizeof(proc_buf)); - - if (count > sizeof(proc_buf)) - goto fail; - - error = osi_copy_from_user(proc_buf, buffer, n); - if (error) - goto fail; - - /* Remove trailing NL */ - if (proc_buf[n-1] == '\n') - proc_buf[n-1] = '\0'; - error = -EINVAL; - if (strncmp(proc_buf, "lock ", 5) == 0) - error = lock_command(proc_buf+5); - - if (strncmp(proc_buf, "unlock ", 7) == 0) - error = unlock_command(proc_buf+7); - - if (strncmp(proc_buf, "convert ", 8) == 0) - error = convert_command(proc_buf+8); - - if (error < 0) - goto fail; - - MOD_DEC_USE_COUNT; - return count; - - fail: - printk("LOCKTEST: '%s' failed : %d\n", proc_buf, error); - MOD_DEC_USE_COUNT; - return error; -} - - - -static int __init test_init(void) -{ - int ls_status; - - osi_list_init(&our_locks); - - gdlm_proc_entry = create_proc_read_entry(procname, S_IFREG | 0666, NULL, - NULL, NULL); - gdlm_proc_entry->write_proc = gdlm_proc_write; - gdlm_proc_entry->read_proc = gdlm_proc_read; - - ls_status = gdlm_new_lockspace(ls, strlen(ls), &lockspace, 0); - if (ls_status < 0 && ls_status != -EEXIST) { - remove_proc_entry(procname, NULL); - return -1; - } - return 0; -} - -static void __exit test_exit(void) -{ - remove_proc_entry(procname, NULL); - gdlm_release_lockspace(lockspace); -} - -module_init(test_init); -module_exit(test_exit); - -MODULE_PARM(ls, "s"); -MODULE_PARM(procname, "s"); diff --git a/dlm/tests/locktest/locktest.c b/dlm/tests/locktest/locktest.c deleted file mode 100644 index a99fe45..0000000 --- a/dlm/tests/locktest/locktest.c +++ /dev/null @@ -1,536 +0,0 @@ -/* Test the locking interface */ - -/* Creates a file called /proc/gtest that you can echo the following commands into: - - lock <name> <mode> [<parent-id>] [<value>] [<bastmode>] - unlock <id> [<value>] [force] - convert <id> <mode> [<value>] - - Lock IDs must be in hex. - - cat /proc/gtest will show the locks known to this module - -*/ - - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/string.h> -#include <linux/sockios.h> -#include <linux/net.h> -#include <linux/netdevice.h> -#include <linux/capability.h> -#include <linux/inet.h> -#include <linux/file.h> -#include <linux/route.h> -#include <linux/interrupt.h> -#include <net/sock.h> -#include <net/scm.h> -#include <asm/segment.h> -#include <asm/system.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/proc_fs.h> -#include <linux/stat.h> -#include <linux/init.h> -#include <linux/poll.h> -#include <net/dst.h> - -#include <cluster/dlm.h> - - -#define atoi(x) simple_strtoul(x, NULL, 16) - -struct my_lock -{ - struct list_head list; - char name[DLM_RESNAME_MAXLEN]; - int rqmode; - int grmode; - int parent; - int bastmode; - struct dlm_lksb lksb; -}; -static struct list_head our_locks; - -/* A "spare" lksb for unlocking other peoples locks with */ -static struct dlm_lksb spare_lksb; - -static dlm_lockspace_t *lockspace; -char *ls = "gtest"; /* Lockspace name */ -char *procname = "gtest"; /* proc file name */ - -static void compast_routine(void *arg); -static void blockast_routine(void *arg, int mode); - -struct proc_dir_entry *dlm_proc_entry = NULL; - -static int modetonum(char *modestr) -{ - int mode = DLM_LOCK_EX; - - if (strnicmp(modestr, "NL", 2) == 0) mode = DLM_LOCK_NL; - if (strnicmp(modestr, "CR", 2) == 0) mode = DLM_LOCK_CR; - if (strnicmp(modestr, "CW", 2) == 0) mode = DLM_LOCK_CW; - if (strnicmp(modestr, "PR", 2) == 0) mode = DLM_LOCK_PR; - if (strnicmp(modestr, "PW", 2) == 0) mode = DLM_LOCK_PW; - if (strnicmp(modestr, "EX", 2) == 0) mode = DLM_LOCK_EX; - - return mode; -} - -static char *numtomode(int mode) -{ - switch (mode) - { - case DLM_LOCK_NL: return "NL"; - case DLM_LOCK_CR: return "CR"; - case DLM_LOCK_CW: return "CW"; - case DLM_LOCK_PR: return "PR"; - case DLM_LOCK_PW: return "PW"; - case DLM_LOCK_EX: return "EX"; - default: return "??"; - } -} - -static struct my_lock *find_mylock(int id) -{ - struct list_head *l; - list_for_each(l, &our_locks) { - struct my_lock *mlk = list_entry(l, struct my_lock, list); - if (mlk->lksb.sb_lkid == id) - return mlk; - } - return NULL; -} - -static int show_locks(char *buf, int maxlen) -{ - struct list_head *l; - int len = 0; - - len += sprintf(buf+len, " lkid parent rq gr name lvb\n"); - list_for_each(l, &our_locks) { - struct my_lock *mlk = list_entry(l, struct my_lock, list); - - len += sprintf(buf+len, "%8x %8x %s %s %-32s %s\n", - mlk->lksb.sb_lkid, - mlk->parent, - numtomode(mlk->rqmode), - numtomode(mlk->grmode), - mlk->name, - mlk->lksb.sb_lvbptr); - } - return len; -} - -static void compast_routine(void *arg) -{ - struct my_lock *lki = (struct my_lock *)arg; - - printk("locktest: Completion AST for %x, status = %d\n", lki->lksb.sb_lkid, lki->lksb.sb_status); - /* Lock or convert suceeded */ - if (lki->lksb.sb_status == 0) { - lki->grmode = lki->rqmode; - } - - /* Convert failed */ - if (lki->lksb.sb_status != 0 && lki->grmode != -1) { - lki->rqmode = lki->grmode; - } - - /* Lock failed - remove it */ - if (lki->lksb.sb_status != 0 && lki->grmode == -1) { - list_del(&lki->list); - kfree(lki->lksb.sb_lvbptr); - kfree(lki); - module_put(THIS_MODULE); - } - - /* Unlock suceeded */ - if (lki->lksb.sb_status == -DLM_EUNLOCK) { - list_del(&lki->list); - kfree(lki->lksb.sb_lvbptr); - kfree(lki); - module_put(THIS_MODULE); - } - -} - -static void query_ast_routine(void *arg) -{ - struct dlm_lksb *lksb = arg; - struct dlm_queryinfo *qi = (struct dlm_queryinfo *)lksb->sb_lvbptr; - int i; - - /* Dump resource info */ - printk("lockinfo: status = %d\n", lksb->sb_status); - printk("lockinfo: resource = '%s'\n", qi->gqi_resinfo->rsi_name); - printk("lockinfo: grantcount = %d\n", qi->gqi_resinfo->rsi_grantcount); - printk("lockinfo: convcount = %d\n", qi->gqi_resinfo->rsi_convcount); - printk("lockinfo: waitcount = %d\n", qi->gqi_resinfo->rsi_waitcount); - printk("lockinfo: masternode = %d\n", qi->gqi_resinfo->rsi_masternode); - - /* Dump all the locks */ - for (i = 0; i < qi->gqi_lockcount; i++) - { - struct dlm_lockinfo *li = &qi->gqi_lockinfo[i]; - - printk("lockinfo: lock: lkid = %x\n", li->lki_lkid); - printk("lockinfo: lock: master lkid = %x\n", li->lki_mstlkid); - printk("lockinfo: lock: parent lkid = %x\n", li->lki_parent); - printk("lockinfo: lock: node = %d\n", li->lki_node); - printk("lockinfo: lock: state = %d\n", li->lki_state); - printk("lockinfo: lock: grmode = %d\n", li->lki_grmode); - printk("lockinfo: lock: rqmode = %d\n", li->lki_rqmode); - printk("\n"); - } - - if (qi->gqi_lockinfo) - kfree(qi->gqi_lockinfo); - kfree(qi->gqi_resinfo); - kfree(qi); - kfree(lksb); -} - -static void blockast_routine(void *arg, int mode) -{ - struct my_lock *lki = (struct my_lock *)arg; - int status; - - printk("locktest: Blocking AST for %x\n", lki->lksb.sb_lkid); - if (lki->bastmode != -1) { - /* convert lock to bastmode */ - lki->rqmode = lki->bastmode; - - status = dlm_lock(lockspace, - lki->bastmode, - &lki->lksb, - DLM_LKF_CONVERT, - NULL, - 0, - 0, - compast_routine, - lki, - blockast_routine, - NULL); - if (status == 0) { - lki->rqmode = lki->bastmode; - lki->bastmode = -1; - } - } -} - - -static int lock_command(char *cmd) -{ - char *str; - int i = 1; - struct my_lock *newlock; - int status; - - newlock = kmalloc(sizeof(struct my_lock), GFP_KERNEL); - if (!newlock) - return -ENOMEM; - - memset(newlock, 0, sizeof(*newlock)); - - newlock->lksb.sb_lvbptr = kmalloc(DLM_LVB_LEN, GFP_KERNEL); - if (!newlock->lksb.sb_lvbptr) - { - kfree(newlock); - return -ENOMEM; - } - memset(newlock->lksb.sb_lvbptr, 0, DLM_LVB_LEN); - - newlock->bastmode = -1; - newlock->grmode = -1; - - str = strsep(&cmd, " "); - while (str) { - switch (i) { - case 1: - strcpy(newlock->name, str); - break; - - case 2: - newlock->rqmode = modetonum(str); - break; - - case 3: - newlock->parent = atoi(str); - break; - - case 4: - strcpy(newlock->lksb.sb_lvbptr, str); - break; - - case 5: - newlock->bastmode = modetonum(str); - break; - } - i++; - str = strsep(&cmd, " "); - } - - status = dlm_lock(lockspace, - newlock->rqmode, - &newlock->lksb, - (i>4)? DLM_LKF_VALBLK: 0, - newlock->name, - strlen(newlock->name)+1, - newlock->parent, - compast_routine, - newlock, - blockast_routine, - NULL); - - if (status < 0) { - kfree(newlock->lksb.sb_lvbptr); - kfree(newlock); - } - else { - try_module_get(THIS_MODULE); - list_add(&newlock->list, &our_locks); - } - - return status; -} - - -static int unlock_command(char *cmd) -{ - struct my_lock *lockstruct=NULL; - char *str; - int i=1; - int status; - int lkid = 0; - int force = 0; - - str = strsep(&cmd, " "); - while (str) { - switch (i) { - case 1: - lkid = atoi(str); - lockstruct = find_mylock(lkid); - break; - - case 2: - if (lockstruct) - strcpy(lockstruct->lksb.sb_lvbptr, str); - break; - case 3: - if (strcmp(str, "force") == 0) - force = 1; - } - i++; - str = strsep(&cmd, " "); - } - - /* Must have "force" if it's not our lock */ - if (!lockstruct && !force) return -EINVAL; - - if (!lockstruct) - { - /* Force out a lock */ - status = dlm_unlock(lockspace, - lkid, - 0, - &spare_lksb, - NULL); - } - else - { - status = dlm_unlock(lockspace, - lockstruct->lksb.sb_lkid, - i>1? DLM_LKF_VALBLK: 0, - &lockstruct->lksb, - NULL); - } - return status; -} - -static int convert_command(char *cmd) -{ - struct my_lock *lockstruct = NULL; - char *str; - int i=1; - int status; - int flags; - - str = strsep(&cmd, " "); - while (str) { - switch (i) { - case 1: - lockstruct = find_mylock(atoi(str)); - if (!lockstruct) return -EINVAL; - break; - - case 2: - lockstruct->rqmode = modetonum(str); - break; - case 3: - strcpy(lockstruct->lksb.sb_lvbptr, str); - break; - } - i++; - str = strsep(&cmd, " "); - } - if (lockstruct->rqmode > lockstruct->grmode) flags = DLM_LKF_QUECVT; - status = dlm_lock(lockspace, - lockstruct->rqmode, - &lockstruct->lksb, - DLM_LKF_CONVERT, - NULL, - 0, - 0, - compast_routine, - lockstruct, - blockast_routine, - NULL); - - return status; -} - - -static int query_command(char *cmd) -{ - char *str; - int i=1; - int status; - int lkid = 0; - int querytype = DLM_QUERY_QUEUE_ALL | DLM_QUERY_LOCKS_ALL; - struct dlm_queryinfo *qi; - struct dlm_lksb *lksb; - int maxlocks = 100; - - str = strsep(&cmd, " "); - while (str) { - switch (i) { - case 1: - lkid = atoi(str); - break; - - case 2: /* Optional */ - querytype = atoi(str); - break; - - case 3: /* max locks */ - maxlocks = atoi(str); - break; - } - i++; - str = strsep(&cmd, " "); - } - - qi = kmalloc(sizeof(struct dlm_queryinfo), GFP_KERNEL); - qi->gqi_resinfo = kmalloc(sizeof(struct dlm_resinfo), GFP_KERNEL); - qi->gqi_lockinfo = kmalloc(sizeof(struct dlm_lockinfo)*maxlocks, GFP_KERNEL); - lksb = kmalloc(sizeof(struct dlm_lksb), GFP_KERNEL); - qi->gqi_locksize = maxlocks; - lksb->sb_lkid = lkid; - lksb->sb_status = 0 ; - lksb->sb_lvbptr = (char *)qi; - - status = dlm_query(lockspace, - lksb, - querytype, - qi, - query_ast_routine, - lksb); - - return status; -} - -static int dlm_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - return show_locks(page, count); -} - -static int dlm_proc_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int error = -EINVAL, n = count; - char proc_buf[132]; - - try_module_get(THIS_MODULE); - - error = -EFAULT; - memset(proc_buf, 0, sizeof(proc_buf)); - - if (count > sizeof(proc_buf)) - goto fail; - - error = copy_from_user(proc_buf, buffer, n) ? -EFAULT : 0; - if (error) - goto fail; - - /* Remove trailing NL */ - if (proc_buf[n-1] == '\n') - proc_buf[n-1] = '\0'; - error = -EINVAL; - if (strncmp(proc_buf, "lock ", 5) == 0) - error = lock_command(proc_buf+5); - - if (strncmp(proc_buf, "unlock ", 7) == 0) - error = unlock_command(proc_buf+7); - - if (strncmp(proc_buf, "convert ", 8) == 0) - error = convert_command(proc_buf+8); - - if (strncmp(proc_buf, "query ", 6) == 0) - error = query_command(proc_buf+6); - - if (error < 0) - goto fail; - - module_put(THIS_MODULE); - return count; - - fail: - printk("LOCKTEST: '%s' failed : %d\n", proc_buf, error); - module_put(THIS_MODULE); - return error; -} - - - -static int __init test_init(void) -{ - int ls_status; - - INIT_LIST_HEAD(&our_locks); - - dlm_proc_entry = create_proc_read_entry(procname, S_IFREG | 0666, NULL, - NULL, NULL); - dlm_proc_entry->write_proc = dlm_proc_write; - dlm_proc_entry->read_proc = dlm_proc_read; - - ls_status = dlm_new_lockspace(ls, strlen(ls), &lockspace, 0); - if (ls_status < 0 && ls_status != -EEXIST) { - remove_proc_entry(procname, NULL); - return -1; - } - return 0; -} - -static void __exit test_exit(void) -{ - remove_proc_entry(procname, NULL); - dlm_release_lockspace(lockspace,0); -} - -module_init(test_init); -module_exit(test_exit); - -MODULE_PARM(ls, "s"); -MODULE_PARM(procname, "s"); -MODULE_LICENSE("GPL"); diff --git a/dlm/tests/locktest/timelocks.c b/dlm/tests/locktest/timelocks.c deleted file mode 100644 index 54b8bf1..0000000 --- a/dlm/tests/locktest/timelocks.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Time locking operations - * - * Note that this needs to be able to get an EX lock on - * a resource so any other locks on the same resource - * (to force mastery etc) should be held at NL. - * but you'd do that anyway, wouldn't you ? - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/string.h> -#include <linux/sockios.h> -#include <linux/net.h> -#include <linux/netdevice.h> -#include <linux/capability.h> -#include <linux/inet.h> -#include <linux/file.h> -#include <linux/route.h> -#include <linux/interrupt.h> -#include <net/sock.h> -#include <net/scm.h> -#include <asm/segment.h> -#include <asm/system.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/proc_fs.h> -#include <linux/stat.h> -#include <linux/init.h> -#include <linux/poll.h> -#include <net/dst.h> - -#include "osi.h" -#include "osi_list.h" -#include "gdlm.h" - -static gdlm_lksb_t our_lksb; -static gdlm_lockspace_t *lockspace; -char *ls = "gtest"; /* Share a lockspace with /proc/gtest */ -char *lockname="timing"; -int convert=0; -int num=1000; /* Number to do */ -int count=0; /* Number done */ - -static struct timeval start_tv, end_tv; - -static int cur_mode; -static int granted = 0; -static int failed = 0; -static void compast_routine(void *arg); -static void finish(void); - -static int convert_lock(int mode) -{ - int status; - - status = gdlm_lock(lockspace, - mode, - &our_lksb, - GDLM_LKF_CONVERT, - NULL, - 0, - 0, - compast_routine, - &our_lksb, - NULL, - NULL); - if (status != 0) - { - printk("timelocks: convert failed: %d\n", status); - failed = 1; - finish(); - } - else - { - cur_mode = mode; - } - return status; -} - -static void unlock() -{ - int status; - status = gdlm_unlock(lockspace, - our_lksb.sb_lkid, - 0, - &our_lksb, - 0); - if (status != 0) - { - printk("timelocks: unlock failed: %d\n", status); - failed = 1; - } - -} - -static void start_lock() -{ - int status; - cur_mode = GDLM_LOCK_EX; - - status = gdlm_lock(lockspace, - cur_mode, - &our_lksb, - 0, - lockname, - strlen(lockname)+1, /* include trailing NUL for ease of following */ - 0, /* Parent */ - compast_routine, - &our_lksb, - NULL, - NULL); - if (status != 0) - { - printk("timelocks: lock failed: %d\n", status); - failed = 1; - } -} - -static void finish() -{ - if (!failed) - { - unsigned long long time_taken; - do_gettimeofday(&end_tv); - - time_taken = (end_tv.tv_sec*1000000 + end_tv.tv_usec) - - (start_tv.tv_sec*1000000 + start_tv.tv_usec); - - printk("timelocks: finished %d %s. Time taken = %lld\n", - num, convert?"converts":"lock/unlocks", time_taken); - } - - MOD_DEC_USE_COUNT; -} - -static void compast_routine(void *arg) -{ - /* If it deadlocked then the lock will be demoted back to PR so try again */ - if (our_lksb.sb_status == -EDEADLOCK) - { - printk("timelocks: deadlocked\n"); - failed = 1; - unlock(); - finish(); - return; - } - - if (our_lksb.sb_status == -GDLM_EUNLOCK) - { - if (++count < num) - { - start_lock(); - } - else - { - finish(); - } - return; - } - - if (our_lksb.sb_status == 0) - { - granted = 1; - switch (cur_mode) - { - case GDLM_LOCK_NL: - if (++count < num) - { - if (convert_lock(GDLM_LOCK_EX) == 0) - granted = 0; - } - else - { - unlock(); - } - break; - - case GDLM_LOCK_EX: - if (convert) - { - /* Only time the conversions */ - if (count == 0) - do_gettimeofday(&start_tv); - - if (convert_lock(GDLM_LOCK_NL) == 0) - granted = 0; - } - else - { - unlock(); - } - break; - } - } - else - { - printk("timelocks: lock failed (compast): %d\n", our_lksb.sb_status); - failed = 1; - unlock(); - finish(); - } -} - - -static int __init time_init(void) -{ - int status; - - status = gdlm_new_lockspace(ls, strlen(ls), &lockspace, 0); - - if (status < 0 && status != -EEXIST) - { - return -1; - } - - MOD_INC_USE_COUNT; - - do_gettimeofday(&start_tv); - start_lock(); - return 0; -} - -static void __exit time_exit(void) -{ -// gdlm_release_lockspace(lockspace); -} - -module_init(time_init); -module_exit(time_exit); - -MODULE_PARM(num, "i"); -MODULE_PARM(lockname, "s"); -MODULE_PARM(ls, "s"); -MODULE_PARM(convert, "i"); diff --git a/dlm/tests/usertest/Makefile b/dlm/tests/usertest/Makefile deleted file mode 100644 index c41b932..0000000 --- a/dlm/tests/usertest/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir = ../../.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -BINARIES=dlmtest asttest lstest pingtest lvb - -all: $(BINARIES) - -CFLAGS+=-I${top_srcdir}/dlm/lib -L${top_srcdir}/dlm/lib -g -D_REENTRANT - -ifneq (${KERNEL_SRC}, ) -CFLAGS += -I${KERNEL_SRC}/include/cluster -else -CFLAGS += -I/usr/include/linux/cluster -endif - - -dlmtest: dlmtest.c - $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread - -asttest: asttest.c - $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread - -lstest: lstest.c - $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread - -pingtest: pingtest.c - $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread - -lvb: lvb.c - $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread -clean: - rm -f *.o $(BINARIES) *~ core - -copytobin: - diff --git a/dlm/tests/usertest/asttest.c b/dlm/tests/usertest/asttest.c deleted file mode 100644 index 132761f..0000000 --- a/dlm/tests/usertest/asttest.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Test program for userland DLM interface w/ AST */ -/* NOTE: This is not much of a program and it fails in all - sorts of ways. But it /does/ illustrate the full dlm_lock - call and ASTs. It doesn /not/ show how you should use the - FD parts fo the API! -*/ - -#ifdef _REENTRANT -#include <pthread.h> -#endif -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stddef.h> -#include <fcntl.h> -#include <netdb.h> -#include <limits.h> -#include <unistd.h> -#include <errno.h> -#include <getopt.h> - -#include "libdlm.h" - -static struct dlm_lksb lksb; -static int use_threads = 0; -static int quiet = 0; - -/* Used by the pthread test */ -static pthread_cond_t cond; -static pthread_mutex_t mutex; - -/* Used by the poll() test */ -static int ast_called = 0; - -static int modetonum(char *modestr) -{ - int mode = LKM_EXMODE; - - if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE; - if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE; - if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE; - if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE; - if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE; - if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE; - - return mode; -} - -static char *numtomode(int mode) -{ - switch (mode) - { - case LKM_NLMODE: return "NL"; - case LKM_CRMODE: return "CR"; - case LKM_CWMODE: return "CW"; - case LKM_PRMODE: return "PR"; - case LKM_PWMODE: return "PW"; - case LKM_EXMODE: return "EX"; - default: return "??"; - } -} - -static void usage(char *prog, FILE *file) -{ - fprintf(file, "Usage:\n"); - fprintf(file, "%s [mcnpquhV] <lockname>\n", prog); - fprintf(file, "\n"); - fprintf(file, " -V Show version of dlmtest\n"); - fprintf(file, " -h Show this help information\n"); - fprintf(file, " -m <mode> lock mode (default EX)\n"); - fprintf(file, " -c <mode> mode to convert to (default none)\n"); - fprintf(file, " -n don't block\n"); - fprintf(file, " -p Use pthreads\n"); - fprintf(file, " -q Quiet\n"); - fprintf(file, " -u Don't unlock explicitly\n"); - fprintf(file, "\n"); - -} - -static void ast_routine(void *arg) -{ - struct dlm_lksb *lksb = arg; - - if (!quiet) - printf("ast called, status = %d, lkid=%x\n", lksb->sb_status, lksb->sb_lkid); - - /* Wake the main thread */ - if (use_threads) - { - pthread_mutex_lock(&mutex); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - } - else - { - ast_called = 1; - } -} - -static void bast_routine(void *arg) -{ - struct dlm_lksb *lksb = arg; - - if (!quiet) - printf("\nblocking ast called, status = %d, lkid=%x\n", lksb->sb_status, lksb->sb_lkid); -} - -/* Using poll(2) to wait for and dispatch ASTs */ -static int poll_for_ast() -{ - struct pollfd pfd; - - pfd.fd = dlm_get_fd(); - pfd.events = POLLIN; - while (!ast_called) - { - if (poll(&pfd, 1, 0) < 0) - { - perror("poll"); - return -1; - } - dlm_dispatch(pfd.fd); - } - ast_called = 0; - return 0; -} - -int main(int argc, char *argv[]) -{ - char *resource = "LOCK-NAME"; - int flags = 0; - int status; - int mode = LKM_EXMODE; - int convmode = -1; - int do_unlock = 1; - signed char opt; - - /* Deal with command-line arguments */ - opterr = 0; - optind = 0; - while ((opt=getopt(argc,argv,"?m:nqupc:vV")) != EOF) - { - switch(opt) - { - case 'h': - usage(argv[0], stdout); - exit(0); - - case '?': - usage(argv[0], stderr); - exit(0); - - case 'm': - mode = modetonum(optarg); - break; - - case 'c': - convmode = modetonum(optarg); - break; - - case 'p': - use_threads++; - break; - - case 'n': - flags |= LKF_NOQUEUE; - break; - - case 'q': - quiet = 1; - break; - - case 'u': - do_unlock = 0; - break; - - - case 'V': - printf("\nasttest version 0.1\n\n"); - exit(1); - break; - } - } - - if (argv[optind]) - resource = argv[optind]; - - if (!quiet) - fprintf(stderr, "locking %s %s %s...", resource, - numtomode(mode), - (flags&LKF_NOQUEUE?"(NOQUEUE)":"")); - - fflush(stderr); - - if (use_threads) - { - pthread_cond_init(&cond, NULL); - pthread_mutex_init(&mutex, NULL); - pthread_mutex_lock(&mutex); - - dlm_pthread_init(); - } - - status = dlm_lock(mode, - &lksb, - flags, - resource, - strlen(resource), - 0, // Parent, - ast_routine, - &lksb, - bast_routine, - NULL); // Range - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("lock"); - - return -1; - } - printf("(lkid=%x)", lksb.sb_lkid); - - /* Wait */ - if (use_threads) - pthread_cond_wait(&cond, &mutex); - else - poll_for_ast(); - - if (!quiet) - { - fprintf(stderr, "unlocking %s...", resource); - fflush(stderr); - } - - if (do_unlock) - { - status = dlm_unlock(lksb.sb_lkid, - 0, // flags - &lksb, - &lksb); // AST args - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("unlock"); - return -1; - } - - /* Wait */ - if (use_threads) - pthread_cond_wait(&cond, &mutex); - else - poll_for_ast(); - } - - return 0; -} - diff --git a/dlm/tests/usertest/dlmtest.c b/dlm/tests/usertest/dlmtest.c deleted file mode 100644 index 321d66b..0000000 --- a/dlm/tests/usertest/dlmtest.c +++ /dev/null @@ -1,288 +0,0 @@ -/* Test program for userland DLM interface */ - -#include <sys/types.h> -#include <sys/uio.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stddef.h> -#include <fcntl.h> -#include <netdb.h> -#include <limits.h> -#include <unistd.h> -#include <errno.h> -#include <getopt.h> - -#include "libdlm.h" - -static int modetonum(char *modestr) -{ - int mode = LKM_EXMODE; - - if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE; - if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE; - if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE; - if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE; - if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE; - if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE; - - return mode; -} - -static char *numtomode(int mode) -{ - switch (mode) - { - case LKM_NLMODE: return "NL"; - case LKM_CRMODE: return "CR"; - case LKM_CWMODE: return "CW"; - case LKM_PRMODE: return "PR"; - case LKM_PWMODE: return "PW"; - case LKM_EXMODE: return "EX"; - default: return "??"; - } -} - -static void usage(char *prog, FILE *file) -{ - fprintf(file, "Usage:\n"); - fprintf(file, "%s [hmcnQpequdV] <lockname>\n", prog); - fprintf(file, "\n"); - fprintf(file, " -V Show version of dlmtest\n"); - fprintf(file, " -h Show this help information\n"); - fprintf(file, " -m <mode> lock mode (default EX)\n"); - fprintf(file, " -c <mode> mode to convert to (default none)\n"); - fprintf(file, " -n don't block\n"); - fprintf(file, " -Q query the lock\n"); - fprintf(file, " -p Persistent lock\n"); - fprintf(file, " -e Expedite conversion\n"); - fprintf(file, " -q Quiet\n"); - fprintf(file, " -u Don't unlock explicitly\n"); - fprintf(file, " -d <secs> Time to hold the lock for\n"); - fprintf(file, "\n"); - -} - - -static void query_ast_routine(void *arg) -{ - struct dlm_lksb *lksb = arg; - struct dlm_queryinfo *qi = (struct dlm_queryinfo *)lksb->sb_lvbptr; - int i; - - qi->gqi_resinfo->rsi_name[qi->gqi_resinfo->rsi_length] = '\0'; - /* Dump resource info */ - printf("lockinfo: status = %d\n", lksb->sb_status); - printf("lockinfo: resource = '%s'\n", qi->gqi_resinfo->rsi_name); - printf("lockinfo: grantcount = %d\n", qi->gqi_resinfo->rsi_grantcount); - printf("lockinfo: convcount = %d\n", qi->gqi_resinfo->rsi_convcount); - printf("lockinfo: waitcount = %d\n", qi->gqi_resinfo->rsi_waitcount); - printf("lockinfo: masternode = %d\n", qi->gqi_resinfo->rsi_masternode); - - /* Dump all the locks */ - for (i = 0; i < qi->gqi_lockcount; i++) - { - struct dlm_lockinfo *li = &qi->gqi_lockinfo[i]; - - printf("lockinfo: lock: lkid = %x\n", li->lki_lkid); - printf("lockinfo: lock: master lkid = %x\n", li->lki_mstlkid); - printf("lockinfo: lock: parent lkid = %x\n", li->lki_parent); - printf("lockinfo: lock: node = %d\n", li->lki_node); - printf("lockinfo: lock: pid = %d\n", li->lki_ownpid); - printf("lockinfo: lock: state = %d\n", li->lki_state); - printf("lockinfo: lock: grmode = %d\n", li->lki_grmode); - printf("lockinfo: lock: rqmode = %d\n", li->lki_rqmode); - printf("\n"); - } - - if (qi->gqi_lockinfo) - free(qi->gqi_lockinfo); -} - - -static struct dlm_lksb lksb; -static struct dlm_queryinfo qinfo; -static struct dlm_resinfo resinfo; -#define MAX_QUERY_LOCKS 10 - -static int query_lock(int lockid) -{ - int status; - - lksb.sb_lkid = lockid; - qinfo.gqi_resinfo = &resinfo; - qinfo.gqi_lockinfo = malloc(sizeof(struct dlm_lockinfo) * MAX_QUERY_LOCKS); - qinfo.gqi_locksize = MAX_QUERY_LOCKS; - lksb.sb_lvbptr = (char *)&qinfo; - - status = dlm_query(&lksb, - DLM_QUERY_QUEUE_ALL | DLM_QUERY_LOCKS_ALL, - &qinfo, - query_ast_routine, - &lksb); - if (status) - perror("Query failed"); - else - sleep(1); /* Just to allow the result to come back. There isn't - a synchronous version of this call */ - return status; -} - - - -int main(int argc, char *argv[]) -{ - char *resource = "LOCK-NAME"; - int flags = 0; - int status; - int delay = 5; - int mode = LKM_EXMODE; - int convmode = -1; - int lockid; - int quiet = 0; - int do_unlock = 1; - int do_query = 0; - int do_expedite = 0; - signed char opt; - - /* Deal with command-line arguments */ - opterr = 0; - optind = 0; - while ((opt=getopt(argc,argv,"?m:nquQepd:c:vV")) != EOF) - { - switch(opt) - { - case 'h': - usage(argv[0], stdout); - exit(0); - - case '?': - usage(argv[0], stderr); - exit(0); - - case 'm': - mode = modetonum(optarg); - break; - - case 'c': - convmode = modetonum(optarg); - break; - - case 'e': - do_expedite = 1; - break; - - case 'p': - flags |= LKF_PERSISTENT; - break; - - case 'n': - flags |= LKF_NOQUEUE; - break; - - case 'd': - delay = atoi(optarg); - break; - - case 'q': - quiet = 1; - break; - - case 'u': - do_unlock = 0; - break; - - case 'Q': - do_query = 1; - break; - - case 'V': - printf("\ndlmtest version 0.3\n\n"); - exit(1); - break; - } - } - - if (argv[optind]) - resource = argv[optind]; - - if (!quiet) - fprintf(stderr, "locking %s %s %s...", resource, - numtomode(mode), - (flags&LKF_NOQUEUE?"(NOQUEUE)":"")); - - fflush(stderr); - - status = lock_resource(resource, mode, flags, &lockid); - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("lock"); - - return -1; - } - if (lockid == 0) - { - fprintf(stderr, "error: got lockid of zero\n"); - return 0; - } - - if (!quiet) fprintf(stderr, "done (lkid = %x)\n", lockid); - - if (!do_unlock) return 0; - - if (do_query) query_lock(lockid); - - sleep(delay); - - if (convmode != -1) - { - if (do_expedite) - flags |= LKF_EXPEDITE; - - if (!quiet) - { - fprintf(stderr, "converting %s to %s...", resource, numtomode(convmode)); - fflush(stderr); - } - - status = lock_resource(resource, convmode, flags | LKF_CONVERT, &lockid); - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("convert"); - return -1; - } - if (!quiet) fprintf(stderr, "done\n"); - } - - sleep(delay); - - if (!quiet) - { - fprintf(stderr, "unlocking %s...", resource); - fflush(stderr); - } - - status = unlock_resource(lockid); - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("unlock"); - return -1; - } - - if (!quiet) fprintf(stderr, "done\n"); - - /* For some reason, calling this IMMEDIATELY before - exitting, causes a thread hang. either don't call it at - all or do something in afterwards before calling exit - */ - dlm_pthread_cleanup(); - return 0; -} - diff --git a/dlm/tests/usertest/lstest.c b/dlm/tests/usertest/lstest.c deleted file mode 100644 index 025572a..0000000 --- a/dlm/tests/usertest/lstest.c +++ /dev/null @@ -1,326 +0,0 @@ -/* Test program for userland lockspaces */ - -#ifdef _REENTRANT -#include <pthread.h> -#endif -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stddef.h> -#include <fcntl.h> -#include <netdb.h> -#include <limits.h> -#include <unistd.h> -#include <errno.h> -#include <getopt.h> - -#include "libdlm.h" - -static struct dlm_lksb lksb; -static int use_threads = 0; -static int quiet = 0; - -/* Used by the pthread test */ -static pthread_cond_t cond; -static pthread_mutex_t mutex; - -/* Used by the poll() test */ -static int ast_called = 0; - -static int modetonum(char *modestr) -{ - int mode = LKM_EXMODE; - - if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE; - if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE; - if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE; - if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE; - if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE; - if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE; - - return mode; -} - -static char *numtomode(int mode) -{ - switch (mode) - { - case LKM_NLMODE: return "NL"; - case LKM_CRMODE: return "CR"; - case LKM_CWMODE: return "CW"; - case LKM_PRMODE: return "PR"; - case LKM_PWMODE: return "PW"; - case LKM_EXMODE: return "EX"; - default: return "??"; - } -} - -static void usage(char *prog, FILE *file) -{ - fprintf(file, "Usage:\n"); - fprintf(file, "%s [mcnpqdlrfuhV] <lockname>\n", prog); - fprintf(file, "\n"); - fprintf(file, " -V Show version of dlmtest\n"); - fprintf(file, " -h Show this help information\n"); - fprintf(file, " -m <mode> lock mode (default EX)\n"); - fprintf(file, " -n don't block\n"); - fprintf(file, " -p Use pthreads\n"); - fprintf(file, " -q Quiet\n"); - fprintf(file, " -d <secs> Delay betwen lock & unlock\n"); - fprintf(file, " -l <ls> Lockspace name to create\n"); - fprintf(file, " -r Don't release lockspace before finishing\n"); - fprintf(file, " -f Force release lockspace\n"); - fprintf(file, " -u Don't unlock explicitly\n"); - fprintf(file, "\n"); - -} - -static void ast_routine(void *arg) -{ - struct dlm_lksb *lksb = arg; - - if (!quiet) - printf("ast called, status = %d, lkid=%x\n", lksb->sb_status, lksb->sb_lkid); - - /* Wake the main thread */ - if (use_threads) - { - pthread_mutex_lock(&mutex); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - } - else - { - ast_called = 1; - } -} - -static void bast_routine(void *arg) -{ - struct dlm_lksb *lksb = arg; - - if (!quiet) - printf("\nblocking ast called, status = %d, lkid=%x\n", lksb->sb_status, lksb->sb_lkid); -} - -/* Using poll(2) to wait for and dispatch ASTs */ -static int poll_for_ast(dlm_lshandle_t ls) -{ - struct pollfd pfd; - - pfd.fd = dlm_ls_get_fd(ls); - pfd.events = POLLIN; - while (!ast_called) - { - if (poll(&pfd, 1, 0) < 0) - { - perror("poll"); - return -1; - } - dlm_dispatch(dlm_ls_get_fd(ls)); - } - ast_called = 0; - return 0; -} - -int main(int argc, char *argv[]) -{ - char *resource = "LOCK-NAME"; - int flags = 0; - int status; - int mode = LKM_EXMODE; - int do_unlock = 1; - int release_ls = 1; - int open_ls = 0; - int force = 0; - int sleeptime = 5; - signed char opt; - char lsname[64]; - dlm_lshandle_t ls; - - strcpy(lsname, "testls"); - - /* Deal with command-line arguments */ - opterr = 0; - optind = 0; - while ((opt=getopt(argc,argv,"?m:nqupd:c:l:rfoV")) != EOF) - { - switch(opt) - { - case 'h': - usage(argv[0], stdout); - exit(0); - - case '?': - usage(argv[0], stderr); - exit(0); - - case 'm': - mode = modetonum(optarg); - break; - - case 'l': - strcpy(lsname, optarg); - break; - - case 'd': - sleeptime = atoi(optarg); - break; - - case 'p': - use_threads++; - break; - - case 'o': - open_ls++; - break; - - case 'f': - force++; - break; - - case 'r': - release_ls = 0; - break; - - case 'n': - flags |= LKF_NOQUEUE; - break; - - case 'q': - quiet = 1; - break; - - case 'u': - do_unlock = 0; - break; - - case 'V': - printf("\nasttest version 0.2\n\n"); - exit(1); - break; - } - } - - if (argv[optind]) - resource = argv[optind]; - - - if (!open_ls) - { - if (!quiet) - fprintf(stderr, "Creating lockspace %s\n", lsname); - - - ls = dlm_create_lockspace(lsname, 0444); - if (ls == NULL) - { - perror("ls create"); - exit(4); - } - } - else - { - if (!quiet) - fprintf(stderr, "Opening lockspace %s\n", lsname); - - - ls = dlm_open_lockspace(lsname); - if (ls == NULL) - { - perror("ls open"); - exit(4); - } - } - - - if (!quiet) - fprintf(stderr, "locking %s %s %s...", resource, - numtomode(mode), - (flags&LKF_NOQUEUE?"(NOQUEUE)":"")); - - fflush(stderr); - - if (use_threads) - { - pthread_cond_init(&cond, NULL); - pthread_mutex_init(&mutex, NULL); - pthread_mutex_lock(&mutex); - - status = dlm_ls_pthread_init(ls); printf("status=%d\n", status); - status = dlm_ls_pthread_init(ls); printf("status=%d\n", status); - } - - status = dlm_ls_lock(ls,mode, - &lksb, - flags, - resource, - strlen(resource), - 0, // Parent, - ast_routine, - &lksb, - bast_routine, - NULL); // Range - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("lock"); - - return -1; - } - - /* Wait */ - if (use_threads) - pthread_cond_wait(&cond, &mutex); - else - poll_for_ast(ls); - - sleep(sleeptime); - - if (!quiet) - { - fprintf(stderr, "unlocking %s...", resource); - fflush(stderr); - } - - if (do_unlock) - { - status = dlm_ls_unlock(ls, - lksb.sb_lkid, - 0, // flags - &lksb, - &lksb); // AST args - if (status == -1) - { - if (!quiet) fprintf(stderr, "\n"); - perror("unlock"); - return -1; - } - - /* Wait */ - if (use_threads) - pthread_cond_wait(&cond, &mutex); - else - poll_for_ast(ls); - } - - if (release_ls) - { - if (!quiet) - fprintf(stderr, "Releasing ls %s\n", lsname); - - status = dlm_release_lockspace(lsname, ls, force); - if (status) - perror("release ls"); - } - - return 0; -} - diff --git a/dlm/tests/usertest/lvb.c b/dlm/tests/usertest/lvb.c deleted file mode 100755 index 16b1f93..0000000 --- a/dlm/tests/usertest/lvb.c +++ /dev/null @@ -1,233 +0,0 @@ -/* Simple LVB test prog */ - -#ifdef VMS -#include starlet -#include psldef -#include ssdef -#include errno -#include descrip -#include rsdmdef -#include lckdef - -#include stdio -#include stdlib -#include string - -struct lksb -{ - int sb_status; - int sb_lkid; - char sb_lvb[16]; -}; -#endif - -#ifdef __linux__ -#include <stdio.h> -#include <pthread.h> -#include <errno.h> -#include <sys/types.h> -#include <netdb.h> -#include <libdlm.h> -#define LCK$M_VALBLK LKF_VALBLK -#define LCK$M_CONVERT LKF_CONVERT -#define LCK$K_CRMODE LKM_CRMODE -#define LCK$K_PWMODE LKM_PWMODE -#define PSL$C_USER 0 -#define SS$_NORMAL 0 -#define SS$_DEADLOCK EDEADLOCK -#define EVMSERR errno -#define sys$exit exit -#define sys$hiber pause - - -struct lksb { - int sb_status; - uint32_t sb_lkid; - char sb_flags; - char *sb_lvb; -}; - -struct dsc$descriptor_s -{ - int dsc$w_length; - char *dsc$a_pointer; -}; - -static int sys$enq(int efn, int mode, struct lksb *lksb, int flags, - struct dsc$descriptor_s *name, int parent, - void *compast, void *astarg, void *blockast, - int accmode, int nullarg) -{ - if (name) - return dlm_lock(mode, (struct dlm_lksb *)lksb, flags, - name->dsc$a_pointer, - name->dsc$w_length, - parent, - compast, astarg, - blockast, NULL); - else - return dlm_lock(mode, (struct dlm_lksb *)lksb, flags, - NULL, - 0, - parent, - compast, astarg, - blockast, NULL); -} - -static int sys$deq(int lkid, struct lksb *lksb, int accmode, int flags, int c) -{ - return dlm_unlock(lkid, flags, (struct dlm_lksb *)lksb, NULL); -} - -#endif - - -static struct lksb our_lksb; -static int cur_mode; -static void compast_routine(void *arg); -static void blockast_routine(void *arg, int mode); -static char *name = "TESTLOCK"; - -#ifdef __linux__ -static char lksb_lvb[DLM_LVB_LEN]; -#endif - -static void start_lock(int mode) -{ - struct dsc$descriptor_s name_s; - int status; - - cur_mode = mode; - -/* Make a descriptor of the name */ - memset(&name_s, 0, sizeof(struct dsc$descriptor_s)); - name_s.dsc$w_length = strlen(name); - name_s.dsc$a_pointer = name; - - /* Lock it */ - status = sys$enq(0, - cur_mode, - &our_lksb, - LCK$M_VALBLK, /* flags */ - &name_s, - 0, /* parent */ - compast_routine, - 0, /* astp */ - blockast_routine, - PSL$C_USER, - 0); - - if (status != SS$_NORMAL) - { - printf("lock enq failed : %s\n", strerror(EVMSERR, status)); - sys$exit(status); - } - - printf("Lock ID is %x\n", our_lksb.sb_lkid); - return; -} - -static int convert_lock(int mode, char *lvb) -{ - int status; - - memset(our_lksb.sb_lvb, 0, 16); - if (lvb[strlen(lvb)-1] == '\n') - lvb[strlen(lvb)-1] = '\0'; - - cur_mode = mode; - strcpy(our_lksb.sb_lvb, lvb); - printf("converting to %d\n", mode); - - /* Lock it */ - status = sys$enq(0, - mode, - &our_lksb, - LCK$M_CONVERT | LCK$M_VALBLK, - NULL, - 0, /* parent */ - compast_routine, - 0, /* astp */ - blockast_routine, - PSL$C_USER, - 0); - - if (status != SS$_NORMAL) - { - printf("convert enq failed : %s\n", strerror(EVMSERR, status)); - } - - return status; -} - -static void unlock() -{ - int status; - - status = sys$deq(our_lksb.sb_lkid, NULL,0,0,0); - if (status != SS$_NORMAL) - { - printf("denq failed : %s\n", strerror(EVMSERR, status)); - } -} - -static void compast_routine(void *arg) -{ -#ifdef __linux__ - if (our_lksb.sb_flags & DLM_SBF_VALNOTVALID) - { - printf("testlock: LVB not valid\n"); - sys$hiber(); - } -#endif - if (our_lksb.sb_status == SS$_DEADLOCK) - { - printf("testlock: deadlocked\n"); - unlock(); - return; - } - - if (our_lksb.sb_status == SS$_NORMAL) - { - printf("testlock. compast, now at %d, lvb=%s\n", cur_mode, our_lksb.sb_lvb); - } - else - { - printf("testlock: lock failed (compast): %s\n", strerror(EVMSERR, our_lksb.sb_status)); - sys$hiber(); - } -} - -static void blockast_routine(void *arg, int mode) -{ - printf("testlock. blkast.\n"); -} - -int main(int argc, char *argv[]) -{ - char buf[80]; - -#ifdef __linux__ - our_lksb.sb_lvb = lksb_lvb; - dlm_pthread_init(); -#endif - - if (argc > 1) - name = argv[1]; - - start_lock(LCK$K_CRMODE); - - do { - fgets(buf, sizeof(buf), stdin); - char cmd = buf[0] & 0x5F; - - if (cmd == 'W') - convert_lock(LCK$K_CRMODE, &buf[1]); - else - convert_lock(LCK$K_PWMODE, &buf[1]); - } - while (buf[0] != 'x'); - - return SS$_NORMAL; -} - diff --git a/dlm/tests/usertest/pingtest.c b/dlm/tests/usertest/pingtest.c deleted file mode 100644 index 2fbc5af..0000000 --- a/dlm/tests/usertest/pingtest.c +++ /dev/null @@ -1,340 +0,0 @@ - -/* Ping Test the locking interface */ - -#ifdef __linux__ -#include <pthread.h> -#include <errno.h> -#include <sys/types.h> -#include <netdb.h> - -#include <libdlm.h> - -static char our_lvb[DLM_LVB_LEN]; -static struct dlm_lksb our_lksb = {.sb_lvbptr = our_lvb}; -static int *lvb_int = (int *)our_lvb; -#define SUCCESS 0 -#endif - - -#ifdef VMS -#include starlet -#include psldef -#include ssdef -#include errno -#include descrip -#include rsdmdef -#include lckdef - -#include stdio -#include stdlib -#include string - -struct lksb -{ - int sb_status; - int sb_lkid; - char sb_lvb[16]; -}; - -static struct lksb our_lksb; -static int *lvb_int = (int *)&our_lksb.sb_lvb; - -#define LKM_NLMODE LCK$K_NLMODE -#define LKM_CRMODE LCK$K_CRMODE -#define LKM_CWMODE LCK$K_CWMODE -#define LKM_PRMODE LCK$K_PRMODE -#define LKM_PWMODE LCK$K_PWMODE -#define LKM_EXMODE LCK$K_EXMODE -#define EDEADLOCK SS$_DEADLOCK - -/* This is wrong...VMS does not deliver ASTs - for $DEQ but we'll never get this code, honest. - */ -#define EUNLOCK 65535 - -#define SUCCESS SS$_NORMAL -#endif - -static char *lockname="ping"; -static int us = 1; -static int maxnode = 2; -static int cur_mode; - -static int granted = 0; -static void compast_routine(void *arg); -static void blockast_routine(void *arg); - -#ifdef __linux__ -static int convert_lock(int mode) -{ - int old_mode = cur_mode; - int status; - - printf("pinglock: convert to %d starting\n", mode); - status = dlm_lock( mode, - &our_lksb, - LKF_VALBLK | LKF_CONVERT, - NULL, - 0, - 0, - compast_routine, - &our_lksb, - blockast_routine, - NULL); - if (status != 0) - { - perror("pinglock: convert failed"); - } - else - { - cur_mode = mode; - printf("pinglock: convert to %d started\n", mode); - } - return status; -} - -static void unlock() -{ - int status; - status = dlm_unlock( our_lksb.sb_lkid, - 0, - &our_lksb, - 0); - if (status != 0) - perror("pinglock: unlock failed"); - -} - -static void start_lock() -{ - int status; - cur_mode = LKM_EXMODE; - - *lvb_int = us-1; - - printf("pinglock: starting\n"); - status = dlm_lock( cur_mode, - &our_lksb, - LKF_VALBLK, - lockname, - strlen(lockname)+1, /* include trailing NUL for ease of following */ - 0, /* Parent */ - compast_routine, - &our_lksb, - blockast_routine, - NULL); - if (status != 0) - perror("pinglock: lock failed"); -} - -#endif /* __linux__ */ - -#ifdef VMS - -static void start_lock() -{ - struct dsc$descriptor_s name_s; - int status; - char *name = "PINGLOCK"; - - cur_mode = LCK$K_EXMODE; - - *lvb_int = us-1; - -/* Make a descriptor of the name */ - memset(&name_s, 0, sizeof(struct dsc$descriptor_s)); - name_s.dsc$w_length = strlen(name); - name_s.dsc$a_pointer = name; - - /* Lock it */ - status = sys$enqw(0, - cur_mode, - &our_lksb, - 0, /* flags */ - &name_s, - 0, /* parent */ - compast_routine, - 0, /* astp */ - blockast_routine, - PSL$C_USER, - RSDM$K_PROCESS_RSDM_ID, - 0); - - if (status != SS$_NORMAL) - { - printf("lock enq failed : %s\n", strerror(EVMSERR, status)); - sys$exit(status); - } - - printf("Lock ID is %x\n", our_lksb.sb_lkid); - return; -} - -static int convert_lock(int mode) -{ - int status; - int old_mode = cur_mode; - - printf("converting to %d\n", mode); - - /* Lock it */ - status = sys$enq(0, - mode, - &our_lksb, - LCK$M_CONVERT | LCK$M_VALBLK, - NULL, - 0, /* parent */ - compast_routine, - 0, /* astp */ - blockast_routine, - PSL$C_USER, - RSDM$K_PROCESS_RSDM_ID, - 0); - - if (status != SS$_NORMAL) - { - printf("convert enq failed : %s\n", strerror(EVMSERR, status)); - sys$wake(); - } - else - { - cur_mode = mode; - status = 0; /* simulate Unix retcodes */ - } - return status; -} - -static void unlock() -{ - int status; - - status = sys$deq(our_lksb.sb_lkid, NULL,0,0,0); - if (status != SS$_NORMAL) - { - printf("denq failed : %s\n", strerror(EVMSERR, status)); - sys$wake(); - } -} - -#endif - -static void compast_routine(void *arg) -{ - -#ifdef __linux__ - if (our_lksb.sb_flags & DLM_SBF_VALNOTVALID) -#endif -#ifdef VMS - if (our_lksb.sb_status == SS$_VALNOTVALID) -#endif - { - printf(" valblk not valid. current value is %d\n", *lvb_int); - unlock(); - exit(10); - } - - if (our_lksb.sb_status == EDEADLOCK) - { - printf("pinglock: deadlocked\n"); - unlock(); - exit(11); - } - - if (our_lksb.sb_status == EUNLOCK) - { - return; - } - - if (our_lksb.sb_status == SUCCESS) - { - granted = 1; - switch (cur_mode) - { - case LKM_NLMODE: - printf("pinglock. compast, (valblk = %d) now at NL\n", *lvb_int); - if (convert_lock(LKM_CRMODE) == 0) - granted = 0; - break; - - case LKM_CRMODE: - printf("pinglock. compast, (valblk = %d) now at CR\n", *lvb_int); - if (*lvb_int == us-1) - { - if (convert_lock(LKM_EXMODE) == 0) - granted = 0; - } - break; - - case LKM_EXMODE: - printf("pinglock. compast. (valblk = %d) now at EX\n", *lvb_int); - if (*lvb_int == us-1) - { - (*lvb_int)++; - *lvb_int %= maxnode; - printf("pinglock. compast. incrementing valblk to %d\n", *lvb_int); - } - if (convert_lock(LKM_CRMODE) == 0) - granted = 0; - break; - } - } - else - { - printf("pinglock: lock failed (compast): %d\n", our_lksb.sb_status); - unlock(); - } -} - -static void blockast_routine(void *arg) -{ - printf("pinglock. blkast, granted = %d\n", granted); - if (!granted) - { - return; - } - - printf("pinglock. blkast, demoting lock to NL\n"); - if (convert_lock(LKM_NLMODE) == 0) - granted = 0; -} - - -#ifdef __linux__ -int main(int argc, char *argv[]) -{ - if (argc < 3) - { - printf("usage: %s <maxnodes> <us>\n", argv[0]); - return 2; - } - maxnode = atoi(argv[1]); - us = atoi(argv[2]); - - dlm_pthread_init(); - start_lock(); - while(1) - sleep(100000); - return 0; -} - - -#endif - -#ifdef VMS -int main(int argc, char *argv[]) -{ - if (argc < 3) - { - printf("usage: %s <maxnodes> <us>\n", argv[0]); - return 2; - } - maxnode = atoi(argv[1]); - us = atoi(argv[2]); - - start_lock(); - while(1) - sys$hiber(); - - return SS$_NORMAL; -} -#endif diff --git a/dlm/tool/Makefile b/dlm/tool/Makefile deleted file mode 100644 index c36a8ff..0000000 --- a/dlm/tool/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir = ../.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -BINARIES=dlm_tool - -all: $(BINARIES) - -CFLAGS+=-I${top_srcdir}/dlm/lib -L${top_srcdir}/dlm/lib -g -I../lib/ -L../lib - -ifneq (${KERNEL_SRC}, ) -CFLAGS += -I${KERNEL_SRC}/include/cluster -else -CFLAGS += -I/usr/include/linux/cluster -endif - - -dlm_tool: main.c - $(CC) $(CFLAGS) -o $@ $< -ldlm -lpthread - -clean: - rm -f *.o $(BINARIES) *~ core - -copytobin: - -install: - -uninstall: - -clean: diff --git a/dlm/tool/main.c b/dlm/tool/main.c deleted file mode 100644 index c76a267..0000000 --- a/dlm/tool/main.c +++ /dev/null @@ -1,426 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2007 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <sys/types.h> -#include <sys/un.h> -#include <inttypes.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <stddef.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <netinet/in.h> - -#include "libdlm.h" - -#define OPTION_STRING "MhVvd:m:" - -#define OP_JOIN 1 -#define OP_LEAVE 2 -#define OP_SPACES 3 -#define OP_LOCKDUMP 4 -#define OP_LOCKDEBUG 5 - -static char *prog_name; -static char *lsname; -static int operation; -static int opt_ind; -static int verbose; -static int dump_mstcpy = 0; -static mode_t create_mode = 0600; - -static void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options] [join|leave|spaces|lockdump|lockdebug]\n", prog_name); - printf("\n"); - printf("Options:\n"); - printf(" -v Verbose output, extra event information\n"); - printf(" -m Permission mode for lockspace device (octal)\n"); - printf(" -M Print MSTCPY locks in lockdump (remote locks, locally mastered)\n"); - printf(" -h Print this help, then exit\n"); - printf(" -V Print program version information, then exit\n"); - printf("\n"); -} - -static void decode_arguments(int argc, char **argv) -{ - int cont = 1; - int optchar; - int need_lsname = 1; - char modebuf[8]; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - case 'm': - memset(modebuf, 0, sizeof(modebuf)); - snprintf(modebuf, 8, optarg); - sscanf(modebuf, "%o", &create_mode); - break; - - case 'M': - dump_mstcpy = 1; - break; - - case 'v': - verbose = 1; - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case 'V': - printf("%s (built %s %s)\n", - prog_name, __DATE__, __TIME__); - /* printf("%s\n", REDHAT_COPYRIGHT); */ - exit(EXIT_SUCCESS); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case EOF: - cont = 0; - break; - - default: - fprintf(stderr, "unknown option: %c\n", optchar); - exit(EXIT_FAILURE); - break; - }; - } - - while (optind < argc) { - if (!strncmp(argv[optind], "join", 4) && - (strlen(argv[optind]) == 4)) { - operation = OP_JOIN; - opt_ind = optind + 1; - break; - } else if (!strncmp(argv[optind], "leave", 5) && - (strlen(argv[optind]) == 5)) { - operation = OP_LEAVE; - opt_ind = optind + 1; - break; - } else if (!strncmp(argv[optind], "spaces", 6) && - (strlen(argv[optind]) == 6)) { - operation = OP_SPACES; - opt_ind = optind + 1; - need_lsname = 0; - break; - } else if (!strncmp(argv[optind], "lockdump", 8) && - (strlen(argv[optind]) == 8)) { - operation = OP_LOCKDUMP; - opt_ind = optind + 1; - break; - } else if (!strncmp(argv[optind], "lockdebug", 9) && - (strlen(argv[optind]) == 9)) { - operation = OP_LOCKDEBUG; - opt_ind = optind + 1; - break; - } - optind++; - } - - if (!operation || !opt_ind) { - print_usage(); - exit(EXIT_FAILURE); - } - - if (optind < argc - 1) - lsname = argv[opt_ind]; - else if (need_lsname) { - fprintf(stderr, "lockspace name required\n"); - exit(EXIT_FAILURE); - } -} - -void do_join(char *name) -{ - dlm_lshandle_t *dh; - - printf("Joining lockspace "%s", permission %o\n", name, create_mode); - fflush(stdout); - - dh = dlm_create_lockspace(name, create_mode); - if (!dh) { - fprintf(stderr, "dlm_create_lockspace %s error %p %d\n", - name, dh, errno); - exit(-1); - } - - printf("done\n"); -} - -void do_leave(char *name) -{ - dlm_lshandle_t *dh; - - printf("Leaving lockspace "%s"\n", name); - fflush(stdout); - - dh = dlm_open_lockspace(name); - if (!dh) { - fprintf(stderr, "dlm_open_lockspace %s error %p %d\n", - name, dh, errno); - exit(-1); - } - - dlm_release_lockspace(name, dh, 1); - printf("done\n"); -} - -#define PROC_LINE_MAX 256 - -void do_spaces(void) -{ - FILE *file; - char path[PATH_MAX]; - char line[PROC_LINE_MAX]; - int fd; - int error; - - snprintf(path, PATH_MAX, "/proc/cluster/services"); - - file = fopen(path, "r"); - - while (fgets(line, PROC_LINE_MAX, file)) { - if (strstr(line, "DLM")) - printf("%s", line); - } - - fclose(file); -} - -char *parse_resource(char *line) -{ - static char name[65]; - char *p; - int i = 0; - int begin = 0; - - memset(name, 0, sizeof(name)); - - for (p = line; ; p++) { - if (*p == '"') { - if (begin) - break; - begin = 1; - continue; - } - if (begin) - name[i++] = *p; - } - - return name; -} - -void print_granted(char *line, char *name, int master) -{ - char lkid[16]; - char grmode[8]; - char remote_lkid[16]; - int remote_nodeid; - unsigned int pid; - - if (strstr(line, "Remote:")) { - if (!dump_mstcpy) - return; - - sscanf(line, "%s %s %u Remote: %d %s\n", &lkid, &grmode, - &pid, &remote_nodeid, remote_lkid); - - printf("id %s gr %s rq %s pid %u MSTCPY %d "%s"\n", - lkid, grmode, "IV", pid, remote_nodeid, name); - - return; - } - - sscanf(line, "%s %s %u\n", &lkid, &grmode, &pid); - - printf("id %s gr %s rq %s pid %u master %d "%s"\n", - lkid, grmode, "IV", pid, master, name); -} - -void print_convert(char *line, char *name, int master) -{ - char lkid[16]; - char grmode[8]; - char rqmode[8]; - char remote_lkid[16]; - int remote_nodeid; - unsigned int pid; - - if (strstr(line, "Remote:")) { - if (!dump_mstcpy) - return; - - sscanf(line, "%s %s (%s) %u Remote: %d %s\n", &lkid, &grmode, - &rqmode, &pid, &remote_nodeid, remote_lkid); - - printf("id %s gr %s rq %s pid %u MSTCPY %d "%s"\n", - lkid, grmode, rqmode, pid, remote_nodeid, name); - - return; - } - - sscanf(line, "%s %s (%s) %u\n", &lkid, &grmode, &rqmode, &pid); - - printf("id %s gr %s rq %s pid %u master %d "%s"\n", - lkid, grmode, rqmode, pid, master, name); -} - -void print_waiting(char *line, char *name, int master) -{ - char lkid[16]; - char grmode[8]; - char rqmode[8]; - char remote_lkid[16]; - int remote_nodeid; - unsigned int pid; - - if (strstr(line, "Remote:")) { - if (!dump_mstcpy) - return; - - sscanf(line, "%s %s (%s) %u Remote: %d %s\n", &lkid, &grmode, - &rqmode, &pid, &remote_nodeid, remote_lkid); - - printf("id %s gr %s rq %s pid %u MSTCPY %d "%s"\n", - lkid, "IV", rqmode, pid, remote_nodeid, name); - - return; - } - - sscanf(line, "%s %s (%s) %u\n", &lkid, &grmode, &rqmode, &pid); - - printf("id %s gr %s rq %s pid %u master %d "%s"\n", - lkid, "IV", rqmode, pid, master, name); -} - -int parse_master_nodeid(char *line) -{ - int nodeid; - - sscanf(line, "Local Copy, Master is node %d", &nodeid); - - return nodeid; -} - -void do_lockdump(char *name) -{ - FILE *file; - char path[PATH_MAX]; - char line[PROC_LINE_MAX]; - char *rname; - int fd; - int error; - int master; - int next_is_granted, next_is_convert, next_is_waiting; - - snprintf(path, PATH_MAX, "/proc/cluster/dlm_locks"); - - fd = open(path, O_WRONLY); - - error = write(fd, name, strlen(name)); - - close(fd); - - file = fopen(path, "r"); - - while (fgets(line, PROC_LINE_MAX, file)) { - if (operation == OP_LOCKDEBUG) { - printf("%s", line); - continue; - } - - if (strlen(line) < 4) { - continue; - } else if (!strncmp(line, "LVB: ", 5)) { - continue; - } else if (!strncmp(line, " ", 5)) { - continue; - } else if (!strncmp(line, "Resource", 8)) { - rname = parse_resource(line); - continue; - } else if (strstr(line, "Master Copy")) { - master = 0; - continue; - } else if (strstr(line, "Local Copy")) { - master = parse_master_nodeid(line); - continue; - } else if (strstr(line, "Granted Queue")) { - next_is_granted = 1; - next_is_convert = 0; - next_is_waiting = 0; - continue; - } else if (strstr(line, "Conversion Queue")) { - next_is_granted = 0; - next_is_convert = 1; - next_is_waiting = 0; - continue; - } else if (strstr(line, "Waiting Queue")) { - next_is_granted = 0; - next_is_convert = 0; - next_is_waiting = 1; - continue; - } else { - if (next_is_granted) - print_granted(line, rname, master); - else if (next_is_convert) - print_convert(line, rname, master); - else if (next_is_waiting) - print_waiting(line, rname, master); - } - } - - fclose(file); -} - -int main(int argc, char **argv) -{ - prog_name = argv[0]; - decode_arguments(argc, argv); - /* check_name(lsname); */ - - switch (operation) { - case OP_JOIN: - do_join(lsname); - break; - - case OP_LEAVE: - do_leave(lsname); - break; - - case OP_SPACES: - do_spaces(); - break; - - case OP_LOCKDUMP: - case OP_LOCKDEBUG: - do_lockdump(lsname); - break; - } - - return 0; -} - diff --git a/doc/min-gfs.txt b/doc/min-gfs.txt deleted file mode 100644 index c7ea8d0..0000000 --- a/doc/min-gfs.txt +++ /dev/null @@ -1,159 +0,0 @@ - -Minimum GFS HowTo ------------------ - -The following gfs configuration requires a minimum amount of hardware and -no expensive storage system. It's the cheapest and quickest way to "play" -with gfs. - - - ---------- ---------- - | GNBD | | GNBD | - | client | | client | <-- these nodes use gfs - | node2 | | node3 | - ---------- ---------- - | | - ------------------ IP network - | - ---------- - | GNBD | - | server | <-- this node doesn't use gfs - | node1 | - ---------- - -- There are three machines to use with hostnames: node1, node2, node3 - -- node1 has an extra disk /dev/sda1 to use for gfs - (this could be hda1 or an lvm LV or an md device) - -- node1 will use gnbd to export this disk to node2 and node3 - -- Node1 cannot use gfs, it only acts as a gnbd server. - (Node1 will /not/ actually be part of the cluster since it is only - running the gnbd server.) - -- Only node2 and node3 will be in the cluster and use gfs. - (A two-node cluster is a special case for cman, noted in the config below.) - -- There's not much point to using clvm in this setup so it's left out. - -- Download the "cluster" source tree. - -- Build and install from the cluster source tree. (The kernel components - are not required on node1 which will only need the gnbd_serv program.) - - cd cluster - ./configure --kernel_src=/path/to/kernel - make; make install - -- Create /etc/cluster/cluster.conf on node2 with the following contents: - -<?xml version="1.0"?> -<cluster name="gamma" config_version="1"> - -<cman two_node="1" expected_votes="1"> -</cman> - -<clusternodes> -<clusternode name="node2"> - <fence> - <method name="single"> - <device name="gnbd" ipaddr="node2"/> - </method> - </fence> -</clusternode> - -<clusternode name="node3"> - <fence> - <method name="single"> - <device name="gnbd" ipaddr="node3"/> - </method> - </fence> -</clusternode> -</clusternodes> - -<fencedevices> - <fencedevice name="gnbd" agent="fence_gnbd" servers="node1"/> -</fencedevices> - -</cluster> - - -- load kernel modules on nodes - -node2 and node3> modprobe gnbd -node2 and node3> modprobe gfs -node2 and node3> modprobe lock_dlm - -- run the following commands - -node1> gnbd_serv -n -node1> gnbd_export -c -d /dev/sda1 -e global_disk - -node2 and node3> gnbd_import -i node1 -node2 and node3> ccsd -node2 and node3> cman_tool join -node2 and node3> fence_tool join - -node2> gfs_mkfs -p lock_dlm -t gamma:gfs1 -j 2 /dev/gnbd/global_disk - -node2 and node3> mount -t gfs /dev/gnbd/global_disk /mnt - -- the end, you now have a gfs file system mounted on node2 and node3 - - -Appendix A ----------- - -To use manual fencing instead of gnbd fencing, the cluster.conf file -would look like this: - -<?xml version="1.0"?> -<cluster name="gamma" config_version="1"> - -<cman two_node="1" expected_votes="1"> -</cman> - -<clusternodes> -<clusternode name="node2"> - <fence> - <method name="single"> - <device name="manual" ipaddr="node2"/> - </method> - </fence> -</clusternode> - -<clusternode name="node3"> - <fence> - <method name="single"> - <device name="manual" ipaddr="node3"/> - </method> - </fence> -</clusternode> -</clusternodes> - -<fencedevices> - <fencedevice name="manual" agent="fence_manual"/> -</fencedevices> - -</cluster> - - -FAQ ---- - -- Why can't node3 use gfs, too? - -You might be able to make it work, but we recommend that you not try. -This software was not intended or designed to allow that kind of usage. - -- Isn't node3 a single point of failure? how do I avoid that? - -Yes it is. For the time being, there's no way to avoid that, apart from -not using gnbd, of course. Eventually, there will be a way to avoid this -using cluster mirroring. - -- More info from - http://sources.redhat.com/cluster/gnbd/gnbd_usage.txt - http://sources.redhat.com/cluster/doc/usage.txt - diff --git a/fence/Makefile b/fence/Makefile deleted file mode 100644 index 15c1f21..0000000 --- a/fence/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -all: copytobin - -copytobin: - cd agents && ${MAKE} copytobin - cd fence_node && ${MAKE} copytobin - cd fence_tool && ${MAKE} copytobin - cd fenced && ${MAKE} copytobin - -clean: - cd agents && ${MAKE} clean - cd bin && ${MAKE} clean - cd fence_node && ${MAKE} clean - cd fence_tool && ${MAKE} clean - cd fenced && ${MAKE} clean - -distclean: clean - rm -f make/defines.mk - -install: - cd bin && ${MAKE} install - cd man && ${MAKE} install - cd init.d && ${MAKE} install - -uninstall: - cd bin && ${MAKE} uninstall - cd man && ${MAKE} uninstall - cd init.d && ${MAKE} uninstall diff --git a/fence/agents/Makefile b/fence/agents/Makefile deleted file mode 100644 index 940da98..0000000 --- a/fence/agents/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################## -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -all: - cd lib && ${MAKE} all - cd apc && ${MAKE} all - cd apc_snmp && ${MAKE} all - cd rsa && ${MAKE} all - cd rsb && ${MAKE} all - cd bladecenter && ${MAKE} all - cd baytech && ${MAKE} all - cd brocade && ${MAKE} all - cd bullpap && ${MAKE} all - # cd cpint && ${MAKE} all - cd drac && ${MAKE} all - cd egenera && ${MAKE} all - # cd ibmblade && ${MAKE} all - cd ilo && ${MAKE} all - cd ipmilan && ${MAKE} all - cd lpar && ${MAKE} all - cd manual && ${MAKE} all - cd mcdata && ${MAKE} all - # cd rackswitch && ${MAKE} all - cd rps10 && ${MAKE} all - cd sanbox2 && ${MAKE} all - cd scsi && ${MAKE} all - cd vixel && ${MAKE} all - cd wti && ${MAKE} all - # cd xcat && ${MAKE} all - cd xvm && ${MAKE} all - # cd zvm && ${MAKE} all - -copytobin: - cd lib && ${MAKE} copytobin - cd apc && ${MAKE} copytobin - cd apc_snmp && ${MAKE} copytobin - cd rsa && ${MAKE} copytobin - cd rsb && ${MAKE} copytobin - cd bladecenter && ${MAKE} copytobin - cd baytech && ${MAKE} copytobin - cd brocade && ${MAKE} copytobin - cd bullpap && ${MAKE} copytobin - # cd cpint && ${MAKE} copytobin - cd drac && ${MAKE} copytobin - cd egenera && ${MAKE} copytobin - # cd ibmblade && ${MAKE} copytobin - cd ilo && ${MAKE} copytobin - cd ipmilan && ${MAKE} copytobin - cd lpar && ${MAKE} copytobin - cd manual && ${MAKE} copytobin - cd mcdata && ${MAKE} copytobin - # cd rackswitch && ${MAKE} copytobin - cd rps10 && ${MAKE} copytobin - cd sanbox2 && ${MAKE} copytobin - cd scsi && ${MAKE} copytobin - cd vixel && ${MAKE} copytobin - cd wti && ${MAKE} copytobin - # cd xcat && ${MAKE} copytobin - cd xvm && ${MAKE} copytobin - # cd zvm && ${MAKE} copytobin - -clean: - cd lib && ${MAKE} clean - cd apc && ${MAKE} clean - cd apc_snmp && ${MAKE} clean - cd rsa && ${MAKE} clean - cd rsb && ${MAKE} clean - cd bladecenter && ${MAKE} clean - cd baytech && ${MAKE} clean - cd brocade && ${MAKE} clean - cd bullpap && ${MAKE} clean - #cd cpint && ${MAKE} clean - cd drac && ${MAKE} clean - cd egenera && ${MAKE} clean - # cd ibmblade && ${MAKE} clean - cd ilo && ${MAKE} clean - cd ipmilan && ${MAKE} clean - cd lpar && ${MAKE} clean - cd manual && ${MAKE} clean - cd mcdata && ${MAKE} clean - # cd rackswitch && ${MAKE} clean - cd rps10 && ${MAKE} clean - cd sanbox2 && ${MAKE} clean - cd scsi && ${MAKE} clean - cd vixel && ${MAKE} clean - cd wti && ${MAKE} clean - # cd xcat && ${MAKE} clean - cd xvm && ${MAKE} clean - # cd zvm && ${MAKE} clean - diff --git a/fence/agents/apc/Makefile b/fence/agents/apc/Makefile deleted file mode 100644 index a80f12b..0000000 --- a/fence/agents/apc/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_apc.py -TARGET= fence_apc - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_apc: fence_apc.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/apc/README b/fence/agents/apc/README deleted file mode 100644 index 37adffb..0000000 --- a/fence/agents/apc/README +++ /dev/null @@ -1,47 +0,0 @@ -This is an snmp based fence agent for APC power switches to be used -with RHEL4 Red Hat Cluster Suite. - -The reasons to use this agent rather than the current fence_apc agent are: -1) This script has been tested with EVERY powerswitch that APC currently -makes. -2) It will work on many older models that are no longer supported by APC. -I have been told that it even works with the AP9200 switch. Older switches -usually don't do well with the fence_apc script. -3) This agent works with large power switches that have more than 8 outlets. -The fence_apc script will also, in the next update -- this script will work for you now. - -If feedback on this beta version of the agent is good, and if ganged switches -can be supported, then this agent may replace fence_apc. - -In order to use this agent, you will need to have net-snmp-utils installed -on every node in your cluster. net-snmp-utils is scheduled for inclusion -in the base RHEL distribution for Update 4, and is yummable in FC5. - -After net-snmp-utils is installed, there will be a directory named: -/usr/share/snmp/mibs/ - -Place the accompanying powernet369.mib file in this directory. - -To use the agent, cp the agent to the /sbin directory on every -cluster node. The interface for the fence_apc_snmp agent is identical to -the existing fence_apc agent, so if you are using APC for fencing in -your cluster, you *could* backup your current fence_apc agent, and -rename this agent from fence_apc_snmp to fence_apc, and it should just work. - -NOTE: The fence_apc_snmp agent does not yet support ganged or 'daisy-chained' -APC switches. - -If you would rather not copy over your fence_apc agent, you can still use -the fence_apc_snmp agent by dropping it into /sbin on every node, and then -defining a <fencedevice> in the cluster.conf file with agent="fence_apc_snmp" -as an attribute, and use it that way. Note, please, that the GUI does -not support this agent yet, and you will have to edit your cluster.conf -by hand and then propagate it yourself. If you need help with this, email -me on linux-cluster or at the address below. - -Big thanks to Nate Straz who laid the foundation for this agent. - -Please let me know how this agent works. ---Jim Parsons - jparsons@redhat.com - -Copyright (C) Red Hat, Inc. 2006 All rights reserved. diff --git a/fence/agents/apc/fence_apc.pl b/fence/agents/apc/fence_apc.pl deleted file mode 100755 index e2fdbd7..0000000 --- a/fence/agents/apc/fence_apc.pl +++ /dev/null @@ -1,474 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -# Change these if the text returned by your equipment is different. -# Test by running script with options -t -v and checking /tmp/apclog - -my $immediate = 'immediate'; # # Or 'delayed' - action string prefix on menu -my $masterswitch = 'masterswitch plus '; # 'Device Manager' option to choose -my $login_prompt = '/: /'; -my $cmd_prompt = '/> $/'; - -my $max_open_tries = 3; # How many telnet attempts to make. Because the - # APC can fail repeated login attempts, this number - # should be more than 1 -my $open_wait = 5; # Seconds to wait between each telnet attempt -my $telnet_timeout = 2; # Seconds to wait for matching telent response -my $debuglog = '/tmp/apclog';# Location of debugging log when in verbose mode -$opt_o = 'reboot'; # Default fence action. - -my $logged_in = 0; - -my $t = new Net::Telnet; - - - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of MasterSwitch\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -n <num> Outlet number to change: [<switch>:]<outlet> \n"; - print " -o <string> Action: Reboot (default), Off or On\n"; - print " -p <string> Login password\n"; - print " -q quiet mode\n"; - print " -T Test mode (cancels action)\n"; - print " -V version\n"; - print " -v Log to file /tmp/apclog\n"; - - exit 0; -} - -sub fail -{ - ($msg)=@_; - print $msg."\n" unless defined $opt_q; - - if (defined $t) - { - # make sure we don't get stuck in a loop due to errors - $t->errmode('return'); - - logout() if $logged_in; - $t->close(); - } - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - exit 0; -} - - -sub login -{ - for (my $i=0; $i<$max_open_tries; $i++) - { - $t->open($opt_a); - ($_) = $t->waitfor($login_prompt); - - # Expect 'User Name : ' - if (! /name/i) { - $t->close(); - sleep($open_wait); - next; - } - - $t->print($opt_l); - ($_) = $t->waitfor($login_prompt); - - # Expect 'Password : ' - if (! /password/i ) { - $t->close(); - sleep($open_wait); - next; - } - - # Send password - $t->print($opt_p); - - (my $dummy, $_) = $t->waitfor('/(>|(?i:user name|password)\s*:) /'); - if (/> /) - { - $logged_in = 1; - - # send newline to flush prompt - $t->print(""); - - return; - } - else - { - fail "invalid username or password"; - } - } - fail "failed: telnet failed: ". $t->errmsg."\n" -} - -# print_escape_char() -- utility subroutine for sending the 'Esc' character -sub print_escape_char -{ - # The APC menu uses "<esc>" to go 'up' menues. We must set - # the output_record_separator to "" so that "\n" is not printed - # after the "<esc>" character - - $ors=$t->output_record_separator; - $t->output_record_separator(""); - $t->print("\x1b"); # send escape - $t->output_record_separator("$ors"); -} - - -# Determine if the switch is a working state. Also check to make sure that -# the switch has been specified in the case that there are slave switches -# present. This assumes that we are at the main menu. -sub identify_switch -{ - - ($_) = $t->waitfor($cmd_prompt); - print_escape_char(); - - # determine what type of switch we are dealling with - ($_) = $t->waitfor($cmd_prompt); - if ( /Switched Rack PDU: Communication Established/i) - { - # No further test needed - } - elsif ( /MS plus 1 : Serial Communication Established/i ) - { - if ( defined $switchnum ) - { - $masterswitch = $masterswitch . $switchnum; - } - elsif ( /MS plus [^1] : Serial Communication Established/i ) - { - fail "multiple switches detected. 'switch' must be defined."; - } - else - { - $switchnum = 1; - } - } - else - { - fail "APC is in undetermined state" - } - - # send a newline to cause APC to reprint the menu - $t->print(""); -} - - -# Navigate through menus to the appropriate outlet control menu of the apc -# MasterSwitch and 79xx series switches. Uses multi-line (mostly) -# case-insensitive matches to recognise menus and works out what option number -# to select from each menu. -sub navigate -{ - # Limit the ammount of menu depths to 20. We should never be this deep - for(my $i=20; $i ; $i--) - { - # Get the new text from the menu - (($_) = $t->waitfor($cmd_prompt)) or next; - - # Identify next option - if ( - # "Control Console", "1- Device Manager" - /--\s*control console.*(\d+)\s*-\s*device manager/is || - - # - # APC MasterSwitch Menus - # - # "Device Manager", "1- MasterSwitch plus 1" - /--\s*device manager.*(\d+)\s*-\s*$masterswitch/is || - - # "Device Manager", "1- Cluster Node 0 ON" - /--\s*(?:device manager|$masterswitch).*(\d+)\s*-\s+Outlet\s+$switchnum:$opt_n\D[^\n]*\s(?-i:ON|OFF)*?\s/ism || - - # "MasterSwitch plus 1", "1- Outlet 1:1 Outlet #1 ON" - /--\s*$masterswitch.*(\d+)\s*-\s*Outlet\s+$switchnum:$opt_n\s[^\n]*\s(?-i:ON|OFF)*?\s/ism || - - # Administrator outlet control menu - /--\s*Outlet $switchnum:$opt_n\D.*(\d+)\s*-\s*outlet control\s*$switchnum:?$opt_n\D/ism || - - - # - # APC 79XX Menus - # - # "3- Outlet Control/Configuration" - /--\s*device manager.*(\d+)\s*-\s*Outlet Control/is || - - # "Device Manager", "1- Cluster Node 0 ON" - /--\s*Outlet Control.*\s+?(\d+)\s*-\s+[^\n\r]*\s*Outlet\s+$opt_n\D[^\n]*\s(?-i:ON|OFF)*?\s/ism || - - # Administrator Outlet Control menu - /--[^\n\r]*Outlet\s+$opt_n\D.*(\d+)\s*-\s*control\s*outlet\s+$opt_n\D/ism || - /--[^\n\r]*Outlet\s+$opt_n\D.*(\d+)\s*-\s*control\s*outlet/ism - ) { - $t->print($1); - next; - } - - if (/.*Press ([^\n\r]+) to continue.*$/) { - $t->print(""); - next; - } - - # "Outlet Control X:N", "4- Immediate Reboot" - if ( /(\d+)\s*-\s*$immediate $opt_o/i || - /--\s*Control Outlet\D.*(\d+)\s*-\s*Immediate\s*$opt_o/is ) { - $t->print($1); - last; - } - - fail "failed: unrecognised menu response\n"; - } -} - - -sub logout -{ - # send a newline to make sure that we refresh the menus - # ($t->waitfor() can hang otherwise) - $t->print(""); - - # Limit the ammount of menu depths to 20. We should never be this deep - for(my $i=20; $i ; $i--) - { - - # Get the new text from the menu - ($_) = $t->waitfor($cmd_prompt); - - if ( - # "Control Console", "4- Logout" - /--\s*control console.*(\d+)\s*-\s*Logout/is - ) { - $t->print($1); - last; - } - else - { - print_escape_char(); - next; - } - } -} - - -sub action -{ - # "Enter 'YES' to continue or <ENTER> to cancel : " - ($_) = $t->waitfor('/: /'); - if (! /$immediate $opt_o.*outlet $opt_n\s.*YES.*to continue/si ) { - fail "failed: unrecognised $opt_o response\n"; - } - - # Test mode? - $t->print($opt_T?'NO':'YES'); - - # "Success", "Press <ENTER> to continue..." - ($_) = $t->waitfor('/continue/'); - $t->print(''); - - if (defined $opt_T) { - logout(); - print "success: test outlet $opt_n $opt_o\n" unless defined $opt_q; - $t->close(); - - # Allow the APC some time to clean connection - # before next login. - sleep 1; - - exit 0; - } elsif ( /Success/i ) { - logout(); - print "success: outlet $opt_n $opt_o\n" unless defined $opt_q; - $t->close(); - - # Allow the APC some time to clean connection - # before next login. - sleep 1; - - exit 0; - } - - fail "failed: unrecognised action response\n"; -} - - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) - { - } - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - elsif ($name eq "login" ) - { - $opt_l = $val; - } - elsif ($name eq "option" ) - { - $opt_o = $val; - } - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "port" ) - { - $opt_n = $val; - } - elsif ($name eq "switch" ) - { - $switchnum = $val; - } - elsif ($name eq "test" ) - { - $opt_T = $val; - } - elsif ($name eq "verbose" ) - { - $opt_v = $val; - } - # Excess name/vals will fail - else - { - fail "parse error: unknown option "$opt""; - } - } -} - - -sub telnet_error -{ - if ($t->errmsg ne "pattern match timed-out") { - fail "failed: telnet returned: ".$t->errmsg."\n"; - } else { - $t->print(""); - } -} - - -### MAIN ####################################################### - -if (@ARGV > 0) { - getopts("a:hl:n:o:p:qTvV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - fail_usage "No '-n' flag specified." unless defined $opt_n; - fail_usage "No '-l' flag specified." unless defined $opt_l; - fail_usage "No '-p' flag specified." unless defined $opt_p; - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(Off|On|Reboot)$/i; - - if ( $opt_n =~ /(\d+):(\d+)/ ) { - $switchnum=($1); - $opt_n = ($2); - } -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $opt_a; - fail "failed: no plug number" unless defined $opt_n; - fail "failed: no login name" unless defined $opt_l; - fail "failed: no password" unless defined $opt_p; - fail "failed: unrecognised action: $opt_o" - unless $opt_o =~ /^(Off|On|Reboot)$/i; -} - -$t->timeout($telnet_timeout); -$t->input_log($debuglog) if $opt_v; -$t->errmode('return'); - -&login; - -&identify_switch; - -# Abort on failure beyond here -$t->errmode(&telnet_error); - -&navigate; -&action; - -exit 0; - - diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py deleted file mode 100755 index b98add3..0000000 --- a/fence/agents/apc/fence_apc.py +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -## The Following Agent Has Been Tested On: -## -## Model Firmware -## +---------------------------------------------+ -## AP7951 AOS v2.7.0, PDU APP v2.7.3 -## AP7941 AOS v3.5.7, PDU APP v3.5.6 -## AP9606 AOS v2.5.4, PDU APP v2.7.3 -## -## @note: ssh is very slow on AP79XX devices protocol (1) and -## cipher (des/blowfish) have to be defined -##### - -import sys, re, pexpect, exceptions -sys.path.append("/usr/lib/fence") -from fencing import * - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - result = "" - try: - conn.send("1\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - - version = 0 - admin = 0 - switch = 0; - - if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)): - switch = 1; - if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)): - if (0 == options.has_key("-s")): - fail_usage("Failed: You have to enter physical switch number") - else: - if (0 == options.has_key("-s")): - options["-s"] = 1 - - if (None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before)): - version = 2 - else: - version = 3 - - if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)): - admin = 0 - else: - admin = 1 - - if switch == 0: - if version == 2: - if admin == 0: - conn.send("2\r\n") - else: - conn.send("3\r\n") - else: - conn.send("2\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - conn.send("1\r\n") - else: - conn.send(options["-s"]+"\r\n") - - while 1 == conn.log_expect(options, [ options["-c"], "Press <ENTER>" ], SHELL_TIMEOUT): - result += conn.before - conn.send("\r\n") - result += conn.before - conn.send(chr(03)) - conn.log_expect(options, "- Logout", SHELL_TIMEOUT) - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - try: - status = re.compile("\s*"+options["-n"]+"-.*(ON|OFF)", re.IGNORECASE).search(result).group(1) - except AttributeError: - fail(EC_STATUS) - - return status.lower().strip() - -def set_power_status(conn, options): - action = { - 'on' : "1", - 'off': "2" - }[options["-o"]] - - try: - conn.send("1\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - - version = 0 - admin2 = 0 - admin3 = 0 - switch = 0 - - if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)): - switch = 1; - ## MasterSwitch has different schema for on/off actions - action = { - 'on' : "1", - 'off': "3" - }[options["-o"]] - if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)): - if (0 == options.has_key("-s")): - fail_usage("Failed: You have to enter physical switch number") - else: - if (0 == options.has_key("-s")): - options["-s"] = 1 - - if (None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before)): - version = 2 - else: - version = 3 - - if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)): - admin2 = 0 - else: - admin2 = 1 - - if switch == 0: - if version == 2: - if admin2 == 0: - conn.send("2\r\n") - else: - conn.send("3\r\n") - else: - conn.send("2\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - if (None == re.compile('.*2- Outlet Restriction.*', re.IGNORECASE | re.S).match(conn.before)): - admin3 = 0 - else: - admin3 = 1 - conn.send("1\r\n") - else: - conn.send(options["-s"] + "\r\n") - - while 1 == conn.log_expect(options, [ options["-c"], "Press <ENTER>" ], SHELL_TIMEOUT): - conn.send("\r\n") - conn.send(options["-n"]+"\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - - if switch == 0: - if admin2 == 1: - conn.send("1\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - if admin3 == 1: - conn.send("1\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - else: - conn.send("1\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - - conn.send(action+"\r\n") - conn.log_expect(options, "Enter 'YES' to continue or <ENTER> to cancel :", SHELL_TIMEOUT) - conn.send("YES\r\n") - conn.log_expect(options, "Press <ENTER> to continue...", SHELL_TIMEOUT) - conn.send("\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - conn.send(chr(03)) - conn.log_expect(options, "- Logout", SHELL_TIMEOUT) - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "secure", "port", "switch", "test" ] - - options = check_input(device_opt, process_input(device_opt)) - - ## - ## Fence agent specific defaults - ##### - options["ssh_options"] = "-1 -c blowfish" - - if 0 == options.has_key("-c"): - options["-c"] = "\n>" - - ## Support for -n [switch]:[plug] notation that was used before - if (-1 != options["-n"].find(":")): - (switch, plug) = options["-n"].split(":", 1) - options["-s"] = switch; - options["-n"] = plug; - - ## - ## Operate the fencing device - #### - conn = fence_login(options) - fence_action(conn, options, set_power_status, get_power_status) - - ## - ## Logout from system - ## - ## In some special unspecified cases it is possible that - ## connection will be closed before we run close(). This is not - ## a problem because everything is checked before. - ###### - try: - conn.sendline("4") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/apc/fence_apc_snmp.py b/fence/agents/apc/fence_apc_snmp.py deleted file mode 100755 index 9fd0c14..0000000 --- a/fence/agents/apc/fence_apc_snmp.py +++ /dev/null @@ -1,463 +0,0 @@ -#!/usr/bin/python - -############################################################################# -############################################################################# -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################# -## This APC Fence script uses snmp to control the APC power -## switch. This script requires that net-snmp-utils be installed -## on all nodes in the cluster, and that the powernet369.mib file be -## located in /usr/share/snmp/mibs/ -############################################################################# -############################################################################# - - - -import getopt, sys -import os -import datetime -import select -import signal -from glob import glob - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -POWER_ON="outletOn" -POWER_OFF="outletOff" -POWER_REBOOT="outletReboot" - - -# oid defining fence device -oid_sysObjectID = '.1.3.6.1.2.1.1.2.0' - - - -class SNMP: - def __init__(self, params): - self.hostname = params['ipaddr'] - self.udpport = params['udpport'] - self.community = params['community'] - - def get(self, oid): - args = ['/usr/bin/snmpget'] - args.append('-Oqn') - args.append('-v') - args.append('1') - args.append('-c') - args.append(self.community) - args.append('-m') - args.append('ALL') - args.append(self.hostname + ':' + self.udpport) - args.append(oid) - strr, code = execWithCaptureStatus("/usr/bin/snmpget", args) - if code: - raise Exception, 'snmpget failed' - l = strr.strip().split() - return l[0], ' '.join(l[1:]) - - def set_int(self, oid, value): - args = ['/usr/bin/snmpset'] - args.append('-Oqn') - args.append('-v') - args.append('1') - args.append('-c') - args.append(self.community) - args.append('-m') - args.append('ALL') - args.append(self.hostname + ':' + self.udpport) - args.append(oid) - args.append('i') - args.append(str(value)) - strr,code = execWithCaptureStatus("/usr/bin/snmpset", args) - if code: - raise Exception, 'snmpset failed' - - def walk(self, oid): - args = ['/usr/bin/snmpwalk'] - args.append('-Oqn') - args.append('-v') - args.append('1') - args.append('-c') - args.append(self.community) - args.append('-m') - args.append('ALL') - args.append(self.hostname + ':' + self.udpport) - args.append(oid) - strr,code = execWithCaptureStatus("/usr/bin/snmpwalk", args) - if code: - raise Exception, 'snmpwalk failed' - lines = strr.strip().splitlines() - ret = [] - for line in lines: - l = line.strip().split() - ret.append((l[0], ' '.join(l[1:]).strip('"'))) - return ret - - - -class FenceAgent: - - def __init__(self, params): - self.snmp = SNMP(params) - - def resolve_outlet(self): - raise Exception, 'resolve_outlet() not implemented' - - def status(self): - oid = self.status_oid % self.resolve_outlet() - dummy, stat = self.snmp.get(oid) - if stat == self.state_on: - return 'on' - elif stat == self.state_off: - return 'off' - else: - raise Exception, 'invalid status ' + stat - - def power_off(self): - oid = self.control_oid % self.resolve_outlet() - self.snmp.set_int(oid, self.turn_off) - - def power_on(self): - oid = self.control_oid % self.resolve_outlet() - self.snmp.set_int(oid, self.turn_on) - - - - - - - - -class MasterSwitch(FenceAgent): - - def __init__(self, params): - FenceAgent.__init__(self, params) - - self.status_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4.%s' - self.control_oid = '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%s' - self.outlet_table_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.2' - - self.state_on = '1' - self.state_off = '2' - - self.turn_on = '1' - self.turn_off = '2' - - self.port = params['port'] - - def resolve_outlet(self): - outlet = None - try: - outlet = str(int(self.port)) - except: - table = self.snmp.walk(self.outlet_table_oid) - for row in table: - if row[1] == self.port: - t = row[0].strip().split('.') - outlet = t[len(t)-1] - if outlet == None: - raise Exception, 'unable to resolve ' + self.port - else: - self.port = outlet - return outlet - - -class MasterSwitchPlus(FenceAgent): - def __init__(self, params): - FenceAgent.__init__(self, params) - - self.status_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.5.%s.1.%s' - self.control_oid = '.1.3.6.1.4.1.318.1.1.6.5.1.1.5.%s.1.%s' - self.outlet_table_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.4' - - self.state_on = '1' - self.state_off = '2' - - self.turn_on = '1' - self.turn_off = '3' - - try: - self.switch = params['switch'] - except: - self.switch = '' - self.port = params['port'] - - def resolve_outlet(self): - switch = None - outlet = None - try: - switch = str(int(self.switch)) - outlet = str(int(self.port)) - except: - table = self.snmp.walk(self.outlet_table_oid) - for row in table: - if row[1] == self.port: - t = row[0].strip().split('.') - outlet = t[len(t)-1] - switch = t[len(t)-3] - if outlet == None: - raise Exception, 'unable to resolve ' + self.port - else: - self.switch = switch - self.port = outlet - return (switch, outlet) - - - - - - -def usage(): - print "Usage:" - print "" - print "Options:" - print " -h Usage" - print " -a <ip> IP address or hostname of fence device" - print " -u <udpport> UDP port to use (default 161)" - print " -c <community> SNMP community (default 'private')" - print " -n <num> Outlet name/number to act on" - print " -o <string> Action: Reboot (default), On, Off and Status" - print " -v Verbose mode - write to /tmp/apclog" - print " -V Version" - - sys.exit(0) - - - -file_log = None -def set_logging(verbose): - global file_log - if verbose: - file_log = open('/tmp/apclog', 'a') - file_log.write('\n----------- ') - file_log.write(datetime.datetime.today().ctime()) - file_log.write(' -----------\n') -def log(msg, error=False): - global file_log - if msg.rfind('\n') != len(msg)-1: - msg += '\n' - if file_log != None: - file_log.write(msg) - if error: - o = sys.stderr - else: - o = sys.stdout - o.write(msg) - - - -def main(): - try: - main2() - return 0 - except Exception, e: - log(str(e), True) - sys.exit(1) -def main2(): - - agents_dir = {'.1.3.6.1.4.1.318.1.3.4.5' : MasterSwitch, - '.1.3.6.1.4.1.318.1.3.4.4' : MasterSwitchPlus} - - verbose = False - params = {} - - if len(sys.argv) > 1: - try: - opts, args = getopt.getopt(sys.argv[1:], "ha:u:c:n:o:vV", ["help", "output="]) - except getopt.GetoptError: - usage() - sys.exit(2) - - for o, a in opts: - o = o.strip() - a = a.strip() - if o == "-v": - verbose = True - if o == "-V": - print "%s\n" % FENCE_RELEASE_NAME - print "%s\n" % REDHAT_COPYRIGHT - print "%s\n" % BUILD_DATE - sys.exit(0) - if o in ("-h", "--help"): - usage() - sys.exit(0) - if o == "-a": - params['ipaddr'] = a - if o == "-u": - params['udpport'] = a - if o == "-c": - params['community'] = a - if o == "-n": - switch = '' - port = a - if ':' in port: - idx = port.find(':') - switch = port[:idx] - port = port[idx+1:] - params['switch'] = switch - params['port'] = port - if o == "-o": - params['option'] = a.lower() - - else: #Get opts from stdin - for line in sys.stdin: - val = line.strip().split("=") - if len(val) == 2: - o = val[0].strip().lower() - a = val[1].strip() - if o == 'verbose': - if a.lower() == 'on' or a.lower() == 'true' or a == '1': - verbose = True - else: - params[o] = a - - - set_logging(verbose) - - - ### validation ### - - try: - if params['ipaddr'] == '': - raise Exception, 'missing ipadddr' - except: - log("FENCE: Missing ipaddr param for fence_apc_snmp...exiting", True) - sys.exit(1) - if 'udpport' not in params: - params['udpport'] = '161' - try: - t = int(params['udpport']) - if t >= 65536 or t < 0: - raise Exception, 'invalid udpport' - except: - log("FENCE: Invalid udpport for fence_apc_snmp...exiting", True) - sys.exit(1) - if 'community' not in params: - params['community'] = 'private' - try: - port = params['port'] - if len(port) == 0: - raise Exception, 'missing port' - except: - log("FENCE: Missing port param for fence_apc_snmp...exiting", True) - sys.exit(1) - if 'switch' not in params: - params['switch'] = '' - try: - act = params['option'].lower() - if act in ['on', 'off', 'reboot', 'status']: - params['option'] = act - else: - usage() - sys.exit(3) - except: - params['option'] = 'reboot' - - ### End of validation ### - - if verbose: - log('called with ' + str(params)) - - agent = None - dummy, sys_id = SNMP(params).get(oid_sysObjectID) - if sys_id not in agents_dir: - log('Fence device with 'oid_sysObjectID=' + sys_id + '' is not supported', True) - sys.exit(1) - agent = agents_dir[sys_id](params) - - if params['option'] == 'status': - log('Outlet "%s" - %s is %s' % (params['port'], - str(agent.resolve_outlet()), - agent.status())) - elif params['option'] == 'on': - agent.power_on() - if agent.status() != 'on': - raise Exception, 'Error turning outlet on' - elif params['option'] == 'off': - agent.power_off() - if agent.status() != 'off': - raise Exception, 'Error turning outlet off' - elif params['option'] == 'reboot': - agent.power_off() - if agent.status() != 'off': - raise Exception, 'Error turning outlet off' - agent.power_on() - if agent.status() != 'on': - raise Exception, 'Error turning outlet on' - else: - print 'nothing to do' - sys.exit(1) - pass - - - -def execWithCaptureStatus(command, argv, searchPath = 0, root = '/', stdin = 0, - catchfd = 1, closefd = -1): - - if not os.access (root + command, os.X_OK): - raise Exception, command + " cannot be run" - - (read, write) = os.pipe() - - childpid = os.fork() - if (not childpid): - if (root and root != '/'): os.chroot (root) - if isinstance(catchfd, tuple): - for fd in catchfd: - os.dup2(write, fd) - else: - os.dup2(write, catchfd) - os.close(write) - os.close(read) - - if closefd != -1: - os.close(closefd) - - if stdin: - os.dup2(stdin, 0) - os.close(stdin) - - if (searchPath): - os.execvp(command, argv) - else: - os.execv(command, argv) - - sys.exit(1) - - os.close(write) - - rc = "" - s = "1" - while (s): - select.select([read], [], []) - s = os.read(read, 1000) - rc = rc + s - - os.close(read) - - try: - (pid, status) = os.waitpid(childpid, 0) - except OSError, (errno, msg): - print __name__, "waitpid:", msg - - if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0): - status = os.WEXITSTATUS(status) - else: - status = -1 - - return (rc, status) - -if __name__ == "__main__": - ret = main() - sys.exit(ret) diff --git a/fence/agents/apc/powernet369.mib b/fence/agents/apc/powernet369.mib deleted file mode 100644 index ab948f8..0000000 --- a/fence/agents/apc/powernet369.mib +++ /dev/null @@ -1,31109 +0,0 @@ --- ************************************************************************* --- AMERICAN POWER CONVERSION PowerNet-MIB --- ************************************************************************* --- Copyright (c) 2005 American Power Conversion, Inc. --- PowerNet is a Trademark of American Power Conversion Corp. --- --- Title: APC TOP LEVEL PowerNet MIB --- --- Version : 3.6.9 --- --- Generated by script: tomib.awk --- --- Input File: powernetPS.mib --- --- Created: Wednesday, January, 26, 2005 --- --- Revision History: --- ************************************************************************* - --- - v3.2.0 Added functionality for MasterSwitch Plus --- - v3.3.0 Added functionality for MX28B (dcDM3) and 3-phase UPS --- - v3.3.2 New traps for Symmetra PX UPS --- 07/15/01 - v3.4.0 Added transfer switch --- - v3.4.3 Added functionality for External and Integrated Environmental Monitor --- 06/14/02 - v3.4.4 Added dcmim2(Siemens) branch, Battery Manager(Reading) traps, and --- Psx Traps for PDU and RM-PDU and Netlock branch/traps --- 06/18/02 - v3.5.0a Sync Control Group support --- 08/06/02 - v3.5.0a Environmental Management System branch/traps --- 09/16/02 - v3.5.0b Fixed some odds/ends ... going to RM-PDU for MS additions --- 09/25/02 - v3.5.0c MS3 additions --- 11/05/02 - v3.5.0e More Environmental Management System/A-Link devices(ARU) --- 11/22/02 - v3.5.0g Added General APC device status OID --- 11/27/02 - v3.5.0h Wrapped up MS3 ((Controlled or Metered) Rack PDU) changes --- 12/26/02 - v3.5.1a Changed MS3 name again, Controlled to Switched Rack PDU --- 01/07/03 - v3.6.0a Added OIDs/Traps for UPS Switchable Outlet Groups. --- 01/09/03 - Adding the General APC device discovery OIDs (hidden) --- 01/28/03 - v3.6.0c Made some small trap pair fixes for Switched Rack PDU (MS3) --- 02/13/03 - v3.6.0d Mods from the review and some EMS fixes. --- Added OID for the new 20kVA Symmetra 3 Phase type. --- Added OIDs to upsAdvConfig for Symmetra type UPSs. --- Added upsDiagnostics branch OID for Symmetra module information. --- 04/05/03 - v3.6.2 Added OID for the new Smart-UPS 7500 and 10000 types. --- 06/04/03 - v3.6.3 Added OIDs/Traps for AirFM. --- 06/24/03 - v3.6.4 Moved some AirFM temps and humidities from system level to module level. --- 10/24/03 - v3.6.4a Added OIDs/Traps for xPDU. --- 10/27/03 - v3.6.4f Added AirPA OIDs. --- 11/03/03 - v3.6.4g Merge of 3.6.4e and 3.6.4f --- 11/07/03 - v3.6.4h Additional review corrections --- 12/01/03 - v3.6.5a Added group OIDs for Air FM. Added C & F OIDs for Air PA setpoint. --- 12/19/03 - v3.6.5b Review corrections. --- 02/23/04 - v3.6.5c Added Modbus to experimental and multiple CB(bank) rPDU support --- 05/05/04 - v3.6.6 Adding EMS status OID and trap for H/W issues, redefined duplicate --- trap #228 (to ARU Device config change) and minor clean-up --- 05/12/04 - v3.6.7a Added Air FM alarm status OIDs. --- 06/03/04 - v3.6.7b Added UPS Config for Simple Signal Shutdowns and Number of External --- batteries. Added Mute option to the UPS Config Audible Alarm. --- 07/12/04 - v3.6.7d Removed Air FM alarm status OIDs due to delay in release. --- 07/14/04 - v3.6.7d Added a detailed description to the UPSAdvConfigAlarm OID --- 07/14/04 - v3.6.7e Added Custom Event traps --- 08/04/04 - v3.6.7 Tag for final builds, see v3.6.7 beta build notes for changes --- 08/26/04 - v3.6.8a Added new traps for UPS internal over temperature fault and cleared. --- 09/01/04 - v3.6.8b Adding new thresholds for EMS probe config & status --- 09/08/04 - v3.6.8c Corrections from MIB review. --- 09/30/04 - v3.6.8d Added new traps for AIS ^F Message events. --- 10/21/04 - v3.6.8e EMS. Added missing traps and new Rate functionality. --- 10/22/04 - v3.6.8f Added resetNetworkLeaveModeAndRestart option to the mcontrolRestartAgent OID. --- 10/28/04 - v3.6.8g Updated EMS sections from mib committee review. --- 11/22/04 - v3.6.8 Tag for final build. --- 12/02/04 - v3.6.9a Added OIDs and traps for BMS-HVA. --- 12/20/04 - v3.6.9c corrections to xPDU. --- 12/20/04 - v3.6.9c added OIDs and traps for xATS. --- 01/03/05 - v3.6.9d removed traps for xATS. --- 01/03/05 - v3.6.9e correction to xATS entries, that removed underscores (mib browser incompatibility) --- 01/07/05 - v3.6.9f --- 01/14/05 - v3.6.9g add xPDU OIDs and traps and some corrections. --- 01/14/05 - v3.6.9g modifications to xATS OIDs and traps. - --- ************************************************************************* --- ************************************************************************* --- PowerNet-MIB { iso org(3) dod(6) internet(1) private(4) --- enterprises(1) apc(318) } - -PowerNet-MIB DEFINITIONS ::= BEGIN - -IMPORTS - enterprises, IpAddress, Gauge, TimeTicks FROM RFC1155-SMI - DisplayString FROM RFC1213-MIB - OBJECT-TYPE FROM RFC-1212 - TRAP-TYPE FROM RFC-1215; - -apc OBJECT IDENTIFIER ::= { enterprises 318 } - -products OBJECT IDENTIFIER ::= { apc 1 } -apcmgmt OBJECT IDENTIFIER ::= { apc 2 } - -hardware OBJECT IDENTIFIER ::= { products 1 } -software OBJECT IDENTIFIER ::= { products 2 } -system OBJECT IDENTIFIER ::= { products 3 } -experimental OBJECT IDENTIFIER ::= { products 4 } - -mconfig OBJECT IDENTIFIER ::= { apcmgmt 1 } -mcontrol OBJECT IDENTIFIER ::= { apcmgmt 2 } -mtrapargs OBJECT IDENTIFIER ::= { apcmgmt 3 } -mfiletransfer OBJECT IDENTIFIER ::= { apcmgmt 4 } - -mconfigClock OBJECT IDENTIFIER ::= { mconfig 6 } - -mfiletransferStatus OBJECT IDENTIFIER ::= { mfiletransfer 1 } -mfiletransferConfig OBJECT IDENTIFIER ::= { mfiletransfer 2 } -mfiletransferControl OBJECT IDENTIFIER ::= { mfiletransfer 3 } - -mfiletransferConfigSettings OBJECT IDENTIFIER ::= { mfiletransferConfig 1 } -mfiletransferConfigTFTP OBJECT IDENTIFIER ::= { mfiletransferConfig 2 } -mfiletransferConfigFTP OBJECT IDENTIFIER ::= { mfiletransferConfig 3 } - -ups OBJECT IDENTIFIER ::= { hardware 1 } -measureUps OBJECT IDENTIFIER ::= { hardware 2 } -miniSNMPadapter OBJECT IDENTIFIER ::= { hardware 3 } -masterswitch OBJECT IDENTIFIER ::= { hardware 4 } -masterswitchVM OBJECT IDENTIFIER ::= { hardware 5 } -masterswitchMSP OBJECT IDENTIFIER ::= { hardware 6 } -dcDM3 OBJECT IDENTIFIER ::= { hardware 7 } -automaticTransferSwitch OBJECT IDENTIFIER ::= { hardware 8 } -dc2 OBJECT IDENTIFIER ::= { hardware 9 } -environmentalMonitor OBJECT IDENTIFIER ::= { hardware 10 } -netlock OBJECT IDENTIFIER ::= { hardware 11 } -rPDU OBJECT IDENTIFIER ::= { hardware 12 } -airConditioners OBJECT IDENTIFIER ::= { hardware 13 } -rARU OBJECT IDENTIFIER ::= { hardware 14 } -xPDU OBJECT IDENTIFIER ::= { hardware 15 } -battMan OBJECT IDENTIFIER ::= { hardware 16 } -xATS OBJECT IDENTIFIER ::= { hardware 17 } -generator OBJECT IDENTIFIER ::= { hardware 18 } - -powerNetSubAgent OBJECT IDENTIFIER ::= { software 1 } - -powerNetSoftwareSystem OBJECT IDENTIFIER ::= { powerNetSubAgent 1 } -powerNetSoftwareConfig OBJECT IDENTIFIER ::= { powerNetSubAgent 2 } - -backUPS OBJECT IDENTIFIER ::= { system 1 } -smartUPS OBJECT IDENTIFIER ::= { system 2 } -matrixUPS OBJECT IDENTIFIER ::= { system 3 } -masterSwitch OBJECT IDENTIFIER ::= { system 4 } -symmetraUPS OBJECT IDENTIFIER ::= { system 5 } -dp100E OBJECT IDENTIFIER ::= { system 6 } -dp300E OBJECT IDENTIFIER ::= { system 7 } -monitors OBJECT IDENTIFIER ::= { system 8 } -redundantSwitch OBJECT IDENTIFIER ::= { system 9 } -dcPower OBJECT IDENTIFIER ::= { system 10 } -automaticXferSwitch OBJECT IDENTIFIER ::= { system 11 } -netLock OBJECT IDENTIFIER ::= { system 12 } -symmetra3PhaseUPS OBJECT IDENTIFIER ::= { system 13 } -networkAir OBJECT IDENTIFIER ::= { system 14 } -infraXurePDU OBJECT IDENTIFIER ::= { system 15 } -ais5000UPS OBJECT IDENTIFIER ::= { system 16 } -smartUPS3Phase OBJECT IDENTIFIER ::= { system 17 } -battManager OBJECT IDENTIFIER ::= { system 18 } -infraXureATS OBJECT IDENTIFIER ::= { system 19 } - -battManIdent OBJECT IDENTIFIER ::= { battMan 1 } -battManSystemCalib OBJECT IDENTIFIER ::= { battMan 2 } -battManUnitCalib OBJECT IDENTIFIER ::= { battMan 3 } -battManStringCalib OBJECT IDENTIFIER ::= { battMan 4 } -battManBatteryCalib OBJECT IDENTIFIER ::= { battMan 5 } -battManConfig OBJECT IDENTIFIER ::= { battMan 6 } -battManAlarm OBJECT IDENTIFIER ::= { battMan 7 } -battManSystemStatus OBJECT IDENTIFIER ::= { battMan 8 } -battManStringStatus OBJECT IDENTIFIER ::= { battMan 9 } -battManBatteryStatus OBJECT IDENTIFIER ::= { battMan 10 } -battManInputContactStatus OBJECT IDENTIFIER ::= { battMan 11 } -battManControl OBJECT IDENTIFIER ::= { battMan 12 } -battManTestResults OBJECT IDENTIFIER ::= { battMan 13 } - -xPDUIdent OBJECT IDENTIFIER ::= { xPDU 1 } -xPDUDevice OBJECT IDENTIFIER ::= { xPDU 2 } -xPDUACMonitoringPoint OBJECT IDENTIFIER ::= { xPDU 3 } -xPDUCircuitBreakers OBJECT IDENTIFIER ::= { xPDU 4 } -xPDUInputContacts OBJECT IDENTIFIER ::= { xPDU 5 } -xPDUOutputRelays OBJECT IDENTIFIER ::= { xPDU 6 } -xPDUMiscGroup OBJECT IDENTIFIER ::= { xPDU 7 } - -xPDUMainInput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 1 } -xPDUBypassInput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 2 } -xPDUUPSInput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 3 } -xPDUSystemOutput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 4 } -xPDUGroundMonitorPoint OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 5 } - -xPDUSystemBreakers OBJECT IDENTIFIER ::= { xPDUCircuitBreakers 1 } -xPDUBranchBreakers OBJECT IDENTIFIER ::= { xPDUCircuitBreakers 2 } - -xATSIdent OBJECT IDENTIFIER ::= { xATS 1 } -xATSDevice OBJECT IDENTIFIER ::= { xATS 2 } -xATSSwitch OBJECT IDENTIFIER ::= { xATS 3 } -xATSACMonitoringPoint OBJECT IDENTIFIER ::= { xATS 4 } -xATSTesting OBJECT IDENTIFIER ::= { xATS 5 } -xATSInputContacts OBJECT IDENTIFIER ::= { xATS 6 } -xATSOutputRelays OBJECT IDENTIFIER ::= { xATS 7 } -xATSMisc OBJECT IDENTIFIER ::= { xATS 8 } - -xATSSwitchStatus OBJECT IDENTIFIER ::= { xATSSwitch 1 } -xATSSwitchSettings OBJECT IDENTIFIER ::= { xATSSwitch 2 } -xATSSwitchTimers OBJECT IDENTIFIER ::= { xATSSwitch 3 } -xATSSwitchBlockMap OBJECT IDENTIFIER ::= { xATSSwitch 4 } -xATSSwitchStatistics OBJECT IDENTIFIER ::= { xATSSwitch 5 } - -xATSSource1 OBJECT IDENTIFIER ::= { xATSACMonitoringPoint 1 } -xATSSource2 OBJECT IDENTIFIER ::= { xATSACMonitoringPoint 2 } -xATSSystemOutput OBJECT IDENTIFIER ::= { xATSACMonitoringPoint 3 } - -xATSTestingStatus OBJECT IDENTIFIER ::= { xATSTesting 1 } -xATSTestingResults OBJECT IDENTIFIER ::= { xATSTesting 2 } -xATSTestingSchedule OBJECT IDENTIFIER ::= { xATSTesting 3 } -xATSTestingSimulatePowerFail OBJECT IDENTIFIER ::= { xATSTesting 4 } - -xATSGenerator OBJECT IDENTIFIER ::= { generator 1 } - -xATSGeneratorIdent OBJECT IDENTIFIER ::= { xATSGenerator 1 } -xATSGeneratorStatus OBJECT IDENTIFIER ::= { xATSGenerator 2 } -xATSGeneratorAdvStatus OBJECT IDENTIFIER ::= { xATSGenerator 3 } -xATSGeneratorOutput OBJECT IDENTIFIER ::= { xATSGenerator 4 } -xATSGeneratorSettings OBJECT IDENTIFIER ::= { xATSGenerator 5 } -xATSGeneratorService OBJECT IDENTIFIER ::= { xATSGenerator 6 } -xATSGeneratorFuelSystem OBJECT IDENTIFIER ::= { xATSGenerator 7 } - - -smartUPS250 OBJECT IDENTIFIER ::= { smartUPS 1 } -smartUPS400 OBJECT IDENTIFIER ::= { smartUPS 2 } -smartUPS600 OBJECT IDENTIFIER ::= { smartUPS 3 } -smartUPS900 OBJECT IDENTIFIER ::= { smartUPS 4 } -smartUPS1250 OBJECT IDENTIFIER ::= { smartUPS 5 } -smartUPS2000 OBJECT IDENTIFIER ::= { smartUPS 6 } - -smartUPS450 OBJECT IDENTIFIER ::= { smartUPS 7 } -smartUPS700 OBJECT IDENTIFIER ::= { smartUPS 8 } -smartUPS1000 OBJECT IDENTIFIER ::= { smartUPS 9 } -smartUPS1400 OBJECT IDENTIFIER ::= { smartUPS 10 } -smartUPS2200 OBJECT IDENTIFIER ::= { smartUPS 11 } -smartUPS3000 OBJECT IDENTIFIER ::= { smartUPS 12 } -smartUPS5000 OBJECT IDENTIFIER ::= { smartUPS 13 } -smartUPS7500 OBJECT IDENTIFIER ::= { smartUPS 14 } -smartUPS10000 OBJECT IDENTIFIER ::= { smartUPS 15 } -smartUPS1500 OBJECT IDENTIFIER ::= { smartUPS 16 } - -matrixUPS3000 OBJECT IDENTIFIER ::= { matrixUPS 1 } -matrixUPS5000 OBJECT IDENTIFIER ::= { matrixUPS 2 } - -masterSwitchV1 OBJECT IDENTIFIER ::= { masterSwitch 1} -masterSwitchV2 OBJECT IDENTIFIER ::= { masterSwitch 2} -masterSwitchVM OBJECT IDENTIFIER ::= { masterSwitch 3} -masterSwitchMSP OBJECT IDENTIFIER ::= { masterSwitch 4} -masterSwitchrPDU OBJECT IDENTIFIER ::= { masterSwitch 5} - -symmetraUPS4kVA OBJECT IDENTIFIER ::= { symmetraUPS 1 } -symmetraUPS8kVA OBJECT IDENTIFIER ::= { symmetraUPS 2 } -symmetraUPS12kVA OBJECT IDENTIFIER ::= { symmetraUPS 3 } -symmetraUPS16kVA OBJECT IDENTIFIER ::= { symmetraUPS 4 } - -environmental OBJECT IDENTIFIER ::= { monitors 1 } -environmentalMgtSystem OBJECT IDENTIFIER ::= { monitors 2 } -emu2 OBJECT IDENTIFIER ::= { monitors 3 } - -dm3 OBJECT IDENTIFIER ::= { dcPower 1 } -dcmim2 OBJECT IDENTIFIER ::= { dcPower 2 } - -symmetra3PhaseUPS40kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 1 } -symmetra3PhaseUPS60kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 2 } -symmetra3PhaseUPS80kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 3 } -symmetra3PhaseUPS20kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 4 } - -airFMSeries OBJECT IDENTIFIER ::= { networkAir 1 } -rackAirRemovalUnit OBJECT IDENTIFIER ::= { networkAir 2 } -airPASeries OBJECT IDENTIFIER ::= { networkAir 3 } - -ais5000UPS10kVA OBJECT IDENTIFIER ::= { ais5000UPS 1 } -ais5000UPS20kVA OBJECT IDENTIFIER ::= { ais5000UPS 2 } -ais5000UPS30kVA OBJECT IDENTIFIER ::= { ais5000UPS 3 } -ais5000UPS40kVA OBJECT IDENTIFIER ::= { ais5000UPS 4 } -ais5000UPS60kVA OBJECT IDENTIFIER ::= { ais5000UPS 5 } -ais5000UPS80kVA OBJECT IDENTIFIER ::= { ais5000UPS 6 } -ais5000UPS100kVA OBJECT IDENTIFIER ::= { ais5000UPS 7 } - -smartUPS3Phase10kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 1 } -smartUPS3Phase15kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 2 } -smartUPS3Phase20kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 3 } -smartUPS3Phase30kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 4 } -smartUPS3Phase40kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 5 } - -upsIdent OBJECT IDENTIFIER ::= { ups 1 } -upsBattery OBJECT IDENTIFIER ::= { ups 2 } -upsInput OBJECT IDENTIFIER ::= { ups 3 } -upsOutput OBJECT IDENTIFIER ::= { ups 4 } -upsConfig OBJECT IDENTIFIER ::= { ups 5 } -upsControl OBJECT IDENTIFIER ::= { ups 6 } -upsTest OBJECT IDENTIFIER ::= { ups 7 } -upsComm OBJECT IDENTIFIER ::= { ups 8 } -upsPhase OBJECT IDENTIFIER ::= { ups 9 } -upsSyncCtrlGroup OBJECT IDENTIFIER ::= { ups 10 } -upsState OBJECT IDENTIFIER ::= { ups 11 } -upsOutletGroups OBJECT IDENTIFIER ::= { ups 12 } -upsDiagnostics OBJECT IDENTIFIER ::= { ups 13 } - -upsBasicIdent OBJECT IDENTIFIER ::= { upsIdent 1 } -upsAdvIdent OBJECT IDENTIFIER ::= { upsIdent 2 } - -upsBasicBattery OBJECT IDENTIFIER ::= { upsBattery 1 } -upsAdvBattery OBJECT IDENTIFIER ::= { upsBattery 2 } - -upsBasicInput OBJECT IDENTIFIER ::= { upsInput 1 } -upsAdvInput OBJECT IDENTIFIER ::= { upsInput 2 } - -upsBasicOutput OBJECT IDENTIFIER ::= { upsOutput 1 } -upsAdvOutput OBJECT IDENTIFIER ::= { upsOutput 2 } - -upsBasicConfig OBJECT IDENTIFIER ::= { upsConfig 1 } -upsAdvConfig OBJECT IDENTIFIER ::= { upsConfig 2 } - -upsBasicControl OBJECT IDENTIFIER ::= { upsControl 1 } -upsAdvControl OBJECT IDENTIFIER ::= { upsControl 2 } - -upsBasicTest OBJECT IDENTIFIER ::= { upsTest 1 } -upsAdvTest OBJECT IDENTIFIER ::= { upsTest 2 } - -upsPhaseResetValues OBJECT IDENTIFIER ::= { upsPhase 1 } -upsPhaseInput OBJECT IDENTIFIER ::= { upsPhase 2 } -upsPhaseOutput OBJECT IDENTIFIER ::= { upsPhase 3 } - -upsSyncCtrlGroupConfig OBJECT IDENTIFIER ::= { upsSyncCtrlGroup 1 } -upsSyncCtrlGroupStatus OBJECT IDENTIFIER ::= { upsSyncCtrlGroup 2 } - -upsBasicState OBJECT IDENTIFIER ::= { upsState 1 } -upsAdvState OBJECT IDENTIFIER ::= { upsState 2 } - -upsOutletGroupStatus OBJECT IDENTIFIER ::= { upsOutletGroups 1 } -upsOutletGroupConfig OBJECT IDENTIFIER ::= { upsOutletGroups 2 } -upsOutletGroupControl OBJECT IDENTIFIER ::= { upsOutletGroups 3 } - -upsDiagnosticIM OBJECT IDENTIFIER ::= { upsDiagnostics 1 } -upsDiagnosticPowerModules OBJECT IDENTIFIER ::= { upsDiagnostics 2 } -upsDiagnosticBatteries OBJECT IDENTIFIER ::= { upsDiagnostics 3 } -upsDiagnosticSubsystem OBJECT IDENTIFIER ::= { upsDiagnostics 4 } -upsDiagnosticExternalDevices OBJECT IDENTIFIER ::= { upsDiagnostics 5 } -upsDiagnosticComBus OBJECT IDENTIFIER ::= { upsDiagnostics 6 } - -upsDiagSwitchGear OBJECT IDENTIFIER ::= { upsDiagnosticExternalDevices 1 } -upsDiagMCCBBox OBJECT IDENTIFIER ::= { upsDiagnosticExternalDevices 2 } -upsDiagTransformer OBJECT IDENTIFIER ::= { upsDiagnosticExternalDevices 3 } - -mUpsEnviron OBJECT IDENTIFIER ::= { measureUps 1 } -mUpsContact OBJECT IDENTIFIER ::= { measureUps 2 } - -serialPort OBJECT IDENTIFIER ::= { miniSNMPadapter 1} - -serialPort1 OBJECT IDENTIFIER ::= { serialPort 1} -serialPort2 OBJECT IDENTIFIER ::= { serialPort 2} - -serialPort2Config OBJECT IDENTIFIER ::= { serialPort2 1} -serialPort2Control OBJECT IDENTIFIER ::= { serialPort2 2} - -sPDUIdent OBJECT IDENTIFIER ::= { masterswitch 1 } -sPDUMasterControl OBJECT IDENTIFIER ::= { masterswitch 2 } -sPDUMasterConfig OBJECT IDENTIFIER ::= { masterswitch 3 } -sPDUOutletControl OBJECT IDENTIFIER ::= { masterswitch 4 } -sPDUOutletConfig OBJECT IDENTIFIER ::= { masterswitch 5 } - -sPDUIdentVM OBJECT IDENTIFIER ::= { masterswitchVM 1 } -sPDUMasterControlVM OBJECT IDENTIFIER ::= { masterswitchVM 2 } -sPDUMasterConfigVM OBJECT IDENTIFIER ::= { masterswitchVM 3 } -sPDUMasterStatusVM OBJECT IDENTIFIER ::= { masterswitchVM 4 } -sPDUOutletControlVM OBJECT IDENTIFIER ::= { masterswitchVM 5 } -sPDUOutletConfigVM OBJECT IDENTIFIER ::= { masterswitchVM 6 } -sPDUOutletStatusVM OBJECT IDENTIFIER ::= { masterswitchVM 7 } - -sPDUIdentMSP OBJECT IDENTIFIER ::= { masterswitchMSP 1 } -sPDUMasterControlMSP OBJECT IDENTIFIER ::= { masterswitchMSP 2 } -sPDUMasterConfigMSP OBJECT IDENTIFIER ::= { masterswitchMSP 3 } -sPDUMasterStatusMSP OBJECT IDENTIFIER ::= { masterswitchMSP 4 } -sPDUOutletControlMSP OBJECT IDENTIFIER ::= { masterswitchMSP 5 } -sPDUOutletConfigMSP OBJECT IDENTIFIER ::= { masterswitchMSP 6 } -sPDUOutletStatusMSP OBJECT IDENTIFIER ::= { masterswitchMSP 7 } - -sPDUOutletConfigMSPall OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 1 } -sPDUOutletConfigMSPgs OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 2 } -sPDUOutletConfigMSPannun OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 3 } -sPDUOutletConfigMSPmups OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 4 } - -rPDUIdent OBJECT IDENTIFIER ::= { rPDU 1 } -rPDULoad OBJECT IDENTIFIER ::= { rPDU 2 } -rPDUOutlet OBJECT IDENTIFIER ::= { rPDU 3 } -rPDUPowerSupply OBJECT IDENTIFIER ::= { rPDU 4 } - -rPDULoadDevice OBJECT IDENTIFIER ::= { rPDULoad 1 } -rPDULoadPhaseConfig OBJECT IDENTIFIER ::= { rPDULoad 2 } -rPDULoadStatus OBJECT IDENTIFIER ::= { rPDULoad 3 } -rPDULoadBankConfig OBJECT IDENTIFIER ::= { rPDULoad 4 } - -rPDUOutletDevice OBJECT IDENTIFIER ::= { rPDUOutlet 1 } -rPDUOutletPhase OBJECT IDENTIFIER ::= { rPDUOutlet 2 } -rPDUOutletControl OBJECT IDENTIFIER ::= { rPDUOutlet 3 } -rPDUOutletConfig OBJECT IDENTIFIER ::= { rPDUOutlet 4 } -rPDUOutletStatus OBJECT IDENTIFIER ::= { rPDUOutlet 5 } -rPDUOutletBank OBJECT IDENTIFIER ::= { rPDUOutlet 6 } - -rPDUPowerSupplyDevice OBJECT IDENTIFIER ::= { rPDUPowerSupply 1 } - -dm3Ident OBJECT IDENTIFIER ::= { dcDM3 1 } -dm3Config OBJECT IDENTIFIER ::= { dcDM3 2 } -dm3Status OBJECT IDENTIFIER ::= { dcDM3 3 } - -dm3IdentSystem OBJECT IDENTIFIER ::= { dm3Ident 1} - -dm3ConfigSystem OBJECT IDENTIFIER ::= { dm3Config 1 } -dm3ConfigLVD OBJECT IDENTIFIER ::= { dm3Config 2 } -dm3ConfigBattery OBJECT IDENTIFIER ::= { dm3Config 3 } -dm3ConfigPowerModules OBJECT IDENTIFIER ::= { dm3Config 4 } -dm3ConfigRelays OBJECT IDENTIFIER ::= { dm3Config 5 } -dm3ConfigDistribution OBJECT IDENTIFIER ::= { dm3Config 6 } - -dm3ConfigRectifier OBJECT IDENTIFIER ::= { dm3ConfigPowerModules 1 } -dm3ConfigConverter OBJECT IDENTIFIER ::= { dm3ConfigPowerModules 2 } - -dm3ConfigRectThresh OBJECT IDENTIFIER ::= { dm3ConfigRectifier 1 } -dm3ConfigRectAlarms OBJECT IDENTIFIER ::= { dm3ConfigRectifier 2 } - -dm3ConfigConvThresh OBJECT IDENTIFIER ::= { dm3ConfigConverter 1 } -dm3ConfigConvAlarms OBJECT IDENTIFIER ::= { dm3ConfigConverter 2 } - -dm3ConfigOutputRelays OBJECT IDENTIFIER ::= { dm3ConfigRelays 1 } -dm3ConfigInputRelays OBJECT IDENTIFIER ::= { dm3ConfigRelays 2 } - -dm3ConfigBreakers OBJECT IDENTIFIER ::= { dm3ConfigDistribution 1 } -dm3ConfigFuses OBJECT IDENTIFIER ::= { dm3ConfigDistribution 2 } - -dm3StatusSystem OBJECT IDENTIFIER ::= { dm3Status 1 } -dm3StatusAlarms OBJECT IDENTIFIER ::= { dm3Status 2 } -dm3StatusBattery OBJECT IDENTIFIER ::= { dm3Status 3 } -dm3StatusOEM OBJECT IDENTIFIER ::= { dm3Status 4 } -dm3StatusLVD OBJECT IDENTIFIER ::= { dm3Status 5 } -dm3StatusPowerModules OBJECT IDENTIFIER ::= { dm3Status 6 } -dm3StatusRelays OBJECT IDENTIFIER ::= { dm3Status 7 } -dm3StatusDistribution OBJECT IDENTIFIER ::= { dm3Status 8 } - -dm3StatusRectifier OBJECT IDENTIFIER ::= { dm3StatusPowerModules 1 } -dm3StatusConverter OBJECT IDENTIFIER ::= { dm3StatusPowerModules 2 } - -dm3StatusOutputRelays OBJECT IDENTIFIER ::= { dm3StatusRelays 1 } -dm3StatusInputRelays OBJECT IDENTIFIER ::= { dm3StatusRelays 2 } - -dm3StatusBreakers OBJECT IDENTIFIER ::= { dm3StatusDistribution 1 } -dm3StatusFuses OBJECT IDENTIFIER ::= { dm3StatusDistribution 2 } - -atsIdent OBJECT IDENTIFIER ::= { automaticTransferSwitch 1 } -atsCalibration OBJECT IDENTIFIER ::= { automaticTransferSwitch 2 } -atsControl OBJECT IDENTIFIER ::= { automaticTransferSwitch 3 } -atsConfig OBJECT IDENTIFIER ::= { automaticTransferSwitch 4 } -atsStatus OBJECT IDENTIFIER ::= { automaticTransferSwitch 5 } - -atsCalibrationInput OBJECT IDENTIFIER ::= { atsCalibration 1 } -atsCalibrationPowerSupply OBJECT IDENTIFIER ::= { atsCalibration 2 } -atsCalibrationOutput OBJECT IDENTIFIER ::= { atsCalibration 3 } - -atsStatusDeviceStatus OBJECT IDENTIFIER ::= { atsStatus 1 } -atsStatusResetValues OBJECT IDENTIFIER ::= { atsStatus 2 } -atsStatusInput OBJECT IDENTIFIER ::= { atsStatus 3 } -atsStatusOutput OBJECT IDENTIFIER ::= { atsStatus 4 } - -dcmim2Ident OBJECT IDENTIFIER ::= { dc2 1 } -dcmim2Control OBJECT IDENTIFIER ::= { dc2 2 } -dcmim2Config OBJECT IDENTIFIER ::= { dc2 3 } -dcmim2Status OBJECT IDENTIFIER ::= { dc2 4 } - -dcmim2IdentSystem OBJECT IDENTIFIER ::= { dcmim2Ident 1 } - -dcmim2ControlSystem OBJECT IDENTIFIER ::= { dcmim2Control 1 } - -dcmim2ConfigSystem OBJECT IDENTIFIER ::= { dcmim2Config 1 } -dcmim2ConfigBattery OBJECT IDENTIFIER ::= { dcmim2Config 2 } -dcmim2ConfigLVD OBJECT IDENTIFIER ::= { dcmim2Config 3 } - -dcmim2StatusSystem OBJECT IDENTIFIER ::= { dcmim2Status 1 } -dcmim2StatusRectifier OBJECT IDENTIFIER ::= { dcmim2Status 2 } -dcmim2StatusBattery OBJECT IDENTIFIER ::= { dcmim2Status 3 } -dcmim2StatusLVD OBJECT IDENTIFIER ::= { dcmim2Status 4 } -dcmim2StatusAlarms OBJECT IDENTIFIER ::= { dcmim2Status 5 } - -external OBJECT IDENTIFIER ::= { environmentalMonitor 1 } -integrated OBJECT IDENTIFIER ::= { environmentalMonitor 2 } -envMgtSystem OBJECT IDENTIFIER ::= { environmentalMonitor 3 } - -emIdent OBJECT IDENTIFIER ::= { external 1 } -emConfig OBJECT IDENTIFIER ::= { external 2 } -emStatus OBJECT IDENTIFIER ::= { external 3 } - -iemIdent OBJECT IDENTIFIER ::= { integrated 1 } -iemConfig OBJECT IDENTIFIER ::= { integrated 2 } -iemStatus OBJECT IDENTIFIER ::= { integrated 3 } - -emsIdent OBJECT IDENTIFIER ::= { envMgtSystem 1 } - -emsOutputRelayControl OBJECT IDENTIFIER ::= { envMgtSystem 2 } -emsOutletControl OBJECT IDENTIFIER ::= { envMgtSystem 3 } -emsSensorControl OBJECT IDENTIFIER ::= { envMgtSystem 4 } -emsAlarmDeviceControl OBJECT IDENTIFIER ::= { envMgtSystem 5 } - -emsConfig OBJECT IDENTIFIER ::= { envMgtSystem 6 } -emsProbeConfig OBJECT IDENTIFIER ::= { envMgtSystem 7 } -emsInputContactConfig OBJECT IDENTIFIER ::= { envMgtSystem 8 } -emsOutputRelayConfig OBJECT IDENTIFIER ::= { envMgtSystem 9 } -emsOutletConfig OBJECT IDENTIFIER ::= { envMgtSystem 10 } -emsSensorConfig OBJECT IDENTIFIER ::= { envMgtSystem 11 } - -emsStatus OBJECT IDENTIFIER ::= { envMgtSystem 12 } -emsProbeStatus OBJECT IDENTIFIER ::= { envMgtSystem 13 } -emsInputContactStatus OBJECT IDENTIFIER ::= { envMgtSystem 14 } -emsOutputRelayStatus OBJECT IDENTIFIER ::= { envMgtSystem 15 } -emsOutletStatus OBJECT IDENTIFIER ::= { envMgtSystem 16 } -emsAlarmDeviceStatus OBJECT IDENTIFIER ::= { envMgtSystem 17 } -emsSensorStatus OBJECT IDENTIFIER ::= { envMgtSystem 18 } - -nlIdent OBJECT IDENTIFIER ::= { netlock 1 } -nlStatus OBJECT IDENTIFIER ::= { netlock 2 } - -airFM OBJECT IDENTIFIER ::= { airConditioners 1 } -airFMIdent OBJECT IDENTIFIER ::= { airFM 1 } -airFMStatus OBJECT IDENTIFIER ::= { airFM 2 } -airFMGroup OBJECT IDENTIFIER ::= { airFM 3 } - -airPA OBJECT IDENTIFIER ::= { airConditioners 2 } -airPAIdent OBJECT IDENTIFIER ::= { airPA 1 } -airPAStatus OBJECT IDENTIFIER ::= { airPA 2 } - -rARUIdent OBJECT IDENTIFIER ::= { rARU 1 } -rARUConfig OBJECT IDENTIFIER ::= { rARU 2 } -rARUStatus OBJECT IDENTIFIER ::= { rARU 3 } - - --- object types - --- the products group --- the experimental group - - - --- the apcmgmt group --- the mconfig group - -mconfigNumTrapReceivers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of managers to send traps to." - ::= { mconfig 1 } - -mconfigTrapReceiverTable OBJECT-TYPE - SYNTAX SEQUENCE OF MconfigTrapReceiverEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of managers to send traps to. The number of - entries is given by the value of mconfigNumTrapReceivers. - Maximum number of Trap Receivers is four." - ::= { mconfig 2 } - -mconfigTrapReceiverEntry OBJECT-TYPE - SYNTAX MconfigTrapReceiverEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The managers to send traps to." - INDEX { trapIndex} - ::= { mconfigTrapReceiverTable 1 } - -MconfigTrapReceiverEntry ::= - SEQUENCE { - trapIndex - INTEGER, - receiverAddr - IpAddress, - communityString - DisplayString, - severity - INTEGER, - acceptThisReceiver - INTEGER, - receiveTrapType - INTEGER - } - -trapIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to a trap receiver entry." - ::= { mconfigTrapReceiverEntry 1 } - -receiverAddr OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP address of the manager to send a trap to." - ::= { mconfigTrapReceiverEntry 2 } - -communityString OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The community name to use in the trap when - sent to the manager." - ::= { mconfigTrapReceiverEntry 3 } - -severity OBJECT-TYPE - SYNTAX INTEGER { - information(1), - warning(2), - severe(3) - } - ACCESS read-only - STATUS obsolete - DESCRIPTION - "The severity threshold of traps to send to the manager. - traps are labeled in severity as informational(1), warning(2), - severe(3). Only traps of equal or greater severity than - this value are sent to the manager." - ::= { mconfigTrapReceiverEntry 4 } - -acceptThisReceiver OBJECT-TYPE - SYNTAX INTEGER { - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An entry will become active if yes, and will - be deleted if no." - ::= { mconfigTrapReceiverEntry 5 } - - -receiveTrapType OBJECT-TYPE - SYNTAX INTEGER { - powernet (1), - ietf (2), - both (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The node in this entry will receive traps defined in APC - PowerNet MIB, if this OID is set to yes." - ::= { mconfigTrapReceiverEntry 6 } - -mconfigBOOTPEnabled OBJECT-TYPE - SYNTAX INTEGER { - yes (1), - no (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The value of yes(1) indicates the PowerNet Adapter is configured to - obtain its IP configuration parameters from a BOOTP server. - - The value of no(2) indicates adapter will assume IP configuration parameters - values saved in adapter's eeprom, which was originally configured at local - console." - ::= { mconfig 3 } - -mconfigTFTPServerIP OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP address of TFTP server. If mconfigBOOTPEnabled is yes(1), then this IP address - is provided by BOOTP server and not allowed to be modified; otherwise, this IP address - can be modified. - - Before using TFTP to load new code image, the image file should be placed in proper - directory of the specified TFTP server. This OID is only supported by AP9605, AP9205, - and AP9603 PowerNet SNMP Adapters." - ::= { mconfig 4 } - -newCodeAuthentViaTFTP OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - validNewAgentCodeImage (2), - sameAgentCodeImage (3), - invalidAgentCodeImage (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Once mcontrolRestartAgent is set to loadAndExecuteNewAgent (3), PowerNet adapter will - start to load the remote image file, for authentication only, instead of saving the code - into flash memory. Only if a validNewAgentCodeImage (1) is found will the agent reboot - the PowerNet adapter and invoke the loader to load and save new code into the flash memory. - Otherwise, the current agent code will continue to run. - - This OID shows the result of the above authentication process. - validNewAgentCodeImage (1) means the code image on TFTP server - is a valid APC agent code and is different version from the current agent. - Once agent identifies this, loader will start to update flash memory with - the new agent code. - - sameAgentCodeImage (2) means the code image on TFTP server is exactly the - same as the currently running agent. Currently running agent will not invoke - loader to load the same again. - - invalidAgentCodeImage (3) means the code image on TFTP server is NOT a valid - APC agent code. Thus, current agent will not load it into the flash memory. - - The value of this OID will be associated with TRAP codeImageAuthentDone. - This OID is only supported by AP9605, AP9205, and AP9603 PowerNet SNMP Adapters." - - ::= { mconfig 5 } - -mconfigClockDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The current date in the mm/dd/yyyy format. Example: 01/01/2000." - ::= { mconfigClock 1 } - -mconfigClockTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The current time in the hh:mm:ss am/pm format. Example: 12:00:00 am." - ::= { mconfigClock 2 } - -mcontrolRestartAgent OBJECT-TYPE - SYNTAX INTEGER { - restartCurrentAgent (1), - continueCurrentAgent (2), - loadAndExecuteNewAgent (3), - restartWithoutAgent (4), - resetNetworkAndRestart (5), - resetNetworkLeaveModeAndRestart (6) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to restartCurrentAgent (1) will restart the same SNMP - agent code currently saved in flash memory. Setting this OID to - loadAndExecuteNewAgent (3) will enable adapter to load a new agent code - into the flash memory and start to execute this new agent code. - Bootp/tftp is the default protocol. loadAndExecuteNewAgent is only - supported by AP9605, AP9205, and AP9603 PowerNet SNMP Adapters. Setting - this OID to restartWithoutAgent (4) will restart the system and not - start the agent. The subsequent time the system restarts the agent will - also automatically restart. Setting this OID to - resetNetworkAndRestart (5) will set the Boot Mode, IP Address, Subnet - Mask, and Default Gateway to defaults, expire any existing DHCP lease - and then restart the system. Setting this OID to - resetNetworkLeaveModeAndRestart (6) will leave the Boot Mode at the - current setting, set the IP Address, Subnet Mask, and Default Gateway to - defaults, expire any existing DHCP lease and then restart the system." - - ::= { mcontrol 1 } - --- The mtrapargs group --- These OIDs allows APC traps to be sent with additional arguments --- which may not be defined in the APC MIB. - -mtrapargsInteger OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an integer argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 1 } - -mtrapargsIpAddress OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an IP address argument - that my not be defined in the APC MIB. - - A get of this OID will return 0.0.0.0." - ::= { mtrapargs 2 } - -mtrapargsString OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an octet string argument - that my not be defined in the APC MIB. - - A get of this OID will return a NULL string." - ::= { mtrapargs 3 } - -mtrapargsGauge OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a Gauge argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 4 } - -mtrapargsTimeTicks OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a TimeTicks argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 5 } - -mtrapargsInteger02 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an integer argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 6 } - -mtrapargsInteger03 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an integer argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 7 } - -mtrapargsIpAddress02 OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an IP address argument - that my not be defined in the APC MIB. - - A get of this OID will return 0.0.0.0." - ::= { mtrapargs 8 } - -mtrapargsIpAddress03 OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an IP address argument - that my not be defined in the APC MIB. - - A get of this OID will return 0.0.0.0." - ::= { mtrapargs 9 } - -mtrapargsString02 OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an octet string argument - that my not be defined in the APC MIB. - - A get of this OID will return a NULL string." - ::= { mtrapargs 10 } - -mtrapargsString03 OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an octet string argument - that my not be defined in the APC MIB. - - A get of this OID will return a NULL string." - ::= { mtrapargs 11 } - -mtrapargsGauge02 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a Gauge argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 12 } - -mtrapargsGauge03 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a Gauge argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 13 } - -mtrapargsTimeTicks02 OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a TimeTicks argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 14 } - -mtrapargsTimeTicks03 OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a TimeTicks argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 15 } - --- the mfiletransfer group --- the mfiletransferStatus group -mfiletransferStatusLastTransferResult OBJECT-TYPE - SYNTAX INTEGER { - lastFileTransferResultSuccessful (1), - lastFileTransferResultNotAvailable (2), - lastFileTransferResultFailureUnknown (3), - lastFileTransferResultFailureServerInaccessible (4), - lastFileTransferResultFailureServerAccessDenied (5), - lastFileTransferResultFailureFileNotFound (6), - lastFileTransferResultFailureFileTypeUnknown (7), - lastFileTransferResultFailureFileCorrupted (8) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Once mfiletransferControlInitiateFileTransfer is set to a value other than doNotInitiateFileTransfer - a file transfer of mfiletransferConfigSettingsFilename will be attempted from either a TFTP or FTP - server. - - This OID shows the last attempted file transfer result. - lastFileTransferResultSuccessful (1) means the file transfer was successful. - lastFileTransferResultNotAvailable (2) means that there have been no previous file transfers. - lastFileTransferResultFailureUnknown (3) means that the last file transfer failed for an unknown reason. - lastFileTransferResultFailureServerInaccessible (4) means that the TFTP or FTP server could not be found on the network. - lastFileTransferResultFailureServerAccessDenied (5) means that the TFTP or FTP server denied access. - lastFileTransferResultFailureFileNotFound (6) means that the file could not be located. - lastFileTransferResultFailureFileTypeUnknown (7) means the file was examined, but the contents were unknown. - lastFileTransferResultFailureFileCorrupt (8) means the transferred file was corrupt." - - ::= { mfiletransferStatus 1 } - --- the mfiletransferConfig group --- the mfiletransferConfigSettings group - -mfiletransferConfigSettingsFilename OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The path and name of the file to transfer using the mfiletransferControlInitiateFileTransfer OID. - If the file to transfer exists in the default server directory then the path may be omitted." - - ::= { mfiletransferConfigSettings 1 } - --- the mfiletransferConfigTFTP group - -mfiletransferConfigTFTPServerAddress OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP Address in dotted decimal notation of the TFTP server involved in the file transfer." - - ::= { mfiletransferConfigTFTP 1 } - --- the mfiletransferConfigFTP group - -mfiletransferConfigFTPServerAddress OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP Address in dotted decimal notation of the FTP server involved in the file transfer." - - ::= { mfiletransferConfigFTP 1 } - -mfiletransferConfigFTPServerUser OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The user identification for logging into the FTP server specified with mfiletransferConfigFTPServerAddress." - - ::= { mfiletransferConfigFTP 2 } - -mfiletransferConfigFTPServerPassword OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The password for logging into the FTP server specified with mfiletransferConfigFTPServerAddress." - - ::= { mfiletransferConfigFTP 3 } - --- the mfiletransferControl group - -mfiletransferControlInitiateFileTransfer OBJECT-TYPE - SYNTAX INTEGER { - doNotInitiateFileTransfer (1), - initiateFileTransferDownloadViaTFTP (2), - initiateFileTransferDownloadViaFTP (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to doNotInitiateFileTransfer (1) will do nothing. - - Setting this OID to initiateFileTransferDownloadViaTFTP (2) will attempt to transfer the file named in - mfiletransferConfigSettingsFilename from the TFTP Server identified in mfiletransferConfigTFTPAddress. - - Setting this OID to initiateFileTransferDownloadViaFTP (3) will attempt to transfer the file named in - mfiletransferConfigSettingsFilename from the FTP Server identified in mfiletransferConfigFTPAddress - using mfiletransferConfigFTPUser and mfiletransferConfigFTPPassword for the FTP Server login process." - - ::= { mfiletransferControl 1 } - --- the battManIdent group - -battManIdentProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the battery manager." - ::= { battManIdent 1 } - -battManIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager network interface hardware revision. - This value is set at the factory." - ::= { battManIdent 2 } - -battManIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager network interface firmware revision. - This value is set at the factory and can change with firmware update." - ::= { battManIdent 3 } - -battManIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date the battery manager was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { battManIdent 4 } - -battManIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager model number character string. - This value is set at the factory." - ::= { battManIdent 5 } - -battManIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager serial number character string. - This value is set at the factory." - ::= { battManIdent 6 } - --- the battManCalib group --- system calibration - -battManOhmicValueCorrectionFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The system ohmic value correction factor in percent." - ::= { battManSystemCalib 1 } - --- unit calibration - -battManUnitCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManUnitCalibTable." - ::= { battManUnitCalib 1 } - -battManUnitCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManUnitCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each unit in the system." - ::= { battManUnitCalib 2 } - -battManUnitCalibTableEntry OBJECT-TYPE - SYNTAX BattManUnitCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The unit to get data from." - INDEX { battManUnitCalibIndex } - ::= { battManUnitCalibTable 1 } - -BattManUnitCalibTableEntry ::= - SEQUENCE { - battManUnitCalibIndex INTEGER, - battManUnitSerialNumber DisplayString, - battManBatteryVoltageZeroCalib INTEGER, - battManBatteryVoltageSpanCalib INTEGER - } - -battManUnitCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of unit calibration entries in the table." - ::= { battManUnitCalibTableEntry 1 } - -battManUnitSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the unit." - ::= { battManUnitCalibTableEntry 2 } - -battManBatteryVoltageZeroCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The unit battery voltage zero calibration in millivolts." - ::= { battManUnitCalibTableEntry 3 } - -battManBatteryVoltageSpanCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The unit battery voltage span calibration in percent." - ::= { battManUnitCalibTableEntry 4 } - --- string calibration table - -battManStringCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManStringCalibTable." - ::= { battManStringCalib 1 } - -battManStringCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManStringCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each string in the system." - ::= { battManStringCalib 2 } - -battManStringCalibTableEntry OBJECT-TYPE - SYNTAX BattManStringCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManStringCalibIndex } - ::= { battManStringCalibTable 1 } - -BattManStringCalibTableEntry ::= - SEQUENCE { - battManStringCalibIndex INTEGER, - battManDCCurrentZeroCalib INTEGER, - battManACCurrentZeroCalib INTEGER, - battManProbeRange INTEGER - } - -battManStringCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string calibration entries in the table." - ::= { battManStringCalibTableEntry 1 } - -battManDCCurrentZeroCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The string DC current zero calibration in tenths of amps." - ::= { battManStringCalibTableEntry 2 } - -battManACCurrentZeroCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The string AC current zero calibration in tenths of amps." - ::= { battManStringCalibTableEntry 3 } - -battManProbeRange OBJECT-TYPE - SYNTAX INTEGER { - amps1000 (1), - amps500 (2), - amps100 (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The string probe range in amps." - ::= { battManStringCalibTableEntry 4 } - ---string 1 battery calibration table - -battManString1BatteryCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1BatteryCalibTable." - ::= { battManBatteryCalib 1 } - -battManString1BatteryCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each battery in String 1." - ::= { battManBatteryCalib 2 } - -battManString1BatteryCalibTableEntry OBJECT-TYPE - SYNTAX BattManString1BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1BatteryCalibIndex } - ::= { battManString1BatteryCalibTable 1 } - -BattManString1BatteryCalibTableEntry ::= - SEQUENCE { - battManString1BatteryCalibIndex INTEGER, - battManString1BatteryInterTierOhmicValue INTEGER - } - -battManString1BatteryCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of battery calibration entries in the table." - ::= { battManString1BatteryCalibTableEntry 1 } - -battManString1BatteryInterTierOhmicValue OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms. This corresponds to the ohmic - value for the positive terminal of the battery." - ::= { battManString1BatteryCalibTableEntry 2 } - ---string 2 battery calibration table - -battManString2BatteryCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2BatteryCalibTable." - ::= { battManBatteryCalib 3 } - -battManString2BatteryCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each battery in String 2." - ::= { battManBatteryCalib 4 } - -battManString2BatteryCalibTableEntry OBJECT-TYPE - SYNTAX BattManString2BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2BatteryCalibIndex } - ::= { battManString2BatteryCalibTable 1 } - -BattManString2BatteryCalibTableEntry ::= - SEQUENCE { - battManString2BatteryCalibIndex INTEGER, - battManString2BatteryInterTierOhmicValue INTEGER - } - -battManString2BatteryCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of battery calibration entries in the table." - ::= { battManString2BatteryCalibTableEntry 1 } - -battManString2BatteryInterTierOhmicValue OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms." - ::= { battManString2BatteryCalibTableEntry 2 } - --- the battManConfig group - -battManConfigApplication OBJECT-TYPE - SYNTAX INTEGER { - silcon (1), - other (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The type of application the battery manager is installed on: - Silcon(1) Silcon UPS or - Other(2) Other UPS/Charger." - ::= { battManConfig 1 } - -battManConfigBatteryChemistry OBJECT-TYPE - SYNTAX INTEGER { - leadAcid (1), - nickel-Cadmium (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The battery chemistry of the monitored batteries: - LeadAcid(1) Lead Acid or - Nickel-Cadmium(2) Nickel-Cadmium." - ::= { battManConfig 2 } - -battManConfigBatteryAHCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amp hour capacity of the monitored batteries 5-2000 AH." - ::= { battManConfig 3 } - -battManConfigNumberofStrings OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of strings in the battery manager system (1 - 2 Silcon)/(1 Other)." - ::= { battManConfig 4 } - -battManConfigBatteriesperString OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of batteries per string." - ::= { battManConfig 5 } - -battManConfigCellsperBattery OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of cells per battery (1 - 6 for lead-acid, 1 - 2 for NiCd." - ::= { battManConfig 6 } - -battManConfigMinCellVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum battery cell voltage alarm limit in millivolts DC." - ::= { battManConfig 7 } - -battManConfigMaxCellVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum battery cell voltage alarm limit in millivolts DC." - ::= { battManConfig 8 } - -battManConfigMaxPilotTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum pilot battery temperature alarm limit in tenths of degrees Fahrenheit." - ::= { battManConfig 9 } - -battManConfigMaxPilotTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum pilot battery temperature alarm limit in tenths of degrees Celcius." - ::= { battManConfig 10 } - -battManConfigMaxAmbientTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum ambient temperature alarm limit in tenths of degrees Fahrenheit." - ::= { battManConfig 11 } - -battManConfigMaxAmbientTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum ambient temperature alarm limit in tenths of degrees Celcius." - ::= { battManConfig 12 } - -battManConfigMinAmbientTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The Minimum Ambient Temperature alarm limit in tenths of degrees Fahrenheit." - ::= { battManConfig 13 } - -battManConfigMinAmbientTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The Minimum Ambient Temperature alarm limit in tenths of degrees Celcius." - ::= { battManConfig 14 } - -battManConfigMaxRippleCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum ripple current alarm limit for the monitored battery - strings in percent of AH capacity." - ::= { battManConfig 15 } - -battManConfigMaxCurrentAcceptanceDeviation OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum current acceptance deviation alarm limit in percentage." - ::= { battManConfig 16 } - -battManConfigMonitorWireLength OBJECT-TYPE - SYNTAX INTEGER { - fiftyFeetOrLess (1), - moreThanFiftyFeet (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The monitor wire length: - fiftyFeetOrLess (1) indicates that the wire length is less than or equal to 50 feet. - moreThanFiftyFeet (2) indicates that the wire length is greater than 50 feet." - ::= { battManConfig 17 } - -battManConfigDischargeVoltageAlarmLevel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The discharge voltage alarm level in percent." - ::= { battManConfig 18 } - -battManConfigAutoAnnunciatorReset OBJECT-TYPE - SYNTAX INTEGER { - disabled (1), - enabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The annunciator output signal reset method: - disabled(1) means the annunciator signal output will be reset when the reset button is pressed. - enabled(2) means the annunciator will stop signalling when all alarm conditions clear." - ::= { battManConfig 19 } - --- the battManAlarm group - -battManAlarmManagementController OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Management Controller Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 1 } - -battManAlarmBatteries OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Batteries Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 2 } - -battManAlarmCharger OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Charger Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 3 } - -battManAlarmEnvironment OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Environment Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 4 } - --- the battManSystemStatus group - --- These are system wide parameters - -battManSystemAmbientTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system ambient temperture in tenths of degrees Celcius." - ::= { battManSystemStatus 1 } - -battManSystemAmbientTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system ambient temperture in tenths of degrees Fahrenheit." - ::= { battManSystemStatus 2 } - -battManSystemPilotTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system pilot temperature in tenths of degrees Celcius." - ::= { battManSystemStatus 3 } - -battManSystemPilotTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system pilot temperature in tenths of degrees Fahrenheit." - ::= { battManSystemStatus 4 } - -battManSystemAmbientHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system has a high temperature alarm." - ::= { battManSystemStatus 5 } - -battManSystemAmbientLowTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system has a low temperature alarm." - ::= { battManSystemStatus 6 } - -battManSystemPilotBatteryHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system has a pilot battery high temperature alarm." - ::= { battManSystemStatus 7 } - -battManSystemPilotProbeDisconnected OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system pilot probe is disconnected." - ::= { battManSystemStatus 8 } - -battManSystemAmbientProbeDisconnected OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system ambient probe is disconnected." - ::= { battManSystemStatus 9 } - --- This is a table of input contact parameters - -battManInputContactTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManContactTable." - ::= { battManInputContactStatus 1 } - -battManInputContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManInputContactTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each contact - in the system. " - ::= { battManInputContactStatus 2 } - -battManInputContactTableEntry OBJECT-TYPE - SYNTAX BattManInputContactTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The contact to get data from." - INDEX { battManInputContactIndex } - ::= { battManInputContactTable 1 } - -BattManInputContactTableEntry ::= - SEQUENCE { - battManInputContactIndex INTEGER, - battManInputContactName DisplayString, - battManInputContactAlarmState INTEGER, - battManInputContactState INTEGER, - battManInputContactNormalState INTEGER, - battManInputContactAlarmDelay INTEGER - } - -battManInputContactIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of contact entries in the table." - ::= { battManInputContactTableEntry 1 } - -battManInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the input contact." - ::= { battManInputContactTableEntry 2 } - -battManInputContactAlarmState OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the alarm condition is active for this contact." - ::= { battManInputContactTableEntry 3 } - -battManInputContactState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to open(1), the input contact is in the open state. - When set to closed(2), the input contact is in the closed state." - ::= { battManInputContactTableEntry 4 } - -battManInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to open(1), the input contact is normally open. - When set to closed(2), the input contact is normally closed." - ::= { battManInputContactTableEntry 5 } - -battManInputContactAlarmDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The alarm delay time in seconds." - ::= { battManInputContactTableEntry 6 } - --- This is a table of battery string parameters - -battManStringTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManStringTable." - ::= { battManStringStatus 1 } - -battManStringTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManStringTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each string - in the system. " - ::= { battManStringStatus 2 } - -battManStringTableEntry OBJECT-TYPE - SYNTAX BattManStringTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManStringIndex } - ::= { battManStringTable 1 } - -BattManStringTableEntry ::= - SEQUENCE { - battManStringIndex INTEGER, - battManStringCurrent INTEGER, - battManStringRippleCurrent INTEGER, - battManStringChargerHighVoltageAlarm INTEGER, - battManStringChargerLowVoltageAlarm INTEGER, - battManStringCurrentProbeDisconnected INTEGER, - battManStringOnBattery INTEGER - } - -battManStringIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string entries in the table." - ::= { battManStringTableEntry 1 } - -battManStringCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The string current in tenths of Amps." - ::= { battManStringTableEntry 2 } - -battManStringRippleCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The string ripple current in tenths of Amps." - ::= { battManStringTableEntry 3 } - -battManStringChargerHighVoltageAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string charger has a high voltage alarm." - ::= { battManStringTableEntry 4 } - -battManStringChargerLowVoltageAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string charger has a low voltage alarm." - ::= { battManStringTableEntry 5 } - -battManStringCurrentProbeDisconnected OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string charger probe is disconnected." - ::= { battManStringTableEntry 6 } - -battManStringOnBattery OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string is in the on-battery state." - ::= { battManStringTableEntry 7 } - --- the battManString1BatteryStatus group - -battManString1BatteryTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1BatteryStatusTable." - ::= { battManBatteryStatus 1 } - -battManString1BatteryTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each string - in the system. " - ::= { battManBatteryStatus 2 } - -battManString1BatteryTableEntry OBJECT-TYPE - SYNTAX BattManString1BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1BatteryIndex } - ::= { battManString1BatteryTable 1 } - -BattManString1BatteryTableEntry ::= - SEQUENCE { - battManString1BatteryIndex INTEGER, - battManString1BatteryVoltage INTEGER, - battManString1BatteryLowestVoltage INTEGER, - battManString1BatteryCellShorted INTEGER, - battManString1BatteryOpenFuseOrConnection INTEGER, - battManString1BatteryLowCapacity INTEGER, - battManString1BatteryHighOhmicValue INTEGER, - battManString1BatteryThermalRunaway INTEGER, - battManString1BatteryDryout INTEGER - } - -battManString1BatteryIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string entries in the table." - ::= { battManString1BatteryTableEntry 1 } - -battManString1BatteryVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery voltage in milli VDC." - ::= { battManString1BatteryTableEntry 2 } - -battManString1BatteryLowestVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The lowest battery discharge voltage during the last power event in milli VDC." - ::= { battManString1BatteryTableEntry 3 } - -battManString1BatteryCellShorted OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a battery cell is shorted." - ::= { battManString1BatteryTableEntry 4 } - -battManString1BatteryOpenFuseOrConnection OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a fuse or connection is open." - ::= { battManString1BatteryTableEntry 5 } - -battManString1BatteryLowCapacity OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has low capacity." - ::= { battManString1BatteryTableEntry 6 } - -battManString1BatteryHighOhmicValue OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a high ohmic value." - ::= { battManString1BatteryTableEntry 7 } - -battManString1BatteryThermalRunaway OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a thermal runaway condition." - ::= { battManString1BatteryTableEntry 8 } - -battManString1BatteryDryout OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a dryout condition." - ::= { battManString1BatteryTableEntry 9 } - --- the battManString2BatteryStatus group - -battManString2BatteryTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2BatteryStatusTable." - ::= { battManBatteryStatus 3 } - -battManString2BatteryTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each string - in the system. " - ::= { battManBatteryStatus 4 } - -battManString2BatteryTableEntry OBJECT-TYPE - SYNTAX BattManString2BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2BatteryIndex } - ::= { battManString2BatteryTable 1 } - -BattManString2BatteryTableEntry ::= - SEQUENCE { - battManString2BatteryIndex INTEGER, - battManString2BatteryVoltage INTEGER, - battManString2BatteryLowestVoltage INTEGER, - battManString2BatteryCellShorted INTEGER, - battManString2BatteryOpenFuseOrConnection INTEGER, - battManString2BatteryLowCapacity INTEGER, - battManString2BatteryHighOhmicValue INTEGER, - battManString2BatteryThermalRunaway INTEGER, - battManString2BatteryDryout INTEGER - } - -battManString2BatteryIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string entries in the table." - ::= { battManString2BatteryTableEntry 1 } - -battManString2BatteryVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery voltage in milli VDC." - ::= { battManString2BatteryTableEntry 2 } - -battManString2BatteryLowestVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The lowest battery discharge voltage during the last power event in milli VDC." - ::= { battManString2BatteryTableEntry 3 } - -battManString2BatteryCellShorted OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a battery cell is shorted." - ::= { battManString2BatteryTableEntry 4 } - -battManString2BatteryOpenFuseOrConnection OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a fuse or connection is open." - ::= { battManString2BatteryTableEntry 5 } - -battManString2BatteryLowCapacity OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has low capacity." - ::= { battManString2BatteryTableEntry 6 } - -battManString2BatteryHighOhmicValue OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a high ohmic value." - ::= { battManString2BatteryTableEntry 7 } - -battManString2BatteryThermalRunaway OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a thermal runaway condition." - ::= { battManString2BatteryTableEntry 8 } - -battManString2BatteryDryout OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a dryout condition." - ::= { battManString2BatteryTableEntry 9 } - --- battery manager control group -battManRemoteAnnunciatorReset OBJECT-TYPE - SYNTAX INTEGER { - noOperation (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to reset(2) will reset the user interface annunciator. - Getting this OID will do nothing and return the noOperation(1) value." - ::= { battManControl 1 } - -battManResetChargeCurrentDeviationBenchmark OBJECT-TYPE - SYNTAX INTEGER { - noOperation (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to reset(2) will reset the charge current deviation benchmark. - Getting this OID will do nothing and return the noOperation(1) value." - ::= { battManControl 2 } - -battManResetLowestDischargeVoltages OBJECT-TYPE - SYNTAX INTEGER { - noOperation (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to reset(2) will reset the lowest discharge voltages. - Getting this OID will do nothing and return the noOperation(1) value." - ::= { battManControl 3 } - --- the battManTestResults group - ---string 1 test results table - -battManString1OhmicValueLastDischargeInfo OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Informational text showing the date/time, load, and pilot temperature for the string - during the last discharge when ohmic values were recorded." - ::= { battManTestResults 1 } - -battManString1OhmicValueTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1OhmicValueTable." - ::= { battManTestResults 2 } - -battManString1OhmicValueTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting ohmic value information from each battery in String 1." - ::= { battManTestResults 3 } - -battManString1OhmicValueTableEntry OBJECT-TYPE - SYNTAX BattManString1OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1OhmicValueIndex } - ::= { battManString1OhmicValueTable 1 } - -BattManString1OhmicValueTableEntry ::= - SEQUENCE { - battManString1OhmicValueIndex INTEGER, - battManString1OhmicValueData INTEGER - } - -battManString1OhmicValueIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery number." - ::= { battManString1OhmicValueTableEntry 1 } - -battManString1OhmicValueData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms. - Note: Negative values are invalid and may indicate faulty calibration - of ohmic value correction factors." - ::= { battManString1OhmicValueTableEntry 2 } - -battManString1ResponseTestChangeTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1ResponseTestChangeTable." - ::= { battManTestResults 4 } - -battManString1ResponseTestChangeTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting response test change information from each battery in String 1." - ::= { battManTestResults 5 } - -battManString1ResponseTestChangeTableEntry OBJECT-TYPE - SYNTAX BattManString1ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1ResponseTestChangeIndex } - ::= { battManString1ResponseTestChangeTable 1 } - -BattManString1ResponseTestChangeTableEntry ::= - SEQUENCE { - battManString1ResponseTestChangeIndex INTEGER, - battManString1ResponseTestChangeData INTEGER - } - -battManString1ResponseTestChangeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of the entries in the table." - ::= { battManString1ResponseTestChangeTableEntry 1 } - -battManString1ResponseTestChangeData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery response test change in percent." - ::= { battManString1ResponseTestChangeTableEntry 2 } - -battManString2OhmicValueLastDischargeInfo OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Informational text showing the date/time, load, and pilot temperature for the string - during the last discharge when ohmic values were recorded." - ::= { battManTestResults 6 } - -battManString2OhmicValueTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2OhmicValueTable." - ::= { battManTestResults 7 } - -battManString2OhmicValueTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting ohmic value information from each battery in String 1." - ::= { battManTestResults 8 } - -battManString2OhmicValueTableEntry OBJECT-TYPE - SYNTAX BattManString2OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2OhmicValueIndex } - ::= { battManString2OhmicValueTable 1 } - -BattManString2OhmicValueTableEntry ::= - SEQUENCE { - battManString2OhmicValueIndex INTEGER, - battManString2OhmicValueData INTEGER - } - -battManString2OhmicValueIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of battery calibration entries in the table." - ::= { battManString2OhmicValueTableEntry 1 } - -battManString2OhmicValueData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms. - Note: Negative values are invalid and may indicate faulty calibration - of ohmic value correction factors." - ::= { battManString2OhmicValueTableEntry 2 } - -battManString2ResponseTestChangeTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2ResponseTestChangeTable." - ::= { battManTestResults 9 } - -battManString2ResponseTestChangeTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting response test change information from each battery in String 1." - ::= { battManTestResults 10 } - -battManString2ResponseTestChangeTableEntry OBJECT-TYPE - SYNTAX BattManString2ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2ResponseTestChangeIndex } - ::= { battManString2ResponseTestChangeTable 1 } - -BattManString2ResponseTestChangeTableEntry ::= - SEQUENCE { - battManString2ResponseTestChangeIndex INTEGER, - battManString2ResponseTestChangeData INTEGER - } - -battManString2ResponseTestChangeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of the entries in the table." - ::= { battManString2ResponseTestChangeTableEntry 1 } - -battManString2ResponseTestChangeData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery response test change in percent." - ::= { battManString2ResponseTestChangeTableEntry 2 } - --- the xPDUIdent group - -xPDUIdentProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the PDU." - ::= { xPDUIdent 1 } - -xPDUIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the PDU. - This value is set at the factory." - ::= { xPDUIdent 2 } - -xPDUIdentFirmwareAppRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application firmware revision of the PDU." - ::= { xPDUIdent 3 } - -xPDUIdentFirmwareAppOSRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application operating system firmware revision of the PDU." - ::= { xPDUIdent 4 } - -xPDUIdentFirmwareControllerRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the PDU controller firmware revision." - ::= { xPDUIdent 5 } - -xPDUIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the PDU was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { xPDUIdent 6 } - -xPDUIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of - the PDU. This value is set at the factory." - ::= { xPDUIdent 7 } - -xPDUIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of - the PDU. This value is set at the factory." - ::= { xPDUIdent 8 } - --- the xPDUDevice group - -xPDUDeviceNominalMainInputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal main input voltage to the PDU. - Measured in Volts, line-to-line for a delta service or - line-to-neutral for a wye service." - ::= { xPDUDevice 1 } - -xPDUDeviceServiceType OBJECT-TYPE - SYNTAX INTEGER { - delta (1), - wye (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of utility input to the PDU. Either 3 wires (delta), or 4 wires (wye)." - ::= { xPDUDevice 2 } - -xPDUDeviceNominalOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal line-to-neutral output voltage to the load measured in Volts." - ::= { xPDUDevice 3 } - -xPDUDeviceMainInputBreakerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The rating of the main input breaker measured in Amps." - ::= { xPDUDevice 4 } - -xPDUDevicePanelBreakerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The rating of the panel breaker measured in Amps." - ::= { xPDUDevice 5 } - -xPDUDeviceTransformerPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not a transformer is installed in the PDU." - ::= { xPDUDevice 6 } - -xPDUDeviceLoadTieBreakerPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not a load tie breaker is installed in the PDU." - ::= { xPDUDevice 7 } - -xPDUDeviceLoadTestPortPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not a load test port is installed in the PDU." - ::= { xPDUDevice 8 } - -xPDUDeviceFusesPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the UPS feed from the PDU includes fuses." - ::= { xPDUDevice 9 } - -xPDUDeviceFansPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not cooling fans are installed in the PDU." - ::= { xPDUDevice 10 } - -xPDUDeviceBypassInputPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the PDU is equipped with a second feed for - the UPS's bypass input." - ::= { xPDUDevice 11 } - -xPDUDeviceCrossTieOutputPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the PDU is equipped with a cross-tie output." - ::= { xPDUDevice 12 } - -xPDUDeviceEarthGroundMonitorPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the PDU can provide ground current measurements." - ::= { xPDUDevice 13 } - -xPDUDeviceInfraXureType OBJECT-TYPE - SYNTAX INTEGER { - typeB (1), - typeC (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the configuration of this PDU system. - Type-B PDU is in a distributed UPS system and has bypass capabilities. - Type-C PDU receives power from a larger central UPS." - ::= { xPDUDevice 14 } - --- Main Input - -xPDUMainInputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an input over voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUMainInput 1 } - -xPDUMainInputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an input under voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUMainInput 2 } - --- Main Input Voltage Table - -xPDUMainInputVoltageTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Main input voltage entries." - ::= { xPDUMainInput 3 } - -xPDUMainInputVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUMainInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input voltage table entries. The number of - entries are the phase entries. - The number of entries is contained in the - xPDUMainInputVoltageTableSize OID." - ::= { xPDUMainInput 4 } - - xPDUMainInputVoltagePhaseEntry OBJECT-TYPE - SYNTAX XPDUMainInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular main input voltage phase." - INDEX { xPDUMainInputVoltagePhaseIndex } - ::= { xPDUMainInputVoltageTable 1 } - - XPDUMainInputVoltagePhaseEntry ::= SEQUENCE { - xPDUMainInputVoltagePhaseIndex INTEGER, - xPDUMainInputVoltageLtoL INTEGER, - xPDUMainInputVoltageLtoN INTEGER - } - - xPDUMainInputVoltagePhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each input phase entry in the table." - ::= { xPDUMainInputVoltagePhaseEntry 1 } - - xPDUMainInputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line PDU input voltage when an isolation transformer is present, - or -1 if no transformer present in this PDU. Measured in tenths of Volts." - ::= { xPDUMainInputVoltagePhaseEntry 2 } - - xPDUMainInputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral PDU input voltage when an isolation transformer is not present, - or -1 if a transformer is present in this PDU. Measured in tenths of Volts." - ::= { xPDUMainInputVoltagePhaseEntry 3 } - - -xPDUBypassInputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which a bypass input over voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUBypassInput 1 } - -xPDUBypassInputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an bypass input under voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUBypassInput 2 } - --- Bypass Input Voltage Table - -xPDUBypassInputVoltageTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of bypass input voltage entries." - ::= { xPDUBypassInput 3 } - -xPDUBypassInputVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUBypassInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of - entries are the phase entries. - The number of entries is contained in the - xPDUBypassInputVoltageTableSize OID." - ::= { xPDUBypassInput 4 } - - xPDUBypassInputVoltagePhaseEntry OBJECT-TYPE - SYNTAX XPDUBypassInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular bypass input voltage phase." - INDEX { xPDUBypassInputVoltagePhaseIndex } - ::= { xPDUBypassInputVoltageTable 1 } - - XPDUBypassInputVoltagePhaseEntry ::= SEQUENCE { - xPDUBypassInputVoltagePhaseIndex INTEGER, - xPDUBypassInputVoltageLtoL INTEGER, - xPDUBypassInputVoltageLtoN INTEGER - } - - xPDUBypassInputVoltagePhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of each bypass input phase entry in the table." - ::= { xPDUBypassInputVoltagePhaseEntry 1 } - - xPDUBypassInputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line bypass input voltage, or -1 if no bypass - feed is present in this PDU. Measured in tenths of Volts" - ::= { xPDUBypassInputVoltagePhaseEntry 2 } - - xPDUBypassInputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral bypass input voltage, or -1 if no bypass - feed is present in this PDU. Measured in tenths of Volts" - ::= { xPDUBypassInputVoltagePhaseEntry 3 } - --- UPS Input Table - -xPDUUPSInputVoltageTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of UPS input voltage entries." - ::= { xPDUUPSInput 1 } - -xPDUUPSInputVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUUPSInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of UPS input table entries. The number of - entries are the phase entries. - The number of entries is contained in the - xPDUUPSInputVoltageTableSize OID." - ::= { xPDUUPSInput 2 } - - xPDUUPSInputVoltagePhaseEntry OBJECT-TYPE - SYNTAX XPDUUPSInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular UPS input voltage phase." - INDEX { xPDUUPSInputVoltagePhaseIndex } - ::= { xPDUUPSInputVoltageTable 1 } - - XPDUUPSInputVoltagePhaseEntry ::= SEQUENCE { - xPDUUPSInputVoltagePhaseIndex INTEGER, - xPDUUPSInputVoltageLtoNPresent INTEGER - } - - xPDUUPSInputVoltagePhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each UPS input phase entry in the table." - ::= { xPDUUPSInputVoltagePhaseEntry 1 } - - xPDUUPSInputVoltageLtoNPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not voltage is present at the UPS feed." - ::= { xPDUUPSInputVoltagePhaseEntry 2 } - --- System Output - -xPDUSystemOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system output frequency in tenths of Hertz." - ::= { xPDUSystemOutput 1 } - -xPDUSystemOutputNeutralCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the neutral current measured at the system output in tenths of Amps." - ::= { xPDUSystemOutput 2 } - -xPDUSystemOutputTotalPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kW." - ::= { xPDUSystemOutput 3 } - -xPDUSystemOutputTotalApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kVA." - ::= { xPDUSystemOutput 4 } - -xPDUSystemOutputTotalPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the total power factor of the system output. - A value of 100 representing a unity power factor (1.00). - Measured in hundredths." - ::= { xPDUSystemOutput 5 } - -xPDUSystemOutputFrequencyTolerance OBJECT-TYPE - SYNTAX INTEGER{ - freqToleranceOff (1), - freqTolerancePointTwo (2), - freqTolerancePointFive (3), - freqToleranceOne (4), - freqToleranceOnePointFive (5), - freqToleranceTwo (6), - freqToleranceThree (7), - freqToleranceFour (8), - freqToleranceFive (9), - freqToleranceNine (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Shows the circuit panel output frequency tolerance in Hertz." - ::= { xPDUSystemOutput 6 } - -xPDUSystemOutputMaxKWPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Defines 100% load in kW. - Purpose is to set to match UPS capabilities." - ::= { xPDUSystemOutput 7 } - -xPDUSystemOutputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an output over voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUSystemOutput 8 } - -xPDUSystemOutputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an output under voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUSystemOutput 9 } - - -xPDUSystemOutputOverCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an over current condition will be generated. - Specified as a percent of the panel breaker rating." - ::= { xPDUSystemOutput 10 } - -xPDUSystemOutputOverCurrentNeutralThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an Over current neutral condition will be generated. - Specified as a percent of the panel breaker rating." - ::= { xPDUSystemOutput 11 } - -xPDUSystemOutputUnderCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an under current condition will be generated. - Specified as a percent of the panel breaker rating." - ::= { xPDUSystemOutput 12 } - -xPDUSystemOutputTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of System Output phase entries." - ::= { xPDUSystemOutput 13 } - -xPDUSystemOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of system output table entries. - The number of entries is contained in the - xPDUSystemOutputTableSize OID." - ::= { xPDUSystemOutput 14 } - - xPDUSystemOutputPhaseEntry OBJECT-TYPE - SYNTAX XPDUSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular system output phase." - INDEX { xPDUSystemOutputPhaseIndex } - ::= { xPDUSystemOutputTable 1 } - - XPDUSystemOutputPhaseEntry ::= SEQUENCE { - xPDUSystemOutputPhaseIndex INTEGER, - xPDUSystemOutputVoltageLtoL INTEGER, - xPDUSystemOutputVoltageLtoN INTEGER, - xPDUSystemOutputPhaseCurrent INTEGER, - xPDUSystemOutputPower INTEGER, - xPDUSystemOutputApparentPower INTEGER, - xPDUSystemOutputPowerFactor INTEGER - } - - xPDUSystemOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each output phase entry in the table." - ::= { xPDUSystemOutputPhaseEntry 1 } - - xPDUSystemOutputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line system output voltage available at the cicuit panel. - Measured in tenths of Volts." - ::= { xPDUSystemOutputPhaseEntry 2 } - - xPDUSystemOutputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral system output voltage available at the cicuit panel. - Measured in tenths of Volts." - ::= { xPDUSystemOutputPhaseEntry 3 } - - - xPDUSystemOutputPhaseCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System load current per phase. Measured in tenths of Amps." - ::= { xPDUSystemOutputPhaseEntry 4 } - - xPDUSystemOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System output power per phase. Measured in tenths of kW." - ::= { xPDUSystemOutputPhaseEntry 5 } - - xPDUSystemOutputApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System output power per phase. Measured in tenths of kVA." - ::= { xPDUSystemOutputPhaseEntry 6 } - - xPDUSystemOutputPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the Power Factor of the system output per phase. - A value of 100 representing a unity Power Factor (1.00). - Measured in hundredths." - ::= { xPDUSystemOutputPhaseEntry 7 } - -xPDUGroundCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the current measured in the earth ground conductor in tenths of Amps." - ::= { xPDUGroundMonitorPoint 1 } - -xPDUGroundCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..50) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which a ground current over current - condition will be generated. Measured in tenths of Amps." - ::= { xPDUGroundMonitorPoint 2 } - --- System Breakers - -xPDUSystemBreakerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of system breaker entries." - ::= { xPDUSystemBreakers 1 } - -xPDUSystemBreakerTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUSystemBreakerTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of system breaker entries. - The number of entries is contained in the - xPDUSystemBreakerTableSize OID." - ::= { xPDUSystemBreakers 2 } - - xPDUSystemBreakerTableEntry OBJECT-TYPE - SYNTAX XPDUSystemBreakerTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular system breaker." - INDEX { xPDUSystemBreakerTableIndex } - ::= { xPDUSystemBreakerTable 1 } - - XPDUSystemBreakerTableEntry ::= SEQUENCE { - xPDUSystemBreakerTableIndex INTEGER, - xPDUSystemBreakerDescription DisplayString, - xPDUSystemBreakerPosition INTEGER - } - - xPDUSystemBreakerTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of system breaker entries in the table." - ::= { xPDUSystemBreakerTableEntry 1 } - -xPDUSystemBreakerDescription OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..79)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A brief description of the system breakers." - ::= { xPDUSystemBreakerTableEntry 2 } - - xPDUSystemBreakerPosition OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether this breaker is open(1) or closed(2)." - ::= { xPDUSystemBreakerTableEntry 3 } - --- Branch Breakers (Breaker Panel) - -xPDUNumOfBranchBreakers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of branch breakers in the Panel." - ::= { xPDUBranchBreakers 1 } - --- Branch Breakers Table - -xPDUBranchBreakerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of branch breaker entries." - ::= { xPDUBranchBreakers 2 } - -xPDUBranchBreakerTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUBranchBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of branch breaker table entries. The - number of entries is given by the value of xPDUBranchBreakerTableSize - The number of entries is contained in the - xPDUBranchBreakerTableSize OID." - ::= { xPDUBranchBreakers 3 } - - xPDUBranchBreakerEntry OBJECT-TYPE - SYNTAX XPDUBranchBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular branch breaker." - INDEX { xPDUBranchBreakerTableIndex } - ::= { xPDUBranchBreakerTable 1 } - - XPDUBranchBreakerEntry ::= SEQUENCE { - xPDUBranchBreakerTableIndex INTEGER, - xPDUBranchBreakerRating INTEGER, - xPDUBranchBreakerRDPFeed INTEGER, - xPDUBranchBreakerTieIndicator INTEGER, - xPDUBranchBreakerCurrent INTEGER, - xPDUBranchBreakerOverCurrentThreshold INTEGER, - xPDUBranchBreakerUnderCurrentThreshold INTEGER - } - - xPDUBranchBreakerTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of branch breaker entries in the table." - ::= { xPDUBranchBreakerEntry 1 } - - xPDUBranchBreakerRating OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates current rating of this breaker. - 0=Breaker is not present. - 1=Earth leakage connection. - 2=Neutral connection. - A value greater than 2 indicates breaker current rating in Amps." - ::= { xPDUBranchBreakerEntry 2 } - - xPDUBranchBreakerRDPFeed OBJECT-TYPE - SYNTAX INTEGER { - remoteDistribution (1), - noRemoteDistribution (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates that a breaker position is feeding a remote - distribution panel." - ::= { xPDUBranchBreakerEntry 3 } - - xPDUBranchBreakerTieIndicator OBJECT-TYPE - SYNTAX INTEGER { - breakerTied (1), - breakerUntied (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates whether or not the breaker pole is physically - connected to the breaker immediately below." - ::= { xPDUBranchBreakerEntry 4 } - - xPDUBranchBreakerCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the branch current in tenths of Amps or -1 when not available." - ::= { xPDUBranchBreakerEntry 5 } - - xPDUBranchBreakerOverCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which a branch circuit over current - condition will be generated. - Specified as a percent of the branch breaker rating." - ::= { xPDUBranchBreakerEntry 6 } - - xPDUBranchBreakerUnderCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a branch circuit under current - condition will be generated. - Specified as a percent of the branch breaker rating." - ::= { xPDUBranchBreakerEntry 7 } - --- the xPDUInputContacts group - -xPDUInputContactNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the PDU." - ::= { xPDUInputContacts 1 } - -xPDUInputContactTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input contact entries." - ::= { xPDUInputContacts 2 } - -xPDUInputContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUInputContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the PDU. - The number of entries is contained in the - xPDUInputContactTableSize OID." - ::= { xPDUInputContacts 3 } - -xPDUInputContactEntry OBJECT-TYPE - SYNTAX XPDUInputContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A contact entry containing information for a given contact." - INDEX { xPDUInputContactNumber } - ::= { xPDUInputContactTable 1 } - -XPDUInputContactEntry ::= - SEQUENCE { - xPDUInputContactNumber INTEGER, - xPDUInputContactName DisplayString, - xPDUInputContactNormalState INTEGER, - xPDUInputContactCurrentState INTEGER - } - -xPDUInputContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the contact on the PDU." - ::= { xPDUInputContactEntry 1 } - -xPDUInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the contact." - ::= { xPDUInputContactEntry 2 } - -xPDUInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the contact." - ::= { xPDUInputContactEntry 3 } - -xPDUInputContactCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the contact." - ::= { xPDUInputContactEntry 4 } - --- the xPDUOutputRelays group - -xPDUOutputRelaysNumRelays OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relays supported by the PDU." - ::= { xPDUOutputRelays 1 } - -xPDUOutputRelaysTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relay entries." - ::= { xPDUOutputRelays 2 } - -xPDUOutputRelayTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output relays supported by the PDU. - The number of entries is contained in the - xPDUOutputRelayTableSize OID." - ::= { xPDUOutputRelays 3 } - -xPDUOutputRelayEntry OBJECT-TYPE - SYNTAX XPDUOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A output relay entry containing information for a given contact." - INDEX { xPDUOutputRelayNumber } - ::= { xPDUOutputRelayTable 1 } - -XPDUOutputRelayEntry ::= - SEQUENCE { - xPDUOutputRelayNumber INTEGER, - xPDUOutputRelayName DisplayString, - xPDUOutputRelayNormalState INTEGER, - xPDUOutputRelayCurrentState INTEGER - } - -xPDUOutputRelayNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the output relay on the PDU." - ::= { xPDUOutputRelayEntry 1 } - -xPDUOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the output relay." - ::= { xPDUOutputRelayEntry 2 } - -xPDUOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the output relay." - ::= { xPDUOutputRelayEntry 3 } - -xPDUOutputRelayCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the output relay." - ::= { xPDUOutputRelayEntry 4 } - --- the xPDUMiscGroup - -xPDUEPOMode OBJECT-TYPE - SYNTAX INTEGER { - armed (1), - disarmed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether the EPO System is armed(1) or disarmed(2)." - ::= { xPDUMiscGroup 1 } - -xPDUTransformTempStatus OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - overtemp (2), - noTransformerPresent (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates if the PDU's isolation transformer is over temperature." - ::= { xPDUMiscGroup 2 } - -xPDUCoolingFanStatus OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - failed (2), - noCoolingFansPresent (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates if one or more of the PDU's cooling fans have failed." - ::= { xPDUMiscGroup 3 } - --- The xATSIdent group - -xATSIdentProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the transfer switch unit." - ::= { xATSIdent 1 } - -xATSIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the transfer switch. - This value is set at the factory." - ::= { xATSIdent 2 } - -xATSIdentFirmwareAppRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application firmware revision of the transfer switch." - ::= { xATSIdent 3 } - -xATSIdentFirmwareAppOSRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application operating system firmware revision of the transfer switch." - ::= { xATSIdent 4 } - -xATSIdentFirmwareControllerRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the transfer switch controller firmware revision." - ::= { xATSIdent 5 } - -xATSIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the transfer switch was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { xATSIdent 6 } - -xATSIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of the transfer switch. - This value is set at the factory." - ::= { xATSIdent 7 } - -xATSIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of the transfer switch. - This value is set at the factory." - ::= { xATSIdent 8 } - --- The xATSDevice group - -xATSDeviceServiceType OBJECT-TYPE - SYNTAX INTEGER { - threeWire (1), - fourWire (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of utility input to the transfer switch. - Either 3 wires (delta), or 4 wires (wye)." - ::= { xATSDevice 1 } - -xATSDeviceNominalVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal line-to-neutral system voltage. - Measured in Volts, line-to-line for a 3-wire service or - line-to-neutral for a 4-wire service. -1 if not available." - ::= { xATSDevice 2 } - -xATSDeviceNominalFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal system frequency. Measured in tenths of Hertz. - -1 if not available." - ::= { xATSDevice 3 } - -xATSDeviceTransferSwitchRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The rating of the transfer switch. - Measured in Amps." - ::= { xATSDevice 4 } - -xATSDeviceDCBackUpPresent OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates if a DC backup is present or not." - ::= { xATSDevice 5 } - --- The xATS Switch Status group - -xATSSwitchStatusSelectedSource OBJECT-TYPE - SYNTAX INTEGER{ - none (1), - source1 (2), - source2 (3), - fault (4), - unknown (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The source which is currently selected, i.e. supplying power to the load." - ::= { xATSSwitchStatus 1 } - -xATSSwitchStatusOperationalMode OBJECT-TYPE - SYNTAX INTEGER{ - automatic (1), - notInAutoAbnormal (2), - notInAuto (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current operating mode of the transfer switch. When the ATS is in - automatic mode, generator starting and ATS transferring is all done automatically - as needed based on the state of source 1. Automatic operation is halted when the - ATS is in either of the notInAuto modes. - A mode of notInAuto indicates that the automatic operation switch is in the - disabled position, as indicated by the xATSSwitchStatusAutomaticOperationSwitch OID. - The notInAutoAbnormal condition indicates that an abnormal - condition has caused the transfer switch to halt automatic operation. - In this case, traps can indicate the exact problem. In the case of - notInAutoAbnormal, refer to the operation manual for details - on how debug the condition and restore automatic operation." - ::= { xATSSwitchStatus 2 } - -xATSSwitchStatusAutomaticOperationSwitch OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - enabled (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The position of the automatic operation switch on the front of the transfer switch." - ::= { xATSSwitchStatus 3 } - -xATSSwitchStatusEngineStartSignal OBJECT-TYPE - SYNTAX INTEGER{ - run (1), - stop (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The position of the Start/Stop contact which signals the generator - engine to start/run. When the ATS is in automatic mode, - generator starting/stopping is under ATS control." - ::= { xATSSwitchStatus 4 } - --- The xATS Switch Setting group - -xATSSwitchSettingsLowVoltageTransferPoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The lowest acceptable voltage condition at source 1. - When any phase of source 1 is lower than this voltage, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified in volts, line-to-line for a 3-wire service or - line-to-neutral for a 4-wire service. - -1 if not available." - ::= { xATSSwitchSettings 1 } - -xATSSwitchSettingsHighVoltageTransferPoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The highest acceptable voltage condition at source 1. - When any phase of source 1 is greater than this voltage, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified in volts, line-to-line for a 3-wire service or - line-to-neutral for a 4-wire service. - -1 if not available." - ::= { xATSSwitchSettings 2 } - -xATSSwitchSettingsMaxFrequencyDeviation OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum acceptable frequency deviation condition from nominal at source 1. - When source 1 frequency is outside the specified range, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified in tenths of Hertz above or below nominal. - A value of zero indicates that frequency is ignored when - determining source quality. - -1 if not available." - ::= { xATSSwitchSettings 3 } - -xATSSwitchSettingsMinPhaseBalance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum required phase balance at source 1. - When the percentage difference between the minimum and maximum - phase voltage measurements at source 1 is greater than this value, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified as a percentage. A value of zero indicates that phase balance - is ignored when determining source quality. - -1 if not available." - ::= { xATSSwitchSettings 4 } - -xATSSwitchSettingsNominalRotation OBJECT-TYPE - SYNTAX INTEGER{ - abc (1), - cba (2), - any (3), - unknown (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The nominal phase rotation (or phase sequence) required by the load. - For certain types of equipment, such as rotating machinery, phase rotation - is critical for proper operation as it determines the direction which motors - will rotate (clockwise or counterclockwise). - Source quality will be seen as bad if the rotation measured at that - ATS input does not match this setting. - If this setting is set to any, phase rotation is ignored." - ::= { xATSSwitchSettings 5 } - -xATSSwitchSettingsAllowClosedTransfer OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2), - unknown (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting enables seemless (closed) transfers between sources. - When possible, both source 1 and source 2 are closed to the output - for a brief time. If closed transfer is not possible within the amount - of time specified by the xATSSwitchSettingsMaxSyncTime OID, - an open transfer will be executed." - ::= { xATSSwitchSettings 6 } - -xATSSwitchSettingsMaxSyncTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "When attempting/seeking to perform a closed transfer, this setting defines - the maximum time allowed before the transfer switch will give up and perform - an open transfer. Specified in seconds. - -1 if not available." - ::= { xATSSwitchSettings 7 } - -xATSSwitchSettingsNeutralTransferTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting defines how long both source 1 and source 2 will be - disconnected from the output, during an open transfer. - Specified in seconds. - -1 if not available." - ::= { xATSSwitchSettings 8 } - -xATSSwitchSettingsClearLatchedAlarms OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Clears any latched alarm conditions." - ::= { xATSSwitchSettings 9 } - -xATSSwitchSettingsSetToFactoryDefaults OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Sets all transfer switch settings to factory default values." - ::= { xATSSwitchSettings 10 } - - --- The xATSSwitchTimers group - - xATSSwitchTimersTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of transfer switch timer entries." - ::= { xATSSwitchTimers 1 } - - xATSSwitchTimersTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSwitchTimersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of timers supported by ATS. - The number of entries is contained in the xATSSwitchTimersTableSize OID." - ::= { xATSSwitchTimers 2 } - - xATSSwitchTimersEntry OBJECT-TYPE - SYNTAX XATSSwitchTimersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information about an individual ATS timer." - INDEX { xATSSwitchTimersIndex } - ::= { xATSSwitchTimersTable 1 } - - XATSSwitchTimersEntry ::= - SEQUENCE { - xATSSwitchTimersIndex INTEGER, - xATSSwitchTimersName DisplayString, - xATSSwitchTimersAbort INTEGER, - xATSSwitchTimersStatus INTEGER, - xATSSwitchTimersRemainingTime INTEGER, - xATSSwitchTimersDelaySetting INTEGER - } - -xATSSwitchTimersIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of timer entries in the table." - ::= { xATSSwitchTimersEntry 1 } - -xATSSwitchTimersName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Name of the individual timer.Refer to ATS operation manual, - or on-line help, for detailed descriptions of ATS timers." - ::= { xATSSwitchTimersEntry 2 } - -xATSSwitchTimersAbort OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This aborts the individual timer." - ::= { xATSSwitchTimersEntry 3 } - -xATSSwitchTimersStatus OBJECT-TYPE - SYNTAX INTEGER{ - inactive (1), - active (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the individual timer. Designates whether this timer - entry is currently running or inactive." - ::= { xATSSwitchTimersEntry 4 } - -xATSSwitchTimersRemainingTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time remaining for this timer entry. - Specified in seconds." - ::= { xATSSwitchTimersEntry 5 } - -xATSSwitchTimersDelaySetting OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay settings associated with this timer entry. - When this timer entry is active, the timer value must exceed this setting - before the ATS behavior associated with this timer is executed. - Refer to ATS operation manual, or on-line help, for detailed - descriptions of ATS timers." - ::= { xATSSwitchTimersEntry 6 } - --- The xATSSwitchBlockMap group - - xATSSwitchBlockMapTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of blocking map entries, or how many ATS actions can be blocked." - ::= { xATSSwitchBlockMap 1 } - - xATSSwitchBlockMapTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSwitchBlockMapEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of blocking maps supported by the ATS. - The number of entries is contained in the xATSSwitchBlockMapTableSize OID." - ::= { xATSSwitchBlockMap 2 } - - xATSSwitchBlockMapEntry OBJECT-TYPE - SYNTAX XATSSwitchBlockMapEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information about a specific ATS blocking map." - INDEX { xATSSwitchBlockMapIndex } - ::= { xATSSwitchBlockMapTable 1 } - - XATSSwitchBlockMapEntry ::= - SEQUENCE { - xATSSwitchBlockMapIndex INTEGER, - xATSSwitchBlockMapName DisplayString, - xATSSwitchBlockMapStatus INTEGER, - xATSSwitchBlockMapSetting INTEGER - } - - xATSSwitchBlockMapIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of blocking map entries in the table." - ::= { xATSSwitchBlockMapEntry 1 } - - xATSSwitchBlockMapName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string describing the ATS action to be blocked." - ::= { xATSSwitchBlockMapEntry 2 } - - xATSSwitchBlockMapStatus OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Represents the status of this blocking map entry, in bit-mapped format. - A non-zero value indicates that this entry's ATS action is currently being blocked. - The bit(s) set indicate which input(s) are causing the blocking (bit0, bit1, etc). - - bit 0 - Contact 1 - bit 1 - Contact 2 - bit 2 - Contact 3 - bit 3 - Contact 4." - ::= { xATSSwitchBlockMapEntry 3 } - - xATSSwitchBlockMapSetting OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting designates the inputs that block the ATS action - The mapping is specified as a bit-field, where each bit set indicates - the input that blocks the ATS action associated with the entry. - - bit 0 - Contact 1 - bit 1 - Contact 2 - bit 2 - Contact 3 - bit 3 - Contact 4." - ::= { xATSSwitchBlockMapEntry 4 } - --- The xATSSwitchStatistics group - - xATSSwitchStatisticsTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of transfer switch statistics entries." - ::= { xATSSwitchStatistics 1 } - - xATSSwitchStatisticsTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSwitchStatisticsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of statistics supported by ATS. - The number of entries is contained in the xATSSwitchStatisticsTableSize OID." - ::= { xATSSwitchStatistics 2 } - - xATSSwitchStatisticsEntry OBJECT-TYPE - SYNTAX XATSSwitchStatisticsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information about an individual ATS statistic." - INDEX { xATSSwitchStatisticsIndex } - ::= { xATSSwitchStatisticsTable 1 } - - XATSSwitchStatisticsEntry ::= - SEQUENCE { - xATSSwitchStatisticsIndex INTEGER, - xATSSwitchStatisticsName DisplayString, - xATSSwitchStatisticsValue DisplayString, - xATSSwitchStatisticsReset INTEGER - } - - xATSSwitchStatisticsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of ATS statistics entries in the table." - ::= { xATSSwitchStatisticsEntry 1 } - - xATSSwitchStatisticsName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This is the name of the ATS statistic associated with this entry." - ::= { xATSSwitchStatisticsEntry 2 } - - xATSSwitchStatisticsValue OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This is the value of the ATS statistic associated with this entry." - ::= { xATSSwitchStatisticsEntry 3 } - - xATSSwitchStatisticsReset OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This will reset the individual ATS statistic associated with this entry." - ::= { xATSSwitchStatisticsEntry 4 } - --- The xATS Source 1 group - -xATSSource1Name OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "String used to identify source 1." - ::= { xATSSource1 1 } - -xATSSource1Position OBJECT-TYPE - SYNTAX INTEGER{ - open (1), - closed (2), - tripped (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current position of the switch at source 1." - ::= { xATSSource1 2 } - -xATSSource1Frequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency at source 1 in tenths of Hertz. - -1 if unavailable." - ::= { xATSSource1 3 } - -xATSSource1Quality OBJECT-TYPE - SYNTAX INTEGER{ - sourceGood (1), - lowVoltage (2), - highVoltage (3), - phaseImbalance (4), - freqOutOfRange (5), - badRotation (6), - unknown (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current line quality of source 1." - ::= { xATSSource1 4 } - -xATSSource1Rotation OBJECT-TYPE - SYNTAX INTEGER{ - abc (1), - cba (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase rotation measured at the source 1 input of the ATS. - The sequence is a reference to the order in which the three phases - pass the zero-crossing boundary in time." - ::= { xATSSource1 5 } - -xATSSource1TableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input voltage entries at the source 1 input of the ATS." - ::= { xATSSource1 6 } - - xATSSource1Table OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSource1PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of voltage table entries for source 1. The number of - entries are the phase entries. The number of entries is contained in the - xATSSource1TableSize OID." - ::= { xATSSource1 7 } - - xATSSource1PhaseEntry OBJECT-TYPE - SYNTAX XATSSource1PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input voltage phase at the source 1 input of the ATS." - INDEX { xATSSource1Index } - ::= { xATSSource1Table 1 } - - XATSSource1PhaseEntry ::= SEQUENCE { - xATSSource1Index INTEGER, - xATSSource1VoltageLtoL INTEGER, - xATSSource1VoltageLtoN INTEGER - } - - xATSSource1Index OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each phase utilized at source 1." - ::= { xATSSource1PhaseEntry 1 } - - xATSSource1VoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 1 line-to-line input voltage. - Measured in tenths of Volts." - ::= { xATSSource1PhaseEntry 2 } - - xATSSource1VoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 1 line-to-neutral input voltage. - Measured in tenths of Volts. -1 for a 3-wire service type." - ::= { xATSSource1PhaseEntry 3 } - --- The xATS Source 2 group - -xATSSource2Name OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "String used to identify source 2." - ::= { xATSSource2 1 } - -xATSSource2Position OBJECT-TYPE - SYNTAX INTEGER{ - open (1), - closed (2), - tripped (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current position of the switch at source 2." - ::= { xATSSource2 2 } - -xATSSource2Frequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency at source 2 in tenths of Hertz. - -1 if not available." - ::= { xATSSource2 3 } - -xATSSource2Quality OBJECT-TYPE - SYNTAX INTEGER{ - sourceGood (1), - lowVoltage (2), - highVoltage (3), - phaseImbalance (4), - freqOutOfRange (5), - badRotation (6), - unknown (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current line quality of source 2." - ::= { xATSSource2 4 } - -xATSSource2Rotation OBJECT-TYPE - SYNTAX INTEGER{ - abc (1), - cba (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase rotation measured at the source 2 input of the ATS. - -1 if not available." - ::= { xATSSource2 5 } - -xATSSource2TableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input voltage entries at the source 2 input of the ATS." - ::= { xATSSource2 6 } - - xATSSource2Table OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSource2PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of voltage table entries for the source 2. The number of - entries are the phase entries. The number of entries is contained in the - xATSSource2TableSize OID." - ::= { xATSSource2 7 } - - xATSSource2PhaseEntry OBJECT-TYPE - SYNTAX XATSSource2PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input voltage phase at the source 2 input of the ATS." - INDEX { xATSSource2Index } - ::= { xATSSource2Table 1 } - - XATSSource2PhaseEntry ::= SEQUENCE { - xATSSource2Index INTEGER, - xATSSource2VoltageLtoL INTEGER, - xATSSource2VoltageLtoN INTEGER - } - - xATSSource2Index OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each phase utilized at the source 2." - ::= { xATSSource2PhaseEntry 1 } - - xATSSource2VoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 2 line-to-line input voltage. - Measured in tenths of Volts." - ::= { xATSSource2PhaseEntry 2 } - - xATSSource2VoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 2 line-to-neutral input voltage. - Measured in tenths of Volts. -1 for a 3-wire service type." - ::= { xATSSource2PhaseEntry 3 } - --- The xATSSystemOutput - -xATSSystemOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system output frequency in tenths of Hertz." - ::= { xATSSystemOutput 1 } - -xATSSystemOutputTotalPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kW." - ::= { xATSSystemOutput 2 } - -xATSSystemOutputTotalApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kVA." - ::= { xATSSystemOutput 3 } - -xATSSystemOutputTotalPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the total power factor of the system output. - A value of 100 representing a unity power factor (1.00) - Specified in hundredths." - ::= { xATSSystemOutput 4 } - -xATSSystemOutputFrequencyTolerance OBJECT-TYPE - SYNTAX INTEGER{ - freqToleranceOff (1), - freqTolerancePointTwo (2), - freqTolerancePointFive (3), - freqToleranceOne (4), - freqToleranceOnePointFive (5), - freqToleranceTwo (6), - freqToleranceThree (7), - freqToleranceFour (8), - freqToleranceFive (9), - freqToleranceNine (10) - - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Shows the panel output frequency tolerance in +/- Hertz." - ::= { xATSSystemOutput 5 } - -xATSSystemOutputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an output over voltage condition will be generated. - Specified as tenths of percent deviation from nominal. - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 6 } - -xATSSystemOutputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an output under voltage condition will be generated. - Specified as tenths of percent deviation from nominal. - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 7 } - -xATSSystemOutputOverCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an over current condition will be generated. - Specified as a percent of the transfer switch rating (xATSDeviceTransferSwitchRating OID). - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 8 } - -xATSSystemOutputUnderCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an under current condition will be generated. - Specified as a percent of the transfer switch rating (xATSDeviceTransferSwitchRating OID). - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 9 } - -xATSSystemOutputAlarmDelayThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Delay the generation of an output alarm. - Specified in seconds." - ::= { xATSSystemOutput 10 } - -xATSSystemOutputTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of system output phase entries." - ::= { xATSSystemOutput 11 } - -xATSSystemOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of system output table entries. - The number of entries is contained in the xATSSystemOutputTableSize OID." - ::= { xATSSystemOutput 12 } - - xATSSystemOutputPhaseEntry OBJECT-TYPE - SYNTAX XATSSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular system output phase." - INDEX { xATSSystemOutputPhaseIndex } - ::= { xATSSystemOutputTable 1 } - - XATSSystemOutputPhaseEntry ::= SEQUENCE { - xATSSystemOutputPhaseIndex INTEGER, - xATSSystemOutputVoltageLtoL INTEGER, - xATSSystemOutputVoltageLtoN INTEGER, - xATSSystemOutputPhaseCurrent INTEGER, - xATSSystemOutputPower INTEGER, - xATSSystemOutputApparentPower INTEGER, - xATSSystemOutputPowerFactor INTEGER - } - - xATSSystemOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each system output phase utilized in this device." - ::= { xATSSystemOutputPhaseEntry 1 } - - xATSSystemOutputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line system output voltage, measured in tenths of Volts, available at the circuit panel. - -1 if not available." - ::= { xATSSystemOutputPhaseEntry 2 } - - xATSSystemOutputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral system output voltage, measured in tenths of Volts, available at the circuit panel. - -1 for a 3-wire service type or if not available." - ::= { xATSSystemOutputPhaseEntry 3 } - - xATSSystemOutputPhaseCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System load current per phase. Measured in Amps. - -1 if not available." - ::= { xATSSystemOutputPhaseEntry 4 } - - xATSSystemOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System output power per phase. Measured in tenths of kW." - ::= { xATSSystemOutputPhaseEntry 5 } - - xATSSystemOutputApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "system output power per phase. Measured in tenths of kVA." - ::= { xATSSystemOutputPhaseEntry 6 } - - xATSSystemOutputPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "indicates the power factor of the system output per phase. - A value of 100 representing a unity power factor (1.00). - Measured in hundredths." - ::= { xATSSystemOutputPhaseEntry 7 } - --- xATS TestingStatus group - -xATSTestingStatusSelectTestProcess OBJECT-TYPE - SYNTAX INTEGER { - engineStartTest (1), - systemLoadTest (2), - generatorHoldTest (3), - cancelTest (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Type of tests that can be selected when no test has been scheduled. - engineStartTest and systemLoadTest may be selected when no tests - are running. Tests that are selected may be cancelled manually." - ::= { xATSTestingStatus 1 } - -xATSTestingStatusTestStatus OBJECT-TYPE - SYNTAX INTEGER { - noTestInProcess (1), - testPending (2), - startingEngine (3), - engineWarmingUp (4), - awaitingTransferToS2 (5), - testingWithLoad (6), - awaitingRetransferToS1 (7), - testingWithoutLoad (8), - stoppingEngine (9), - holdingOnGenerator (10) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The present system test status/state." - ::= { xATSTestingStatus 2 } - -xATSTestingStatusProfileWarmupTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time that the generator will warm up during a test. - This is portion of the test when the xATSTestingStatusTestStatus - OID returns the value engineWarmingUp. - Specified in seconds." - ::= { xATSTestingStatus 3 } - -xATSTestingStatusProfileLoadedTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time that ATS will apply the system load to the generator - during a system load test. - This is portion of the test when the xATSTestingStatusTestStatus - OID returns the value testingWithLoad. - Specified in minutes." - ::= { xATSTestingStatus 4 } - -xATSTestingStatusProfileUnloadedTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time that the generator will run following the warm up - portion of a start test, or the loaded portion of a load test. - This is portion of the test when the xATSTestingStatusTestStatus - OID returns the value testingWithoutLoad. - Specified in seconds." - ::= { xATSTestingStatus 5 } - --- xATS TestingResults group - -xATSTestingResultsLastDateOfTest OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Date of the last test that was performed, either scheduled or manual. - Test results are available in the xATSTestingResultsLastResult OID. - Specified in the dd/mm/yyyy format, or 'none' if not available." - ::= { xATSTestingResults 1 } - -xATSTestingResultsLastResult OBJECT-TYPE - SYNTAX INTEGER { - startTestPassed (1), - loadTestPassed (2), - startSignalFailure (3), - failedGenNotInAuto (4), - failedGenEmerStop (5), - failedGenShutdown (6), - failedGenDidNotStart (7), - failedS2NeverGood (8), - genFailedDuringWarmup (9), - failureOnXferToS1 (10), - genFailedLoaded (11), - failureOnRexferToS2 (12), - genFailedToStop (13), - failedAtsInternalFault (14), - failedAtsNotInAuto (15), - cancelledManualTest (16), - cancelledScheduledTest (17) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The result of the last ATS/generator system test." - ::= { xATSTestingResults 2 } - -xATSTestingResultsTestLastTestTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Time of day at which the last test was performed, either scheduled or manual. - Test results are available in the xATSTestingResultsLastResult OID. - Specified in the hh:mm:ss format, or 'none' if not available." - ::= { xATSTestingResults 3 } - -xATSTestingResultsLastCrankDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent cranking the generator before it started during the last test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 4 } - -xATSTestingResultsLastWarmupDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent in the engineWarmingUp state during the last system test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 5 } - -xATSTestingResultsLastLoadedDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent in the testingWithLoad state during the last system test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 6 } - -xATSTestingResultsLastUnloadedDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent in the testingWithoutLoad state during the last system test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 7 } - --- xATS TestingSchedule group - -xATSTestingScheduleFrequency OBJECT-TYPE - SYNTAX INTEGER { - never (1), - daily (2), - weekly (3), - monthly (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The frequency of running scheduled tests." - ::= { xATSTestingSchedule 1 } - -xATSTestingScheduleTestDay OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The desired day for the scheduled test. This object applies only - when the xATSTestingScheduleFrequency OID is set to weekly or monthly. - For weekly test frequency, the string is the day the test will be run. - For monthly test frequency, the string indicates the day, - and the instance within the month. - For example, for monthly frequency: 2nd sunday, 3rd monday, 4th tuesday, - for weekly frequency: sunday, monday, tuesday." - ::= { xATSTestingSchedule 2 } - -xATSTestingScheduleTestTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The time of day that the scheduled test will occur. - Specified in the format hh:mm." - ::= { xATSTestingSchedule 3 } - -xATSTestingScheduleTestWithLoadInterval OBJECT-TYPE - SYNTAX INTEGER { - applyLoadEveryTest (1), - neverApplyLoad (2), - applyLoadMonthly (3), - applyLoadMonthlyDetailed (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting specifies which system tests should include applying the - load to the generator. The applyLoadMonthlyDetailed entry - in the list will apply load once, for each month represented in the - xATSTestingScheduleTestWithLoadSelectMonth OID." - ::= { xATSTestingSchedule 4 } - -xATSTestingScheduleTestWithLoadSelectMonth OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The detailed selection for testing with load on a month-by-month basis. - This object is applicable when the xATSTestingScheduleTestWithLoadInterval - is set to applyLoadMonthlyDetailed. Otherwise this selection will be ignored. - Format for this string is a comma-separated entry of months. - For example: Jan,Mar,Dec. - The string will return 'No Months Scheduled' if no months have been selected." - ::= { xATSTestingSchedule 5 } - -xATSTestingScheduleNextTestDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the next scheduled test, in the format dd-mmm-yyyy." - ::= { xATSTestingSchedule 6 } - --- xATSTestingSimulatePowerFail group - -xATSTestingSimulatePowerFailTest OBJECT-TYPE - SYNTAX INTEGER{ - cancelSimulation (1), - fiveSecondsSimulation (2), - tenSecondsSimulation (3), - thirtySecondsSimulation (4), - oneMinuteSimulation (5), - threeMinutesSimulation (6), - fiveMinutesSimulation (7), - tenMinutesSimulation (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This object executes a simulated power failure for the duration indicated. - Simulation can be aborted by selecting cancelSimulation." - ::= { xATSTestingSimulatePowerFail 1 } - -xATSTestingSimulatePowerFailTimeRemaining OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the time remaining in seconds, for a simulated power failure. - a value of zero indicates that simulated power failure is not active." - ::= { xATSTestingSimulatePowerFail 2 } - --- The xATS Input Contact group - -xATSInputContactNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the ATS." - ::= { xATSInputContacts 1 } - -xATSInputContactTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input contact entries." - ::= { xATSInputContacts 2 } - -xATSInputContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the ATS. - The number of entries is contained in the - xATSInputContactTableSize OID." - ::= { xATSInputContacts 3 } - - xATSInputContactEntry OBJECT-TYPE - SYNTAX XATSContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A contact entry containing information for a given contact." - INDEX { xATSInputContactNumber } - ::= { xATSInputContactTable 1 } - - XATSContactEntry ::= - SEQUENCE { - xATSInputContactNumber INTEGER, - xATSInputContactName DisplayString, - xATSInputContactNormalState INTEGER, - xATSInputContactCurrentState INTEGER - } - - xATSInputContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the contact on the ATS." - ::= { xATSInputContactEntry 1 } - - xATSInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the contact." - ::= { xATSInputContactEntry 2 } - - xATSInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the contact." - ::= { xATSInputContactEntry 3 } - - xATSInputContactCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the contact." - ::= { xATSInputContactEntry 4 } - --- the xATS OutputRelays group - - xATSOutputRelayNumRelays OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relays supported by the ATS." - ::= { xATSOutputRelays 1 } - - xATSOutputRelayTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relay entries." - ::= { xATSOutputRelays 2 } - - xATSOutputRelayTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output relays supported by the ATS. - The number of entries is contained in the - xATSOutputRelayTableSize OID." - ::= { xATSOutputRelays 3 } - - xATSOutputRelayEntry OBJECT-TYPE - SYNTAX XATSOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A output relay entry containing information for a given contact." - INDEX { xATSOutputRelayNumber } - ::= { xATSOutputRelayTable 1 } - - XATSOutputRelayEntry ::= - SEQUENCE { - xATSOutputRelayNumber INTEGER, - xATSOutputRelayName DisplayString, - xATSOutputRelayNormalState INTEGER, - xATSOutputRelayCurrentState INTEGER - } - - xATSOutputRelayNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the output relay on the ATS." - ::= { xATSOutputRelayEntry 1 } - - xATSOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the output relay." - ::= { xATSOutputRelayEntry 2 } - - xATSOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the output relay." - ::= { xATSOutputRelayEntry 3 } - - xATSOutputRelayCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the output relay." - ::= { xATSOutputRelayEntry 4 } - --- The xATS Generator Ident group - -xATSGeneratorIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of the generator. - This value is set at the factory." - ::= { xATSGeneratorIdent 1 } - -xATSGeneratorIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of the generator. - This value is set at the factory." - ::= { xATSGeneratorIdent 2 } - -xATSGeneratorIdentDateofManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying when the generator was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { xATSGeneratorIdent 3 } - -xATSGeneratorIdentVoltageConfiguration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The voltage for which the generator's alternator is designed. - Specified in Volts line-to-line." - ::= { xATSGeneratorIdent 4 } - -xATSGeneratorIdentMaxPowerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The max power rating of the generator. Specified in kW." - ::= { xATSGeneratorIdent 5 } - -xATSGeneratorIdentAlternatorFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency for which the generator's alternator is designed. - Specified in Hertz." - ::= { xATSGeneratorIdent 6 } - --- The xATS Generator Status group - -xATSGeneratorStatusGeneratorName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name or label for the generator connected to the source 2 of the ATS." - ::= { xATSGeneratorStatus 1 } - -xATSGeneratorStatusOperational OBJECT-TYPE - SYNTAX INTEGER{ - nocomm (1), - off (2), - ready (3), - starting (4), - idle (5), - running (6), - normalStop (7), - emergencyStop (8), - notInAuto (9), - shutdown (10), - unknown (11) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The operational status of the generator. unavailable when unrecognized status is received." - ::= { xATSGeneratorStatus 2 } - -xATSGeneratorStatusModeSwitchPosition OBJECT-TYPE - SYNTAX INTEGER{ - off (1), - manual (2), - automatic (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The position of the generator's auto-mode switch. - In automatic mode, the generator is started and stopped via the - remote start contact, which has state indicated in the - xATSGeneratorStatusRemoteStart OID. - In manual mode generator start/stop control is via local command only. - Off prevents the generator from running." - ::= { xATSGeneratorStatus 3 } - -xATSGeneratorStatusRemoteStart OBJECT-TYPE - SYNTAX INTEGER{ - stop (1), - run (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the generator's remote start contact, which is - provided as an output from the transfer switch to start/stop the - generator when in automatic mode." - ::= { xATSGeneratorStatus 4 } - --- The xATS Generator Advanced Status group - -xATSGeneratorAdvStatusBatteryVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The voltage of the generator's starting battery. - Measured in tenths of VDC, or -1 if not available." - ::= { xATSGeneratorAdvStatus 1 } - -xATSGeneratorAdvStatusOilPressure OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The generator's engine oil pressure. - Measured in tenths of Psi or kPa, based on the - value of the xATSGeneratorSettingsMetricUnit OID, - or -1 if not available." - ::= { xATSGeneratorAdvStatus 2 } - -xATSGeneratorAdvStatusCoolantTemperature OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Current coolant temperature in the generator. - Measured in degrees Celsius or Fahrenheit, based on the - value of the xATSGeneratorSettingsMetricUnit OID, - or -1 if not available." - ::= { xATSGeneratorAdvStatus 3 } - -xATSGeneratorAdvStatusEngineRPM OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Current engine speed of the generator. - Measured in RPM, or -1 if not available." - ::= { xATSGeneratorAdvStatus 4 } - -xATSGeneratorAdvStatusOilLevel OBJECT-TYPE - SYNTAX INTEGER{ - ok (1), - low (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates adequate oil level in the generator." - ::= { xATSGeneratorAdvStatus 5 } - -xATSGeneratorAdvStatusCoolantLevel OBJECT-TYPE - SYNTAX INTEGER{ - ok (1), - low (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates adequate coolant level in the generator." - ::= { xATSGeneratorAdvStatus 6 } - --- The xATS Generator Output group - -xATSGeneratorOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output frequency of the generator. - Measured in tenths of Hertz, or -1 if not avaialble." - ::= { xATSGeneratorOutput 1 } - -xATSGeneratorOutputTotalPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total output power of the generator. - Measured in tenths of tenths of kW, or -1 if not avaialble." - ::= { xATSGeneratorOutput 2 } - -xATSGeneratorOutputTotalApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total output power of the generator. - Measured in tenths of kVA, or -1 if not avaialble." - ::= { xATSGeneratorOutput 3 } - -xATSGeneratorOutputTotalPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the total load power factor of the generator. - A value of 100 representing a unity power factor (1.00), - or -1 when if not avaialble." - ::= { xATSGeneratorOutput 4 } - -xATSGeneratorOutputTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of generator output phase entries." - ::= { xATSGeneratorOutput 5 } - - xATSGeneratorOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSGeneratorOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of generator output table entries. - The number of entries is contained in the xATSGeneratorOutputTableSize OID." - ::= { xATSGeneratorOutput 6 } - - xATSGeneratorOutputPhaseEntry OBJECT-TYPE - SYNTAX XATSGeneratorOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular generator output phase." - INDEX { xATSGeneratorOutputPhaseIndex } - ::= { xATSGeneratorOutputTable 1 } - - XATSGeneratorOutputPhaseEntry ::= SEQUENCE { - xATSGeneratorOutputPhaseIndex INTEGER, - xATSGeneratorOutputVoltageLtoL INTEGER, - xATSGeneratorOutputVoltageLtoN INTEGER, - xATSGeneratorOutputPhaseCurrent INTEGER, - xATSGeneratorOutputPower INTEGER, - xATSGeneratorOutputApparentPower INTEGER, - xATSGeneratorOutputPowerFactor INTEGER - } - - xATSGeneratorOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each generator output phase utilized in this device." - ::= { xATSGeneratorOutputPhaseEntry 1 } - - xATSGeneratorOutputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line generator output voltage. - Measured in Volts, or -1 if not available." - ::= { xATSGeneratorOutputPhaseEntry 2 } - - xATSGeneratorOutputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral generator output voltage. - Measured in volts, or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 3 } - - xATSGeneratorOutputPhaseCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Generator load current per phase. - Measured in Amps, or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 4 } - - xATSGeneratorOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Generator output power per phase. - Measured in tenths of kW, or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 5 } - - xATSGeneratorOutputApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Generator output power per phase. - Measured in tenths of kVA, or -1 if not available." - ::= { xATSGeneratorOutputPhaseEntry 6 } - - xATSGeneratorOutputPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the load power factor of the generator output per phase. - A value of 100 representing a unity power factor (1.00), - or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 7 } - --- xATS Generator Settings group - -xATSGeneratorSettingsVoltageAdjust OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The voltage adjust of the generator. - Specified in volts line-to-line, - or -1 if not available." - ::= { xATSGeneratorSettings 1 } - -xATSGeneratorSettingsFrequencyAdjust OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency adjust of the generator. - Specified in tenths of Hertz." - ::= { xATSGeneratorSettings 2 } - -xATSGeneratorSettingsStartDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The delay, in seconds, after the remote run signal is activated - before the generator's engine will be cranked to start, - or -1 if not available." - ::= { xATSGeneratorSettings 3 } - -xATSGeneratorSettingsStopDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The delay, in seconds, before the generator will stop - after the remote run signal is deactivated, - or -1 if not available." - ::= { xATSGeneratorSettings 4 } - -xATSGeneratorSettingsCrankCycleEnable OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - enabled (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When Crank Cycle is enabled, the engine will be cranked up to the time - specified by the xATSGeneratorSettingsCrankTime OID. - If the generator's engine does not start, there will be a pause as - specified by the xATSGeneratorSettingsCrankRestTime OID before the - engine will be cranked again. This cycle is repeated as specified by - the xATSGeneratorSettingsNumberCrank OID. - When crank cycle is disabled, the generator's engine will be - cranked continuously until it starts." - ::= { xATSGeneratorSettings 5 } - -xATSGeneratorSettingsCrankTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The duration of engine cranking, in seconds, when starting the generator. - Applicable when the xATSGeneratorSettingsCrankCycleEnable OID is enabled. - -1 if not available." - ::= { xATSGeneratorSettings 6 } - -xATSGeneratorSettingsCrankRestTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The pause duration, in seconds, following an unsuccessful attempt to start the generator. - Applicable when the xATSGeneratorSettingsCrankCycleEnable OID is enabled. - -1 if not available." - ::= { xATSGeneratorSettings 7 } - -xATSGeneratorSettingsNumberCrank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of failed crank attempts before giving up on starting the generator. - Applicable when the xATSGeneratorSettingsCrankCycleEnable OID is enabled. - -1 if not available." - ::= { xATSGeneratorSettings 8 } - -xATSGeneratorSettingsMetricUnit OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - enabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Specifies the use of metric units in generator related OIDs, as well - as on all other interfaces including the generator's local interface." - ::= { xATSGeneratorSettings 9 } - --- xATS generator service group - -xATSGeneratorServiceTotalRunHoursLifetime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total time that the generator engine has been run, - over the life of the generator. Measured in hours. - -1 if not available." - ::= { xATSGeneratorService 1 } - -xATSGeneratorServiceEngineStartsLifetime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Number of engine starts over the life of the generator. - -1 if not available." - ::= { xATSGeneratorService 2 } - -xATSGeneratorServiceTotalkWhLifetime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total kWh of operation over the life of the generator. - -1 if not available." - ::= { xATSGeneratorService 3 } - -xATSGeneratorServiceTotalRunHoursSinceMaintanence OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total time that the generator engine has been run, - since last service maintenance. Measured in tenths of hours. - -1 if not available." - ::= { xATSGeneratorService 4 } - -xATSGeneratorServiceEngineStartsSinceMaintanence OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Number of engine starts since last service maintenance. - -1 if not available." - ::= { xATSGeneratorService 5 } - -xATSGeneratorServiceTotalkWhMaintanence OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total kWh of operation since last service maintenance. - -1 if not available." - ::= { xATSGeneratorService 6 } - -xATSGeneratorServiceResetRecord OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Resets the engine start counter, engine run-hours, and kWh values that have - accumulated in the generator since last maintenance. - Also, the last service date will be reset to the current system date, and - any service alarms will be cleared." - ::= { xATSGeneratorService 7 } - -xATSGeneratorServiceRecordResetDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Date at which the generator's service record was reset, in dd-mmm-yyyy format." - ::= { xATSGeneratorService 8 } - -xATSGeneratorServiceNextServiceDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Date at which the next generator service is due in dd-mmm-yyyy format. - Based on the xATSGeneratorServiceCalendarIntervalThreshold OID - or '' if the calander-based threshold is set to off." - ::= { xATSGeneratorService 9 } - -xATSGeneratorServiceRunHoursUntilServiceDate OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Runhours until the next generator service is due, in hours. - Based on the xATSGeneratorServiceRunHoursThreshold OID - or -1 if the runhour-based threshold is set to off." - ::= { xATSGeneratorService 10 } - -xATSGeneratorServiceRunHoursThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - runThreshold100Hours (2), - runThreshold150Hours (3), - runThreshold200Hours (4), - runThreshold250Hours (5), - runThreshold300Hours (6), - runThreshold400Hours (7), - runThreshold500Hours (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Runhour-based service interval. When the run-hours since - service surpasses this threshold, generator service is due." - ::= { xATSGeneratorService 11 } - -xATSGeneratorServiceCalendarIntervalThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - interval1month (2), - interval2month (3), - interval3month (4), - interval6month (5), - intervalyearly (6) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Calander-based service interval. When the next service date, - as indicated by the xATSGeneratorServiceNextServiceDate OID - is in the past, generator is due for service." - ::= { xATSGeneratorService 12 } - --- The xATS Generator Fuel system group - -xATSGeneratorFuelSystemType OBJECT-TYPE - SYNTAX INTEGER{ - diesel (1), - propane (2), - naturalGas (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of fuel used by the generator." - ::= { xATSGeneratorFuelSystem 1 } - -xATSGeneratorFuelSystemTankSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Size of the generator's fuel tank. - Specified in gallons or liters, based on the value of the - xATSGeneratorSettingsMetricUnit OID, or -1 if not available." - ::= { xATSGeneratorFuelSystem 2 } - -xATSGeneratorFuelSystemFuelLevel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Fuel remaining in the generator tank. - Measured in percent of tank fill, or -1 if if not available." - ::= { xATSGeneratorFuelSystem 3 } - -xATSGeneratorFuelSystemRuntimePower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The power value used in the runtime remaining calculation. - Measured in tenths of kW, or -1 if not available." - ::= { xATSGeneratorFuelSystem 4 } - -xATSGeneratorFuelSystemEstimatedRunTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An estimate of available runtime for the generator, based on - available fuel as specified in the xATSGeneratorFuelSystemFuelLevel OID - and kW load as specified in the xATSGeneratorFuelSystemRuntimePower OID. - Measured in tenths of hours, or -1 if not available." - ::= { xATSGeneratorFuelSystem 5 } - -xATSGeneratorFuelSystemLowRunTimeThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - oneHour (2), - twoHours (3), - threeHours (4), - fourHours (5), - fiveHours (6), - sixHours (7), - twelveHours (8), - oneDay (9), - twoDays (10), - threeDays (11), - fourDays (12), - fiveDays (13), - sixDays (14), - sevenDays (15) - - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a low runtime alarm will exist." - ::= { xATSGeneratorFuelSystem 6 } - -xATSGeneratorFuelSystemVeryLowRunTimeThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - oneHour (2), - twoHours (3), - threeHours (4), - fourHours (5), - fiveHours (6), - sixHours (7), - twelveHours (8), - oneDay (9), - twoDays (10), - threeDays (11), - fourDays (12), - fiveDays (13), - sixDays (14), - sevenDays (15) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a very low runtime alarm will exist." - ::= { xATSGeneratorFuelSystem 7 } - -xATSGeneratorFuelSystemLowFuelLevelThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a low fuel alarm will exist, with a value of 0 indicating disabled. - Specified as percent of tank fill." - ::= { xATSGeneratorFuelSystem 8 } - -xATSGeneratorFuelSystemVeryLowFuelLevelThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a very low fuel alarm will exist, with a value of 0 indicating disabled. - Specified as percent of tank fill." - ::= { xATSGeneratorFuelSystem 9 } - --- the software group --- the powerNetSubAgent group --- the powerNetSoftwareSystem group - -powerNetSoftwareSystemDescription OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..79)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A brief description of the PowerNet sub-agent." - ::= { powerNetSoftwareSystem 1 } - -powerNetSoftwareOid OBJECT-TYPE - SYNTAX OBJECT IDENTIFIER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The object identifier of the PowerNet sub-agent." - ::= { powerNetSoftwareSystem 2 } - --- powerNetSmuxPeer OBJECT IDENTIFIER ::= { powerNetSoftwareOid 1 } --- powerNetDPIPeer OBJECT IDENTIFIER ::= { powerNetSoftwareOid 2 } - -powerNetSoftwareSystemUpTime OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time that the sub-agent has been running." - ::= { powerNetSoftwareSystem 3 } - - --- powerNetSoftwareConfig group - -powerNetSoftwareTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of software modules supporting the UPS." - ::= { powerNetSoftwareConfig 1 } - -powerNetSoftwareTable OBJECT-TYPE - SYNTAX SEQUENCE OF SoftwareEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of the software monitoring the UPS." - ::= { powerNetSoftwareConfig 2 } - -powerNetSoftwareEntry OBJECT-TYPE - SYNTAX SoftwareEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information on a software module." - INDEX { moduleNumber } - ::= { powerNetSoftwareTable 1 } - -SoftwareEntry ::= - SEQUENCE { - moduleNumber - INTEGER, - moduleName - DisplayString, - moduleVersion - DisplayString, - moduleDate - DisplayString - } - -moduleNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index into the Software Entry Table" - ::= { powerNetSoftwareEntry 1 } - -moduleName OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..79)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the software module." - ::= { powerNetSoftwareEntry 2 } - -moduleVersion OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..8)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The version of the software module." - ::= { powerNetSoftwareEntry 3 } - -moduleDate OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..9)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the software module represented as mm-dd-yy." - ::= { powerNetSoftwareEntry 4 } - - --- the ups group --- the upsIdent group --- the upsBasicIdent - -upsBasicIdentModel OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The UPS model name (e.g. 'APC Smart-UPS 600')." - ::= { upsBasicIdent 1 } - -upsBasicIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An 8 byte ID string identifying the UPS. This object - can be set by the administrator." - ::= { upsBasicIdent 2 } - - --- the upsAdvIdent group - -upsAdvIdentFirmwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the UPS system's microprocessor." - ::= { upsAdvIdent 1 } - -upsAdvIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the UPS was manufactured in mm/dd/yy format." - ::= { upsAdvIdent 2 } - -upsAdvIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 8-character string identifying the serial number of - the UPS internal microprocessor. This number is set at - the factory. NOTE: This number does NOT correspond to - the serial number on the rear of the UPS." - ::= { upsAdvIdent 3 } - - - --- the upsBattery group --- the upsBasicBattery group - -upsBasicBatteryStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - batteryNormal(2), - batteryLow(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the UPS batteries. A batteryLow(3) - value indicates the UPS will be unable to sustain the - current load, and its services will be lost if power is - not restored. The amount of run time in reserve at the - time of low battery can be configured by the - upsAdvConfigLowBatteryRunTime." - ::= { upsBasicBattery 1 } - -upsBasicBatteryTimeOnBattery OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The elapsed time since the UPS has switched to battery - power." - ::= { upsBasicBattery 2 } - -upsBasicBatteryLastReplaceDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The date when the UPS system's batteries were last replaced - in mm/dd/yy format. For Smart-UPS models, this value - is originally set in the factory. When the UPS batteries - are replaced, this value should be reset by the administrator." - ::= { upsBasicBattery 3 } - - - --- the upsAdvBattery group - -upsAdvBatteryCapacity OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remaining battery capacity expressed in - percent of full capacity." - ::= { upsAdvBattery 1 } - -upsAdvBatteryTemperature OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current internal UPS temperature expressed in - Celsius." - ::= { upsAdvBattery 2 } - -upsAdvBatteryRunTimeRemaining OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The UPS battery run time remaining before battery - exhaustion." - ::= { upsAdvBattery 3 } - -upsAdvBatteryReplaceIndicator OBJECT-TYPE - SYNTAX INTEGER { - noBatteryNeedsReplacing(1), - batteryNeedsReplacing(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether the UPS batteries need replacing." - ::= { upsAdvBattery 4 } - -upsAdvBatteryNumOfBattPacks OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of external battery packs connected to the UPS. If - the UPS does not use smart cells then the agent reports - ERROR_NO_SUCH_NAME." - ::= { upsAdvBattery 5 } - -upsAdvBatteryNumOfBadBattPacks OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of external battery packs connected to the UPS that - are defective. If the UPS does not use smart cells then the - agent reports ERROR_NO_SUCH_NAME." - ::= { upsAdvBattery 6 } - -upsAdvBatteryNominalVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal battery voltage in Volts." - ::= { upsAdvBattery 7 } - -upsAdvBatteryActualVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The actual battery bus voltage in Volts." - ::= { upsAdvBattery 8 } - -upsAdvBatteryCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery current in Amps." - ::= { upsAdvBattery 9 } - -upsAdvTotalDCCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total DC current in Amps." - ::= { upsAdvBattery 10 } - - --- the upsBasicInput group - -upsBasicInputPhase OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current AC input phase." - ::= { upsBasicInput 1 } - - --- the upsAdvInput group - -upsAdvInputLineVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current utility line voltage in VAC." - ::= { upsAdvInput 1 } - -upsAdvInputMaxLineVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum utility line voltage in VAC over the - previous 1 minute period." - ::= { upsAdvInput 2 } - -upsAdvInputMinLineVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum utility line voltage in VAC over the - previous 1 minute period." - ::= { upsAdvInput 3 } - -upsAdvInputFrequency OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current input frequency to the UPS system in Hz." - ::= { upsAdvInput 4 } - - -upsAdvInputLineFailCause OBJECT-TYPE - SYNTAX INTEGER { - noTransfer(1), - highLineVoltage(2), - brownout(3), - blackout(4), - smallMomentarySag(5), - deepMomentarySag(6), - smallMomentarySpike(7), - largeMomentarySpike(8), - selfTest(9), - rateOfVoltageChnage(10) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The reason for the occurrence of the last transfer to UPS - battery power. The variable is set to: - - noTransfer(1) -- if there is no transfer yet. - - highLineVoltage(2) -- if the transfer to battery is caused - by an over voltage greater than the high transfer voltage. - - brownout(3) -- if the duration of the outage is greater than - five seconds and the line voltage is between 40% of the - rated output voltage and the low transfer voltage. - - blackout(4) -- if the duration of the outage is greater than five - seconds and the line voltage is between 40% of the rated - output voltage and ground. - - smallMomentarySag(5) -- if the duration of the outage is less - than five seconds and the line voltage is between 40% of the - rated output voltage and the low transfer voltage. - - deepMomentarySag(6) -- if the duration of the outage is less - than five seconds and the line voltage is between 40% of the - rated output voltage and ground. The variable is set to - - smallMomentarySpike(7) -- if the line failure is caused by a - rate of change of input voltage less than ten volts per cycle. - - largeMomentarySpike(8) -- if the line failure is caused by - a rate of change of input voltage greater than ten volts per cycle. - - selfTest(9) -- if the UPS was commanded to do a self test. - - rateOfVoltageChange(10) -- if the failure is due to the rate of change of - the line voltage." - ::= { upsAdvInput 5 } - - --- the upsBasicOutput group - -upsBasicOutputStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - onLine(2), - onBattery(3), - onSmartBoost(4), - timedSleeping(5), - softwareBypass(6), - off(7), - rebooting(8), - switchedBypass(9), - hardwareFailureBypass(10), - sleepingUntilPowerReturn(11), - onSmartTrim(12) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current state of the UPS. If the UPS is unable - to determine the state of the UPS this variable is set - to unknown(1)." - ::= { upsBasicOutput 1 } - -upsBasicOutputPhase OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current output phase." - ::= { upsBasicOutput 2 } - - --- the upsAdvOutput group - -upsAdvOutputVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage of the UPS system in VAC." - ::= { upsAdvOutput 1 } - -upsAdvOutputFrequency OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current output frequency of the UPS system in Hz." - ::= { upsAdvOutput 2 } - -upsAdvOutputLoad OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current UPS load expressed in percent - of rated capacity." - ::= { upsAdvOutput 3 } - -upsAdvOutputCurrent OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current in amperes drawn by the load on the UPS." - ::= { upsAdvOutput 4 } - - --- the upsBasicConfig group - -upsBasicConfigNumDevices OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of devices that are plugged into the UPS." - ::= { upsBasicConfig 1 } - -upsBasicConfigDeviceTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsBasicConfigDeviceEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of devices that are plugged into the UPS. - The number of entries is given by the value of - upsBasicConfigNumDevices." - ::= { upsBasicConfig 2 } - -upsBasicConfigDeviceEntry OBJECT-TYPE - SYNTAX UpsBasicConfigDeviceEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The devices plugged in to the UPS." - INDEX { deviceIndex } - ::= { upsBasicConfigDeviceTable 1 } - -UpsBasicConfigDeviceEntry ::= - SEQUENCE { - deviceIndex - INTEGER, - deviceName - DisplayString, - vaRating - INTEGER, - acceptThisDevice - INTEGER - } - -deviceIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the device that is plugged into the UPS." - ::= { upsBasicConfigDeviceEntry 1 } - -deviceName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name/description of the device plugged into the UPS." - ::= { upsBasicConfigDeviceEntry 2 } - -vaRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The volt-amp rating of the device plugged into the UPS." - ::= { upsBasicConfigDeviceEntry 3 } - -acceptThisDevice OBJECT-TYPE - SYNTAX INTEGER { - yes(1), - no(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An entry is added if yes, the entry is deleted if no." - ::= { upsBasicConfigDeviceEntry 4 } - - - - --- the upsAdvConfig group - -upsAdvConfigRatedOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The nominal output voltage from the UPS in VAC. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { upsAdvConfig 1 } - -upsAdvConfigHighTransferVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum line voltage in VAC allowed before the - UPS system transfers to battery backup. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 2 } - -upsAdvConfigLowTransferVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum line voltage in VAC allowed before the - UPS system transfers to battery backup. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { upsAdvConfig 3 } - -upsAdvConfigAlarm OBJECT-TYPE - SYNTAX INTEGER { - timed(1), - atLowBattery(2), - never(3), - mute(4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A flag indicating how the UPS should handle audible - line fail alarms: - timed(1): UPS alarm will sound after a preset timed duration starting - from the line fail condition (see OID upsAdvConfigAlarmTimer for the - alarm timer value) - atLowBattery(2): UPS alarm will sound when the UPS has reached a Low - Battery condition during a line fail - never(3): Disables the UPS audible alarm - mute(4): Mutes the current alarm for some UPSs only when it is in an - alarm state and will return to the previously configured option when - the UPS recovers from the alarm condition" - ::= { upsAdvConfig 4 } - -upsAdvConfigAlarmTimer OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The time after initial line failure at which the UPS - begins emitting audible alarms (beeping). This timer is - observed only if the value of extControlAlarm is timed(2). - Allowed values are 0 or 30 seconds. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { upsAdvConfig 5 } - -upsAdvConfigMinReturnCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum battery capacity required before the UPS will - return from a low battery shutdown condition. The capacity is - measured from 0% battery capacity (or Low Battery) as a percent - of full capacity (100%). In other words, the UPS will not re-energize - the output until the battery has charged so that its' capacity is equal - to this value. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 6 } - -upsAdvConfigSensitivity OBJECT-TYPE - SYNTAX INTEGER { - auto(1), - low(2), - medium(3), - high(4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The sensitivity of the UPS to utility line abnormalities - or noises." - ::= { upsAdvConfig 7 } - -upsAdvConfigLowBatteryRunTime OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The desired run time of the UPS, in seconds, once the - low battery condition is reached. During this time the UPS will - produce a constant warning tone which can not be disabled. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a set - request, the UPS interprets the value as the next higher - acceptable value. If the provided value is higher than the - highest acceptable value, the highest acceptable value is used." - ::= { upsAdvConfig 8 } - -upsAdvConfigReturnDelay OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay in seconds after utility line power returns - before the UPS will turn on. This value is also used - when the UPS comes out of a reboot and before the UPS - wakes up from 'sleep' mode. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 9 } - -upsAdvConfigShutoffDelay OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay in seconds the UPS remains on after being told - to turn off. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 10 } - -upsAdvConfigUpsSleepTime OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The time in seconds for the UPS to go to 'sleep' when - instructed. When in sleep mode, the UPS will not provide - output power regardless of the input line state. Once the - specified time has elapsed, output power will be restored. - - This is a configuration setting. The UPS will not go to - sleep until told to do so by the manager from a management - station. - - Any input value is allowed, however the UPS only recognizes - 1/10 of an hour increments. The provided value will be - rounded to the closest 1/10 of an hour with one exception: - Any value entered between 1 and 540 seconds will be rounded - to 360 seconds (or 6 minutes)." - ::= { upsAdvConfig 11 } - - -upsAdvConfigSetEEPROMDefaults OBJECT-TYPE - SYNTAX INTEGER { - noSetEEPROMDefaults(1), - setEEPROMDefaults(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "WRITE: Resets the UPS EEPROM variables to default values. - READ: returns 0" - ::= { upsAdvConfig 12 } - -upsAdvConfigDipSwitchSetting OBJECT-TYPE - SYNTAX SEQUENCE OF UpsAdvConfigDipSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Current settings of UPS dip switches." - ::= { upsAdvConfig 13 } - -upsAdvConfigDipSwitchEntry OBJECT-TYPE - SYNTAX UpsAdvConfigDipSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The current setting of one dip switch." - INDEX { dipSwitchIndex } - ::= { upsAdvConfigDipSwitchSetting 1 } - -UpsAdvConfigDipSwitchEntry ::= - SEQUENCE { - dipSwitchIndex - INTEGER, - dipSwitchStatus - INTEGER - } - -dipSwitchIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a UPS dip switch." - ::= { upsAdvConfigDipSwitchEntry 1 } - -dipSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - on(1), - off(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The setting of a UPS dip switch." - ::= { upsAdvConfigDipSwitchEntry 2 } - -upsAdvConfigBattExhaustThresh OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of seconds prior to battery exhaustion when the - UPS will switch off power to its load." - ::= { upsAdvConfig 14 } - -upsAdvConfigPassword OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The password entered at the UPS front panel to enable local - configuration of the EEProm. If the password is disabled or - is not supported, then the agent returns a null string." - ::= { upsAdvConfig 15 } - -upsAdvConfigAllowedSetTable OBJECT-TYPE - SYNTAX SEQUENCE OF ApcUpsConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The table listing the allowed values for all discrete - configurable UPS variables." - ::= { upsAdvConfig 16 } - -apcUpsConfigEntry OBJECT-TYPE - SYNTAX ApcUpsConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The table entry for a configurable UPS variable." - INDEX { apcUpsConfigFieldIndex } - ::= { upsAdvConfigAllowedSetTable 1 } - -ApcUpsConfigEntry ::= SEQUENCE { - apcUpsConfigFieldIndex INTEGER, - apcUpsConfigFieldOID OBJECT IDENTIFIER, - apcUpsConfigFieldValueRange DisplayString - } - -apcUpsConfigFieldIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to an eeprom field entry." - ::= { apcUpsConfigEntry 1 } - -apcUpsConfigFieldOID OBJECT-TYPE - SYNTAX OBJECT IDENTIFIER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The OID of the current configurable value." - ::= { apcUpsConfigEntry 2 } - -apcUpsConfigFieldValueRange OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The discrete set of allowed values of a configurable - register. Individual values are delimited by a comma." - ::= { apcUpsConfigEntry 3 } - -upsAdvConfigBattCabAmpHour OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS battery cabinet amp hour setting." - ::= { upsAdvConfig 17 } - -upsAdvConfigPositionSelector OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - rack (2), - tower (3) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure UPS position selector. If the UPS doesn't - support this configuration it will report unknown (1). - The positions are either rack (2) for rack mounted or - tower (3) for tower unit." - ::= { upsAdvConfig 18 } - -upsAdvConfigOutputFreqRange OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - freqRangeAUTO (2), - freqRange60Var1 (3), - freqRange60Var3 (4), - freqRange50Var1 (5), - freqRange50Var3 (6), - freqRange60Var10 (7), - freqRange50Var10 (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the output frequency tolerance range. - unknown(1) indicates the output frequency is unknown. - freqRangeAUTO(2) configure the output frequency range for automatic. - freqRange60Var1(3) configure the output frequency range for 60 +/- 0.1 Hz - freqRange60Var3(4) configure the output frequency range for 60 +/- 3.0 Hz - freqRange50Var1(5) configure the output frequency range for 50 +/- 0.1 Hz - freqRange50Var3(6) configure the output frequency range for 50 +/- 3.0 Hz - freqRange60Var10(7) configure the output frequency range for 60 +/- 10 Hz - freqRange50Var10(8) configure the output frequency range for 50 +/- 10 Hz" - ::= { upsAdvConfig 19 } - -upsAdvConfigUPSFail OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - gotoBypass (2), - dropLoad (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the UPS fail action. If UPS fails, - and frequency or voltage is out of range it will either - GotoBypass (2) or DropLoad (3). This OID will report - unknown (1) if it is not supported feature or option." - ::= { upsAdvConfig 20 } - -upsAdvConfigAlarmRedundancy OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS alarm if the redundancy is - under the current redundancy. Use -1 for never." - ::= { upsAdvConfig 21 } - -upsAdvConfigAlarmLoadOver OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS alarm if the load is - over the current load in kVA. Use -1 for never." - ::= { upsAdvConfig 22 } - -upsAdvConfigAlarmRuntimeUnder OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS alarm if the runtime is - under the current time of minutes. Use -1 for never." - ::= { upsAdvConfig 23 } - -upsAdvConfigVoutReporting OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - voutAUTO (2), - vout208 (3), - vout240 (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the way the UPS scales its output voltage readings. - unknown(1) indicates the Vout Reporting is unknown. - voutAUTO(2) configure the Vout Reporting for automatic scalling. - vout208(3) configure the Vout Reporting for 208 Volts. - vout240(4) configure the Vout Reporting for 240 Volts." - ::= { upsAdvConfig 24 } - -upsAdvConfigNumExternalBatteries OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the number of external batteries connected to the UPS." - ::= { upsAdvConfig 25 } - -upsAdvConfigSimpleSignalShutdowns OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - disabled (2), - enabled (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure Simple Signal shutdown commands from the Simple Signal - port to be issued to the UPS. - unknown(1) indicates the Simple Signal Shutdown setting is unknown. - disabled(2) configure to disable Simple Signal Shutdowns. - enabled(3) configure to enable Simple Signal Shutdowns." - ::= { upsAdvConfig 26 } - - --- the upsSyncCtrlGroupConfig group - -upsSCGMembershipGroupNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The SCG Membership Group number (MGN) is a 16-bit number allowing - up to 65534 separate groups that can be identified and distinguished - per IP subnet. Zero and 65535 are not used. The MGN is used in all - communication between members of the SCG and a Network Management Card - (NMC) will listen and only respond to commands sent to it using its - configured SCG ID." - ::= { upsSyncCtrlGroupConfig 1 } - -upsSCGActiveMembershipStatus OBJECT-TYPE - SYNTAX INTEGER { - enabledSCG (1), - disabledSCG (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Membership in the configured SCG can be enabled and - disabled. If an NMC is configured for an SCG, but - has its membership disabled, all synchronized control commands - received will be ignored." - ::= { upsSyncCtrlGroupConfig 2 } - -upsSCGPowerSynchronizationDelayTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The Power Synchronization Delay Time (PSD) setting is the maximum - number of seconds an SCG Initiator will wait for all SCG members to - recover utility power before completing the reboot sequence of a - reboot or sleep command. If all SCG members are ready to proceed, - no additional delay is introduced." - ::= { upsSyncCtrlGroupConfig 3 } - -upsSCGReturnBatteryCapacityOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A reboot command uses the Initiator�s Return battery Capacity (RBC) to control - when the SCG completes this operation. In a Normal Control Operation (NCC) the - UPS will only complete the reboot if RBC is reached. Due to normal battery - charge rate variations it may be desirable for the Followers to complete the - reboot if they are within some range of the Initiator�s RBC when the Initiator - is prepared (charged to RBC) to complete the reboot. The Return Battery - Capacity Offset (RBCO) defines a percent battery capacity subtracted from an - RBC above which a Follower�s battery must be charged for it to complete a - reboot. For example, if the Initiator�s RBC is 50% and the Initiator�s RBCO is - 5% then a Follower�s battery capacity is within range if it is greater or equal - to 45% (50% - 5%) at the time when the Initiator tries to complete the reboot - command. The default RBCO is 10%. " - ::= { upsSyncCtrlGroupConfig 4 } - -upsSCGMultiCastIP OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The MultiCast IP address of the SCG Group." - ::= { upsSyncCtrlGroupConfig 5 } - --- the upsSyncCtrlGroupStatus group - -upsSCGNumOfGroupMembers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of active, communicating members in the Sync Control Group (SCG). - This variable indicates the number of rows in the SCG Status Table." - ::= { upsSyncCtrlGroupStatus 1 } - --- Sync Control Group Status Table - -upsSCGStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsSCGStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of SCG status table entries. The number of entries - is given by the value of upsSCGNumOfGroupMembers." - ::= { upsSyncCtrlGroupStatus 2 } - - upsSCGStatusEntry OBJECT-TYPE - SYNTAX UpsSCGStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular SCG Member." - INDEX { upsSCGStatusTableIndex } - ::= { upsSCGStatusTable 1 } - - UpsSCGStatusEntry ::= SEQUENCE { - upsSCGStatusTableIndex INTEGER, - upsSCGMemberIP IpAddress, - upsSCGACInputStatus INTEGER, - upsSCGACOutputStatus INTEGER - } - - upsSCGStatusTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a status entry for an active, communicating SCG member." - ::= { upsSCGStatusEntry 1 } - - upsSCGMemberIP OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The IP address of an active, communicating SCG Member." - ::= { upsSCGStatusEntry 2 } - - upsSCGACInputStatus OBJECT-TYPE - SYNTAX INTEGER { - acInGood(1), - acInBad(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID indicates the AC Input Status of the SCG Member. - acInGood(1) indicates the AC Input is within tolerance. - acInBad(2) indicates the AC Input is not within tolerance." - ::= { upsSCGStatusEntry 3 } - - upsSCGACOutputStatus OBJECT-TYPE - SYNTAX INTEGER { - acOutOn(1), - acOutOff(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID indicates the AC Output Status of the SCG Member. - acOutOn(1) indicates the UPS output is providing power to the load. - acOutOff(2) indicates the UPS output is not providing power to the load. " - ::= { upsSCGStatusEntry 4 } - --- the upsBasicState group - -upsBasicStateOutputState OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 64 flags representing - the current state(s) of the UPS. If the Network Card - is unable to determine the state of the UPS, this - variable is set to �UNKNOWN�. - - The flags are numbered 1 to 64, read from left to - right. The flags are defined as follows: - - Flag 1: Abnormal Condition Present - Flag 2: On Battery - Flag 3: Low Battery - Flag 4: On Line - - Flag 5: Replace Battery - Flag 6: Serial Communication Established - Flag 7: AVR Boost Active* - Flag 8: AVR Trim Active* - - Flag 9: Overload - Flag 10: Runtime Calibration - Flag 11: Batteries Discharged - Flag 12: Manual Bypass - - Flag 13: Software Bypass - Flag 14: In Bypass due to Internal Fault - Flag 15: In Bypass due to Supply Failure* - Flag 16: In Bypass due to Fan Failure* - - Flag 17: Sleeping on a Timer - Flag 18: Sleeping until Utility Power Returns - Flag 19: On - Flag 20: Rebooting - - Flag 21: Battery Communication Lost* - Flag 22: Graceful Shutdown Initiated - Flag 23: Smart Boost or Smart Trim Fault* - Flag 24: Bad Output Voltage* - - Flag 25: Battery Charger Failure* - Flag 26: High Battery Temperature - Flag 27: Self Test In Progress - Flag 28: Low Battery / On Battery - - Flag 29: Graceful Shutdown Issued by Upstream Device - Flag 30: Graceful Shutdown Issued by Downstream Device - Flag 31: No Batteries Attached* - Flag 32: Synchronized command is in progress - - Flag 33: <Not Used> - Flag 34: <Not Used> - Flag 35: <Not Used> - Flag 36: <Not Used> - - Flag 37: <Not Used> - Flag 38: <Not Used> - Flag 39: <Not Used> - Flag 40: <Not Used> - - Flag 41: <Not Used> - Flag 42: <Not Used> - Flag 43: <Not Used> - Flag 44: <Not Used> - - Flag 45: <Not Used> - Flag 46: <Not Used> - Flag 47: <Not Used> - Flag 48: <Not Used> - - Flag 49: <Not Used> - Flag 50: <Not Used> - Flag 51: <Not Used> - Flag 52: <Not Used> - - Flag 53: <Not Used> - Flag 54: <Not Used> - Flag 55: <Not Used> - Flag 56: <Not Used> - - Flag 57: <Not Used> - Flag 58: <Not Used> - Flag 59: <Not Used> - Flag 60: <Not Used> - - Flag 61: <Not Used> - Flag 62: <Not Used> - Flag 63: <Not Used> - Flag 64: <Not Used>" - - ::= { upsBasicState 1 } - --- the upsAdvState group - -upsAdvStateAbnormalConditions OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 32 flags representing - the current active UPS faults. If the Network Card - is unable to determine the values of the flags, this - variable is set to �UNKNOWN�. If this variable is not - supported by the connected UPS, this variable is set to - �NOT SUPPORTED�. - - The flags are numbered from 1 to 32, and read from left to - right. The flags are defined as follows: - - Flag 1: Power Module Failure - Flag 2: Main Intelligence Module Failure - Flag 3: Redundant Intelligence Module Failure - Flag 4: Battery Failure - - Flag 5: Load(kVA) Alarm Threshold Violation - Flag 6: Redundancy Lost - Flag 7: Redundancy Below Alarm Threshold - Flag 8: Bypass notin Range; Either Frequency or Voltage - - Flag 9: Bypass Contactor Stuck in Bypass Condition - Flag 10: Bypass Contactor Stuck in On-Line Condition - Flag 11: In Bypass due to an Internal Fault - Flag 12: In Bypass due to an Overload - - Flag 13: In Maintanence Bypass - Flag 14: Input Circuit Braker Tripped Open - Flag 15: System Level Fan Failure - Flag 16: Redundant Intelligent Module in Control - - Flag 17: IIC Inter-Module Communication Failure - Flag 18: No Working Power Modules - Flag 19: Load Shutdown From Bypass; Input Frequency - Flag 20: Runtime Below Alarm Threshold - - Flag 21: Extended Run Frame Fault - Flag 22: Output Voltage out of Range - Flag 23: UPS Not Synchronized - Flag 24: No Batteries Installed - - Flag 25: Battery Voltage High - Flag 26: UPS Specific Fault Detected - Flag 27: Site Wiring Fault - Flag 28: Backfeed Protection Relay Opened - - Flag 29: <Not Used> - Flag 30: <Not Used> - Flag 31: <Not Used> - Flag 32: <Not Used>" - ::= { upsAdvState 1 } - -upsAdvStateSymmetra3PhaseSpecificFaults OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 64 flags representing - the current active UPS specific faults for the Symmetra - 3-Phase UPS models. If the Network Card is unable to - determine the values of the flags, this variable is set - to �UNKNOWN�. If the connected UPS does not use this - variable, it is set to �NOT SUPPORTED�. - - The flags are numbered from 1 to 64, and read from left - to right. The bits are defined as follows: - - Flag 1: External Switch Gear Failure - Flag 2: External Transformer Over Temperature - Flag 3: External DC Circuit Breaker Tripped - Flag 4: System Power Supply Failure - - Flag 5: Battery Monitor Card Failure - Flag 6: Battery Monitor Card Removed - Flag 7: XR Communication Card Failure - Flag 8: XR Communication Card Removed - - Flag 9: External Switch Gear Monitoring Card Failure - Flag 10: External Switch Gear Monitoring Card Removed - Flag 11: Internal DC Circiut Breaker Tripped - Flag 12: Static Bypass Switch Failure - - Flag 13: System EEPROM Removed - Flag 14: System EEPROM Failure - Flag 15: UPS in Forced Bypass - Flag 16: <Not Used> - - Flag 17: <Not Used> - Flag 18: <Not Used> - Flag 19: <Not Used> - Flag 20: <Not Used> - - Flag 21: <Not Used> - Flag 22: <Not Used> - Flag 23: <Not Used> - Flag 24: <Not Used> - - Flag 25: <Not Used> - Flag 26: <Not Used> - Flag 27: <Not Used> - Flag 28: <Not Used> - - Flag 29: <Not Used> - Flag 30: <Not Used> - Flag 31: <Not Used> - Flag 32: <Not Used> - - Flag 33: <Not Used> - Flag 34: <Not Used> - Flag 35: <Not Used> - Flag 36: <Not Used> - - Flag 37: <Not Used> - Flag 38: <Not Used> - Flag 39: <Not Used> - Flag 40: <Not Used> - - Flag 41: <Not Used> - Flag 42: <Not Used> - Flag 43: <Not Used> - Flag 44: <Not Used> - - Flag 45: <Not Used> - Flag 46: <Not Used> - Flag 47: <Not Used> - Flag 48: <Not Used> - - Flag 49: <Not Used> - Flag 50: <Not Used> - Flag 51: <Not Used> - Flag 52: <Not Used> - - Flag 53: <Not Used> - Flag 54: <Not Used> - Flag 55: <Not Used> - Flag 56: <Not Used> - - Flag 57: <Not Used> - Flag 58: <Not Used> - Flag 59: <Not Used> - Flag 60: <Not Used> - - Flag 61: <Not Used> - Flag 62: <Not Used> - Flag 63: <Not Used> - Flag 64: <Not Used>" - ::= { upsAdvState 2 } - -upsAdvStateDP300ESpecificFaults OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 64 flags representing - the current active UPS specific faults for the Silcon - DP300E UPS models. If the Network Card is unable to - determine the values of the flags, this variable is set - to �UNKNOWN�. If the connected UPS does not use this - variable, it is set to �NOT SUPPORTED�. - - The flags are numbered from 1 to 64, and read from left - to right. The bits are defined as follows: - - Flag 1: Peak Current Limiter Avtive - Flag 2: Bypass Power Supply Fault - Flag 3: Delta Current LImiter Active - Flag 4: Fan Fault - - Flag 5: High DC warning - Flag 6: Inverter Voltage Error - Flag 7: Parallel Synchronization Error - Flag 8: Second Power Supply Fault - - Flag 9: Internal Power Supply Fault - Flag 10: <Not Used> - Flag 11: <Not Used> - Flag 12: <Not Used> - - Flag 13: <Not Used> - Flag 14: Bypass Static Switch High Temperature - Flag 15: High Battery Temperature - Flag 16: Battery Weak - - Flag 17: <Not Used> - Flag 18: System Locked in Operation Mode - Flag 19: RAM1 Memory Write Error - Flag 20: Memory Write Error - - Flag 21: Communication to VQ Bypass Lost - Flag 22: Communication to VQ Output Lost - Flag 23: Communication to DMU Lost - Flag 24: Communication to Controller Lost - - Flag 25: Communication to Parallel IF Lost - Flag 26: External Shutdown Accepted - Flag 27: DC Capacitor Charge Error - Flag 28: Communication to VQ Mains Lost - - Flag 29: Bypass Synchronization Error - Flag 30: Charge Error - Flag 31: <Not Used> - Flag 32: <Not Used> - - Flag 33: <Not Used> - Flag 34: <Not Used> - Flag 35: <Not Used> - Flag 36: <Not Used> - - Flag 37: <Not Used> - Flag 38: <Not Used> - Flag 39: <Not Used> - Flag 40: <Not Used> - - Flag 41: <Not Used> - Flag 42: <Not Used> - Flag 43: <Not Used> - Flag 44: <Not Used> - - Flag 45: <Not Used> - Flag 46: <Not Used> - Flag 47: <Not Used> - Flag 48: <Not Used> - - Flag 49: <Not Used> - Flag 50: <Not Used> - Flag 51: <Not Used> - Flag 52: <Not Used> - - Flag 53: <Not Used> - Flag 54: <Not Used> - Flag 55: <Not Used> - Flag 56: <Not Used> - - Flag 57: <Not Used> - Flag 58: <Not Used> - Flag 59: <Not Used> - Flag 60: <Not Used> - - Flag 61: <Not Used> - Flag 62: <Not Used> - Flag 63: <Not Used> - Flag 64: <Not Used>" - ::= { upsAdvState 3 } - - --- the upsBasicControl group - -upsBasicControlConserveBattery OBJECT-TYPE - SYNTAX INTEGER { - noTurnOffUps(1), - turnOffUpsToConserveBattery(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to turnUpsOffToConserveBattery(2) - causes a UPS on battery to be put into 'sleep' mode. The - UPS will turn back on when utility power is restored. - Attempting to turn off a UPS that is not on battery will - result in a badValue error. - - Setting this value to noTurnOffUps(1) has no - effect. - - The value noTurnOffUps(1) will always be returned - when the variable is read." -::= { upsBasicControl 1 } - - - --- the upsAdvControl group - -upsAdvControlUpsOff OBJECT-TYPE - SYNTAX INTEGER { - noTurnUpsOff(1), - turnUpsOff(2), - turnUpsOffGracefully(3), - turnUpsSyncGroupOff(4), - turnUpsSyncGroupOffAfterDelay(5), - turnUpsSyncGroupOffGracefully(6) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to turnUpsOff(2) causes - the UPS to shut off. When in this state, the UPS - will not provide output power regardless of the input - line state. - - Setting this variable to turnUpsOffGracefully(3) causes - the UPS to shut off after a delay period. This allows the - host to shut down in a graceful manner. When in this state, - the UPS will not provide output power regardless of the - input line state. - - If this UPS is an active member of a Synchronized - Control Group (SCG) the turnUpsSyncGroupOff(4) command - will perform a Synchronized Turn Off of all active Group - members regardless of their current AC output status. - - If this UPS is an active member of a Synchronized - Control Group (SCG) the turnUpsSyncGroupOffAfterDelay(5) - command will perform a Synchronized Turn Off After Delay - of all active Group members regardless of their current - AC output status. This unit's Shutdown Delay will be used - to execute the Turn Off After Delay command. - - If this UPS is an active member of an SCG, the - turnUpsSyncGroupOffGracefully(6) command will perform a - Synchronized Turn Off Gracefully of all active Group - members regardless of their current AC output status. - This unit's Maximum Shutdown Time and Shutdown Delay will - be used to execute the Turn Off Gracefully command. - - Setting this value to noTurnUpsOff(1) has no - effect. - - The value noTurnUpsOff(1) will always be returned - when the variable is read." - ::= { upsAdvControl 1 } - -upsAdvControlRebootUps OBJECT-TYPE - SYNTAX INTEGER { - noRebootUps(1), - rebootUps(2), - rebootUpsGracefully(3), - rebootSyncGroupUps(4), - rebootSyncGroupUpsGracefully(5) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to rebootUps(2) causes the - UPS to shut off and turn back on. - - Setting this variable to rebootUpsGracefully(3) causes the - UPS to shut off and turn back on after a delay period. - This allows the host to shut down in a graceful manner. - - If this UPS is an active member of a Synchronized Control - Group (SCG) the rebootSyncGroupUps(4) command will perform - a Synchronized Reboot of all active Group members regardless - of their current AC output status. This unit's Power - Synchronization Delay, Shutdown Delay, Return Delay, - Return Battery Capacity, and Return Battery Capacity Offset - will be used to execute the Reboot command. - - If this UPS is an active member of a SCG the - rebootSyncGroupUpsGracefully(5) command will perform a - Synchronized Reboot of all active Group members regardless - of their current AC output status. This unit's Power - Synchronization Delay, Maximum Shutdown Time, - Shutdown Delay, Return Delay, Return Battery Capacity, and - Return Battery Capacity Offset will be used - to execute the Reboot command. - - Setting this value to noRebootUps(1) has no effect. - - The value noRebootUps(1) will always be returned - when the variable is read." - ::= { upsAdvControl 2 } - -upsAdvControlUpsSleep OBJECT-TYPE - SYNTAX INTEGER { - noPutUpsToSleep(1), - putUpsToSleep(2), - putUpsToSleepGracefully(3), - putUpsSyncGroupToSleep(4), - putUpsSyncGroupToSleepGracefully(5) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to putUpsToSleep(2) causes - the UPS to go to sleep for the time specified by - upsAdvConfigUpsSleepTime. - - Setting this variable to putUpsToSleepGracefully(3) - causes the UPS to go to sleep for the time specified - by upsAdvConfigUpsSleepTime after a delay period. - This allows the host to shut down in a graceful manner. - - If this UPS is an active member of a Synchronized Control - Group (SCG), the putUpsSyncGroupToSleep(4) command will perform - a Synchronized Sleep of all active Group members regardless - of their current AC output status. This unit's Power - Synchronization Delay, Shutdown Delay, Sleep Time, - and Return Delay will be used to execute the sleep command. - - If this UPS is an active member of a SCG the - putUpsSyncGroupToSleepGracefully(5) command will perform a - Synchronized Sleep Gracefully of all active Group members - regardless of their current AC output status. This unit's - Power Synchronization Delay, Maximum Shutdown Time, Shutdown - Delay, Sleep Time, and Return Delay to execute the sleep - command. - - When in sleep mode, the UPS will not provide output - power regardless of the input line state. Once the - specified time has elapsed, output power will be - restored. - - Setting this value to noPutUpsToSleep(1) has no - effect. - - The value noPutUpsToSleep(1) will always be returned - when the variable is read." - ::= { upsAdvControl 3 } - - -upsAdvControlSimulatePowerFail OBJECT-TYPE - SYNTAX INTEGER { - noSimulatePowerFailure(1), - simulatePowerFailure(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to simulatePowerFailure(2) causes - the UPS switch to battery power. - - Setting this value to noSimulatePowerFailure(1) has no - effect. - - The value noSimulatePowerFailure(1) will always be returned - when the variable is read." - ::= { upsAdvControl 4 } - - -upsAdvControlFlashAndBeep OBJECT-TYPE - SYNTAX INTEGER { - noFlashAndBeep(1), - flashAndBeep(2), - flashAndBeepSyncGroup(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to flashAndBeep(2) causes the - UPS to beep and simultaneously turn on the UPS front - panel lights (Smart-UPS only). - - If this UPS is an active member of a Synchronized Control - Group (SCG), the flashAndBeepSyncGroup(3) command will - Flash and Beep all active Group members regardless of - current AC output status. - - Setting this value to noFlashAndBeep(1) has no - effect. - - The value noFlashAndBeep(1) will always be returned - when the variable is read." - ::= { upsAdvControl 5 } - - -upsAdvControlTurnOnUPS OBJECT-TYPE - SYNTAX INTEGER { - noTurnOnUPS(1), - turnOnUPS(2), - turnOnUPSSyncGroup(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to turnOnUPS(2) causes the - UPS to be turned on immediately. - - If this UPS is an active member of a Synchronized Control - Group (SCG), the turnOnUPSSyncGroup(3) command will perform - a Synchronized Turn On of all active Group members - regardless of their current AC output status. - - Setting this value to noTurnOnUPS(1) has no - effect. - - The value noTurnOnUPS(1) will always be returned - when the variable is read." - ::= { upsAdvControl 6 } - -upsAdvControlBypassSwitch OBJECT-TYPE - SYNTAX INTEGER { - noBypassSwitch (1), - switchToBypass (2), - switchOutOfBypass(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This switch puts the UPS in or out of bypass mode." - ::= { upsAdvControl 7 } - - --- the upsTest group - --- the upsBasicTest group - --- the upsAdvTest group - -upsAdvTestDiagnosticSchedule OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - biweekly(2), - weekly(3), - atTurnOn(4), - never(5) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The UPS system's automatic battery test schedule." - ::= { upsAdvTest 1 } - - -upsAdvTestDiagnostics OBJECT-TYPE - SYNTAX INTEGER { - noTestDiagnostics(1), - testDiagnostics(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to testDiagnostics(2) causes - the UPS to perform a diagnostic self test. - - Setting this value to noTestDiagnostics(1) has no - effect. - - The value noTestDiagnostics(1) will always be returned - when the variable is read." - ::= { upsAdvTest 2 } - -upsAdvTestDiagnosticsResults OBJECT-TYPE - SYNTAX INTEGER { - ok(1), - failed(2), - invalidTest(3), - testInProgress(4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The results of the last UPS diagnostics test performed." - ::= { upsAdvTest 3 } - -upsAdvTestLastDiagnosticsDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date the last UPS diagnostics test was performed in - mm/dd/yy format." - ::= { upsAdvTest 4 } - -upsAdvTestRuntimeCalibration OBJECT-TYPE - SYNTAX INTEGER { - noPerformCalibration(1), - performCalibration(2), - cancelCurrentCalibration(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to performCalibration(2) causes - the UPS to discharge to calibrate the UPS. - The test will only start if the battery capacity is 100%. - The test runs until capacity is less than 25%. - - Setting this variable to cancelCurrentCalibration(3) - after setting performCalibration(2) will cancel the - current discharge. - - Setting this variable to noPerformCalibration(1) - will have no effect. - - The value noPerformCalibration(1) will always be returned - when the variable is read. - - The result of the calibration will be saved in - upsAdvTestCalibrationResult." - ::= { upsAdvTest 5 } - -upsAdvTestCalibrationResults OBJECT-TYPE - SYNTAX INTEGER { - ok(1), - invalidCalibration(2), - calibrationInProgress(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The results of the last runtime calibration. - - Value ok(1) means a successful runtime calibration. - - Value invalidCalibration(2) indicates last calibration did - not take place since the battery capacity was below - 100%. - - Value calibrationInProgress(3) means a calibration - is occurring now. " - ::= { upsAdvTest 6 } - -upsAdvTestCalibrationDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date the last UPS runtime calibration was - performed in mm/dd/yy format." - ::= { upsAdvTest 7 } - --- the upsComm group - -upsCommStatus OBJECT-TYPE - SYNTAX INTEGER { - ok(1), - noComm(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of agent's communication with UPS. " - ::= { upsComm 1 } - - --- the measureUps group --- the Environ group - -mUpsEnvironAmbientTemperature OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The ambient temperature in Celsius for Probe 1." - ::= { mUpsEnviron 1 } - -mUpsEnvironRelativeHumidity OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The relative humidity as a percentage for Probe 1." - ::= { mUpsEnviron 2 } - - -mUpsEnvironAmbientTemperature2 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The ambient temperature in Celsius for Probe 2." - ::= { mUpsEnviron 3 } - -mUpsEnvironRelativeHumidity2 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The relative humidity as a percentage for Probe 2." - ::= { mUpsEnviron 4 } - --- the mUpsContact group - -mUpsContactNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the Measure-UPS." - ::= { mUpsContact 1 } - -mUpsContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF ContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Measure-UPS." - ::= { mUpsContact 2 } - -mUpsContactEntry OBJECT-TYPE - SYNTAX ContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A contact entry containing information for a given contact." - INDEX { contactNumber } - ::= { mUpsContactTable 1 } - -ContactEntry ::= - SEQUENCE { - contactNumber - INTEGER, - normalState - INTEGER, - description - DisplayString, - monitoringStatus - INTEGER, - currentStatus - INTEGER - } - -contactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the contact on the Measure-UPS." - ::= { mUpsContactEntry 1 } - -normalState OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - open(2), - closed(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the contact. If the normal - operating position cannot be set then it is controlled via the - dip switch on the Measure-UPS and is therefore read-only." - ::= { mUpsContactEntry 2 } - -description OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the contact." - ::= { mUpsContactEntry 3 } - -monitoringStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - enabled(2), - disabled(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A flag indicating whether this contact is - monitored, or not." - ::= { mUpsContactEntry 4 } - -currentStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - noFault(2), - fault(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the contact. - If the contact is not in its normal state. This value - is set to fault(2)." - ::= { mUpsContactEntry 5 } - --- Three Phase Group - --- --- Reset Max/Min Values Group --- - - upsPhaseResetMaxMinValues OBJECT-TYPE - SYNTAX INTEGER { - none (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Reset the maximum and minimum UPS values: - upsPhaseInputMaxVoltage, upsPhaseInputMinVoltage, - upsPhaseInputMaxCurrent, upsPhaseInputMinCurrent, - upsPhaseInputMaxPower, upsPhaseInputMinPower, - upsPhaseOutputMaxCurrent, upsPhaseOutputMinCurrent, - upsPhaseOutputMaxLoad, upsPhaseOutputMinLoad, - upsPhaseOutputMaxPercentLoad, upsPhaseOutputMinPercentLoad, - upsPhaseOutputMaxPower, upsPhaseOutputMinPower, - upsPhaseOutputMaxPercentPower, upsPhaseOutputMinPercentPower." - ::= { upsPhaseResetValues 1 } - --- --- Input Group --- - --- Number of Inputs - - upsPhaseNumInputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input feeds to this device. - This variable indicates the number of rows in the - input table." - ::= { upsPhaseInput 1 } - --- Input Table - - upsPhaseInputTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the value of upsPhaseNumInputs." - ::= { upsPhaseInput 2 } - - upsPhaseInputEntry OBJECT-TYPE - SYNTAX UpsPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input." - INDEX { upsPhaseInputTableIndex } - ::= { upsPhaseInputTable 1 } - - UpsPhaseInputEntry ::= SEQUENCE { - upsPhaseInputTableIndex INTEGER, - upsPhaseNumInputPhases INTEGER, - upsPhaseInputVoltageOrientation INTEGER, - upsPhaseInputFrequency INTEGER, - upsPhaseInputType INTEGER, - upsPhaseInputName DisplayString - } - - upsPhaseInputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { upsPhaseInputEntry 1 } - - upsPhaseNumInputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input phases utilized in this - device. The sum of all the upsPhaseNumInputPhases - variable indicates the number of rows in the - input phase table." - ::= { upsPhaseInputEntry 2 } - - upsPhaseInputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage orientation: - 1: unknown for this UPS - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { upsPhaseInputEntry 3 } - - upsPhaseInputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input frequency in 0.1 Hertz, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseInputEntry 4 } - - upsPhaseInputType OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - main(2), - bypass(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input type." - ::= { upsPhaseInputEntry 5 } - - upsPhaseInputName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A name given to a particular input." - ::= { upsPhaseInputEntry 6 } - --- Input Phase Table - - upsPhaseInputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the sum of the upsPhaseNumInputPhases." - ::= { upsPhaseInput 3 } - - upsPhaseInputPhaseEntry OBJECT-TYPE - SYNTAX UpsPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input phase." - INDEX { upsPhaseInputPhaseTableIndex, upsPhaseInputPhaseIndex } - ::= { upsPhaseInputPhaseTable 1 } - - UpsPhaseInputPhaseEntry ::= SEQUENCE { - upsPhaseInputPhaseTableIndex INTEGER, - upsPhaseInputPhaseIndex INTEGER, - upsPhaseInputVoltage INTEGER, - upsPhaseInputMaxVoltage INTEGER, - upsPhaseInputMinVoltage INTEGER, - upsPhaseInputCurrent INTEGER, - upsPhaseInputMaxCurrent INTEGER, - upsPhaseInputMinCurrent INTEGER, - upsPhaseInputPower INTEGER, - upsPhaseInputMaxPower INTEGER, - upsPhaseInputMinPower INTEGER - } - - upsPhaseInputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { upsPhaseInputPhaseEntry 1 } - - upsPhaseInputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input phase identifier." - ::= { upsPhaseInputPhaseEntry 2 } - - upsPhaseInputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage in VAC, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseInputPhaseEntry 3 } - - upsPhaseInputMaxVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input voltage in VAC measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 4 } - - upsPhaseInputMinVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input voltage in VAC measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 5 } - - upsPhaseInputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input current in 0.1 amperes, or -1 if it's - unsupported by this UPS." - ::= { upsPhaseInputPhaseEntry 6 } - - upsPhaseInputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 7 } - - upsPhaseInputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 8 } - - upsPhaseInputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input power in Watts, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseInputPhaseEntry 9 } - - upsPhaseInputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 10 } - - upsPhaseInputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 11 } - - -- - -- The Output group. - -- - - -- Number of Outputs - - upsPhaseNumOutputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output feeds to this device. - This variable indicates the number of rows in the - output table." - ::= { upsPhaseOutput 1 } - - -- Output Table - - upsPhaseOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of entries - is given by the value of upsOutputNumPhases." - ::= { upsPhaseOutput 2 } - - upsPhaseOutputEntry OBJECT-TYPE - SYNTAX UpsPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output." - INDEX { upsPhaseOutputTableIndex } - ::= { upsPhaseOutputTable 1 } - - UpsPhaseOutputEntry ::= SEQUENCE { - upsPhaseOutputTableIndex INTEGER, - upsPhaseNumOutputPhases INTEGER, - upsPhaseOutputVoltageOrientation INTEGER, - upsPhaseOutputFrequency INTEGER - } - - upsPhaseOutputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { upsPhaseOutputEntry 1 } - - upsPhaseNumOutputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output phases utilized in this - device. The sum of all the upsPhaseNumOutputPhases - variable indicates the number of rows in the - output phase table." - ::= { upsPhaseOutputEntry 2 } - - upsPhaseOutputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage orientation: - 1: unknown for this UPS - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { upsPhaseOutputEntry 3 } - - upsPhaseOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output frequency in 0.1 Hertz, or -1 if it's - unsupported by this UPS." - ::= { upsPhaseOutputEntry 4 } - - -- Output Phase Table - - upsPhaseOutputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of - entries is given by the sum of the upsPhaseNumOutputPhases." - ::= { upsPhaseOutput 3 } - - upsPhaseOutputPhaseEntry OBJECT-TYPE - SYNTAX UpsPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output phase." - INDEX { upsPhaseOutputPhaseTableIndex, upsPhaseOutputPhaseIndex } - ::= { upsPhaseOutputPhaseTable 1 } - - UpsPhaseOutputPhaseEntry ::= SEQUENCE { - upsPhaseOutputPhaseTableIndex INTEGER, - upsPhaseOutputPhaseIndex INTEGER, - upsPhaseOutputVoltage INTEGER, - upsPhaseOutputCurrent INTEGER, - upsPhaseOutputMaxCurrent INTEGER, - upsPhaseOutputMinCurrent INTEGER, - upsPhaseOutputLoad INTEGER, - upsPhaseOutputMaxLoad INTEGER, - upsPhaseOutputMinLoad INTEGER, - upsPhaseOutputPercentLoad INTEGER, - upsPhaseOutputMaxPercentLoad INTEGER, - upsPhaseOutputMinPercentLoad INTEGER, - upsPhaseOutputPower INTEGER, - upsPhaseOutputMaxPower INTEGER, - upsPhaseOutputMinPower INTEGER, - upsPhaseOutputPercentPower INTEGER, - upsPhaseOutputMaxPercentPower INTEGER, - upsPhaseOutputMinPercentPower INTEGER - } - - upsPhaseOutputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { upsPhaseOutputPhaseEntry 1 } - - upsPhaseOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output phase identifier." - ::= { upsPhaseOutputPhaseEntry 2 } - - upsPhaseOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage in VAC, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseOutputPhaseEntry 3 } - - upsPhaseOutputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output current in 0.1 amperes drawn - by the load on the UPS, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseOutputPhaseEntry 4 } - - upsPhaseOutputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 5 } - - upsPhaseOutputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 6 } - - upsPhaseOutputLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output load in VA, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseOutputPhaseEntry 7 } - - upsPhaseOutputMaxLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output load in VA measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 8 } - - upsPhaseOutputMinLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output load in VA measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 9 } - - upsPhaseOutputPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the UPS load capacity in VA at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this UPS." - ::= { upsPhaseOutputPhaseEntry 10 } - - upsPhaseOutputMaxPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the UPS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last reset - (upsPhaseResetMaxMinValues), or -1 if it's unsupported - by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 11 } - - upsPhaseOutputMinPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum percentage of the UPS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last reset - (upsPhaseResetMaxMinValues), or -1 if it's unsupported - by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 12 } - - upsPhaseOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output power in Watts, or -1 if it's - unsupported by this UPS." - ::= { upsPhaseOutputPhaseEntry 13 } - - upsPhaseOutputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 14 } - - upsPhaseOutputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 15 } - - upsPhaseOutputPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the UPS power capacity in Watts at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this UPS." - ::= { upsPhaseOutputPhaseEntry 16 } - - upsPhaseOutputMaxPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the UPS power capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last - reset (upsPhaseResetMaxMinValues), or -1 if it's - unsupported by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 17 } - - upsPhaseOutputMinPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the UPS power capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last - reset (upsPhaseResetMaxMinValues), or -1 if it's - unsupported by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 18 } - --- the upsOutletGroupStatus group - -upsOutletGroupStatusTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlet groups for the UPS." - ::= { upsOutletGroupStatus 1 } - -upsOutletGroupStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsOutletGroupStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting status of the outlet groups. The number of - entries is contained in the upsOutletGroupStatusTableSize OID." - ::= { upsOutletGroupStatus 2 } - -upsOutletGroupStatusEntry OBJECT-TYPE - SYNTAX UpsOutletGroupStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet group status to get." - INDEX { upsOutletGroupStatusIndex} - ::= { upsOutletGroupStatusTable 1 } - -UpsOutletGroupStatusEntry ::= - SEQUENCE { - upsOutletGroupStatusIndex INTEGER, - upsOutletGroupStatusName DisplayString, - upsOutletGroupStatusGroupState INTEGER, - upsOutletGroupStatusCommandPending INTEGER - } - -upsOutletGroupStatusIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet group entry." - ::= { upsOutletGroupStatusEntry 1 } - -upsOutletGroupStatusName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet group. This OID is provided - for informational purposes only. This value is set - by the upsOutletGroupConfigName OID." - ::= { upsOutletGroupStatusEntry 2 } - -upsOutletGroupStatusGroupState OBJECT-TYPE - SYNTAX INTEGER { - upsOutletGroupStatusOn (1), - upsOutletGroupStatusOff (2), - upsOutletGroupStatusUnknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet group state. If the outlet - group is on, the upsOutletGroupStatusOn (1) value will be returned. If - the outlet group is off, the upsOutletGroupStatusOff (2) value will be - returned. If the state of the outlet group cannot be determined, the - upsOutletGroupStatusUnknown (3) value will be returned." - - ::= { upsOutletGroupStatusEntry 3 } - -upsOutletGroupStatusCommandPending OBJECT-TYPE - SYNTAX INTEGER { - upsOutletGroupCommandPending (1), - upsOutletGroupNoCommandPending (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet group. If a command is pending on the - outlet group, the upsOutletGroupCommandPending (1) value - will be returned. If there is not a command pending - on the outlet group, the upsOutletGroupNoCommandPending (2) - will be returned." - ::= { upsOutletGroupStatusEntry 4 } - --- the upsOutletGroupConfig group - -upsOutletGroupConfigTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlet groups for the UPS." - ::= { upsOutletGroupConfig 1 } - -upsOutletGroupConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsOutletGroupConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The list of outlet groups to configure. The number of entries - is defined by the upsOutletGroupConfigTableSize OID." - ::= { upsOutletGroupConfig 2 } - -upsOutletGroupConfigEntry OBJECT-TYPE - SYNTAX UpsOutletGroupConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet groups to configure." - INDEX { upsOutletGroupConfigIndex} - ::= { upsOutletGroupConfigTable 1 } - -UpsOutletGroupConfigEntry ::= - SEQUENCE { - upsOutletGroupConfigIndex INTEGER, - upsOutletGroupConfigName DisplayString, - upsOutletGroupConfigPowerOnDelay INTEGER, - upsOutletGroupConfigPowerOffDelay INTEGER, - upsOutletGroupConfigRebootDuration INTEGER - } - -upsOutletGroupConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet group entry." - ::= { upsOutletGroupConfigEntry 1 } - -upsOutletGroupConfigName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet group." - ::= { upsOutletGroupConfigEntry 2 } - -upsOutletGroupConfigPowerOnDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet group will delay - powering on when the delayed on or reboot command is applied. - Allowed values are -1 (for Never) or 0 to 600 seconds." - ::= { upsOutletGroupConfigEntry 3 } - -upsOutletGroupConfigPowerOffDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet group will delay - powering off when the delayed off command is applied. - Allowed values are 0 to 600 seconds." - ::= { upsOutletGroupConfigEntry 4 } - -upsOutletGroupConfigRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before initiating the power on sequence. - Allowed values are 0 to 600 seconds." - ::= { upsOutletGroupConfigEntry 5 } - --- the upsOutletGroupControl group - -upsOutletGroupControlTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlet groups for the UPS." - ::= { upsOutletGroupControl 1 } - -upsOutletGroupControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsOutletGroupControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet groups. The number of - entries is contained in the upsOutletGroupControlTableSize OID." - ::= { upsOutletGroupControl 2 } - -upsOutletGroupControlEntry OBJECT-TYPE - SYNTAX UpsOutletGroupControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet group to control." - INDEX { upsOutletGroupControlIndex} - ::= { upsOutletGroupControlTable 1 } - -UpsOutletGroupControlEntry ::= - SEQUENCE { - upsOutletGroupControlIndex INTEGER, - upsOutletGroupControlName DisplayString, - upsOutletGroupControlCommand INTEGER - } - -upsOutletGroupControlIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet group entry." - ::= { upsOutletGroupControlEntry 1 } - -upsOutletGroupControlName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet group. This OID is provided - for informational purposes only. This value is set - by the upsOutletGroupConfigName OID." - ::= { upsOutletGroupControlEntry 2 } - -upsOutletGroupControlCommand OBJECT-TYPE - SYNTAX INTEGER { - upsOutletGroupImmediateOn (1), - upsOutletGroupImmediateOff (2), - upsOutletGroupImmediateReboot (3), - upsOutletGroupDelayedOn (4), - upsOutletGroupDelayedOff (5), - upsOutletGroupDelayedReboot (6), - upsOutletGroupCancelPendingCommand (7), - upsOutletGroupControlUnknown (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet group state. If the outlet - group is on, the upsOutletGroupImmediateOn (1) value will be returned. If - the outlet group is off, the upsOutletGroupImmediateOff (2) value will be - returned. - - If the state of the outlet group cannot be determined, the - upsOutletGroupControlUnknown (8) value will be returned. - - Setting this variable to upsOutletGroupImmediateOn (1) will turn the - outlet group on. - - Setting this variable to upsOutletGroupImmediateOff (2) will turn the - outlet group off. - - Setting this variable to upsOutletGroupImmediateReboot (3) will turn the outlet - group off, wait the upsOutletGroupConfigRebootDuration OID time, wait the - upsOutletGroupConfigPowerOnDelay OID, and then turn the outlet group on. - - Setting this variable to upsOutletGroupDelayedOn (4) will turn the outlet - group on after the upsOutletGroupConfigPowerOnDelay OID has elapsed. - - Setting this variable to upsOutletGroupDelayedOff (5) will turn the outlet - group off after the upsOutletGroupConfigPowerOffDelay OID has elapsed. - - Setting this variable to upsOutletGroupDelayedReboot (6) will turn the outlet - group off after the upsOutletGroupConfigPowerOffDelay OID has elapsed, wait the - upsOutletGroupConfigRebootDuration OID time, wait the - upsOutletGroupConfigPowerOnDelay OID, and then turn the outlet group on. - - Setting this variable to upsOutletGroupCancelPendingCommand (7) will - cause any pending command to this outlet group to be canceled." - ::= { upsOutletGroupControlEntry 3 } - --- the upsDiagnosticIM group - -upsDiagIMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Intelligence Modules in or attached to the UPS." - ::= { upsDiagnosticIM 1 } - -upsDiagIMTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagIMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual Intelligence Modules. The number of - entries is contained in the upsDiagIMTableSize OID." - ::= { upsDiagnosticIM 2 } - -upsDiagIMEntry OBJECT-TYPE - SYNTAX UpsDiagIMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics and information of an Intelligence Module." - INDEX { upsDiagIMIndex} - ::= { upsDiagIMTable 1 } - -UpsDiagIMEntry ::= - SEQUENCE { - upsDiagIMIndex INTEGER, - upsDiagIMType INTEGER, - upsDiagIMStatus INTEGER, - upsDiagIMFirmwareRev DisplayString, - upsDiagIMSlaveFirmwareRev DisplayString, - upsDiagIMHardwareRev DisplayString, - upsDiagIMSerialNum DisplayString, - upsDiagIMManufactureDate DisplayString - } - -upsDiagIMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Intelligence Module entry." - ::= { upsDiagIMEntry 1 } - -upsDiagIMType OBJECT-TYPE - SYNTAX INTEGER { - imUnknown (1), - imMIM (2), - imRIM (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of the Intelligence Module. - imUnknown(1) indicates the IM type is unknown. - imMIM(2) indicates the IM type is a Main Intelligence Module. - imRIM(3) indicates the IM type is Redundant Intelligence Module." - ::= { upsDiagIMEntry 2 } - -upsDiagIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Intelligence Module. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagIMEntry 3 } - -upsDiagIMFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Intelligence Module." - ::= { upsDiagIMEntry 4 } - -upsDiagIMSlaveFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The slave firmware revision of the Intelligence Module." - ::= { upsDiagIMEntry 5 } - -upsDiagIMHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Intelligence Module." - ::= { upsDiagIMEntry 6 } - -upsDiagIMSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Intelligence Module." - ::= { upsDiagIMEntry 7 } - -upsDiagIMManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the Intelligence Module." - ::= { upsDiagIMEntry 8 } - --- the upsDiagnosticPowerModules group - -upsDiagPMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Power Modules in or attached to the UPS." - ::= { upsDiagnosticPowerModules 1 } - -upsDiagPMTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagPMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of Individual Power modules. The number of - entries is contained in the upsDiagPMTableSize OID." - ::= { upsDiagnosticPowerModules 2 } - -upsDiagPMEntry OBJECT-TYPE - SYNTAX UpsDiagPMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an Power Module." - INDEX { upsDiagPMIndex} - ::= { upsDiagPMTable 1 } - -UpsDiagPMEntry ::= - SEQUENCE { - upsDiagPMIndex INTEGER, - upsDiagPMStatus INTEGER, - upsDiagPMFirmwareRev DisplayString, - upsDiagPMHardwareRev DisplayString, - upsDiagPMSerialNum DisplayString, - upsDiagPMManufactureDate DisplayString - } - -upsDiagPMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Power Module entry." - ::= { upsDiagPMEntry 1 } - -upsDiagPMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Power Module. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagPMEntry 2 } - -upsDiagPMFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Power Module." - ::= { upsDiagPMEntry 3 } - -upsDiagPMHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Power Module." - ::= { upsDiagPMEntry 4 } - -upsDiagPMSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Power Module." - ::= { upsDiagPMEntry 5 } - -upsDiagPMManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the Power Module." - ::= { upsDiagPMEntry 6 } - --- the upsDiagnosticBatteries group - -upsDiagBatteryTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of batteries in or attached to the UPS." - ::= { upsDiagnosticBatteries 1 } - -upsDiagBatteryTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagBatteryEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual batteries. The number of - entries is contained in the upsDiagBattTableSize OID." - ::= { upsDiagnosticBatteries 2 } - -upsDiagBatteryEntry OBJECT-TYPE - SYNTAX UpsDiagBatteryEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a battery." - INDEX { upsDiagBatteryIndex} - ::= { upsDiagBatteryTable 1 } - -UpsDiagBatteryEntry ::= - SEQUENCE { - upsDiagBatteryFrameIndex INTEGER, - upsDiagBatteryIndex INTEGER, - upsDiagBatteryStatus INTEGER, - upsDiagBatterySerialNumber DisplayString, - upsDiagBatteryFirmwareRev DisplayString, - upsDiagBatteryManufactureDate DisplayString, - upsDiagBatteryType DisplayString - } - -upsDiagBatteryFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the battery frame entry. - Frame 0 indicates the Main frame. Extended Run (XR) frames - start from index 1." - ::= { upsDiagBatteryEntry 1 } - -upsDiagBatteryIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the battery entry." - ::= { upsDiagBatteryEntry 2 } - -upsDiagBatteryStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - failed (4), - highTemperature (5), - replaceImmediately (6), - lowCapacity (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the battery. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the battery status is OK. - failed(4) indicates the battery status is failed. - highTemperature(5) indicates the battery has a high temperature condition. - replaceImmediately(6) indicates the battery must be replaced immediately. - lowCapacity(7) indicates the battery has a low capacity." - ::= { upsDiagBatteryEntry 3 } - -upsDiagBatterySerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the battery." - ::= { upsDiagBatteryEntry 4 } - -upsDiagBatteryFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the battery." - ::= { upsDiagBatteryEntry 5 } - -upsDiagBatteryManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the battery." - ::= { upsDiagBatteryEntry 6 } - -upsDiagBatteryType OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery type or rating for the battery." - ::= { upsDiagBatteryEntry 7 } - --- the upsDiagnosticSubsystem group - -upsDiagSubSysFrameTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of frames attached to the UPS including the Main frame." - ::= { upsDiagnosticSubsystem 1 } - -upsDiagSubSysFrameTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysFrameEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual XR Frames." - ::= { upsDiagnosticSubsystem 2 } - -upsDiagSubSysFrameEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysFrameEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an XR Frame." - INDEX { upsDiagSubSysFrameIndex} - ::= { upsDiagSubSysFrameTable 1 } - -UpsDiagSubSysFrameEntry ::= - SEQUENCE { - upsDiagSubSysFrameIndex INTEGER, - upsDiagSubSysFrameType INTEGER, - upsDiagSubSysFrameFirmwareRev DisplayString, - upsDiagSubSysFrameHardwareRev DisplayString, - upsDiagSubSysFrameSerialNum DisplayString, - upsDiagSubSysFrameManufactureDate DisplayString - } - -upsDiagSubSysFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysFrameEntry 1 } - -upsDiagSubSysFrameType OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - frameTypeMain (3), - frameTypeXR (4), - frameTypeLXR (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of Frame. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - frameTypeMain(3) indicates the the frame type is the Main Frame. - frameTypeXR(4) indicates the frame type is an XR Frame. - frameTypeLXR(5) indicates the frame type is an LXR Frame." - ::= { upsDiagSubSysFrameEntry 2 } - -upsDiagSubSysFrameFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the frame." - ::= { upsDiagSubSysFrameEntry 3 } - -upsDiagSubSysFrameHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the frame." - ::= { upsDiagSubSysFrameEntry 4 } - -upsDiagSubSysFrameSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the frame." - ::= { upsDiagSubSysFrameEntry 5 } - -upsDiagSubSysFrameManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the frame." - ::= { upsDiagSubSysFrameEntry 6 } - -upsDiagSubSysIntBypSwitchTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Internal Bypass switches attached to the UPS." - ::= { upsDiagnosticSubsystem 3 } - -upsDiagSubSysIntBypSwitchTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysIntBypSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of the Internal Bypass Switch." - ::= { upsDiagnosticSubsystem 4 } - -upsDiagSubSysIntBypSwitchEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysIntBypSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of the Internal Bypass Switch." - INDEX { upsDiagSubSysIntBypSwitchIndex} - ::= { upsDiagSubSysIntBypSwitchTable 1 } - -UpsDiagSubSysIntBypSwitchEntry ::= - SEQUENCE { - upsDiagSubSysIntBypSwitchFrameIndex INTEGER, - upsDiagSubSysIntBypSwitchIndex INTEGER, - upsDiagSubSysIntBypSwitchStatus INTEGER, - upsDiagSubSysIntBypSwitchFirmwareRev DisplayString, - upsDiagSubSysIntBypSwitchHardwareRev DisplayString, - upsDiagSubSysIntBypSwitchSerialNum DisplayString, - upsDiagSubSysIntBypSwitchManufactureDate DisplayString - } - -upsDiagSubSysIntBypSwitchFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysIntBypSwitchEntry 1 } - -upsDiagSubSysIntBypSwitchIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Internal Bypass Switch index entry." - ::= { upsDiagSubSysIntBypSwitchEntry 2 } - -upsDiagSubSysIntBypSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Internal Bypass Switch status. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysIntBypSwitchEntry 3 } - -upsDiagSubSysIntBypSwitchFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 4 } - -upsDiagSubSysIntBypSwitchHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 5 } - -upsDiagSubSysIntBypSwitchSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 6 } - -upsDiagSubSysIntBypSwitchManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 7 } - -upsDiagSubSysBattMonitorTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Battery Monitor Boards attached to the UPS." - ::= { upsDiagnosticSubsystem 5 } - -upsDiagSubSysBattMonitorTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysBattMonitorEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of the Battery Monitor Board." - ::= { upsDiagnosticSubsystem 6 } - -upsDiagSubSysBattMonitorEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysBattMonitorEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of the Battery Monitor Board." - INDEX { upsDiagSubSysBattMonitorIndex} - ::= { upsDiagSubSysBattMonitorTable 1 } - -UpsDiagSubSysBattMonitorEntry ::= - SEQUENCE { - upsDiagSubSysBattMonitorFrameIndex INTEGER, - upsDiagSubSysBattMonitorIndex INTEGER, - upsDiagSubSysBattMonitorStatus INTEGER, - upsDiagSubSysBattMonitorFirmwareRev DisplayString, - upsDiagSubSysBattMonitorHardwareRev DisplayString, - upsDiagSubSysBattMonitorSerialNum DisplayString, - upsDiagSubSysBattMonitorManufactureDate DisplayString - } - -upsDiagSubSysBattMonitorFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysBattMonitorEntry 1 } - -upsDiagSubSysBattMonitorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 2 } - -upsDiagSubSysBattMonitorStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Battery Monitor Board. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysBattMonitorEntry 3 } - -upsDiagSubSysBattMonitorFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 4 } - -upsDiagSubSysBattMonitorHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 5 } - -upsDiagSubSysBattMonitorSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 6 } - -upsDiagSubSysBattMonitorManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the manufacture for the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 7 } - -upsDiagSubSysExternalSwitchGearTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of External Switch Gears attached to the UPS." - ::= { upsDiagnosticSubsystem 7 } - -upsDiagSubSysExternalSwitchGearTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysExternalSwitchGearEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of the individual External Switch Gear." - ::= { upsDiagnosticSubsystem 8 } - -upsDiagSubSysExternalSwitchGearEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysExternalSwitchGearEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an individual External Switch Gear." - INDEX { upsDiagSubSysExternalSwitchGearIndex} - ::= { upsDiagSubSysExternalSwitchGearTable 1 } - -UpsDiagSubSysExternalSwitchGearEntry ::= - SEQUENCE { - upsDiagSubSysExternalSwitchGearFrameIndex INTEGER, - upsDiagSubSysExternalSwitchGearIndex INTEGER, - upsDiagSubSysExternalSwitchGearStatus INTEGER, - upsDiagSubSysExternalSwitchGearFirmwareRev DisplayString, - upsDiagSubSysExternalSwitchGearHardwareRev DisplayString, - upsDiagSubSysExternalSwitchGearSerialNum DisplayString, - upsDiagSubSysExternalSwitchGearManufactureDate DisplayString - } - -upsDiagSubSysExternalSwitchGearFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysExternalSwitchGearEntry 1 } - -upsDiagSubSysExternalSwitchGearIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the External Switch Gear." - ::= { upsDiagSubSysExternalSwitchGearEntry 2 } - -upsDiagSubSysExternalSwitchGearStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the External Switch Gear. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysExternalSwitchGearEntry 3 } - -upsDiagSubSysExternalSwitchGearFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 4 } - -upsDiagSubSysExternalSwitchGearHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 5 } - -upsDiagSubSysExternalSwitchGearSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 6 } - -upsDiagSubSysExternalSwitchGearManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the manufacture for the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 7 } - -upsDiagSubSysDisplayInterfaceCardTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Display Interface Cards attached to the UPS." - ::= { upsDiagnosticSubsystem 9 } - -upsDiagSubSysDisplayInterfaceCardTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysDisplayInterfaceCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual Display Interface Cards." - ::= { upsDiagnosticSubsystem 10 } - -upsDiagSubSysDisplayInterfaceCardEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysDisplayInterfaceCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a Display Interface Card." - INDEX { upsDiagSubSysDisplayInterfaceCardIndex} - ::= { upsDiagSubSysDisplayInterfaceCardTable 1 } - -UpsDiagSubSysDisplayInterfaceCardEntry ::= - SEQUENCE { - upsDiagSubSysDisplayInterfaceCardFrameIndex INTEGER, - upsDiagSubSysDisplayInterfaceCardIndex INTEGER, - upsDiagSubSysDisplayInterfaceCardStatus INTEGER - } - -upsDiagSubSysDisplayInterfaceCardFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysDisplayInterfaceCardEntry 1 } - -upsDiagSubSysDisplayInterfaceCardIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Display Interface Card." - ::= { upsDiagSubSysDisplayInterfaceCardEntry 2 } - -upsDiagSubSysDisplayInterfaceCardStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Display Interface Card. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysDisplayInterfaceCardEntry 3 } - -upsDiagSubSysDCCircuitBreakerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC Circuit Breakers attached to the UPS." - ::= { upsDiagnosticSubsystem 11 } - -upsDiagSubSysDCCircuitBreakerTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysDCCircuitBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual DC Circuit Breakers." - ::= { upsDiagnosticSubsystem 12 } - -upsDiagSubSysDCCircuitBreakerEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysDCCircuitBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a DC Circuit Breaker." - INDEX { upsDiagSubSysDCCircuitBreakerIndex} - ::= { upsDiagSubSysDCCircuitBreakerTable 1 } - -UpsDiagSubSysDCCircuitBreakerEntry ::= - SEQUENCE { - upsDiagSubSysDCCircuitBreakerFrameIndex INTEGER, - upsDiagSubSysDCCircuitBreakerIndex INTEGER, - upsDiagSubSysDCCircuitBreakerStatus INTEGER - } - -upsDiagSubSysDCCircuitBreakerFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysDCCircuitBreakerEntry 1 } - -upsDiagSubSysDCCircuitBreakerIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the DC Circuit Breaker." - ::= { upsDiagSubSysDCCircuitBreakerEntry 2 } - -upsDiagSubSysDCCircuitBreakerStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the DC Circuit Breaker. - unknown(1) indicates the circuit breaker status is unknown. - notInstalled(2) indicates the circuit breaker is not installed. - opened(3) indicates the circuit breaker is opened. - closed(4) indicates the circuit breaker is closed." - ::= { upsDiagSubSysDCCircuitBreakerEntry 3 } - -upsDiagSubSysSystemPowerSupplyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of System Power Supplies attached to the UPS." - ::= { upsDiagnosticSubsystem 13 } - -upsDiagSubSysSystemPowerSupplyTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysSystemPowerSupplyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual System Power Supplies." - ::= { upsDiagnosticSubsystem 14 } - -upsDiagSubSysSystemPowerSupplyEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysSystemPowerSupplyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a System Power Supply." - INDEX { upsDiagSubSysSystemPowerSupplyIndex} - ::= { upsDiagSubSysSystemPowerSupplyTable 1 } - -UpsDiagSubSysSystemPowerSupplyEntry ::= - SEQUENCE { - upsDiagSubSysSystemPowerSupplyFrameIndex INTEGER, - upsDiagSubSysSystemPowerSupplyIndex INTEGER, - upsDiagSubSysSystemPowerSupplyStatus INTEGER - } - -upsDiagSubSysSystemPowerSupplyFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysSystemPowerSupplyEntry 1 } - -upsDiagSubSysSystemPowerSupplyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a System Power Supply." - ::= { upsDiagSubSysSystemPowerSupplyEntry 2 } - -upsDiagSubSysSystemPowerSupplyStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the System Power Supply. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysSystemPowerSupplyEntry 3 } - -upsDiagSubSysXRCommunicationCardTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of XR Communication Cards attached to the UPS." - ::= { upsDiagnosticSubsystem 15 } - -upsDiagSubSysXRCommunicationCardTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysXRCommunicationCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual XR Communication Cards." - ::= { upsDiagnosticSubsystem 16 } - -upsDiagSubSysXRCommunicationCardEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysXRCommunicationCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an XR Communication Card." - INDEX { upsDiagSubSysXRCommunicationCardIndex} - ::= { upsDiagSubSysXRCommunicationCardTable 1 } - -UpsDiagSubSysXRCommunicationCardEntry ::= - SEQUENCE { - upsDiagSubSysXRCommunicationCardFrameIndex INTEGER, - upsDiagSubSysXRCommunicationCardIndex INTEGER, - upsDiagSubSysXRCommunicationCardStatus INTEGER - } - -upsDiagSubSysXRCommunicationCardFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysXRCommunicationCardEntry 1 } - -upsDiagSubSysXRCommunicationCardIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an XR Communication Card." - ::= { upsDiagSubSysXRCommunicationCardEntry 2 } - -upsDiagSubSysXRCommunicationCardStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the XR Communication Card. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysXRCommunicationCardEntry 3 } - -upsDiagSubSysExternalPowerFrameBoardTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of External Power Frame Boards attached to the UPS." - ::= { upsDiagnosticSubsystem 17 } - -upsDiagSubSysExternalPowerFrameBoardTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysExternalPowerFrameBoardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual External Power Frame Boards." - ::= { upsDiagnosticSubsystem 18 } - -upsDiagSubSysExternalPowerFrameBoardEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysExternalPowerFrameBoardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an External Power Frame Board." - INDEX { upsDiagSubSysExternalPowerFrameBoardIndex} - ::= { upsDiagSubSysExternalPowerFrameBoardTable 1 } - -UpsDiagSubSysExternalPowerFrameBoardEntry ::= - SEQUENCE { - upsDiagSubSysExternalPowerFrameBoardFrameIndex INTEGER, - upsDiagSubSysExternalPowerFrameBoardIndex INTEGER, - upsDiagSubSysExternalPowerFrameBoardStatus INTEGER - } - -upsDiagSubSysExternalPowerFrameBoardFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysExternalPowerFrameBoardEntry 1 } - -upsDiagSubSysExternalPowerFrameBoardIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an External Power Frame Board." - ::= { upsDiagSubSysExternalPowerFrameBoardEntry 2 } - -upsDiagSubSysExternalPowerFrameBoardStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the External Power Frame Board. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysExternalPowerFrameBoardEntry 3 } - -upsDiagSubSysChargerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Chargers attached to the UPS." - ::= { upsDiagnosticSubsystem 19 } - - upsDiagSubSysChargerTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysChargerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual chargers." - ::= { upsDiagnosticSubsystem 20 } - -upsDiagSubSysChargerEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysChargerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a charger." - INDEX { upsDiagSubSysChargerIndex} - ::= { upsDiagSubSysChargerTable 1 } - -UpsDiagSubSysChargerEntry ::= - SEQUENCE { - upsDiagSubSysChargerFrameIndex INTEGER, - upsDiagSubSysChargerIndex INTEGER, - upsDiagSubSysChargerStatus INTEGER - } - -upsDiagSubSysChargerFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysChargerEntry 1 } - -upsDiagSubSysChargerIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a charger." - ::= { upsDiagSubSysChargerEntry 2 } - -upsDiagSubSysChargerStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Charger. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysChargerEntry 3 } - --- the upsDiagnosticExternalDevices group - -upsDiagSwitchGearStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - fail (4), - lostComm (5), - overtemp (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - fail(4) indicates the device status has failed. - lostComm(5) indicates the device has lost communication. - overtemp(6) indicates the device has an over temperature condition." - ::= { upsDiagSwitchGear 1 } - -upsDiagSwitchGearInputSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear Input Switch. - unknown(1) indicates the switch status is unknown. - notInstalled(2) indicates the switch is not installed. - opened(3) indicates the switch is opened. - closed(4) indicates the switch is closed." - ::= { upsDiagSwitchGear 2 } - -upsDiagSwitchGearOutputSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear Output Switch. - unknown(1) indicates the switch status is unknown. - notInstalled(2) indicates the switch is not installed. - opened(3) indicates the switch is opened. - closed(4) indicates the switch is closed." - ::= { upsDiagSwitchGear 3 } - -upsDiagSwitchGearBypassSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear Bypass Switch. - unknown(1) indicates the switch status is unknown. - notInstalled(2) indicates the switch is not installed. - opened(3) indicates the switch is opened. - closed(4) indicates the switch is closed." - ::= { upsDiagSwitchGear 4 } - -upsDiagMCCBBoxStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the MCCB Box (Molded Case Circuit Breaker Box) external device. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - opened(3) indicates the circuit is opened. - closed(4) indicates the circuit is closed." - ::= { upsDiagMCCBBox 1 } - -upsDiagTransformerStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - fail (4), - lostComm (5), - overtemp (6), - opened (7), - closed (8) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the External Transformer. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - fail(4) indicates the device status has failed. - lostComm(5) indicates the device has lost communication. - overtemp(6) indicates the device has an over temperature condition. - opened(7) indicates the circuit is opened. - closed(8) indicates the circuit is closed." - ::= { upsDiagTransformer 1 } - --- the upsDiagnosticComBus group - -upsDiagComBusInternalMIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the internal MIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 1 } - -upsDiagComBusInternalRIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the internal RIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 2 } - -upsDiagComBusMIMtoRIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the MIM to RIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 3 } - -upsDiagComBusExternalMIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the external MIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 4 } - -upsDiagComBusExternalRIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the external RIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 5 } - --- the serialPort2Config group - -serialPort2Mode OBJECT-TYPE - SYNTAX INTEGER { - localConsole(1), - passthrough(2) - } - ACCESS read-write - STATUS obsolete - DESCRIPTION - "Setting this variable to passthrough will enable mini's port2 - behave like a UPS port. Choosing localConsole will enable the port - to be used as local console." - ::= { serialPort2Config 1 } --- the serialPort2Control group - -setPulseOnTXD OBJECT-TYPE - SYNTAX INTEGER { - noSetPulseOnTXD(1), - setPulseOnTXD(2), - setTXDLow(3), - setTXDHigh(4) - - } - ACCESS read-write - STATUS obsolete - DESCRIPTION - "Setting this variable to setPulseOnTXD(2) - causes adapter to generate a PULSE on TXD pin of serial port 2. - The duration in the prototype implementation will be 1 second. - - Setting this value to noSetPulseOnTXD(1) has no - effect. - - The value noSetPulseOnTXD(1) will always be returned - when the variable is read. - - Setting this value to setTXDLow(3), or setTXDHigh(4) will keep TXD - always low or high respectively." - ::= { serialPort2Control 1 } - --- the sPDUIdent group - -sPDUIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the PDU. This value - is set at the factory." - ::= { sPDUIdent 1 } - -sPDUIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 8 byte ID string identifying the PDU firmware revision. - This value is set at the factory." - ::= { sPDUIdent 2 } - - -sPDUIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the PDU was manufactured in mm/dd/yy format. - This value is set at the factory. The year 2000 will be - represented by 00." - ::= { sPDUIdent 3 } - -sPDUIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 10-character string identifying the model number of - the PDU internal. This value is set at the factory." - ::= { sPDUIdent 4 } - -sPDUIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 12-character string identifying the serial number of - the PDU internal microprocessor. This value is set at - the factory." - ::= { sPDUIdent 5 } - - --- the sPDUMasterControl group - -sPDUMasterControlSwitch OBJECT-TYPE - SYNTAX INTEGER { - turnAllOnNow (1), - turnAllOnSequence (2), - turnAllOffNow (3), - rebootAllNow (4), - rebootAllSequence (5), - noCommand (6), - turnAllOffSequence (7) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to turnAllOnNow (1) will turn all outlets - on immediately. - - Setting this OID to turnAllOnSequence (2) will turn all outlets - on as defined by each outlet's sPDUOutletPowerOnTime OID value. - - Setting this OID to turnAllOff (3) will turn all outlets - off immediately. - - Setting this OID to rebootAllNow (4) will reboot all outlets - immediately. - - For MasterSwitch firmware version 1.X, setting this OID to - rebootAllSequence (5) reboots all outlets, with power returned - to the outlets in the sequence defined by each outlet's - sPDUOutletPowerOnTime OID value. - - For MasterSwitch firmware version 2.X, setting this OID to - rebootAllSequence (5) will cause a turnAllOffSequence to be performed. - Once all outlets are off, the MasterSwitch will then delay the - sPDUMasterConfigReboot OID time, and then perform a turnAllOnSequence. - - For MasterSwitch firmware version 2.X, setting this OID to - turnAllOffSequence (7) will turn all outlets off as defined by - each outlet's sPDUOutletPowerOffTime OID value. - - For MasterSwitch firmware version 1.X, setting this OID to - turnAllOffSequence (7) will have no effect. - - Getting this OID will return the noCommand (6) value." - - ::= { sPDUMasterControl 1 } - - -sPDUMasterState OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will cause the status of all outlets to be - returned. This OID is provided for informational purposes only. - To change the outlet state, the user should use the sPDUOutletCtl - OID in the sPDUOutletControlTable. - - The format of the data returned is a character string consisting - of the word 'On' if the outlet is on or 'Off' if the outlet is - off. At least one space will delimit each outlet entry in the - string. - - If the outlet states are unknown, the character string 'Unknown' - will be returned. This signifies that there is an inconsistancy - in the PDU. In the rare case that this should happen, the user - is advised to shut down all equipment powered by the PDU and - then cycle the PDU's power. This will put the PDU in a consistent - state." - - ::= { sPDUMasterControl 2 } - -sPDUMasterPending OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will cause the command pending status of all outlets to be returned. - - The format of the data returned is a character string consisting - of the word 'Yes' if a command is pending for the outlet or 'No' - if there is no command pending for the outlet. At least one - space will delimit each outlet entry in the string. - - If the pending states are unknown, the character string 'Unknown' - will be returned. This signifies that there is an inconsistancy - in the PDU. In the rare case that this should happen, the user - is advised to shut down all equipment powered by the PDU and then - cycle the PDU's power. This will put the PDU in a consistent state." - ::= { sPDUMasterControl 3 } - - --- the sPDUMasterConfig group - -sPDUMasterConfigPowerOn OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when - power is provided to the PDU and when the PDU - provides basic master power to the outlets. - - Allowed values are: - - -1 never apply power automatically. - 0 apply power immediately. - 15 apply power in 15 seconds. - 30 apply power in 30 seconds. - 45 apply power in 45 seconds. - 60 apply power in 60 seconds (1 minute). - 120 apply power in 120 seconds (2 minutes). - 300 apply power in 300 seconds (5 minutes). - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - - ::= { sPDUMasterConfig 1 } - -sPDUMasterConfigReboot OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed values are: - - 5 wait 5 seconds between off/on. - 10 wait 10 seconds between off/on. - 15 wait 15 seconds between off/on. - 20 wait 20 seconds between off/on. - 30 wait 30 seconds between off/on. - 45 wait 45 seconds between off/on. - 60 wait 60 seconds (1 minute) between off/on. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used. - - This OID is read-only for the MasterSwitch version 2.X and is the - maximum sPDUOutletRebootDuration OID of the individual outlets." - - ::= { sPDUMasterConfig 2 } - -sPDUMasterConfigPDUName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the PDU. The maximum value is 20 characters." - ::= { sPDUMasterConfig 3 } - - - --- the sPDUOutletControl group -sPDUOutletControlTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlets for the PDU." - ::= { sPDUOutletControl 1 } - - -sPDUOutletControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the sPDUOutletControlTableSize OID." - ::= { sPDUOutletControl 2 } - -sPDUOutletControlEntry OBJECT-TYPE - SYNTAX OutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletControlIndex} - ::= { sPDUOutletControlTable 1 } - -OutletControlEntry ::= - SEQUENCE { - sPDUOutletControlIndex INTEGER, - sPDUOutletPending INTEGER, - sPDUOutletCtl INTEGER, - sPDUOutletCtlName DisplayString - } - -sPDUOutletControlIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletControlEntry 1 } - -sPDUOutletPending OBJECT-TYPE - SYNTAX INTEGER{ - commandPending (1), - noCommandPending (2), - commandPendingUnknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Reports whether the current outlet has a pending command. - - If the commandPendingUnknown (3) value is returned, all - devices powered by the PDU should be shut down. The PDU's - power should then be cycled to clear this condition." - - ::= { sPDUOutletControlEntry 2 } - -sPDUOutletCtl OBJECT-TYPE - SYNTAX INTEGER { - outletOn (1), - outletOff (2), - outletReboot (3), - outletUnknown (4), - outletOnWithDelay (5), - outletOffWithDelay (6), - outletRebootWithDelay (7) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletOn (1) value will be returned. - If the outlet is off, the outletOff (2) value will be - returned. - - If the state of the outlet cannot be determined, the - outletUnknown (4) value will be returned. If the - outletUnknown condition should occur, all devices - powered by the PDU should be shut down. The PDU's power - should then be cycled to clear this condition. - - Setting this variable to outletOn (1) will turn the outlet on. - - Setting this variable to outletOff (2) will turn the outlet off. - - Setting this variable to outletReboot (3) will reboot the outlet. - - Setting this variable to outletOnWithDelay (5) will turn the outlet on - after the sPDUOutletPowerOnTime OID has elapsed. This option is not - valid for MasterSwitch firmware version 1.X. - - Setting this variable to outletOffWithDelay (6) will turn the outlet off - after the sPDUOutletPowerOffTime OID has elapsed. This option is not valid - for MasterSwitch firmware version 1.X. - - Setting this variable to outletRebootWithDelay (7) will turn the outlet off - after the sPDUOutletPowerOffTime OID has elapsed, wait the sPDUOutletRebootDuration - OID time, then turn the outlet back on. - This option is not valid for MasterSwitch firmware version 1.X." - - ::= { sPDUOutletControlEntry 3 } - -sPDUOutletCtlName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 20 characters. - This OID is provided for informational purposes only. - This value is set by the sPDUOutletName OID." - - ::= { sPDUOutletControlEntry 4 } - --- the sPDUOutletConfig group -sPDUOutletConfigTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlets for the PDU." - ::= { sPDUOutletConfig 1 } - -sPDUOutletConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF SPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The list of outlets to configure. The number of - entries is defined by the sPDUOutletConfigTableSize - OID." - - ::= { sPDUOutletConfig 2 } - -sPDUOutletConfigEntry OBJECT-TYPE - SYNTAX SPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletConfigIndex} - ::= { sPDUOutletConfigTable 1 } - -SPDUOutletConfigEntry ::= - SEQUENCE { - sPDUOutletConfigIndex INTEGER, - sPDUOutletPowerOnTime INTEGER, - sPDUOutletName DisplayString, - sPDUOutletPowerOffTime INTEGER, - sPDUOutletRebootDuration INTEGER - } - -sPDUOutletConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigEntry 1 } - -sPDUOutletPowerOnTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering on when the MasterSwitch is powered on. - - Allowed values are: - - -1 never power on automatically. - 0 power on with the Master Switch. - 15 power on 15 seconds after the MasterSwitch has power applied. - 30 power on 30 seconds after the MasterSwitch has power applied. - 45 power on 45 seconds after the MasterSwitch has power applied. - 60 power on 60 seconds (1 minute) after the MasterSwitch has power applied. - 120 power on 120 seconds (2 minutes) after the MasterSwitch has power applied. - 300 power on 300 seconds (5 minutes) after the MasterSwitch has power applied. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - - ::= { sPDUOutletConfigEntry 2 } - -sPDUOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 20 characters." - - ::= { sPDUOutletConfigEntry 3 } - -sPDUOutletPowerOffTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering off. - - Allowed values are: - - -1 never power off automatically. - 0 power off with the MasterSwitch. - 15 power off 15 seconds after being commanded. - 30 power off 30 seconds after being commanded. - 45 power off 45 seconds after being commanded. - 60 power off 60 seconds (1 minute) after being commanded. - 120 power off 120 seconds (2 minutes) after being commanded. - 300 power off 300 seconds (5 minutes) after being commanded. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used. - - This OID is not available for MasterSwitch firmware version 1.X." - - ::= { sPDUOutletConfigEntry 4 } - -sPDUOutletRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed values are: - - 5 wait 5 seconds between off/on. - 10 wait 10 seconds between off/on. - 15 wait 15 seconds between off/on. - 20 wait 20 seconds between off/on. - 30 wait 30 seconds between off/on. - 45 wait 45 seconds between off/on. - 60 wait 60 seconds (1 minute) between off/on. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used. - - This OID is not available for MasterSwitch firmware version 1.X." - - ::= { sPDUOutletConfigEntry 5 } - - --- the sPDUIdentVM group - -sPDUIdentVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs controllable - by this IP address." - ::= { sPDUIdentVM 1 } - - -sPDUIdentVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for query of the individual MasterSwitch VMs. - The number of entries is contained in the - sPDUIdentVMTableSize OID." - ::= { sPDUIdentVM 2 } - -sPDUIdentVMEntry OBJECT-TYPE - SYNTAX IdentVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to query." - INDEX { sPDUIdentVMIndex} - ::= { sPDUIdentVMTable 1 } - -IdentVMEntry ::= - SEQUENCE { - sPDUIdentVMIndex INTEGER, - sPDUIdentNameVM DisplayString, - sPDUIdentHardwareRevVM DisplayString, - sPDUIdentFirmwareRevVM DisplayString, - sPDUIdentDateOfManufactureVM DisplayString, - sPDUIdentModelNumberVM DisplayString, - sPDUIdentSerialNumberVM DisplayString - } - -sPDUIdentVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUIdentVMEntry 1 } - -sPDUIdentNameVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 23-character string identifying the - MasterSwitch VM. " - ::= { sPDUIdentVMEntry 2 } - -sPDUIdentHardwareRevVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware version of the MasterSwitch VM. - This value is set at the factory." - ::= { sPDUIdentVMEntry 3 } - -sPDUIdentFirmwareRevVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 6-character ID string identifying the MasterSwitch VM - firmware version. This value is set at the factory." - ::= { sPDUIdentVMEntry 4 } - - -sPDUIdentDateOfManufactureVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the MasterSwitch VM was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { sPDUIdentVMEntry 5 } - -sPDUIdentModelNumberVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the model number of - the MasterSwitch VM. This value is set at the factory." - ::= { sPDUIdentVMEntry 6 } - -sPDUIdentSerialNumberVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the serial number of - the MasterSwitch VM. This value is set at the factory." - ::= { sPDUIdentVMEntry 7 } - - --- the sPDUMasterControlVM group - -sPDUMasterControlVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs controllable - by this IP address." - ::= { sPDUMasterControlVM 1 } - - -sPDUMasterControlVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of the individual MasterSwitch VMs. - The number of entries is contained in the - sPDUMasterControlVMTableSize OID." - ::= { sPDUMasterControlVM 2 } - -sPDUMasterControlVMEntry OBJECT-TYPE - SYNTAX MasterControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to control." - INDEX { sPDUMasterControlVMIndex} - ::= { sPDUMasterControlVMTable 1 } - -MasterControlVMEntry ::= - SEQUENCE { - sPDUMasterControlVMIndex INTEGER, - sPDUMasterControlVMName DisplayString, - sPDUMasterControlVMCommand INTEGER - } - -sPDUMasterControlVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUMasterControlVMEntry 1 } - -sPDUMasterControlVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigVMName OID." - ::= { sPDUMasterControlVMEntry 2 } - -sPDUMasterControlVMCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandAllVM (1), - immediateAllOnVM (2), - immediateAllOffVM (3), - immediateAllRebootVM (4), - delayedAllOnVM (5), - delayedAllOffVM (6), - sequencedAllRebootVM (7), - delayedAllRebootVM (8), - delayedSequenceAllRebootVM (9), - cancelAllPendingCommandsVM (10), - audioAlarmMute (11) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to immediateAllOnVM (2) will turn all outlets - on immediately. - - Setting this OID to immediateAllOffVM (3) will turn all outlets - off immediately. - - Setting this OID to immediateAllRebootVM (4) will reboot all outlets - immediately. - - Setting this OID to delayedAllOnVM (5) will turn all outlets on as - defined by each outlet's sPDUOutletConfigVMPowerOnTime OID value. - - Setting this OID to delayedAllOffVM (6) will turn all outlets - off as defined by each outlet's sPDUOutletConfigVMPowerOffTime OID value. - - Setting this OID to sequencedAllRebootVM (7) will cause a - immediateAllOffVM command to be performed. The MasterSwitch VM will - then delay the sPDUMasterStatusVMRebootDuration OID time, and then - perform a delayedAllOnVM command. - - Setting this OID to delayedAllRebootVM (8) will cause a delayedAllOffVM - command to be performed. Each outlet will then wait its - sPDUOutletConfigVMRebootDuration before returning power to the outlet. - - Setting this OID to delayedSequenceAllRebootVM (9) will cause a - delayedAllOffVM command to be performed. Once all outlets are off, - the MasterSwitch VM will then delay the sPDUMasterStatusVMRebootDuration - OID time, and then perform a delayedAllOnVM command. - - Setting this OID to cancelAllPendingCommandsVM (10) will cause all pending - commands on the MasterSwitch VM to be canceled. - - - Setting this OID to audioAlarmMute (11) will temporarily silence the audible - alarm for the duration of the current overload condition. The audible alarm - will be activated on subsequent overload alarms. - - Getting this OID will return the noCommandAllVM (1) value." - ::= { sPDUMasterControlVMEntry 3 } - - --- the sPDUMasterConfigVM group - -sPDUMasterConfigVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs configurable - by this IP address." - ::= { sPDUMasterConfigVM 1 } - - -sPDUMasterConfigVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of the individual MasterSwitch VMs. - The number of entries is contained in the - sPDUMasterConfigVMTableSize OID." - ::= { sPDUMasterConfigVM 2 } - -sPDUMasterConfigVMEntry OBJECT-TYPE - SYNTAX MasterConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to configure." - INDEX { sPDUMasterConfigVMIndex} - ::= { sPDUMasterConfigVMTable 1 } - -MasterConfigVMEntry ::= - SEQUENCE { - sPDUMasterConfigVMIndex INTEGER, - sPDUMasterConfigVMName DisplayString, - sPDUMasterConfigVMColdstartDelay INTEGER, - sPDUMasterConfigVMAudioAlarmActivated INTEGER, - sPDUMasterConfigVMHighLoadWarningThreshold INTEGER, - sPDUMasterConfigVMLowLoadWarningThreshold INTEGER, - sPDUMasterConfigVMOverloadRestriction INTEGER - } - -sPDUMasterConfigVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUMasterConfigVMEntry 1 } - - -sPDUMasterConfigVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUMasterConfigVMEntry 2 } - -sPDUMasterConfigVMColdstartDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when - power is provided to the MasterSwitch VM and - when the MasterSwitch VM provides basic master - power to the outlets. - - Allowed values are: - - -1 never apply power automatically. - 0 apply power immediately. - 15 apply power in 15 seconds. - 30 apply power in 30 seconds. - 45 apply power in 45 seconds. - 60 apply power in 60 seconds (1 minute). - 120 apply power in 120 seconds (2 minutes). - 300 apply power in 300 seconds (5 minutes). - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUMasterConfigVMEntry 3 } - -sPDUMasterConfigVMAudioAlarmActivated OBJECT-TYPE - SYNTAX INTEGER { - audioAlarmActiveNever (1), - audioAlarmActiveOnOverload (2), - audioAlarmActiveOnOverloadImminent (3) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to audioAlarmActiveNever (1) will disable - the audio alarm on the MasterSwitch VM. - - Setting this OID to audioAlarmActiveOnOverload (2) will - activate the audio alarm on the MasterSwitch VM when an - overload condition is present. - - Setting this OID to audioAlarmActiveOnOverloadImminent (3) - will activate the audio alarm on the MasterSwitch VM when - the load on the MasterSwitch VM has surpassed the - sPDUMasterConfigVMHighLoadWarningThreshold OID value." - ::= { sPDUMasterConfigVMEntry 4 } - -sPDUMasterConfigVMHighLoadWarningThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing an overload condition. It is - represented as a percentage of full load." - ::= { sPDUMasterConfigVMEntry 5 } - -sPDUMasterConfigVMLowLoadWarningThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing a low consumption condition. It is - represented as a percentage of full load." - ::= { sPDUMasterConfigVMEntry 6 } - -sPDUMasterConfigVMOverloadRestriction OBJECT-TYPE - SYNTAX INTEGER { - alwaysAllowTurnON (1), - restrictOnWarning (2), - restrictOnOverload (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID controls the behavior of the MasterSwitch VM - when an overload condition is possible and additional - outlets are requested to be turned on. - - Setting this OID to alwaysAllowTurnON (1) will always allow - the outlets to turn on. - - Setting this OID to restrictOnWarning (2) will not allow - outlets to turn on if the sPDUMasterConfigVMHighLoadWarningThreshold - OID is exceeded. - - Setting this OID to restrictOnOverload (3) will not allow - outlets to turn on if the MasterSwitch Vm is in an - overload condition." - ::= { sPDUMasterConfigVMEntry 7 } - --- the sPDUMasterStatusVM group - -sPDUMasterStatusVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs at - this IP address." - ::= { sPDUMasterStatusVM 1 } - - -sPDUMasterStatusVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for gathering of status from the individual - MasterSwitch VMs. The number of entries is contained - in the sPDUMasterStatusVMTableSize OID." - ::= { sPDUMasterStatusVM 2 } - -sPDUMasterStatusVMEntry OBJECT-TYPE - SYNTAX MasterStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to gather status from." - INDEX { sPDUMasterStatusVMIndex} - ::= { sPDUMasterStatusVMTable 1 } - -MasterStatusVMEntry ::= - SEQUENCE { - sPDUMasterStatusVMIndex INTEGER, - sPDUMasterStatusVMName DisplayString, - sPDUMasterStatusVMCommandPending INTEGER, - sPDUMasterStatusVMOverloadCondition INTEGER, - sPDUMasterStatusVMLowLoadCondition INTEGER, - sPDUMasterStatusVMCurrentLoad INTEGER, - sPDUMasterStatusVMMaxLoad INTEGER, - sPDUMasterStatusVMOutletCount INTEGER, - sPDUMasterStatusVMRebootDuration INTEGER - } - -sPDUMasterStatusVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUMasterStatusVMEntry 1 } - -sPDUMasterStatusVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUMasterStatusVMEntry 2 } - -sPDUMasterStatusVMCommandPending OBJECT-TYPE - SYNTAX INTEGER { - commandPendingMasterTrueVM (1), - commandPendingMasterFalseVM (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return commandPendingMasterTrueVM (1) - if the MasterSwitch VM has a pending command on any of its - outlets. - - commandPendingMasterFalseVM (2) will be returned if there are - no pending commands." - ::= { sPDUMasterStatusVMEntry 3 } - -sPDUMasterStatusVMOverloadCondition OBJECT-TYPE - SYNTAX INTEGER { - overloadConditionTrueVM (1), - overloadConditionFalseVM (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return overloadConditionTrueVM (1) - if the sPDUMasterConfigVMHighLoadWarningThreshold OID is - violated. - - overloadConditionFalseVM (2) will be returned if the - sPDUMasterConfigVMHighLoadWarningThreshold OID is not - violated." - ::= { sPDUMasterStatusVMEntry 4 } - -sPDUMasterStatusVMLowLoadCondition OBJECT-TYPE - SYNTAX INTEGER { - lowLoadConditionTrueVM (1), - lowLoadConditionFalseVM (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return lowLoadConditionTrueVM (1) - if the sPDUMasterConfigVMLowLoadWarningThreshold OID is - violated. - - lowLoadConditionFalseVM (2) will be returned if the - sPDUMasterConfigVMHighLoadWarningThreshold OID is not - violated. " - ::= { sPDUMasterStatusVMEntry 5 } - -sPDUMasterStatusVMCurrentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the total amount of power - being consumed by the load. It is represented as a - percentage of full load." - ::= { sPDUMasterStatusVMEntry 6 } - -sPDUMasterStatusVMMaxLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the total amount of power - that this MasterSwitch VM can provide. It is represented - in Amps." - ::= { sPDUMasterStatusVMEntry 7 } - -sPDUMasterStatusVMOutletCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of controllable - outlets for this MasterSwitch VM." - ::= { sPDUMasterStatusVMEntry 8 } - -sPDUMasterStatusVMRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the largest - sPDUOutletConfigVMRebootDuration OID time - for this MasterSwitch VM." - ::= { sPDUMasterStatusVMEntry 9 } - --- the sPDUOutletControlVM group - - -sPDUOutletControlVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletControlVM 1 } - -sPDUOutletControlVMEntry OBJECT-TYPE - SYNTAX OutletControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletControlVMIndex, sPDUOutletControlVMOutletIndex } - ::= { sPDUOutletControlVMTable 1 } - -OutletControlVMEntry ::= - SEQUENCE { - sPDUOutletControlVMIndex INTEGER, - sPDUOutletControlVMName DisplayString, - sPDUOutletControlVMOutletIndex INTEGER, - sPDUOutletControlVMOutletName DisplayString, - sPDUOutletControlVMOutletCommand INTEGER - } - -sPDUOutletControlVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM." - ::= { sPDUOutletControlVMEntry 1 } - -sPDUOutletControlVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters. - This OID is provided for informational purposes only." - ::= { sPDUOutletControlVMEntry 2 } - -sPDUOutletControlVMOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletControlVMEntry 3 } - -sPDUOutletControlVMOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters. - This OID is provided for informational purposes only." - ::= { sPDUOutletControlVMEntry 4 } - -sPDUOutletControlVMOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOnVM (1), - immediateOffVM (2), - immediateRebootVM (3), - delayedOnVM (4), - delayedOffVM (5), - delayedRebootVM (6), - cancelPendingCommandVM (7) - - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOnVM (1) value will be returned. - If the outlet is off, the immediateOffVM (2) value will be - returned. - - - Setting this variable to immediateOnVM (1) will immediately turn the outlet on. - - Setting this variable to immediateOffVM (2) will immediately turn the outlet off. - - Setting this variable to immediateRebootVM (3) will immediately reboot the outlet. - - Setting this variable to delayedOnVM (4) will turn the outlet on - after the sPDUOutletConfigVMPowerOnTime OID time has elapsed. - - Setting this variable to delayedOffVM (5) will turn the outlet off - after the sPDUOutletConfigVMPowerOffTime OID time has elapsed. - - Setting this variable to delayedRebootVM (6) will cause the - MasterSwitch VM to perform a delayedOffVM command, wait the - sPDUOutletConfigVMRebootDuration OID time, and then perform the - immediateOnVM command. - - Setting this variable to cancelPendingCommandVM (7) will cause any - pending command to this outlet to be canceled." - ::= { sPDUOutletControlVMEntry 5 } - --- the sPDUOutletConfigVM group - -sPDUOutletConfigVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletConfigVM 1 } - -sPDUOutletConfigVMEntry OBJECT-TYPE - SYNTAX OutletConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigVMIndex, sPDUOutletConfigVMOutletIndex } - ::= { sPDUOutletConfigVMTable 1 } - -OutletConfigVMEntry ::= - SEQUENCE { - sPDUOutletConfigVMIndex INTEGER, - sPDUOutletConfigVMName DisplayString, - sPDUOutletConfigVMOutletIndex INTEGER, - sPDUOutletConfigVMOutletName DisplayString, - sPDUOutletConfigVMPowerOnTime INTEGER, - sPDUOutletConfigVMPowerOffTime INTEGER, - sPDUOutletConfigVMRebootDuration INTEGER - } - -sPDUOutletConfigVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM." - ::= { sPDUOutletConfigVMEntry 1 } - -sPDUOutletConfigVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUOutletConfigVMEntry 2 } - -sPDUOutletConfigVMOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigVMEntry 3 } - - -sPDUOutletConfigVMOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters." - ::= { sPDUOutletConfigVMEntry 4 } - -sPDUOutletConfigVMPowerOnTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering on at coldstart or when a command that requires - a turn-on delay is issued. - - Allowed values are: - - -1 never power on. - 0 power on immediately. - 15 power on 15 seconds after being commanded. - 30 power on 30 seconds after being commanded. - 45 power on 45 seconds after being commanded. - 60 power on 60 seconds (1 minute) after being commanded. - 120 power on 120 seconds (2 minutes) after being commanded. - 300 power on 300 seconds (5 minutes) after being commanded. - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUOutletConfigVMEntry 5 } - - -sPDUOutletConfigVMPowerOffTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering off when a command that requires - a turn-off delay is issued. - - - Allowed values are: - - -1 never power off automatically. - 0 power off immediately. - 15 power off 15 seconds after being commanded. - 30 power off 30 seconds after being commanded. - 45 power off 45 seconds after being commanded. - 60 power off 60 seconds (1 minute) after being commanded. - 120 power off 120 seconds (2 minutes) after being commanded. - 300 power off 300 seconds (5 minutes) after being commanded. - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUOutletConfigVMEntry 6 } - -sPDUOutletConfigVMRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed values are: - - 5 wait 5 seconds between off/on. - 10 wait 10 seconds between off/on. - 15 wait 15 seconds between off/on. - 20 wait 20 seconds between off/on. - 30 wait 30 seconds between off/on. - 45 wait 45 seconds between off/on. - 60 wait 60 seconds (1 minute) between off/on. - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUOutletConfigVMEntry 7 } - --- the sPDUOutletStatusVM group - -sPDUOutletStatusVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of individual outlets. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletStatusVM 1 } - -sPDUOutletStatusVMEntry OBJECT-TYPE - SYNTAX OutletStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to gather status from." - INDEX { sPDUOutletStatusVMIndex, sPDUOutletStatusVMOutletIndex } - ::= { sPDUOutletStatusVMTable 1 } - -OutletStatusVMEntry ::= - SEQUENCE { - sPDUOutletStatusVMIndex INTEGER, - sPDUOutletStatusVMName DisplayString, - sPDUOutletStatusVMOutletIndex INTEGER, - sPDUOutletStatusVMOutletName DisplayString, - sPDUOutletStatusVMOutletState INTEGER, - sPDUOutletStatusVMCommandPending INTEGER - } - -sPDUOutletStatusVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM." - ::= { sPDUOutletStatusVMEntry 1 } - -sPDUOutletStatusVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUOutletStatusVMEntry 2 } - -sPDUOutletStatusVMOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletStatusVMEntry 3 } - -sPDUOutletStatusVMOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters." - ::= { sPDUOutletStatusVMEntry 4 } - -sPDUOutletStatusVMOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletStatusVMOn (1), - outletStatusVMOff (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletStatusOnVM (1) value will be returned. - If the outlet is off, the outletStatusOffVM (2) value will be - returned. " - ::= { sPDUOutletStatusVMEntry 5 } - -sPDUOutletStatusVMCommandPending OBJECT-TYPE - SYNTAX INTEGER { - outletStatusVMCommandPending (1), - outletStatusVMNoCommandPending (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet. If a command is pending on the - outlet, the outletStatusVMCommandPending (1) value - will be returned. If there is not a command pending - on the outlet, the outletStatusVMNoCommandPending (2) - will be returned." - ::= { sPDUOutletStatusVMEntry 6 } - --- the sPDUIdentMSP group - -sPDUIdentMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses controllable - by this IP address." - ::= { sPDUIdentMSP 1 } - - -sPDUIdentMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for query of the individual MasterSwitch pluses. - The number of entries is contained in the - sPDUIdentMSPTableSize OID." - ::= { sPDUIdentMSP 2 } - -sPDUIdentMSPEntry OBJECT-TYPE - SYNTAX IdentMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to query." - INDEX { sPDUIdentMSPIndex} - ::= { sPDUIdentMSPTable 1 } - -IdentMSPEntry ::= - SEQUENCE { - sPDUIdentMSPIndex INTEGER, - sPDUIdentNameMSP DisplayString, - sPDUIdentHardwareRevMSP DisplayString, - sPDUIdentFirmwareRevMSP DisplayString, - sPDUIdentDateOfManufactureMSP DisplayString, - sPDUIdentModelNumberMSP DisplayString, - sPDUIdentSerialNumberMSP DisplayString - } - -sPDUIdentMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUIdentMSPEntry 1 } - -sPDUIdentNameMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUIdentMSPEntry 2 } - -sPDUIdentHardwareRevMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware version of the MasterSwitch plus. - This value is set at the factory." - ::= { sPDUIdentMSPEntry 3 } - -sPDUIdentFirmwareRevMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 6-character ID string identifying the MasterSwitch plus - firmware version. This value is set at the factory." - ::= { sPDUIdentMSPEntry 4 } - -sPDUIdentDateOfManufactureMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the MasterSwitch plus was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { sPDUIdentMSPEntry 5 } - -sPDUIdentModelNumberMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the model number of - the MasterSwitch plus. This value is set at the factory." - ::= { sPDUIdentMSPEntry 6 } - -sPDUIdentSerialNumberMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the serial number of - the MasterSwitch plus. This value is set at the factory." - ::= { sPDUIdentMSPEntry 7 } - - --- the sPDUMasterControlMSP group - -sPDUMasterControlMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses controllable - by this IP address." - ::= { sPDUMasterControlMSP 1 } - -sPDUMasterControlMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of the individual MasterSwitch pluses. - The number of entries is contained in the - sPDUMasterControlMSPTableSize OID." - ::= { sPDUMasterControlMSP 2 } - -sPDUMasterControlMSPEntry OBJECT-TYPE - SYNTAX MasterControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to control." - INDEX { sPDUMasterControlMSPIndex} - ::= { sPDUMasterControlMSPTable 1 } - -MasterControlMSPEntry ::= - SEQUENCE { - sPDUMasterControlMSPIndex INTEGER, - sPDUMasterControlMSPName DisplayString, - sPDUMasterControlMSPCommand INTEGER - } - -sPDUMasterControlMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUMasterControlMSPEntry 1 } - -sPDUMasterControlMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUMasterControlMSPEntry 2 } - -sPDUMasterControlMSPCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandAllMSP (1), - immediateAllOnMSP (2), - sequencedAllOnMSP (3), - immediateAllOffMSP (4), - gracefulAllRebootMSP (5), - immediateAllRebootMSP (6), - gracefulAllShutdownMSP (7), - overrideAllBatCapThreshMSP (8), - cancelAllPendingCommandsMSP (9), - restoreFactoryDefaultsMSP (10) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to immediateAllOnMSP (2) will turn all outlets - on immediately. - - Setting this OID to sequencedAllOnMSP (3) will turn all outlets - on as defined by each outlet's sPDUOutletConfigMSPPowerOnDelay OID value. - - Setting this OID to immediateAllOffMSP (4) will turn all outlets - off immediately. - - Setting this OID to gracefulAllRebootMSP (5) will reboot all outlets - (after the device running PowerChute confirms shutdown) as defined - by each outlet's sPDUOutletConfigMSPRebootDuration OID time value. - - Setting this OID to immediateAllRebootMSP (6) will reboot all outlets - immediately. - - Setting this OID to gracefulAllShutdownMSP (7) will shutdown all outlets - (after the device running PowerChute confirms shutdown) as defined - by each outlet's sPDUOutletConfigMSPPowerOffDelay OID time value. Each - outlet will then turn on after the sum of its - sPDUOutletConfigMSPRestartDelay and sPDUOutletConfigMSPPowerOnDelay OID - values. - - Setting this OID to overrideAllBatCapThreshMSP (8) will cause the - outlet to ignore the Battery Capacity Threshold and proceed turning on - the outlets as defined by each outlet's sPDUOutletConfigMSPPowerOnDelay - OID value. - - Setting this OID to cancelAllPendingCommandsMSP (9) will cause all pending - commands on the MasterSwitch plus to be canceled. - - Setting this OID to restoreFactoryDefaultsMSP (10) will cause the settings of - the MasterSwitch plus to be restored to the factory defaults. - - Getting this OID will return the noCommandAllMSP (1) value." - ::= { sPDUMasterControlMSPEntry 3 } - - --- the sPDUMasterConfigMSP group - -sPDUMasterConfigMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses configurable - by this IP address." - ::= { sPDUMasterConfigMSP 1 } - -sPDUMasterConfigMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterConfigMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of the individual MasterSwitch pluses. - The number of entries is contained in the - sPDUMasterConfigMSPTableSize OID." - ::= { sPDUMasterConfigMSP 2 } - -sPDUMasterConfigMSPEntry OBJECT-TYPE - SYNTAX MasterConfigMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to configure." - INDEX { sPDUMasterConfigMSPIndex} - ::= { sPDUMasterConfigMSPTable 1 } - -MasterConfigMSPEntry ::= - SEQUENCE { - sPDUMasterConfigMSPIndex INTEGER, - sPDUMasterConfigMSPName DisplayString, - sPDUMasterConfigMSPPowerOnTimeDelay INTEGER, - sPDUMasterConfigMSPManualButton INTEGER - } - -sPDUMasterConfigMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUMasterConfigMSPEntry 1 } - -sPDUMasterConfigMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. Maximum size is 23 characters." - ::= { sPDUMasterConfigMSPEntry 2 } - -sPDUMasterConfigMSPPowerOnTimeDelay OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when - power is provided to the MasterSwitch plus and - when the MasterSwitch plus provides basic master - power to the outlets. - - Allowed values are: - - 0 - 9999 seconds (0 - 2hrs, 46 mins, 39 secs). - 0 indicates to apply power immediately." - ::= { sPDUMasterConfigMSPEntry 3 } - - -sPDUMasterConfigMSPManualButton OBJECT-TYPE - SYNTAX INTEGER { - manualButtonDisabled (1), - manualButtonEnabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to manualButtonDisabled (1) will disable - the manual button on the MasterSwitch plus. - - Setting this OID to manualButtonEnabled (2) will enable - the manual button on the MasterSwitch plus." - ::= { sPDUMasterConfigMSPEntry 4 } - --- the sPDUMasterStatusMSP group - -sPDUMasterStatusMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses at - this IP address." - ::= { sPDUMasterStatusMSP 1 } - - -sPDUMasterStatusMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for gathering of status from the individual - MasterSwitch pluses. The number of entries is contained - in the sPDUMasterStatusMSPTableSize OID." - ::= { sPDUMasterStatusMSP 2 } - -sPDUMasterStatusMSPEntry OBJECT-TYPE - SYNTAX MasterStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to gather status from." - INDEX { sPDUMasterStatusMSPIndex} - ::= { sPDUMasterStatusMSPTable 1 } - -MasterStatusMSPEntry ::= - SEQUENCE { - sPDUMasterStatusMSPIndex INTEGER, - sPDUMasterStatusMSPName DisplayString, - sPDUMasterStatusMSPOutletCount INTEGER - } - -sPDUMasterStatusMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUMasterStatusMSPEntry 1 } - -sPDUMasterStatusMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUMasterStatusMSPEntry 2 } - -sPDUMasterStatusMSPOutletCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of controllable - outlets for this MasterSwitch plus." - ::= { sPDUMasterStatusMSPEntry 3 } - --- the sPDUOutletControlMSP group - -sPDUOutletControlMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletControlMSP 1 } - -sPDUOutletControlMSPEntry OBJECT-TYPE - SYNTAX OutletControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletControlMSPIndex, sPDUOutletControlMSPOutletIndex } - ::= { sPDUOutletControlMSPTable 1 } - -OutletControlMSPEntry ::= - SEQUENCE { - sPDUOutletControlMSPIndex INTEGER, - sPDUOutletControlMSPName DisplayString, - sPDUOutletControlMSPOutletIndex INTEGER, - sPDUOutletControlMSPOutletName DisplayString, - sPDUOutletControlMSPOutletCommand INTEGER - } - -sPDUOutletControlMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletControlMSPEntry 1 } - -sPDUOutletControlMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletControlMSPEntry 2 } - -sPDUOutletControlMSPOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletControlMSPEntry 3 } - -sPDUOutletControlMSPOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletControlMSPEntry 4 } - -sPDUOutletControlMSPOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOnMSP (1), - delayedOnMSP (2), - immediateOffMSP (3), - gracefulRebootMSP (4), - immediateRebootMSP (5), - gracefulshutdownMSP (6), - overrideBatCapThreshMSP (7), - cancelPendingCommandMSP (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOnMSP (1) value will be returned. - If the outlet is off, the immediateOffMSP (3) value will be - returned. - - Setting this variable to immediateOnMSP (1) will immediately turn the outlet on. - - Setting this variable to delayedOnMSP (2) will turn the outlet on - after the sPDUOutletConfigMSPPowerOnDelay OID time has elapsed. - - Setting this variable to immediateOffMSP (3) will immediately turn the outlet off. - - Setting this variable to gracefulRebootMSP (4) will cause the outlet to wait for - device confirmation (if applicable) and then turn the outlet off after the - sPDUOutletConfigMSPPowerOffDelay OID time has elapsed. The outlet will then turn - on after the sPDUOutletConfigMSPRebootDuration OID time has elapsed. - - Setting this variable to immediateRebootMSP (5) will immediately reboot the outlet. - - Setting this variable to gracefulshutdownMSP (6) will cause the outlet to wait for - device confirmation (if applicable) and then turn the outlet off after the - sPDUOutletConfigMSPPowerOffDelay OID time has elapsed. The outlet will then turn - on after the sum of the sPDUOutletConfigMSPRestartTime OID time and the - sPDUOutletConfigMSPPowerOnDelay OID time has elapsed. - - Setting this variable to overrideBatCapThreshMSP (7) will cause the outlet to - ignore the Battery Capacity Threshold and proceed waiting on the - sPDUOutletConfigMSPPowerOnDelay OID time before turning the outlet on. - - Setting this variable to cancelPendingCommandMSP (8) will cause any - pending command to this outlet to be canceled." - ::= { sPDUOutletControlMSPEntry 5 } - --- the sPDUOutletConfigMSPall group - -sPDUOutletConfigMSPallTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPallEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPall 1 } - -sPDUOutletConfigMSPallEntry OBJECT-TYPE - SYNTAX OutletConfigMSPallEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPallIndex, sPDUOutletConfigMSPallOutletIndex } - ::= { sPDUOutletConfigMSPallTable 1 } - -OutletConfigMSPallEntry ::= - SEQUENCE { - sPDUOutletConfigMSPallIndex INTEGER, - sPDUOutletConfigMSPallName DisplayString, - sPDUOutletConfigMSPallOutletIndex INTEGER, - sPDUOutletConfigMSPallOutletName DisplayString, - sPDUOutletConfigMSPallOutletCtrlMode INTEGER - } - -sPDUOutletConfigMSPallIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPallEntry 1 } - -sPDUOutletConfigMSPallName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPallEntry 2 } - -sPDUOutletConfigMSPallOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPallEntry 3 } - -sPDUOutletConfigMSPallOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters." - ::= { sPDUOutletConfigMSPallEntry 4 } - -sPDUOutletConfigMSPallOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to modeGracefulShutdown (1) will put this - outlet into the Graceful Shutdown control mode. - - Setting this OID to modeAnnunciator (2) will put this outlet - into the Annunciator control mode." - ::= { sPDUOutletConfigMSPallEntry 5 } - - --- the sPDUOutConfigMSPgs group - -sPDUOutletConfigMSPgsTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPgsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPgs 1 } - -sPDUOutletConfigMSPgsEntry OBJECT-TYPE - SYNTAX OutletConfigMSPgsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPgsIndex, sPDUOutletConfigMSPgsOutletIndex } - ::= { sPDUOutletConfigMSPgsTable 1 } - -OutletConfigMSPgsEntry ::= - SEQUENCE { - sPDUOutletConfigMSPgsIndex INTEGER, - sPDUOutletConfigMSPgsName DisplayString, - sPDUOutletConfigMSPgsOutletIndex INTEGER, - sPDUOutletConfigMSPgsOutletName DisplayString, - sPDUOutletConfigMSPgsOutletCtrlMode INTEGER, - sPDUOutletConfigMSPgsDeviceConfirm INTEGER, - sPDUOutletConfigMSPgsLowBattWarning INTEGER, - sPDUOutletConfigMSPgsLowBattMult INTEGER, - sPDUOutletConfigMSPgsRestartDelay INTEGER, - sPDUOutletConfigMSPgsPowerOnDelay INTEGER, - sPDUOutletConfigMSPgsPowerOffDelay INTEGER, - sPDUOutletConfigMSPgsBattCapThresh INTEGER, - sPDUOutletConfigMSPgsRebootDuration INTEGER - } - -sPDUOutletConfigMSPgsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPgsEntry 1 } - -sPDUOutletConfigMSPgsName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPgsEntry 2 } - -sPDUOutletConfigMSPgsOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPgsEntry 3 } - -sPDUOutletConfigMSPgsOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPgsEntry 4 } - -sPDUOutletConfigMSPgsOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Control Mode of the outlet. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPgsEntry 5 } - -sPDUOutletConfigMSPgsDeviceConfirm OBJECT-TYPE - SYNTAX INTEGER { - deviceConfirmNo (1), - deviceConfirmYes (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to deviceConfirmNo (1) cause the outlet to - NOT wait for device confirmation while performing graceful - operations. - - Setting this OID to deviceConfirmYes (2) cause the outlet to - wait for device confirmation while performing graceful - operations." - ::= { sPDUOutletConfigMSPgsEntry 6 } - -sPDUOutletConfigMSPgsLowBattWarning OBJECT-TYPE - SYNTAX INTEGER (-2..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in 6 second intervals, between - when the UPS goes on battery and the power down sequence for - the outlet is initiated. - - Allowed values are: - - -2 - Never initiate the power down sequence on low battery warning. - -1 - Initiate power down sequence based on remaining runtime. - 1 - 9999 six second intervals (6 secs - 16hrs, 39 mins, 54 secs). - 0 indicates to immediately initiate power down sequence on low - battery warning." - ::= { sPDUOutletConfigMSPgsEntry 7 } - -sPDUOutletConfigMSPgsLowBattMult OBJECT-TYPE - SYNTAX INTEGER (1..7) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " Only applicable if sPDUOutletConfigMSPgsLowBattWarning OID is - set to -1 (On Runtime Remaining). - - Allows you to set the value to stagger the shutdown sequence of the outlets. - 1 provides the longest delay (the outlet to shutoff first), and 7 would - provide the shortest delay (the outlet to shut off last). - - Allowed values are: - 1 - 7." - ::= { sPDUOutletConfigMSPgsEntry 8 } - -sPDUOutletConfigMSPgsRestartDelay OBJECT-TYPE - SYNTAX INTEGER (-1..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in 6 minute intervals, between - when the outlet is turned off and the outlet is turned back on - when performing a Graceful Shutdown. - - Allowed values are: - - -1 - Never turn outlet back on after a Graceful shutdown. - 0 - 9999 six minute intervals (0 - 999hrs, 54 mins)." - ::= { sPDUOutletConfigMSPgsEntry 9 } - -sPDUOutletConfigMSPgsPowerOnDelay OBJECT-TYPE - SYNTAX INTEGER (-1..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between the UPS entering - normal (on-line) state and the outlet being powered on. - - Allowed values are: - - -1 - Remain Off when the UPS enters the on-line state. - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPgsEntry 10 } - - -sPDUOutletConfigMSPgsPowerOffDelay OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when the server - shuts down and the outlet is powered off. - - Allowed values are: - - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPgsEntry 11 } - -sPDUOutletConfigMSPgsBattCapThresh OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The minimum battery capacity, as a percent (0-100%), required - of the UPS before an outlet will be allowed to power on. - - Allowed values are: - - 0 - 100 percent." - ::= { sPDUOutletConfigMSPgsEntry 12 } - -sPDUOutletConfigMSPgsRebootDuration OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, from outlet off until - outlet on during a reboot. - - Allowed values are: - - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPgsEntry 13 } - - --- the sPDUOutConfigMSPannun group - -sPDUOutletConfigMSPannunTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPannunEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPannun 1 } - -sPDUOutletConfigMSPannunEntry OBJECT-TYPE - SYNTAX OutletConfigMSPannunEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPannunIndex, sPDUOutletConfigMSPannunOutletIndex } - ::= { sPDUOutletConfigMSPannunTable 1 } - -OutletConfigMSPannunEntry ::= - SEQUENCE { - sPDUOutletConfigMSPannunIndex INTEGER, - sPDUOutletConfigMSPannunName DisplayString, - sPDUOutletConfigMSPannunOutletIndex INTEGER, - sPDUOutletConfigMSPannunOutletName DisplayString, - sPDUOutletConfigMSPannunOutletCtrlMode INTEGER, - sPDUOutletConfigMSPannunInitialState INTEGER, - sPDUOutletConfigMSPannunAlarmActionDly INTEGER - } - -sPDUOutletConfigMSPannunIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPannunEntry 1 } - -sPDUOutletConfigMSPannunName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPannunEntry 2 } - -sPDUOutletConfigMSPannunOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPannunEntry 3 } - -sPDUOutletConfigMSPannunOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPannunEntry 4 } - -sPDUOutletConfigMSPannunOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Control Mode of the outlet. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPannunEntry 5 } - -sPDUOutletConfigMSPannunInitialState OBJECT-TYPE - SYNTAX INTEGER { - initialStateOff (1), - initialStateOn (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to initialStateOff (1) causes the outlet - to default to off when in the non-alarmed condition. - - Setting this OID to initialStateOn (2) causes the outlet - to default to on when in the non-alarmed condition." - ::= { sPDUOutletConfigMSPannunEntry 6 } - -sPDUOutletConfigMSPannunAlarmActionDly OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of time, in seconds, that an enabled Measure-UPS - alarm must be asserted before an alarm condition is recognized. - - Allowed values are: - - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPannunEntry 7 } - - --- the sPDUOutConfigMSPmups group - -sPDUOutletConfigMSPmupsTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPmupsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPmups 1 } - -sPDUOutletConfigMSPmupsEntry OBJECT-TYPE - SYNTAX OutletConfigMSPmupsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPmupsIndex, sPDUOutletConfigMSPmupsOutletIndex } - ::= { sPDUOutletConfigMSPmupsTable 1 } - -OutletConfigMSPmupsEntry ::= - SEQUENCE { - sPDUOutletConfigMSPmupsIndex INTEGER, - sPDUOutletConfigMSPmupsName DisplayString, - sPDUOutletConfigMSPmupsOutletIndex INTEGER, - sPDUOutletConfigMSPmupsOutletName DisplayString, - sPDUOutletConfigMSPmupsZone1 INTEGER, - sPDUOutletConfigMSPmupsZone2 INTEGER, - sPDUOutletConfigMSPmupsZone3 INTEGER, - sPDUOutletConfigMSPmupsZone4 INTEGER, - sPDUOutletConfigMSPmupsP1LowHum INTEGER, - sPDUOutletConfigMSPmupsP1HiHum INTEGER, - sPDUOutletConfigMSPmupsP1LowTemp INTEGER, - sPDUOutletConfigMSPmupsP1HiTemp INTEGER, - sPDUOutletConfigMSPmupsP2LowHum INTEGER, - sPDUOutletConfigMSPmupsP2HiHum INTEGER, - sPDUOutletConfigMSPmupsP2LowTemp INTEGER, - sPDUOutletConfigMSPmupsP2HiTemp INTEGER - } - -sPDUOutletConfigMSPmupsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPmupsEntry 1 } - -sPDUOutletConfigMSPmupsName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPmupsEntry 2 } - -sPDUOutletConfigMSPmupsOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPmupsEntry 3 } - -sPDUOutletConfigMSPmupsOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPmupsEntry 4 } - -sPDUOutletConfigMSPmupsZone1 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 1 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 1 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 5 } - -sPDUOutletConfigMSPmupsZone2 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 2 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 2 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 6 } - -sPDUOutletConfigMSPmupsZone3 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 3 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 3 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 7 } - -sPDUOutletConfigMSPmupsZone4 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 4 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 4 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 8 } - -sPDUOutletConfigMSPmupsP1LowHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 low humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 low humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 9 } - -sPDUOutletConfigMSPmupsP1HiHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 high humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 high humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 10 } - -sPDUOutletConfigMSPmupsP1LowTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 low temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 low temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 11 } - -sPDUOutletConfigMSPmupsP1HiTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 high temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 high temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 12 } - -sPDUOutletConfigMSPmupsP2LowHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 low humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 low humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 13 } - -sPDUOutletConfigMSPmupsP2HiHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 high humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 high humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 14 } - -sPDUOutletConfigMSPmupsP2LowTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 low temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 low temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 15 } - -sPDUOutletConfigMSPmupsP2HiTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 high temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 high temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 16 } - --- the sPDUOutletStatusMSP group - -sPDUOutletStatusMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of individual outlets. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletStatusMSP 1 } - -sPDUOutletStatusMSPEntry OBJECT-TYPE - SYNTAX OutletStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to gather status from." - INDEX { sPDUOutletStatusMSPIndex, sPDUOutletStatusMSPOutletIndex } - ::= { sPDUOutletStatusMSPTable 1 } - -OutletStatusMSPEntry ::= - SEQUENCE { - sPDUOutletStatusMSPIndex INTEGER, - sPDUOutletStatusMSPName DisplayString, - sPDUOutletStatusMSPOutletIndex INTEGER, - sPDUOutletStatusMSPOutletName DisplayString, - sPDUOutletStatusMSPOutletState INTEGER, - sPDUOutletStatusMSPCommandPending INTEGER, - sPDUOutletStatusMSPOutletCtrlMode INTEGER - } - -sPDUOutletStatusMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch MSP." - ::= { sPDUOutletStatusMSPEntry 1 } - -sPDUOutletStatusMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletStatusMSPEntry 2 } - -sPDUOutletStatusMSPOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletStatusMSPEntry 3 } - -sPDUOutletStatusMSPOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletStatusMSPEntry 4 } - -sPDUOutletStatusMSPOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletStatusMSPOn (1), - outletStatusMSPOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletStatusMSPOn (1) value will be returned. - If the outlet is off, the outletStatusMSPOff (2) value will be - returned. " - ::= { sPDUOutletStatusMSPEntry 5 } - -sPDUOutletStatusMSPCommandPending OBJECT-TYPE - SYNTAX INTEGER { - outletStatusMSPCommandPending (1), - outletStatusMSPNoCommandPending (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet. If a command is pending on the - outlet, the outletStatusMSPCommandPending (1) value - will be returned. If there is not a command pending - on the outlet, the outletStatusMSPNoCommandPending (2) - will be returned." - ::= { sPDUOutletStatusMSPEntry 6 } - -sPDUOutletStatusMSPOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Control Mode of the outlet. - This OID is provided for informational purposes only." - ::= { sPDUOutletStatusMSPEntry 7 } - - --- the rPDUIdent group - -rPDUIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the Rack PDU. - The maximum string size is device dependent." - ::= { rPDUIdent 1 } - -rPDUIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Rack PDU. - This value is set at the factory." - ::= { rPDUIdent 2 } - -rPDUIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 8-byte ID string identifying the Rack PDU firmware revision. - This value is set at the factory." - ::= { rPDUIdent 3 } - - -rPDUIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the Rack PDU was manufactured in mm/dd/yy format. - This value is set at the factory. The year 2000 will be - represented by 00." - ::= { rPDUIdent 4 } - -rPDUIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 10-character string identifying the model number of - the Rack PDU. This value is set at the factory." - ::= { rPDUIdent 5 } - -rPDUIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 12-character string identifying the serial number of - the Rack PDU. This value is set at the factory." - ::= { rPDUIdent 6 } - -rPDUIdentDeviceRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the electrical rating of the device." - - ::= { rPDUIdent 7 } - -rPDUIdentDeviceNumOutlets OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of outlets contained in the device." - - ::= { rPDUIdent 8 } - -rPDUIdentDeviceNumPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of phases supported by the device." - - ::= { rPDUIdent 9 } - -rPDUIdentDeviceNumBreakers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of circuit breakers supported by the device. - This is the same as the number of banks of outlets." - - ::= { rPDUIdent 10 } - -rPDUIdentDeviceBreakerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return rating of the circuit breakers on the device if it has any." - - ::= { rPDUIdent 11 } - -rPDUIdentDeviceOrientation OBJECT-TYPE - SYNTAX INTEGER { - orientHorizontal (1), - orientVertical (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the intended physical orientation of the device. - - OrientHorizonatal(1) indicates Horizontal. - OrientVertical(2) indicates Vertical." - - ::= { rPDUIdent 12 } - -rPDUIdentDeviceOutletLayout OBJECT-TYPE - SYNTAX INTEGER { - seqPhaseToNeutral (1), - seqPhaseToPhase (2), - seqPhToNeu21PhToPh (3), - seqPhToPhGrouped (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return outlet layout for the device. - - SeqPhaseToNeutral(1) indicates outlet layout as follows: - 1:1-N,2:2-N,3:3-N,4:1-N,5:2-N,... - - SeqPhaseToPhase(2) indicates outlet layout as follows: - 1:1-2,2:2-3,3:3-1,4:1-2,5:2-3,... - - SeqPhToNeu21PhToPh(3) indicates outlet layout as follows: - 1:1-N,2:2-N...21:3-N,22:1-2,23:2-3,24:3-1,... - - SeqPhToPhGrouped(4) indicates outlet layout as follows: - Otlts1-8::(3-1),Otlts9-16::(2-3),Otlts17-24::(1-2)." - ::= { rPDUIdent 13 } - - - --- the rPDULoadDevice group - -rPDULoadDevMaxPhaseLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the maximum rated power - that each phase of the Rack PDU can provide. It is - represented in Amps." - ::= { rPDULoadDevice 1 } - -rPDULoadDevNumPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of phases available with this Rack PDU." - ::= { rPDULoadDevice 2 } - -rPDULoadDevMaxBankLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the maximum rated power - that each bank of the Rack PDU can provide. It is - represented in Amps. - - 0 will be returned if the device does not have any banks." - - ::= { rPDULoadDevice 3 } - -rPDULoadDevNumBanks OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of banks of outlets available with this Rack PDU. - A bank of outlets has a unique circuit breaker for a subset - of the total number of outlets on the rPDU." - ::= { rPDULoadDevice 4 } - --- the rPDULoadPhaseConfig group - -rPDULoadPhaseConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF LoadPhaseConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of each Rack PDU phase. - The number of entries is contained in the - rPDULoadDevNumPhases OID." - ::= { rPDULoadPhaseConfig 1 } - -rPDULoadPhaseConfigEntry OBJECT-TYPE - SYNTAX LoadPhaseConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Rack PDU phase to configure." - INDEX { rPDULoadPhaseConfigIndex} - ::= { rPDULoadPhaseConfigTable 1 } - -LoadPhaseConfigEntry ::= - SEQUENCE { - rPDULoadPhaseConfigIndex INTEGER, - rPDULoadPhaseConfigLowLoadThreshold INTEGER, - rPDULoadPhaseConfigNearOverloadThreshold INTEGER, - rPDULoadPhaseConfigOverloadThreshold INTEGER - } - -rPDULoadPhaseConfigIndex OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Rack PDU phase entry." - ::= { rPDULoadPhaseConfigEntry 1 } - -rPDULoadPhaseConfigLowLoadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing a low consumption condition. It is - represented in amps. A warning will be issued when the - load is less than the threshold value. - - A threshold value of 0 amps effectively disables this - warning. - - Maximum value must be less than the value returned - by the rPDULoadPhaseConfigNearOverloadThreshold OID." - ::= { rPDULoadPhaseConfigEntry 2 } - -rPDULoadPhaseConfigNearOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than the value returned by - the rPDULoadPhaseConfigLowLoadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadPhaseConfigOverloadThreshold OID." - ::= { rPDULoadPhaseConfigEntry 3 } - -rPDULoadPhaseConfigOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load has entered an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than or equal to the value - returned by the rPDULoadPhaseConfigNearOverloadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadDevMaxPhaseLoad OID." - ::= { rPDULoadPhaseConfigEntry 4 } - - --- the rPDULoadStatus group - -rPDULoadStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF LoadStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of each Rack PDU phase/bank. - The number of entries is calculated by adding - the number of phases (rPDULoadDevNumPhases OID) and - the number of banks of outlets (rPDULoadDevNumBanks) - Number of entries = #phases + #banks. - NOTE: If a device has phase and bank information, all phase information - shall preceed the bank information." - ::= { rPDULoadStatus 1 } - -rPDULoadStatusEntry OBJECT-TYPE - SYNTAX LoadStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Rack PDU phase/bank to gather status from." - INDEX { rPDULoadStatusIndex} - ::= { rPDULoadStatusTable 1 } - -LoadStatusEntry ::= - SEQUENCE { - rPDULoadStatusIndex INTEGER, - rPDULoadStatusLoad Gauge, - rPDULoadStatusLoadState INTEGER, - rPDULoadStatusPhaseNumber INTEGER, - rPDULoadStatusBankNumber INTEGER - } - -rPDULoadStatusIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Rack PDU phase/bank entry. All phase information will preceed - any bank information" - ::= { rPDULoadStatusEntry 1 } - -rPDULoadStatusLoad OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the phase/bank load measured - in tenths of amps." - ::= { rPDULoadStatusEntry 2 } - -rPDULoadStatusLoadState OBJECT-TYPE - SYNTAX INTEGER { - phaseLoadNormal (1), - phaseLoadLow (2), - phaseLoadNearOverload (3), - phaseLoadOverload (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the phase/bank load state. - - phaseLoadNormal(1) indicates that the phase/bank is - operating properly within the rPDULoadConfigLowLoadThreshold - and rPDULoadConfigNearOverloadThreshold OID values. - - phaseLoadLow(2) indicates that the phase/bank load has - dropped below the rPDULoadConfigLowLoadThreshold OID value. - An SNMP trap will occur when this state is entered or cleared. - - phaseLoadNearOverload(3) indicates that the phase/bank load - is greater than or equal to the - rPDULoadConfigNearOverloadThreshold OID value. - An SNMP trap will occur when this state is entered or cleared. - - phaseLoadOverload(4) indicates that the phase/bank load is - greater than or equal to the rPDULoadConfigOverloadThreshold - OID value. - An SNMP trap will occur when this state is entered or cleared." - ::= { rPDULoadStatusEntry 3 } - -rPDULoadStatusPhaseNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase number to which this record refers. A value of 0 will be returned if - this is bank related information." - ::= { rPDULoadStatusEntry 4 } - -rPDULoadStatusBankNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank number to which this record refers. A value of 0 will be returned if - this is phase related information." - ::= { rPDULoadStatusEntry 5 } - --- the rPDULoadBankConfig group - -rPDULoadBankConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF LoadBankConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of each Rack PDU bank. - The number of entries is contained in the - rPDULoadDevNumBanks OID." - ::= { rPDULoadBankConfig 1 } - -rPDULoadBankConfigEntry OBJECT-TYPE - SYNTAX LoadBankConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Rack PDU bank to configure." - INDEX { rPDULoadBankConfigIndex} - ::= { rPDULoadBankConfigTable 1 } - -LoadBankConfigEntry ::= - SEQUENCE { - rPDULoadBankConfigIndex INTEGER, - rPDULoadBankConfigLowLoadThreshold INTEGER, - rPDULoadBankConfigNearOverloadThreshold INTEGER, - rPDULoadBankConfigOverloadThreshold INTEGER - } - -rPDULoadBankConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Rack PDU bank entry." - ::= { rPDULoadBankConfigEntry 1 } - -rPDULoadBankConfigLowLoadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing a low consumption condition. It is - represented in amps. A warning will be issued when the - load is less than the threshold value. - - A threshold value of 0 amps effectively disables this - warning. - - Maximum value must be less than the value returned - by the rPDULoadBankConfigNearOverloadThreshold OID. - - -1 will be returned if the device has no banks." - - ::= { rPDULoadBankConfigEntry 2 } - -rPDULoadBankConfigNearOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than the value returned by - the rPDULoadBankConfigLowLoadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadBankConfigOverloadThreshold OID. - - -1 will be returned if the device has no banks." - - ::= { rPDULoadBankConfigEntry 3 } - -rPDULoadBankConfigOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load has entered an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than or equal to the value - returned by the rPDULoadBankConfigNearOverloadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadDevMaxBankLoad OID. - - -1 will be returned if the device has no banks." - - ::= { rPDULoadBankConfigEntry 4 } - - --- the rPDUOutletDevice group - -rPDUOutletDevCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandAll (1), - immediateAllOn (2), - immediateAllOff (3), - immediateAllReboot (4), - delayedAllOn (5), - delayedAllOff (6), - delayedAllReboot (7), - cancelAllPendingCommands (8), - gracefulAllOff (9), - gracefulAllReboot (10) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to immediateAllOn (2) will turn all outlets - on immediately. - - Setting this OID to immediateAllOff (3) will turn all outlets - off immediately. - - Setting this OID to immediateAllReboot (4) will reboot all outlets - immediately. - - Setting this OID to delayedAllOn (5) will turn all outlets on as - defined by each outlet's rPDUOutletConfigPowerOnTime OID value. - - Setting this OID to delayedAllOff (6) will turn all outlets - off as defined by each outlet's rPDUOutletConfigPowerOffTime OID value. - - Setting this OID to delayedAllReboot (7) will cause a - delayedAllOff command to be performed. Once all outlets are off, - the Switched Rack PDU will then delay the largest - rPDUOutletConfigRebootDuration OID time, and then perform a - delayedAllOn command. - - Setting this OID to cancelAllPendingCommands (8) will cause all pending - commands on the Switched Rack PDU to be canceled. - - Setting this variable to gracefulAllOff (9) will cause the - Switched Rack PDU to shut all outlets off after it waits the - servers graceful shutdown time and each outlet's shutdown delay. - - Setting this variable to gracefulAllReboot (10) will cause the - Switched Rack PDU to shut all outlets off after it waits the - servers graceful shutdown time and each outlet's shutdown delay. - Once all outlet are off, it will wait until the UPS reaches the - configured minimum return battery capacity, then each outlet's - return delay before it turns the outlet back on. - - Getting this OID will return the noCommandAll (1) value." - ::= { rPDUOutletDevice 1 } - -rPDUOutletDevColdstartDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of delay, in seconds, between when - power is provided to the Switched Rack PDU and - when the Switched Rack PDU provides basic master - power to the outlets. - - Allowed values are: - - -1 - never apply power automatically. - 0 - apply power immediately. - 1 to 300 - delay up to 300 seconds (5 minutes)." - ::= { rPDUOutletDevice 2 } - -rPDUOutletDevNumCntrlOutlets OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of controlled outlets on this Switched Rack PDU." - ::= { rPDUOutletDevice 3 } - -rPDUOutletDevNumTotalOutlets OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of outlets on this Rack PDU." - ::= { rPDUOutletDevice 4 } - - --- the rPDUOutletPhase group - -rPDUOutletPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for management of outlets on a per phase basis." - ::= { rPDUOutletPhase 1 } - -rPDUOutletPhaseEntry OBJECT-TYPE - SYNTAX OutletPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The phase to manage." - INDEX { rPDUOutletPhaseIndex} - ::= { rPDUOutletPhaseTable 1 } - -OutletPhaseEntry ::= - SEQUENCE { - rPDUOutletPhaseIndex INTEGER, - rPDUOutletPhaseOverloadRestriction INTEGER - } - -rPDUOutletPhaseIndex OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Switched Rack PDU phase entry." - ::= { rPDUOutletPhaseEntry 1 } - -rPDUOutletPhaseOverloadRestriction OBJECT-TYPE - SYNTAX INTEGER { - alwaysAllowTurnON (1), - restrictOnNearOverload (2), - restrictOnOverload (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID controls the behavior of a Switched Rack PDU - phase when an overload condition is possible and - additional outlets are requested to be turned on. - - Setting this OID to alwaysAllowTurnON (1) will always allow - the outlets on the corresponding phase to turn on. - - Setting this OID to restrictOnNearOverload (2) will not allow - outlets on the corresponding phase to turn on if the - rPDULoadConfigNearOverloadThreshold OID is exceeded. - - Setting this OID to restrictOnOverload (3) will not allow - outlets on the corresponding phase to turn on if the - rPDULoadConfigOverloadThreshold OID is exceeded." - ::= { rPDUOutletPhaseEntry 2 } - - --- the rPDUOutletControl group - -rPDUOutletControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF RPDUOutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of the individual outlets. - The number of entries is contained in the - rPDUOutletDevNumCntrlOutlets OID." - ::= { rPDUOutletControl 1 } - -rPDUOutletControlEntry OBJECT-TYPE - SYNTAX RPDUOutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet to control." - INDEX { rPDUOutletControlIndex} - ::= { rPDUOutletControlTable 1 } - -RPDUOutletControlEntry ::= - SEQUENCE { - rPDUOutletControlIndex INTEGER, - rPDUOutletControlOutletName DisplayString, - rPDUOutletControlOutletPhase INTEGER, - rPDUOutletControlOutletCommand INTEGER, - rPDUOutletControlOutletBank INTEGER - } - -rPDUOutletControlIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { rPDUOutletControlEntry 1 } - -rPDUOutletControlOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is dependent on device. - An error will be returned if the set request exceeds the max size. - This OID is provided for informational purposes only." - ::= { rPDUOutletControlEntry 2 } - -rPDUOutletControlOutletPhase OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3), - phase1-2 (4), - phase2-3 (5), - phase3-1 (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase/s associated with this outlet. - - For single phase devices, this object will always - return phase1(1). - - For 3-phase devices, this object will return phase1 (1), - phase2 (2), or phase3 (3) for outlets tied to a single - phase. For outlets tied to two phases, this object will - return phase1-2 (4) for phases 1 and 2, phase2-3 (5) for - phases 2 and 3, and phase3-1 (6) for phases 3 and 1." - ::= { rPDUOutletControlEntry 3 } - -rPDUOutletControlOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOn (1), - immediateOff (2), - immediateReboot (3), - delayedOn (4), - delayedOff (5), - delayedReboot (6), - cancelPendingCommand (7), - gracefulOff (8), - gracefulReboot (9) - - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOn (1) value will be returned. - If the outlet is off, the immediateOff (2) value will be - returned. - - - Setting this variable to immediateOn (1) will immediately turn - the outlet on. - - Setting this variable to immediateOff (2) will immediately turn - the outlet off. - - Setting this variable to immediateReboot (3) will immediately - reboot the outlet. - - Setting this variable to delayedOn (4) will turn the outlet on - after the rPDUOutletConfigPowerOnTime OID time has elapsed. - - Setting this variable to delayedOff (5) will turn the outlet off - after the rPDUOutletConfigPowerOffTime OID time has elapsed. - - Setting this variable to delayedReboot (6) will cause the - Switched Rack PDU to perform a delayedOff command, wait the - rPDUOutletConfigRebootDuration OID time, and then perform a - delayedOn command. - - Setting this variable to cancelPendingCommand (7) will cause any - pending command to this outlet to be canceled. - - Setting this variable to gracefulOff (8) will cause the - Switched Rack PDU to shut the outlet off after it waits the - servers graceful shutdown time and the outlets shutdown delay. - - Setting this variable to gracefulReboot (9) will cause the - Switched Rack PDU to shut the outlet off after it waits the - servers graceful shutdown time and the outlets shutdown delay. - Once the outlet is off, it will wait until the UPS reaches the - configured minimum return battery capacity, then the outlets - return delay before it turns the outlet back on." - - ::= { rPDUOutletControlEntry 4 } - -rPDUOutletControlOutletBank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank associated with this outlet." - ::= { rPDUOutletControlEntry 5 } - - --- the rPDUOutletConfig group - -rPDUOutletConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF RPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the rPDUOutletDevNumCntrlOutlets OID." - ::= { rPDUOutletConfig 1 } - -rPDUOutletConfigEntry OBJECT-TYPE - SYNTAX RPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet to configure." - INDEX { rPDUOutletConfigIndex} - ::= { rPDUOutletConfigTable 1 } - -RPDUOutletConfigEntry ::= - SEQUENCE { - rPDUOutletConfigIndex INTEGER, - rPDUOutletConfigOutletName DisplayString, - rPDUOutletConfigOutletPhase INTEGER, - rPDUOutletConfigPowerOnTime INTEGER, - rPDUOutletConfigPowerOffTime INTEGER, - rPDUOutletConfigRebootDuration INTEGER, - rPDUOutletConfigOutletBank INTEGER - } - -rPDUOutletConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { rPDUOutletConfigEntry 1 } - -rPDUOutletConfigOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is dependent on device. - An error will be returned if the set request exceeds the max size." - ::= { rPDUOutletConfigEntry 2 } - -rPDUOutletConfigOutletPhase OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3), - phase1-2 (4), - phase2-3 (5), - phase3-1 (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase/s associated with this outlet. - - For single phase devices, this object will always - return phase1(1). - - For 3-phase devices, this object will return phase1 (1), - phase2 (2), or phase3 (3) for outlets tied to a single - phase. For outlets tied to two phases, this object will - return phase1-2 (4) for phases 1 and 2, phase2-3 (5) for - phases 2 and 3, and phase3-1 (6) for phases 3 and 1." - ::= { rPDUOutletConfigEntry 3 } - -rPDUOutletConfigPowerOnTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering on at coldstart or when a command that requires - a turn-on delay is issued. - - Allowed values are: - - -1 - never power on. - 0 - power on immediately. - 1 to 300 - power on up to 300 seconds (5 minutes) after being - commanded." - ::= { rPDUOutletConfigEntry 4 } - -rPDUOutletConfigPowerOffTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering off when a command that requires - a turn-off delay is issued. - - Allowed values are: - - -1 - never power off. - 0 - power off immediately. - 1 to 300 - power off up to 300 seconds (5 minutes) after being - commanded." - ::= { rPDUOutletConfigEntry 5 } - -rPDUOutletConfigRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed range is any value between 5 and 60 seconds (1 minute)." - ::= { rPDUOutletConfigEntry 6 } - -rPDUOutletConfigOutletBank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank associated with this outlet." - ::= { rPDUOutletConfigEntry 7 } - - --- the rPDUOutletStatus group - -rPDUOutletStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF RPDUOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of individual outlets. The number of - entries is contained in the rPDUOutletDevNumCntrlOutlets OID." - ::= { rPDUOutletStatus 1 } - -rPDUOutletStatusEntry OBJECT-TYPE - SYNTAX RPDUOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet to gather status from." - INDEX { rPDUOutletStatusIndex} - ::= { rPDUOutletStatusTable 1 } - -RPDUOutletStatusEntry ::= - SEQUENCE { - rPDUOutletStatusIndex INTEGER, - rPDUOutletStatusOutletName DisplayString, - rPDUOutletStatusOutletPhase INTEGER, - rPDUOutletStatusOutletState INTEGER, - rPDUOutletStatusCommandPending INTEGER, - rPDUOutletStatusOutletBank INTEGER - } - -rPDUOutletStatusIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { rPDUOutletStatusEntry 1 } - -rPDUOutletStatusOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is dependent on device. - An error will be returned if the set request exceeds the max size. - This OID is provided for informational purposes only." - ::= { rPDUOutletStatusEntry 2 } - -rPDUOutletStatusOutletPhase OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3), - phase1-2 (4), - phase2-3 (5), - phase3-1 (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase/s associated with this outlet. - - For single phase devices, this object will always - return phase1(1). - - For 3-phase devices, this object will return phase1 (1), - phase2 (2), or phase3 (3) for outlets tied to a single - phase. For outlets tied to two phases, this object will - return phase1-2 (4) for phases 1 and 2, phase2-3 (5) for - phases 2 and 3, and phase3-1 (6) for phases 3 and 1." - ::= { rPDUOutletStatusEntry 3 } - -rPDUOutletStatusOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletStatusOn (1), - outletStatusOff (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletStatusOn (1) value will be returned. - If the outlet is off, the outletStatusOff (2) value will be - returned. " - ::= { rPDUOutletStatusEntry 4 } - -rPDUOutletStatusCommandPending OBJECT-TYPE - SYNTAX INTEGER { - outletStatusCommandPending (1), - outletStatusNoCommandPending (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet. If a command is pending on the - outlet, the outletStatusCommandPending (1) value - will be returned. If there is not a command pending - on the outlet, the outletStatusNoCommandPending (2) - will be returned." - ::= { rPDUOutletStatusEntry 5 } - -rPDUOutletStatusOutletBank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank associated with this outlet." - ::= { rPDUOutletStatusEntry 6 } - - --- the rPDUOutletBank group - -rPDUOutletBankTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletBankEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for management of outlets on a per bank basis." - ::= { rPDUOutletBank 1 } - -rPDUOutletBankEntry OBJECT-TYPE - SYNTAX OutletBankEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The bank to manage." - INDEX { rPDUOutletBankIndex} - ::= { rPDUOutletBankTable 1 } - -OutletBankEntry ::= - SEQUENCE { - rPDUOutletBankIndex INTEGER, - rPDUOutletBankOverloadRestriction INTEGER - } - -rPDUOutletBankIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Switched Rack PDU bank entry." - ::= { rPDUOutletBankEntry 1 } - -rPDUOutletBankOverloadRestriction OBJECT-TYPE - SYNTAX INTEGER { - alwaysAllowTurnON (1), - restrictOnNearOverload (2), - restrictOnOverload (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID controls the behavior of a Switched Rack PDU - bank when an overload condition is possible and - additional outlets are requested to be turned on. - - Setting this OID to alwaysAllowTurnON (1) will always allow - the outlets on the corresponding bank to turn on. - - Setting this OID to restrictOnNearOverload (2) will not allow - outlets on the corresponding bank to turn on if the - rPDULoadConfigNearOverloadThreshold OID is exceeded. - - Setting this OID to restrictOnOverload (3) will not allow - outlets on the corresponding bank to turn on if the - rPDULoadConfigOverloadThreshold OID is exceeded." - ::= { rPDUOutletBankEntry 2 } - --- the rPDUPowerSupplyDevice group - -rPDUPowerSupply1Status OBJECT-TYPE - SYNTAX INTEGER { - powerSupply1Ok (1), - powerSupply1Failed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return powerSupply1Ok(1) if power - supply 1 is functioning normally. If not functioning normally, - this OID will return powerSupply1Failed(2)." - ::= { rPDUPowerSupplyDevice 1 } - -rPDUPowerSupply2Status OBJECT-TYPE - SYNTAX INTEGER { - powerSupply2Ok (1), - powerSupply2Failed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return powerSupply2Ok(1) if power - supply 2 is functioning normally. If not functioning normally, - this OID will return powerSupply2Failed(2)." - ::= { rPDUPowerSupplyDevice 2 } - - - --- the dm3IdentSystem group - -dm3IdentSysDescriptionTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC description records." - ::= { dm3IdentSystem 1 } - -dm3IdentSysDescriptionTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing description records of the powerplant. The number of - entries is contained in the dm3IdentSysDescriptionTableSize OID." - ::= { dm3IdentSystem 2 } - -dm3IdentSysDescriptionEntry OBJECT-TYPE - SYNTAX IdentSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The powerplant description record to reference." - INDEX { dm3IdentSysDescriptionIndex } - ::= { dm3IdentSysDescriptionTable 1 } - -IdentSysDescriptionEntry ::= - SEQUENCE { - dm3IdentSysDescriptionIndex INTEGER, - dm3IdentSysDescriptionText DisplayString - } - -dm3IdentSysDescriptionIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant description record." - ::= { dm3IdentSysDescriptionEntry 1 } - -dm3IdentSysDescriptionText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 16 character text field describing the DC power plant device. - This field can be configured from the dm3ConfigSysDescriptionText OID." - ::= { dm3IdentSysDescriptionEntry 2 } - -dm3IdentSysModel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Model type of the DC power plant." - ::= { dm3IdentSystem 3 } - -dm3IdentSysCntrlRev OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Integer representation of the hardware revision of the Master Controller board." - ::= { dm3IdentSystem 4 } - -dm3IdentSysFWVersion OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Integer representation of the power plant Master Controller firmware revision." - ::= { dm3IdentSystem 5 } - --- the dm3ConfigSystem group - -dm3ConfigSysDescriptionTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC description records." - ::= { dm3ConfigSystem 1 } - -dm3ConfigSysDescriptionTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing description records of the powerplant. The number of - entries is contained in the dm3ConfigSysDescriptionTableSize OID." - ::= { dm3ConfigSystem 2 } - -dm3ConfigSysDescriptionEntry OBJECT-TYPE - SYNTAX ConfigSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The powerplant description record to reference." - INDEX { dm3ConfigSysDescriptionIndex } - ::= { dm3ConfigSysDescriptionTable 1 } - -ConfigSysDescriptionEntry ::= - SEQUENCE { - dm3ConfigSysDescriptionIndex INTEGER, - dm3ConfigSysDescriptionText DisplayString - } - -dm3ConfigSysDescriptionIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant description record." - - ::= { dm3ConfigSysDescriptionEntry 1 } - -dm3ConfigSysDescriptionText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "16 character text field describing the DC power plant device." - - ::= { dm3ConfigSysDescriptionEntry 2 } - -dm3ConfigSysHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Ambient high temperature threshold. Temperature sensor located on Master - Controller board. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigSystem 3 } - -dm3ConfigSysHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the System High Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigSystem 4 } - -dm3ConfigSysLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Ambient low temperature threshold. Temperature sensor located on Master - Controller board. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigSystem 5 } - -dm3ConfigSysLowTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the System Low Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigSystem 6 } - -dm3ConfigSysHardwareTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the System Hardware Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigSystem 7 } - -dm3ConfigSysRemoteAccess OBJECT-TYPE - SYNTAX INTEGER { - accessEnabled (1), - accessDisabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - " - This OID is used to disable remote write access to the power plant. - Setting this OID to accessEnabled (1) will have no affect. - Setting this OID to accessDisabled (2) will disable the ability to - remotely configure the DC powerplant. - - Once remote access is disabled, it can only be restored from the front - panel of the DC power plant." - ::= { dm3ConfigSystem 8 } - - --- the dm3ConfigLVD group - -dm3ConfigLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs controllable - by this IP address." - ::= { dm3ConfigLVD 1 } - -dm3ConfigLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the LVDs. The number of - entries is contained in the dm3ConfigLVDTableSize OID." - ::= { dm3ConfigLVD 2 } - -dm3ConfigLVDEntry OBJECT-TYPE - SYNTAX ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to configure." - INDEX { dm3ConfigLVDIndex } - ::= { dm3ConfigLVDTable 1 } - -ConfigLVDEntry ::= - SEQUENCE { - dm3ConfigLVDIndex INTEGER, - dm3ConfigLVDName DisplayString, - dm3ConfigLVDEnable INTEGER, - dm3ConfigLVDTripThresh INTEGER, - dm3ConfigLVDResetThresh INTEGER, - dm3ConfigLVDOpenAlarm INTEGER, - dm3ConfigLVDHWAlarm INTEGER - } - -dm3ConfigLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dm3ConfigLVDEntry 1 } - -dm3ConfigLVDName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the LVD. The maximum value is 16 characters." - ::= { dm3ConfigLVDEntry 2 } - -dm3ConfigLVDEnable OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is used to control and indicate if the LVD is on or off. - Setting this OID to enabledYes (1) will enable (turn on) the LVD. - Setting this OID to enabledNo (2) will disable (turn off) the LVD." - ::= { dm3ConfigLVDEntry 3 } - -dm3ConfigLVDTripThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Trip threshold. If voltage exceeds threshold, the LVD will trip. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigLVDEntry 4 } - -dm3ConfigLVDResetThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Reset threshold. If voltage exceeds threshold, the LVD will reset. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigLVDEntry 5 } - -dm3ConfigLVDOpenAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the LVD Open Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigLVDEntry 6 } - -dm3ConfigLVDHWAlarm OBJECT-TYPE -SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the LVD Hardware Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigLVDEntry 7 } - - --- the dm3ConfigBattery group - -dm3ConfigBattFloatVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Float Voltage. This setting controls the power plant voltage. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 1 } - -dm3ConfigBattMaxRecharge OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Maximum Recharge Rate. This setting controls the battery max - recharge rate. The value is based on C/20 for 240 AHr battery string. - - Values are represented in thousandths of Amps (mA). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 2 } - -dm3ConfigBattDischargeThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery discharge threshold. If battery output current exceeds threshold - a battery discharge alarm will occur. - - Values are represented in thousandths of Amps (mA). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 3 } - -dm3ConfigBattDischargeAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Discharge Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 4 } - -dm3ConfigBattHighVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery high voltage threshold. If system battery voltage exceeds threshold - a battery high voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 5 } - -dm3ConfigBattHighVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery High Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 6 } - -dm3ConfigBattLowVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery low voltage threshold. If system battery voltage is under threshold - a battery low voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 7 } - -dm3ConfigBattLowVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Low Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 8 } - -dm3ConfigBattHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery high temperature threshold. If system battery temperature exceeds threshold - a battery high temperature alarm will occur. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - - ::= { dm3ConfigBattery 9 } - -dm3ConfigBattHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery High Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 10 } - -dm3ConfigBattLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery low temperature threshold. If system battery temperature is under threshold - a battery low temperature alarm will occur. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - - ::= { dm3ConfigBattery 11 } - -dm3ConfigBattLowTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Low Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 12 } - -dm3ConfigBattAmpHour OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Amp-Hour Size. Units are thousandths of Amp hours (mAHr). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 13 } - -dm3ConfigCompMethod OBJECT-TYPE - SYNTAX INTEGER { - tempcompOn (1), - tempcompOff (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is used to configure and get the state of the battery - temperature compensation. - - Setting this OID to tempcompOn (1) will enable/turn on the battery temperature compensation. - Setting this OID to tempcompOff (2) will disable/turn off the battery temperature compensation." - ::= { dm3ConfigBattery 14 } - -dm3ConfigCompTempCoeff OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Compensation Temperature Coefficient. (uV/degC/cell). - - Units are presented in microvolts. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 15 } - -dm3ConfigHighKneeTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "High Knee for temperature compensation: Compensation temperature coefficient - becomes 0mV/degC/cell. - - Values are represented in thousandths of degrees Celcius. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 16 } - -dm3ConfigLowKneeTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Low Knee for temperature compensation: Compensation temperature coefficient - becomes 0mV/degC/cell. - - Values are represented in thousandths of degrees Celcius. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 17 } - -dm3ConfigBattHwCurrentAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Current Hardware Alarm (indicating current is outside realistic - limits, or a possible measurement fault; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 18 } - -dm3ConfigBattHwTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Temperature Hardware Alarm (indicating temperature is outside realistic - limits, or a possible measurement fault; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 19 } - - --- the dm3ConfigRectThresh group -dm3ConfigRectHighVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier high voltage threshold. If rectifier voltage exceeds threshold - a rectifier high voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 1 } - - -dm3ConfigRectLowVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier low voltage threshold. If rectifier voltage is under threshold - a rectifier low voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 2 } - -dm3ConfigRectFailSafe OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier Fail Safe point. This OID represents the value sent to rectifier controllers - to use in the event of communications loss with the Master Controller or Master Controller - board failure. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 3 } - -dm3ConfigRectFailComm OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier Communication Fail timeout. This OID represents the time interval in which there is no - communication between the rectifier and the master controller at which the rectifier will reset - all its values to default. - - Values are represented in hundredths of Seconds. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 4 } - --- the dm3ConfigRectAlarms group - -dm3ConfigRectHighVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier High Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 1 } - -dm3ConfigRectLowVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Low Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 2 } - -dm3ConfigRectConfigAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This alarm is activated when a new rectifier is detected; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 3 } - -dm3ConfigRect1ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting indicates the action if ONE rectifier of a N+1 system has failed; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 4 } - -dm3ConfigRect2ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting indicates the action if TWO OR MORE rectifiers of a N+1 system have failed; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 5 } - -dm3ConfigRectDiagAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Controller Diagnostics Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 6 } - -dm3ConfigRectImbalanceAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Imbalance Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 7 } - -dm3ConfigRectCurrLimitAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Current Limit Alarm (indicating rectifier in the Current Limit state); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 8 } - -dm3ConfigRectStandbyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Standby Alarm (indicating output DC has been turned off); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 9 } - -dm3ConfigRectFanFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Fan Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 10 } - -dm3ConfigRectFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 11 } - -dm3ConfigRectHwVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Hardware Voltage Alarm (indicating voltage outside realistic limits, - or a possible measurement fault); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 12 } - - --- the dm3ConfigConvThresh group - -dm3ConfigConvHighVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter high voltage threshold. If converter voltage exceeds threshold - a converter high voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - - ::= { dm3ConfigConvThresh 1 } - -dm3ConfigConvLowVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter low voltage threshold. If converter voltage exceeds threshold - a converter low voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 2 } - -dm3ConfigConvFailSafe OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Fail Safe point. This OID represents the value sent to converter controllers - to use in the event of communications loss with the Master Controller or Master Controller - board failure. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 3 } - -dm3ConfigConvSetPoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Set point. This OID represents the initial set point used in the - voltage control loop. - - Units are thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 4 } - -dm3ConfigConvFailMax OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Fail Maximum limit. This OID represents the value sent to the converter - controllers to define the maximum set point allowed. - - Units are thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 5 } - -dm3ConfigConvFailMin OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Fail Minimum limit. This OID represents the value sent to the converter - controllers to define the minimum set point allowed. - - Units are thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 6 } - -dm3ConfigConvFailComm OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Communication Fail timeout. This OID represents the time interval in which there is no - communication between the converter and the master controller at which the converter will reset - all its values to default. - - Values are represented in hundredths of Seconds. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 7 } - --- the dm3ConfigConvAlarms group -dm3ConfigConvHighVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter High Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 1 } - -dm3ConfigConvLowVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Low Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 2 } - -dm3ConfigConvConfigAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Configuration Alarm (indicating a new converter has been detected); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 3 } - -dm3ConfigConv1ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter 1ofN Alarm (indicating action if ONE converter of a N+1 system has failed); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 4 } - -dm3ConfigConv2ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter 2ofN Alarm (indicating action if TWO OR MORE converters of a N+1 system has failed); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 5 } - -dm3ConfigConvDiagAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Diagnostics Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 6 } - -dm3ConfigConvImbalanceAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Imbalance Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 7 } - -dm3ConfigConvCurrLimitAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Current Limit Alarm (indicating the converter is in the Current Limit state); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 8 } - -dm3ConfigConvStandbyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Standby Alarm (indicating the converter is in the Standby state); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 9 } - -dm3ConfigConvFanFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Fan Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 10 } - -dm3ConfigConvFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 11 } - -dm3ConfigConvHwVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Voltage Alarm (indicating voltage outside realistic limits, or a - possible measurement fault); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 12 } - - --- the dm3ConfigOutputRelays group - -dm3ConfigOutRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant Output Relays controllable - by this IP address." - ::= { dm3ConfigOutputRelays 1 } - -dm3ConfigOutRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the Output Relays. The number of - entries is contained in the dm3ConfigOutRlyTableSize OID." - ::= { dm3ConfigOutputRelays 2 } - -dm3ConfigOutRlyEntry OBJECT-TYPE - SYNTAX ConfigOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relay to configure." - INDEX { dm3ConfigOutRlyIndex } - ::= { dm3ConfigOutRlyTable 1 } - -ConfigOutRlyEntry ::= - SEQUENCE { - dm3ConfigOutRlyIndex INTEGER, - dm3ConfigOutRlyName DisplayString, - dm3ConfigOutRlyDelay INTEGER, - dm3ConfigOutRlyAlarm INTEGER - } - -dm3ConfigOutRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant output relay." - ::= { dm3ConfigOutRlyEntry 1 } - -dm3ConfigOutRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the output relay. The maximum value is 16 characters." - ::= { dm3ConfigOutRlyEntry 2 } - -dm3ConfigOutRlyDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Output Relay Delay. This OID represents the time delay from the initiation of an - output relay action to when the output relay action does occur. If the alarm condition - disappears before the end of the delay, no action will occur. Delay for Major - and Minor alarms is not configurable and is always set to 0. - - Values are represented in hundredths of seconds. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigOutRlyEntry 3 } - -dm3ConfigOutRlyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Output Relay Alarm. This setting indicates what action to perform in the event of - an output relay alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - - Relay Alarm for Major and Minor alarms is not configurable and is always set to - alarmMajor and alarmMinor respectively." - - ::= { dm3ConfigOutRlyEntry 4 } - - --- the dm3ConfigInputRelays group - -dm3ConfigInRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant Input Relays controllable - by this IP address." - ::= { dm3ConfigInputRelays 1 } - -dm3ConfigInRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the Input Relays. The number of - entries is contained in the dm3ConfigInRlyTableSize OID." - ::= { dm3ConfigInputRelays 2 } - -dm3ConfigInRlyEntry OBJECT-TYPE - SYNTAX ConfigInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input relay to configure." - INDEX { dm3ConfigInRlyIndex } - ::= { dm3ConfigInRlyTable 1 } - -ConfigInRlyEntry ::= - SEQUENCE { - dm3ConfigInRlyIndex INTEGER, - dm3ConfigInRlyName DisplayString, - dm3ConfigInRlyDelay INTEGER, - dm3ConfigInRlyAlarm INTEGER - } - -dm3ConfigInRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant input relay." - ::= { dm3ConfigInRlyEntry 1 } - -dm3ConfigInRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the input relay. The maximum value is 16 characters." - - ::= { dm3ConfigInRlyEntry 2 } - -dm3ConfigInRlyDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Input Relay Delay. This OID represents the time delay from the initiation of an - input relay action to when the input relay action does occur. If the alarm condition - disappears before the end of the delay, no action will occur. - - Values are represented in hundredths of seconds. - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigInRlyEntry 3 } - -dm3ConfigInRlyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Input Relay Alarm. This setting indicates what action to perform in the event of - an input relay alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigInRlyEntry 4 } - --- the dm3ConfigBreakers group - -dm3ConfigBreakersTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant circuit breakers controllable - by this IP address." - ::= { dm3ConfigBreakers 1 } - -dm3ConfigBreakersTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the circuit breakers. The number of - entries is contained in the dm3ConfigBreakersTableSize OID." - ::= { dm3ConfigBreakers 2 } - -dm3ConfigBreakersEntry OBJECT-TYPE - SYNTAX ConfigBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The circuit breaker to configure." - INDEX { dm3ConfigBreakersIndex } - ::= { dm3ConfigBreakersTable 1 } - -ConfigBreakersEntry ::= - SEQUENCE { - dm3ConfigBreakersIndex INTEGER, - dm3ConfigBreakersName DisplayString, - dm3ConfigBreakersAlarm INTEGER - } - -dm3ConfigBreakersIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant circuit breaker." - ::= { dm3ConfigBreakersEntry 1 } - -dm3ConfigBreakersName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the circuit breaker. The maximum value is 16 characters." - ::= { dm3ConfigBreakersEntry 2 } - -dm3ConfigBreakersAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Circuit Breaker Alarm. This setting indicates what action to perform in the event of - a circuit breaker alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBreakersEntry 3 } - --- the dm3ConfigFuses group - -dm3ConfigFusesTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant Fuses controllable - by this IP address." - ::= { dm3ConfigFuses 1 } - -dm3ConfigFusesTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the Fuses. The number of - entries is contained in the dm3ConfigFusesTableSize OID." - ::= { dm3ConfigFuses 2 } - -dm3ConfigFusesEntry OBJECT-TYPE - SYNTAX ConfigFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The fuse to configure." - INDEX { dm3ConfigFusesIndex } - ::= { dm3ConfigFusesTable 1 } - -ConfigFusesEntry ::= - SEQUENCE { - dm3ConfigFusesIndex INTEGER, - dm3ConfigFusesName DisplayString, - dm3ConfigFusesAlarm INTEGER - } - -dm3ConfigFusesIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant fuse." - ::= { dm3ConfigFusesEntry 1 } - -dm3ConfigFusesName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the fuse. The maximum value is 16 characters." - ::= { dm3ConfigFusesEntry 2 } - -dm3ConfigFusesAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Fuses Alarm. This setting indicates what action to perform in the event of - a Fuse alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigFusesEntry 3 } - --- the dm3StatusSystem group - -dm3StatusSystemTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System temperature based on sensor on Master Controller PCB. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dm3StatusSystem 1 } - -dm3StatusSystemStart OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Time stamp at DC powerplant initialization. - The time is represented as MMM,DD,YYYY,HH:MM:SS." - ::= { dm3StatusSystem 2 } - -dm3StatusSysRemoteAccess OBJECT-TYPE - SYNTAX INTEGER { - accessEnabled (1), - accessDisabled (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Remote Access indicator - This setting indicates if configuration (write) access to the powerplant is enabled or - disabled at the powerplant level. - This value will be accessEnabled (1) if remote configuration is enabled, and - accessDisabled (2) if remote configuration is disabled." - ::= { dm3StatusSystem 3 } - -dm3StatusSysSecurityLevel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable shows the current active security access level of controller. This - can only be changed directly from the front panel." - ::= { dm3StatusSystem 4 } - -dm3StatusSysTempSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System temperature sanity indicator. Indicates if the system temperature is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates temperature is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusSystem 5 } - -dm3StatusSysAlarmState OBJECT-TYPE - SYNTAX INTEGER{ - alarmMinor (1), - alarmMajor (2), - alarmBoth (3), - alarmNone (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System Alarm State. Reflects the alarm status of the overall DC system. - If a minor alarm is present, the value will be alarmMinor(1). - If a major alarm is present, the value will be alarmMajor(2). - If both minor and a major alarm is present, the value will be alarmBoth(3). - If no alarm is present, the value will be alarmNone(4)." - ::= { dm3StatusSystem 6 } - -dm3StatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the DC system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { dm3StatusSystem 7 } - - --- the dm3StatusAlarms group - -dm3StatusAlarmsTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant alarms viewable - by this IP address." - ::= { dm3StatusAlarms 1 } - -dm3StatusAlarmsTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing system alarms. The number of - entries is contained in the dm3StatusAlarmsTableSize OID." - ::= { dm3StatusAlarms 2 } - -dm3StatusAlarmsEntry OBJECT-TYPE - SYNTAX StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm to display." - INDEX { dm3StatusAlarmsIndex } - ::= { dm3StatusAlarmsTable 1 } - -StatusAlarmsEntry ::= - SEQUENCE { - dm3StatusAlarmsIndex INTEGER, - dm3StatusAlarmsText DisplayString - } - -dm3StatusAlarmsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the system alarm." - ::= { dm3StatusAlarmsEntry 1 } - -dm3StatusAlarmsText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The 16 character text describing the active alarm condition." - ::= { dm3StatusAlarmsEntry 2 } - --- the dm3StatusBattery group - -dm3StatusBattCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Current: This OID shows the battery current in thousandths of Amps (mA)." - ::= { dm3StatusBattery 1 } - -dm3StatusBattTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Temperature: - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dm3StatusBattery 2 } - -dm3StatusBattCurrentSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery current sanity indicator. Indicates if the battery current is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates current is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusBattery 3 } - -dm3StatusBattTempSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery temperature sanity indicator. Indicates if the battery temperature is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates temperature is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusBattery 4 } - --- the dm3StatusOEM group - -dm3StatusOEMrectOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier offset value in thousandths of Volts (mV)." - ::= { dm3StatusOEM 1 } - -dm3StatusOEMrectGain OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier gain value in thousandths of Volts (mV/V)." - ::= { dm3StatusOEM 2 } - -dm3StatusOEMconvOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter offset value in thousandths of Volts (mV)." - ::= { dm3StatusOEM 3 } - -dm3StatusOEMconvGain OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter gain value in thousandths of Volts (mV/V)." - ::= { dm3StatusOEM 4 } - -dm3StatusOEMshuntOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the shunt offset value in thousandths of Amps (mA)." - ::= { dm3StatusOEM 5 } - -dm3StatusOEMshuntGain OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the shunt gain value in thousandths of Amps (mA/A)." - ::= { dm3StatusOEM 6 } - --- the dm3StatusLVD group - -dm3StatusLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs viewable - by this IP address." - ::= { dm3StatusLVD 1 } - -dm3StatusLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the LVDs. The number of - entries is contained in the dm3StatusLVDTableSize OID." - ::= { dm3StatusLVD 2 } - -dm3StatusLVDEntry OBJECT-TYPE - SYNTAX StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to gather status from." - INDEX { dm3StatusLVDIndex } - ::= { dm3StatusLVDTable 1 } - -StatusLVDEntry ::= - SEQUENCE { - dm3StatusLVDIndex INTEGER, - dm3StatusLVDName DisplayString, - dm3StatusLVDState INTEGER, - dm3StatusLVDHwFault INTEGER - } - -dm3StatusLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dm3StatusLVDEntry 1 } - -dm3StatusLVDName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the LVD. The maximum size is - 16 characters. The name is set by using the - dm3ConfigLVDName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusLVDEntry 2 } - -dm3StatusLVDState OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpened (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the LVD is closed. - statusOpened (2) will be returned if the LVD is opened." - ::= { dm3StatusLVDEntry 3 } - -dm3StatusLVDHwFault OBJECT-TYPE - SYNTAX INTEGER { - statusFault (1), - statusNofault (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusFault (1) if the LVD is faulted. - statusNofault (2) will be returned if the LVD is not faulted." - ::= { dm3StatusLVDEntry 4 } - --- the dm3StatusRectifier group - -dm3StatusRectTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant rectifiers viewable - by this IP address." - ::= { dm3StatusRectifier 1 } - -dm3StatusRectTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the rectifiers. The number of - entries is contained in the dm3StatusRectTableSize OID." - ::= { dm3StatusRectifier 2 } - -dm3StatusRectEntry OBJECT-TYPE - SYNTAX StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The rectifier to gather status from." - INDEX { dm3StatusRectIndex } - ::= { dm3StatusRectTable 1 } - -StatusRectEntry ::= - SEQUENCE { - dm3StatusRectIndex INTEGER, - dm3StatusRectID INTEGER, - dm3StatusRectDesc DisplayString, - dm3StatusRectCurrent INTEGER, - dm3StatusRectCurrentLimit INTEGER, - dm3StatusRectStandby INTEGER, - dm3StatusRectFanFail INTEGER, - dm3StatusRectFail INTEGER, - dm3StatusRectDevType INTEGER, - dm3StatusRectPhyAddr INTEGER, - dm3StatusRectCfg INTEGER, - dm3StatusRectPcbRev INTEGER, - dm3StatusRectFwVer INTEGER, - dm3StatusRectPresent INTEGER, - dm3StatusRectDiagPass INTEGER, - dm3StatusRectState INTEGER - } - -dm3StatusRectIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant rectifier." - ::= { dm3StatusRectEntry 1 } - -dm3StatusRectID OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier ID. This enumerates the number of the rectifier within - a group of rectifiers." - ::= { dm3StatusRectEntry 2 } - -dm3StatusRectDesc OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the 16-character rectifier description." - ::= { dm3StatusRectEntry 3 } - -dm3StatusRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier current in thousandths of Amps (mA)." - ::= { dm3StatusRectEntry 4 } - -dm3StatusRectCurrentLimit OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is in the Current Limit state. - statusFalse (2) will be returned if the rectifier is not in the Current Limit state." - ::= { dm3StatusRectEntry 5 } - -dm3StatusRectStandby OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is in the Standby state. - statusFalse (2) will be returned if the rectifier is not in the Standby state." - ::= { dm3StatusRectEntry 6 } - -dm3StatusRectFanFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier Fan has failed. - statusFalse (2) will be returned if the rectifier Fan has not failed." - ::= { dm3StatusRectEntry 7 } - -dm3StatusRectFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier has failed. - statusFalse (2) will be returned if the rectifier has not failed." - ::= { dm3StatusRectEntry 8 } - -dm3StatusRectDevType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device type." - ::= { dm3StatusRectEntry 9 } - -dm3StatusRectPhyAddr OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier physical address (the address on the bus)." - ::= { dm3StatusRectEntry 10 } - -dm3StatusRectCfg OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is present after - power-up or set-configuration. - statusFalse (2) will be returned if the rectifier is not configured." - ::= { dm3StatusRectEntry 11 } - -dm3StatusRectPcbRev OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device PCB serial number." - ::= { dm3StatusRectEntry 12 } - -dm3StatusRectFwVer OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device firmware revision." - ::= { dm3StatusRectEntry 13 } - -dm3StatusRectPresent OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is present. - statusFalse (2) will be returned if the rectifier is not present." - ::= { dm3StatusRectEntry 14 } - -dm3StatusRectDiagPass OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier diagnostics have passed. - statusFalse (2) will be returned if the rectifier diagnostics have not passed." - ::= { dm3StatusRectEntry 15 } - -dm3StatusRectState OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device state as defined by the device status register." - ::= { dm3StatusRectEntry 16 } - -dm3StatusSysRectVoltSanity OBJECT-TYPE - SYNTAX INTEGER { - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Rectifier voltage sanity indicator. Indicates if the rectifier voltage is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates voltage is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusRectifier 3 } - -dm3StatusSysRectAvailable OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is available. - statusFalse (2) will be returned if the rectifier is not available." - ::= { dm3StatusRectifier 4 } - -dm3StatusSysRectType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the type of rectifier the system has. There can only be a single type of - rectifier in the power plant" - ::= { dm3StatusRectifier 5 } - -dm3StatusSysRectVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level rectifier voltage in thousandths of Volts (mV)." - ::= { dm3StatusRectifier 6 } - -dm3StatusSysRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level rectifier current in thousandths of Amps (mA)." - ::= { dm3StatusRectifier 7 } - - --- the dm3StatusConverter group - -dm3StatusConvTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant converters viewable - by this IP address." - ::= { dm3StatusConverter 1 } - -dm3StatusConvTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusConvEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the converters. The number of - entries is contained in the dm3StatusConvTableSize OID." - ::= { dm3StatusConverter 2 } - -dm3StatusConvEntry OBJECT-TYPE - SYNTAX StatusConvEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The converter to gather status from." - INDEX { dm3StatusConvIndex } - ::= { dm3StatusConvTable 1 } - -StatusConvEntry ::= - SEQUENCE { - dm3StatusConvIndex INTEGER, - dm3StatusConvID INTEGER, - dm3StatusConvDesc DisplayString, - dm3StatusConvCurrent INTEGER, - dm3StatusConvCurrentLimit INTEGER, - dm3StatusConvStandby INTEGER, - dm3StatusConvFanFail INTEGER, - dm3StatusConvFail INTEGER, - dm3StatusConvDevType INTEGER, - dm3StatusConvPhyAddr INTEGER, - dm3StatusConvCfg INTEGER, - dm3StatusConvPcbRev INTEGER, - dm3StatusConvFwVer INTEGER, - dm3StatusConvPresent INTEGER, - dm3StatusConvDiagPass INTEGER, - dm3StatusConvState INTEGER - } - -dm3StatusConvIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant converter." - ::= { dm3StatusConvEntry 1 } - -dm3StatusConvID OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter ID. This enumerates the number of the converter within - a group of converters." - ::= { dm3StatusConvEntry 2 } - -dm3StatusConvDesc OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the 16 character converter description." - ::= { dm3StatusConvEntry 3 } - -dm3StatusConvCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter current in thousandths of Amps (mA)." - ::= { dm3StatusConvEntry 4 } - -dm3StatusConvCurrentLimit OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is in the Current Limit state. - statusFalse (2) will be returned if the converter is not in the Current Limit state." - ::= { dm3StatusConvEntry 5 } - -dm3StatusConvStandby OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is in the Standby state. - statusFalse (2) will be returned if the converter is not in the Standby state." - ::= { dm3StatusConvEntry 6 } - -dm3StatusConvFanFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter Fan has failed. - statusFalse (2) will be returned if the converter Fan has not failed." - ::= { dm3StatusConvEntry 7 } - -dm3StatusConvFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter has failed. - statusFalse (2) will be returned if the converter has not failed." - ::= { dm3StatusConvEntry 8 } - -dm3StatusConvDevType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter device type." - ::= { dm3StatusConvEntry 9 } - -dm3StatusConvPhyAddr OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter physical address (the address on the bus)." - ::= { dm3StatusConvEntry 10 } - -dm3StatusConvCfg OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is present after - power-up or set-configuration. - statusFalse (2) will be returned if the converter is not configured." - ::= { dm3StatusConvEntry 11 } - -dm3StatusConvPcbRev OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter device PCB serial number." - ::= { dm3StatusConvEntry 12 } - -dm3StatusConvFwVer OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter device firmware version." - ::= { dm3StatusConvEntry 13 } - -dm3StatusConvPresent OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is present. - statusFalse (2) will be returned if the converter is not present." - ::= { dm3StatusConvEntry 14 } - -dm3StatusConvDiagPass OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter diagnostics have passed. - statusFalse (2) will be returned if the converter diagnostics have not passed." - ::= { dm3StatusConvEntry 15 } - -dm3StatusConvState OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter state as defined by the device status register." - ::= { dm3StatusConvEntry 16 } - -dm3StatusSysConvVoltSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Converter voltage sanity indicator. Indicates if the converter voltage is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates voltage is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusConverter 3 } - -dm3StatusSysConvAvailable OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is available. - statusFalse (2) will be returned if the converter is not available." - ::= { dm3StatusConverter 4 } - -dm3StatusSysConvType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter type." - ::= { dm3StatusConverter 5 } - -dm3StatusSysConvVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level converter voltage in thousandths of volts (mV)." - ::= { dm3StatusConverter 6 } - -dm3StatusSysConvCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level converter current in thousandths of Amps (mA)." - ::= { dm3StatusConverter 7 } - --- the dm3StatusOutputRelays group - -dm3StatusOutRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant output relays viewable - by this IP address." - ::= { dm3StatusOutputRelays 1 } - -dm3StatusOutRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the output relays. The number of - entries is contained in the dm3StatusOutRlyTableSize OID." - ::= { dm3StatusOutputRelays 2 } - -dm3StatusOutRlyEntry OBJECT-TYPE - SYNTAX StatusOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relay to gather status from." - INDEX { dm3StatusOutRlyIndex } - ::= { dm3StatusOutRlyTable 1 } - -StatusOutRlyEntry ::= - SEQUENCE { - dm3StatusOutRlyIndex INTEGER, - dm3StatusOutRlyName DisplayString, - dm3StatusOutRlyStatus INTEGER - } - -dm3StatusOutRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant output relay." - ::= { dm3StatusOutRlyEntry 1 } - -dm3StatusOutRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the output relay. The maximum size is - 16 characters. The name is set by using the - dm3ConfigOutRlyName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusOutRlyEntry 2 } - -dm3StatusOutRlyStatus OBJECT-TYPE - SYNTAX INTEGER { - statusOn (1), - statusOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusOn (1) if the output relay is enabled/on. - statusOff (2) will be returned if the output relay is disabled/off." - ::= { dm3StatusOutRlyEntry 3 } - - --- the dm3StatusInputRelays group - -dm3StatusInRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant input relays viewable - by this IP address." - ::= { dm3StatusInputRelays 1 } - -dm3StatusInRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the input relays. The number of - entries is contained in the dm3StatusInRlyTableSize OID." - ::= { dm3StatusInputRelays 2 } - - -dm3StatusInRlyEntry OBJECT-TYPE - SYNTAX StatusInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input relays to gather status from." - INDEX { dm3StatusInRlyIndex } - ::= { dm3StatusInRlyTable 1 } - -StatusInRlyEntry ::= - SEQUENCE { - dm3StatusInRlyIndex INTEGER, - dm3StatusInRlyName DisplayString, - dm3StatusInRlyStatus INTEGER - } - -dm3StatusInRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant input relay." - ::= { dm3StatusInRlyEntry 1 } - -dm3StatusInRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the input relay. The maximum size is - 16 characters. The name is set by using the - dm3ConfigInRlyName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusInRlyEntry 2 } - -dm3StatusInRlyStatus OBJECT-TYPE - SYNTAX INTEGER { - statusOn (1), - statusOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusOn (1) if the input relay is enabled/on. - statusOff (2) will be returned if the input relay is disabled/off." - ::= { dm3StatusInRlyEntry 3 } - --- the dm3StatusBreakers group - -dm3StatusBreakersTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant circuit breakers viewable - by this IP address." - ::= { dm3StatusBreakers 1 } - -dm3StatusBreakersTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the circuit breakers. The number of - entries is contained in the dm3StatusBreakersTableSize OID." - ::= { dm3StatusBreakers 2 } - -dm3StatusBreakersEntry OBJECT-TYPE - SYNTAX StatusBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The circuit breaker to gather status from." - INDEX { dm3StatusBreakersIndex } - ::= { dm3StatusBreakersTable 1 } - -StatusBreakersEntry ::= - SEQUENCE { - dm3StatusBreakersIndex INTEGER, - dm3StatusBreakersName DisplayString, - dm3StatusBreakersStatus INTEGER - } - -dm3StatusBreakersIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant circuit breaker." - ::= { dm3StatusBreakersEntry 1 } - -dm3StatusBreakersName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the circuit breaker. The maximum size is - 16 characters. The name is set by using the - dm3ConfigBreakersName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusBreakersEntry 2 } - -dm3StatusBreakersStatus OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpen (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the circuit breaker is closed. - statusOpen (2) will be returned if the circuit breaker is open." - ::= { dm3StatusBreakersEntry 3 } - --- the dm3StatusFuses group - -dm3StatusFusesTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant fuses controllable - by this IP address." - ::= { dm3StatusFuses 1 } - -dm3StatusFusesTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the fuses. The number of - entries is contained in the dm3StatusFusesTableSize OID." - ::= { dm3StatusFuses 2 } - -dm3StatusFusesEntry OBJECT-TYPE - SYNTAX StatusFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The fuse to gather status from." - INDEX { dm3StatusFusesIndex } - ::= { dm3StatusFusesTable 1 } - -StatusFusesEntry ::= - SEQUENCE { - dm3StatusFusesIndex INTEGER, - dm3StatusFusesName DisplayString, - dm3StatusFusesStatus INTEGER - } - -dm3StatusFusesIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant fuse." - ::= { dm3StatusFusesEntry 1 } - -dm3StatusFusesName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the fuse. The maximum size is - 16 characters. The name is set by using the - dm3ConfigFuseName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusFusesEntry 2 } - -dm3StatusFusesStatus OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpen (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the fuse is closed. - statusOpen (2) will be returned if the fuse is open." - ::= { dm3StatusFusesEntry 3 } - --- the atsIdent group - -atsIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware version of the Automatic Transfer Switch. - This value is set at the factory." - ::= { atsIdent 1 } - -atsIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string identifying the Automatic Transfer Switch - firmware version." - ::= { atsIdent 2 } - -atsIdentFirmwareDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of release for this Automatic Transfer Switch - firmware version. " - ::= { atsIdent 3 } - -atsIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the Automatic Transfer Switch was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { atsIdent 4 } - -atsIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string identifying the model number of the Automatic Transfer Switch. - This value is set at the factory." - ::= { atsIdent 5 } - -atsIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string identifying the serial number of - the Automatic Transfer Switch. This value is set at the factory." - ::= { atsIdent 6 } - -atsIdentNominalLineVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "RMS Utility Voltage measured in V." - ::= { atsIdent 7 } - -atsIdentNominalLineFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Utility Power Frequency measured in Hz." - ::= { atsIdent 8 } - --- the atsCalibration group - --- Input Voltage Calibration Factor table - - atsCalibrationNumInputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of inputs to this device." - ::= { atsCalibrationInput 1 } - - atsCalibrationNumInputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of phases per input for this device." - ::= { atsCalibrationInput 2 } - - atsCalibrationInputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSCalibrationInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The number of phases per input line to this device." - ::= { atsCalibrationInput 3 } - - atsCalibrationInputPhaseEntry OBJECT-TYPE - SYNTAX ATSCalibrationInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing calibration information applicable to a - particular input phase." - INDEX { atsCalibrationInputTableIndex, atsCalibrationInputPhaseTableIndex } - ::= { atsCalibrationInputTable 1 } - - ATSCalibrationInputPhaseEntry ::= SEQUENCE { - atsCalibrationInputTableIndex INTEGER, - atsCalibrationInputPhaseTableIndex INTEGER, - atsLineVoltageCalibrationFactor INTEGER - } - - atsCalibrationInputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { atsCalibrationInputPhaseEntry 1 } - - atsCalibrationInputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input phase identifier." - ::= { atsCalibrationInputPhaseEntry 2 } - - atsLineVoltageCalibrationFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Line Voltage Calibration factor. - This value is set at the factory." - ::= { atsCalibrationInputPhaseEntry 3 } - --- Power Supply Voltage Calibration table - - atsCalibrationPowerSupplyVoltages OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of power supply voltages supported by this device. - This variable indicates the number of rows in the - atsCalibrationPowerSupplyTable. There is one entry per - supported voltage: 24V, 12V and 5V" - ::= { atsCalibrationPowerSupply 1 } - - atsCalibrationPowerSupplyVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSCalibrationPowerSupplyVoltageEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of Power Supply table entries." - ::= { atsCalibrationPowerSupply 2 } - - atsCalibrationPowerSupplyVoltageEntry OBJECT-TYPE - SYNTAX ATSCalibrationPowerSupplyVoltageEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular Power Supply Voltage." - INDEX { atsCalibrationPowerSupplyVoltageTableIndex } - ::= { atsCalibrationPowerSupplyVoltageTable 1 } - - ATSCalibrationPowerSupplyVoltageEntry ::= SEQUENCE { - atsCalibrationPowerSupplyVoltageTableIndex INTEGER, - atsCalibrationPowerSupplyVoltage INTEGER, - atsPowerSupplyVoltageCalibrationFactor INTEGER - } - - atsCalibrationPowerSupplyVoltageTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The power supply voltage identifier. - Three power supply voltages are supported by the ATS: - 24V , 12V and 5V . - The value of this index indicates the power supply voltage: - 1 = 24V - 2 = 12V - 3 = 5V" - ::= { atsCalibrationPowerSupplyVoltageEntry 1 } - - atsCalibrationPowerSupplyVoltage OBJECT-TYPE - SYNTAX INTEGER { - powerSupply24V(1), - powerSupply12V(2), - powerSupply(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value describes the power supply voltage." - ::= { atsCalibrationPowerSupplyVoltageEntry 2 } - - atsPowerSupplyVoltageCalibrationFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Line Voltage Calibration factor. - This value is set at the factory." - ::= { atsCalibrationPowerSupplyVoltageEntry 3 } - --- Output Current Calibration table - - atsCalibrationNumOutputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output lines from this device. - This variable indicates the number of rows in the - atsCalibrationOutputTable." - ::= { atsCalibrationOutput 1 } - - atsCalibrationNumOutputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output phases utilized in this - device." - ::= { atsCalibrationOutput 2 } - - atsCalibrationOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSCalibrationOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries." - ::= { atsCalibrationOutput 3 } - - atsCalibrationOutputEntry OBJECT-TYPE - SYNTAX ATSCalibrationOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output." - INDEX { atsCalibrationOutputTableIndex, atsCalibrationOutputPhasesTableIndex } - ::= { atsCalibrationOutputTable 1 } - - ATSCalibrationOutputEntry ::= SEQUENCE { - atsCalibrationOutputTableIndex INTEGER, - atsCalibrationOutputPhasesTableIndex INTEGER, - atsOutputCurrentCalibrationFactor INTEGER - } - - atsCalibrationOutputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { atsCalibrationOutputEntry 1 } - - atsCalibrationOutputPhasesTableIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3), - neutral(4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each calibration factor for each - output phase utilized in this device and one for neutral. " - ::= { atsCalibrationOutputEntry 2 } - - atsOutputCurrentCalibrationFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output current calibration factor measured in Amps." - ::= { atsCalibrationOutputEntry 3 } - - --- the atsControl group - -atsControlResetATS OBJECT-TYPE - SYNTAX INTEGER { - none(1), - reset(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable will cause the Automatic Transfer Switch to - perform a power-on reset." - ::= { atsControl 1 } - -atsControlClearAllAlarms OBJECT-TYPE - SYNTAX INTEGER { - none(1), - clear(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable will clear all alarms in the Automatic Transfer Switch." - ::= { atsControl 2 } - --- the atsConfig group - -atsConfigProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A configurable character string." - ::= { atsConfig 1 } - -atsConfigPreferredSource OBJECT-TYPE - SYNTAX INTEGER { - sourceA(1), - sourceB(2), - none(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This variable returns the preferred source of power when both sources are OK." - ::= { atsConfig 2 } - -atsConfigFrontPanelLockout OBJECT-TYPE - SYNTAX INTEGER { - disableFrontPanel(1), - enableFrontPanel(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to disableFrontPanel(1) will disallow source - preference configuration of the Automatic Transfer Switch via the - Front Panel. Once this value is set, it can only be re-enabled through - the serial interface of the ATS. - When this variable is set to enableFrontPanel(2), source preference - configuration of the Automatic Transfer Switch via the Front Panel - is allowed." - ::= { atsConfig 3 } - -atsConfigVoltageSensitivity OBJECT-TYPE - SYNTAX INTEGER { - high(1), - low(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This variable defines the sensitivity to changes in voltage: - high(1) for best protection, low(2) for frequent small line - voltage changes." - ::= { atsConfig 4 } - -atsConfigTransferVoltageRange OBJECT-TYPE - SYNTAX INTEGER { - wide(1), - medium(2), - narrow(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This variable defines the range of acceptable voltage from a power source. - If the voltage measured from the selected input source is not within this - range, the Automatic Transfer Switch will switch over (transfer) to the - alternate power source." - - ::= { atsConfig 5 } - -atsConfigCurrentLimit OBJECT-TYPE - SYNTAX INTEGER (0..20) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The threshold (in Amps) at which an Over Current Alarm will be generated." - - ::= { atsConfig 6 } - - -atsConfigResetValues OBJECT-TYPE - SYNTAX INTEGER { - none(1), - reset(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Resets the ATS configuration to its default values." - - ::= { atsConfig 7 } - --- the atsStatus group - - atsStatusCommStatus OBJECT-TYPE - SYNTAX INTEGER { - atsNeverDiscovered(1), - atsCommEstablished(2), - atsCommLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current communication status - of the Automatic Transfer Switch. " - ::= { atsStatusDeviceStatus 1 } - - atsStatusSelectedSource OBJECT-TYPE - SYNTAX INTEGER { - sourceA(1), - sourceB(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current source of power. " - ::= { atsStatusDeviceStatus 2 } - - atsStatusRedundancyState OBJECT-TYPE - SYNTAX INTEGER { - atsRedundancyLost(1), - atsFullyRedundant(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current redundancy state of the ATS. - atsRedundancyLost(1) indicates that the ATS is unable to - switch over to the alternate power source if the current source fails. - atsFullyRedundant(2) indicates that the ATS will switch over to - the alternate power source if the current source fails." - ::= { atsStatusDeviceStatus 3 } - - atsStatusOverCurrentState OBJECT-TYPE - SYNTAX INTEGER { - atsOverCurrent(1), - atsCurrentOK(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the output current state of the ATS. - atsOverCurrent(1) indicates that the ATS has exceeded the output - current threshold and will not allow a switch over to the alternate power - source if the current source fails. - atsCurrentOK(2) indicates that the output current is below the - output current threshold." - ::= { atsStatusDeviceStatus 4 } - - atsStatus5VPowerSupply OBJECT-TYPE - SYNTAX INTEGER { - atsPowerSupplyFailure(1), - atsPowerSupplyOK(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current state of the ATS 5-volt power supply. - atsPowerSupplyFailure(1) indicates the 5-volt power supply has failed - and that the ATS serial port Configuration Menu is not accessible . - atsPowerSupplyOK(2) indicates that the ATS 5-volt power supply - is operating within tolerance." - ::= { atsStatusDeviceStatus 5 } - - atsStatus24VPowerSupply OBJECT-TYPE - SYNTAX INTEGER { - atsPowerSupplyFailure(1), - atsPowerSupplyOK(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current state of the ATS 24-volt power supply. - atsPowerSupplyFailure(1) indicates the 24-volt power supply has failed - and the ATS is unable to switch over to the alternate power source if - the current source fails. - atsPowerSupplyOK(2) indicates that the ATS 24-volt power supply - is operating within tolerance." - ::= { atsStatusDeviceStatus 6 } - - atsStatusResetMaxMinValues OBJECT-TYPE - SYNTAX INTEGER { - none(1), - reset(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Resets the maximum and minimum ATS values: - atsInputMaxVoltage, atsInputMinVoltage, - atsInputMaxCurrent, atsInputMinCurrent, - atsInputMaxPower, atsInputMinPower, - atsOutputMaxCurrent, atsOutputMinCurrent, - atsOutputMaxLoad, atsOutputMinLoad, - atsOutputMaxPercentLoad, atsOutputMinPercentLoad, - atsOutputMaxPower, atsOutputMinPower, - atsOutputMaxPercentPower, atsOutputMinPercentPower. - These variables represent the maximum and minimum ATS values - since the last time they were read or reset by this OID. - Values unsupported by this ATS will return (-1)." - ::= { atsStatusResetValues 1 } - --- --- Input Group --- - --- Number of Inputs - - atsNumInputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input feeds to this device. - This variable indicates the number of rows in the - input table." - ::= { atsStatusInput 1 } - --- Input Table - - atsInputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the value of atsNumInputs." - ::= { atsStatusInput 2 } - - atsInputEntry OBJECT-TYPE - SYNTAX ATSPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input." - INDEX { atsInputTableIndex } - ::= { atsInputTable 1 } - - ATSPhaseInputEntry ::= SEQUENCE { - atsInputTableIndex INTEGER, - atsNumInputPhases INTEGER, - atsInputVoltageOrientation INTEGER, - atsInputFrequency INTEGER, - atsInputType INTEGER, - atsInputName DisplayString - } - - atsInputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { atsInputEntry 1 } - - atsNumInputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input phases utilized in this - device. The sum of all the atsNumInputPhases - variable indicates the number of rows in the - input phase table." - ::= { atsInputEntry 2 } - - atsInputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage orientation: - 1: unknown for this Source - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { atsInputEntry 3 } - - atsInputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input frequency in Hertz, or -1 if it's unsupported - by this Source." - ::= { atsInputEntry 4 } - - atsInputType OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - main(2), - bypass(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input type." - ::= { atsInputEntry 5 } - - atsInputName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A name given to a particular input." - ::= { atsInputEntry 6 } - --- Input Phase Table - - atsInputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the sum of the atsNumInputPhases." - ::= { atsStatusInput 3 } - - atsInputPhaseEntry OBJECT-TYPE - SYNTAX ATSPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input phase." - INDEX { atsInputPhaseTableIndex, atsInputPhaseIndex } - ::= { atsInputPhaseTable 1 } - - ATSPhaseInputPhaseEntry ::= SEQUENCE { - atsInputPhaseTableIndex INTEGER, - atsInputPhaseIndex INTEGER, - atsInputVoltage INTEGER, - atsInputMaxVoltage INTEGER, - atsInputMinVoltage INTEGER, - atsInputCurrent INTEGER, - atsInputMaxCurrent INTEGER, - atsInputMinCurrent INTEGER, - atsInputPower INTEGER, - atsInputMaxPower INTEGER, - atsInputMinPower INTEGER - } - - atsInputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { atsInputPhaseEntry 1 } - - atsInputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input phase identifier." - ::= { atsInputPhaseEntry 2 } - - atsInputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage in VAC, or -1 if it's unsupported - by this Source." - ::= { atsInputPhaseEntry 3 } - - atsInputMaxVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input voltage in VAC measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 4 } - - atsInputMinVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input voltage in VAC measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 5 } - - atsInputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input current in amperes, or -1 if it's - unsupported by this Source." - ::= { atsInputPhaseEntry 6 } - - atsInputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input current in amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 7 } - - atsInputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input current in amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 8 } - - atsInputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input power in Watts, or -1 if it's unsupported - by this Source." - ::= { atsInputPhaseEntry 9 } - - atsInputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 10 } - - atsInputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 11 } - - -- - -- The Output group. - -- - - -- Number of Outputs - - atsNumOutputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output feeds to this device. - This variable indicates the number of rows in the - output table." - ::= { atsStatusOutput 1 } - - -- Output Table - - atsOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of entries - is given by the value of atsOutputNumPhases." - ::= { atsStatusOutput 2 } - - atsOutputEntry OBJECT-TYPE - SYNTAX ATSPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output." - INDEX { atsOutputTableIndex } - ::= { atsOutputTable 1 } - - ATSPhaseOutputEntry ::= SEQUENCE { - atsOutputTableIndex INTEGER, - atsNumOutputPhases INTEGER, - atsOutputVoltageOrientation INTEGER, - atsOutputFrequency INTEGER - } - - atsOutputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { atsOutputEntry 1 } - - atsNumOutputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output phases utilized in this - device. The sum of all the atsNumOutputPhases - variable indicates the number of rows in the - output phase table." - ::= { atsOutputEntry 2 } - - atsOutputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage orientation: - 1: unknown for this ATS - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { atsOutputEntry 3 } - - atsOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output frequency in Hertz, or -1 if it's - unsupported by this ATS." - ::= { atsOutputEntry 4 } - - -- Output Phase Table - - atsOutputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of - entries is given by the sum of the atsNumOutputPhases." - ::= { atsStatusOutput 3 } - - atsOutputPhaseEntry OBJECT-TYPE - SYNTAX ATSPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output phase." - INDEX { atsOutputPhaseTableIndex, atsOutputPhaseIndex } - ::= { atsOutputPhaseTable 1 } - - ATSPhaseOutputPhaseEntry ::= SEQUENCE { - atsOutputPhaseTableIndex INTEGER, - atsOutputPhaseIndex INTEGER, - atsOutputVoltage INTEGER, - atsOutputCurrent INTEGER, - atsOutputMaxCurrent INTEGER, - atsOutputMinCurrent INTEGER, - atsOutputLoad INTEGER, - atsOutputMaxLoad INTEGER, - atsOutputMinLoad INTEGER, - atsOutputPercentLoad INTEGER, - atsOutputMaxPercentLoad INTEGER, - atsOutputMinPercentLoad INTEGER, - atsOutputPower INTEGER, - atsOutputMaxPower INTEGER, - atsOutputMinPower INTEGER, - atsOutputPercentPower INTEGER, - atsOutputMaxPercentPower INTEGER, - atsOutputMinPercentPower INTEGER - } - - atsOutputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { atsOutputPhaseEntry 1 } - - atsOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3), - neutral(4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each output phase utilized in - this device and one for neutral. " - ::= { atsOutputPhaseEntry 2 } - - atsOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage in VAC, or -1 if it's unsupported - by this ATS." - ::= { atsOutputPhaseEntry 3 } - - atsOutputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output current in 0.1 amperes drawn - by the load on the ATS, or -1 if it's unsupported - by this ATS." - ::= { atsOutputPhaseEntry 4 } - - atsOutputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output current in 0.1 amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 5 } - - atsOutputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output current in 0.1 amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 6 } - - atsOutputLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output load in VA, or -1 if it's unsupported - by this ATS." - ::= { atsOutputPhaseEntry 7 } - - atsOutputMaxLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output load in VA measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 8 } - - atsOutputMinLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output load in VA measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 9 } - - atsOutputPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the ATS load capacity in VA at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this ATS." - ::= { atsOutputPhaseEntry 10 } - - atsOutputMaxPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the ATS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 11 } - - atsOutputMinPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum percentage of the ATS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 12 } - - atsOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output power in Watts, or -1 if it's - unsupported by this ATS." - ::= { atsOutputPhaseEntry 13 } - - atsOutputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 14 } - - atsOutputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 15 } - - atsOutputPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the ATSpower capacity in Watts at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this ATS." - ::= { atsOutputPhaseEntry 16 } - - atsOutputMaxPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the ATSpower capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 17 } - - atsOutputMinPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum percentage of the ATSpower capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 18 } - --- the dcmim2IdentSystem group - -dcmim2IdentSysFWVersion OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Integer representation of the power plant Master Controller firmware revision." - ::= { dcmim2IdentSystem 1 } - - --- the dcmim2ControlSystem group - -dcmim2ControlRunFunctBatteryTest OBJECT-TYPE - SYNTAX INTEGER { - battTestOff (1), - battTestOn (2) -} - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this OID will return the battery functional test state. If - the test is off, the battTestOff (1) value will be returned. - If the test is on, the battTestOn (2) value will be - returned. - - Setting this OID to battTestOff (1) will turn the battery functional test off. - Setting this OID to battTestOn (2) will turn the battery functional test on." - - ::= { dcmim2ControlSystem 1 } - -dcmim2ControlRunCapacityBatteryTest OBJECT-TYPE - SYNTAX INTEGER { - battTestOff (1), - battTestOn (2) -} - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this OID will return the battery capacity test state. If - the test is off, the battTestOff (1) value will be returned. - If the test is on, the battTestOn (2) value will be - returned. - - Setting this OID to battTestOff (1) will turn the battery capacity test off. - Setting this OID to battTestOn (2) will turn the battery capacity test on." - - ::= { dcmim2ControlSystem 2 } - - --- the dcmim2ConfigSystem group - -dcmim2ConfigSysHighTempTrip OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Trip level (threshold) at which System High Temp alarm condition is created. - Range 28 to 100 (degC). - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - - ::= { dcmim2ConfigSystem 1 } - -dcmim2ConfigSysHighTempReset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Level at which System High Temp alarm condition is reset (cleared). - Range 25 to (upper temp - 3) (degC). - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dcmim2ConfigSystem 2 } - -dcmim2ConfigSysLowTempTrip OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Trip level (threshold) at which System Low Temp alarm condition is created. - Range -100 to 10 (degC). - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dcmim2ConfigSystem 3 } - -dcmim2ConfigSysLowTempReset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Level at which System Low Temp alarm condition is reset (cleared). - Range (lower temp + 3) to 13 (degC). - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dcmim2ConfigSystem 4 } - --- the dcmim2ConfigBattery group - -dcmim2ConfigBattFloatVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Float Voltage defined at 25 degrees Celsius. - - Values are represented in thousandths of Volts (mV)." - - ::= { dcmim2ConfigBattery 1 } - -dcmim2ConfigBattMaxRecharge OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Maximum Recharge Rate. This is the maximum current used - during battery charging. - - Values are represented in thousandths of Amps (mA)." - - ::= { dcmim2ConfigBattery 2 } - -dcmim2ConfigBattMfgCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery capacity (Amp-Hour Size) as specified by the battery manufacturer. - - Values are represented in thousandths of Amp hours (mAHr)." - - ::= { dcmim2ConfigBattery 3 } - -dcmim2ConfigBattType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Type of battery in the powerplant - - Valid values range from 0 to 254." - - ::= { dcmim2ConfigBattery 4 } - -dcmim2ConfigBattFunctTestDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Duration of the battery functional test. - - Values are represented in thousandths of seconds (mSecs)." - - ::= { dcmim2ConfigBattery 5 } - -dcmim2ConfigBattFunctTestThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold the battery voltage of the system must remain above - in order to pass the battery functional test. - - Values are represented in thousandths of Volts (mV)." - - ::= { dcmim2ConfigBattery 6 } - -dcmim2ConfigBattCapacityTestPercent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold for good battery capacity test results. - - Values range from 0 to 100 percent." - - ::= { dcmim2ConfigBattery 7 } - -dcmim2ConfigBattCapacityTestEndThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Safeguard voltage at which battery capacity test will end - if there is a battery problem. - - Values are represented in thousandths of Volts (mV)." - - ::= { dcmim2ConfigBattery 8 } - -dcmim2ConfigBattCapacityTestCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Constant current value used during battery capacity testing. - - Values are represented in thousandths of Amps (mA)." - - ::= { dcmim2ConfigBattery 9 } - - --- the dcmim2ConfigLVD group - -dcmim2ConfigLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs controllable - by this IP address." - ::= { dcmim2ConfigLVD 1 } - -dcmim2ConfigLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the LVDs. The number of - entries is contained in the dcmim2ConfigLVDTableSize OID." - ::= { dcmim2ConfigLVD 2 } - -dcmim2ConfigLVDEntry OBJECT-TYPE - SYNTAX DC2ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to configure." - INDEX { dcmim2ConfigLVDIndex } - ::= { dcmim2ConfigLVDTable 1 } - -DC2ConfigLVDEntry ::= - SEQUENCE { - dcmim2ConfigLVDIndex INTEGER, - dcmim2ConfigLVDTrip INTEGER, - dcmim2ConfigLVDReset INTEGER, - dcmim2ConfigLVDState INTEGER - } - -dcmim2ConfigLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dcmim2ConfigLVDEntry 1 } - -dcmim2ConfigLVDTrip OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Trip threshold. System bus voltage at which LVD will trip (open) - during a battery backup operation. - - Values are represented in thousandths of Volts (mV)." - ::= { dcmim2ConfigLVDEntry 2 } - -dcmim2ConfigLVDReset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Reset threshold. System bus voltage at which LVD will reset (close) - after AC power has been restored. - - Values are represented in thousandths of Volts (mV)." - ::= { dcmim2ConfigLVDEntry 3 } - -dcmim2ConfigLVDState OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpened (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the LVD is closed. - statusOpened (2) will be returned if the LVD is opened." - ::= { dcmim2ConfigLVDEntry 4 } - - --- the dcmim2StatusSystem group - -dcmim2StatusSysRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System (Total Rectifier) current in thousandths of Amps (mA)." - ::= { dcmim2StatusSystem 1 } - -dcmim2StatusSysLoadCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Load current in thousandths of Amps (mA)." - ::= { dcmim2StatusSystem 2 } - -dcmim2StatusSysBusVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System bus voltage in thousandths of Volts (mV)." - ::= { dcmim2StatusSystem 3 } - -dcmim2StatusSysAmbientTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System temperature based on sensor on Master Controller PCB. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - ::= { dcmim2StatusSystem 4 } - -dcmim2StatusSysUpTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Length of time since the DC Powerplant controller has been powered up." - ::= { dcmim2StatusSystem 5 } - -dcmim2StatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the DC system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { dcmim2StatusSystem 6 } - - --- the dcmim2StatusRectifier group - -dcmim2StatusRectTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant rectifiers viewable - by this IP address." - ::= { dcmim2StatusRectifier 1 } - -dcmim2StatusRectTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the rectifiers. The number of - entries is contained in the dcmim2StatusRectTableSize OID." - ::= { dcmim2StatusRectifier 2 } - -dcmim2StatusRectEntry OBJECT-TYPE - SYNTAX DC2StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The rectifier to gather status from." - INDEX { dcmim2StatusRectIndex } - ::= { dcmim2StatusRectTable 1 } - -DC2StatusRectEntry ::= - SEQUENCE { - dcmim2StatusRectIndex INTEGER, - dcmim2StatusRectDevType INTEGER, - dcmim2StatusRectID INTEGER, - dcmim2StatusRectPhyAddr INTEGER, - dcmim2StatusRectFail INTEGER, - dcmim2StatusRectCurrent INTEGER - } - -dcmim2StatusRectIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant rectifier." - ::= { dcmim2StatusRectEntry 1 } - -dcmim2StatusRectDevType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device type." - ::= { dcmim2StatusRectEntry 2 } - -dcmim2StatusRectID OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier ID. This enumerates the number of the rectifier within - a group of rectifiers." - ::= { dcmim2StatusRectEntry 3 } - -dcmim2StatusRectPhyAddr OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier physical address (the address on the bus)." - ::= { dcmim2StatusRectEntry 4 } - -dcmim2StatusRectFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier has failed. - statusFalse (2) will be returned if the rectifier has not failed." - ::= { dcmim2StatusRectEntry 5 } - -dcmim2StatusRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the individual rectifier current in thousandths of Amps (mA)." - ::= { dcmim2StatusRectEntry 6 } - - --- the dcmim2StatusBattery group - -dcmim2StatusBattFloatVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Float Voltage represented in thousandths of Volts (mV)." - ::= { dcmim2StatusBattery 1 } - -dcmim2StatusBattCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Current: This OID shows the battery current in thousandths of Amps (mA)." - ::= { dcmim2StatusBattery 2 } - -dcmim2StatusBattTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Temperature: - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - ::= { dcmim2StatusBattery 3 } - -dcmim2StatusBattMfgCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery capacity (Amp-Hour Size) as specified by the battery manufacturer. - Values are represented in thousandths of Amp hours (mAHr)." - ::= { dcmim2StatusBattery 4 } - -dcmim2StatusBattTestCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery capacity (Amp-Hour Size) as determined by the battery capacity test. - Values are represented in thousandths of Amp hours (mAHr)." - ::= { dcmim2StatusBattery 5 } - -dcmim2StatusBattFunctTestResult OBJECT-TYPE - SYNTAX INTEGER{ - functTestNotPerformed (1), - functTestInProcess (2), - functTestInterrupted (3), - functTestPass (4), - functTestFail (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Results of the last battery functional test that was run." - ::= { dcmim2StatusBattery 6 } - -dcmim2StatusBattCapacityTestResult OBJECT-TYPE - SYNTAX INTEGER{ - capacityTestNotPerformed (1), - capacityTestInProcess (2), - capacityTestInterrupted (3), - capacityTestPass (4), - capacityTestFail (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Results of the last battery capacity test that was run." - ::= { dcmim2StatusBattery 7 } - - --- the dcmim2StatusLVD group - -dcmim2StatusLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs accessible - by this IP address." - ::= { dcmim2StatusLVD 1 } - -dcmim2StatusLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing the LVDs. The number of - entries is contained in the dcmim2StatusLVDTableSize OID." - ::= { dcmim2StatusLVD 2 } - -dcmim2StatusLVDEntry OBJECT-TYPE - SYNTAX DC2StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to access." - INDEX { dcmim2StatusLVDIndex } - ::= { dcmim2StatusLVDTable 1 } - -DC2StatusLVDEntry ::= - SEQUENCE { - dcmim2StatusLVDIndex INTEGER, - dcmim2StatusLVDState INTEGER - } - -dcmim2StatusLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dcmim2StatusLVDEntry 1 } - -dcmim2StatusLVDState OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpened (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the LVD is closed. - statusOpened (2) will be returned if the LVD is opened." - ::= { dcmim2StatusLVDEntry 2 } - - --- the dcmim2StatusAlarms group - -dcmim2StatusAlarmsTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant alarms viewable - by this IP address." - ::= { dcmim2StatusAlarms 1 } - -dcmim2StatusAlarmsTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing system alarms. The number of - entries is contained in the dcmim2StatusAlarmsTableSize OID." - ::= { dcmim2StatusAlarms 2 } - -dcmim2StatusAlarmsEntry OBJECT-TYPE - SYNTAX DC2StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm to display." - INDEX { dcmim2StatusAlarmsIndex } - ::= { dcmim2StatusAlarmsTable 1 } - -DC2StatusAlarmsEntry ::= - SEQUENCE { - dcmim2StatusAlarmsIndex INTEGER, - dcmim2StatusAlarmsText DisplayString - } - -dcmim2StatusAlarmsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the system alarm." - ::= { dcmim2StatusAlarmsEntry 1 } - -dcmim2StatusAlarmsText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The 16 character text describing the active alarm condition." - ::= { dcmim2StatusAlarmsEntry 2 } - --- External Environmental Monitor - -emIdentFirmwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Environmental Monitor." - ::= { emIdent 1 } - -emConfigProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of temperature and humidity probes available." - ::= { emConfig 1 } - -emConfigProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their configurations." - ::= { emConfig 2 } - -emConfigProbesEntry OBJECT-TYPE - SYNTAX EmConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor probe configurations." - INDEX { emConfigProbeNumber } - ::= { emConfigProbesTable 1 } - -EmConfigProbesEntry ::= - SEQUENCE { - emConfigProbeNumber - INTEGER, - emConfigProbeName - DisplayString, - emConfigProbeHighTempThreshold - INTEGER, - emConfigProbeLowTempThreshold - INTEGER, - emConfigProbeTempUnits - INTEGER, - emConfigProbeHighHumidThreshold - INTEGER, - emConfigProbeLowHumidThreshold - INTEGER, - emConfigProbeHighTempEnable - INTEGER, - emConfigProbeLowTempEnable - INTEGER, - emConfigProbeHighHumidEnable - INTEGER, - emConfigProbeLowHumidEnable - INTEGER - } - -emConfigProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index into an Environmental Monitor probe entry." - ::= { emConfigProbesEntry 1 } - -emConfigProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name of the probe set by the user, - possibly denoting its location or purpose." - ::= { emConfigProbesEntry 2 } - -emConfigProbeHighTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm threshold for the probe. - Units are displayed in the scale selected in - the 'emConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { emConfigProbesEntry 3 } - -emConfigProbeLowTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm threshold for the probe. - Units are displayed in the scale selected in - the 'emConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { emConfigProbesEntry 4 } - -emConfigProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { emConfigProbesEntry 5 } - -emConfigProbeHighHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm threshold for the probe in - percent relative humidity." - ::= { emConfigProbesEntry 6 } - -emConfigProbeLowHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm threshold for the probe in - percent relative humidity." - ::= { emConfigProbesEntry 7 } - -emConfigProbeHighTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 8 } - -emConfigProbeLowTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 9 } - -emConfigProbeHighHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 10 } - -emConfigProbeLowHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 11 } - -emConfigContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the Environmental - Monitor." - ::= { emConfig 3 } - -emConfigContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their configurations." - ::= { emConfig 4 } - -emConfigContactsEntry OBJECT-TYPE - SYNTAX EmConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor contact configurations." - INDEX { emConfigContactNumber } - ::= { emConfigContactsTable 1 } - -EmConfigContactsEntry ::= - SEQUENCE { - emConfigContactNumber - INTEGER, - emConfigContactName - DisplayString, - emConfigContactEnable - INTEGER - } - -emConfigContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an Environmental Monitor contact." - ::= { emConfigContactsEntry 1 } - -emConfigContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name for an Environmental Monitor - contact set by the user, possibly denoting its - location or purpose." - ::= { emConfigContactsEntry 2 } - -emConfigContactEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An Environmental Monitor contact alarm enable/disable. - No alarm will be generated if the contact is disabled(1). - An alarm will be generated if the contact is enabled(2) - and the contact has been faulted." - ::= { emConfigContactsEntry 3 } - -emStatusCommStatus OBJECT-TYPE - SYNTAX INTEGER { - noComm(1), - comm(2), - commLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The communication status between the agent - and the Environmental Monitor. - - noComm(1), Communication has never been established. - comm(2), Communication has been established. - commLost(3), Communication was established, but was lost." - ::= { emStatus 1 } - -emStatusProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of available probes on the Environmental - Monitor." - ::= { emStatus 2 } - -emStatusProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their status." - ::= { emStatus 3 } - -emStatusProbesEntry OBJECT-TYPE - SYNTAX EmStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the probe." - INDEX { emStatusProbeNumber } - ::= { emStatusProbesTable 1 } - -EmStatusProbesEntry ::= - SEQUENCE { - emStatusProbeNumber - INTEGER, - emStatusProbeName - DisplayString, - emStatusProbeStatus - INTEGER, - emStatusProbeCurrentTemp - INTEGER, - emStatusProbeTempUnits - INTEGER, - emStatusProbeCurrentHumid - INTEGER, - emStatusProbeHighTempViolation - INTEGER, - emStatusProbeLowTempViolation - INTEGER, - emStatusProbeHighHumidViolation - INTEGER, - emStatusProbeLowHumidViolation - INTEGER - } - -emStatusProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the probe." - ::= { emStatusProbesEntry 1 } - -emStatusProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the probe set by the user, - possibly denoting its location or purpose." - ::= { emStatusProbesEntry 2 } - -emStatusProbeStatus OBJECT-TYPE - SYNTAX INTEGER { - disconnected(1), - connected(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The connected status of the probe, either - disconnected(1) or connected(2)." - ::= { emStatusProbesEntry 3 } - -emStatusProbeCurrentTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current temperature reading from the probe displayed - in the units shown in the 'emStatusProbeTempUnits' OID - (Celsius or Fahrenheit)." - ::= { emStatusProbesEntry 4 } - -emStatusProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { emStatusProbesEntry 5 } - -emStatusProbeCurrentHumid OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current humidity reading from the probe in - percent relative humidity." - ::= { emStatusProbesEntry 6 } - -emStatusProbeHighTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a highTempViolation(2) - if the current temperature reading shown in the - 'emStatusProbeCurrentTemp' OID is greater than or equal to - the high temperature threshold value, the - 'emConfigProbeHighTempThreshold' OID, and the value of the - 'emConfigProbeHighTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'emConfigProbeHighTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { emStatusProbesEntry 7 } - -emStatusProbeLowTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a lowTempViolation(2) - if the current temperature reading shown in the - 'emStatusProbeCurrentTemp' OID is less than or equal to - the low temperature threshold value, the - 'emConfigProbeLowTempThreshold' OID, and the value of the - 'emConfigProbeLowTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'emConfigProbeLowTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { emStatusProbesEntry 8 } - -emStatusProbeHighHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high humidity violation status of the probe humidity - reading. This OID will show a highTempViolation(2) - if the current humidity reading shown in the - 'emStatusProbeCurrentHumid' OID is greater than or equal to - the high humidity threshold value, the - 'emConfigProbeHighHumidThreshold' OID, and the value of the - 'emConfigProbeHighHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'emConfigProbeHighHumidEnable' OID is - disabled, this OID will show disabled(3)" - ::= { emStatusProbesEntry 9 } - -emStatusProbeLowHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The low humidity violation status of the probe humidity - reading. This OID will show a lowTempViolation(2) - if the current humidity reading shown in the - 'emStatusProbeCurrentHumid' OID is less than or equal to - the low humidity threshold value, the - 'emConfigProbeLowHumidThreshold' OID, and the value of the - 'emConfigProbeLowHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'emConfigProbeLowHumidEnable' OID is - disabled, this OID will show disabled(3)." - ::= { emStatusProbesEntry 10 } - -emStatusContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the - Environmental Monitor." - ::= { emStatus 4 } - -emStatusContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their status." - ::= { emStatus 5 } - -emStatusContactsEntry OBJECT-TYPE - SYNTAX EmStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the contact." - INDEX { emStatusContactNumber } - ::= { emStatusContactsTable 1 } - -EmStatusContactsEntry ::= - SEQUENCE { - emStatusContactNumber - INTEGER, - emStatusContactName - DisplayString, - emStatusContactStatus - INTEGER - } - -emStatusContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Environmental Monitor contact." - ::= { emStatusContactsEntry 1 } - -emStatusContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the Environmental Monitor contact - set by the user, possibly denoting its location or purpose." - ::= { emStatusContactsEntry 2 } - -emStatusContactStatus OBJECT-TYPE - SYNTAX INTEGER { - noFault(1), - fault(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Environmental Monitor contact. The status - will show noFault(1) if the contact is in the normal state - and the 'emConfigContactEnable' OID is enabled. The status will - show a fault(2) if the contact is faulted and the - 'emContactEnable' OID is enabled. If the 'emConfigContactEnable' - OID is disabled, the status will show disabled(3)." - ::= { emStatusContactsEntry 3 } - --- Integrated Environmental Monitor (IEM) - -iemIdentHardwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Integrated Environmental - Monitor." - ::= { iemIdent 1 } - -iemConfigProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of temperature and humidity probes available." - ::= { iemConfig 1 } - -iemConfigProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their configurations." - ::= { iemConfig 2 } - -iemConfigProbesEntry OBJECT-TYPE - SYNTAX IemConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor probe configurations." - INDEX { iemConfigProbeNumber } - ::= { iemConfigProbesTable 1 } - -IemConfigProbesEntry ::= - SEQUENCE { - iemConfigProbeNumber - INTEGER, - iemConfigProbeName - DisplayString, - iemConfigProbeHighTempThreshold - INTEGER, - iemConfigProbeLowTempThreshold - INTEGER, - iemConfigProbeTempUnits - INTEGER, - iemConfigProbeHighHumidThreshold - INTEGER, - iemConfigProbeLowHumidThreshold - INTEGER, - iemConfigProbeHighTempEnable - INTEGER, - iemConfigProbeLowTempEnable - INTEGER, - iemConfigProbeHighHumidEnable - INTEGER, - iemConfigProbeLowHumidEnable - INTEGER - } - -iemConfigProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to a Environmental Monitor probe entry." - ::= { iemConfigProbesEntry 1 } - -iemConfigProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name for the probe set by the user, - possibly denoting its location or purpose." - ::= { iemConfigProbesEntry 2 } - -iemConfigProbeHighTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm threshold for the probe. - Units are displayed in the scale selected in the - 'iemConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { iemConfigProbesEntry 3 } - -iemConfigProbeLowTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm threshold for the probe. - Units are displayed in the scale selected in the - 'iemConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { iemConfigProbesEntry 4 } - -iemConfigProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { iemConfigProbesEntry 5 } - -iemConfigProbeHighHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm threshold for the probe in - percent relative humidity." - ::= { iemConfigProbesEntry 6 } - -iemConfigProbeLowHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm threshold for the probe in - percent relative humidity." - ::= { iemConfigProbesEntry 7 } - -iemConfigProbeHighTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 8 } - -iemConfigProbeLowTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 9 } - -iemConfigProbeHighHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 10 } - -iemConfigProbeLowHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 11 } - -iemConfigContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts available on the Environmental - Monitor." - ::= { iemConfig 3 } - -iemConfigContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their configurations." - ::= { iemConfig 4 } - -iemConfigContactsEntry OBJECT-TYPE - SYNTAX IemConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor contact configurations." - INDEX { iemConfigContactNumber } - ::= { iemConfigContactsTable 1 } - -IemConfigContactsEntry ::= - SEQUENCE { - iemConfigContactNumber - INTEGER, - iemConfigContactName - DisplayString, - iemConfigContactEnable - INTEGER - } - -iemConfigContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an Environmental Monitor contact." - ::= { iemConfigContactsEntry 1 } - -iemConfigContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name for the Environmental Monitor contact - set by the user, possibly denoting its location or purpose." - ::= { iemConfigContactsEntry 2 } - -iemConfigContactEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An Environmental Monitor contact alarm enable/disable." - ::= { iemConfigContactsEntry 3 } - - -iemStatusProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of available probes on the Environmental - Monitor." - ::= { iemStatus 1 } - -iemStatusProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their status." - ::= { iemStatus 2 } - -iemStatusProbesEntry OBJECT-TYPE - SYNTAX IemStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the probe." - INDEX { iemStatusProbeNumber } - ::= { iemStatusProbesTable 1 } - -IemStatusProbesEntry ::= - SEQUENCE { - iemStatusProbeNumber - INTEGER, - iemStatusProbeName - DisplayString, - iemStatusProbeStatus - INTEGER, - iemStatusProbeCurrentTemp - INTEGER, - iemStatusProbeTempUnits - INTEGER, - iemStatusProbeCurrentHumid - INTEGER, - iemStatusProbeHighTempViolation - INTEGER, - iemStatusProbeLowTempViolation - INTEGER, - iemStatusProbeHighHumidViolation - INTEGER, - iemStatusProbeLowHumidViolation - INTEGER - } - -iemStatusProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the probe." - ::= { iemStatusProbesEntry 1 } - -iemStatusProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the probe set by the user, - denoting its location or purpose." - ::= { iemStatusProbesEntry 2 } - -iemStatusProbeStatus OBJECT-TYPE - SYNTAX INTEGER { - disconnected(1), - connected(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The connected status of the probe, either - disconnected(1) or connected(2)." - ::= { iemStatusProbesEntry 3 } - -iemStatusProbeCurrentTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current temperature reading from the probe displayed - in the units shown in the 'iemStatusProbeTempUnits' OID - (Celsius or Fahrenheit)." - ::= { iemStatusProbesEntry 4 } - -iemStatusProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { iemStatusProbesEntry 5 } - -iemStatusProbeCurrentHumid OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current humidity reading from the probe in percent - relative humidity." - ::= { iemStatusProbesEntry 6 } - -iemStatusProbeHighTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a highTempViolation(2) - if the current temperature reading shown in the - 'iemStatusProbeCurrentTemp' OID is greater than or equal to - the high temperature threshold value, the - 'iemConfigProbeHighTempThreshold' OID, and the value of the - 'iemConfigProbeHighTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'iemConfigProbeHighTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { iemStatusProbesEntry 7 } - -iemStatusProbeLowTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a lowTempViolation(2) - if the current temperature reading shown in the - 'iemStatusProbeCurrentTemp' OID is less than or equal to - the low temperature threshold value, the - 'iemConfigProbeLowTempThreshold' OID, and the value of the - 'iemPConfigrobeLowTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'iemConfigProbeLowTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { iemStatusProbesEntry 8 } - -iemStatusProbeHighHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high humidity violation status of the probe humidity - reading. This OID will show a highTempViolation(2) - if the current humidity reading shown in the - 'iemStatusProbeCurrentHumid' OID is greater than or equal to - the high humidity threshold value, the - 'iemConfigProbeHighHumidThreshold' OID, and the value of the - 'iemConfigProbeHighHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'iemConfigProbeHighHumidEnable' OID is - disabled, this OID will show disabled(3)." - ::= { iemStatusProbesEntry 9 } - -iemStatusProbeLowHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The low humidity violation status of the probe humidity - reading. This OID will show a lowTempViolation(2) - if the current humidity reading shown in the - 'iemStatusProbeCurrentHumid' OID is less than or equal to - the low humidity threshold value, the - 'iemConfigProbeLowHumidThreshold' OID, and the value of the - 'iemConfigProbeLowHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'iemConfigProbeLowHumidEnable' OID is - disabled, this OID will show disabled(3)." - ::= { iemStatusProbesEntry 10 } - -iemStatusContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported on the - Environmental Monitor." - ::= { iemStatus 3 } - -iemStatusContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their status." - ::= { iemStatus 4 } - -iemStatusContactsEntry OBJECT-TYPE - SYNTAX IemStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the contact." - INDEX { iemStatusContactNumber } - ::= { iemStatusContactsTable 1 } - -IemStatusContactsEntry ::= - SEQUENCE { - iemStatusContactNumber - INTEGER, - iemStatusContactName - DisplayString, - iemStatusContactStatus - INTEGER - } - -iemStatusContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Environmental Monitor contact." - ::= { iemStatusContactsEntry 1 } - -iemStatusContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the Environmental Monitor contact - set by the user, denoting its location or purpose." - ::= { iemStatusContactsEntry 2 } - -iemStatusContactStatus OBJECT-TYPE - SYNTAX INTEGER { - noFault(1), - fault(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Environmental Monitor contact. The status - will show noFault(1) if the contact is in the normal state - and the 'iemConfigContactEnable' OID is enabled. The status will - show a fault(2) if the contact is faulted and the - 'iemConfigContactEnable' OID is enabled. If the - 'iemConfigContactEnable' OID is disabled, the status will show - disabled(3)." - ::= { iemStatusContactsEntry 3 } - -iemStatusRelaysNumRelays OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relays supported on the - Environmental Monitor." - ::= { iemStatus 6 } - -iemStatusRelaysTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemStatusRelaysEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output relays supported by the - Environmental Monitor and their status." - ::= { iemStatus 7 } - -iemStatusRelaysEntry OBJECT-TYPE - SYNTAX IemStatusRelaysEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the relay." - INDEX { iemStatusRelayNumber } - ::= { iemStatusRelaysTable 1 } - -IemStatusRelaysEntry ::= - SEQUENCE { - iemStatusRelayNumber - INTEGER, - iemStatusRelayName - DisplayString, - iemStatusRelayStatus - INTEGER - } - -iemStatusRelayNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the output relay." - ::= { iemStatusRelaysEntry 1 } - -iemStatusRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the output relay set by the - user, denoting its location or purpose." - ::= { iemStatusRelaysEntry 2 } - -iemStatusRelayStatus OBJECT-TYPE - SYNTAX INTEGER { - faultState(1), - normalState(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the output relay, either faultState(1) or - normalState(2)." - ::= { iemStatusRelaysEntry 3 } - --- Environmental Management System (EMS) - --- EMS IDENT - -emsIdentEMSName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { emsIdent 1 } - -emsIdentProductNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of - the device. This value is set at the factory." - ::= { emsIdent 2 } - -emsIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the device." - ::= { emsIdent 3 } - -emsIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the device. - This value is set at the factory." - ::= { emsIdent 4 } - -emsIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the device was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { emsIdent 5 } - -emsIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of - the device. This value is set at the factory." - ::= { emsIdent 6 } - --- EMS CONTROL - --- EMS OUTPUT RELAY CONTROL STATUS TABLE - -emsOutputRelayControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutputRelayControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual output relays. The number of - entries is contained in the emsStatusOutputRelayCount OID." - ::= { emsOutputRelayControl 1 } - -emsOutputRelayControlEntry OBJECT-TYPE - SYNTAX OutputRelayControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relays to control." - INDEX { emsOutputRelayControlOutputRelayIndex } - ::= { emsOutputRelayControlTable 1 } - -OutputRelayControlEMSEntry ::= - SEQUENCE { - emsOutputRelayControlOutputRelayIndex INTEGER, - emsOutputRelayControlOutputRelayName DisplayString, - emsOutputRelayControlOutputRelayCommand INTEGER - } - -emsOutputRelayControlOutputRelayIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the output relay entry." - ::= { emsOutputRelayControlEntry 1 } - -emsOutputRelayControlOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the output relay. - This OID is provided for informational purposes only." - ::= { emsOutputRelayControlEntry 2 } - -emsOutputRelayControlOutputRelayCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateCloseEMS (1), - immediateOpenEMS (2) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the output relay state. If - the output relay is closed, the immediateCloseEMS (1) value will be returned. - If the output relay is open, the immediateOpenEMS (2) value will be - returned. - - Setting this variable to immediateCloseEMS (1) will immediately close the relay. - - Setting this variable to immediateOpenEMS (2) will immediately open the relay." - ::= { emsOutputRelayControlEntry 3 } - --- EMS OUTLET CONTROL TABLE - -emsOutletControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the emsStatusOutletCount OID." - ::= { emsOutletControl 1 } - -emsOutletControlEntry OBJECT-TYPE - SYNTAX OutletControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { emsOutletControlOutletIndex } - ::= { emsOutletControlTable 1 } - -OutletControlEMSEntry ::= - SEQUENCE { - emsOutletControlOutletIndex INTEGER, - emsOutletControlOutletName DisplayString, - emsOutletControlOutletCommand INTEGER - } - -emsOutletControlOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { emsOutletControlEntry 1 } - -emsOutletControlOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. - This OID is provided for informational purposes only." - ::= { emsOutletControlEntry 2 } - -emsOutletControlOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOnEMS (1), - immediateOffEMS (2) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOnEMS (1) value will be returned. - If the outlet is off, the immediateOffEMS (2) value will be - returned. - - Setting this variable to immediateOnEMS (1) will immediately turn the outlet on. - - Setting this variable to immediateOffEMS (2) will immediately turn the outlet off." - ::= { emsOutletControlEntry 3 } - --- EMS SENSOR CONTROL TABLE - -emsSensorControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSSensorControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control/reset of individual sensors. The number of - entries is contained in the emsStatusSensorCount OID." - ::= { emsSensorControl 1 } - -emsSensorControlEntry OBJECT-TYPE - SYNTAX EMSSensorControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The sensors to control/reset." - INDEX { emsSensorControlSensorIndex } - ::= { emsSensorControlTable 1 } - -EMSSensorControlEntry ::= - SEQUENCE { - emsSensorControlSensorIndex INTEGER, - emsSensorControlSensorSystemName DisplayString, - emsSensorControlSensorUserName DisplayString, - emsSensorControlSensorCommand INTEGER - } - -emsSensorControlSensorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the sensor entry." - ::= { emsSensorControlEntry 1 } - -emsSensorControlSensorSystemName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system name of the sensor. This describes the hardware system - intent of this sensor." - ::= { emsSensorControlEntry 2 } - -emsSensorControlSensorUserName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the sensor as given by the system user." - ::= { emsSensorControlEntry 3 } - -emsSensorControlSensorCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandEMS (1), - resetCommandEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return noCommandEMS(1). - - Setting this variable to resetCommandEMS(2) will issue a reset command to the - sensor. Some sensors cannot be manually reset and will not be affected - by this command." - ::= { emsSensorControlEntry 4 } - --- EMS ALARM DEVICE CONTROL TABLE - -emsAlarmDeviceControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF AlarmDeviceControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual alarm devices. - Note: Some alarm devices are not controllable. The number of - entries is contained in the emsStatusAlarmDeviceCount OID." - ::= { emsAlarmDeviceControl 1 } - -emsAlarmDeviceControlEntry OBJECT-TYPE - SYNTAX AlarmDeviceControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm devices to control." - INDEX { emsAlarmDeviceControlDeviceIndex } - ::= { emsAlarmDeviceControlTable 1 } - -AlarmDeviceControlEMSEntry ::= - SEQUENCE { - emsAlarmDeviceControlDeviceIndex INTEGER, - emsAlarmDeviceControlDeviceName DisplayString, - emsAlarmDeviceControlDeviceCommand INTEGER - } - -emsAlarmDeviceControlDeviceIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the alarm device entry." - ::= { emsAlarmDeviceControlEntry 1 } - -emsAlarmDeviceControlDeviceName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the alarm device. - This OID is provided for informational purposes only." - ::= { emsAlarmDeviceControlEntry 2 } - -emsAlarmDeviceControlDeviceCommand OBJECT-TYPE - SYNTAX INTEGER { - alarmDeviceOnEMS (1), - alarmDeviceOffEMS (2), - alarmDeviceNotInstalledEMS (3) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the device state. If - the device is active, the alarmDeviceOnEMS (1) value will be returned. - If the device is inactive, the alarmDeviceOffEMS (2) value will be - returned. If the device is not installed, the - alarmDeviceNotInstalledEMS (3) value will be returned. - - Actions resulting from setting this variable are device-dependent. - - Setting this variable to alarmDeviceOnEMS (1) will turn that device (ex. Beacon) on. - Setting this variable to alarmDeviceOffEMS (2) will turn that device off." - - ::= { emsAlarmDeviceControlEntry 3 } - - --- EMS CONFIG - -emsConfigName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the device." - ::= { emsConfig 1 } - -emsConfigCheckLogLight OBJECT-TYPE - SYNTAX INTEGER { - lightDisabled (1), - lightOnInformational (2), - lightOnWarning (3), - lightOnSevere (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The setting of this OID determines the level of event that will - trigger the check-log light on the EMS. This is not available on the EMU2. - - lightDisabled (1) disables the check-log light. - lightOnInformational (2) lights check-log for any event of - informational severity or above. - lightOnWarning (3) lights check-log for any event of - warning severity or above. - lightOnSevere (4) lights check-log for any event of severe severity." - - ::= { emsConfig 2 } - --- EMS PROBE CONFIG TABLE - -emsProbeConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSProbeConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual probes. The number of - entries is contained in the emsStatusProbeCount OID." - ::= { emsProbeConfig 1 } - -emsProbeConfigEntry OBJECT-TYPE - SYNTAX EMSProbeConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The probes to configure." - INDEX { emsProbeConfigProbeIndex } - ::= { emsProbeConfigTable 1 } - -EMSProbeConfigEntry ::= - SEQUENCE { - emsProbeConfigProbeIndex INTEGER, - emsProbeConfigProbeName DisplayString, - emsProbeConfigProbeHighTempThresh INTEGER, - emsProbeConfigProbeLowTempThresh INTEGER, - emsProbeConfigProbeHighHumidityThresh INTEGER, - emsProbeConfigProbeLowHumidityThresh INTEGER, - emsProbeConfigProbeMaxTempThresh INTEGER, - emsProbeConfigProbeMinTempThresh INTEGER, - emsProbeConfigProbeDeltaTemp INTEGER, - emsProbeConfigProbeMaxHumidityThresh INTEGER, - emsProbeConfigProbeMinHumidityThresh INTEGER, - emsProbeConfigProbeDeltaHumidity INTEGER, - emsProbeConfigProbeSTIncTempVariance INTEGER, - emsProbeConfigProbeSTIncTempTime INTEGER, - emsProbeConfigProbeSTDecTempVariance INTEGER, - emsProbeConfigProbeSTDecTempTime INTEGER, - emsProbeConfigProbeLTIncTempVariance INTEGER, - emsProbeConfigProbeLTIncTempTime INTEGER, - emsProbeConfigProbeLTDecTempVariance INTEGER, - emsProbeConfigProbeLTDecTempTime INTEGER - } - -emsProbeConfigProbeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the probe entry." - ::= { emsProbeConfigEntry 1 } - -emsProbeConfigProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the probe." - ::= { emsProbeConfigEntry 2 } - -emsProbeConfigProbeHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe high temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 3 } - -emsProbeConfigProbeLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe low temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 4 } - -emsProbeConfigProbeHighHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe high humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 5 } - -emsProbeConfigProbeLowHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe low humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 6 } - -emsProbeConfigProbeMaxTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe maximum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 7 } - -emsProbeConfigProbeMinTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe minimum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 8 } - -emsProbeConfigProbeDeltaTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe delta temperature. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 9 } - -emsProbeConfigProbeMaxHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe maximum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 10 } - -emsProbeConfigProbeMinHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe minimum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 11 } - -emsProbeConfigProbeDeltaHumidity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe delta humidity. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 12 } - -emsProbeConfigProbeSTIncTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term increasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 13 } - -emsProbeConfigProbeSTIncTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term increasing temperature time used for rate of change alarms. - - Values are represented in whole number minutes." - ::= { emsProbeConfigEntry 14 } - -emsProbeConfigProbeSTDecTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term decreasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 15 } - -emsProbeConfigProbeSTDecTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term decreasing temperature time used for rate of change alarms. - - Values are represented in whole number minutes." - ::= { emsProbeConfigEntry 16 } - -emsProbeConfigProbeLTIncTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term increasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 17 } - -emsProbeConfigProbeLTIncTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term increasing temperature time used for rate of change alarms. - - Values are represented in whole number hours." - ::= { emsProbeConfigEntry 18 } - -emsProbeConfigProbeLTDecTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term decreasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 19 } - -emsProbeConfigProbeLTDecTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term decreasing temperature time used for rate of change alarms. - - Values are represented in whole number hours." - ::= { emsProbeConfigEntry 20 } - - --- EMS INPUT CONTACT CONFIG STATUS TABLE - -emsInputContactConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSInputContactConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual input contacts. The number of - entries is contained in the emsStatusInputContactCount OID." - ::= { emsInputContactConfig 1 } - -emsInputContactConfigEntry OBJECT-TYPE - SYNTAX EMSInputContactConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input contacts to configure." - INDEX { emsInputContactConfigInputContactIndex } - ::= { emsInputContactConfigTable 1 } - -EMSInputContactConfigEntry ::= - SEQUENCE { - emsInputContactConfigInputContactIndex INTEGER, - emsInputContactConfigInputContactName DisplayString, - emsInputContactConfigInputContactNormalState INTEGER - } - -emsInputContactConfigInputContactIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the input contact entry." - ::= { emsInputContactConfigEntry 1 } - -emsInputContactConfigInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the input contact." - ::= { emsInputContactConfigEntry 2 } - -emsInputContactConfigInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the input contact. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned. - - Setting this variable will change the normal state of the input contact" - ::= { emsInputContactConfigEntry 3 } - --- EMS OUTPUT RELAY CONFIG STATUS TABLE - -emsOutputRelayConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutputRelayConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual output relays. The number of - entries is contained in the emsStatusOutputRelayCount OID." - ::= { emsOutputRelayConfig 1 } - -emsOutputRelayConfigEntry OBJECT-TYPE - SYNTAX EMSOutputRelayConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relays to configure." - INDEX { emsOutputRelayConfigOutputRelayIndex } - ::= { emsOutputRelayConfigTable 1 } - -EMSOutputRelayConfigEntry ::= - SEQUENCE { - emsOutputRelayConfigOutputRelayIndex INTEGER, - emsOutputRelayConfigOutputRelayName DisplayString, - emsOutputRelayConfigOutputRelayNormalState INTEGER - } - -emsOutputRelayConfigOutputRelayIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the output relay entry." - ::= { emsOutputRelayConfigEntry 1 } - -emsOutputRelayConfigOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the output relay." - ::= { emsOutputRelayConfigEntry 2 } - -emsOutputRelayConfigOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the output relay. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned. - - Setting this variable will change the normal state of the output relay" - ::= { emsOutputRelayConfigEntry 3 } - --- EMS OUTLET CONFIG TABLE - -emsOutletConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the emsStatusOutletCount OID." - ::= { emsOutletConfig 1 } - -emsOutletConfigEntry OBJECT-TYPE - SYNTAX EMSOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { emsOutletConfigOutletIndex } - ::= { emsOutletConfigTable 1 } - -EMSOutletConfigEntry ::= - SEQUENCE { - emsOutletConfigOutletIndex INTEGER, - emsOutletConfigOutletName DisplayString, - emsOutletConfigOutletNormalState INTEGER - } - -emsOutletConfigOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { emsOutletConfigEntry 1 } - -emsOutletConfigOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet." - ::= { emsOutletConfigEntry 2 } - -emsOutletConfigOutletNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyOnEMS (1), - normallyOffEMS (2) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the outlet. If - the normal state is on, the normallyOnEMS (1) value will be returned. - If the normal state is off, the normallyOffEMS (2) value will be - returned. - - Setting this variable will change the normal state of the outlet" - ::= { emsOutletConfigEntry 3 } - --- EMS SENSOR CONFIG TABLE - -emsSensorConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSSensorConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual sensors. The number of - entries is contained in the emsStatusSensorCount OID." - ::= { emsSensorConfig 1 } - -emsSensorConfigEntry OBJECT-TYPE - SYNTAX EMSSensorConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The sensors to configure." - INDEX { emsSensorConfigSensorIndex } - ::= { emsSensorConfigTable 1 } - -EMSSensorConfigEntry ::= - SEQUENCE { - emsSensorConfigSensorIndex INTEGER, - emsSensorConfigSensorSystemName DisplayString, - emsSensorConfigSensorUserName DisplayString, - emsSensorConfigSensorNormalState INTEGER, - emsSensorConfigSensorAlarmDelay INTEGER - } - -emsSensorConfigSensorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the sensor entry." - ::= { emsSensorConfigEntry 1 } - -emsSensorConfigSensorSystemName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system name of the sensor. This describes the hardware system - intent of this sensor." - ::= { emsSensorConfigEntry 2 } - -emsSensorConfigSensorUserName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the sensor as given by the system user." - ::= { emsSensorConfigEntry 3 } - -emsSensorConfigSensorNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the sensor. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned. - - Setting this variable will change the normal state of the sensor. Note: - Only the AUX sensor in the EMS has a configurable Normal State" - ::= { emsSensorConfigEntry 4 } - -emsSensorConfigSensorAlarmDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay (in seconds) after a sensor detects an alarm condition before the - condition is reported." - ::= { emsSensorConfigEntry 5 } - --- EMS STATUS ---- EMS MASTER status - -emsStatusEMSName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { emsStatus 1 } - -emsStatusCommStatus OBJECT-TYPE - SYNTAX INTEGER { - noComm(1), - comm(2), - commLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The communication status between the agent - and the device. - - noComm(1), Communication has never been established. - comm(2), Communication has been established. - commLost(3), Communication was established, but was lost." - ::= { emsStatus 2 } - -emsStatusProbeCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of T/H probes (both local and remote) that - is supported by this device." - ::= { emsStatus 3 } - -emsStatusInputContactCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of Input Contacts that - is supported by this device." - ::= { emsStatus 4 } - -emsStatusOutputRelayCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of Output Relays that - is supported by this device." - ::= { emsStatus 5 } - -emsStatusOutletCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of AC Outlets that - is supported by this device." - ::= { emsStatus 6 } - -emsStatusSensorCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of Sensors that - is supported by this device." - ::= { emsStatus 7 } - -emsStatusAlinkAruDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of remote Aru's supported by this device." - ::= { emsStatus 8 } - -emsStatusAlinkProbeDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of remote T/H probes supported by this device." - ::= { emsStatus 9 } - -emsStatusAlarmDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of alarm devices supported by this device." - ::= { emsStatus 10 } - -emsStatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { emsStatus 11 } - -emsStatusCheckLogLight OBJECT-TYPE - SYNTAX INTEGER { - lightOff (1), - lightOn (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the check-log light on the device. - For the EMU2, this will always indicate lightOff(1). - - lightOff (1) indicates the light is off (no new log entries). - lightOn (2) indicates the light is on (new log entries present)." - - ::= { emsStatus 12 } - -emsStatusHardwareStatus OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the EMS hardware. This integer should be interpreted - as a bit map, with each bit representing the presence or absence of - a specific hardware error condition. - - 0 indicates there are no error conditions detected in the EMS hardware. - 1 indicates a Current Limit error condition related to the Alink port. - 2 indicates incorrect hardware is plugged into an EMS port. - 3 indicates that both of these error conditions are present." - - ::= { emsStatus 13 } - --- EMS PROBE STATUS TABLE - -emsProbeStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSProbeStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual probes. The number of - entries is contained in the emsStatusProbeCount OID." - ::= { emsProbeStatus 1 } - -emsProbeStatusEntry OBJECT-TYPE - SYNTAX EMSProbeStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The probes to access." - INDEX { emsProbeStatusProbeIndex } - ::= { emsProbeStatusTable 1 } - -EMSProbeStatusEntry ::= - SEQUENCE { - emsProbeStatusProbeIndex INTEGER, - emsProbeStatusProbeName DisplayString, - emsProbeStatusProbeTemperature INTEGER, - emsProbeStatusProbeHighTempThresh INTEGER, - emsProbeStatusProbeLowTempThresh INTEGER, - emsProbeStatusProbeHumidity INTEGER, - emsProbeStatusProbeHighHumidityThresh INTEGER, - emsProbeStatusProbeLowHumidityThresh INTEGER, - emsProbeStatusProbeSerialNumber DisplayString, - emsProbeStatusProbeCommStatus INTEGER, - emsProbeStatusProbeAlarmStatus INTEGER, - emsProbeStatusProbeMaxTempThresh INTEGER, - emsProbeStatusProbeMinTempThresh INTEGER, - emsProbeStatusProbeMaxHumidityThresh INTEGER, - emsProbeStatusProbeMinHumidityThresh INTEGER - } - -emsProbeStatusProbeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the probe entry." - ::= { emsProbeStatusEntry 1 } - -emsProbeStatusProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the probe." - ::= { emsProbeStatusEntry 2 } - -emsProbeStatusProbeTemperature OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe temperature reading. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 3 } - -emsProbeStatusProbeHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe high temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 4 } - -emsProbeStatusProbeLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe low temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 5 } - -emsProbeStatusProbeHumidity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe humidity reading. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 6 } - -emsProbeStatusProbeHighHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe high humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 7 } - -emsProbeStatusProbeLowHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe low humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 8 } - -emsProbeStatusProbeSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A label indicating the type (Local[L] or Remote[R]) and Number - of the probe. For example, the first local probe would be L1 and - the third remote probe would be R3." - ::= { emsProbeStatusEntry 9 } - -emsProbeStatusProbeCommStatus OBJECT-TYPE - SYNTAX INTEGER { - commsNeverDiscovered(1), - commsEstablished(2), - commsLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - " The state of communications to the probe. - commNeverDiscovered(1) indicates there has never been communications with this device. - commsEstablished(2) indicates communication is normal and active with this device. - commsLost(3) indicates communication had been established, but is no longer." - ::= { emsProbeStatusEntry 10 } - -emsProbeStatusProbeAlarmStatus OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The alarm status of the probe. This integer should be interpreted - as a bit map, with each bit representing the presence or absence of - the specific alarm conditions listed below. The bit will be '1' if - the condition is present, and '0' if the condition is not present. - - Bit Hex. Value Description - 1 0x0001 Maximum temperature exceeded. - 2 0x0002 High temperature exceeded. - 3 0x0004 Low temperature exceeded. - 4 0x0008 Minimum temperature exceeded. - 5 0x0010 Short-term increasing temperature rate exceeded. - 6 0x0020 Short-term decreasing temperature rate exceeded. - 7 0x0040 Long-term increasing temperature rate exceeded. - 8 0x0080 Long-term decreasing temperature rate exceeded. - 9 0x0100 Maximum humidity exceeded. - 10 0x0200 High humidity exceeded. - 11 0x0400 Low humidity exceeded. - 12 0x0800 Minimum humidity exceeded." - ::= { emsProbeStatusEntry 11 } - -emsProbeStatusProbeMaxTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe maximum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 12 } - -emsProbeStatusProbeMinTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe minimum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 13 } - -emsProbeStatusProbeMaxHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe maximum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 14 } - -emsProbeStatusProbeMinHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe minimum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 15 } - - --- EMS INPUT CONTACT STATUS TABLE - -emsInputContactStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSInputContactStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual input contacts. The number of - entries is contained in the emsStatusInputContactCount OID." - ::= { emsInputContactStatus 1 } - -emsInputContactStatusEntry OBJECT-TYPE - SYNTAX EMSInputContactStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input contacts to access." - INDEX { emsInputContactStatusInputContactIndex } - ::= { emsInputContactStatusTable 1 } - -EMSInputContactStatusEntry ::= - SEQUENCE { - emsInputContactStatusInputContactIndex INTEGER, - emsInputContactStatusInputContactName DisplayString, - emsInputContactStatusInputContactState INTEGER, - emsInputContactStatusInputContactNormalState INTEGER - } - -emsInputContactStatusInputContactIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the input contact entry." - ::= { emsInputContactStatusEntry 1 } - -emsInputContactStatusInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the input contact." - ::= { emsInputContactStatusEntry 2 } - -emsInputContactStatusInputContactState OBJECT-TYPE - SYNTAX INTEGER { - contactClosedEMS (1), - contactOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the state of the input contact. If - the input contact is closed, the contactClosedEMS (1) value will be returned. - If the input contact state is open, the contactOpenEMS (2) value will be - returned. " - - ::= { emsInputContactStatusEntry 3 } - -emsInputContactStatusInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the input contact. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is open, the normallyOpenEMS (2) value will be - returned. " - - ::= { emsInputContactStatusEntry 4 } - - --- EMS OUTPUT RELAY STATUS TABLE - -emsOutputRelayStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutputRelayStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual output relays. The number of - entries is contained in the emsStatusOutputRelayCount OID." - ::= { emsOutputRelayStatus 1 } - -emsOutputRelayStatusEntry OBJECT-TYPE - SYNTAX EMSOutputRelayStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relays to access." - INDEX { emsOutputRelayStatusOutputRelayIndex } - ::= { emsOutputRelayStatusTable 1 } - -EMSOutputRelayStatusEntry ::= - SEQUENCE { - emsOutputRelayStatusOutputRelayIndex INTEGER, - emsOutputRelayStatusOutputRelayName DisplayString, - emsOutputRelayStatusOutputRelayState INTEGER, - emsOutputRelayStatusOutputRelayNormalState INTEGER - } - -emsOutputRelayStatusOutputRelayIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the output relay entry." - ::= { emsOutputRelayStatusEntry 1 } - -emsOutputRelayStatusOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the output relay." - ::= { emsOutputRelayStatusEntry 2 } - -emsOutputRelayStatusOutputRelayState OBJECT-TYPE - SYNTAX INTEGER { - relayClosedEMS (1), - relayOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the state of the output relay. If - the output relay is closed, the relayClosedEMS (1) value will be returned. - If the output relay is open, the relayOpenEMS (2) value will be - returned. " - - ::= { emsOutputRelayStatusEntry 3 } - -emsOutputRelayStatusOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the output relay. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is open, the normallyOpenEMS (2) value will be - returned. " - - ::= { emsOutputRelayStatusEntry 4 } - --- EMS OUTLET STATUS TABLE - -emsOutletStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual outlets. The number of - entries is contained in the emsStatusOutletCount OID." - ::= { emsOutletStatus 1 } - -emsOutletStatusEntry OBJECT-TYPE - SYNTAX EMSOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to access." - INDEX { emsOutletStatusOutletIndex } - ::= { emsOutletStatusTable 1 } - -EMSOutletStatusEntry ::= - SEQUENCE { - emsOutletStatusOutletIndex INTEGER, - emsOutletStatusOutletName DisplayString, - emsOutletStatusOutletState INTEGER, - emsOutletStatusOutletNormalState INTEGER - } - -emsOutletStatusOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { emsOutletStatusEntry 1 } - -emsOutletStatusOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet." - ::= { emsOutletStatusEntry 2 } - -emsOutletStatusOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletOnEMS (1), - outletOffEMS (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the state of the outlet. If - the outlet is on, the outletOnEMS (1) value will be returned. - If the outlet is off, the outletOffEMS (2) value will be - returned. " - - ::= { emsOutletStatusEntry 3 } - -emsOutletStatusOutletNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyOnEMS (1), - normallyOffEMS (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the outlet. If - the normal state is on, the normallyOnEMS (1) value will be returned. - If the normal state is off, the normallyOffEMS (2) value will be - returned. " - - ::= { emsOutletStatusEntry 4 } - --- EMS ALARM DEVICE STATUS TABLE - -emsAlarmDeviceStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSAlarmDeviceStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual alarm devices. The number of - entries is contained in the emsStatusAlarmDeviceCount OID." - ::= { emsAlarmDeviceStatus 1 } - -emsAlarmDeviceStatusEntry OBJECT-TYPE - SYNTAX EMSAlarmDeviceStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm devices to access." - INDEX { emsAlarmDeviceStatusDeviceIndex } - ::= { emsAlarmDeviceStatusTable 1 } - -EMSAlarmDeviceStatusEntry ::= - SEQUENCE { - emsAlarmDeviceStatusDeviceIndex INTEGER, - emsAlarmDeviceStatusDeviceName DisplayString, - emsAlarmDeviceStatusDeviceState INTEGER - } - -emsAlarmDeviceStatusDeviceIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the alarm device entry." - ::= { emsAlarmDeviceStatusEntry 1 } - -emsAlarmDeviceStatusDeviceName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the alarm device. - This OID is provided for informational purposes only." - ::= { emsAlarmDeviceStatusEntry 2 } - -emsAlarmDeviceStatusDeviceState OBJECT-TYPE - SYNTAX INTEGER { - alarmDeviceOnEMS (1), - alarmDeviceOffEMS (2), - alarmDeviceNotInstalledEMS (3) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the device state. If - the device is active, the alarmDeviceOnEMS (1) value will be returned. - If the device is inactive, the alarmDeviceOffEMS (2) value will be - returned. If the device is not installed, the - alarmDeviceNotInstalledEMS (3) value will be returned." - - ::= { emsAlarmDeviceStatusEntry 3 } - - --- EMS SENSOR STATUS TABLE - -emsSensorStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSSensorStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual sensors. The number of - entries is contained in the emsStatusSensorCount OID." - ::= { emsSensorStatus 1 } - -emsSensorStatusEntry OBJECT-TYPE - SYNTAX EMSSensorStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The sensors to access." - INDEX { emsSensorStatusSensorIndex } - ::= { emsSensorStatusTable 1 } - -EMSSensorStatusEntry ::= - SEQUENCE { - emsSensorStatusSensorIndex INTEGER, - emsSensorStatusSensorSystemName DisplayString, - emsSensorStatusSensorName DisplayString, - emsSensorStatusSensorState INTEGER, - emsSensorStatusSensorNormalState INTEGER, - emsSensorStatusSensorAlarmDelay INTEGER - } - -emsSensorStatusSensorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the sensor entry." - ::= { emsSensorStatusEntry 1 } - -emsSensorStatusSensorSystemName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system name of the sensor. This describes the hardware system - intent of this sensor." - ::= { emsSensorStatusEntry 2 } - -emsSensorStatusSensorName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the sensor as given by the system user." - ::= { emsSensorStatusEntry 3 } - -emsSensorStatusSensorState OBJECT-TYPE - SYNTAX INTEGER { - sensorFaultedEMS (1), - sensorOKEMS (2), - sensorNotInstalledEMS (3) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the sensor state. If the sensor is faulted, - the sensorFaultedEMS (1) value will be returned. - If the sensor is not faulted, the sensorOKEMS (2) value will be - returned. If the sensor is not installed, the sensorNotInstalledEMS (3) - value will be returned." - ::= { emsSensorStatusEntry 4 } - -emsSensorStatusSensorNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the sensor. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned." - ::= { emsSensorStatusEntry 5 } - -emsSensorStatusSensorAlarmDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The delay (in seconds) after a sensor detects an alarm condition before the - condition is reported." - ::= { emsSensorStatusEntry 6 } - - - --- airFM AIR CONDITIONER IDENT - -airFMIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { airFMIdent 1 } - -airFMIdentTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the airFMIdentTable. " - ::= { airFMIdent 2 } - -airFMIdentTable OBJECT-TYPE - SYNTAX SEQUENCE OF AirFMIdentTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting identification information - from each module in the system. " - ::= { airFMIdent 3 } - -airFMIdentTableEntry OBJECT-TYPE - SYNTAX AirFMIdentTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The module to get information from." - INDEX { airFMIdentModuleIndex } - ::= { airFMIdentTable 1 } - -AirFMIdentTableEntry ::= - SEQUENCE { - airFMIdentModuleIndex INTEGER, - airFMIdentModuleModelNumber DisplayString, - airFMIdentModuleDateOfMfg DisplayString, - airFMIdentModuleSerialNumber DisplayString, - airFMIdentModuleFirmwareRev DisplayString, - airFMIdentModuleHardwareRev DisplayString - } - -airFMIdentModuleIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the module information." - ::= { airFMIdentTableEntry 1 } - -airFMIdentModuleModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - model number. " - ::= { airFMIdentTableEntry 2 } - -airFMIdentModuleDateOfMfg OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - manufacture date. " - ::= { airFMIdentTableEntry 3 } - -airFMIdentModuleSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - unit serial number. " - ::= { airFMIdentTableEntry 4 } - -airFMIdentModuleFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - firmware revision. " - ::= { airFMIdentTableEntry 5 } - -airFMIdentModuleHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - hardware revision. " - ::= { airFMIdentTableEntry 6 } - --- airFM AIR CONDITIONER STATUS - -airFMStatusSystemOn OBJECT-TYPE - SYNTAX INTEGER { - statusOn (1), - statusOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The operating state of the system. " - ::= { airFMStatus 1 } - -airFMStatusSystemAverageRetTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system average return air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 2 } - -airFMStatusSystemAverageRetTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system average return air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 3 } - -airFMStatusSystemAverageRetHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system average return air - humidity. " - ::= { airFMStatus 4 } - -airFMStatusSystemActionTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system action air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 5 } - -airFMStatusSystemActionTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system action air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 6 } - -airFMStatusSystemActionHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system action air humidity. " - ::= { airFMStatus 7 } - -airFMStatusSystemRemoteHighTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote high air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 8 } - -airFMStatusSystemRemoteHighTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote high air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 9 } - -airFMStatusSystemRemoteAvgTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote average air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 10 } - -airFMStatusSystemRemoteAvgTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote average air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 11 } - -airFMStatusSystemRemoteAvgHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote average air - humidity. " - ::= { airFMStatus 12 } - -airFMStatusSystemRemoteLowTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote low air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 13 } - -airFMStatusSystemRemoteLowTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote low air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 14 } - -airFMStatusSystemCoolingEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system cooling - function enable. " - ::= { airFMStatus 15 } - -airFMStatusSystemReheatingEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system reheating - function enable. " - ::= { airFMStatus 16 } - -airFMStatusSystemHumidifyEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system humidify - function enable. " - ::= { airFMStatus 17 } - -airFMStatusSystemDehumidifyEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system dehumidify - function enable. " - ::= { airFMStatus 18 } - -airFMStatusModuleTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the airFMStatusModuleTable. " - ::= { airFMStatus 19 } - -airFMStatusModuleTable OBJECT-TYPE - SYNTAX SEQUENCE OF AirFMStatusModuleEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each module - in the system. " - ::= { airFMStatus 20 } - -airFMStatusModuleEntry OBJECT-TYPE - SYNTAX AirFMStatusModuleEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The module to get status from." - INDEX { airFMStatusModuleIndex } - ::= { airFMStatusModuleTable 1 } - -AirFMStatusModuleEntry ::= - SEQUENCE { - airFMStatusModuleIndex INTEGER, - airFMStatusModuleOutputCapacity INTEGER, - airFMStatusModuleSupplyTempC INTEGER, - airFMStatusModuleSupplyTempF INTEGER, - airFMStatusModuleSupplyHum INTEGER, - airFMStatusModuleReturnTempC INTEGER, - airFMStatusModuleReturnTempF INTEGER, - airFMStatusModuleReturnHum INTEGER - } - -airFMStatusModuleIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the module information." - ::= { airFMStatusModuleEntry 1 } - -airFMStatusModuleOutputCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module output capacity in kilowatts." - ::= { airFMStatusModuleEntry 2 } - -airFMStatusModuleSupplyTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module supply air temperature in - tenths of degrees Celsius. " - ::= { airFMStatusModuleEntry 3 } - -airFMStatusModuleSupplyTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module supply air temperature in - tenths of degrees Fahrenheit. " - ::= { airFMStatusModuleEntry 4 } - -airFMStatusModuleSupplyHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module supply air humidity. " - ::= { airFMStatusModuleEntry 5 } - -airFMStatusModuleReturnTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module return air temperature in - tenths of degrees Celsius. " - ::= { airFMStatusModuleEntry 6 } - -airFMStatusModuleReturnTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module return air temperature in - tenths of degrees Fahrenheit. " - ::= { airFMStatusModuleEntry 7 } - -airFMStatusModuleReturnHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module return air humidity. " - ::= { airFMStatusModuleEntry 8 } - --- airFM AIR CONDITIONER GROUP DATA - -airFMGroupSysStatus OBJECT-TYPE - SYNTAX INTEGER { - statusOnLine (1), - statusIdle (2), - statusLoadShare (3), - statusOffLine (4), - statusFailed (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of this system within the group. " - ::= { airFMGroup 1 } - -airFMGroupSysRuntime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of hours the system has been running. " - ::= { airFMGroup 2 } - -airFMGroupSysRole OBJECT-TYPE - SYNTAX INTEGER { - rolePrimary (1), - roleBackup (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The role of this system within the group. " - ::= { airFMGroup 3 } - --- airPA Portable Air Conditioner Ident - -airPAIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device name. " - ::= { airPAIdent 1 } - -airPAModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device model number. " - ::= { airPAIdent 2 } - -airPADateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying when the device was produced. " - ::= { airPAIdent 3 } - -airPASerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device serial number. " - ::= { airPAIdent 4 } - -airPAFirmwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device firmware revision. " - ::= { airPAIdent 5 } - -airPAHardwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device hardware revision. " - ::= { airPAIdent 6 } - --- airPA Portable Air Conditioner Status - -airPASystemPower OBJECT-TYPE - SYNTAX INTEGER { - powerON (1), - powerOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the unit's system power setting. - - ON(1) The system power is turned on. - OFF(2) The system power is turned off. " - ::= { airPAStatus 1 } - -airPAOperatingMode OBJECT-TYPE - SYNTAX INTEGER { - modeOFF (1), - modeVENTING (2), - modeCOOLING (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current operating mode of the unit. - - OFF(1) The system is off. - VENTING(2) The system's venting function is active. - COOLING(3) The system's cooling function is active. " - ::= { airPAStatus 2 } - -airPASetpointTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature setpoint in Fahrenheit to which the unit is controlling. " - ::= { airPAStatus 3 } - -airPASetpointTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature setpoint in Celsius to which the unity is controlling. " - ::= { airPAStatus 4 } - -airPABlowerSpeed OBJECT-TYPE - SYNTAX INTEGER { - speedLOW (1), - speedHIGH (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's blower speed setting. - - LOW(1) The blower speed is low. - HIGH(2) The blower speed is high. " - ::= { airPAStatus 5 } - -airPACompressor OBJECT-TYPE - SYNTAX INTEGER { - statusON (1), - statusOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's compressor status. - - ON(1) The compressor is turned on. - OFF(2) The compressor is turned off. " - ::= { airPAStatus 6 } - -airPACondenserFan OBJECT-TYPE - SYNTAX INTEGER { - statusON (1), - statusOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's condenser fan status. - - ON(1) The condenser fan is turned on. - OFF(2) The condenser fan is turned off. " - ::= { airPAStatus 7 } - -airPACondensatePump OBJECT-TYPE - SYNTAX INTEGER { - statusON (1), - statusOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's condensate pump status. - - ON(1) The condensate pump is turned on. - OFF(2) The condensate pump is turned off. " - ::= { airPAStatus 8 } - -airPASupplyTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The supply temperature in degrees Fahrenheit. " - ::= { airPAStatus 9 } - -airPASupplyTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The supply temperature in degrees Celsius. " - ::= { airPAStatus 10 } - -airPAReturnTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The return temperature in degrees Fahrenheit. " - ::= { airPAStatus 11 } - -airPAReturnTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The return temperature in degrees Celsius. " - ::= { airPAStatus 12 } - -airPARemoteTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remote temperature in degrees Fahrenheit. " - ::= { airPAStatus 13 } - -airPARemoteTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remote temperature in degrees Celsius. " - ::= { airPAStatus 14 } - -airPARemoteHumidity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remote humidity. " - ::= { airPAStatus 15 } - --- RACK AIR REMOVAL UNIT IDENT - -rARUIdentTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for query of the individual devices. - The number of entries is contained in the - rARUStatusAruDeviceCount OID." - ::= { rARUIdent 1 } - -rARUIdentEntry OBJECT-TYPE - SYNTAX IdentRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The device to query." - INDEX { rARUIdentIndex} - ::= { rARUIdentTable 1 } - -IdentRARUEntry ::= - SEQUENCE { - rARUIdentIndex INTEGER, - rARUIdentName DisplayString - } - -rARUIdentIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the device entry." - ::= { rARUIdentEntry 1 } - -rARUIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { rARUIdentEntry 2 } - - --- RACK AIR REMOVAL UNIT CONFIGURATION - -rARUConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual ARUs. The number of - entries is contained in the rARUStatusAruDeviceCount OID." - ::= { rARUConfig 1 } - -rARUConfigEntry OBJECT-TYPE - SYNTAX ConfigRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The ARUs to configure." - INDEX { rARUConfigAruIndex } - ::= { rARUConfigTable 1 } - -ConfigRARUEntry ::= - SEQUENCE { - rARUConfigAruIndex INTEGER, - rARUConfigAruName DisplayString, - rARUConfigAruRemoteSetpoint INTEGER, - rARUConfigAruTempOvrdEnableDisable INTEGER, - rARUConfigAruTempOvrdSetpoint INTEGER - } - -rARUConfigAruIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the device entry." - ::= { rARUConfigEntry 1 } - -rARUConfigAruName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the ARU." - ::= { rARUConfigEntry 2 } - -rARUConfigAruRemoteSetpoint OBJECT-TYPE - SYNTAX INTEGER { - aruOff (1), - aru85F-29C (2), - aru90F-32C (3), - aru95F-35C (4), - aru100F-38C (5), - aru7kW (6), - aru5kW (7), - aru3kW (8), - aru2kW (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is the Remote setpoint of the ARU. - NOTE: -1 will be returned if the ARU is not communicating." - - ::= { rARUConfigEntry 3 } - -rARUConfigAruTempOvrdEnableDisable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is used to enable/disable the remote temperature override setting of the ARU. - - If this OID is set to 1, the remote setting for temperature override is disabled. - If this OID is set to 2, the remote setting for temperature override is enabled." - ::= { rARUConfigEntry 4 } - -rARUConfigAruTempOvrdSetpoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is the Temperature Override setpoint of the ARU. - NOTE: -1 will be returned if the ARU is not communicating." - - ::= { rARUConfigEntry 5 } - --- RACK AIR REMOVAL UNIT STATUS - -rARUStatusAruDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of ARUs accessible from this IP." - ::= { rARUStatus 1 } - -rARUStatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { rARUStatus 2 } - -rARUStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual ARUs. The number of - entries is contained in the rARUStatusAruDeviceCount OID." - ::= { rARUStatus 3 } - -rARUStatusEntry OBJECT-TYPE - SYNTAX StatusRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The ARUs to access." - INDEX { rARUStatusAruIndex } - ::= { rARUStatusTable 1 } - -StatusRARUEntry ::= - SEQUENCE { - rARUStatusAruIndex INTEGER, - rARUStatusAruName DisplayString, - rARUStatusAruRemoteSetpoint INTEGER, - rARUStatusAruManualSetpoint INTEGER, - rARUStatusAruTemp1 INTEGER, - rARUStatusAruTemp2 INTEGER, - rARUStatusAruTemp3 INTEGER, - rARUStatusAruTempOvrdEnableDisable INTEGER, - rARUStatusAruTempOvrdSetpoint INTEGER, - rARUStatusAruAlarmState DisplayString, - rARUStatusAruCommStatus INTEGER - } - -rARUStatusAruIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the ARU entry." - ::= { rARUStatusEntry 1 } - -rARUStatusAruName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the ARU." - ::= { rARUStatusEntry 2 } - -rARUStatusAruRemoteSetpoint OBJECT-TYPE - SYNTAX INTEGER { - aruOff (1), - aru85F-29C (2), - aru90F-32C (3), - aru95F-35C (4), - aru100F-38C (5), - aru7kW (6), - aru5kW (7), - aru3kW (8), - aru2kW (9) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU remote setpoint temperature setting. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 3 } - -rARUStatusAruManualSetpoint OBJECT-TYPE - SYNTAX INTEGER { - aruOff (1), - aru85F-29C (2), - aru90F-32C (3), - aru95F-35C (4), - aru100F-38C (5), - aru7kW (6), - aru5kW (7), - aru3kW (8), - aru2kW (9), - aruRem (10) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU manual setpoint temperature setting. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - If the manual setpoint is set to Remote, this OID will return 0. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 4 } - -rARUStatusAruTemp1 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU temperature probe #1 reading. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 5 } - -rARUStatusAruTemp2 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU temperature probe #2 reading. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 6 } - -rARUStatusAruTemp3 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU temperature probe #3 reading. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 7 } - -rARUStatusAruTempOvrdEnableDisable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID indicates whether the ARU remote temperature override is enabled or disabled. - If this OID is a 1, the remote setting for temperature override is disabled. - If this OID is a 2, the remote setting for temperature override is enabled." - ::= { rARUStatusEntry 8 } - -rARUStatusAruTempOvrdSetpoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU remote temperature override setpoint setting. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 9 } - -rARUStatusAruAlarmState OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 8 flags representing - the current alarm state of the ARU. If the state of - the ARU is unknown, this variable is set to �UNKNOWN�. - - The flags are numbered 1 to 8, read from left to - right. The flags are defined as follows: - - Flag 1: Fan Fail 1 - Flag 2: Fan Fail 2 - Flag 3: Fan Fail 3 - Flag 4: Smoke - - Flag 5: High Temp (Out of Thermal Control) - Flag 6: Over Temp (Exhaust Temp. Exceeds Override Setpoint) - Flag 7: Reserved - Flag 8: Reserved" - ::= { rARUStatusEntry 10 } - -rARUStatusAruCommStatus OBJECT-TYPE - SYNTAX INTEGER { - commsNeverDiscovered(1), - commsEstablished(2), - commsLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of communications to the device. - commNeverDiscovered(1) indicates there has never been communications with this device. - commsEstablished(2) indicates communication is normal and active with this device. - commsLost(3) indicates communication had been established, but is no device." - ::= { rARUStatusEntry 11 } - --- Traps --- Annotations are provided for Novell's NMS product --- --- Each trap has at least one variable (mtrapargsString) which always appears --- as the last variable in the list. This variable contains either a static --- or dynamically-constructed string which provides an enhanced description of --- the trap's purpose and any pertinent information about the trap. - -communicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communication to the UPS has been lost. Steps - to reestablish communication are in progress." - --#TYPE "APC UPS: Communication lost" - --#SUMMARY "Communication lost between the agent and the UPS." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 1 - -upsOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS has sensed a load greater than 100 percent - of its rated capacity." - --#TYPE "APC UPS: Overload" - --#SUMMARY "The UPS has sensed a load greater than 100 percent of its rated capacity." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 2 - -upsDiagnosticsFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS failed its internal diagnostic self-test." - --#TYPE "APC UPS: Failed self-test" - --#SUMMARY "The UPS has failed its internal self-test." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 3 - -upsDischarged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS batteries are discharged; if utility power fails - an immediate low battery condition will exist. Sufficient runtime - for necessary action cannot be guaranteed." - --#TYPE "APC UPS: batteries are discharged" - --#SUMMARY "The UPS batteries are discharged." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 4 - -upsOnBattery TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has switched to battery backup power." - --#TYPE "APC UPS: On battery" - --#SUMMARY "The UPS has switched to battery backup power." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 5 - -smartBoostOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has enabled SmartBoost(TM)." - --#TYPE "APC UPS: SmartBoost(TM)" - --#SUMMARY "The UPS has enabled SmartBoost(TM); low incoming line voltage." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 6 - -lowBattery TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS batteries are low and will soon be exhausted. - If utility power is not restored the UPS will put itself - to 'sleep' and immediately cut power to the load." - --#TYPE "APC UPS: Low battery" - --#SUMMARY "The UPS system's batteries are low and will soon be exhausted." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 7 - -communicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication with the UPS has been established." - --#TYPE "APC UPS: Communication established" - --#SUMMARY "UPS communication has been established." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 8 - -powerRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Utility power has been restored." - --#TYPE "APC UPS: Utility power restored" - --#SUMMARY "Returned from battery backup power; utility power restored." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 9 - -upsDiagnosticsPassed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS passed its internal self-test." - --#TYPE "APC UPS: Passed self-test" - --#SUMMARY "The UPS passed internal self-test." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 10 - -returnFromLowBattery TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has returned from a low battery - condition." - --#TYPE "APC UPS: Returned from Low-Battery condition" - --#SUMMARY "The UPS has returned from a Low-Battery condition." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 11 - -upsTurnedOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has been turned 'off' by the management station." - --#TYPE "APC UPS: Turned off" - --#SUMMARY "The UPS has been switched off by a management station." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 12 - -upsSleeping TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS is entering 'sleep' mode. Power - to the load will be cut off." - --#TYPE "APC UPS: Entered sleep mode" - --#SUMMARY "The UPS entered sleep mode. Power to the load will be cut off." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 13 - -upsWokeUp TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATION: The UPS has returned from 'sleep' mode. Power - to the load has been restored." - --#TYPE "APC UPS: Wake up" - --#SUMMARY "The UPS has returned from sleep mode. Power to the load has been restored." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 14 - -upsRebootStarted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has started its reboot sequence. - The UPS will reboot itself at this time." - --#TYPE "APC UPS: Starting reboot" - --#SUMMARY "The UPS has started its reboot sequence." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 15 - -upsDipSwitchChanged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The dip switch settings on the UPS have been - changed, possibly altering UPS performance." - --#TYPE "APC UPS: DIP switch altered" - --#SUMMARY "The DIP switch settings on the UPS have been changed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 16 - -upsBatteryNeedsReplacement TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The batteries of the UPS need immediate replacement." - --#TYPE "APC UPS: UPS batteries need replacement" - --#SUMMARY "The UPS batteries require immediate replacement." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 17 - - --- the Environmental Monitor traps - -contactFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: One of the contacts on the Environmental Monitor has - changed from its default position. The first variable is - the contact number that is faulted." - --#TYPE "APC Environment: Contact fault" - --#SUMMARY "An Environment contact closure has faulted." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 18 - -contactFaultResolved TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A fault on one of the Environmental Monitor contacts - has been resolved. The first variable is - the contact number that has been resolved." - --#TYPE "APC Environment: Contact fault cleared." - --#SUMMARY "A Environment contact closure has returned to it's default state." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 19 - --- the Matrix-UPS traps - -hardwareFailureBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: UPS on bypass due to internal fault" - --#TYPE "APC UPS: On bypass due to internal fault" - --#SUMMARY "The UPS is on bypass due to an internal fault." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 20 - -softwareBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: UPS on bypass - user set via software or panel" - --#TYPE "APC UPS: On bypass by user via software or panel" - --#SUMMARY "UPS put on bypass by user via software or front UPS panel." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 21 - -switchedBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: UPS on bypass - initiated by user" - --#TYPE "APC UPS: On bypass initiated by user" - --#SUMMARY "UPS put on bypass by user." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 22 - -returnFromBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: UPS has returned from bypass" - --#TYPE "APC UPS: UPS has returned from bypass" - --#SUMMARY "The UPS has returned from bypass mode." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 23 - -bypassPowerSupplyFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Base module bypass power supply needs repair" - --#TYPE "APC UPS: Base module bypass power supply needs repair" - --#SUMMARY "The base module bypass power supply needs repair." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 24 - -baseFanFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Base module fan needs repair" - --#TYPE "APC UPS: Base module fan needs repair" - --#SUMMARY "The base module fan needs repair." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 25 - -batteryPackCommLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Check installation of external battery packs signal cable" - --#TYPE "APC UPS: Communication lost with battery packs" - --#SUMMARY "Communication lost with external battery packs, check battery signal cable." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 26 - -batteryPackCommEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: UPS is communicating with the external battery packs." - --#TYPE "APC UPS: Communication established with battery packs" - --#SUMMARY "Communication established with external battery packs." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 27 - -calibrationStart TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A battery calibration test has been initiated on the UPS." - --#TYPE "APC UPS: Calibration initiated" - --#SUMMARY "A battery run time calibration test has been initiated." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 28 - --- Misc. Traps - -restartAgent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Agent restarting as commanded by manager." - --#TYPE "APC SNMP Agent: Agent restarting" - --#SUMMARY "Agent restarting as commanded by manager." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 29 - -upsTurnedOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A UPS is turned on." - --#TYPE "APC UPS: A UPS is turned on." - --#SUMMARY " A UPS is turned on." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 30 - -smartAvrReducing TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS is reducing the line voltage via SmartTrim(TM)." - --#TYPE "APC UPS: SmartTrim(TM) reducing" - --#SUMMARY "The UPS has enabled SmartTrim(TM) voltage reduction." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 31 - -codeAuthenticationDone TRAP-TYPE - ENTERPRISE apc - VARIABLES { mconfigTFTPServerIP, newCodeAuthentViaTFTP } - DESCRIPTION - "INFORMATIONAL: Authentication on agent code image is done." - --#TYPE "APC CODE: Authentication on agent code image is done." - --#SUMMARY "Authentication on agent code image is done." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 32 - -upsOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The overload condition has been cleared." - --#TYPE "APC UPS: Overload cleared." - --#SUMMARY "The overload condition has been cleared. ." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 33 - -smartBoostOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has returned from SmartBoost(TM)." - --#TYPE "APC UPS: SmartBoost(TM) off." - --#SUMMARY "The UPS has returned from SmartBoost(TM)." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 34 - -smartAvrReducingOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has returned from SmartTrim(TM)." - --#TYPE "APC UPS: SmartTrim(TM) reducing off" - --#SUMMARY "The UPS has returned from SmartTrim(TM) voltage reduction." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 35 - -upsBatteryReplaced TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A bad battery fault has been cleared." - --#TYPE "APC UPS: Bad battery replaced" - --#SUMMARY "The UPS has returned from a bad battery fault." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 36 - -calibrationEnd TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has finished calibrating." - --#TYPE "APC UPS: Calibration end" - --#SUMMARY "The UPS has finished calibrating" - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 37 - -dischargeCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A UPS discharge condition has been cleared." - --#TYPE "APC UPS: Discharge cleared." - --#SUMMARY "The UPS discharge condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 38 - -gracefullShutdown TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A graceful shutdown has been initiated." - --#TYPE "APC UPS: A graceful shutdown has been initiated." - --#SUMMARY "A graceful shutdown has been initiated." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 39 - - -outletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletControlIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has turned on. - If sPDUOutletControlIndex equals zero, then all outlets have - turned on." - --#TYPE "APC PDU: Outlet has been turned on." - --#SUMMARY "Outlet has been turned on" - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 41 - - -outletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletControlIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has turned off. - If sPDUOutletControlIndex equals zero, then all outlets - have turned off." - --#TYPE "APC PDU: Outlet has turned off." - --#SUMMARY "Outlet has turned off." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 42 - -outletReboot TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletControlIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has rebooted. - If sPDUOutletControlIndex equals zero, then all outlets - have rebooted." - --#TYPE "APC PDU: Outlet has rebooted." - --#SUMMARY "Outlet has rebooted." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 43 - -configChangeSNMP TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The SNMP configuration has been changed." - --#TYPE "APC: The SNMP configuration has been changed." - --#SUMMARY "The SNMP configuration has been changed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 44 - - -configChangeOutlet TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletConfigIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has changed configuration. - If sPDUOutletConfigIndex equals zero, then the Master outlet - has changed configuration." - --#TYPE "APC PDU: Outlet configuration has been changed." - --#SUMMARY "Outlet configuration has been changed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 45 - -accessViolationConsole TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Someone has attempted to login via the console with the incorrect password." - --#TYPE "APC: Access violation via the console." - --#SUMMARY "Three unsuccessful logins have been attempted via the console." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 46 - -accessViolationHTTP TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Someone has attempted to login via HTTP with the incorrect password." - --#TYPE "APC: Access violation via HTTP." - --#SUMMARY "An unsuccessful attempt to login via HTTP." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 47 - -passwordChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The password for the device has been changed." - --#TYPE "APC: Password change for the device." - --#SUMMARY "Someone has changed the password on the device." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 48 - -badVoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The output voltage is not within acceptable range." - --#TYPE "APC UPS: Bad output voltage." - --#SUMMARY "The output voltage is not within acceptable range." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 49 - -badVoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The output voltage has returned to an acceptable level." - --#TYPE "APC UPS: The bad voltage output condition has been cleared." - --#SUMMARY "The output voltage has returned to an acceptable level." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 50 - -chargerFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The battery charger has failed." - --#TYPE "APC UPS: The battery charger has failed." - --#SUMMARY "The battery charger has failed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 51 - -chargerFailureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The battery charger failure condition has been cleared." - --#TYPE "APC UPS: The battery charger failure condition cleared" - --#SUMMARY "The battery charger failure condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 52 - -batteryOverTemperature TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The battery temperature threshold has been violated." - --#TYPE "APC UPS: The battery temperature threshold has been violated." - --#SUMMARY "The battery temperature threshold has been violated." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 53 - -batteryOverTemperatureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The battery over temperature has been cleared." - --#TYPE "APC UPS: The battery over temperature has been cleared." - --#SUMMARY "The battery over temperature has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 54 - - smartRelayFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: SmartBoost(TM) or SmartTrim(TM) relay fault." - --#TYPE "APC UPS: SmartBoost(TM) or SmartTrim(TM) relay fault." - --#SUMMARY "SmartBoost(TM) or SmartTrim(TM) relay fault." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 55 - -smartRelayFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: SmartBoost(TM) or SmartTrim(TM) relay fault has been cleared." - --#TYPE "APC UPS: SmartBoost(TM) or SmartTrim(TM) relay fault cleared." - --#SUMMARY "SmartBoost(TM) or SmartTrim(TM) relay fault has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 56 - -humidityThresholdViolation1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Probe 1 humidity threshold violated. The - first variable is the current humidity." - --#TYPE "APC Environmental Monitor: Probe 1 humidity threshold violation" - --#SUMMARY "A humidity threshold has been violated on probe 1." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 57 - -humidityThresholdViolationCleared1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor humidity threshold violation has been cleared on probe 1." - --#TYPE "APC Environmental Monitor: Probe 1 humidity violation cleared" - --#SUMMARY "A humidity threshold violation has been cleared on probe 1." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 58 - -temperatureThresholdViolation1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Environmental Monitor temperature threshold has been violated on probe 1. - The first variable is the current temperature." - --#TYPE "APC Environmental Monitor: Probe 1 temperature violation" - --#SUMMARY "A temperature threshold has been violated on probe 1." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 59 - -temperatureThresholdViolationCleared1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor temperature threshold violation has been cleared on probe 1." - --#TYPE "APC Environmental Monitor: Probe 1 temperature violation cleared" - --#SUMMARY "A temperature threshold violation has been cleared on probe 1." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 60 - -humidityThresholdViolation2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Environmental Monitor humidity threshold has been violated on probe 2. - The first variable is the current humidity." - --#TYPE "APC Environmental Monitor: Probe 2 humidity violation" - --#SUMMARY "A humidity threshold has been violated on probe 2." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 61 - -humidityThresholdViolationCleared2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor humidity threshold violation has been cleared on probe 2." - --#TYPE "APC Environmental Monitor: Probe 2 humidity violation cleared" - --#SUMMARY "A humidity threshold violation has been cleared on probe 2." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 62 - -temperatureThresholdViolation2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Environmental Monitor temperature threshold has been violated on probe 2. - The first variable is the current temperature." - --#TYPE "APC Environmental Monitor: Probe 2 temperature violation" - --#SUMMARY "A temperature threshold has been violated on probe 2." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 63 - -temperatureThresholdViolationCleared2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor temperature threshold violation has been cleared on probe 2." - --#TYPE "APC Environmental Monitor: Probe 2 temperature violation cleared" - --#SUMMARY "A temperature threshold violation has been cleared on probe 2." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 64 - -mupsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication with the Environmental Monitor has been established." - --#TYPE "APC Environmental Monitor: Communication established" - --#SUMMARY "Communication established between the agent and the Environmental Monitor." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 65 - -mupsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communication to the Environmental Monitor has been lost. Steps - to reestablish communication are in progress." - --#TYPE "APC Environmental Monitor: Communication failure" - --#SUMMARY "Communication lost between the agent and the Environmental Monitor." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 66 - -batteryIncrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of batteries has increased." - --#TYPE "APC UPS: The number of batteries has increased." - --#SUMMARY "The number of batteries has increased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 67 - -batteryDecrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of batteries has decreased." - --#TYPE "APC UPS: The number of batteries has decreased." - --#SUMMARY "The number of batteries has decreased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 68 - -powerModuleIncrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of power modules has increased." - --#TYPE "APC UPS: The number of power modules has increased." - --#SUMMARY "The number of power modules has increased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 69 - -powerModuleDecrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of power modules has decreased." - --#TYPE "APC UPS: The number of power modules has decreased." - --#SUMMARY "The number of power modules has decreased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 70 - -intelligenceModuleInserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An intelligence module has been inserted." - --#TYPE "APC UPS: An intelligence module has been inserted." - --#SUMMARY "An intelligence module has been inserted." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 71 - -intelligenceModuleRemoved TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An intelligence module has been removed." - --#TYPE "APC UPS: An intelligence module has been removed." - --#SUMMARY "An intelligence module has been removed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 72 - -rintelligenceModuleInserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A redundant intelligence module has been inserted." - --#TYPE "APC UPS: A redundant intelligence module has been inserted." - --#SUMMARY "A redundant intelligence module has been inserted." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 73 - -rintelligenceModuleRemoved TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A redundant intelligence module has been removed." - --#TYPE "APC UPS: A redundant intelligence module has been removed." - --#SUMMARY "A redundant intelligence module has been removed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 74 - -extBatteryFrameIncease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An external battery frame has been added." - --#TYPE "APC UPS: An external battery frame has been added." - --#SUMMARY "An external battery frame has been added." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 75 - -extBatteryFrameDecrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An external battery frame has been removed." - --#TYPE "APC UPS: An external battery frame has been removed." - --#SUMMARY "An external battery frame has been removed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 76 - -abnormalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An abnormal condition has been detected. - The first variable is the fault condition." - --#TYPE "APC: An abnormal condition has been detected." - --#SUMMARY "An abnormal condition has been detected." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 77 - -abnormalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An abnormal condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC: An abnormal condition has been cleared." - --#SUMMARY "An abnormal condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 78 - -deviceStatusChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString} - DESCRIPTION - "INFORMATIONAL: The status of the device being monitored has changed." - --#TYPE "APC : The status of the device being monitored has changed." - --#SUMMARY "The status of the device being monitored has changed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 79 - -noBatteries TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has no batteries attached." - --#TYPE "APC UPS: No batteries attached." - --#SUMMARY "The UPS has no batteries attached." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 80 - -noBatteriesCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS's batteries have been attached." - --#TYPE "APC UPS: The no batteries attached condition has been cleared." - --#SUMMARY "The UPS's batteries have been attached." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 81 - -userAdded TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A new user has been added." - --#TYPE "APC: A new user has been added." - --#SUMMARY "A new user has been added." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 82 - -userDeleted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user has been deleted." - --#TYPE "APC: A user has been deleted." - --#SUMMARY "A user has been deleted." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 83 - -userModified TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user has been modified." - --#TYPE "APC: A user has been modified." - --#SUMMARY "A user has been modified." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 84 - --- MasterSwitch Vm Traps - -msvmCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the MasterSwitch VM has been established." - --#TYPE "APC: Communications established with the MasterSwitch VM." - --#SUMMARY "Communications with the MasterSwitch VM has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 85 - -msvmCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the MasterSwitch VM has been lost." - --#TYPE "APC: Communications lost with the MasterSwitch VM." - --#SUMMARY "Communications with the MasterSwitch VM has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 86 - -msvmOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "SEVERE: The MasterSwitch VM in an overload condition." - --#TYPE "APC: The MasterSwitch VM is near or at an overload condition." - --#SUMMARY "The MasterSwitch VM is near or at an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 87 - -msvmOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The overload condition on the MasterSwitch VM has been cleared." - --#TYPE "APC: The overload condition cleared on the MasterSwitch VM." - --#SUMMARY "The overload condition on the MasterSwitch VM has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 88 - -msvmOutletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, - sPDUOutletControlVMOutletIndex, sPDUOutletControlVMOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch VM has turned on." - --#TYPE "APC: An outlet on the MasterSwitch VM has turned on." - --#SUMMARY "An outlet on the MasterSwitch VM has turned on." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 89 - -msvmOutletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, - sPDUOutletControlVMOutletIndex, sPDUOutletControlVMOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch VM has turned off." - --#TYPE "APC: An outlet on the MasterSwitch VM has turned off." - --#SUMMARY "An outlet on the MasterSwitch VM has turned off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 90 - -msvmDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on a MasterSwitch VM." - --#TYPE "APC: A device configuration change on a MasterSwitch VM." - --#SUMMARY "A device configuration change has been made on a MasterSwitch VM." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 91 - -msvmOutletConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, - sPDUOutletControlVMOutletIndex, sPDUOutletControlVMOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet configuration change has been made on a MasterSwitch VM." - --#TYPE "APC: An outlet configuration change on a MasterSwitch VM." - --#SUMMARY "An outlet configuration change has been made on a MasterSwitch VM." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 92 - -msvmLowLoad TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The MasterSwitch VM has violated the low load threshold." - --#TYPE "APC: The MasterSwitch VM has violated the low load threshold." - --#SUMMARY "The MasterSwitch VM has violated the low load threshold." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 93 - -msvmLowLoadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The low load condition on the MasterSwitch VM has been cleared." - --#TYPE "APC: The low load condition cleared on the MasterSwitch VM." - --#SUMMARY "The low load condition on the MasterSwitch VM has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 94 - -msvmNearOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "SEVERE: The MasterSwitch VM is approaching an overload condition." - --#TYPE "APC: The MasterSwitch VM is near or at an overload condition." - --#SUMMARY "The MasterSwitch VM is near or at an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 95 - -msvmNearOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The near overload condition on the MasterSwitch VM has been cleared." - --#TYPE "APC: The overload condition cleared on the MasterSwitch VM." - --#SUMMARY "The overload condition on the MasterSwitch VM has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 96 - -msvmPowerSupplyStatusChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The power supply status of the MasterSwitch VM has changed." - --#TYPE "APC: The power supply status changed on MasterSwitch VM" - --#SUMMARY "The power supply status of the MasterSwitch VM has changed." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 97 - --- MasterSwitch plus (MSP) Traps - -mspCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the MasterSwitch plus has been established." - --#TYPE "APC: Communications established with the MasterSwitch plus." - --#SUMMARY "Communications with the MasterSwitch plus has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 98 - -mspCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the MasterSwitch plus has been lost." - --#TYPE "APC: Communications lost with the MasterSwitch plus." - --#SUMMARY "Communications with the MasterSwitch plus has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 99 - -mspOutletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, - sPDUOutletControlMSPOutletIndex, sPDUOutletControlMSPOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch plus has turned on." - --#TYPE "APC: An outlet on the MasterSwitch plus has turned on." - --#SUMMARY "An outlet on the MasterSwitch plus has turned on." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 100 - -mspOutletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, - sPDUOutletControlMSPOutletIndex, sPDUOutletControlMSPOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch plus has turned off." - --#TYPE "APC: An outlet on the MasterSwitch plus has turned off." - --#SUMMARY "An outlet on the MasterSwitch plus has turned off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 101 - -mspDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on a MasterSwitch plus." - --#TYPE "APC: A device configuration change on a MasterSwitch plus." - --#SUMMARY "A device configuration change has been made on a MasterSwitch plus." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 102 - -mspOutletConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, sPDUOutletControlMSPOutletIndex, sPDUOutletControlMSPOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet configuration change has been made on a MasterSwitch plus." - --#TYPE "APC: An outlet configuration change on a MasterSwitch plus." - --#SUMMARY "An outlet configuration change has been made on a MasterSwitch plus." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 103 - -rsSourceSwitched TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger02, mtrapargsString03, mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Redundant Switch has switched source. - The first variable is an integer representing the current source: 0=A, 1=B. - The second variable is the 32-character name of the current source. - The third variable is an integer representing the transfer cause: - 0=No Transfers Recorded, 1=Due to user action or preferred switching, - 3=Due to line notch or spike, 5=Due to low line voltage, - 7=Transfer due to high line voltage, - 9=Transfer due to frequency out of range. - The fourth variable is a character string listing the transfer cause." - --#TYPE "APC Redundant Switch: The Redundant Switch has switched source" - --#SUMMARY "The Redundant Switch has switched source." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 104 - -rsLostRedundancy TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: The Redundant Switch has lost redundancy. - The first variable is an integer representing the source which is no longer available: 0=A, 1=B. - The second variable is the 32-character name of the source which is no longer available." - --#TYPE "APC Redundant Switch: The Redundant Switch has lost redundancy" - --#SUMMARY "The Redundant Switch has has lost redundancy." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 105 - -rsRedundancyRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Redundancy has been restored to the Redundant Switch . - The first variable is an integer representing the source which has been restored: 0=A, 1=B. - The second variable is the 32-character name of the source which has been restored." - --#TYPE "APC Redundant Switch: Redundancy has been restored." - --#SUMMARY "Redundancy has been restored to the Redundant Switch ." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 106 - -rsConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A configuration change has been made on a Redundant Switch." - --#TYPE "APC: A configuration change on a Redundant Switch." - --#SUMMARY "A configuration change has been made on a Redundant Switch." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 107 - -rsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the Redundant Switch has been established." - --#TYPE "APC: Communications established with the Redundant Switch." - --#SUMMARY "Communications with the Redundant Switch has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 108 - -rsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the Redundant Switch has been lost." - --#TYPE "APC: Communications lost with the Redundant Switch." - --#SUMMARY "Communications with the Redundant Switch has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 109 - -dcCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the DC power plant has been established." - --#TYPE "APC: Communications established with the DC power plant." - --#SUMMARY "Communications with the DC power plant has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 110 - -dcCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the DC power plant has been lost." - --#TYPE "APC: Communications lost with the DC power plant." - --#SUMMARY "Communications with the DC power plant has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 111 - -dcPINChanged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The active PIN on the DC controller has been changed." - --#TYPE "APC: The active PIN on the DC controller has been changed." - --#SUMMARY "The active PIN on the DC controller has been changed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 112 - -dcMajorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: A Major alarm is active in the DC power plant." - --#TYPE "APC: A Major alarm is active in the DC power plant." - --#SUMMARY "A Major alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 113 - -dcMajorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Major alarm is no longer active in the DC power plant." - --#TYPE "APC: A Major alarm is no longer active in the DC power plant." - --#SUMMARY "A Major alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 114 - -dcMinorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Minor alarm is active in the DC power plant." - --#TYPE "APC: A Minor alarm is active in the DC power plant." - --#SUMMARY "A Minor alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 115 - -dcMinorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Minor alarm is no longer active in the DC power plant." - --#TYPE "APC: A Minor alarm is no longer active in the DC power plant." - --#SUMMARY "A Minor alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 116 - -dcOutputRelayOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusOutRlyIndex, dm3StatusOutRlyName, mtrapargsString } - DESCRIPTION - "WARNING: An output relay for the powerplant has been activated (state changed to on). - The first variable is an integer representing the output relay number that has gone on. - The second variable is the 16-character name of the output relay." - --#TYPE "APC: An output relay has gone on." - --#SUMMARY "An output relay has gone on in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 117 - -dcOutputRelayOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusOutRlyIndex, dm3StatusOutRlyName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An output relay for the powerplant has been deactivated (state changed to off). - The first variable is an integer representing the output relay number that has gone off. - The second variable is the 16-character name of the output relay." - --#TYPE "APC: An output relay has gone off." - --#SUMMARY "An output relay has gone off in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 118 - -dcInputRelayOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusInRlyIndex, dm3StatusInRlyName, mtrapargsString } - DESCRIPTION - "WARNING: An input relay for the powerplant has been activated (state changed to on). - The first variable is an integer representing the input relay number that has gone on. - The second variable is the 16-character name of the input relay." - --#TYPE "APC: An input relay has gone on." - --#SUMMARY "An input relay has gone on in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 119 - -dcInputRelayOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusInRlyIndex, dm3StatusInRlyName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An input relay for the powerplant has been deactivated (state changed to off). - The first variable is an integer representing the input relay number that has gone off. - The second variable is the 16-character name of the input relay." - --#TYPE "APC: An input relay has gone off." - --#SUMMARY "An input relay has gone off in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 120 - -logicPowerSuppliesIncreased TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of system power supplies has increased." - --#TYPE "APC UPS: The number of system power supplies has increased." - --#SUMMARY "The number of system power supplies has increased." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 121 - -logicPowerSuppliesDecreased TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of system power supplies has decreased." - --#TYPE "APC UPS: The number of system power supplies has decreased." - --#SUMMARY "The number of system power supplies has decreased." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 122 - -externalSwitchGearClosed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: External Switch Gear closed." - --#TYPE "APC UPS: External Switch Gear closed." - --#SUMMARY "External Switch Gear closed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 123 - -externalSwitchGearOpened TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: External Switch Gear opened." - --#TYPE "APC UPS: External Switch Gear opened." - --#SUMMARY "External Switch Gear opened." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 124 - -generalDeviceEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: APC Device event." - --#TYPE "APC Device event" - --#SUMMARY "APC Device event." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 125 - -atsSourceSwitched TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Automatic Transfer Switch has switched source. - The first variable is an integer representing the current source: 0=A, 1=B. - The second variable is the 32-character name of the current source." - --#TYPE "APC Automatic Transfer Switch: The ATS has switched source" - --#SUMMARY "The Automatic Transfer Switch has switched source." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 126 - -atsLostRedundancy TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: The Automatic Transfer Switch has lost redundancy. - The first variable is an integer representing the source which is no longer available: 0=A, 1=B. - The second variable is the 32-character name of the source which is no longer available." - --#TYPE "APC Automatic Transfer Switch: The ATS has lost redundancy. " - --#SUMMARY "The Automatic Transfer Switch has has lost redundancy." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 127 - -atsRedundancyRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Redundancy has been restored to the Automatic Transfer Switch . - The first variable is an integer representing the source which has been restored: 0=A, 1=B. - The second variable is the 32-character name of the source which has been restored." - --#TYPE "APC Automatic Transfer Switch: Redundancy has been restored." - --#SUMMARY "Redundancy has been restored to the Automatic Transfer Switch ." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 128 - -atsConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A configuration change has been made on the Automatic Transfer Switch. - The first variable is an integer representing the configuration setting which changed: - 0=Transfer Voltage Range, 1=Sensitivity 2=Preferred Source - 3=Front Panel Lockout 4=Current Limit" - --#TYPE "APC Automatic Transfer Switch: ATS configuration changed." - --#SUMMARY "A configuration change has been made on a Automatic Transfer Switch." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 129 - -atsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the Automatic Transfer Switch has been established." - --#TYPE "APC Automatic Transfer Switch: Communications established." - --#SUMMARY "Communications with the Automatic Transfer Switch has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 130 - -atsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the Automatic Transfer Switch has been lost." - --#TYPE "APC Automatic Transfer Switch: Communications lost." - --#SUMMARY "Communications with the Automatic Transfer Switch has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 131 - -atsOverCurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Output Current has exceeded threshold." - --#TYPE "APC Automatic Transfer Switch: Output Current exceeded threshold" - --#SUMMARY "Output Current has exceeded Threshold. " - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 132 - -atsOverCurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Output Current has returned below threshold." - --#TYPE "APC Automatic Transfer Switch: Output Current below threshold." - --#SUMMARY "Output Current has returned below threshold." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 133 - -atsPowerSupplyFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The Automatic Transfer Switch Power Supply has failed. - The first variable is an integer representing the Power Supply which - has failed: 0=24V, 1=12V 2=5V." - --#TYPE "APC Automatic Transfer Switch: The ATS Power Supply has failed." - --#SUMMARY "The Automatic Transfer Switch Power Supply has failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 134 - -atsPowerSupplyFailureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Automatic Transfer Power Supply Failure Cleared. - The first variable is an integer representing the Power Supply which - has cleared: 0=24V, 1=12V 2=5V." - --#TYPE "APC Automatic Transfer Switch: Power Supply Failure Cleared." - --#SUMMARY "The Automatic Transfer Switch Power Supply Failure Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 135 - -dcMainsFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Mains Fail alarm is active in the DC power plant." - --#TYPE "APC: A Mains Fail alarm is active in the DC power plant." - --#SUMMARY "A Mains Fail alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 136 - -dcMainsFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Mains Fail alarm is no longer active in the DC power plant." - --#TYPE "APC: Mains Fail alarm is no longer active in the DC power plant." - --#SUMMARY "Mains Fail alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 137 - -dcFanFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Fan Fail alarm is active in the DC power plant." - --#TYPE "APC: A Fan Fail alarm is active in the DC power plant." - --#SUMMARY "A Fan Fail alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 138 - -dcFanFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Fan Fail alarm is no longer active in the DC power plant." - --#TYPE "APC: A Fan Fail alarm is no longer active in the DC power plant." - --#SUMMARY "A Fan Fail alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 139 - -dcRectifierOvertempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Rect. Overtemp alarm is active in the power plant." - --#TYPE "APC: Rect. Overtemp alarm is active in the power plant." - --#SUMMARY "Rect. Overtemp alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 140 - -dcRectifierOvertempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Rect. Overtemp alarm is no longer active in the power plant." - --#TYPE "APC: Rect. Overtmp alarm is no longer active in the power plant." - --#SUMMARY "Rect. Overtmp alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 141 - -dcCurrentLimitAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Current Limit alarm is active in the power plant." - --#TYPE "APC: A Current Limit alarm is active in the power plant." - --#SUMMARY "A Current Limit alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 142 - -dcCurrentLimitAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Current Limit alarm is no longer active in the power plant." - --#TYPE "APC: Current Limit alarm is no longer active in the power plant." - --#SUMMARY "Current Limit alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 143 - -dcRectifierFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Rect. Fail alarm is active in the power plant." - --#TYPE "APC: A Rect. Fail alarm is active in the power plant." - --#SUMMARY "A Rect. Fail alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 144 - -dcRectifierFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Rect. Fail alarm is no longer active in the power plant." - --#TYPE "APC: Rect. Fail alarm is no longer active in the power plant." - --#SUMMARY "Rect. Fail alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 145 - -dcMultRectFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Multiple Rect. Fail alarm is active in the powerplant." - --#TYPE "APC: Multiple Rect. Fail alarm is active in the powerplant." - --#SUMMARY "Multiple Rect. Fail alarm is active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 146 - -dcMultRectFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Mult Rect Fail alarm is no longer active in the powerplant." - --#TYPE "APC: Mult Rect Fail alarm is no longer active in the powerplant." - --#SUMMARY "Mult Rect Fail alarm is no longer active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 147 - -dcBatteryBreakerAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Batt. Breaker alarm is active in the power plant." - --#TYPE "APC: Batt. Breaker alarm is active in the power plant." - --#SUMMARY "Batt. Breaker alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 148 - -dcBatteryBreakerAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Batt. Breaker alarm is no longer active in the power plant." - --#TYPE "APC: Batt. Breaker alarm is no longer active in the power plant." - --#SUMMARY "Batt. Breaker alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 149 - -dcRectifierOVPAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Rect. OVP alarm is active in the power plant." - --#TYPE "APC: A Rect. OVP alarm is active in the power plant." - --#SUMMARY "A Rect. OVP alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 150 - -dcRectifierOVPAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Rect. OVP alarm is no longer active in the power plant." - --#TYPE "APC: A Rect. OVP alarm is no longer active in the power plant." - --#SUMMARY "A Rect. OVP alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 151 - -dcLVDImminentAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A LVD Imminent alarm is active in the powerplant." - --#TYPE "APC: A LVD Imminent alarm is active in the powerplant." - --#SUMMARY "A LVD Imminent alarm is active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 152 - -dcLVDImminentAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A LVD Imminent alarm is no longer active in the powerplant." - --#TYPE "APC: A LVD Imminent alarm is no longer active in the powerplant." - --#SUMMARY "A LVD Imminent alarm is no longer active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 153 - -dcFuseCBAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Fuse/CB alarm is active in the DC power plant." - --#TYPE "APC: A Fuse/CB alarm alarm is active in the DC power plant." - --#SUMMARY "A Fuse/CB alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 154 - -dcFuseCBAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Fuse/CB alarm is no longer active in the DC power plant." - --#TYPE "APC: A Fuse/CB alarm is no longer active in the DC power plant." - --#SUMMARY "A Fuse/CB alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 155 - -dcBatteryTestFail TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Battery Test failed in the DC power plant." - --#TYPE "APC: A Battery Test failed in the DC power plant." - --#SUMMARY "A Battery Test failed in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 156 - -dcTemperatureAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Temperature is active in the power plant." - --#TYPE "APC: A Temperature alarm is active in the power plant." - --#SUMMARY "A Temperature alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 157 - -dcTemperatureAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Temperature alarm is no longer active in the power plant." - --#TYPE "APC: A Temperature alarm is no longer active in the power plant." - --#SUMMARY "A Temperature alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 158 - -dcHumidityAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Humidity alarm is active in the DC power plant." - --#TYPE "APC: A Humidity alarm is active in the DC power plant." - --#SUMMARY "A Humidity alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 159 - -dcHumidityAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Humidity alarm is no longer active in the DC power plant." - --#TYPE "APC: A Humidity alarm is no longer active in the DC power plant." - --#SUMMARY "A Humidity alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 160 - -dcBBCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Power plant bridging board communications established." - --#TYPE "APC: Power plant bridging board communications established." - --#SUMMARY "Power plant bridging board communications established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 161 - -dcBBCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Power plant bridging board communications lost." - --#TYPE "APC: Power plant bridging board communications lost." - --#SUMMARY "Power plant bridging board communications lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 162 - -iemHighTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentTemp, iemStatusProbeTempUnits, iemStatusProbeNumber, - iemStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: High temperature threshold violated on Integrated - Environmental Monitor probe. The first variable is the - current temperature. The second variable is the temperature - scale. The third variable is the probe number. The fourth - variable is the probe name." - --#TYPE "APC IEM: High temperature threshold violation." - --#SUMMARY "High temperature threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 163 - -iemHighTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High temperature threshold violated on Integrated - Environmental Monitor probe has been cleared. The first variable - is the probe number. The second variable is the probe name." - --#TYPE "APC IEM: High temperature threshold violation cleared." - --#SUMMARY "High temperature threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 164 - -iemLowTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentTemp, iemStatusProbeTempUnits, iemStatusProbeNumber, - iemStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Low temperature threshold violated on integrated - probe. The first variable is the current temperature. The - second variable is the temperature scale. The third - variable is the probe number. The fourth variable is the - probe name." - --#TYPE "APC IEM: Low temperature threshold violation." - --#SUMMARY "Low temperature threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 165 - -iemLowTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low temperature threshold violated on integrated - probe has been cleared. The first variable is the probe number. - The second variable is the probe name." - --#TYPE "APC IEM: Low temperature threshold violation cleared." - --#SUMMARY "Low temperature threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 166 - -iemHighHumidThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentHumid, iemStatusProbeNumber, iemStatusProbeName, - mtrapargsString } - DESCRIPTION - "SEVERE: High humidity threshold violated on integrated - probe. The first variable is the current humidity. The - second variable is the probe number. The third variable - is the probe name." - --#TYPE "APC IEM: High humidity threshold violation." - --#SUMMARY "High humidity threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 167 - -iemHighHumidThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High humidity threshold violated on integrated - probe cleared. The first variable is the probe number. The second - variable is the probe name." - --#TYPE "APC IEM: High humidity threshold violation cleared." - --#SUMMARY "High humidity threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 168 - -iemLowHumidThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentHumid, iemStatusProbeNumber, iemStatusProbeName, - mtrapargsString } - DESCRIPTION - "SEVERE: Low humidity threshold violated on integrated - probe. The first variable is the current humidity. The - second variable is the probe number. The third variable - is the probe name." - --#TYPE "APC IEM: Low humidity threshold violation." - --#SUMMARY "Low humidity threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 169 - -iemLowHumidThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low humidity threshold violated on integrated - probe cleared. The first variable is the probe number. The second - variable is the probe name." - --#TYPE "APC IEM: Low humidity threshold violation cleared." - --#SUMMARY "Low humidity threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 170 - -iemProbeDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The temperature/humidity probe on the Integrated - Environmental Monitor has been disconnected. This trap is - generated when a probe that has been in communication with - the Environmental Monitor has been disconnected or can no - longer communicate." - --#TYPE "APC IEM: Probe disconnected." - --#SUMMARY "Probe has been disconnected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 171 - -iemProbeConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The temperature/humidity probe on the Integrated - Environmental Monitor has been connected. This trap is generated - when the Environmental Monitor establishes communication with a - probe that had previously not been connected." - --#TYPE "APC IEM: Probe Connected." - --#SUMMARY "Probe has been connected." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 172 - -iemContactFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusContactNumber, iemStatusContactName, mtrapargsString } - DESCRIPTION - "SEVERE: There is a contact fault on the Integrated - Environmental Monitor. The first argument is the number - of the contact. The second argument is the name of the - contact." - --#TYPE "APC IEM: Contact fault." - --#SUMMARY "Contact fault." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 173 - -iemContactFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusContactNumber, iemStatusContactName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The contact fault on the Integrated - Environmental Monitor has been cleared. The first - argument is the number of the contact. The second - argument is the name of the contact." - --#TYPE "APC IEM: Contact fault." - --#SUMMARY "Contact fault cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 174 - -iemRelayFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusRelayNumber, iemStatusRelayName, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: The output relay on the Integrated Environmental - Monitor has switched to the fault state. The first - argument is the number of the output relay. The second - argument is the name of the output relay. The third - argument is the event that caused the fault." - --#TYPE "APC IEM: Output relay fault." - --#SUMMARY "Output relay has faulted." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 175 - -iemRelayFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusRelayNumber, iemStatusRelayName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The fault condition on the output relay on the - Integrated Environmental Monitor has cleared. The first - argument is the number of the output relay. The second - argument is the name of the output relay." - --#TYPE "APC IEM: Output relay fault condition cleared." - --#SUMMARY "Output relay fault cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 176 - -bmBatManCommEstab TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Serial Communications Established with Battery Manager." - --#TYPE "BatMan : Communications Established." - --#SUMMARY "Communications Established." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 177 - -bmBatManCommLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Serial Communications Lost with Battery Manager." - --#TYPE "BatMan : Communications Lost." - --#SUMMARY "Communications Lost." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 178 - -bmBatManKneeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Battery Voltage Knee Threshold Alarm Detected." - --#TYPE "BatMan : Knee Alarm Detected." - --#SUMMARY "Knee Alarm Detected." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 179 - -bmBatManKneeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Battery Voltage Knee Threshold Alarm Cleared." - --#TYPE "BatMan : Knee Alarm Cleared." - --#SUMMARY "Knee Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 180 - -bmBatManChargerAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Charger Alarm Detected." - --#TYPE "BatMan : Charger Alarm Detected." - --#SUMMARY "Charger Alarm Detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 181 - -bmBatManChargerAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Charger Alarm Cleared." - --#TYPE "BatMan : Charger Alarm Cleared." - --#SUMMARY "Charger Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 182 - -bmBatManBatteryAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Battery Alarm Detected." - --#TYPE "BatMan : Battery Alarm Detected." - --#SUMMARY "Battery Alarm Detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 183 - -bmBatManBatteryAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Battery Alarm Cleared." - --#TYPE "BatMan : Battery Alarm Cleared." - --#SUMMARY "Battery Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 184 - -bmBatManEnvironmentAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Environment Alarm Detected." - --#TYPE "BatMan : Environment Alarm Detected." - --#SUMMARY "Environment Alarm Detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 185 - -bmBatManEnvironmentAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Environment Alarm Cleared." - --#TYPE "BatMan : Environment Alarm Cleared." - --#SUMMARY "Environment Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 186 - -bmBatManMaintenanceAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Maintenance Alarm Detected." - --#TYPE "BatMan : Maintenance Due Alarm Detected." - --#SUMMARY "Maintenance Due Alarm Detected." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 187 - -bmBatManMaintenanceAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Maintenance Alarm Cleared." - --#TYPE "BatMan : Maintenance Due Alarm Cleared." - --#SUMMARY "Maintenance Due Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 188 - -pduCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication Established. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 189 - -pduCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Communication Lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 190 - -pduUtilityLineUndervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Utility Line Undervoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Undervoltage." - --#SUMMARY "Utility Line Undervoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 191 - -pduUtilityLineUndervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Utility Line Undervoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Undervoltage Cleared." - --#SUMMARY "Utility Line Undervoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 192 - -pduUtilityLineOvervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Utility Line Overvoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Overvoltage." - --#SUMMARY "Utility Line Overvoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 193 - -pduUtilityLineOvervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Utility Line Overvoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Overvoltage Cleared." - --#SUMMARY "Utility Line Overvoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 194 - -pduGroundOvercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Ground Overcurrent. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Ground Overcurrent." - --#SUMMARY "Ground Overcurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 195 - -pduGroundOvercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Ground Overcurrent Cleared. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Ground Overcurrent Cleared." - --#SUMMARY "Ground Overcurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 196 - -pduCircuitPanelInputUndervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Undervoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undervoltage." - --#SUMMARY "Circuit Panel Input Undervoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 197 - -pduCircuitPanelInputUndervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Undervoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undervoltage Cleared." - --#SUMMARY "Circuit Panel Input Undervoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 198 - -pduCircuitPanelInputOvervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Overvoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overvoltage." - --#SUMMARY "Circuit Panel Input Overvoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 199 - -pduCircuitPanelInputOvervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Overvoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overvoltage Cleared." - --#SUMMARY "Circuit Panel Input Overvoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 200 - -pduCircuitPanelInputUndercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Undercurrent. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undercurrent." - --#SUMMARY "Circuit Panel Input Undercurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 201 - -pduCircuitPanelInputUndercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Undercurrent Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undercurrent Cleared." - --#SUMMARY "Circuit Panel Input Undercurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 202 - -pduCircuitPanelInputOvercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Overcurrent. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overcurrent." - --#SUMMARY "Circuit Panel Input Overcurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 203 - -pduCircuitPanelInputOvercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Overcurrent Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overcurrent Cleared." - --#SUMMARY "Circuit Panel Input Overcurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 204 - -pduCircuitPanelFrequencyOutOfRange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Frequency Out Of Range. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Frequency Out Of Range." - --#SUMMARY "Circuit Panel Input Frequency Out Of Range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 205 - -pduCircuitPanelFrequencyOutofRangeCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Frequency No Longer Out Of Range. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Frequency No Longer Out Of Range." - --#SUMMARY "Circuit Panel Input Frequency No Longer Out Of Range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 206 - -pduCircuitPanelNeutralOvercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Neutral Overcurrent. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Neutral Overcurrent." - --#SUMMARY "Circuit Panel Input Neutral Overcurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 207 - -pduCircuitPanelNeutralOvercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Neutral Overcurrent Cleared. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Neutral Overcurrent Cleared." - --#SUMMARY "Circuit Panel Input Neutral Overcurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 208 - -pduSystemOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: PDU System Off. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: System Off." - --#SUMMARY "PDU System Off." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 209 - -pduOnBatteryMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: PDU is in On Battery Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: On Battery Mode." - --#SUMMARY "PDU is in On Battery Mode." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 210 - -pduMaintenanceBypassMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: PDU is in Maintenance Bypass Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Maintenance Bypass Mode." - --#SUMMARY "PDU is in Maintenance Bypass Mode." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 211 - -pduAtypicalBypassMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "WARNING: PDU is in Atypical Bypass Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Atypical Bypass Mode." - --#SUMMARY "PDU is in Atypical Bypass Mode." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 212 - -pduNoPanelFeedMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: PDU is in No Panel Feed Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: No Panel Feed Mode." - --#SUMMARY "PDU is in No Panel Feed Mode." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 213 - -pduUpsOperationMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: PDU is in Ups Operation Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Ups Operation Mode." - --#SUMMARY "PDU is in Ups Operation Mode." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 214 - -pduForcedBypassMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "WARNING: PDU is in Forced Bypass Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Forced Bypass Mode." - --#SUMMARY "PDU is in Forced Bypass Mode." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 215 - -pduInputTransformerOverTemperature TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Input Transformer Over Temperature. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Input Transformer Over Temperature." - --#SUMMARY "Input Transformer Over Temperature." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 216 - -pduInputTransformerOverTemperatureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Input Transformer Over Temperature Cleared. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Input Transformer Over Temperature Cleared." - --#SUMMARY "Input Transformer Over Temperature Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 217 - -pduUPSInputVoltageLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: UPS Input Voltage phase-N Lost. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: UPS Input Voltage phase-N Lost." - --#SUMMARY "UPS Input Voltage phase-N Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 218 - -pduUPSInputVoltageRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: UPS Input Voltage phase-N Restored. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: UPS Input Voltage phase-N Restored." - --#SUMMARY "UPS Input Voltage phase-N Restored." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 219 - -pduContactFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: A contact closure in the PDU is in an abnormal position. - The first argument is the serial number. - The second argument is the device name. - The third argument is the number of the contact." - --#TYPE "APC PDU: Contact Abnormal." - --#SUMMARY "Contact Abnormal." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 220 - -pduContactFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A contact closure in the PDU is in a normal position. - The first argument is the serial number. - The second argument is the device name. - The third argument is the number of the contact." - --#TYPE "APC PDU: Contact Normal." - --#SUMMARY "Contact Normal." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 221 - -rPDUBankPhaseLowLoad TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A bank or phase on the Rack PDU has violated the low load threshold. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Violation of bank or phase low load threshold." - --#SUMMARY "A bank or phase on the Rack PDU has violated the low load threshold." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 222 - -rPDUBankPhaseLowLoadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The bank or phase low load condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase low load condition cleared." - --#SUMMARY "The bank or phase low load condition on a Rack PDU has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 223 - -rPDUBankPhaseNearOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A bank or phase of the Rack PDU is near an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase near an overload condition." - --#SUMMARY "A bank or phase of the Rack PDU is near an overload condition." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 224 - -rPDUBankPhaseNearOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The bank or phase near overload condition on a Rack PDU has - been cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase near overload condition has cleared." - --#SUMMARY "Rack PDU bank or phase near overload condition has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 225 - -rPDUBankPhaseOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "SEVERE: A bank or phase of the Rack PDU is in an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase overload condition." - --#SUMMARY "A bank or phase of the Rack PDU is in an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 226 - -rPDUBankPhaseOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The bank or phase overload condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase overload condition has cleared." - --#SUMMARY "The bank or phase overload condition on a Rack PDU has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 227 - -aruDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Device Configurtion change. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: ARU Device configuration change." - --#SUMMARY "ARU device configuration change." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 228 - -rmPDUCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Communication Lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC RM PDU: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 229 - -emsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication Established. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC EMS: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 230 - -emsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: Communication Lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC EMS: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 231 - -emsProbeConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A probe has been connected to the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC EMS: Probe Connected." - --#SUMMARY "Probe Connected." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 232 - -emsProbeDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: A probe has been disconnected from the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC EMS: Probe Disconnected." - --#SUMMARY "Probe Disconnected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 233 - -emsSensorConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A sensor has been connected to the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Connected." - --#SUMMARY "Sensor Connected." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 234 - -emsSensorDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "SEVERE: A sensor has been disconnected from the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Disconnected." - --#SUMMARY "Sensor Disconnected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 235 - -emsSensorFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "SEVERE: A EMS sensor is in the fault condition. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Fault." - --#SUMMARY "Sensor Fault." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 236 - -emsSensorFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A EMS sensor fault condition has cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Fault Cleared." - --#SUMMARY "Sensor Fault Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 237 - -emsBeaconConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A beacon has been connected to the EMS. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon Connected." - --#SUMMARY "Beacon Connected." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 238 - -emsBeaconDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: A beacon has been disconnected from the EMS. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon Disconnected." - --#SUMMARY "Beacon Disconnected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 239 - -emsBeaconOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A EMS beacon has gone on. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon On." - --#SUMMARY "Beacon On." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 240 - -emsBeaconOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A EMS beacon has gone off. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon Off." - --#SUMMARY "Beacon Off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 241 - -emsMajorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: A Major Alarm is present in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Major Alarm." - --#SUMMARY "Major Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 242 - -emsMajorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Major Alarm condition has been cleared in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Major Alarm Cleared." - --#SUMMARY "Major Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 243 - -emsMinorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: A Minor Alarm is present in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Minor Alarm." - --#SUMMARY "Minor Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 244 - -emsMinorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Minor Alarm condition has been cleared in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Minor Alarm Cleared." - --#SUMMARY "Minor Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 245 - -emsOutletStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutletStatusOutletIndex, emsOutletStatusOutletName, - emsOutletStatusOutletState, emsOutletStatusOutletNormalState, mtrapargsString } - DESCRIPTION - "WARNING: An outlet on the EMS has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the outlet number. - The fourth argument is the outlet name. - The fifth argument is the current outlet state (1=ON, 2=OFF). - The sixth argument is the configured normal outlet state (1=ON, 2=OFF)." - --#TYPE "APC EMS: Outlet has changed to its abnormal state." - --#SUMMARY "Outlet has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 246 - -emsOutletStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutletStatusOutletIndex, emsOutletStatusOutletName, - emsOutletStatusOutletState, emsOutletStatusOutletNormalState, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the EMS has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the outlet number. - The fourth argument is the outlet name. - The fifth argument is the current outlet state (1=ON, 2=OFF). - The sixth argument is the configured normal outlet state (1=ON, 2=OFF)." - --#TYPE "APC EMS: Outlet has changed to its normal state." - --#SUMMARY "Outlet has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 247 - -emsInputContactStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsInputContactStatusInputContactIndex, - emsInputContactStatusInputContactName, emsInputContactStatusInputContactState, - emsInputContactStatusInputContactNormalState, mtrapargsString } - DESCRIPTION - "WARNING: An input contact on the EMS has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal input contact state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Input contact has changed to its abnormal state." - --#SUMMARY "Input contact has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 248 - -emsInputContactStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsInputContactStatusInputContactIndex, - emsInputContactStatusInputContactName, emsInputContactStatusInputContactState, - emsInputContactStatusInputContactNormalState, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An input contact on the EMS has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal input contact state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Input contact has changed to its normal state." - --#SUMMARY "Input contact has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 249 - -emsOutputRelayStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutputRelayStatusOutputRelayIndex, - emsOutputRelayStatusOutputRelayName, emsOutputRelayStatusOutputRelayState, - emsOutputRelayStatusOutputRelayNormalState, mtrapargsString } - DESCRIPTION - "WARNING: An output relay on the EMS has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the output relay number. - The fourth argument is the output relay name. - The fifth argument is the current output relay state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal output relay state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Output Relay has changed to its abnormal state." - --#SUMMARY "Output Relay has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 250 - -emsOutputRelayStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutputRelayStatusOutputRelayIndex, - emsOutputRelayStatusOutputRelayName, emsOutputRelayStatusOutputRelayState, - emsOutputRelayStatusOutputRelayNormalState, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An output relay on the EMS has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the output relay number. - The fourth argument is the output relay name. - The fifth argument is the current output relay state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal output relay state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Output Relay has changed to its normal state." - --#SUMMARY "Output Relay has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 251 - -emsDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC: A device configuration change on a EMS." - --#SUMMARY "A device configuration change has been made on a EMS." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 252 - -envHighTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: High temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: High temperature threshold violation." - --#SUMMARY "High temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 253 - -envHighTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: High temperature threshold violation cleared." - --#SUMMARY "High temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 254 - -envLowTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Low temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Low temperature threshold violation." - --#SUMMARY "Low temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 255 - -envLowTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Low temperature threshold violation cleared." - --#SUMMARY "Low temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 256 - -envHighHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: High humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: High humidity threshold violation." - --#SUMMARY "High humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 257 - -envHighHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: High humidity threshold violation cleared." - --#SUMMARY "High humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 258 - -envLowHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Low humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Low humidity threshold violation." - --#SUMMARY "Low humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 259 - -envLowHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Low humidity threshold violation cleared." - --#SUMMARY "Low humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 260 - - --- Switched and Metered Rack PDU Traps - -rPDUCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication with a Rack PDU has been established. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Communication established." - --#SUMMARY "Communication with a Rack PDU established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 266 - -rPDUCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "SEVERE: Communication with a Rack PDU has been lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Communication lost." - --#SUMMARY "Communication with a Rack PDU has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 267 - -rPDUOutletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on a Switched Rack PDU has turned on. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number. - The fourth argument is the outlet name." - --#TYPE "APC Switched Rack PDU: An outlet has turned on." - --#SUMMARY "An outlet on a Switched Rack PDU has turned on." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 268 - -rPDUOutletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on a Switched Rack PDU has turned off. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number. - The fourth argument is the outlet name." - --#TYPE "APC Switched Rack PDU: An outlet has turned off." - --#SUMMARY "An outlet on a Switched Rack PDU has turned off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 269 - -rPDUDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on a - Rack PDU. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Device configuration change made." - --#SUMMARY "Device configuration change has been made on a Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 270 - -rPDUOutletConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet configuration change has been made on a - Switched Rack PDU. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number. - The fourth argument is the outlet name." - --#TYPE "APC Switched Rack PDU: Outlet configuration change made." - --#SUMMARY "Outlet configuration change has been made on a Switched Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 271 - -rPDULowLoad TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A Rack PDU has violated the low load threshold. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Violation of low load threshold." - --#SUMMARY "A Rack PDU has violated the low load threshold." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 272 - -rPDULowLoadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The low load condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Low load condition cleared." - --#SUMMARY "The low load condition on a Rack PDU has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 273 - -rPDUNearOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A Rack PDU is near an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Near an overload condition." - --#SUMMARY "A Rack PDU is near an overload condition." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 274 - -rPDUNearOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The near overload condition on a Rack PDU has - been cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Near overload condition has cleared." - --#SUMMARY "Rack PDU near overload condition has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 275 - -rPDUOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "SEVERE: A Rack PDU is in an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Overload condition." - --#SUMMARY "A Rack PDU is in an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 276 - -rPDUOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The overload condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Overload condition has cleared." - --#SUMMARY "The overload condition on a Rack PDU has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 277 - -rPDUPowerSupply1Fail TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "SEVERE: Power Supply 1 on Rack PDU is in FAIL state. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 1 is in FAIL state." - --#SUMMARY "Power Supply 1 on Rack PDU is in FAIL state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 278 - -rPDUPowerSupply1Ok TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Power Supply 1 on Rack PDU is operating normally. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 1 is operating normally." - --#SUMMARY "Power Supply 1 on Rack PDU is operating normally." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 279 - -rPDUPowerSupply2Fail TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "SEVERE: Power Supply 2 on Rack PDU is in FAIL state. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 2 is in FAIL state." - --#SUMMARY "Power Supply 2 on Rack PDU is in FAIL state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 280 - -rPDUPowerSupply2Ok TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Power Supply 2 on Rack PDU is operating normally. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 2 is operating normally." - --#SUMMARY "Power Supply 2 on Rack PDU is operating normally." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 281 - -rPDUPhaseConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadPhaseConfigIndex, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A phase configuration change has been made on a - Rack PDU. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase index number." - --#TYPE "APC Rack PDU: Phase configuration change made." - --#SUMMARY "Phase configuration change has been made on a Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 282 - -rPDUCancelPendingCommand TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A cancel pending command has been made on a - Switched Rack PDU. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number (0 indicates all outlets). - The fourth argument is the outlet name (or device name if all outlets)." - --#TYPE "APC Switched Rack PDU: Cancel Pending Command made." - --#SUMMARY "A Cancel Pending Command has been made on a Switched Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 283 - -aruAlinkCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Communication Established. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 284 - -aruAlinkCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Communication Lost. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 285 - -aruFanFail TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Fan Fail. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Fan Fail." - --#SUMMARY "Fan Fail." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 286 - -aruFanFailCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Fan Fail Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Fan Fail Cleared." - --#SUMMARY "Fan Fail Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 287 - -aruSmokeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Smoke Alarm. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Smoke Alarm." - --#SUMMARY "Smoke Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 288 - -aruSmokeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Smoke Alarm Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Smoke Alarm Cleared." - --#SUMMARY "Smoke Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 289 - -aruHighTemperatureAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU High Temperature Alarm. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: High Temperature Alarm." - --#SUMMARY "High Temperature Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 290 - -aruHighTemperatureAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU High Temperature Alarm Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: High Temperature Alarm Cleared." - --#SUMMARY "High Temperature Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 291 - -aruExhaustTemperatureAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Exhaust Temperature Alarm. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Exhaust Temperature Alarm." - --#SUMMARY "Exhaust Temperature Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 292 - -aruExhaustTemperatureAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Exhaust Temperature Alarm Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Exhaust Temperature Alarm Cleared." - --#SUMMARY "Exhaust Temperature Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 293 - -envAlinkCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote Probe Communication Established. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC ENV: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 294 - -envAlinkCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote Probe Communication Lost. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC ENV: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 295 - -emsAlinkPowerOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: Alink Power Overload. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Alink Power Overload." - --#SUMMARY "Alink Power Overload." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 296 - -emsAlinkPowerOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Alink Power Overload Cleared. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Alink Power Overload Cleared." - --#SUMMARY "Alink Power Overload Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 297 - -upsOutletGroupTurnedOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { upsOutletGroupControlIndex, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The specified Outlet Group turned on." - --#TYPE "APC UPS: Outlet Group turned on." - --#SUMMARY "Outlet Group turned on" - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 298 - -upsOutletGroupTurnedOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { upsOutletGroupControlIndex, mtrapargsString } - DESCRIPTION - "WARNING: The specified Outlet Group turned off." - --#TYPE "APC UPS: Outlet Group turned off." - --#SUMMARY "Outlet Group turned off." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 299 - -smwCriticalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "SEVERE: A Symmetra MW UPS critical condition has been detected. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A critical condition has been detected." - --#SUMMARY "A critical condition has been detected." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 300 - -smwCriticalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Symmetra MW UPS critical condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A critical condition has been cleared." - --#SUMMARY "A critical condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 301 - -smwWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "WARNING: A Symmetra MW UPS warning condition has been detected. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A warning condition has been detected." - --#SUMMARY "A warning condition has been detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 302 - -smwWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "WARNING: A Symmetra MW UPS warning condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A warning condition has been cleared." - --#SUMMARY "A warning condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 303 - -smwInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Symmetra MW UPS informational condition has been detected. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: Informational condition detected." - --#SUMMARY "An informational condition has been detected." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 304 - -smwInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Symmetra MW UPS informational condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: Informational condition cleared." - --#SUMMARY "An informational condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 305 - -airCriticalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Air critical condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A critical condition was detected. " - --#SUMMARY "A critical condition was detected. " - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 306 - -airCriticalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Air critical condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A critical condition was cleared. " - --#SUMMARY "A critical condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 307 - -airWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: An Air warning condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A warning condition was detected. " - --#SUMMARY "A warning condition was detected. " - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 308 - -airWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: An Air warning condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A warning condition was cleared. " - --#SUMMARY "A warning condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 309 - -airInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Air informational condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: Informational condition detected. " - --#SUMMARY "An informational condition was detected. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 310 - -airInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Air informational condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: Informational condition was cleared. " - --#SUMMARY "An informational condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 311 - --- xPDU Traps (part 1) - -xPDUInputVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase - (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XPDU: Main input voltage out-of-range alarm." - --#SUMMARY "Input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 312 - -xPDUInputVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Main input voltage back in range." - --#SUMMARY "Input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 313 - - -xPDUInputVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase - (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm was generated." - --#TYPE "APC XPDU: Main input voltage out-of-range alarm." - --#SUMMARY "Input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 314 - -xPDUInputVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Main input voltage back in range." - --#SUMMARY "Input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 315 - -xPDUBypassVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase bypass input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XPDU: Bypass input voltage out-of-range alarm." - --#SUMMARY "Bypass input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 316 - -xPDUBypassVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase bypass input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Bypass input voltage back in range." - --#SUMMARY "Bypass input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 317 - -xPDUBypassVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase bypass input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm was generated." - --#TYPE "APC XPDU: Bypass input voltage out-of-range alarm." - --#SUMMARY "Bypass input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 318 - -xPDUBypassVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase bypass input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Bypass input voltage back in range." - --#SUMMARY "Bypass input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 319 - -xPDUOutputVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XPDU: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 320 - -xPDUOutputVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 321 - -xPDUOutputVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm was generated." - --#TYPE "APC XPDU: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 322 - -xPDUOutputVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 323 - -xPDUOutputCurrentLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in Amps, from which the alarm was generated." - --#TYPE "APC XPDU: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 324 - -xPDUOutputCurrentLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 325 - -xPDUOutputCurrentHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in Amps, above which the alarm was generated." - --#TYPE "APC XPDU: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 326 - -xPDUOutputCurrentHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 327 - -xPDUOutputFrequencyAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The devices output frequency is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the frequency deviation from the nominal in tenths of Hertz." - --#TYPE "APC XPDU: Output frequency out-of-range alarm." - --#SUMMARY "Output frequency is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 328 - -xPDUOutputFrequencyAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices output frequency is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Output frequency back in range." - --#SUMMARY "Output frequency in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 329 - -xPDUSystemGroundCurrentAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The devices earth ground current is over the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Earth ground current over range alarm." - --#SUMMARY "Earth ground current is over limit." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 330 - -xPDUSystemGroundCurrentAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices earth ground current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Earth ground current back in range." - --#SUMMARY "Earth ground current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 331 - -xPDUInputContactStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: A user input contact on the device has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Input contact has changed to its abnormal state." - --#SUMMARY "Input contact has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 332 - -xPDUInputContactStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user input contact on the device has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Input contact has changed to its normal state." - --#SUMMARY "Input contact has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 333 - -xPDUOutputRelayStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: An Output Relay on the device has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the Output Relay number. - The fourth argument is the Output Relay name. - The fifth argument is the current Output Relay state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal Output Relay state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Output Relay has changed to its abnormal state." - --#SUMMARY "Output Relay has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 334 - -xPDUOutputRelayStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Output Relay on the device has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the Output Relay number. - The fourth argument is the Output Relay name. - The fifth argument is the current Output Relay state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal Output Relay state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Output Relay has changed to its normal state." - --#SUMMARY "Output Relay has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 335 - -xPDUCoolingFanAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's internal cooling fans have failed. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Cooling fan failure alarm." - --#SUMMARY "Cooling fan failure." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 336 - -xPDUCoolingFanAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's cooling fans are now functioning properly. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Cooling fan alarm cleared." - --#SUMMARY "Cooling fan alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 337 - -xPDUTransformerTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's isolation transformer is over temperature. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Isolation transformer over temperature alarm." - --#SUMMARY "Transformer temp alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 338 - -xPDUTransformerTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's isolation transformer is no longer over temperature. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Isolation transformer over temperature alarm cleared." - --#SUMMARY "Transformer temp alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 339 - -xPDUBranchCurrentLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The current in a branch circuit is outside the limits specified for that - branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in tenth of Amps, from which the alarm was generated." - --#TYPE "APC XPDU: Branch circuit current out-of-range alarm." - --#SUMMARY "Branch circuit current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 340 - -xPDUBranchCurrentLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The current in a branch circuit is back within the limits - specified for that branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Branch circuit current back in range." - --#SUMMARY "Branch circuit current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 341 - -xPDUBranchCurrentHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The current in a branch circuit is outside the limits specified for that - branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in tenth of Amps, above which the alarm was generated." - --#TYPE "APC XPDU: Branch circuit current out-of-range alarm." - --#SUMMARY "Branch circuit current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 342 - -xPDUBranchCurrentHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The current in a branch circuit is back within the limits - specified for that branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Branch circuit current back in range." - --#SUMMARY "Branch circuit current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 343 - - -xPDUInternalCommError TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: There is an internal communication error in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Internal communication error." - --#SUMMARY "Internal communication error." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 344 - -emsHardwareStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's hardware is improperly configured and operating outside - normal bounds for the hardware. This can be caused by improper devices being - connected to the EMS ports or Alink Current limit detection." - --#TYPE "APC EMS: Hardware is in an abnormal state." - --#SUMMARY "Hardware is in an abnormal state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 345 - -emsHardwareStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's hardware is in its normal operational state. - The first argument is the host device serial number." - --#TYPE "APC EMS: Hardware is in a normal state." - --#SUMMARY "Hardware is in its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 346 - -ceSevereCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: A Custom Event severe condition was detected. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A severe condition was detected. " - --#SUMMARY "A severe condition was detected. " - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 347 - -ceSevereConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event severe condition was cleared. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A severe condition was cleared. " - --#SUMMARY "A severe condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 348 - -ceWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: A Custom Event warning condition was detected. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A warning condition was detected. " - --#SUMMARY "A warning condition was detected. " - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 349 - -ceWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event warning condition was cleared. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A warning condition was cleared. " - --#SUMMARY "A warning condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 350 - -ceInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event informational condition was detected. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: Informational condition detected. " - --#SUMMARY "An informational condition was detected. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 351 - -ceInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event informational condition was cleared. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: Informational condition was cleared. " - --#SUMMARY "An informational condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 352 - -upsInternalOverTemperature TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The internal over temperature condition exists." - --#TYPE "APC UPS: The internal over temperature condition exists." - --#SUMMARY "The internal over temperature condition exists." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 353 - -upsInternalOverTemperatureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The internal over temperature condition cleared." - --#TYPE "APC UPS: The internal over temperature condition cleared." - --#SUMMARY "The internal over temperature condition cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 354 - -upsMpuReset TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The MPU has been reset." - --#TYPE "APC UPS: The MPU has been reset." - --#SUMMARY "The MPU has been reset." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 355 - -upsOutputSwitchClosed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Output Switch is closed." - --#TYPE "APC UPS: The Output Switch is closed." - --#SUMMARY "The Output Switch is closed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 356 - -upsOutputSwitchOpened TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Output Switch is open." - --#TYPE "APC UPS: The Output Switch is open." - --#SUMMARY "The Output Switch is open." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 357 - -upsCalibrationStackChanged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A calibration value in the stack was changed." - --#TYPE "APC UPS: A calibration value in the stack was changed." - --#SUMMARY "A calibration value in the stack was changed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 358 - - --- Upgraded EMS now has more env traps - -envMaxTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Max temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Max temperature threshold violation." - --#SUMMARY "Max temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 359 - -envMaxTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Max temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Max temperature threshold violation cleared." - --#SUMMARY "Max temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 360 - -envMinTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Min temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Min temperature threshold violation." - --#SUMMARY "Min temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 361 - -envMinTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Min temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Min temperature threshold violation cleared." - --#SUMMARY "Min temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 362 - -envMaxHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Max humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Max humidity threshold violation." - --#SUMMARY "Max humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 363 - -envMaxHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Max humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Max humidity threshold violation cleared." - --#SUMMARY "Max humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 364 - -envMinHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Min humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Min humidity threshold violation." - --#SUMMARY "Min humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 365 - -envMinHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Min humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Min humidity threshold violation cleared." - --#SUMMARY "Min humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 366 - -envSTIncTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Short-term increasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term inc. temp rate violation." - --#SUMMARY "Short-term inc. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 367 - -envSTIncTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Short-term increasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term inc. temp rate violation cleared." - --#SUMMARY "Short-term inc. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 368 - -envSTDecTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Short-term decreasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term dec. temp rate violation." - --#SUMMARY "Short-term dec. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 369 - -envSTDecTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Short-term decreasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term dec. temp rate violation cleared." - --#SUMMARY "Short-term dec. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 370 - -envLTIncTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Long-term increasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term inc. temp rate violation." - --#SUMMARY "Long-term inc. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 371 - -envLTIncTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Long-term increasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term inc. temp rate violation cleared." - --#SUMMARY "Long-term inc. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 372 - -envLTDecTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Long-term decreasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term dec. temp rate violation." - --#SUMMARY "Long-term dec. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 373 - -envLTDecTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Long-term decreasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term dec. temp rate violation cleared." - --#SUMMARY "Long-term dec. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 374 - --- Battery Management System Traps - -bmsCriticalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: A Battery Management System critical condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A critical condition was detected. " - --#SUMMARY "A critical condition was detected. " - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 375 - -bmsCriticalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Battery Management System critical condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A critical condition was cleared. " - --#SUMMARY "A critical condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 376 - -bmsWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: A Battery Management System warning condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A warning condition was detected. " - --#SUMMARY "A warning condition was detected. " - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 377 - -bmsWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: A Battery Management System warning condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A warning condition was cleared. " - --#SUMMARY "A warning condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 378 - -bmsInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Battery Management System informational condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: Informational condition detected. " - --#SUMMARY "An informational condition was detected. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 379 - -bmsInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Battery Management System informational condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: Informational condition was cleared. " - --#SUMMARY "An informational condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 380 - --- xATS Traps - -xATSOutputVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XATS: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 381 - -xATSOutputVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XATS: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 382 - -xATSOutputVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm is generated." - --#TYPE "APC XATS: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 383 - -xATSOutputVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XATS: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 384 - -xATSOutputCurrentLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral, 5=L1-2, 6=L2-3, 7=L3-1). - The fourth argument is the measured current in Amps. - The fifth argument is the threshold, in Amps, from which the alarm was generated." - --#TYPE "APC XATS: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 385 - -xATSOutputCurrentLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral). - The fourth argument is the measured current in Amps." - --#TYPE "APC XATS: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 386 - -xATSOutputCurrentHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral). - The fourth argument is the measured current in Amps. - The fifth argument is the threshold, in Amps, from which the alarm was generated." - --#TYPE "APC XATS: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 387 - -xATSOutputCurrentHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral). - The fourth argument is the measured current in Amps." - --#TYPE "APC XATS: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 388 - - -xATSOutputFrequencyAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "SEVERE: The devices output frequency is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the frequency deviation from the nominal in tenths of Hertz. - The fourth argument is the frequency deviation threshold in tenths of Hertz, - from which the alarm was generated." - --#TYPE "APC XATS: Output frequency out-of-range alarm." - --#SUMMARY "Output frequency is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 389 - -xATSOutputFrequencyAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices output frequency is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Output frequency back in range." - --#SUMMARY "Output frequency in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 390 - -xATSInternalCommError TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: There is an internal communication error in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Internal communication error." - --#SUMMARY "Internal communication error." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 391 - -xATSInternalCommErrorCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Internal communication has been restored. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Internal Communication error cleared." - --#SUMMARY "ATS Communication error cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 392 - -xATSDataCommMismatchError TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: A data incompatibility exists within the device. This - is typically the result of mismatches between firmware revisions - of the transfer switch controller and the Network Management interface. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Data mismatch error." - --#SUMMARY "ATS data mismatch error." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 393 - -xATSDataCommMismatchErrorCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The internal data incompatibility has been resolved. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: data mismatch error cleared." - --#SUMMARY "ATS data mismatch error cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 394 - -xATSGenCommLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The XATS cannot communicate with the generator. - This will make unavailable all the xATSGenerator OIDs. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: No communication with generator." - --#SUMMARY "ATS/Generator communication lost." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 395 - -xATSGenCommEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The XATS has established communication with the generator. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Communication with generator established." - --#SUMMARY "ATS/generator communication established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 396 - -xATSNeutralPosition TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsString } - DESCRIPTION - "WARNING: XATS has transferred to neutral position. - In this position neither Source 1 nor Source 2 is selected, - and the XATS will have no output voltage. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the mode in which the switch is operating - (1=Auto, 2=Not-in-Auto, Abnormal Condition 3=Not-in-Auto, manual)." - --#TYPE "APC XATS: Transferred to the neutral (no output power) position." - --#SUMMARY "Transferred to neutral." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 397 - -xATSSwitchTransferEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: XATS has transferred from one source to the other. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the mode in which the switch is operating. - (1=Auto, 2=Not-in-Auto, Abnormal Condition 3=Not-in-Auto, manual). - The fourth argument is the input source selected (1=Source 1, 2=Source 2). - The fifth argument is type of transfer that took place. (1=Closed, 2=Open, 3=Unknown)" - --#TYPE "APC XATS: Transferred from Source-X to Source-Y." - --#SUMMARY "Source-to-Source transfer." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 398 - -xATSInternalATSFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An internal XATS fault has been detected. - The XATS may have forced itself to not-in-auto mode (abnormal condition), - as indicated by the xATSSwitchStatusAutoSwitchOperationalMode OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the detected fault. - - 1=Cannot Close S1 - 2=Cannot Close S2 - 3=Cannot Open S1 - 4=Cannot Open S2 - 5=Cannot Trip Open S1 - 6=Cannot Trip Open S2 - 7=Start Contact Failure - 8=Voltage Sensing Failure" - - --#TYPE "APC XATS: Internal fault detected." - --#SUMMARY "ATS internal fault detected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 399 - -xATSInternalATSFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected internal XATS fault has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the detected fault. - - 1=Cannot Close S1 - 2=Cannot Close S2 - 3=Cannot Open S1 - 4=Cannot Open S2 - 5=Cannot Trip Open S1 - 6=Cannot Trip Open S2 - 7=Start Contact Failure - 8=Voltage Sensing Failure" - - --#TYPE "APC XATS: Internal fault cleared." - --#SUMMARY "ATS internal fault cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 400 - -xATSEngineStartAsserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The XATS has asserted the Engine Start contact. - This should result in the generator producing output voltage. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the reason that the start signal was asserted - 1=Unknown, 2=S1 Low Voltage, 3=S1 High Voltage, 4=S1 Line Imbalance, - 5=S1 Freq Range, 6=S1 Bad Rotation." - --#TYPE "APC XATS: Engine Start signal asserted." - --#SUMMARY "Engine Start asserted." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 401 - -xATSEngineStopAsserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The XATS has de-asserted the Engine Start contact. - This should result in the generator shutting down, and producing no output voltage. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Engine Stop signal asserted." - --#SUMMARY "Engine Stop asserted." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 402 - -xATSStartFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The generator failed to start. After assertion of the - Engine Start signal, the quality of Source 2 was not seen as good. - This alarm can be cleared using the xATSSwitchStatusClearLatchedAlarms OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the line quality at S2 - 1=Unknown, 2=S2 Low Voltage, 3=S2 High Voltage, 4=S2 Line Imbalance, - 4=S2 Freq Range, 5=S2 Bad Rotation." - --#TYPE "APC XATS: Generator failed to start alarm." - --#SUMMARY "Generator failed to start." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 403 - -xATSStopFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The generator failed to stop. After de-assertion of the - Engine Start signal, the quality of Source 2 continued to be seen as good. - This alarm can be cleared using the xATSSwitchStatusClearLatchedAlarms OID. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator failed to stop alarm." - --#SUMMARY "Generator failed to stop." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 404 - -xATSNotInAutomaticMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: Automatic Transfer Switch is not in automatic mode. - The first argument is the host device serial number. - The second argument is the host device name. - The xATSSwitchStatusAutoSwitchStatus OID and the - xATSSwitchStatusAutoSwitchOperationalMode OID - can provide more information about the state of the XATS." - --#TYPE "APC XATS: XATS is not-in-automatic mode." - --#SUMMARY "ATS not in auto." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 405 - -xATSNotInAutomaticModeCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Automatic Transfer Switch is in automatic mode. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: XATS in auto mode." - --#SUMMARY "ATS in auto mode." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 406 - -xATSEpoTripped TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's Emergency Power Off (EPO) circuit is tripped. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) tripped." - --#SUMMARY "EPO tripped." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 407 - -xATSEpoReset TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's Emergency Power Off (EPO) circuit has been - reset to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) reset." - --#SUMMARY "EPO armed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 408 - -xATSEpoTestMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The device's Emergency Power Off (EPO) circuit has been - switched back to the test position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) in test mode." - --#SUMMARY "EPO disabled." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 409 - -xATSEpoArmed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's Emergency Power Off (EPO) circuit has been - switched back to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) enabled." - --#SUMMARY "EPO armed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 410 - -xATSTestInitiated TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A scheduled test has been initiated. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of test initiated (1=scheduled, 2=manual)." - --#TYPE "APC XATS: Test initiated." - --#SUMMARY "Test initiated." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 411 - -xATSTestCancelled TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The scheduled test has been canceled - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of test initiated (1=scheduled, 2=manual)." - --#TYPE "APC XATS: Test cancelled." - --#SUMMARY "Test cancelled." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 412 - -xATSTestFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The initiated test has failed. - This alarm can be cleared using the xATSSwitchStatusClearLatchedAlarms OID. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Initiated test failed." - --#SUMMARY "Initiated test failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 413 - -xATSTestPassed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The initiated test has passed - switched back to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Initiated test passed." - --#SUMMARY "Initiated test passed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 414 - -xATSInputContactStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: A user input contact on the device has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XATS: Input contact has changed to its abnormal state." - --#SUMMARY "Input contact has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 415 - -xATSInputContactStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user input contact on the device has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XATS: Input contact has changed to its normal state." - --#SUMMARY "Input contact has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 416 - -xATSRemoteStartContactMismatch TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The state of the generator's Remote Start input - and the ATS's Engine Start output do not match. - This indicates something wrong in the Engine Start wiring, - which must be corrected. This condition will prevent the - generator from being started when needed. - - (See also: xATSGeneratorStatusRemoteStart - and xATSSwitchStatusEngineStartSignal OIDs) - - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator/ATS start contact mismatch." - --#SUMMARY "Generator/ATS start contact mismatch." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 417 - -xATSRemoteStartContactMismatchCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Mismatch in the state of the generator's - Remote Start input and the ATS's Engine Start output as been resolved. - This indicates something wrong in the Engine Start wiring, - which must be corrected. This condition will prevent the - generator from being started when needed. - - (See also: xATSGeneratorStatusRemoteStart - and xATSSwitchStatusEngineStartSignal OIDs) - - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator/ATS start contact mismatch cleared." - --#SUMMARY "Generator/ATS start contact mismatch cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 418 - -xATSDoorOpenAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The XATS exterior panel door is open. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Panel door is open alarm." - --#SUMMARY "Panel door open alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 419 - -xATSDoorOpenAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The external door to the device is closed. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Panel door open alarm cleared." - --#SUMMARY "Panel door open alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 420 - -xATSDCBackupAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The XATS's DC backup has been lost. The XATS will lose power - on Source 1 failure, causing the Engine Start signal to be asserted. - The XATS will then restart from Source 2. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: DC backup failure." - --#SUMMARY "ATS DC backup failure." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 421 - -xATSDCBackupAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: DC backup alarm has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: DC backup alarm cleared." - --#SUMMARY "DC backup alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 422 - --- xATS Generator Traps - -xATSGeneratorLowCoolantLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Low coolant level has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant level alarm." - --#SUMMARY "Generator low coolant level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 423 - -xATSGeneratorLowCoolantLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low coolant level has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant level alarm cleared." - --#SUMMARY "Generator low coolant level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 424 - -xATSGeneratorVeryLowCoolantLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Very low coolant level has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very low coolant level alarm." - --#SUMMARY "Generator very low coolant level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 425 - -xATSGeneratorVeryLowCoolantLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected Very low coolant level has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very low coolant level alarm cleared." - --#SUMMARY "Generator very low coolant level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 426 - -xATSGeneratorHighCoolantTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: High coolant temperature has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high coolant temperature alarm." - --#SUMMARY "Generator high coolant temperature alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 427 - -xATSGeneratorHighCoolantTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected high coolant temperature has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high coolant temperature alarm cleared." - --#SUMMARY "Generator high coolant temperature alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 428 - -xATSGeneratorVeryHighCoolantTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Very high coolant temperature has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very high coolant temperature alarm." - --#SUMMARY "Generator very high coolant temperature alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 429 - -xATSGeneratorVeryHighCoolantTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Very high coolant temperature condition has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very high coolant temperature alarm cleared." - --#SUMMARY "Generator very high coolant temperature alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 430 - -xATSGeneratorLowCoolantTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Low coolant temperature has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant temperature alarm." - --#SUMMARY "Generator low coolant temperature alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 431 - -xATSGeneratorLowCoolantTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The low coolant temperature condition has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant temperature alarm cleared." - --#SUMMARY "Generator low coolant temperature alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 432 - -xATSGeneratorLowOilLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Low oil level has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil level alarm." - --#SUMMARY "Generator low oil level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 433 - -xATSGeneratorLowOilLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low oil level alarm has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil level alarm cleared." - --#SUMMARY "Generator low oil level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 434 - -xATSGeneratorLowBatteryVoltDuringCrankAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's battery voltage has been detected - as low while cranking the engine. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Low batt. voltage while cranking alarm." - --#SUMMARY "Generator low battery volts while cranking alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 435 - -xATSGeneratorLowBatteryVoltDuringCrankAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's low battery voltage while - cranking condition has been cleared. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "XGEN: Generator low batt. voltage while cranking alarm cleared." - --#SUMMARY "Generator low battery volts while cranking alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 436 - -xATSGeneratorVeryLowBatteryVoltDuringCrankAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's battery voltage has been detected - as very low while cranking the engine. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "XGEN: Generator v.low battery voltage while cranking alarm." - --#SUMMARY "Generator v.low battery volts while cranking alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 437 - -xATSGeneratorVeryLowBatteryVoltDuringCrankAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's high battery voltage while - cranking condition has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "XGEN: Generator v.low batt volt, while cranking alarm cleared." - --#SUMMARY "Generator v.low battery volts while cranking alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 438 - -xATSGeneratorEStop TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's emergency stop input has been activated. - After the emergency stop signal has been removed, the E-Stop condition - must be cleared before the generator can be started again. - E-Stop conditions can only be cleared via the generator front panel. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code. - The fourth argument is the type of E-Stop (1=LOCAL, 2=REMOTE)." - --#TYPE "APC XGEN: Generator emergency stop engaged." - --#SUMMARY "Generator emergency stop engaged." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 439 - -xATSGeneratorEStopCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's emergency stop condition has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code. - The fourth argument is the type of E-Stop (1=LOCAL, 2=REMOTE)." - --#TYPE "APC XGEN: Generator emergency stop condition cleared." - --#SUMMARY "Generator emergency stop condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 440 - -xATSGeneratorHighBatteryVolt TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The generator's battery voltage has been detected as high. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high battery voltage." - --#SUMMARY "Generator high battery volts." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 441 - -xATSGeneratorHighBatteryVoltCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected high battery voltage has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high battery voltage condition cleared." - --#SUMMARY "Generator high battery volts condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 442 - -xATSGeneratorLowBatteryVolt TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's battery voltage has been detected as low. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low battery voltage." - --#SUMMARY "Generator low battery volts." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 443 - -xATSGeneratorLowBatteryVoltCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low battery voltage has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low battery voltage condition cleared." - --#SUMMARY "Generator low battery volts condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 444 - -xATSGeneratorControlSwitchNotAuto TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The control switch on the generator is not in auto position. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator not-in-automatic mode." - --#SUMMARY "Generator not-in-auto." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 445 - -xATSGeneratorControlSwitchNotAutoCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The control switch on the generator is in auto position. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator automatic mode restored." - --#SUMMARY "Generator not-in-auto cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 446 - -xATSGeneratorLowOilPressure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's oil pressure has been detected as low. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil pressure." - --#SUMMARY "Generator low oil pressure." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 447 - -xATSGeneratorLowOilPressureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low oil pressure has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil pressure condition cleared." - --#SUMMARY "Generator low oil pressure condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 448 - -xATSGeneratorVeryLowOilPressure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's oil pressure has been detected as very low. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator v.low oil pressure." - --#SUMMARY "Generator v.low oil pressure." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 449 - -xATSGeneratorVeryLowOilPressureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected v.low oil pressure has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator v.low oil pressure condition cleared." - --#SUMMARY "Generator v.low oil pressure condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 450 - -xATSGeneratorOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator is overloaded. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator is in overload event." - --#SUMMARY "Generator on overload event." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 451 - -xATSGeneratorOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator is running within loading limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator is in overload event cleared." - --#SUMMARY "Generator on overload event cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 452 - -xATSGeneratorLowACVEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator AC voltage is outside the acceptable bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage." - --#SUMMARY " State of the Generator ac voltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 453 - -xATSGeneratorLowACVEventCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator AC voltage is within normal bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage cleared." - --#SUMMARY "State of the Generator ac voltage cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 454 - -xATSGeneratorHighACVEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator AC voltage is outside the acceptable bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage." - --#SUMMARY " State of the Generator ac voltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 455 - -xATSGeneratorHighACVEventCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator AC voltage is within normal bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage cleared." - --#SUMMARY "State of the Generator ac voltage cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 456 - -xATSGeneratorOverspeed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator is running over the acceptable RPM. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator overspeed condition." - --#SUMMARY "Generator overspeed condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 457 - -xATSGeneratorOverspeedCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator overspeed shutdown has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator overspeed condition cleared." - --#SUMMARY "Generator overspeed condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 458 - -xATSGeneratorEngineCold TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator engine is cold, may not start. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator engine is cold, may not start." - --#SUMMARY "Generator engine is cold." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 459 - -xATSGeneratorEngineColdCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The engine is not cold to start. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Engine is cold to start condition cleared." - --#SUMMARY "Engine is cold to start condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 460 - -xATSGeneratorOutputBreakerOpen TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generators output breaker has been detected as open. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator output breaker open alarm." - --#SUMMARY "Generator output breaker open." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 461 - -xATSGeneratorOutputBreakerOpenCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The engine is not cold to start. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator output breaker open alarm cleared." - --#SUMMARY "Generator output breaker open cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 462 - -xATSGeneratorLowFuelLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The tank fuel level is below the limits specified - in the xATSGeneratorFuelSystemLowFuelLevelThreshold OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured fuel level in percent of full." - --#TYPE "APC XGEN: Low fuel level alarm." - --#SUMMARY "Generator low fuel level alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 463 - -xATSGeneratorLowFuelLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The tank fuel level is back above the specified limit. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Low fuel level alarm cleared." - --#SUMMARY "Generator low fuel level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 464 - -xATSGeneratorVeryLowFuelLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The tank fuel level is below the low threshold limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured tank fuel level in percent of full." - --#TYPE "APC XGEN: Very Low fuel level alarm." - --#SUMMARY "Generator very low fuel level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 465 - -xATSGeneratorVeryLowFuelLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low tank level has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Very low fuel level alarm cleared." - --#SUMMARY "Generator very low fuel level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 466 - -xATSGeneratorLowRunTimeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The estimated runtime is below the limits specified. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the estimated runtime in hours." - --#TYPE "APC XGEN: Low run time alarm." - --#SUMMARY "Generator low run time alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 467 - -xATSGeneratorLowRunTimeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low runtime has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Low run time alarm cleared." - --#SUMMARY "Generator low run time alarm." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 468 - -xATSGeneratorVeryLowRunTimeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The estimated runtime is below the limits specified - in the xATSGeneratorFuelSystemVeryLowRunTimeThreshold OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the estimated runtime in hours." - --#TYPE "APC XGEN: Very low run time alarm." - --#SUMMARY "Generator very low run time alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 469 - -xATSGeneratorVeryLowRunTimeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low runtime has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Very low run time alarm cleared." - --#SUMMARY "Generator very low run time alarm." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 470 - -xATSGeneratorServiceDueAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The generator is due for scheduled service. - Generation of this alarm is based on calender days since - and/or actual generator run-hours since last service. - This alarm is cleared using the xATSGeneratorServiceResetRecord OID. - - (See also: xATSGeneratorServiceCalendarIntervalThreshold - and xATSGeneratorServiceRunHoursThreshold OIDs) - - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator scheduled maintenance is due." - --#SUMMARY "Generator maintenance due." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 471 - -xATSGeneratorServiceDueAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's service registers have been reset. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator service due alarm is cleared." - --#SUMMARY "Generator service alarm is cleard." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 472 - -xATSGeneratorShutdown TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator is shutdown. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator shutdown." - --#SUMMARY "Generator shutdown" - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 473 - -xATSGeneratorShutdownCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator shutdown alarm is cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator shutdown is cleared." - --#SUMMARY "Generator shutdown is cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 474 - -xATSGeneratorBatteryCharger TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator battery charger is nonfunctional. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator batt. charger is nonfunctional." - --#SUMMARY "Generator battery charger is nonfunctional" - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 475 - -xATSGeneratorBatteryChargerCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: nonfunctionality of the generator battery is cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: " Nonfunctionality of battery charger is cleared." - --#SUMMARY "non-functionality of Generator battery charger is cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 476 - -xATSGeneratorGenericEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Any generic generator event. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator generic event." - --#SUMMARY "Generator generic event." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 477 - -xATSGeneratorGenericEventCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Generated generic generator event is cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generic generator event is cleared." - --#SUMMARY "Generic generator event is cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 478 - --- xPDU Traps (part 2) - -xPDUInternalCommErrorCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Internal communication has been restored. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Internal Communication error cleared." - --#SUMMARY "Communication error cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 479 - -xPDUSystemStateAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The PDU's breakers (Q1, Q2 & Q3) are in a configuration that might lead - to system unavailability. it may signify a temporary condition, when the breakers - are placed in an atypical manner as the user transitions to (UPS OPERATION or MAINTENANCE BYPASS) - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of alarm - (1=NO UPS INPUT, 2=NO PANEL FEED, 3=ATYPICAL BYPASS MODE)." - --#TYPE "APC XPDU: System state alarm ." - --#SUMMARY "PDU state alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 480 - -xPDUSystemStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The PDU's breakers (Q1, Q2 & Q3) are set in a configuration - that is a non-alarm state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of alarm (1=UPS OPERATION, 2=MAINTENANCE BYPASS)." - --#TYPE "APC XPDU: System state returned to normal." - --#SUMMARY "PDU state normal." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 481 - -xPDUEpoTestMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The device's Emergency Power Off (EPO) circuit has been - switched back to the test position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Emergency Power Off (EPO) in test mode." - --#SUMMARY "EPO disabled." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 482 - -xPDUEpoArmed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's Emergency Power Off (EPO) circuit has been - switched back to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Emergency Power Off (EPO) enabled." - --#SUMMARY "EPO armed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 483 - -xPDUFuseBlownAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: One or more fuses in this PDU have been detected as open. - These fuses are in the feed to the UPS associated with this PDU. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3)." - --#TYPE "APC XPDU: Check fuse alarm." - --#SUMMARY "Fuse detected opened." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 484 - -xPDUFuseBlownAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A previous check fuse alarm in this PDU has cleared. - These fuses are in the feed to the UPS associated with this PDU. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3)." - --#TYPE "APC XPDU: Check fuse alarm cleared." - --#SUMMARY "Fuse alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 485 - -xPDUBreakerPositionAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "SEVERE: A PDU breaker is in a state that compromises system availability. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the breaker (1=MAIN INPUT, 2=BYPASS INPUT, 3=CROSS TIE). - The fourth argument is the breaker position (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Breaker position alarm." - --#SUMMARY "Breaker position alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 486 - -xPDUBreakerPositionAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A PDU breaker is no longer in a state that compromises system availability. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the breaker (1=MAIN INPUT, 2=BYPASS INPUT, 3=CROSS TIE)." - --#TYPE "APC XPDU: Breaker position alarm cleared." - --#SUMMARY "Breaker alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 487 - -xPDUBreakerChangeEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A system breaker or switch within the device has changed state. - They are generated when any of the Q1, Q2 or Q3 breakers have changed states. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the breaker that has changed - (1=UPS FEED (Q1), 2=UPS OUTPUT(Q2), 3=MAINTENANCE BYPASS (Q3). - The fourth argument is the state of the breaker that has changed (1=OPEN, 2=CLOSED). - The fifth argument is a 8-bit field representing the state of all breakers in the system, - when any of one of the Q1, Q2 or Q3 breakers have changed state. - - The bit map is represented in the following manner (b7, b6 ... b0) - b0 - UPS FEED (Q1) - b1 - MAINTENANCE BYPASS (Q3) - b2 - UPS OUTPUT (Q2) - b3 - MAIN INPUT - b4 - BYPASS INPUT - b5 - CROSS-TIE OUTPUT - - Example: value of 60 (0x3C) indicates that the CROSS_TIE, BYPASS and MAIN INPUT, and Q2 breakers - are CLOSED and Q2, Q1 breakers are OPEN." - --#TYPE "APC XPDU: Breaker/switch change event." - --#SUMMARY "Breaker/switch change event." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 488 - -xPDUControllerFirmwareUpdateTransferStart TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Start Controller firmware transfer in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Start controller firmware transfer." - --#SUMMARY "Start controller firmware transfer." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 489 - -xPDUControllerFirmwareUpdateTransferComplete TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Transfer of Controller firmware was completed in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Controller firmware transfer completed." - --#SUMMARY "Controller firmware transfer completed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 490 - -xPDUControllerFirmwareUpdateTransferFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: Transfer of Controller firmware has failed in the PDU. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Controller firmware transfer failed." - --#SUMMARY "Controller firmware transfer failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 491 - -xATSControllerFirmwareUpdateTransferStart TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Start Controller firmware transfer in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Start controller firmware transfer." - --#SUMMARY "Start controller firmware transfer." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 492 - -xATSControllerFirmwareUpdateTransferComplete TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Transfer of Controller firmware was completed in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Controller firmware transfer completed." - --#SUMMARY "Controller firmware transfer completed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 493 - -xATSControllerFirmwareUpdateTransferFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: Transfer of Controller firmware has failed in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Controller firmware transfer failed." - --#SUMMARY "Controller firmware transfer failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 494 - -apcDeviceShutdownHeartbeat TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsTimeTicks, mtrapargsString} - DESCRIPTION - "INFORMATIONAL: " - --#TYPE "APC X:" - --#SUMMARY "." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 999 - -apcDiscoveryAlarmStateTableUpdate TRAP-TYPE - ENTERPRISE apc - VARIABLES { apcDiscoveryDeviceAlarmStateChangeCount } - DESCRIPTION - "INTERNAL: A Discovery Alarm State Table Update trap is sent - when any data alarm state is added, removed, or its parameters - are changed in the condition table. This trap is - only for machine-to-machine communication. " - --#TYPE "APC X:" - --#SUMMARY "." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 1000 - -END diff --git a/fence/agents/apc_snmp/Makefile b/fence/agents/apc_snmp/Makefile deleted file mode 100644 index 11d8495..0000000 --- a/fence/agents/apc_snmp/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -include ${top_srcdir}/make/defines.mk - - -SOURCE= fence_apc_snmp.py -TARGET= fence_apc_snmp - -RESOURCES = powernet369.mib README_SNMP - - -all: $(TARGET) ${RESOURCES} - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: all - for v in $(TARGET) ${RESOURCES}; do \ - cp $${v} ${top_srcdir}/bin/$${v}; \ - done - - -.PHONY: clean -clean: - rm -f $(TARGET) diff --git a/fence/agents/apc_snmp/README_SNMP b/fence/agents/apc_snmp/README_SNMP deleted file mode 100644 index 37adffb..0000000 --- a/fence/agents/apc_snmp/README_SNMP +++ /dev/null @@ -1,47 +0,0 @@ -This is an snmp based fence agent for APC power switches to be used -with RHEL4 Red Hat Cluster Suite. - -The reasons to use this agent rather than the current fence_apc agent are: -1) This script has been tested with EVERY powerswitch that APC currently -makes. -2) It will work on many older models that are no longer supported by APC. -I have been told that it even works with the AP9200 switch. Older switches -usually don't do well with the fence_apc script. -3) This agent works with large power switches that have more than 8 outlets. -The fence_apc script will also, in the next update -- this script will work for you now. - -If feedback on this beta version of the agent is good, and if ganged switches -can be supported, then this agent may replace fence_apc. - -In order to use this agent, you will need to have net-snmp-utils installed -on every node in your cluster. net-snmp-utils is scheduled for inclusion -in the base RHEL distribution for Update 4, and is yummable in FC5. - -After net-snmp-utils is installed, there will be a directory named: -/usr/share/snmp/mibs/ - -Place the accompanying powernet369.mib file in this directory. - -To use the agent, cp the agent to the /sbin directory on every -cluster node. The interface for the fence_apc_snmp agent is identical to -the existing fence_apc agent, so if you are using APC for fencing in -your cluster, you *could* backup your current fence_apc agent, and -rename this agent from fence_apc_snmp to fence_apc, and it should just work. - -NOTE: The fence_apc_snmp agent does not yet support ganged or 'daisy-chained' -APC switches. - -If you would rather not copy over your fence_apc agent, you can still use -the fence_apc_snmp agent by dropping it into /sbin on every node, and then -defining a <fencedevice> in the cluster.conf file with agent="fence_apc_snmp" -as an attribute, and use it that way. Note, please, that the GUI does -not support this agent yet, and you will have to edit your cluster.conf -by hand and then propagate it yourself. If you need help with this, email -me on linux-cluster or at the address below. - -Big thanks to Nate Straz who laid the foundation for this agent. - -Please let me know how this agent works. ---Jim Parsons - jparsons@redhat.com - -Copyright (C) Red Hat, Inc. 2006 All rights reserved. diff --git a/fence/agents/apc_snmp/fence_apc_snmp.py b/fence/agents/apc_snmp/fence_apc_snmp.py deleted file mode 100755 index 3078a9e..0000000 --- a/fence/agents/apc_snmp/fence_apc_snmp.py +++ /dev/null @@ -1,469 +0,0 @@ -#!/usr/bin/python - -############################################################################# -############################################################################# -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################# -## This APC Fence script uses snmp to control the APC power -## switch. This script requires that net-snmp-utils be installed -## on all nodes in the cluster, and that the powernet369.mib file be -## located in /usr/share/snmp/mibs/ -############################################################################# -############################################################################# - - - -import getopt, sys -import os -import datetime -import time -import select -import signal -from glob import glob - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -POWER_ON="outletOn" -POWER_OFF="outletOff" -POWER_REBOOT="outletReboot" - - -# oid defining fence device -oid_sysObjectID = '.1.3.6.1.2.1.1.2.0' - - - -class SNMP: - def __init__(self, params): - self.hostname = params['ipaddr'] - self.udpport = params['udpport'] - self.community = params['community'] - - def get(self, oid): - args = ['/usr/bin/snmpget'] - args.append('-Oqn') - args.append('-v') - args.append('1') - args.append('-c') - args.append(self.community) - args.append('-m') - args.append('ALL') - args.append(self.hostname + ':' + self.udpport) - args.append(oid) - strr, code = execWithCaptureStatus("/usr/bin/snmpget", args) - if code: - raise Exception, 'snmpget failed' - l = strr.strip().split() - return l[0], ' '.join(l[1:]) - - def set_int(self, oid, value): - args = ['/usr/bin/snmpset'] - args.append('-Oqn') - args.append('-v') - args.append('1') - args.append('-c') - args.append(self.community) - args.append('-m') - args.append('ALL') - args.append(self.hostname + ':' + self.udpport) - args.append(oid) - args.append('i') - args.append(str(value)) - strr,code = execWithCaptureStatus("/usr/bin/snmpset", args) - if code: - raise Exception, 'snmpset failed' - - def walk(self, oid): - args = ['/usr/bin/snmpwalk'] - args.append('-Oqn') - args.append('-v') - args.append('1') - args.append('-c') - args.append(self.community) - args.append('-m') - args.append('ALL') - args.append(self.hostname + ':' + self.udpport) - args.append(oid) - strr,code = execWithCaptureStatus("/usr/bin/snmpwalk", args) - if code: - raise Exception, 'snmpwalk failed' - lines = strr.strip().splitlines() - ret = [] - for line in lines: - l = line.strip().split() - ret.append((l[0], ' '.join(l[1:]).strip('"'))) - return ret - - - -class FenceAgent: - - def __init__(self, params): - self.snmp = SNMP(params) - - def resolve_outlet(self): - raise Exception, 'resolve_outlet() not implemented' - - def status(self): - oid = self.status_oid % self.resolve_outlet() - dummy, stat = self.snmp.get(oid) - if stat == self.state_on or stat == "outletStatusOn": - return 'on' - elif stat == self.state_off or stat == "outletStatusOff": - return 'off' - else: - raise Exception, 'invalid status ' + stat - - def power_off(self): - oid = self.control_oid % self.resolve_outlet() - self.snmp.set_int(oid, self.turn_off) - - def power_on(self): - oid = self.control_oid % self.resolve_outlet() - self.snmp.set_int(oid, self.turn_on) - - - - - - - - -class MasterSwitch(FenceAgent): - - def __init__(self, params): - FenceAgent.__init__(self, params) - - self.status_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4.%s' - self.control_oid = '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%s' - self.outlet_table_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.2' - - self.state_on = '1' - self.state_off = '2' - - self.turn_on = '1' - self.turn_off = '2' - - self.port = params['port'] - - def resolve_outlet(self): - outlet = None - try: - outlet = str(int(self.port)) - except: - table = self.snmp.walk(self.outlet_table_oid) - for row in table: - if row[1] == self.port: - t = row[0].strip().split('.') - outlet = t[len(t)-1] - if outlet == None: - raise Exception, 'unable to resolve ' + self.port - else: - self.port = outlet - return outlet - - -class MasterSwitchPlus(FenceAgent): - def __init__(self, params): - FenceAgent.__init__(self, params) - - self.status_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.5.%s.1.%s' - self.control_oid = '.1.3.6.1.4.1.318.1.1.6.5.1.1.5.%s.1.%s' - self.outlet_table_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.4' - - self.state_on = '1' - self.state_off = '2' - - self.turn_on = '1' - self.turn_off = '3' - - try: - self.switch = params['switch'] - except: - self.switch = '' - self.port = params['port'] - - def resolve_outlet(self): - switch = None - outlet = None - try: - switch = str(int(self.switch)) - outlet = str(int(self.port)) - except: - table = self.snmp.walk(self.outlet_table_oid) - for row in table: - if row[1] == self.port: - t = row[0].strip().split('.') - outlet = t[len(t)-1] - switch = t[len(t)-3] - if outlet == None: - raise Exception, 'unable to resolve ' + self.port - else: - self.switch = switch - self.port = outlet - return (switch, outlet) - - - - - - -def usage(): - print "Usage:" - print "" - print "Options:" - print " -h Usage" - print " -a <ip> IP address or hostname of fence device" - print " -u <udpport> UDP port to use (default 161)" - print " -c <community> SNMP community (default 'private')" - print " -n <num> Outlet name/number to act on" - print " -o <string> Action: Reboot (default), On, Off and Status" - print " -v <filename> Verbose mode - write to file" - print " -V Version" - - sys.exit(0) - - - -file_log = None -def set_logging(verbose, verbose_filename): - global file_log - if verbose: - file_log = open(verbose_filename, 'a') - file_log.write('\n----------- ') - file_log.write(datetime.datetime.today().ctime()) - file_log.write(' -----------\n') -def log(msg, error=False): - global file_log - if msg.rfind('\n') != len(msg)-1: - msg += '\n' - if file_log != None: - file_log.write(msg) - if error: - o = sys.stderr - else: - o = sys.stdout - o.write(msg) - - - -def main(): - try: - main2() - return 0 - except Exception, e: - log(str(e), True) - sys.exit(1) -def main2(): - - agents_dir = {'.1.3.6.1.4.1.318.1.3.4.5' : MasterSwitch, - '.1.3.6.1.4.1.318.1.3.4.4' : MasterSwitchPlus} - - verbose = False - params = {} - - if len(sys.argv) > 1: - try: - opts, args = getopt.getopt(sys.argv[1:], "ha:u:c:n:o:v:V", ["help", "output="]) - except getopt.GetoptError: - usage() - sys.exit(2) - - for o, a in opts: - o = o.strip() - a = a.strip() - if o == "-v": - verbose = True - verbose_filename = a - if o == "-V": - print "%s\n" % FENCE_RELEASE_NAME - print "%s\n" % REDHAT_COPYRIGHT - print "%s\n" % BUILD_DATE - sys.exit(0) - if o in ("-h", "--help"): - usage() - sys.exit(0) - if o == "-a": - params['ipaddr'] = a - if o == "-u": - params['udpport'] = a - if o == "-c": - params['community'] = a - if o == "-n": - switch = '' - port = a - if ':' in port: - idx = port.find(':') - switch = port[:idx] - port = port[idx+1:] - params['switch'] = switch - params['port'] = port - if o == "-o": - params['option'] = a.lower() - - else: #Get opts from stdin - for line in sys.stdin: - val = line.strip().split("=") - if len(val) == 2: - o = val[0].strip().lower() - a = val[1].strip() - if o == 'verbose': - if a.lower() == 'on' or a.lower() == 'true' or a == '1': - verbose = True - else: - params[o] = a - - - set_logging(verbose, verbose_filename) - - - ### validation ### - - try: - if params['ipaddr'] == '': - raise Exception, 'missing ipadddr' - except: - log("FENCE: Missing ipaddr param for fence_apc_snmp...exiting", True) - sys.exit(1) - if 'udpport' not in params: - params['udpport'] = '161' - try: - t = int(params['udpport']) - if t >= 65536 or t < 0: - raise Exception, 'invalid udpport' - except: - log("FENCE: Invalid udpport for fence_apc_snmp...exiting", True) - sys.exit(1) - if 'community' not in params: - params['community'] = 'private' - try: - port = params['port'] - if len(port) == 0: - raise Exception, 'missing port' - except: - log("FENCE: Missing port param for fence_apc_snmp...exiting", True) - sys.exit(1) - if 'switch' not in params: - params['switch'] = '' - try: - act = params['option'].lower() - if act in ['on', 'off', 'reboot', 'status']: - params['option'] = act - else: - usage() - sys.exit(3) - except: - params['option'] = 'reboot' - - ### End of validation ### - - if verbose: - log('called with ' + str(params)) - - agent = None - dummy, sys_id = SNMP(params).get(oid_sysObjectID) - if sys_id not in agents_dir: - log('Fence device with 'oid_sysObjectID=' + sys_id + '' is not supported', True) - sys.exit(1) - agent = agents_dir[sys_id](params) - - if params['option'] == 'status': - log('Outlet "%s" - %s is %s' % (params['port'], - str(agent.resolve_outlet()), - agent.status())) - elif params['option'] == 'on': - agent.power_on() - time.sleep(5) - if agent.status() != 'on': - raise Exception, 'Error turning outlet on' - elif params['option'] == 'off': - agent.power_off() - time.sleep(5) - if agent.status() != 'off': - raise Exception, 'Error turning outlet off' - elif params['option'] == 'reboot': - agent.power_off() - time.sleep(5) - if agent.status() != 'off': - raise Exception, 'Error turning outlet off' - agent.power_on() - time.sleep(5) - if agent.status() != 'on': - raise Exception, 'Error turning outlet on' - else: - print 'nothing to do' - sys.exit(1) - pass - - - -def execWithCaptureStatus(command, argv, searchPath = 0, root = '/', stdin = 0, - catchfd = 1, closefd = -1): - - if not os.access (root + command, os.X_OK): - raise Exception, command + " cannot be run" - - (read, write) = os.pipe() - - childpid = os.fork() - if (not childpid): - if (root and root != '/'): os.chroot (root) - if isinstance(catchfd, tuple): - for fd in catchfd: - os.dup2(write, fd) - else: - os.dup2(write, catchfd) - os.close(write) - os.close(read) - - if closefd != -1: - os.close(closefd) - - if stdin: - os.dup2(stdin, 0) - os.close(stdin) - - if (searchPath): - os.execvp(command, argv) - else: - os.execv(command, argv) - - sys.exit(1) - - os.close(write) - - rc = "" - s = "1" - while (s): - select.select([read], [], []) - s = os.read(read, 1000) - rc = rc + s - - os.close(read) - - try: - (pid, status) = os.waitpid(childpid, 0) - except OSError, (errno, msg): - print __name__, "waitpid:", msg - - if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0): - status = os.WEXITSTATUS(status) - else: - status = -1 - - return (rc, status) - -if __name__ == "__main__": - ret = main() - sys.exit(ret) diff --git a/fence/agents/apc_snmp/powernet369.mib b/fence/agents/apc_snmp/powernet369.mib deleted file mode 100644 index ab948f8..0000000 --- a/fence/agents/apc_snmp/powernet369.mib +++ /dev/null @@ -1,31109 +0,0 @@ --- ************************************************************************* --- AMERICAN POWER CONVERSION PowerNet-MIB --- ************************************************************************* --- Copyright (c) 2005 American Power Conversion, Inc. --- PowerNet is a Trademark of American Power Conversion Corp. --- --- Title: APC TOP LEVEL PowerNet MIB --- --- Version : 3.6.9 --- --- Generated by script: tomib.awk --- --- Input File: powernetPS.mib --- --- Created: Wednesday, January, 26, 2005 --- --- Revision History: --- ************************************************************************* - --- - v3.2.0 Added functionality for MasterSwitch Plus --- - v3.3.0 Added functionality for MX28B (dcDM3) and 3-phase UPS --- - v3.3.2 New traps for Symmetra PX UPS --- 07/15/01 - v3.4.0 Added transfer switch --- - v3.4.3 Added functionality for External and Integrated Environmental Monitor --- 06/14/02 - v3.4.4 Added dcmim2(Siemens) branch, Battery Manager(Reading) traps, and --- Psx Traps for PDU and RM-PDU and Netlock branch/traps --- 06/18/02 - v3.5.0a Sync Control Group support --- 08/06/02 - v3.5.0a Environmental Management System branch/traps --- 09/16/02 - v3.5.0b Fixed some odds/ends ... going to RM-PDU for MS additions --- 09/25/02 - v3.5.0c MS3 additions --- 11/05/02 - v3.5.0e More Environmental Management System/A-Link devices(ARU) --- 11/22/02 - v3.5.0g Added General APC device status OID --- 11/27/02 - v3.5.0h Wrapped up MS3 ((Controlled or Metered) Rack PDU) changes --- 12/26/02 - v3.5.1a Changed MS3 name again, Controlled to Switched Rack PDU --- 01/07/03 - v3.6.0a Added OIDs/Traps for UPS Switchable Outlet Groups. --- 01/09/03 - Adding the General APC device discovery OIDs (hidden) --- 01/28/03 - v3.6.0c Made some small trap pair fixes for Switched Rack PDU (MS3) --- 02/13/03 - v3.6.0d Mods from the review and some EMS fixes. --- Added OID for the new 20kVA Symmetra 3 Phase type. --- Added OIDs to upsAdvConfig for Symmetra type UPSs. --- Added upsDiagnostics branch OID for Symmetra module information. --- 04/05/03 - v3.6.2 Added OID for the new Smart-UPS 7500 and 10000 types. --- 06/04/03 - v3.6.3 Added OIDs/Traps for AirFM. --- 06/24/03 - v3.6.4 Moved some AirFM temps and humidities from system level to module level. --- 10/24/03 - v3.6.4a Added OIDs/Traps for xPDU. --- 10/27/03 - v3.6.4f Added AirPA OIDs. --- 11/03/03 - v3.6.4g Merge of 3.6.4e and 3.6.4f --- 11/07/03 - v3.6.4h Additional review corrections --- 12/01/03 - v3.6.5a Added group OIDs for Air FM. Added C & F OIDs for Air PA setpoint. --- 12/19/03 - v3.6.5b Review corrections. --- 02/23/04 - v3.6.5c Added Modbus to experimental and multiple CB(bank) rPDU support --- 05/05/04 - v3.6.6 Adding EMS status OID and trap for H/W issues, redefined duplicate --- trap #228 (to ARU Device config change) and minor clean-up --- 05/12/04 - v3.6.7a Added Air FM alarm status OIDs. --- 06/03/04 - v3.6.7b Added UPS Config for Simple Signal Shutdowns and Number of External --- batteries. Added Mute option to the UPS Config Audible Alarm. --- 07/12/04 - v3.6.7d Removed Air FM alarm status OIDs due to delay in release. --- 07/14/04 - v3.6.7d Added a detailed description to the UPSAdvConfigAlarm OID --- 07/14/04 - v3.6.7e Added Custom Event traps --- 08/04/04 - v3.6.7 Tag for final builds, see v3.6.7 beta build notes for changes --- 08/26/04 - v3.6.8a Added new traps for UPS internal over temperature fault and cleared. --- 09/01/04 - v3.6.8b Adding new thresholds for EMS probe config & status --- 09/08/04 - v3.6.8c Corrections from MIB review. --- 09/30/04 - v3.6.8d Added new traps for AIS ^F Message events. --- 10/21/04 - v3.6.8e EMS. Added missing traps and new Rate functionality. --- 10/22/04 - v3.6.8f Added resetNetworkLeaveModeAndRestart option to the mcontrolRestartAgent OID. --- 10/28/04 - v3.6.8g Updated EMS sections from mib committee review. --- 11/22/04 - v3.6.8 Tag for final build. --- 12/02/04 - v3.6.9a Added OIDs and traps for BMS-HVA. --- 12/20/04 - v3.6.9c corrections to xPDU. --- 12/20/04 - v3.6.9c added OIDs and traps for xATS. --- 01/03/05 - v3.6.9d removed traps for xATS. --- 01/03/05 - v3.6.9e correction to xATS entries, that removed underscores (mib browser incompatibility) --- 01/07/05 - v3.6.9f --- 01/14/05 - v3.6.9g add xPDU OIDs and traps and some corrections. --- 01/14/05 - v3.6.9g modifications to xATS OIDs and traps. - --- ************************************************************************* --- ************************************************************************* --- PowerNet-MIB { iso org(3) dod(6) internet(1) private(4) --- enterprises(1) apc(318) } - -PowerNet-MIB DEFINITIONS ::= BEGIN - -IMPORTS - enterprises, IpAddress, Gauge, TimeTicks FROM RFC1155-SMI - DisplayString FROM RFC1213-MIB - OBJECT-TYPE FROM RFC-1212 - TRAP-TYPE FROM RFC-1215; - -apc OBJECT IDENTIFIER ::= { enterprises 318 } - -products OBJECT IDENTIFIER ::= { apc 1 } -apcmgmt OBJECT IDENTIFIER ::= { apc 2 } - -hardware OBJECT IDENTIFIER ::= { products 1 } -software OBJECT IDENTIFIER ::= { products 2 } -system OBJECT IDENTIFIER ::= { products 3 } -experimental OBJECT IDENTIFIER ::= { products 4 } - -mconfig OBJECT IDENTIFIER ::= { apcmgmt 1 } -mcontrol OBJECT IDENTIFIER ::= { apcmgmt 2 } -mtrapargs OBJECT IDENTIFIER ::= { apcmgmt 3 } -mfiletransfer OBJECT IDENTIFIER ::= { apcmgmt 4 } - -mconfigClock OBJECT IDENTIFIER ::= { mconfig 6 } - -mfiletransferStatus OBJECT IDENTIFIER ::= { mfiletransfer 1 } -mfiletransferConfig OBJECT IDENTIFIER ::= { mfiletransfer 2 } -mfiletransferControl OBJECT IDENTIFIER ::= { mfiletransfer 3 } - -mfiletransferConfigSettings OBJECT IDENTIFIER ::= { mfiletransferConfig 1 } -mfiletransferConfigTFTP OBJECT IDENTIFIER ::= { mfiletransferConfig 2 } -mfiletransferConfigFTP OBJECT IDENTIFIER ::= { mfiletransferConfig 3 } - -ups OBJECT IDENTIFIER ::= { hardware 1 } -measureUps OBJECT IDENTIFIER ::= { hardware 2 } -miniSNMPadapter OBJECT IDENTIFIER ::= { hardware 3 } -masterswitch OBJECT IDENTIFIER ::= { hardware 4 } -masterswitchVM OBJECT IDENTIFIER ::= { hardware 5 } -masterswitchMSP OBJECT IDENTIFIER ::= { hardware 6 } -dcDM3 OBJECT IDENTIFIER ::= { hardware 7 } -automaticTransferSwitch OBJECT IDENTIFIER ::= { hardware 8 } -dc2 OBJECT IDENTIFIER ::= { hardware 9 } -environmentalMonitor OBJECT IDENTIFIER ::= { hardware 10 } -netlock OBJECT IDENTIFIER ::= { hardware 11 } -rPDU OBJECT IDENTIFIER ::= { hardware 12 } -airConditioners OBJECT IDENTIFIER ::= { hardware 13 } -rARU OBJECT IDENTIFIER ::= { hardware 14 } -xPDU OBJECT IDENTIFIER ::= { hardware 15 } -battMan OBJECT IDENTIFIER ::= { hardware 16 } -xATS OBJECT IDENTIFIER ::= { hardware 17 } -generator OBJECT IDENTIFIER ::= { hardware 18 } - -powerNetSubAgent OBJECT IDENTIFIER ::= { software 1 } - -powerNetSoftwareSystem OBJECT IDENTIFIER ::= { powerNetSubAgent 1 } -powerNetSoftwareConfig OBJECT IDENTIFIER ::= { powerNetSubAgent 2 } - -backUPS OBJECT IDENTIFIER ::= { system 1 } -smartUPS OBJECT IDENTIFIER ::= { system 2 } -matrixUPS OBJECT IDENTIFIER ::= { system 3 } -masterSwitch OBJECT IDENTIFIER ::= { system 4 } -symmetraUPS OBJECT IDENTIFIER ::= { system 5 } -dp100E OBJECT IDENTIFIER ::= { system 6 } -dp300E OBJECT IDENTIFIER ::= { system 7 } -monitors OBJECT IDENTIFIER ::= { system 8 } -redundantSwitch OBJECT IDENTIFIER ::= { system 9 } -dcPower OBJECT IDENTIFIER ::= { system 10 } -automaticXferSwitch OBJECT IDENTIFIER ::= { system 11 } -netLock OBJECT IDENTIFIER ::= { system 12 } -symmetra3PhaseUPS OBJECT IDENTIFIER ::= { system 13 } -networkAir OBJECT IDENTIFIER ::= { system 14 } -infraXurePDU OBJECT IDENTIFIER ::= { system 15 } -ais5000UPS OBJECT IDENTIFIER ::= { system 16 } -smartUPS3Phase OBJECT IDENTIFIER ::= { system 17 } -battManager OBJECT IDENTIFIER ::= { system 18 } -infraXureATS OBJECT IDENTIFIER ::= { system 19 } - -battManIdent OBJECT IDENTIFIER ::= { battMan 1 } -battManSystemCalib OBJECT IDENTIFIER ::= { battMan 2 } -battManUnitCalib OBJECT IDENTIFIER ::= { battMan 3 } -battManStringCalib OBJECT IDENTIFIER ::= { battMan 4 } -battManBatteryCalib OBJECT IDENTIFIER ::= { battMan 5 } -battManConfig OBJECT IDENTIFIER ::= { battMan 6 } -battManAlarm OBJECT IDENTIFIER ::= { battMan 7 } -battManSystemStatus OBJECT IDENTIFIER ::= { battMan 8 } -battManStringStatus OBJECT IDENTIFIER ::= { battMan 9 } -battManBatteryStatus OBJECT IDENTIFIER ::= { battMan 10 } -battManInputContactStatus OBJECT IDENTIFIER ::= { battMan 11 } -battManControl OBJECT IDENTIFIER ::= { battMan 12 } -battManTestResults OBJECT IDENTIFIER ::= { battMan 13 } - -xPDUIdent OBJECT IDENTIFIER ::= { xPDU 1 } -xPDUDevice OBJECT IDENTIFIER ::= { xPDU 2 } -xPDUACMonitoringPoint OBJECT IDENTIFIER ::= { xPDU 3 } -xPDUCircuitBreakers OBJECT IDENTIFIER ::= { xPDU 4 } -xPDUInputContacts OBJECT IDENTIFIER ::= { xPDU 5 } -xPDUOutputRelays OBJECT IDENTIFIER ::= { xPDU 6 } -xPDUMiscGroup OBJECT IDENTIFIER ::= { xPDU 7 } - -xPDUMainInput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 1 } -xPDUBypassInput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 2 } -xPDUUPSInput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 3 } -xPDUSystemOutput OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 4 } -xPDUGroundMonitorPoint OBJECT IDENTIFIER ::= { xPDUACMonitoringPoint 5 } - -xPDUSystemBreakers OBJECT IDENTIFIER ::= { xPDUCircuitBreakers 1 } -xPDUBranchBreakers OBJECT IDENTIFIER ::= { xPDUCircuitBreakers 2 } - -xATSIdent OBJECT IDENTIFIER ::= { xATS 1 } -xATSDevice OBJECT IDENTIFIER ::= { xATS 2 } -xATSSwitch OBJECT IDENTIFIER ::= { xATS 3 } -xATSACMonitoringPoint OBJECT IDENTIFIER ::= { xATS 4 } -xATSTesting OBJECT IDENTIFIER ::= { xATS 5 } -xATSInputContacts OBJECT IDENTIFIER ::= { xATS 6 } -xATSOutputRelays OBJECT IDENTIFIER ::= { xATS 7 } -xATSMisc OBJECT IDENTIFIER ::= { xATS 8 } - -xATSSwitchStatus OBJECT IDENTIFIER ::= { xATSSwitch 1 } -xATSSwitchSettings OBJECT IDENTIFIER ::= { xATSSwitch 2 } -xATSSwitchTimers OBJECT IDENTIFIER ::= { xATSSwitch 3 } -xATSSwitchBlockMap OBJECT IDENTIFIER ::= { xATSSwitch 4 } -xATSSwitchStatistics OBJECT IDENTIFIER ::= { xATSSwitch 5 } - -xATSSource1 OBJECT IDENTIFIER ::= { xATSACMonitoringPoint 1 } -xATSSource2 OBJECT IDENTIFIER ::= { xATSACMonitoringPoint 2 } -xATSSystemOutput OBJECT IDENTIFIER ::= { xATSACMonitoringPoint 3 } - -xATSTestingStatus OBJECT IDENTIFIER ::= { xATSTesting 1 } -xATSTestingResults OBJECT IDENTIFIER ::= { xATSTesting 2 } -xATSTestingSchedule OBJECT IDENTIFIER ::= { xATSTesting 3 } -xATSTestingSimulatePowerFail OBJECT IDENTIFIER ::= { xATSTesting 4 } - -xATSGenerator OBJECT IDENTIFIER ::= { generator 1 } - -xATSGeneratorIdent OBJECT IDENTIFIER ::= { xATSGenerator 1 } -xATSGeneratorStatus OBJECT IDENTIFIER ::= { xATSGenerator 2 } -xATSGeneratorAdvStatus OBJECT IDENTIFIER ::= { xATSGenerator 3 } -xATSGeneratorOutput OBJECT IDENTIFIER ::= { xATSGenerator 4 } -xATSGeneratorSettings OBJECT IDENTIFIER ::= { xATSGenerator 5 } -xATSGeneratorService OBJECT IDENTIFIER ::= { xATSGenerator 6 } -xATSGeneratorFuelSystem OBJECT IDENTIFIER ::= { xATSGenerator 7 } - - -smartUPS250 OBJECT IDENTIFIER ::= { smartUPS 1 } -smartUPS400 OBJECT IDENTIFIER ::= { smartUPS 2 } -smartUPS600 OBJECT IDENTIFIER ::= { smartUPS 3 } -smartUPS900 OBJECT IDENTIFIER ::= { smartUPS 4 } -smartUPS1250 OBJECT IDENTIFIER ::= { smartUPS 5 } -smartUPS2000 OBJECT IDENTIFIER ::= { smartUPS 6 } - -smartUPS450 OBJECT IDENTIFIER ::= { smartUPS 7 } -smartUPS700 OBJECT IDENTIFIER ::= { smartUPS 8 } -smartUPS1000 OBJECT IDENTIFIER ::= { smartUPS 9 } -smartUPS1400 OBJECT IDENTIFIER ::= { smartUPS 10 } -smartUPS2200 OBJECT IDENTIFIER ::= { smartUPS 11 } -smartUPS3000 OBJECT IDENTIFIER ::= { smartUPS 12 } -smartUPS5000 OBJECT IDENTIFIER ::= { smartUPS 13 } -smartUPS7500 OBJECT IDENTIFIER ::= { smartUPS 14 } -smartUPS10000 OBJECT IDENTIFIER ::= { smartUPS 15 } -smartUPS1500 OBJECT IDENTIFIER ::= { smartUPS 16 } - -matrixUPS3000 OBJECT IDENTIFIER ::= { matrixUPS 1 } -matrixUPS5000 OBJECT IDENTIFIER ::= { matrixUPS 2 } - -masterSwitchV1 OBJECT IDENTIFIER ::= { masterSwitch 1} -masterSwitchV2 OBJECT IDENTIFIER ::= { masterSwitch 2} -masterSwitchVM OBJECT IDENTIFIER ::= { masterSwitch 3} -masterSwitchMSP OBJECT IDENTIFIER ::= { masterSwitch 4} -masterSwitchrPDU OBJECT IDENTIFIER ::= { masterSwitch 5} - -symmetraUPS4kVA OBJECT IDENTIFIER ::= { symmetraUPS 1 } -symmetraUPS8kVA OBJECT IDENTIFIER ::= { symmetraUPS 2 } -symmetraUPS12kVA OBJECT IDENTIFIER ::= { symmetraUPS 3 } -symmetraUPS16kVA OBJECT IDENTIFIER ::= { symmetraUPS 4 } - -environmental OBJECT IDENTIFIER ::= { monitors 1 } -environmentalMgtSystem OBJECT IDENTIFIER ::= { monitors 2 } -emu2 OBJECT IDENTIFIER ::= { monitors 3 } - -dm3 OBJECT IDENTIFIER ::= { dcPower 1 } -dcmim2 OBJECT IDENTIFIER ::= { dcPower 2 } - -symmetra3PhaseUPS40kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 1 } -symmetra3PhaseUPS60kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 2 } -symmetra3PhaseUPS80kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 3 } -symmetra3PhaseUPS20kVA OBJECT IDENTIFIER ::= { symmetra3PhaseUPS 4 } - -airFMSeries OBJECT IDENTIFIER ::= { networkAir 1 } -rackAirRemovalUnit OBJECT IDENTIFIER ::= { networkAir 2 } -airPASeries OBJECT IDENTIFIER ::= { networkAir 3 } - -ais5000UPS10kVA OBJECT IDENTIFIER ::= { ais5000UPS 1 } -ais5000UPS20kVA OBJECT IDENTIFIER ::= { ais5000UPS 2 } -ais5000UPS30kVA OBJECT IDENTIFIER ::= { ais5000UPS 3 } -ais5000UPS40kVA OBJECT IDENTIFIER ::= { ais5000UPS 4 } -ais5000UPS60kVA OBJECT IDENTIFIER ::= { ais5000UPS 5 } -ais5000UPS80kVA OBJECT IDENTIFIER ::= { ais5000UPS 6 } -ais5000UPS100kVA OBJECT IDENTIFIER ::= { ais5000UPS 7 } - -smartUPS3Phase10kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 1 } -smartUPS3Phase15kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 2 } -smartUPS3Phase20kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 3 } -smartUPS3Phase30kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 4 } -smartUPS3Phase40kVA OBJECT IDENTIFIER ::= { smartUPS3Phase 5 } - -upsIdent OBJECT IDENTIFIER ::= { ups 1 } -upsBattery OBJECT IDENTIFIER ::= { ups 2 } -upsInput OBJECT IDENTIFIER ::= { ups 3 } -upsOutput OBJECT IDENTIFIER ::= { ups 4 } -upsConfig OBJECT IDENTIFIER ::= { ups 5 } -upsControl OBJECT IDENTIFIER ::= { ups 6 } -upsTest OBJECT IDENTIFIER ::= { ups 7 } -upsComm OBJECT IDENTIFIER ::= { ups 8 } -upsPhase OBJECT IDENTIFIER ::= { ups 9 } -upsSyncCtrlGroup OBJECT IDENTIFIER ::= { ups 10 } -upsState OBJECT IDENTIFIER ::= { ups 11 } -upsOutletGroups OBJECT IDENTIFIER ::= { ups 12 } -upsDiagnostics OBJECT IDENTIFIER ::= { ups 13 } - -upsBasicIdent OBJECT IDENTIFIER ::= { upsIdent 1 } -upsAdvIdent OBJECT IDENTIFIER ::= { upsIdent 2 } - -upsBasicBattery OBJECT IDENTIFIER ::= { upsBattery 1 } -upsAdvBattery OBJECT IDENTIFIER ::= { upsBattery 2 } - -upsBasicInput OBJECT IDENTIFIER ::= { upsInput 1 } -upsAdvInput OBJECT IDENTIFIER ::= { upsInput 2 } - -upsBasicOutput OBJECT IDENTIFIER ::= { upsOutput 1 } -upsAdvOutput OBJECT IDENTIFIER ::= { upsOutput 2 } - -upsBasicConfig OBJECT IDENTIFIER ::= { upsConfig 1 } -upsAdvConfig OBJECT IDENTIFIER ::= { upsConfig 2 } - -upsBasicControl OBJECT IDENTIFIER ::= { upsControl 1 } -upsAdvControl OBJECT IDENTIFIER ::= { upsControl 2 } - -upsBasicTest OBJECT IDENTIFIER ::= { upsTest 1 } -upsAdvTest OBJECT IDENTIFIER ::= { upsTest 2 } - -upsPhaseResetValues OBJECT IDENTIFIER ::= { upsPhase 1 } -upsPhaseInput OBJECT IDENTIFIER ::= { upsPhase 2 } -upsPhaseOutput OBJECT IDENTIFIER ::= { upsPhase 3 } - -upsSyncCtrlGroupConfig OBJECT IDENTIFIER ::= { upsSyncCtrlGroup 1 } -upsSyncCtrlGroupStatus OBJECT IDENTIFIER ::= { upsSyncCtrlGroup 2 } - -upsBasicState OBJECT IDENTIFIER ::= { upsState 1 } -upsAdvState OBJECT IDENTIFIER ::= { upsState 2 } - -upsOutletGroupStatus OBJECT IDENTIFIER ::= { upsOutletGroups 1 } -upsOutletGroupConfig OBJECT IDENTIFIER ::= { upsOutletGroups 2 } -upsOutletGroupControl OBJECT IDENTIFIER ::= { upsOutletGroups 3 } - -upsDiagnosticIM OBJECT IDENTIFIER ::= { upsDiagnostics 1 } -upsDiagnosticPowerModules OBJECT IDENTIFIER ::= { upsDiagnostics 2 } -upsDiagnosticBatteries OBJECT IDENTIFIER ::= { upsDiagnostics 3 } -upsDiagnosticSubsystem OBJECT IDENTIFIER ::= { upsDiagnostics 4 } -upsDiagnosticExternalDevices OBJECT IDENTIFIER ::= { upsDiagnostics 5 } -upsDiagnosticComBus OBJECT IDENTIFIER ::= { upsDiagnostics 6 } - -upsDiagSwitchGear OBJECT IDENTIFIER ::= { upsDiagnosticExternalDevices 1 } -upsDiagMCCBBox OBJECT IDENTIFIER ::= { upsDiagnosticExternalDevices 2 } -upsDiagTransformer OBJECT IDENTIFIER ::= { upsDiagnosticExternalDevices 3 } - -mUpsEnviron OBJECT IDENTIFIER ::= { measureUps 1 } -mUpsContact OBJECT IDENTIFIER ::= { measureUps 2 } - -serialPort OBJECT IDENTIFIER ::= { miniSNMPadapter 1} - -serialPort1 OBJECT IDENTIFIER ::= { serialPort 1} -serialPort2 OBJECT IDENTIFIER ::= { serialPort 2} - -serialPort2Config OBJECT IDENTIFIER ::= { serialPort2 1} -serialPort2Control OBJECT IDENTIFIER ::= { serialPort2 2} - -sPDUIdent OBJECT IDENTIFIER ::= { masterswitch 1 } -sPDUMasterControl OBJECT IDENTIFIER ::= { masterswitch 2 } -sPDUMasterConfig OBJECT IDENTIFIER ::= { masterswitch 3 } -sPDUOutletControl OBJECT IDENTIFIER ::= { masterswitch 4 } -sPDUOutletConfig OBJECT IDENTIFIER ::= { masterswitch 5 } - -sPDUIdentVM OBJECT IDENTIFIER ::= { masterswitchVM 1 } -sPDUMasterControlVM OBJECT IDENTIFIER ::= { masterswitchVM 2 } -sPDUMasterConfigVM OBJECT IDENTIFIER ::= { masterswitchVM 3 } -sPDUMasterStatusVM OBJECT IDENTIFIER ::= { masterswitchVM 4 } -sPDUOutletControlVM OBJECT IDENTIFIER ::= { masterswitchVM 5 } -sPDUOutletConfigVM OBJECT IDENTIFIER ::= { masterswitchVM 6 } -sPDUOutletStatusVM OBJECT IDENTIFIER ::= { masterswitchVM 7 } - -sPDUIdentMSP OBJECT IDENTIFIER ::= { masterswitchMSP 1 } -sPDUMasterControlMSP OBJECT IDENTIFIER ::= { masterswitchMSP 2 } -sPDUMasterConfigMSP OBJECT IDENTIFIER ::= { masterswitchMSP 3 } -sPDUMasterStatusMSP OBJECT IDENTIFIER ::= { masterswitchMSP 4 } -sPDUOutletControlMSP OBJECT IDENTIFIER ::= { masterswitchMSP 5 } -sPDUOutletConfigMSP OBJECT IDENTIFIER ::= { masterswitchMSP 6 } -sPDUOutletStatusMSP OBJECT IDENTIFIER ::= { masterswitchMSP 7 } - -sPDUOutletConfigMSPall OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 1 } -sPDUOutletConfigMSPgs OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 2 } -sPDUOutletConfigMSPannun OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 3 } -sPDUOutletConfigMSPmups OBJECT IDENTIFIER ::= { sPDUOutletConfigMSP 4 } - -rPDUIdent OBJECT IDENTIFIER ::= { rPDU 1 } -rPDULoad OBJECT IDENTIFIER ::= { rPDU 2 } -rPDUOutlet OBJECT IDENTIFIER ::= { rPDU 3 } -rPDUPowerSupply OBJECT IDENTIFIER ::= { rPDU 4 } - -rPDULoadDevice OBJECT IDENTIFIER ::= { rPDULoad 1 } -rPDULoadPhaseConfig OBJECT IDENTIFIER ::= { rPDULoad 2 } -rPDULoadStatus OBJECT IDENTIFIER ::= { rPDULoad 3 } -rPDULoadBankConfig OBJECT IDENTIFIER ::= { rPDULoad 4 } - -rPDUOutletDevice OBJECT IDENTIFIER ::= { rPDUOutlet 1 } -rPDUOutletPhase OBJECT IDENTIFIER ::= { rPDUOutlet 2 } -rPDUOutletControl OBJECT IDENTIFIER ::= { rPDUOutlet 3 } -rPDUOutletConfig OBJECT IDENTIFIER ::= { rPDUOutlet 4 } -rPDUOutletStatus OBJECT IDENTIFIER ::= { rPDUOutlet 5 } -rPDUOutletBank OBJECT IDENTIFIER ::= { rPDUOutlet 6 } - -rPDUPowerSupplyDevice OBJECT IDENTIFIER ::= { rPDUPowerSupply 1 } - -dm3Ident OBJECT IDENTIFIER ::= { dcDM3 1 } -dm3Config OBJECT IDENTIFIER ::= { dcDM3 2 } -dm3Status OBJECT IDENTIFIER ::= { dcDM3 3 } - -dm3IdentSystem OBJECT IDENTIFIER ::= { dm3Ident 1} - -dm3ConfigSystem OBJECT IDENTIFIER ::= { dm3Config 1 } -dm3ConfigLVD OBJECT IDENTIFIER ::= { dm3Config 2 } -dm3ConfigBattery OBJECT IDENTIFIER ::= { dm3Config 3 } -dm3ConfigPowerModules OBJECT IDENTIFIER ::= { dm3Config 4 } -dm3ConfigRelays OBJECT IDENTIFIER ::= { dm3Config 5 } -dm3ConfigDistribution OBJECT IDENTIFIER ::= { dm3Config 6 } - -dm3ConfigRectifier OBJECT IDENTIFIER ::= { dm3ConfigPowerModules 1 } -dm3ConfigConverter OBJECT IDENTIFIER ::= { dm3ConfigPowerModules 2 } - -dm3ConfigRectThresh OBJECT IDENTIFIER ::= { dm3ConfigRectifier 1 } -dm3ConfigRectAlarms OBJECT IDENTIFIER ::= { dm3ConfigRectifier 2 } - -dm3ConfigConvThresh OBJECT IDENTIFIER ::= { dm3ConfigConverter 1 } -dm3ConfigConvAlarms OBJECT IDENTIFIER ::= { dm3ConfigConverter 2 } - -dm3ConfigOutputRelays OBJECT IDENTIFIER ::= { dm3ConfigRelays 1 } -dm3ConfigInputRelays OBJECT IDENTIFIER ::= { dm3ConfigRelays 2 } - -dm3ConfigBreakers OBJECT IDENTIFIER ::= { dm3ConfigDistribution 1 } -dm3ConfigFuses OBJECT IDENTIFIER ::= { dm3ConfigDistribution 2 } - -dm3StatusSystem OBJECT IDENTIFIER ::= { dm3Status 1 } -dm3StatusAlarms OBJECT IDENTIFIER ::= { dm3Status 2 } -dm3StatusBattery OBJECT IDENTIFIER ::= { dm3Status 3 } -dm3StatusOEM OBJECT IDENTIFIER ::= { dm3Status 4 } -dm3StatusLVD OBJECT IDENTIFIER ::= { dm3Status 5 } -dm3StatusPowerModules OBJECT IDENTIFIER ::= { dm3Status 6 } -dm3StatusRelays OBJECT IDENTIFIER ::= { dm3Status 7 } -dm3StatusDistribution OBJECT IDENTIFIER ::= { dm3Status 8 } - -dm3StatusRectifier OBJECT IDENTIFIER ::= { dm3StatusPowerModules 1 } -dm3StatusConverter OBJECT IDENTIFIER ::= { dm3StatusPowerModules 2 } - -dm3StatusOutputRelays OBJECT IDENTIFIER ::= { dm3StatusRelays 1 } -dm3StatusInputRelays OBJECT IDENTIFIER ::= { dm3StatusRelays 2 } - -dm3StatusBreakers OBJECT IDENTIFIER ::= { dm3StatusDistribution 1 } -dm3StatusFuses OBJECT IDENTIFIER ::= { dm3StatusDistribution 2 } - -atsIdent OBJECT IDENTIFIER ::= { automaticTransferSwitch 1 } -atsCalibration OBJECT IDENTIFIER ::= { automaticTransferSwitch 2 } -atsControl OBJECT IDENTIFIER ::= { automaticTransferSwitch 3 } -atsConfig OBJECT IDENTIFIER ::= { automaticTransferSwitch 4 } -atsStatus OBJECT IDENTIFIER ::= { automaticTransferSwitch 5 } - -atsCalibrationInput OBJECT IDENTIFIER ::= { atsCalibration 1 } -atsCalibrationPowerSupply OBJECT IDENTIFIER ::= { atsCalibration 2 } -atsCalibrationOutput OBJECT IDENTIFIER ::= { atsCalibration 3 } - -atsStatusDeviceStatus OBJECT IDENTIFIER ::= { atsStatus 1 } -atsStatusResetValues OBJECT IDENTIFIER ::= { atsStatus 2 } -atsStatusInput OBJECT IDENTIFIER ::= { atsStatus 3 } -atsStatusOutput OBJECT IDENTIFIER ::= { atsStatus 4 } - -dcmim2Ident OBJECT IDENTIFIER ::= { dc2 1 } -dcmim2Control OBJECT IDENTIFIER ::= { dc2 2 } -dcmim2Config OBJECT IDENTIFIER ::= { dc2 3 } -dcmim2Status OBJECT IDENTIFIER ::= { dc2 4 } - -dcmim2IdentSystem OBJECT IDENTIFIER ::= { dcmim2Ident 1 } - -dcmim2ControlSystem OBJECT IDENTIFIER ::= { dcmim2Control 1 } - -dcmim2ConfigSystem OBJECT IDENTIFIER ::= { dcmim2Config 1 } -dcmim2ConfigBattery OBJECT IDENTIFIER ::= { dcmim2Config 2 } -dcmim2ConfigLVD OBJECT IDENTIFIER ::= { dcmim2Config 3 } - -dcmim2StatusSystem OBJECT IDENTIFIER ::= { dcmim2Status 1 } -dcmim2StatusRectifier OBJECT IDENTIFIER ::= { dcmim2Status 2 } -dcmim2StatusBattery OBJECT IDENTIFIER ::= { dcmim2Status 3 } -dcmim2StatusLVD OBJECT IDENTIFIER ::= { dcmim2Status 4 } -dcmim2StatusAlarms OBJECT IDENTIFIER ::= { dcmim2Status 5 } - -external OBJECT IDENTIFIER ::= { environmentalMonitor 1 } -integrated OBJECT IDENTIFIER ::= { environmentalMonitor 2 } -envMgtSystem OBJECT IDENTIFIER ::= { environmentalMonitor 3 } - -emIdent OBJECT IDENTIFIER ::= { external 1 } -emConfig OBJECT IDENTIFIER ::= { external 2 } -emStatus OBJECT IDENTIFIER ::= { external 3 } - -iemIdent OBJECT IDENTIFIER ::= { integrated 1 } -iemConfig OBJECT IDENTIFIER ::= { integrated 2 } -iemStatus OBJECT IDENTIFIER ::= { integrated 3 } - -emsIdent OBJECT IDENTIFIER ::= { envMgtSystem 1 } - -emsOutputRelayControl OBJECT IDENTIFIER ::= { envMgtSystem 2 } -emsOutletControl OBJECT IDENTIFIER ::= { envMgtSystem 3 } -emsSensorControl OBJECT IDENTIFIER ::= { envMgtSystem 4 } -emsAlarmDeviceControl OBJECT IDENTIFIER ::= { envMgtSystem 5 } - -emsConfig OBJECT IDENTIFIER ::= { envMgtSystem 6 } -emsProbeConfig OBJECT IDENTIFIER ::= { envMgtSystem 7 } -emsInputContactConfig OBJECT IDENTIFIER ::= { envMgtSystem 8 } -emsOutputRelayConfig OBJECT IDENTIFIER ::= { envMgtSystem 9 } -emsOutletConfig OBJECT IDENTIFIER ::= { envMgtSystem 10 } -emsSensorConfig OBJECT IDENTIFIER ::= { envMgtSystem 11 } - -emsStatus OBJECT IDENTIFIER ::= { envMgtSystem 12 } -emsProbeStatus OBJECT IDENTIFIER ::= { envMgtSystem 13 } -emsInputContactStatus OBJECT IDENTIFIER ::= { envMgtSystem 14 } -emsOutputRelayStatus OBJECT IDENTIFIER ::= { envMgtSystem 15 } -emsOutletStatus OBJECT IDENTIFIER ::= { envMgtSystem 16 } -emsAlarmDeviceStatus OBJECT IDENTIFIER ::= { envMgtSystem 17 } -emsSensorStatus OBJECT IDENTIFIER ::= { envMgtSystem 18 } - -nlIdent OBJECT IDENTIFIER ::= { netlock 1 } -nlStatus OBJECT IDENTIFIER ::= { netlock 2 } - -airFM OBJECT IDENTIFIER ::= { airConditioners 1 } -airFMIdent OBJECT IDENTIFIER ::= { airFM 1 } -airFMStatus OBJECT IDENTIFIER ::= { airFM 2 } -airFMGroup OBJECT IDENTIFIER ::= { airFM 3 } - -airPA OBJECT IDENTIFIER ::= { airConditioners 2 } -airPAIdent OBJECT IDENTIFIER ::= { airPA 1 } -airPAStatus OBJECT IDENTIFIER ::= { airPA 2 } - -rARUIdent OBJECT IDENTIFIER ::= { rARU 1 } -rARUConfig OBJECT IDENTIFIER ::= { rARU 2 } -rARUStatus OBJECT IDENTIFIER ::= { rARU 3 } - - --- object types - --- the products group --- the experimental group - - - --- the apcmgmt group --- the mconfig group - -mconfigNumTrapReceivers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of managers to send traps to." - ::= { mconfig 1 } - -mconfigTrapReceiverTable OBJECT-TYPE - SYNTAX SEQUENCE OF MconfigTrapReceiverEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of managers to send traps to. The number of - entries is given by the value of mconfigNumTrapReceivers. - Maximum number of Trap Receivers is four." - ::= { mconfig 2 } - -mconfigTrapReceiverEntry OBJECT-TYPE - SYNTAX MconfigTrapReceiverEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The managers to send traps to." - INDEX { trapIndex} - ::= { mconfigTrapReceiverTable 1 } - -MconfigTrapReceiverEntry ::= - SEQUENCE { - trapIndex - INTEGER, - receiverAddr - IpAddress, - communityString - DisplayString, - severity - INTEGER, - acceptThisReceiver - INTEGER, - receiveTrapType - INTEGER - } - -trapIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to a trap receiver entry." - ::= { mconfigTrapReceiverEntry 1 } - -receiverAddr OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP address of the manager to send a trap to." - ::= { mconfigTrapReceiverEntry 2 } - -communityString OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The community name to use in the trap when - sent to the manager." - ::= { mconfigTrapReceiverEntry 3 } - -severity OBJECT-TYPE - SYNTAX INTEGER { - information(1), - warning(2), - severe(3) - } - ACCESS read-only - STATUS obsolete - DESCRIPTION - "The severity threshold of traps to send to the manager. - traps are labeled in severity as informational(1), warning(2), - severe(3). Only traps of equal or greater severity than - this value are sent to the manager." - ::= { mconfigTrapReceiverEntry 4 } - -acceptThisReceiver OBJECT-TYPE - SYNTAX INTEGER { - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An entry will become active if yes, and will - be deleted if no." - ::= { mconfigTrapReceiverEntry 5 } - - -receiveTrapType OBJECT-TYPE - SYNTAX INTEGER { - powernet (1), - ietf (2), - both (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The node in this entry will receive traps defined in APC - PowerNet MIB, if this OID is set to yes." - ::= { mconfigTrapReceiverEntry 6 } - -mconfigBOOTPEnabled OBJECT-TYPE - SYNTAX INTEGER { - yes (1), - no (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The value of yes(1) indicates the PowerNet Adapter is configured to - obtain its IP configuration parameters from a BOOTP server. - - The value of no(2) indicates adapter will assume IP configuration parameters - values saved in adapter's eeprom, which was originally configured at local - console." - ::= { mconfig 3 } - -mconfigTFTPServerIP OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP address of TFTP server. If mconfigBOOTPEnabled is yes(1), then this IP address - is provided by BOOTP server and not allowed to be modified; otherwise, this IP address - can be modified. - - Before using TFTP to load new code image, the image file should be placed in proper - directory of the specified TFTP server. This OID is only supported by AP9605, AP9205, - and AP9603 PowerNet SNMP Adapters." - ::= { mconfig 4 } - -newCodeAuthentViaTFTP OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - validNewAgentCodeImage (2), - sameAgentCodeImage (3), - invalidAgentCodeImage (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Once mcontrolRestartAgent is set to loadAndExecuteNewAgent (3), PowerNet adapter will - start to load the remote image file, for authentication only, instead of saving the code - into flash memory. Only if a validNewAgentCodeImage (1) is found will the agent reboot - the PowerNet adapter and invoke the loader to load and save new code into the flash memory. - Otherwise, the current agent code will continue to run. - - This OID shows the result of the above authentication process. - validNewAgentCodeImage (1) means the code image on TFTP server - is a valid APC agent code and is different version from the current agent. - Once agent identifies this, loader will start to update flash memory with - the new agent code. - - sameAgentCodeImage (2) means the code image on TFTP server is exactly the - same as the currently running agent. Currently running agent will not invoke - loader to load the same again. - - invalidAgentCodeImage (3) means the code image on TFTP server is NOT a valid - APC agent code. Thus, current agent will not load it into the flash memory. - - The value of this OID will be associated with TRAP codeImageAuthentDone. - This OID is only supported by AP9605, AP9205, and AP9603 PowerNet SNMP Adapters." - - ::= { mconfig 5 } - -mconfigClockDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The current date in the mm/dd/yyyy format. Example: 01/01/2000." - ::= { mconfigClock 1 } - -mconfigClockTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The current time in the hh:mm:ss am/pm format. Example: 12:00:00 am." - ::= { mconfigClock 2 } - -mcontrolRestartAgent OBJECT-TYPE - SYNTAX INTEGER { - restartCurrentAgent (1), - continueCurrentAgent (2), - loadAndExecuteNewAgent (3), - restartWithoutAgent (4), - resetNetworkAndRestart (5), - resetNetworkLeaveModeAndRestart (6) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to restartCurrentAgent (1) will restart the same SNMP - agent code currently saved in flash memory. Setting this OID to - loadAndExecuteNewAgent (3) will enable adapter to load a new agent code - into the flash memory and start to execute this new agent code. - Bootp/tftp is the default protocol. loadAndExecuteNewAgent is only - supported by AP9605, AP9205, and AP9603 PowerNet SNMP Adapters. Setting - this OID to restartWithoutAgent (4) will restart the system and not - start the agent. The subsequent time the system restarts the agent will - also automatically restart. Setting this OID to - resetNetworkAndRestart (5) will set the Boot Mode, IP Address, Subnet - Mask, and Default Gateway to defaults, expire any existing DHCP lease - and then restart the system. Setting this OID to - resetNetworkLeaveModeAndRestart (6) will leave the Boot Mode at the - current setting, set the IP Address, Subnet Mask, and Default Gateway to - defaults, expire any existing DHCP lease and then restart the system." - - ::= { mcontrol 1 } - --- The mtrapargs group --- These OIDs allows APC traps to be sent with additional arguments --- which may not be defined in the APC MIB. - -mtrapargsInteger OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an integer argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 1 } - -mtrapargsIpAddress OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an IP address argument - that my not be defined in the APC MIB. - - A get of this OID will return 0.0.0.0." - ::= { mtrapargs 2 } - -mtrapargsString OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an octet string argument - that my not be defined in the APC MIB. - - A get of this OID will return a NULL string." - ::= { mtrapargs 3 } - -mtrapargsGauge OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a Gauge argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 4 } - -mtrapargsTimeTicks OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a TimeTicks argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 5 } - -mtrapargsInteger02 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an integer argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 6 } - -mtrapargsInteger03 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an integer argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 7 } - -mtrapargsIpAddress02 OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an IP address argument - that my not be defined in the APC MIB. - - A get of this OID will return 0.0.0.0." - ::= { mtrapargs 8 } - -mtrapargsIpAddress03 OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an IP address argument - that my not be defined in the APC MIB. - - A get of this OID will return 0.0.0.0." - ::= { mtrapargs 9 } - -mtrapargsString02 OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an octet string argument - that my not be defined in the APC MIB. - - A get of this OID will return a NULL string." - ::= { mtrapargs 10 } - -mtrapargsString03 OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with an octet string argument - that my not be defined in the APC MIB. - - A get of this OID will return a NULL string." - ::= { mtrapargs 11 } - -mtrapargsGauge02 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a Gauge argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 12 } - -mtrapargsGauge03 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a Gauge argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 13 } - -mtrapargsTimeTicks02 OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a TimeTicks argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 14 } - -mtrapargsTimeTicks03 OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID allows APC traps to be sent with a TimeTicks argument - that my not be defined in the APC MIB. - - A get of this OID will return 0." - ::= { mtrapargs 15 } - --- the mfiletransfer group --- the mfiletransferStatus group -mfiletransferStatusLastTransferResult OBJECT-TYPE - SYNTAX INTEGER { - lastFileTransferResultSuccessful (1), - lastFileTransferResultNotAvailable (2), - lastFileTransferResultFailureUnknown (3), - lastFileTransferResultFailureServerInaccessible (4), - lastFileTransferResultFailureServerAccessDenied (5), - lastFileTransferResultFailureFileNotFound (6), - lastFileTransferResultFailureFileTypeUnknown (7), - lastFileTransferResultFailureFileCorrupted (8) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Once mfiletransferControlInitiateFileTransfer is set to a value other than doNotInitiateFileTransfer - a file transfer of mfiletransferConfigSettingsFilename will be attempted from either a TFTP or FTP - server. - - This OID shows the last attempted file transfer result. - lastFileTransferResultSuccessful (1) means the file transfer was successful. - lastFileTransferResultNotAvailable (2) means that there have been no previous file transfers. - lastFileTransferResultFailureUnknown (3) means that the last file transfer failed for an unknown reason. - lastFileTransferResultFailureServerInaccessible (4) means that the TFTP or FTP server could not be found on the network. - lastFileTransferResultFailureServerAccessDenied (5) means that the TFTP or FTP server denied access. - lastFileTransferResultFailureFileNotFound (6) means that the file could not be located. - lastFileTransferResultFailureFileTypeUnknown (7) means the file was examined, but the contents were unknown. - lastFileTransferResultFailureFileCorrupt (8) means the transferred file was corrupt." - - ::= { mfiletransferStatus 1 } - --- the mfiletransferConfig group --- the mfiletransferConfigSettings group - -mfiletransferConfigSettingsFilename OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The path and name of the file to transfer using the mfiletransferControlInitiateFileTransfer OID. - If the file to transfer exists in the default server directory then the path may be omitted." - - ::= { mfiletransferConfigSettings 1 } - --- the mfiletransferConfigTFTP group - -mfiletransferConfigTFTPServerAddress OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP Address in dotted decimal notation of the TFTP server involved in the file transfer." - - ::= { mfiletransferConfigTFTP 1 } - --- the mfiletransferConfigFTP group - -mfiletransferConfigFTPServerAddress OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The IP Address in dotted decimal notation of the FTP server involved in the file transfer." - - ::= { mfiletransferConfigFTP 1 } - -mfiletransferConfigFTPServerUser OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The user identification for logging into the FTP server specified with mfiletransferConfigFTPServerAddress." - - ::= { mfiletransferConfigFTP 2 } - -mfiletransferConfigFTPServerPassword OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The password for logging into the FTP server specified with mfiletransferConfigFTPServerAddress." - - ::= { mfiletransferConfigFTP 3 } - --- the mfiletransferControl group - -mfiletransferControlInitiateFileTransfer OBJECT-TYPE - SYNTAX INTEGER { - doNotInitiateFileTransfer (1), - initiateFileTransferDownloadViaTFTP (2), - initiateFileTransferDownloadViaFTP (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to doNotInitiateFileTransfer (1) will do nothing. - - Setting this OID to initiateFileTransferDownloadViaTFTP (2) will attempt to transfer the file named in - mfiletransferConfigSettingsFilename from the TFTP Server identified in mfiletransferConfigTFTPAddress. - - Setting this OID to initiateFileTransferDownloadViaFTP (3) will attempt to transfer the file named in - mfiletransferConfigSettingsFilename from the FTP Server identified in mfiletransferConfigFTPAddress - using mfiletransferConfigFTPUser and mfiletransferConfigFTPPassword for the FTP Server login process." - - ::= { mfiletransferControl 1 } - --- the battManIdent group - -battManIdentProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the battery manager." - ::= { battManIdent 1 } - -battManIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager network interface hardware revision. - This value is set at the factory." - ::= { battManIdent 2 } - -battManIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager network interface firmware revision. - This value is set at the factory and can change with firmware update." - ::= { battManIdent 3 } - -battManIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date the battery manager was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { battManIdent 4 } - -battManIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager model number character string. - This value is set at the factory." - ::= { battManIdent 5 } - -battManIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery manager serial number character string. - This value is set at the factory." - ::= { battManIdent 6 } - --- the battManCalib group --- system calibration - -battManOhmicValueCorrectionFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The system ohmic value correction factor in percent." - ::= { battManSystemCalib 1 } - --- unit calibration - -battManUnitCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManUnitCalibTable." - ::= { battManUnitCalib 1 } - -battManUnitCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManUnitCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each unit in the system." - ::= { battManUnitCalib 2 } - -battManUnitCalibTableEntry OBJECT-TYPE - SYNTAX BattManUnitCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The unit to get data from." - INDEX { battManUnitCalibIndex } - ::= { battManUnitCalibTable 1 } - -BattManUnitCalibTableEntry ::= - SEQUENCE { - battManUnitCalibIndex INTEGER, - battManUnitSerialNumber DisplayString, - battManBatteryVoltageZeroCalib INTEGER, - battManBatteryVoltageSpanCalib INTEGER - } - -battManUnitCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of unit calibration entries in the table." - ::= { battManUnitCalibTableEntry 1 } - -battManUnitSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the unit." - ::= { battManUnitCalibTableEntry 2 } - -battManBatteryVoltageZeroCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The unit battery voltage zero calibration in millivolts." - ::= { battManUnitCalibTableEntry 3 } - -battManBatteryVoltageSpanCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The unit battery voltage span calibration in percent." - ::= { battManUnitCalibTableEntry 4 } - --- string calibration table - -battManStringCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManStringCalibTable." - ::= { battManStringCalib 1 } - -battManStringCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManStringCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each string in the system." - ::= { battManStringCalib 2 } - -battManStringCalibTableEntry OBJECT-TYPE - SYNTAX BattManStringCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManStringCalibIndex } - ::= { battManStringCalibTable 1 } - -BattManStringCalibTableEntry ::= - SEQUENCE { - battManStringCalibIndex INTEGER, - battManDCCurrentZeroCalib INTEGER, - battManACCurrentZeroCalib INTEGER, - battManProbeRange INTEGER - } - -battManStringCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string calibration entries in the table." - ::= { battManStringCalibTableEntry 1 } - -battManDCCurrentZeroCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The string DC current zero calibration in tenths of amps." - ::= { battManStringCalibTableEntry 2 } - -battManACCurrentZeroCalib OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The string AC current zero calibration in tenths of amps." - ::= { battManStringCalibTableEntry 3 } - -battManProbeRange OBJECT-TYPE - SYNTAX INTEGER { - amps1000 (1), - amps500 (2), - amps100 (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The string probe range in amps." - ::= { battManStringCalibTableEntry 4 } - ---string 1 battery calibration table - -battManString1BatteryCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1BatteryCalibTable." - ::= { battManBatteryCalib 1 } - -battManString1BatteryCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each battery in String 1." - ::= { battManBatteryCalib 2 } - -battManString1BatteryCalibTableEntry OBJECT-TYPE - SYNTAX BattManString1BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1BatteryCalibIndex } - ::= { battManString1BatteryCalibTable 1 } - -BattManString1BatteryCalibTableEntry ::= - SEQUENCE { - battManString1BatteryCalibIndex INTEGER, - battManString1BatteryInterTierOhmicValue INTEGER - } - -battManString1BatteryCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of battery calibration entries in the table." - ::= { battManString1BatteryCalibTableEntry 1 } - -battManString1BatteryInterTierOhmicValue OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms. This corresponds to the ohmic - value for the positive terminal of the battery." - ::= { battManString1BatteryCalibTableEntry 2 } - ---string 2 battery calibration table - -battManString2BatteryCalibTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2BatteryCalibTable." - ::= { battManBatteryCalib 3 } - -battManString2BatteryCalibTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting calibration information from each battery in String 2." - ::= { battManBatteryCalib 4 } - -battManString2BatteryCalibTableEntry OBJECT-TYPE - SYNTAX BattManString2BatteryCalibTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2BatteryCalibIndex } - ::= { battManString2BatteryCalibTable 1 } - -BattManString2BatteryCalibTableEntry ::= - SEQUENCE { - battManString2BatteryCalibIndex INTEGER, - battManString2BatteryInterTierOhmicValue INTEGER - } - -battManString2BatteryCalibIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of battery calibration entries in the table." - ::= { battManString2BatteryCalibTableEntry 1 } - -battManString2BatteryInterTierOhmicValue OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms." - ::= { battManString2BatteryCalibTableEntry 2 } - --- the battManConfig group - -battManConfigApplication OBJECT-TYPE - SYNTAX INTEGER { - silcon (1), - other (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The type of application the battery manager is installed on: - Silcon(1) Silcon UPS or - Other(2) Other UPS/Charger." - ::= { battManConfig 1 } - -battManConfigBatteryChemistry OBJECT-TYPE - SYNTAX INTEGER { - leadAcid (1), - nickel-Cadmium (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The battery chemistry of the monitored batteries: - LeadAcid(1) Lead Acid or - Nickel-Cadmium(2) Nickel-Cadmium." - ::= { battManConfig 2 } - -battManConfigBatteryAHCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amp hour capacity of the monitored batteries 5-2000 AH." - ::= { battManConfig 3 } - -battManConfigNumberofStrings OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of strings in the battery manager system (1 - 2 Silcon)/(1 Other)." - ::= { battManConfig 4 } - -battManConfigBatteriesperString OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of batteries per string." - ::= { battManConfig 5 } - -battManConfigCellsperBattery OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of cells per battery (1 - 6 for lead-acid, 1 - 2 for NiCd." - ::= { battManConfig 6 } - -battManConfigMinCellVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum battery cell voltage alarm limit in millivolts DC." - ::= { battManConfig 7 } - -battManConfigMaxCellVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum battery cell voltage alarm limit in millivolts DC." - ::= { battManConfig 8 } - -battManConfigMaxPilotTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum pilot battery temperature alarm limit in tenths of degrees Fahrenheit." - ::= { battManConfig 9 } - -battManConfigMaxPilotTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum pilot battery temperature alarm limit in tenths of degrees Celcius." - ::= { battManConfig 10 } - -battManConfigMaxAmbientTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum ambient temperature alarm limit in tenths of degrees Fahrenheit." - ::= { battManConfig 11 } - -battManConfigMaxAmbientTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum ambient temperature alarm limit in tenths of degrees Celcius." - ::= { battManConfig 12 } - -battManConfigMinAmbientTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The Minimum Ambient Temperature alarm limit in tenths of degrees Fahrenheit." - ::= { battManConfig 13 } - -battManConfigMinAmbientTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The Minimum Ambient Temperature alarm limit in tenths of degrees Celcius." - ::= { battManConfig 14 } - -battManConfigMaxRippleCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum ripple current alarm limit for the monitored battery - strings in percent of AH capacity." - ::= { battManConfig 15 } - -battManConfigMaxCurrentAcceptanceDeviation OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum current acceptance deviation alarm limit in percentage." - ::= { battManConfig 16 } - -battManConfigMonitorWireLength OBJECT-TYPE - SYNTAX INTEGER { - fiftyFeetOrLess (1), - moreThanFiftyFeet (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The monitor wire length: - fiftyFeetOrLess (1) indicates that the wire length is less than or equal to 50 feet. - moreThanFiftyFeet (2) indicates that the wire length is greater than 50 feet." - ::= { battManConfig 17 } - -battManConfigDischargeVoltageAlarmLevel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The discharge voltage alarm level in percent." - ::= { battManConfig 18 } - -battManConfigAutoAnnunciatorReset OBJECT-TYPE - SYNTAX INTEGER { - disabled (1), - enabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The annunciator output signal reset method: - disabled(1) means the annunciator signal output will be reset when the reset button is pressed. - enabled(2) means the annunciator will stop signalling when all alarm conditions clear." - ::= { battManConfig 19 } - --- the battManAlarm group - -battManAlarmManagementController OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Management Controller Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 1 } - -battManAlarmBatteries OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Batteries Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 2 } - -battManAlarmCharger OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Charger Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 3 } - -battManAlarmEnvironment OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Environment Alarm is : - normal(1) no alarm condtions identified - alarm(2) an alarm condition exits." - ::= { battManAlarm 4 } - --- the battManSystemStatus group - --- These are system wide parameters - -battManSystemAmbientTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system ambient temperture in tenths of degrees Celcius." - ::= { battManSystemStatus 1 } - -battManSystemAmbientTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system ambient temperture in tenths of degrees Fahrenheit." - ::= { battManSystemStatus 2 } - -battManSystemPilotTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system pilot temperature in tenths of degrees Celcius." - ::= { battManSystemStatus 3 } - -battManSystemPilotTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system pilot temperature in tenths of degrees Fahrenheit." - ::= { battManSystemStatus 4 } - -battManSystemAmbientHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system has a high temperature alarm." - ::= { battManSystemStatus 5 } - -battManSystemAmbientLowTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system has a low temperature alarm." - ::= { battManSystemStatus 6 } - -battManSystemPilotBatteryHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system has a pilot battery high temperature alarm." - ::= { battManSystemStatus 7 } - -battManSystemPilotProbeDisconnected OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system pilot probe is disconnected." - ::= { battManSystemStatus 8 } - -battManSystemAmbientProbeDisconnected OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the system ambient probe is disconnected." - ::= { battManSystemStatus 9 } - --- This is a table of input contact parameters - -battManInputContactTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManContactTable." - ::= { battManInputContactStatus 1 } - -battManInputContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManInputContactTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each contact - in the system. " - ::= { battManInputContactStatus 2 } - -battManInputContactTableEntry OBJECT-TYPE - SYNTAX BattManInputContactTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The contact to get data from." - INDEX { battManInputContactIndex } - ::= { battManInputContactTable 1 } - -BattManInputContactTableEntry ::= - SEQUENCE { - battManInputContactIndex INTEGER, - battManInputContactName DisplayString, - battManInputContactAlarmState INTEGER, - battManInputContactState INTEGER, - battManInputContactNormalState INTEGER, - battManInputContactAlarmDelay INTEGER - } - -battManInputContactIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of contact entries in the table." - ::= { battManInputContactTableEntry 1 } - -battManInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the input contact." - ::= { battManInputContactTableEntry 2 } - -battManInputContactAlarmState OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the alarm condition is active for this contact." - ::= { battManInputContactTableEntry 3 } - -battManInputContactState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to open(1), the input contact is in the open state. - When set to closed(2), the input contact is in the closed state." - ::= { battManInputContactTableEntry 4 } - -battManInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to open(1), the input contact is normally open. - When set to closed(2), the input contact is normally closed." - ::= { battManInputContactTableEntry 5 } - -battManInputContactAlarmDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The alarm delay time in seconds." - ::= { battManInputContactTableEntry 6 } - --- This is a table of battery string parameters - -battManStringTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManStringTable." - ::= { battManStringStatus 1 } - -battManStringTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManStringTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each string - in the system. " - ::= { battManStringStatus 2 } - -battManStringTableEntry OBJECT-TYPE - SYNTAX BattManStringTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManStringIndex } - ::= { battManStringTable 1 } - -BattManStringTableEntry ::= - SEQUENCE { - battManStringIndex INTEGER, - battManStringCurrent INTEGER, - battManStringRippleCurrent INTEGER, - battManStringChargerHighVoltageAlarm INTEGER, - battManStringChargerLowVoltageAlarm INTEGER, - battManStringCurrentProbeDisconnected INTEGER, - battManStringOnBattery INTEGER - } - -battManStringIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string entries in the table." - ::= { battManStringTableEntry 1 } - -battManStringCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The string current in tenths of Amps." - ::= { battManStringTableEntry 2 } - -battManStringRippleCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The string ripple current in tenths of Amps." - ::= { battManStringTableEntry 3 } - -battManStringChargerHighVoltageAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string charger has a high voltage alarm." - ::= { battManStringTableEntry 4 } - -battManStringChargerLowVoltageAlarm OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string charger has a low voltage alarm." - ::= { battManStringTableEntry 5 } - -battManStringCurrentProbeDisconnected OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string charger probe is disconnected." - ::= { battManStringTableEntry 6 } - -battManStringOnBattery OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that the string is in the on-battery state." - ::= { battManStringTableEntry 7 } - --- the battManString1BatteryStatus group - -battManString1BatteryTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1BatteryStatusTable." - ::= { battManBatteryStatus 1 } - -battManString1BatteryTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each string - in the system. " - ::= { battManBatteryStatus 2 } - -battManString1BatteryTableEntry OBJECT-TYPE - SYNTAX BattManString1BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1BatteryIndex } - ::= { battManString1BatteryTable 1 } - -BattManString1BatteryTableEntry ::= - SEQUENCE { - battManString1BatteryIndex INTEGER, - battManString1BatteryVoltage INTEGER, - battManString1BatteryLowestVoltage INTEGER, - battManString1BatteryCellShorted INTEGER, - battManString1BatteryOpenFuseOrConnection INTEGER, - battManString1BatteryLowCapacity INTEGER, - battManString1BatteryHighOhmicValue INTEGER, - battManString1BatteryThermalRunaway INTEGER, - battManString1BatteryDryout INTEGER - } - -battManString1BatteryIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string entries in the table." - ::= { battManString1BatteryTableEntry 1 } - -battManString1BatteryVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery voltage in milli VDC." - ::= { battManString1BatteryTableEntry 2 } - -battManString1BatteryLowestVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The lowest battery discharge voltage during the last power event in milli VDC." - ::= { battManString1BatteryTableEntry 3 } - -battManString1BatteryCellShorted OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a battery cell is shorted." - ::= { battManString1BatteryTableEntry 4 } - -battManString1BatteryOpenFuseOrConnection OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a fuse or connection is open." - ::= { battManString1BatteryTableEntry 5 } - -battManString1BatteryLowCapacity OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has low capacity." - ::= { battManString1BatteryTableEntry 6 } - -battManString1BatteryHighOhmicValue OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a high ohmic value." - ::= { battManString1BatteryTableEntry 7 } - -battManString1BatteryThermalRunaway OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a thermal runaway condition." - ::= { battManString1BatteryTableEntry 8 } - -battManString1BatteryDryout OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a dryout condition." - ::= { battManString1BatteryTableEntry 9 } - --- the battManString2BatteryStatus group - -battManString2BatteryTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2BatteryStatusTable." - ::= { battManBatteryStatus 3 } - -battManString2BatteryTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each string - in the system. " - ::= { battManBatteryStatus 4 } - -battManString2BatteryTableEntry OBJECT-TYPE - SYNTAX BattManString2BatteryTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2BatteryIndex } - ::= { battManString2BatteryTable 1 } - -BattManString2BatteryTableEntry ::= - SEQUENCE { - battManString2BatteryIndex INTEGER, - battManString2BatteryVoltage INTEGER, - battManString2BatteryLowestVoltage INTEGER, - battManString2BatteryCellShorted INTEGER, - battManString2BatteryOpenFuseOrConnection INTEGER, - battManString2BatteryLowCapacity INTEGER, - battManString2BatteryHighOhmicValue INTEGER, - battManString2BatteryThermalRunaway INTEGER, - battManString2BatteryDryout INTEGER - } - -battManString2BatteryIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of string entries in the table." - ::= { battManString2BatteryTableEntry 1 } - -battManString2BatteryVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery voltage in milli VDC." - ::= { battManString2BatteryTableEntry 2 } - -battManString2BatteryLowestVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The lowest battery discharge voltage during the last power event in milli VDC." - ::= { battManString2BatteryTableEntry 3 } - -battManString2BatteryCellShorted OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a battery cell is shorted." - ::= { battManString2BatteryTableEntry 4 } - -battManString2BatteryOpenFuseOrConnection OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates that a fuse or connection is open." - ::= { battManString2BatteryTableEntry 5 } - -battManString2BatteryLowCapacity OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has low capacity." - ::= { battManString2BatteryTableEntry 6 } - -battManString2BatteryHighOhmicValue OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a high ohmic value." - ::= { battManString2BatteryTableEntry 7 } - -battManString2BatteryThermalRunaway OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a thermal runaway condition." - ::= { battManString2BatteryTableEntry 8 } - -battManString2BatteryDryout OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - alarm (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When set to alarm(2), indicates a battery has a dryout condition." - ::= { battManString2BatteryTableEntry 9 } - --- battery manager control group -battManRemoteAnnunciatorReset OBJECT-TYPE - SYNTAX INTEGER { - noOperation (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to reset(2) will reset the user interface annunciator. - Getting this OID will do nothing and return the noOperation(1) value." - ::= { battManControl 1 } - -battManResetChargeCurrentDeviationBenchmark OBJECT-TYPE - SYNTAX INTEGER { - noOperation (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to reset(2) will reset the charge current deviation benchmark. - Getting this OID will do nothing and return the noOperation(1) value." - ::= { battManControl 2 } - -battManResetLowestDischargeVoltages OBJECT-TYPE - SYNTAX INTEGER { - noOperation (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to reset(2) will reset the lowest discharge voltages. - Getting this OID will do nothing and return the noOperation(1) value." - ::= { battManControl 3 } - --- the battManTestResults group - ---string 1 test results table - -battManString1OhmicValueLastDischargeInfo OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Informational text showing the date/time, load, and pilot temperature for the string - during the last discharge when ohmic values were recorded." - ::= { battManTestResults 1 } - -battManString1OhmicValueTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1OhmicValueTable." - ::= { battManTestResults 2 } - -battManString1OhmicValueTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting ohmic value information from each battery in String 1." - ::= { battManTestResults 3 } - -battManString1OhmicValueTableEntry OBJECT-TYPE - SYNTAX BattManString1OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1OhmicValueIndex } - ::= { battManString1OhmicValueTable 1 } - -BattManString1OhmicValueTableEntry ::= - SEQUENCE { - battManString1OhmicValueIndex INTEGER, - battManString1OhmicValueData INTEGER - } - -battManString1OhmicValueIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery number." - ::= { battManString1OhmicValueTableEntry 1 } - -battManString1OhmicValueData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms. - Note: Negative values are invalid and may indicate faulty calibration - of ohmic value correction factors." - ::= { battManString1OhmicValueTableEntry 2 } - -battManString1ResponseTestChangeTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString1ResponseTestChangeTable." - ::= { battManTestResults 4 } - -battManString1ResponseTestChangeTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString1ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting response test change information from each battery in String 1." - ::= { battManTestResults 5 } - -battManString1ResponseTestChangeTableEntry OBJECT-TYPE - SYNTAX BattManString1ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString1ResponseTestChangeIndex } - ::= { battManString1ResponseTestChangeTable 1 } - -BattManString1ResponseTestChangeTableEntry ::= - SEQUENCE { - battManString1ResponseTestChangeIndex INTEGER, - battManString1ResponseTestChangeData INTEGER - } - -battManString1ResponseTestChangeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of the entries in the table." - ::= { battManString1ResponseTestChangeTableEntry 1 } - -battManString1ResponseTestChangeData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery response test change in percent." - ::= { battManString1ResponseTestChangeTableEntry 2 } - -battManString2OhmicValueLastDischargeInfo OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Informational text showing the date/time, load, and pilot temperature for the string - during the last discharge when ohmic values were recorded." - ::= { battManTestResults 6 } - -battManString2OhmicValueTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2OhmicValueTable." - ::= { battManTestResults 7 } - -battManString2OhmicValueTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting ohmic value information from each battery in String 1." - ::= { battManTestResults 8 } - -battManString2OhmicValueTableEntry OBJECT-TYPE - SYNTAX BattManString2OhmicValueTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2OhmicValueIndex } - ::= { battManString2OhmicValueTable 1 } - -BattManString2OhmicValueTableEntry ::= - SEQUENCE { - battManString2OhmicValueIndex INTEGER, - battManString2OhmicValueData INTEGER - } - -battManString2OhmicValueIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of battery calibration entries in the table." - ::= { battManString2OhmicValueTableEntry 1 } - -battManString2OhmicValueData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery inter-tier ohmic value in ohms. - Note: Negative values are invalid and may indicate faulty calibration - of ohmic value correction factors." - ::= { battManString2OhmicValueTableEntry 2 } - -battManString2ResponseTestChangeTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the battManString2ResponseTestChangeTable." - ::= { battManTestResults 9 } - -battManString2ResponseTestChangeTable OBJECT-TYPE - SYNTAX SEQUENCE OF BattManString2ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting response test change information from each battery in String 1." - ::= { battManTestResults 10 } - -battManString2ResponseTestChangeTableEntry OBJECT-TYPE - SYNTAX BattManString2ResponseTestChangeTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The string to get data from." - INDEX { battManString2ResponseTestChangeIndex } - ::= { battManString2ResponseTestChangeTable 1 } - -BattManString2ResponseTestChangeTableEntry ::= - SEQUENCE { - battManString2ResponseTestChangeIndex INTEGER, - battManString2ResponseTestChangeData INTEGER - } - -battManString2ResponseTestChangeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of the entries in the table." - ::= { battManString2ResponseTestChangeTableEntry 1 } - -battManString2ResponseTestChangeData OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery response test change in percent." - ::= { battManString2ResponseTestChangeTableEntry 2 } - --- the xPDUIdent group - -xPDUIdentProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the PDU." - ::= { xPDUIdent 1 } - -xPDUIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the PDU. - This value is set at the factory." - ::= { xPDUIdent 2 } - -xPDUIdentFirmwareAppRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application firmware revision of the PDU." - ::= { xPDUIdent 3 } - -xPDUIdentFirmwareAppOSRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application operating system firmware revision of the PDU." - ::= { xPDUIdent 4 } - -xPDUIdentFirmwareControllerRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the PDU controller firmware revision." - ::= { xPDUIdent 5 } - -xPDUIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the PDU was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { xPDUIdent 6 } - -xPDUIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of - the PDU. This value is set at the factory." - ::= { xPDUIdent 7 } - -xPDUIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of - the PDU. This value is set at the factory." - ::= { xPDUIdent 8 } - --- the xPDUDevice group - -xPDUDeviceNominalMainInputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal main input voltage to the PDU. - Measured in Volts, line-to-line for a delta service or - line-to-neutral for a wye service." - ::= { xPDUDevice 1 } - -xPDUDeviceServiceType OBJECT-TYPE - SYNTAX INTEGER { - delta (1), - wye (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of utility input to the PDU. Either 3 wires (delta), or 4 wires (wye)." - ::= { xPDUDevice 2 } - -xPDUDeviceNominalOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal line-to-neutral output voltage to the load measured in Volts." - ::= { xPDUDevice 3 } - -xPDUDeviceMainInputBreakerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The rating of the main input breaker measured in Amps." - ::= { xPDUDevice 4 } - -xPDUDevicePanelBreakerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The rating of the panel breaker measured in Amps." - ::= { xPDUDevice 5 } - -xPDUDeviceTransformerPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not a transformer is installed in the PDU." - ::= { xPDUDevice 6 } - -xPDUDeviceLoadTieBreakerPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not a load tie breaker is installed in the PDU." - ::= { xPDUDevice 7 } - -xPDUDeviceLoadTestPortPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not a load test port is installed in the PDU." - ::= { xPDUDevice 8 } - -xPDUDeviceFusesPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the UPS feed from the PDU includes fuses." - ::= { xPDUDevice 9 } - -xPDUDeviceFansPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not cooling fans are installed in the PDU." - ::= { xPDUDevice 10 } - -xPDUDeviceBypassInputPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the PDU is equipped with a second feed for - the UPS's bypass input." - ::= { xPDUDevice 11 } - -xPDUDeviceCrossTieOutputPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the PDU is equipped with a cross-tie output." - ::= { xPDUDevice 12 } - -xPDUDeviceEarthGroundMonitorPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not the PDU can provide ground current measurements." - ::= { xPDUDevice 13 } - -xPDUDeviceInfraXureType OBJECT-TYPE - SYNTAX INTEGER { - typeB (1), - typeC (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the configuration of this PDU system. - Type-B PDU is in a distributed UPS system and has bypass capabilities. - Type-C PDU receives power from a larger central UPS." - ::= { xPDUDevice 14 } - --- Main Input - -xPDUMainInputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an input over voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUMainInput 1 } - -xPDUMainInputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an input under voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUMainInput 2 } - --- Main Input Voltage Table - -xPDUMainInputVoltageTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Main input voltage entries." - ::= { xPDUMainInput 3 } - -xPDUMainInputVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUMainInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input voltage table entries. The number of - entries are the phase entries. - The number of entries is contained in the - xPDUMainInputVoltageTableSize OID." - ::= { xPDUMainInput 4 } - - xPDUMainInputVoltagePhaseEntry OBJECT-TYPE - SYNTAX XPDUMainInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular main input voltage phase." - INDEX { xPDUMainInputVoltagePhaseIndex } - ::= { xPDUMainInputVoltageTable 1 } - - XPDUMainInputVoltagePhaseEntry ::= SEQUENCE { - xPDUMainInputVoltagePhaseIndex INTEGER, - xPDUMainInputVoltageLtoL INTEGER, - xPDUMainInputVoltageLtoN INTEGER - } - - xPDUMainInputVoltagePhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each input phase entry in the table." - ::= { xPDUMainInputVoltagePhaseEntry 1 } - - xPDUMainInputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line PDU input voltage when an isolation transformer is present, - or -1 if no transformer present in this PDU. Measured in tenths of Volts." - ::= { xPDUMainInputVoltagePhaseEntry 2 } - - xPDUMainInputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral PDU input voltage when an isolation transformer is not present, - or -1 if a transformer is present in this PDU. Measured in tenths of Volts." - ::= { xPDUMainInputVoltagePhaseEntry 3 } - - -xPDUBypassInputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which a bypass input over voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUBypassInput 1 } - -xPDUBypassInputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an bypass input under voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUBypassInput 2 } - --- Bypass Input Voltage Table - -xPDUBypassInputVoltageTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of bypass input voltage entries." - ::= { xPDUBypassInput 3 } - -xPDUBypassInputVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUBypassInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of - entries are the phase entries. - The number of entries is contained in the - xPDUBypassInputVoltageTableSize OID." - ::= { xPDUBypassInput 4 } - - xPDUBypassInputVoltagePhaseEntry OBJECT-TYPE - SYNTAX XPDUBypassInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular bypass input voltage phase." - INDEX { xPDUBypassInputVoltagePhaseIndex } - ::= { xPDUBypassInputVoltageTable 1 } - - XPDUBypassInputVoltagePhaseEntry ::= SEQUENCE { - xPDUBypassInputVoltagePhaseIndex INTEGER, - xPDUBypassInputVoltageLtoL INTEGER, - xPDUBypassInputVoltageLtoN INTEGER - } - - xPDUBypassInputVoltagePhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of each bypass input phase entry in the table." - ::= { xPDUBypassInputVoltagePhaseEntry 1 } - - xPDUBypassInputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line bypass input voltage, or -1 if no bypass - feed is present in this PDU. Measured in tenths of Volts" - ::= { xPDUBypassInputVoltagePhaseEntry 2 } - - xPDUBypassInputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral bypass input voltage, or -1 if no bypass - feed is present in this PDU. Measured in tenths of Volts" - ::= { xPDUBypassInputVoltagePhaseEntry 3 } - --- UPS Input Table - -xPDUUPSInputVoltageTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of UPS input voltage entries." - ::= { xPDUUPSInput 1 } - -xPDUUPSInputVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUUPSInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of UPS input table entries. The number of - entries are the phase entries. - The number of entries is contained in the - xPDUUPSInputVoltageTableSize OID." - ::= { xPDUUPSInput 2 } - - xPDUUPSInputVoltagePhaseEntry OBJECT-TYPE - SYNTAX XPDUUPSInputVoltagePhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular UPS input voltage phase." - INDEX { xPDUUPSInputVoltagePhaseIndex } - ::= { xPDUUPSInputVoltageTable 1 } - - XPDUUPSInputVoltagePhaseEntry ::= SEQUENCE { - xPDUUPSInputVoltagePhaseIndex INTEGER, - xPDUUPSInputVoltageLtoNPresent INTEGER - } - - xPDUUPSInputVoltagePhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each UPS input phase entry in the table." - ::= { xPDUUPSInputVoltagePhaseEntry 1 } - - xPDUUPSInputVoltageLtoNPresent OBJECT-TYPE - SYNTAX INTEGER { - notPresent (1), - present (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether or not voltage is present at the UPS feed." - ::= { xPDUUPSInputVoltagePhaseEntry 2 } - --- System Output - -xPDUSystemOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system output frequency in tenths of Hertz." - ::= { xPDUSystemOutput 1 } - -xPDUSystemOutputNeutralCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the neutral current measured at the system output in tenths of Amps." - ::= { xPDUSystemOutput 2 } - -xPDUSystemOutputTotalPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kW." - ::= { xPDUSystemOutput 3 } - -xPDUSystemOutputTotalApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kVA." - ::= { xPDUSystemOutput 4 } - -xPDUSystemOutputTotalPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the total power factor of the system output. - A value of 100 representing a unity power factor (1.00). - Measured in hundredths." - ::= { xPDUSystemOutput 5 } - -xPDUSystemOutputFrequencyTolerance OBJECT-TYPE - SYNTAX INTEGER{ - freqToleranceOff (1), - freqTolerancePointTwo (2), - freqTolerancePointFive (3), - freqToleranceOne (4), - freqToleranceOnePointFive (5), - freqToleranceTwo (6), - freqToleranceThree (7), - freqToleranceFour (8), - freqToleranceFive (9), - freqToleranceNine (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Shows the circuit panel output frequency tolerance in Hertz." - ::= { xPDUSystemOutput 6 } - -xPDUSystemOutputMaxKWPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Defines 100% load in kW. - Purpose is to set to match UPS capabilities." - ::= { xPDUSystemOutput 7 } - -xPDUSystemOutputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an output over voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUSystemOutput 8 } - -xPDUSystemOutputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER (0..30) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an output under voltage condition will be generated. - Specified as percent deviation from nominal." - ::= { xPDUSystemOutput 9 } - - -xPDUSystemOutputOverCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an over current condition will be generated. - Specified as a percent of the panel breaker rating." - ::= { xPDUSystemOutput 10 } - -xPDUSystemOutputOverCurrentNeutralThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an Over current neutral condition will be generated. - Specified as a percent of the panel breaker rating." - ::= { xPDUSystemOutput 11 } - -xPDUSystemOutputUnderCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an under current condition will be generated. - Specified as a percent of the panel breaker rating." - ::= { xPDUSystemOutput 12 } - -xPDUSystemOutputTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of System Output phase entries." - ::= { xPDUSystemOutput 13 } - -xPDUSystemOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of system output table entries. - The number of entries is contained in the - xPDUSystemOutputTableSize OID." - ::= { xPDUSystemOutput 14 } - - xPDUSystemOutputPhaseEntry OBJECT-TYPE - SYNTAX XPDUSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular system output phase." - INDEX { xPDUSystemOutputPhaseIndex } - ::= { xPDUSystemOutputTable 1 } - - XPDUSystemOutputPhaseEntry ::= SEQUENCE { - xPDUSystemOutputPhaseIndex INTEGER, - xPDUSystemOutputVoltageLtoL INTEGER, - xPDUSystemOutputVoltageLtoN INTEGER, - xPDUSystemOutputPhaseCurrent INTEGER, - xPDUSystemOutputPower INTEGER, - xPDUSystemOutputApparentPower INTEGER, - xPDUSystemOutputPowerFactor INTEGER - } - - xPDUSystemOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each output phase entry in the table." - ::= { xPDUSystemOutputPhaseEntry 1 } - - xPDUSystemOutputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line system output voltage available at the cicuit panel. - Measured in tenths of Volts." - ::= { xPDUSystemOutputPhaseEntry 2 } - - xPDUSystemOutputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral system output voltage available at the cicuit panel. - Measured in tenths of Volts." - ::= { xPDUSystemOutputPhaseEntry 3 } - - - xPDUSystemOutputPhaseCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System load current per phase. Measured in tenths of Amps." - ::= { xPDUSystemOutputPhaseEntry 4 } - - xPDUSystemOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System output power per phase. Measured in tenths of kW." - ::= { xPDUSystemOutputPhaseEntry 5 } - - xPDUSystemOutputApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System output power per phase. Measured in tenths of kVA." - ::= { xPDUSystemOutputPhaseEntry 6 } - - xPDUSystemOutputPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the Power Factor of the system output per phase. - A value of 100 representing a unity Power Factor (1.00). - Measured in hundredths." - ::= { xPDUSystemOutputPhaseEntry 7 } - -xPDUGroundCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the current measured in the earth ground conductor in tenths of Amps." - ::= { xPDUGroundMonitorPoint 1 } - -xPDUGroundCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..50) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which a ground current over current - condition will be generated. Measured in tenths of Amps." - ::= { xPDUGroundMonitorPoint 2 } - --- System Breakers - -xPDUSystemBreakerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of system breaker entries." - ::= { xPDUSystemBreakers 1 } - -xPDUSystemBreakerTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUSystemBreakerTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of system breaker entries. - The number of entries is contained in the - xPDUSystemBreakerTableSize OID." - ::= { xPDUSystemBreakers 2 } - - xPDUSystemBreakerTableEntry OBJECT-TYPE - SYNTAX XPDUSystemBreakerTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular system breaker." - INDEX { xPDUSystemBreakerTableIndex } - ::= { xPDUSystemBreakerTable 1 } - - XPDUSystemBreakerTableEntry ::= SEQUENCE { - xPDUSystemBreakerTableIndex INTEGER, - xPDUSystemBreakerDescription DisplayString, - xPDUSystemBreakerPosition INTEGER - } - - xPDUSystemBreakerTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of system breaker entries in the table." - ::= { xPDUSystemBreakerTableEntry 1 } - -xPDUSystemBreakerDescription OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..79)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A brief description of the system breakers." - ::= { xPDUSystemBreakerTableEntry 2 } - - xPDUSystemBreakerPosition OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether this breaker is open(1) or closed(2)." - ::= { xPDUSystemBreakerTableEntry 3 } - --- Branch Breakers (Breaker Panel) - -xPDUNumOfBranchBreakers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of branch breakers in the Panel." - ::= { xPDUBranchBreakers 1 } - --- Branch Breakers Table - -xPDUBranchBreakerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of branch breaker entries." - ::= { xPDUBranchBreakers 2 } - -xPDUBranchBreakerTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUBranchBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of branch breaker table entries. The - number of entries is given by the value of xPDUBranchBreakerTableSize - The number of entries is contained in the - xPDUBranchBreakerTableSize OID." - ::= { xPDUBranchBreakers 3 } - - xPDUBranchBreakerEntry OBJECT-TYPE - SYNTAX XPDUBranchBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular branch breaker." - INDEX { xPDUBranchBreakerTableIndex } - ::= { xPDUBranchBreakerTable 1 } - - XPDUBranchBreakerEntry ::= SEQUENCE { - xPDUBranchBreakerTableIndex INTEGER, - xPDUBranchBreakerRating INTEGER, - xPDUBranchBreakerRDPFeed INTEGER, - xPDUBranchBreakerTieIndicator INTEGER, - xPDUBranchBreakerCurrent INTEGER, - xPDUBranchBreakerOverCurrentThreshold INTEGER, - xPDUBranchBreakerUnderCurrentThreshold INTEGER - } - - xPDUBranchBreakerTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of branch breaker entries in the table." - ::= { xPDUBranchBreakerEntry 1 } - - xPDUBranchBreakerRating OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates current rating of this breaker. - 0=Breaker is not present. - 1=Earth leakage connection. - 2=Neutral connection. - A value greater than 2 indicates breaker current rating in Amps." - ::= { xPDUBranchBreakerEntry 2 } - - xPDUBranchBreakerRDPFeed OBJECT-TYPE - SYNTAX INTEGER { - remoteDistribution (1), - noRemoteDistribution (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates that a breaker position is feeding a remote - distribution panel." - ::= { xPDUBranchBreakerEntry 3 } - - xPDUBranchBreakerTieIndicator OBJECT-TYPE - SYNTAX INTEGER { - breakerTied (1), - breakerUntied (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates whether or not the breaker pole is physically - connected to the breaker immediately below." - ::= { xPDUBranchBreakerEntry 4 } - - xPDUBranchBreakerCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the branch current in tenths of Amps or -1 when not available." - ::= { xPDUBranchBreakerEntry 5 } - - xPDUBranchBreakerOverCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which a branch circuit over current - condition will be generated. - Specified as a percent of the branch breaker rating." - ::= { xPDUBranchBreakerEntry 6 } - - xPDUBranchBreakerUnderCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a branch circuit under current - condition will be generated. - Specified as a percent of the branch breaker rating." - ::= { xPDUBranchBreakerEntry 7 } - --- the xPDUInputContacts group - -xPDUInputContactNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the PDU." - ::= { xPDUInputContacts 1 } - -xPDUInputContactTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input contact entries." - ::= { xPDUInputContacts 2 } - -xPDUInputContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUInputContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the PDU. - The number of entries is contained in the - xPDUInputContactTableSize OID." - ::= { xPDUInputContacts 3 } - -xPDUInputContactEntry OBJECT-TYPE - SYNTAX XPDUInputContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A contact entry containing information for a given contact." - INDEX { xPDUInputContactNumber } - ::= { xPDUInputContactTable 1 } - -XPDUInputContactEntry ::= - SEQUENCE { - xPDUInputContactNumber INTEGER, - xPDUInputContactName DisplayString, - xPDUInputContactNormalState INTEGER, - xPDUInputContactCurrentState INTEGER - } - -xPDUInputContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the contact on the PDU." - ::= { xPDUInputContactEntry 1 } - -xPDUInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the contact." - ::= { xPDUInputContactEntry 2 } - -xPDUInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the contact." - ::= { xPDUInputContactEntry 3 } - -xPDUInputContactCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the contact." - ::= { xPDUInputContactEntry 4 } - --- the xPDUOutputRelays group - -xPDUOutputRelaysNumRelays OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relays supported by the PDU." - ::= { xPDUOutputRelays 1 } - -xPDUOutputRelaysTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relay entries." - ::= { xPDUOutputRelays 2 } - -xPDUOutputRelayTable OBJECT-TYPE - SYNTAX SEQUENCE OF XPDUOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output relays supported by the PDU. - The number of entries is contained in the - xPDUOutputRelayTableSize OID." - ::= { xPDUOutputRelays 3 } - -xPDUOutputRelayEntry OBJECT-TYPE - SYNTAX XPDUOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A output relay entry containing information for a given contact." - INDEX { xPDUOutputRelayNumber } - ::= { xPDUOutputRelayTable 1 } - -XPDUOutputRelayEntry ::= - SEQUENCE { - xPDUOutputRelayNumber INTEGER, - xPDUOutputRelayName DisplayString, - xPDUOutputRelayNormalState INTEGER, - xPDUOutputRelayCurrentState INTEGER - } - -xPDUOutputRelayNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the output relay on the PDU." - ::= { xPDUOutputRelayEntry 1 } - -xPDUOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the output relay." - ::= { xPDUOutputRelayEntry 2 } - -xPDUOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the output relay." - ::= { xPDUOutputRelayEntry 3 } - -xPDUOutputRelayCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the output relay." - ::= { xPDUOutputRelayEntry 4 } - --- the xPDUMiscGroup - -xPDUEPOMode OBJECT-TYPE - SYNTAX INTEGER { - armed (1), - disarmed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether the EPO System is armed(1) or disarmed(2)." - ::= { xPDUMiscGroup 1 } - -xPDUTransformTempStatus OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - overtemp (2), - noTransformerPresent (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates if the PDU's isolation transformer is over temperature." - ::= { xPDUMiscGroup 2 } - -xPDUCoolingFanStatus OBJECT-TYPE - SYNTAX INTEGER { - normal (1), - failed (2), - noCoolingFansPresent (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates if one or more of the PDU's cooling fans have failed." - ::= { xPDUMiscGroup 3 } - --- The xATSIdent group - -xATSIdentProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the transfer switch unit." - ::= { xATSIdent 1 } - -xATSIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the transfer switch. - This value is set at the factory." - ::= { xATSIdent 2 } - -xATSIdentFirmwareAppRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application firmware revision of the transfer switch." - ::= { xATSIdent 3 } - -xATSIdentFirmwareAppOSRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the application operating system firmware revision of the transfer switch." - ::= { xATSIdent 4 } - -xATSIdentFirmwareControllerRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ID string identifying the transfer switch controller firmware revision." - ::= { xATSIdent 5 } - -xATSIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the transfer switch was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { xATSIdent 6 } - -xATSIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of the transfer switch. - This value is set at the factory." - ::= { xATSIdent 7 } - -xATSIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of the transfer switch. - This value is set at the factory." - ::= { xATSIdent 8 } - --- The xATSDevice group - -xATSDeviceServiceType OBJECT-TYPE - SYNTAX INTEGER { - threeWire (1), - fourWire (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of utility input to the transfer switch. - Either 3 wires (delta), or 4 wires (wye)." - ::= { xATSDevice 1 } - -xATSDeviceNominalVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal line-to-neutral system voltage. - Measured in Volts, line-to-line for a 3-wire service or - line-to-neutral for a 4-wire service. -1 if not available." - ::= { xATSDevice 2 } - -xATSDeviceNominalFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal system frequency. Measured in tenths of Hertz. - -1 if not available." - ::= { xATSDevice 3 } - -xATSDeviceTransferSwitchRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The rating of the transfer switch. - Measured in Amps." - ::= { xATSDevice 4 } - -xATSDeviceDCBackUpPresent OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Indicates if a DC backup is present or not." - ::= { xATSDevice 5 } - --- The xATS Switch Status group - -xATSSwitchStatusSelectedSource OBJECT-TYPE - SYNTAX INTEGER{ - none (1), - source1 (2), - source2 (3), - fault (4), - unknown (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The source which is currently selected, i.e. supplying power to the load." - ::= { xATSSwitchStatus 1 } - -xATSSwitchStatusOperationalMode OBJECT-TYPE - SYNTAX INTEGER{ - automatic (1), - notInAutoAbnormal (2), - notInAuto (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current operating mode of the transfer switch. When the ATS is in - automatic mode, generator starting and ATS transferring is all done automatically - as needed based on the state of source 1. Automatic operation is halted when the - ATS is in either of the notInAuto modes. - A mode of notInAuto indicates that the automatic operation switch is in the - disabled position, as indicated by the xATSSwitchStatusAutomaticOperationSwitch OID. - The notInAutoAbnormal condition indicates that an abnormal - condition has caused the transfer switch to halt automatic operation. - In this case, traps can indicate the exact problem. In the case of - notInAutoAbnormal, refer to the operation manual for details - on how debug the condition and restore automatic operation." - ::= { xATSSwitchStatus 2 } - -xATSSwitchStatusAutomaticOperationSwitch OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - enabled (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The position of the automatic operation switch on the front of the transfer switch." - ::= { xATSSwitchStatus 3 } - -xATSSwitchStatusEngineStartSignal OBJECT-TYPE - SYNTAX INTEGER{ - run (1), - stop (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The position of the Start/Stop contact which signals the generator - engine to start/run. When the ATS is in automatic mode, - generator starting/stopping is under ATS control." - ::= { xATSSwitchStatus 4 } - --- The xATS Switch Setting group - -xATSSwitchSettingsLowVoltageTransferPoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The lowest acceptable voltage condition at source 1. - When any phase of source 1 is lower than this voltage, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified in volts, line-to-line for a 3-wire service or - line-to-neutral for a 4-wire service. - -1 if not available." - ::= { xATSSwitchSettings 1 } - -xATSSwitchSettingsHighVoltageTransferPoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The highest acceptable voltage condition at source 1. - When any phase of source 1 is greater than this voltage, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified in volts, line-to-line for a 3-wire service or - line-to-neutral for a 4-wire service. - -1 if not available." - ::= { xATSSwitchSettings 2 } - -xATSSwitchSettingsMaxFrequencyDeviation OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum acceptable frequency deviation condition from nominal at source 1. - When source 1 frequency is outside the specified range, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified in tenths of Hertz above or below nominal. - A value of zero indicates that frequency is ignored when - determining source quality. - -1 if not available." - ::= { xATSSwitchSettings 3 } - -xATSSwitchSettingsMinPhaseBalance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum required phase balance at source 1. - When the percentage difference between the minimum and maximum - phase voltage measurements at source 1 is greater than this value, - source quality is considered bad and the generator run signal - is asserted to begin generator operation. - Specified as a percentage. A value of zero indicates that phase balance - is ignored when determining source quality. - -1 if not available." - ::= { xATSSwitchSettings 4 } - -xATSSwitchSettingsNominalRotation OBJECT-TYPE - SYNTAX INTEGER{ - abc (1), - cba (2), - any (3), - unknown (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The nominal phase rotation (or phase sequence) required by the load. - For certain types of equipment, such as rotating machinery, phase rotation - is critical for proper operation as it determines the direction which motors - will rotate (clockwise or counterclockwise). - Source quality will be seen as bad if the rotation measured at that - ATS input does not match this setting. - If this setting is set to any, phase rotation is ignored." - ::= { xATSSwitchSettings 5 } - -xATSSwitchSettingsAllowClosedTransfer OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2), - unknown (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting enables seemless (closed) transfers between sources. - When possible, both source 1 and source 2 are closed to the output - for a brief time. If closed transfer is not possible within the amount - of time specified by the xATSSwitchSettingsMaxSyncTime OID, - an open transfer will be executed." - ::= { xATSSwitchSettings 6 } - -xATSSwitchSettingsMaxSyncTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "When attempting/seeking to perform a closed transfer, this setting defines - the maximum time allowed before the transfer switch will give up and perform - an open transfer. Specified in seconds. - -1 if not available." - ::= { xATSSwitchSettings 7 } - -xATSSwitchSettingsNeutralTransferTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting defines how long both source 1 and source 2 will be - disconnected from the output, during an open transfer. - Specified in seconds. - -1 if not available." - ::= { xATSSwitchSettings 8 } - -xATSSwitchSettingsClearLatchedAlarms OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Clears any latched alarm conditions." - ::= { xATSSwitchSettings 9 } - -xATSSwitchSettingsSetToFactoryDefaults OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Sets all transfer switch settings to factory default values." - ::= { xATSSwitchSettings 10 } - - --- The xATSSwitchTimers group - - xATSSwitchTimersTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of transfer switch timer entries." - ::= { xATSSwitchTimers 1 } - - xATSSwitchTimersTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSwitchTimersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of timers supported by ATS. - The number of entries is contained in the xATSSwitchTimersTableSize OID." - ::= { xATSSwitchTimers 2 } - - xATSSwitchTimersEntry OBJECT-TYPE - SYNTAX XATSSwitchTimersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information about an individual ATS timer." - INDEX { xATSSwitchTimersIndex } - ::= { xATSSwitchTimersTable 1 } - - XATSSwitchTimersEntry ::= - SEQUENCE { - xATSSwitchTimersIndex INTEGER, - xATSSwitchTimersName DisplayString, - xATSSwitchTimersAbort INTEGER, - xATSSwitchTimersStatus INTEGER, - xATSSwitchTimersRemainingTime INTEGER, - xATSSwitchTimersDelaySetting INTEGER - } - -xATSSwitchTimersIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of timer entries in the table." - ::= { xATSSwitchTimersEntry 1 } - -xATSSwitchTimersName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Name of the individual timer.Refer to ATS operation manual, - or on-line help, for detailed descriptions of ATS timers." - ::= { xATSSwitchTimersEntry 2 } - -xATSSwitchTimersAbort OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This aborts the individual timer." - ::= { xATSSwitchTimersEntry 3 } - -xATSSwitchTimersStatus OBJECT-TYPE - SYNTAX INTEGER{ - inactive (1), - active (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the individual timer. Designates whether this timer - entry is currently running or inactive." - ::= { xATSSwitchTimersEntry 4 } - -xATSSwitchTimersRemainingTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time remaining for this timer entry. - Specified in seconds." - ::= { xATSSwitchTimersEntry 5 } - -xATSSwitchTimersDelaySetting OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay settings associated with this timer entry. - When this timer entry is active, the timer value must exceed this setting - before the ATS behavior associated with this timer is executed. - Refer to ATS operation manual, or on-line help, for detailed - descriptions of ATS timers." - ::= { xATSSwitchTimersEntry 6 } - --- The xATSSwitchBlockMap group - - xATSSwitchBlockMapTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of blocking map entries, or how many ATS actions can be blocked." - ::= { xATSSwitchBlockMap 1 } - - xATSSwitchBlockMapTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSwitchBlockMapEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of blocking maps supported by the ATS. - The number of entries is contained in the xATSSwitchBlockMapTableSize OID." - ::= { xATSSwitchBlockMap 2 } - - xATSSwitchBlockMapEntry OBJECT-TYPE - SYNTAX XATSSwitchBlockMapEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information about a specific ATS blocking map." - INDEX { xATSSwitchBlockMapIndex } - ::= { xATSSwitchBlockMapTable 1 } - - XATSSwitchBlockMapEntry ::= - SEQUENCE { - xATSSwitchBlockMapIndex INTEGER, - xATSSwitchBlockMapName DisplayString, - xATSSwitchBlockMapStatus INTEGER, - xATSSwitchBlockMapSetting INTEGER - } - - xATSSwitchBlockMapIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of blocking map entries in the table." - ::= { xATSSwitchBlockMapEntry 1 } - - xATSSwitchBlockMapName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string describing the ATS action to be blocked." - ::= { xATSSwitchBlockMapEntry 2 } - - xATSSwitchBlockMapStatus OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Represents the status of this blocking map entry, in bit-mapped format. - A non-zero value indicates that this entry's ATS action is currently being blocked. - The bit(s) set indicate which input(s) are causing the blocking (bit0, bit1, etc). - - bit 0 - Contact 1 - bit 1 - Contact 2 - bit 2 - Contact 3 - bit 3 - Contact 4." - ::= { xATSSwitchBlockMapEntry 3 } - - xATSSwitchBlockMapSetting OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting designates the inputs that block the ATS action - The mapping is specified as a bit-field, where each bit set indicates - the input that blocks the ATS action associated with the entry. - - bit 0 - Contact 1 - bit 1 - Contact 2 - bit 2 - Contact 3 - bit 3 - Contact 4." - ::= { xATSSwitchBlockMapEntry 4 } - --- The xATSSwitchStatistics group - - xATSSwitchStatisticsTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of transfer switch statistics entries." - ::= { xATSSwitchStatistics 1 } - - xATSSwitchStatisticsTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSwitchStatisticsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of statistics supported by ATS. - The number of entries is contained in the xATSSwitchStatisticsTableSize OID." - ::= { xATSSwitchStatistics 2 } - - xATSSwitchStatisticsEntry OBJECT-TYPE - SYNTAX XATSSwitchStatisticsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information about an individual ATS statistic." - INDEX { xATSSwitchStatisticsIndex } - ::= { xATSSwitchStatisticsTable 1 } - - XATSSwitchStatisticsEntry ::= - SEQUENCE { - xATSSwitchStatisticsIndex INTEGER, - xATSSwitchStatisticsName DisplayString, - xATSSwitchStatisticsValue DisplayString, - xATSSwitchStatisticsReset INTEGER - } - - xATSSwitchStatisticsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Index of ATS statistics entries in the table." - ::= { xATSSwitchStatisticsEntry 1 } - - xATSSwitchStatisticsName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This is the name of the ATS statistic associated with this entry." - ::= { xATSSwitchStatisticsEntry 2 } - - xATSSwitchStatisticsValue OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This is the value of the ATS statistic associated with this entry." - ::= { xATSSwitchStatisticsEntry 3 } - - xATSSwitchStatisticsReset OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This will reset the individual ATS statistic associated with this entry." - ::= { xATSSwitchStatisticsEntry 4 } - --- The xATS Source 1 group - -xATSSource1Name OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "String used to identify source 1." - ::= { xATSSource1 1 } - -xATSSource1Position OBJECT-TYPE - SYNTAX INTEGER{ - open (1), - closed (2), - tripped (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current position of the switch at source 1." - ::= { xATSSource1 2 } - -xATSSource1Frequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency at source 1 in tenths of Hertz. - -1 if unavailable." - ::= { xATSSource1 3 } - -xATSSource1Quality OBJECT-TYPE - SYNTAX INTEGER{ - sourceGood (1), - lowVoltage (2), - highVoltage (3), - phaseImbalance (4), - freqOutOfRange (5), - badRotation (6), - unknown (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current line quality of source 1." - ::= { xATSSource1 4 } - -xATSSource1Rotation OBJECT-TYPE - SYNTAX INTEGER{ - abc (1), - cba (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase rotation measured at the source 1 input of the ATS. - The sequence is a reference to the order in which the three phases - pass the zero-crossing boundary in time." - ::= { xATSSource1 5 } - -xATSSource1TableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input voltage entries at the source 1 input of the ATS." - ::= { xATSSource1 6 } - - xATSSource1Table OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSource1PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of voltage table entries for source 1. The number of - entries are the phase entries. The number of entries is contained in the - xATSSource1TableSize OID." - ::= { xATSSource1 7 } - - xATSSource1PhaseEntry OBJECT-TYPE - SYNTAX XATSSource1PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input voltage phase at the source 1 input of the ATS." - INDEX { xATSSource1Index } - ::= { xATSSource1Table 1 } - - XATSSource1PhaseEntry ::= SEQUENCE { - xATSSource1Index INTEGER, - xATSSource1VoltageLtoL INTEGER, - xATSSource1VoltageLtoN INTEGER - } - - xATSSource1Index OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each phase utilized at source 1." - ::= { xATSSource1PhaseEntry 1 } - - xATSSource1VoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 1 line-to-line input voltage. - Measured in tenths of Volts." - ::= { xATSSource1PhaseEntry 2 } - - xATSSource1VoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 1 line-to-neutral input voltage. - Measured in tenths of Volts. -1 for a 3-wire service type." - ::= { xATSSource1PhaseEntry 3 } - --- The xATS Source 2 group - -xATSSource2Name OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "String used to identify source 2." - ::= { xATSSource2 1 } - -xATSSource2Position OBJECT-TYPE - SYNTAX INTEGER{ - open (1), - closed (2), - tripped (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current position of the switch at source 2." - ::= { xATSSource2 2 } - -xATSSource2Frequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency at source 2 in tenths of Hertz. - -1 if not available." - ::= { xATSSource2 3 } - -xATSSource2Quality OBJECT-TYPE - SYNTAX INTEGER{ - sourceGood (1), - lowVoltage (2), - highVoltage (3), - phaseImbalance (4), - freqOutOfRange (5), - badRotation (6), - unknown (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current line quality of source 2." - ::= { xATSSource2 4 } - -xATSSource2Rotation OBJECT-TYPE - SYNTAX INTEGER{ - abc (1), - cba (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase rotation measured at the source 2 input of the ATS. - -1 if not available." - ::= { xATSSource2 5 } - -xATSSource2TableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input voltage entries at the source 2 input of the ATS." - ::= { xATSSource2 6 } - - xATSSource2Table OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSource2PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of voltage table entries for the source 2. The number of - entries are the phase entries. The number of entries is contained in the - xATSSource2TableSize OID." - ::= { xATSSource2 7 } - - xATSSource2PhaseEntry OBJECT-TYPE - SYNTAX XATSSource2PhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input voltage phase at the source 2 input of the ATS." - INDEX { xATSSource2Index } - ::= { xATSSource2Table 1 } - - XATSSource2PhaseEntry ::= SEQUENCE { - xATSSource2Index INTEGER, - xATSSource2VoltageLtoL INTEGER, - xATSSource2VoltageLtoN INTEGER - } - - xATSSource2Index OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each phase utilized at the source 2." - ::= { xATSSource2PhaseEntry 1 } - - xATSSource2VoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 2 line-to-line input voltage. - Measured in tenths of Volts." - ::= { xATSSource2PhaseEntry 2 } - - xATSSource2VoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Source 2 line-to-neutral input voltage. - Measured in tenths of Volts. -1 for a 3-wire service type." - ::= { xATSSource2PhaseEntry 3 } - --- The xATSSystemOutput - -xATSSystemOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system output frequency in tenths of Hertz." - ::= { xATSSystemOutput 1 } - -xATSSystemOutputTotalPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kW." - ::= { xATSSystemOutput 2 } - -xATSSystemOutputTotalApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Shows the total system output power in tenths of kVA." - ::= { xATSSystemOutput 3 } - -xATSSystemOutputTotalPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the total power factor of the system output. - A value of 100 representing a unity power factor (1.00) - Specified in hundredths." - ::= { xATSSystemOutput 4 } - -xATSSystemOutputFrequencyTolerance OBJECT-TYPE - SYNTAX INTEGER{ - freqToleranceOff (1), - freqTolerancePointTwo (2), - freqTolerancePointFive (3), - freqToleranceOne (4), - freqToleranceOnePointFive (5), - freqToleranceTwo (6), - freqToleranceThree (7), - freqToleranceFour (8), - freqToleranceFive (9), - freqToleranceNine (10) - - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Shows the panel output frequency tolerance in +/- Hertz." - ::= { xATSSystemOutput 5 } - -xATSSystemOutputOverVoltThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an output over voltage condition will be generated. - Specified as tenths of percent deviation from nominal. - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 6 } - -xATSSystemOutputUnderVoltThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an output under voltage condition will be generated. - Specified as tenths of percent deviation from nominal. - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 7 } - -xATSSystemOutputOverCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold above which an over current condition will be generated. - Specified as a percent of the transfer switch rating (xATSDeviceTransferSwitchRating OID). - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 8 } - -xATSSystemOutputUnderCurrentThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which an under current condition will be generated. - Specified as a percent of the transfer switch rating (xATSDeviceTransferSwitchRating OID). - A value of zero indicates that the threshold is disabled." - ::= { xATSSystemOutput 9 } - -xATSSystemOutputAlarmDelayThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Delay the generation of an output alarm. - Specified in seconds." - ::= { xATSSystemOutput 10 } - -xATSSystemOutputTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of system output phase entries." - ::= { xATSSystemOutput 11 } - -xATSSystemOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of system output table entries. - The number of entries is contained in the xATSSystemOutputTableSize OID." - ::= { xATSSystemOutput 12 } - - xATSSystemOutputPhaseEntry OBJECT-TYPE - SYNTAX XATSSystemOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular system output phase." - INDEX { xATSSystemOutputPhaseIndex } - ::= { xATSSystemOutputTable 1 } - - XATSSystemOutputPhaseEntry ::= SEQUENCE { - xATSSystemOutputPhaseIndex INTEGER, - xATSSystemOutputVoltageLtoL INTEGER, - xATSSystemOutputVoltageLtoN INTEGER, - xATSSystemOutputPhaseCurrent INTEGER, - xATSSystemOutputPower INTEGER, - xATSSystemOutputApparentPower INTEGER, - xATSSystemOutputPowerFactor INTEGER - } - - xATSSystemOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each system output phase utilized in this device." - ::= { xATSSystemOutputPhaseEntry 1 } - - xATSSystemOutputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line system output voltage, measured in tenths of Volts, available at the circuit panel. - -1 if not available." - ::= { xATSSystemOutputPhaseEntry 2 } - - xATSSystemOutputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral system output voltage, measured in tenths of Volts, available at the circuit panel. - -1 for a 3-wire service type or if not available." - ::= { xATSSystemOutputPhaseEntry 3 } - - xATSSystemOutputPhaseCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System load current per phase. Measured in Amps. - -1 if not available." - ::= { xATSSystemOutputPhaseEntry 4 } - - xATSSystemOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System output power per phase. Measured in tenths of kW." - ::= { xATSSystemOutputPhaseEntry 5 } - - xATSSystemOutputApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "system output power per phase. Measured in tenths of kVA." - ::= { xATSSystemOutputPhaseEntry 6 } - - xATSSystemOutputPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "indicates the power factor of the system output per phase. - A value of 100 representing a unity power factor (1.00). - Measured in hundredths." - ::= { xATSSystemOutputPhaseEntry 7 } - --- xATS TestingStatus group - -xATSTestingStatusSelectTestProcess OBJECT-TYPE - SYNTAX INTEGER { - engineStartTest (1), - systemLoadTest (2), - generatorHoldTest (3), - cancelTest (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Type of tests that can be selected when no test has been scheduled. - engineStartTest and systemLoadTest may be selected when no tests - are running. Tests that are selected may be cancelled manually." - ::= { xATSTestingStatus 1 } - -xATSTestingStatusTestStatus OBJECT-TYPE - SYNTAX INTEGER { - noTestInProcess (1), - testPending (2), - startingEngine (3), - engineWarmingUp (4), - awaitingTransferToS2 (5), - testingWithLoad (6), - awaitingRetransferToS1 (7), - testingWithoutLoad (8), - stoppingEngine (9), - holdingOnGenerator (10) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The present system test status/state." - ::= { xATSTestingStatus 2 } - -xATSTestingStatusProfileWarmupTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time that the generator will warm up during a test. - This is portion of the test when the xATSTestingStatusTestStatus - OID returns the value engineWarmingUp. - Specified in seconds." - ::= { xATSTestingStatus 3 } - -xATSTestingStatusProfileLoadedTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time that ATS will apply the system load to the generator - during a system load test. - This is portion of the test when the xATSTestingStatusTestStatus - OID returns the value testingWithLoad. - Specified in minutes." - ::= { xATSTestingStatus 4 } - -xATSTestingStatusProfileUnloadedTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time that the generator will run following the warm up - portion of a start test, or the loaded portion of a load test. - This is portion of the test when the xATSTestingStatusTestStatus - OID returns the value testingWithoutLoad. - Specified in seconds." - ::= { xATSTestingStatus 5 } - --- xATS TestingResults group - -xATSTestingResultsLastDateOfTest OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Date of the last test that was performed, either scheduled or manual. - Test results are available in the xATSTestingResultsLastResult OID. - Specified in the dd/mm/yyyy format, or 'none' if not available." - ::= { xATSTestingResults 1 } - -xATSTestingResultsLastResult OBJECT-TYPE - SYNTAX INTEGER { - startTestPassed (1), - loadTestPassed (2), - startSignalFailure (3), - failedGenNotInAuto (4), - failedGenEmerStop (5), - failedGenShutdown (6), - failedGenDidNotStart (7), - failedS2NeverGood (8), - genFailedDuringWarmup (9), - failureOnXferToS1 (10), - genFailedLoaded (11), - failureOnRexferToS2 (12), - genFailedToStop (13), - failedAtsInternalFault (14), - failedAtsNotInAuto (15), - cancelledManualTest (16), - cancelledScheduledTest (17) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The result of the last ATS/generator system test." - ::= { xATSTestingResults 2 } - -xATSTestingResultsTestLastTestTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Time of day at which the last test was performed, either scheduled or manual. - Test results are available in the xATSTestingResultsLastResult OID. - Specified in the hh:mm:ss format, or 'none' if not available." - ::= { xATSTestingResults 3 } - -xATSTestingResultsLastCrankDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent cranking the generator before it started during the last test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 4 } - -xATSTestingResultsLastWarmupDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent in the engineWarmingUp state during the last system test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 5 } - -xATSTestingResultsLastLoadedDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent in the testingWithLoad state during the last system test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 6 } - -xATSTestingResultsLastUnloadedDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time spent in the testingWithoutLoad state during the last system test. - Specified in seconds, or -1 if not available." - ::= { xATSTestingResults 7 } - --- xATS TestingSchedule group - -xATSTestingScheduleFrequency OBJECT-TYPE - SYNTAX INTEGER { - never (1), - daily (2), - weekly (3), - monthly (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The frequency of running scheduled tests." - ::= { xATSTestingSchedule 1 } - -xATSTestingScheduleTestDay OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The desired day for the scheduled test. This object applies only - when the xATSTestingScheduleFrequency OID is set to weekly or monthly. - For weekly test frequency, the string is the day the test will be run. - For monthly test frequency, the string indicates the day, - and the instance within the month. - For example, for monthly frequency: 2nd sunday, 3rd monday, 4th tuesday, - for weekly frequency: sunday, monday, tuesday." - ::= { xATSTestingSchedule 2 } - -xATSTestingScheduleTestTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The time of day that the scheduled test will occur. - Specified in the format hh:mm." - ::= { xATSTestingSchedule 3 } - -xATSTestingScheduleTestWithLoadInterval OBJECT-TYPE - SYNTAX INTEGER { - applyLoadEveryTest (1), - neverApplyLoad (2), - applyLoadMonthly (3), - applyLoadMonthlyDetailed (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting specifies which system tests should include applying the - load to the generator. The applyLoadMonthlyDetailed entry - in the list will apply load once, for each month represented in the - xATSTestingScheduleTestWithLoadSelectMonth OID." - ::= { xATSTestingSchedule 4 } - -xATSTestingScheduleTestWithLoadSelectMonth OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The detailed selection for testing with load on a month-by-month basis. - This object is applicable when the xATSTestingScheduleTestWithLoadInterval - is set to applyLoadMonthlyDetailed. Otherwise this selection will be ignored. - Format for this string is a comma-separated entry of months. - For example: Jan,Mar,Dec. - The string will return 'No Months Scheduled' if no months have been selected." - ::= { xATSTestingSchedule 5 } - -xATSTestingScheduleNextTestDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the next scheduled test, in the format dd-mmm-yyyy." - ::= { xATSTestingSchedule 6 } - --- xATSTestingSimulatePowerFail group - -xATSTestingSimulatePowerFailTest OBJECT-TYPE - SYNTAX INTEGER{ - cancelSimulation (1), - fiveSecondsSimulation (2), - tenSecondsSimulation (3), - thirtySecondsSimulation (4), - oneMinuteSimulation (5), - threeMinutesSimulation (6), - fiveMinutesSimulation (7), - tenMinutesSimulation (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This object executes a simulated power failure for the duration indicated. - Simulation can be aborted by selecting cancelSimulation." - ::= { xATSTestingSimulatePowerFail 1 } - -xATSTestingSimulatePowerFailTimeRemaining OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the time remaining in seconds, for a simulated power failure. - a value of zero indicates that simulated power failure is not active." - ::= { xATSTestingSimulatePowerFail 2 } - --- The xATS Input Contact group - -xATSInputContactNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the ATS." - ::= { xATSInputContacts 1 } - -xATSInputContactTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input contact entries." - ::= { xATSInputContacts 2 } - -xATSInputContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the ATS. - The number of entries is contained in the - xATSInputContactTableSize OID." - ::= { xATSInputContacts 3 } - - xATSInputContactEntry OBJECT-TYPE - SYNTAX XATSContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A contact entry containing information for a given contact." - INDEX { xATSInputContactNumber } - ::= { xATSInputContactTable 1 } - - XATSContactEntry ::= - SEQUENCE { - xATSInputContactNumber INTEGER, - xATSInputContactName DisplayString, - xATSInputContactNormalState INTEGER, - xATSInputContactCurrentState INTEGER - } - - xATSInputContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the contact on the ATS." - ::= { xATSInputContactEntry 1 } - - xATSInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the contact." - ::= { xATSInputContactEntry 2 } - - xATSInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the contact." - ::= { xATSInputContactEntry 3 } - - xATSInputContactCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the contact." - ::= { xATSInputContactEntry 4 } - --- the xATS OutputRelays group - - xATSOutputRelayNumRelays OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relays supported by the ATS." - ::= { xATSOutputRelays 1 } - - xATSOutputRelayTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relay entries." - ::= { xATSOutputRelays 2 } - - xATSOutputRelayTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output relays supported by the ATS. - The number of entries is contained in the - xATSOutputRelayTableSize OID." - ::= { xATSOutputRelays 3 } - - xATSOutputRelayEntry OBJECT-TYPE - SYNTAX XATSOutputRelayEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A output relay entry containing information for a given contact." - INDEX { xATSOutputRelayNumber } - ::= { xATSOutputRelayTable 1 } - - XATSOutputRelayEntry ::= - SEQUENCE { - xATSOutputRelayNumber INTEGER, - xATSOutputRelayName DisplayString, - xATSOutputRelayNormalState INTEGER, - xATSOutputRelayCurrentState INTEGER - } - - xATSOutputRelayNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the output relay on the ATS." - ::= { xATSOutputRelayEntry 1 } - - xATSOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the output relay." - ::= { xATSOutputRelayEntry 2 } - - xATSOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the output relay." - ::= { xATSOutputRelayEntry 3 } - - xATSOutputRelayCurrentState OBJECT-TYPE - SYNTAX INTEGER { - open (1), - closed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the output relay." - ::= { xATSOutputRelayEntry 4 } - --- The xATS Generator Ident group - -xATSGeneratorIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of the generator. - This value is set at the factory." - ::= { xATSGeneratorIdent 1 } - -xATSGeneratorIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of the generator. - This value is set at the factory." - ::= { xATSGeneratorIdent 2 } - -xATSGeneratorIdentDateofManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying when the generator was manufactured in mm/dd/yyyy format. - This value is set at the factory." - ::= { xATSGeneratorIdent 3 } - -xATSGeneratorIdentVoltageConfiguration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The voltage for which the generator's alternator is designed. - Specified in Volts line-to-line." - ::= { xATSGeneratorIdent 4 } - -xATSGeneratorIdentMaxPowerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The max power rating of the generator. Specified in kW." - ::= { xATSGeneratorIdent 5 } - -xATSGeneratorIdentAlternatorFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency for which the generator's alternator is designed. - Specified in Hertz." - ::= { xATSGeneratorIdent 6 } - --- The xATS Generator Status group - -xATSGeneratorStatusGeneratorName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name or label for the generator connected to the source 2 of the ATS." - ::= { xATSGeneratorStatus 1 } - -xATSGeneratorStatusOperational OBJECT-TYPE - SYNTAX INTEGER{ - nocomm (1), - off (2), - ready (3), - starting (4), - idle (5), - running (6), - normalStop (7), - emergencyStop (8), - notInAuto (9), - shutdown (10), - unknown (11) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The operational status of the generator. unavailable when unrecognized status is received." - ::= { xATSGeneratorStatus 2 } - -xATSGeneratorStatusModeSwitchPosition OBJECT-TYPE - SYNTAX INTEGER{ - off (1), - manual (2), - automatic (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The position of the generator's auto-mode switch. - In automatic mode, the generator is started and stopped via the - remote start contact, which has state indicated in the - xATSGeneratorStatusRemoteStart OID. - In manual mode generator start/stop control is via local command only. - Off prevents the generator from running." - ::= { xATSGeneratorStatus 3 } - -xATSGeneratorStatusRemoteStart OBJECT-TYPE - SYNTAX INTEGER{ - stop (1), - run (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the generator's remote start contact, which is - provided as an output from the transfer switch to start/stop the - generator when in automatic mode." - ::= { xATSGeneratorStatus 4 } - --- The xATS Generator Advanced Status group - -xATSGeneratorAdvStatusBatteryVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The voltage of the generator's starting battery. - Measured in tenths of VDC, or -1 if not available." - ::= { xATSGeneratorAdvStatus 1 } - -xATSGeneratorAdvStatusOilPressure OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The generator's engine oil pressure. - Measured in tenths of Psi or kPa, based on the - value of the xATSGeneratorSettingsMetricUnit OID, - or -1 if not available." - ::= { xATSGeneratorAdvStatus 2 } - -xATSGeneratorAdvStatusCoolantTemperature OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Current coolant temperature in the generator. - Measured in degrees Celsius or Fahrenheit, based on the - value of the xATSGeneratorSettingsMetricUnit OID, - or -1 if not available." - ::= { xATSGeneratorAdvStatus 3 } - -xATSGeneratorAdvStatusEngineRPM OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Current engine speed of the generator. - Measured in RPM, or -1 if not available." - ::= { xATSGeneratorAdvStatus 4 } - -xATSGeneratorAdvStatusOilLevel OBJECT-TYPE - SYNTAX INTEGER{ - ok (1), - low (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates adequate oil level in the generator." - ::= { xATSGeneratorAdvStatus 5 } - -xATSGeneratorAdvStatusCoolantLevel OBJECT-TYPE - SYNTAX INTEGER{ - ok (1), - low (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates adequate coolant level in the generator." - ::= { xATSGeneratorAdvStatus 6 } - --- The xATS Generator Output group - -xATSGeneratorOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output frequency of the generator. - Measured in tenths of Hertz, or -1 if not avaialble." - ::= { xATSGeneratorOutput 1 } - -xATSGeneratorOutputTotalPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total output power of the generator. - Measured in tenths of tenths of kW, or -1 if not avaialble." - ::= { xATSGeneratorOutput 2 } - -xATSGeneratorOutputTotalApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total output power of the generator. - Measured in tenths of kVA, or -1 if not avaialble." - ::= { xATSGeneratorOutput 3 } - -xATSGeneratorOutputTotalPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the total load power factor of the generator. - A value of 100 representing a unity power factor (1.00), - or -1 when if not avaialble." - ::= { xATSGeneratorOutput 4 } - -xATSGeneratorOutputTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of generator output phase entries." - ::= { xATSGeneratorOutput 5 } - - xATSGeneratorOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF XATSGeneratorOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of generator output table entries. - The number of entries is contained in the xATSGeneratorOutputTableSize OID." - ::= { xATSGeneratorOutput 6 } - - xATSGeneratorOutputPhaseEntry OBJECT-TYPE - SYNTAX XATSGeneratorOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular generator output phase." - INDEX { xATSGeneratorOutputPhaseIndex } - ::= { xATSGeneratorOutputTable 1 } - - XATSGeneratorOutputPhaseEntry ::= SEQUENCE { - xATSGeneratorOutputPhaseIndex INTEGER, - xATSGeneratorOutputVoltageLtoL INTEGER, - xATSGeneratorOutputVoltageLtoN INTEGER, - xATSGeneratorOutputPhaseCurrent INTEGER, - xATSGeneratorOutputPower INTEGER, - xATSGeneratorOutputApparentPower INTEGER, - xATSGeneratorOutputPowerFactor INTEGER - } - - xATSGeneratorOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each generator output phase utilized in this device." - ::= { xATSGeneratorOutputPhaseEntry 1 } - - xATSGeneratorOutputVoltageLtoL OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-line generator output voltage. - Measured in Volts, or -1 if not available." - ::= { xATSGeneratorOutputPhaseEntry 2 } - - xATSGeneratorOutputVoltageLtoN OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Line-to-neutral generator output voltage. - Measured in volts, or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 3 } - - xATSGeneratorOutputPhaseCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Generator load current per phase. - Measured in Amps, or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 4 } - - xATSGeneratorOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Generator output power per phase. - Measured in tenths of kW, or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 5 } - - xATSGeneratorOutputApparentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Generator output power per phase. - Measured in tenths of kVA, or -1 if not available." - ::= { xATSGeneratorOutputPhaseEntry 6 } - - xATSGeneratorOutputPowerFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates the load power factor of the generator output per phase. - A value of 100 representing a unity power factor (1.00), - or -1 if not avaialble." - ::= { xATSGeneratorOutputPhaseEntry 7 } - --- xATS Generator Settings group - -xATSGeneratorSettingsVoltageAdjust OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The voltage adjust of the generator. - Specified in volts line-to-line, - or -1 if not available." - ::= { xATSGeneratorSettings 1 } - -xATSGeneratorSettingsFrequencyAdjust OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frequency adjust of the generator. - Specified in tenths of Hertz." - ::= { xATSGeneratorSettings 2 } - -xATSGeneratorSettingsStartDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The delay, in seconds, after the remote run signal is activated - before the generator's engine will be cranked to start, - or -1 if not available." - ::= { xATSGeneratorSettings 3 } - -xATSGeneratorSettingsStopDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The delay, in seconds, before the generator will stop - after the remote run signal is deactivated, - or -1 if not available." - ::= { xATSGeneratorSettings 4 } - -xATSGeneratorSettingsCrankCycleEnable OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - enabled (2), - unknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "When Crank Cycle is enabled, the engine will be cranked up to the time - specified by the xATSGeneratorSettingsCrankTime OID. - If the generator's engine does not start, there will be a pause as - specified by the xATSGeneratorSettingsCrankRestTime OID before the - engine will be cranked again. This cycle is repeated as specified by - the xATSGeneratorSettingsNumberCrank OID. - When crank cycle is disabled, the generator's engine will be - cranked continuously until it starts." - ::= { xATSGeneratorSettings 5 } - -xATSGeneratorSettingsCrankTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The duration of engine cranking, in seconds, when starting the generator. - Applicable when the xATSGeneratorSettingsCrankCycleEnable OID is enabled. - -1 if not available." - ::= { xATSGeneratorSettings 6 } - -xATSGeneratorSettingsCrankRestTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The pause duration, in seconds, following an unsuccessful attempt to start the generator. - Applicable when the xATSGeneratorSettingsCrankCycleEnable OID is enabled. - -1 if not available." - ::= { xATSGeneratorSettings 7 } - -xATSGeneratorSettingsNumberCrank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of failed crank attempts before giving up on starting the generator. - Applicable when the xATSGeneratorSettingsCrankCycleEnable OID is enabled. - -1 if not available." - ::= { xATSGeneratorSettings 8 } - -xATSGeneratorSettingsMetricUnit OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - enabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Specifies the use of metric units in generator related OIDs, as well - as on all other interfaces including the generator's local interface." - ::= { xATSGeneratorSettings 9 } - --- xATS generator service group - -xATSGeneratorServiceTotalRunHoursLifetime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total time that the generator engine has been run, - over the life of the generator. Measured in hours. - -1 if not available." - ::= { xATSGeneratorService 1 } - -xATSGeneratorServiceEngineStartsLifetime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Number of engine starts over the life of the generator. - -1 if not available." - ::= { xATSGeneratorService 2 } - -xATSGeneratorServiceTotalkWhLifetime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total kWh of operation over the life of the generator. - -1 if not available." - ::= { xATSGeneratorService 3 } - -xATSGeneratorServiceTotalRunHoursSinceMaintanence OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total time that the generator engine has been run, - since last service maintenance. Measured in tenths of hours. - -1 if not available." - ::= { xATSGeneratorService 4 } - -xATSGeneratorServiceEngineStartsSinceMaintanence OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Number of engine starts since last service maintenance. - -1 if not available." - ::= { xATSGeneratorService 5 } - -xATSGeneratorServiceTotalkWhMaintanence OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Total kWh of operation since last service maintenance. - -1 if not available." - ::= { xATSGeneratorService 6 } - -xATSGeneratorServiceResetRecord OBJECT-TYPE - SYNTAX INTEGER{ - yes (1), - no (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Resets the engine start counter, engine run-hours, and kWh values that have - accumulated in the generator since last maintenance. - Also, the last service date will be reset to the current system date, and - any service alarms will be cleared." - ::= { xATSGeneratorService 7 } - -xATSGeneratorServiceRecordResetDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Date at which the generator's service record was reset, in dd-mmm-yyyy format." - ::= { xATSGeneratorService 8 } - -xATSGeneratorServiceNextServiceDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Date at which the next generator service is due in dd-mmm-yyyy format. - Based on the xATSGeneratorServiceCalendarIntervalThreshold OID - or '' if the calander-based threshold is set to off." - ::= { xATSGeneratorService 9 } - -xATSGeneratorServiceRunHoursUntilServiceDate OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Runhours until the next generator service is due, in hours. - Based on the xATSGeneratorServiceRunHoursThreshold OID - or -1 if the runhour-based threshold is set to off." - ::= { xATSGeneratorService 10 } - -xATSGeneratorServiceRunHoursThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - runThreshold100Hours (2), - runThreshold150Hours (3), - runThreshold200Hours (4), - runThreshold250Hours (5), - runThreshold300Hours (6), - runThreshold400Hours (7), - runThreshold500Hours (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Runhour-based service interval. When the run-hours since - service surpasses this threshold, generator service is due." - ::= { xATSGeneratorService 11 } - -xATSGeneratorServiceCalendarIntervalThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - interval1month (2), - interval2month (3), - interval3month (4), - interval6month (5), - intervalyearly (6) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Calander-based service interval. When the next service date, - as indicated by the xATSGeneratorServiceNextServiceDate OID - is in the past, generator is due for service." - ::= { xATSGeneratorService 12 } - --- The xATS Generator Fuel system group - -xATSGeneratorFuelSystemType OBJECT-TYPE - SYNTAX INTEGER{ - diesel (1), - propane (2), - naturalGas (3), - unknown (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of fuel used by the generator." - ::= { xATSGeneratorFuelSystem 1 } - -xATSGeneratorFuelSystemTankSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Size of the generator's fuel tank. - Specified in gallons or liters, based on the value of the - xATSGeneratorSettingsMetricUnit OID, or -1 if not available." - ::= { xATSGeneratorFuelSystem 2 } - -xATSGeneratorFuelSystemFuelLevel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Fuel remaining in the generator tank. - Measured in percent of tank fill, or -1 if if not available." - ::= { xATSGeneratorFuelSystem 3 } - -xATSGeneratorFuelSystemRuntimePower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The power value used in the runtime remaining calculation. - Measured in tenths of kW, or -1 if not available." - ::= { xATSGeneratorFuelSystem 4 } - -xATSGeneratorFuelSystemEstimatedRunTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An estimate of available runtime for the generator, based on - available fuel as specified in the xATSGeneratorFuelSystemFuelLevel OID - and kW load as specified in the xATSGeneratorFuelSystemRuntimePower OID. - Measured in tenths of hours, or -1 if not available." - ::= { xATSGeneratorFuelSystem 5 } - -xATSGeneratorFuelSystemLowRunTimeThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - oneHour (2), - twoHours (3), - threeHours (4), - fourHours (5), - fiveHours (6), - sixHours (7), - twelveHours (8), - oneDay (9), - twoDays (10), - threeDays (11), - fourDays (12), - fiveDays (13), - sixDays (14), - sevenDays (15) - - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a low runtime alarm will exist." - ::= { xATSGeneratorFuelSystem 6 } - -xATSGeneratorFuelSystemVeryLowRunTimeThreshold OBJECT-TYPE - SYNTAX INTEGER{ - disabled (1), - oneHour (2), - twoHours (3), - threeHours (4), - fourHours (5), - fiveHours (6), - sixHours (7), - twelveHours (8), - oneDay (9), - twoDays (10), - threeDays (11), - fourDays (12), - fiveDays (13), - sixDays (14), - sevenDays (15) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a very low runtime alarm will exist." - ::= { xATSGeneratorFuelSystem 7 } - -xATSGeneratorFuelSystemLowFuelLevelThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a low fuel alarm will exist, with a value of 0 indicating disabled. - Specified as percent of tank fill." - ::= { xATSGeneratorFuelSystem 8 } - -xATSGeneratorFuelSystemVeryLowFuelLevelThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold below which a very low fuel alarm will exist, with a value of 0 indicating disabled. - Specified as percent of tank fill." - ::= { xATSGeneratorFuelSystem 9 } - --- the software group --- the powerNetSubAgent group --- the powerNetSoftwareSystem group - -powerNetSoftwareSystemDescription OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..79)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A brief description of the PowerNet sub-agent." - ::= { powerNetSoftwareSystem 1 } - -powerNetSoftwareOid OBJECT-TYPE - SYNTAX OBJECT IDENTIFIER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The object identifier of the PowerNet sub-agent." - ::= { powerNetSoftwareSystem 2 } - --- powerNetSmuxPeer OBJECT IDENTIFIER ::= { powerNetSoftwareOid 1 } --- powerNetDPIPeer OBJECT IDENTIFIER ::= { powerNetSoftwareOid 2 } - -powerNetSoftwareSystemUpTime OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The time that the sub-agent has been running." - ::= { powerNetSoftwareSystem 3 } - - --- powerNetSoftwareConfig group - -powerNetSoftwareTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of software modules supporting the UPS." - ::= { powerNetSoftwareConfig 1 } - -powerNetSoftwareTable OBJECT-TYPE - SYNTAX SEQUENCE OF SoftwareEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of the software monitoring the UPS." - ::= { powerNetSoftwareConfig 2 } - -powerNetSoftwareEntry OBJECT-TYPE - SYNTAX SoftwareEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information on a software module." - INDEX { moduleNumber } - ::= { powerNetSoftwareTable 1 } - -SoftwareEntry ::= - SEQUENCE { - moduleNumber - INTEGER, - moduleName - DisplayString, - moduleVersion - DisplayString, - moduleDate - DisplayString - } - -moduleNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index into the Software Entry Table" - ::= { powerNetSoftwareEntry 1 } - -moduleName OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..79)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the software module." - ::= { powerNetSoftwareEntry 2 } - -moduleVersion OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..8)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The version of the software module." - ::= { powerNetSoftwareEntry 3 } - -moduleDate OBJECT-TYPE - SYNTAX DisplayString (SIZE (0..9)) - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the software module represented as mm-dd-yy." - ::= { powerNetSoftwareEntry 4 } - - --- the ups group --- the upsIdent group --- the upsBasicIdent - -upsBasicIdentModel OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The UPS model name (e.g. 'APC Smart-UPS 600')." - ::= { upsBasicIdent 1 } - -upsBasicIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An 8 byte ID string identifying the UPS. This object - can be set by the administrator." - ::= { upsBasicIdent 2 } - - --- the upsAdvIdent group - -upsAdvIdentFirmwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the UPS system's microprocessor." - ::= { upsAdvIdent 1 } - -upsAdvIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the UPS was manufactured in mm/dd/yy format." - ::= { upsAdvIdent 2 } - -upsAdvIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 8-character string identifying the serial number of - the UPS internal microprocessor. This number is set at - the factory. NOTE: This number does NOT correspond to - the serial number on the rear of the UPS." - ::= { upsAdvIdent 3 } - - - --- the upsBattery group --- the upsBasicBattery group - -upsBasicBatteryStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - batteryNormal(2), - batteryLow(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the UPS batteries. A batteryLow(3) - value indicates the UPS will be unable to sustain the - current load, and its services will be lost if power is - not restored. The amount of run time in reserve at the - time of low battery can be configured by the - upsAdvConfigLowBatteryRunTime." - ::= { upsBasicBattery 1 } - -upsBasicBatteryTimeOnBattery OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The elapsed time since the UPS has switched to battery - power." - ::= { upsBasicBattery 2 } - -upsBasicBatteryLastReplaceDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The date when the UPS system's batteries were last replaced - in mm/dd/yy format. For Smart-UPS models, this value - is originally set in the factory. When the UPS batteries - are replaced, this value should be reset by the administrator." - ::= { upsBasicBattery 3 } - - - --- the upsAdvBattery group - -upsAdvBatteryCapacity OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remaining battery capacity expressed in - percent of full capacity." - ::= { upsAdvBattery 1 } - -upsAdvBatteryTemperature OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current internal UPS temperature expressed in - Celsius." - ::= { upsAdvBattery 2 } - -upsAdvBatteryRunTimeRemaining OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The UPS battery run time remaining before battery - exhaustion." - ::= { upsAdvBattery 3 } - -upsAdvBatteryReplaceIndicator OBJECT-TYPE - SYNTAX INTEGER { - noBatteryNeedsReplacing(1), - batteryNeedsReplacing(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Indicates whether the UPS batteries need replacing." - ::= { upsAdvBattery 4 } - -upsAdvBatteryNumOfBattPacks OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of external battery packs connected to the UPS. If - the UPS does not use smart cells then the agent reports - ERROR_NO_SUCH_NAME." - ::= { upsAdvBattery 5 } - -upsAdvBatteryNumOfBadBattPacks OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of external battery packs connected to the UPS that - are defective. If the UPS does not use smart cells then the - agent reports ERROR_NO_SUCH_NAME." - ::= { upsAdvBattery 6 } - -upsAdvBatteryNominalVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The nominal battery voltage in Volts." - ::= { upsAdvBattery 7 } - -upsAdvBatteryActualVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The actual battery bus voltage in Volts." - ::= { upsAdvBattery 8 } - -upsAdvBatteryCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery current in Amps." - ::= { upsAdvBattery 9 } - -upsAdvTotalDCCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total DC current in Amps." - ::= { upsAdvBattery 10 } - - --- the upsBasicInput group - -upsBasicInputPhase OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current AC input phase." - ::= { upsBasicInput 1 } - - --- the upsAdvInput group - -upsAdvInputLineVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current utility line voltage in VAC." - ::= { upsAdvInput 1 } - -upsAdvInputMaxLineVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum utility line voltage in VAC over the - previous 1 minute period." - ::= { upsAdvInput 2 } - -upsAdvInputMinLineVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum utility line voltage in VAC over the - previous 1 minute period." - ::= { upsAdvInput 3 } - -upsAdvInputFrequency OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current input frequency to the UPS system in Hz." - ::= { upsAdvInput 4 } - - -upsAdvInputLineFailCause OBJECT-TYPE - SYNTAX INTEGER { - noTransfer(1), - highLineVoltage(2), - brownout(3), - blackout(4), - smallMomentarySag(5), - deepMomentarySag(6), - smallMomentarySpike(7), - largeMomentarySpike(8), - selfTest(9), - rateOfVoltageChnage(10) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The reason for the occurrence of the last transfer to UPS - battery power. The variable is set to: - - noTransfer(1) -- if there is no transfer yet. - - highLineVoltage(2) -- if the transfer to battery is caused - by an over voltage greater than the high transfer voltage. - - brownout(3) -- if the duration of the outage is greater than - five seconds and the line voltage is between 40% of the - rated output voltage and the low transfer voltage. - - blackout(4) -- if the duration of the outage is greater than five - seconds and the line voltage is between 40% of the rated - output voltage and ground. - - smallMomentarySag(5) -- if the duration of the outage is less - than five seconds and the line voltage is between 40% of the - rated output voltage and the low transfer voltage. - - deepMomentarySag(6) -- if the duration of the outage is less - than five seconds and the line voltage is between 40% of the - rated output voltage and ground. The variable is set to - - smallMomentarySpike(7) -- if the line failure is caused by a - rate of change of input voltage less than ten volts per cycle. - - largeMomentarySpike(8) -- if the line failure is caused by - a rate of change of input voltage greater than ten volts per cycle. - - selfTest(9) -- if the UPS was commanded to do a self test. - - rateOfVoltageChange(10) -- if the failure is due to the rate of change of - the line voltage." - ::= { upsAdvInput 5 } - - --- the upsBasicOutput group - -upsBasicOutputStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - onLine(2), - onBattery(3), - onSmartBoost(4), - timedSleeping(5), - softwareBypass(6), - off(7), - rebooting(8), - switchedBypass(9), - hardwareFailureBypass(10), - sleepingUntilPowerReturn(11), - onSmartTrim(12) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current state of the UPS. If the UPS is unable - to determine the state of the UPS this variable is set - to unknown(1)." - ::= { upsBasicOutput 1 } - -upsBasicOutputPhase OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current output phase." - ::= { upsBasicOutput 2 } - - --- the upsAdvOutput group - -upsAdvOutputVoltage OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage of the UPS system in VAC." - ::= { upsAdvOutput 1 } - -upsAdvOutputFrequency OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current output frequency of the UPS system in Hz." - ::= { upsAdvOutput 2 } - -upsAdvOutputLoad OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current UPS load expressed in percent - of rated capacity." - ::= { upsAdvOutput 3 } - -upsAdvOutputCurrent OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current in amperes drawn by the load on the UPS." - ::= { upsAdvOutput 4 } - - --- the upsBasicConfig group - -upsBasicConfigNumDevices OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of devices that are plugged into the UPS." - ::= { upsBasicConfig 1 } - -upsBasicConfigDeviceTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsBasicConfigDeviceEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of devices that are plugged into the UPS. - The number of entries is given by the value of - upsBasicConfigNumDevices." - ::= { upsBasicConfig 2 } - -upsBasicConfigDeviceEntry OBJECT-TYPE - SYNTAX UpsBasicConfigDeviceEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The devices plugged in to the UPS." - INDEX { deviceIndex } - ::= { upsBasicConfigDeviceTable 1 } - -UpsBasicConfigDeviceEntry ::= - SEQUENCE { - deviceIndex - INTEGER, - deviceName - DisplayString, - vaRating - INTEGER, - acceptThisDevice - INTEGER - } - -deviceIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the device that is plugged into the UPS." - ::= { upsBasicConfigDeviceEntry 1 } - -deviceName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name/description of the device plugged into the UPS." - ::= { upsBasicConfigDeviceEntry 2 } - -vaRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The volt-amp rating of the device plugged into the UPS." - ::= { upsBasicConfigDeviceEntry 3 } - -acceptThisDevice OBJECT-TYPE - SYNTAX INTEGER { - yes(1), - no(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An entry is added if yes, the entry is deleted if no." - ::= { upsBasicConfigDeviceEntry 4 } - - - - --- the upsAdvConfig group - -upsAdvConfigRatedOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The nominal output voltage from the UPS in VAC. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { upsAdvConfig 1 } - -upsAdvConfigHighTransferVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The maximum line voltage in VAC allowed before the - UPS system transfers to battery backup. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 2 } - -upsAdvConfigLowTransferVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum line voltage in VAC allowed before the - UPS system transfers to battery backup. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { upsAdvConfig 3 } - -upsAdvConfigAlarm OBJECT-TYPE - SYNTAX INTEGER { - timed(1), - atLowBattery(2), - never(3), - mute(4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A flag indicating how the UPS should handle audible - line fail alarms: - timed(1): UPS alarm will sound after a preset timed duration starting - from the line fail condition (see OID upsAdvConfigAlarmTimer for the - alarm timer value) - atLowBattery(2): UPS alarm will sound when the UPS has reached a Low - Battery condition during a line fail - never(3): Disables the UPS audible alarm - mute(4): Mutes the current alarm for some UPSs only when it is in an - alarm state and will return to the previously configured option when - the UPS recovers from the alarm condition" - ::= { upsAdvConfig 4 } - -upsAdvConfigAlarmTimer OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The time after initial line failure at which the UPS - begins emitting audible alarms (beeping). This timer is - observed only if the value of extControlAlarm is timed(2). - Allowed values are 0 or 30 seconds. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { upsAdvConfig 5 } - -upsAdvConfigMinReturnCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The minimum battery capacity required before the UPS will - return from a low battery shutdown condition. The capacity is - measured from 0% battery capacity (or Low Battery) as a percent - of full capacity (100%). In other words, the UPS will not re-energize - the output until the battery has charged so that its' capacity is equal - to this value. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 6 } - -upsAdvConfigSensitivity OBJECT-TYPE - SYNTAX INTEGER { - auto(1), - low(2), - medium(3), - high(4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The sensitivity of the UPS to utility line abnormalities - or noises." - ::= { upsAdvConfig 7 } - -upsAdvConfigLowBatteryRunTime OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The desired run time of the UPS, in seconds, once the - low battery condition is reached. During this time the UPS will - produce a constant warning tone which can not be disabled. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a set - request, the UPS interprets the value as the next higher - acceptable value. If the provided value is higher than the - highest acceptable value, the highest acceptable value is used." - ::= { upsAdvConfig 8 } - -upsAdvConfigReturnDelay OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay in seconds after utility line power returns - before the UPS will turn on. This value is also used - when the UPS comes out of a reboot and before the UPS - wakes up from 'sleep' mode. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 9 } - -upsAdvConfigShutoffDelay OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay in seconds the UPS remains on after being told - to turn off. - - For a list of allowed values supported by your UPS model, - see the UPS User's Manual. - - If a value other than a supported value is provided in a - set request, the UPS interprets it as a the next higher - acceptable value. If the provided value is higher than - the highest acceptable value, the highest acceptable - value is used." - ::= { upsAdvConfig 10 } - -upsAdvConfigUpsSleepTime OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The time in seconds for the UPS to go to 'sleep' when - instructed. When in sleep mode, the UPS will not provide - output power regardless of the input line state. Once the - specified time has elapsed, output power will be restored. - - This is a configuration setting. The UPS will not go to - sleep until told to do so by the manager from a management - station. - - Any input value is allowed, however the UPS only recognizes - 1/10 of an hour increments. The provided value will be - rounded to the closest 1/10 of an hour with one exception: - Any value entered between 1 and 540 seconds will be rounded - to 360 seconds (or 6 minutes)." - ::= { upsAdvConfig 11 } - - -upsAdvConfigSetEEPROMDefaults OBJECT-TYPE - SYNTAX INTEGER { - noSetEEPROMDefaults(1), - setEEPROMDefaults(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "WRITE: Resets the UPS EEPROM variables to default values. - READ: returns 0" - ::= { upsAdvConfig 12 } - -upsAdvConfigDipSwitchSetting OBJECT-TYPE - SYNTAX SEQUENCE OF UpsAdvConfigDipSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Current settings of UPS dip switches." - ::= { upsAdvConfig 13 } - -upsAdvConfigDipSwitchEntry OBJECT-TYPE - SYNTAX UpsAdvConfigDipSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The current setting of one dip switch." - INDEX { dipSwitchIndex } - ::= { upsAdvConfigDipSwitchSetting 1 } - -UpsAdvConfigDipSwitchEntry ::= - SEQUENCE { - dipSwitchIndex - INTEGER, - dipSwitchStatus - INTEGER - } - -dipSwitchIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a UPS dip switch." - ::= { upsAdvConfigDipSwitchEntry 1 } - -dipSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - on(1), - off(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The setting of a UPS dip switch." - ::= { upsAdvConfigDipSwitchEntry 2 } - -upsAdvConfigBattExhaustThresh OBJECT-TYPE - SYNTAX TimeTicks - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The number of seconds prior to battery exhaustion when the - UPS will switch off power to its load." - ::= { upsAdvConfig 14 } - -upsAdvConfigPassword OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The password entered at the UPS front panel to enable local - configuration of the EEProm. If the password is disabled or - is not supported, then the agent returns a null string." - ::= { upsAdvConfig 15 } - -upsAdvConfigAllowedSetTable OBJECT-TYPE - SYNTAX SEQUENCE OF ApcUpsConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The table listing the allowed values for all discrete - configurable UPS variables." - ::= { upsAdvConfig 16 } - -apcUpsConfigEntry OBJECT-TYPE - SYNTAX ApcUpsConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The table entry for a configurable UPS variable." - INDEX { apcUpsConfigFieldIndex } - ::= { upsAdvConfigAllowedSetTable 1 } - -ApcUpsConfigEntry ::= SEQUENCE { - apcUpsConfigFieldIndex INTEGER, - apcUpsConfigFieldOID OBJECT IDENTIFIER, - apcUpsConfigFieldValueRange DisplayString - } - -apcUpsConfigFieldIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to an eeprom field entry." - ::= { apcUpsConfigEntry 1 } - -apcUpsConfigFieldOID OBJECT-TYPE - SYNTAX OBJECT IDENTIFIER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The OID of the current configurable value." - ::= { apcUpsConfigEntry 2 } - -apcUpsConfigFieldValueRange OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The discrete set of allowed values of a configurable - register. Individual values are delimited by a comma." - ::= { apcUpsConfigEntry 3 } - -upsAdvConfigBattCabAmpHour OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS battery cabinet amp hour setting." - ::= { upsAdvConfig 17 } - -upsAdvConfigPositionSelector OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - rack (2), - tower (3) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure UPS position selector. If the UPS doesn't - support this configuration it will report unknown (1). - The positions are either rack (2) for rack mounted or - tower (3) for tower unit." - ::= { upsAdvConfig 18 } - -upsAdvConfigOutputFreqRange OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - freqRangeAUTO (2), - freqRange60Var1 (3), - freqRange60Var3 (4), - freqRange50Var1 (5), - freqRange50Var3 (6), - freqRange60Var10 (7), - freqRange50Var10 (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the output frequency tolerance range. - unknown(1) indicates the output frequency is unknown. - freqRangeAUTO(2) configure the output frequency range for automatic. - freqRange60Var1(3) configure the output frequency range for 60 +/- 0.1 Hz - freqRange60Var3(4) configure the output frequency range for 60 +/- 3.0 Hz - freqRange50Var1(5) configure the output frequency range for 50 +/- 0.1 Hz - freqRange50Var3(6) configure the output frequency range for 50 +/- 3.0 Hz - freqRange60Var10(7) configure the output frequency range for 60 +/- 10 Hz - freqRange50Var10(8) configure the output frequency range for 50 +/- 10 Hz" - ::= { upsAdvConfig 19 } - -upsAdvConfigUPSFail OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - gotoBypass (2), - dropLoad (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the UPS fail action. If UPS fails, - and frequency or voltage is out of range it will either - GotoBypass (2) or DropLoad (3). This OID will report - unknown (1) if it is not supported feature or option." - ::= { upsAdvConfig 20 } - -upsAdvConfigAlarmRedundancy OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS alarm if the redundancy is - under the current redundancy. Use -1 for never." - ::= { upsAdvConfig 21 } - -upsAdvConfigAlarmLoadOver OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS alarm if the load is - over the current load in kVA. Use -1 for never." - ::= { upsAdvConfig 22 } - -upsAdvConfigAlarmRuntimeUnder OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure settings of UPS alarm if the runtime is - under the current time of minutes. Use -1 for never." - ::= { upsAdvConfig 23 } - -upsAdvConfigVoutReporting OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - voutAUTO (2), - vout208 (3), - vout240 (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the way the UPS scales its output voltage readings. - unknown(1) indicates the Vout Reporting is unknown. - voutAUTO(2) configure the Vout Reporting for automatic scalling. - vout208(3) configure the Vout Reporting for 208 Volts. - vout240(4) configure the Vout Reporting for 240 Volts." - ::= { upsAdvConfig 24 } - -upsAdvConfigNumExternalBatteries OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure the number of external batteries connected to the UPS." - ::= { upsAdvConfig 25 } - -upsAdvConfigSimpleSignalShutdowns OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - disabled (2), - enabled (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Configure Simple Signal shutdown commands from the Simple Signal - port to be issued to the UPS. - unknown(1) indicates the Simple Signal Shutdown setting is unknown. - disabled(2) configure to disable Simple Signal Shutdowns. - enabled(3) configure to enable Simple Signal Shutdowns." - ::= { upsAdvConfig 26 } - - --- the upsSyncCtrlGroupConfig group - -upsSCGMembershipGroupNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The SCG Membership Group number (MGN) is a 16-bit number allowing - up to 65534 separate groups that can be identified and distinguished - per IP subnet. Zero and 65535 are not used. The MGN is used in all - communication between members of the SCG and a Network Management Card - (NMC) will listen and only respond to commands sent to it using its - configured SCG ID." - ::= { upsSyncCtrlGroupConfig 1 } - -upsSCGActiveMembershipStatus OBJECT-TYPE - SYNTAX INTEGER { - enabledSCG (1), - disabledSCG (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Membership in the configured SCG can be enabled and - disabled. If an NMC is configured for an SCG, but - has its membership disabled, all synchronized control commands - received will be ignored." - ::= { upsSyncCtrlGroupConfig 2 } - -upsSCGPowerSynchronizationDelayTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The Power Synchronization Delay Time (PSD) setting is the maximum - number of seconds an SCG Initiator will wait for all SCG members to - recover utility power before completing the reboot sequence of a - reboot or sleep command. If all SCG members are ready to proceed, - no additional delay is introduced." - ::= { upsSyncCtrlGroupConfig 3 } - -upsSCGReturnBatteryCapacityOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A reboot command uses the Initiator�s Return battery Capacity (RBC) to control - when the SCG completes this operation. In a Normal Control Operation (NCC) the - UPS will only complete the reboot if RBC is reached. Due to normal battery - charge rate variations it may be desirable for the Followers to complete the - reboot if they are within some range of the Initiator�s RBC when the Initiator - is prepared (charged to RBC) to complete the reboot. The Return Battery - Capacity Offset (RBCO) defines a percent battery capacity subtracted from an - RBC above which a Follower�s battery must be charged for it to complete a - reboot. For example, if the Initiator�s RBC is 50% and the Initiator�s RBCO is - 5% then a Follower�s battery capacity is within range if it is greater or equal - to 45% (50% - 5%) at the time when the Initiator tries to complete the reboot - command. The default RBCO is 10%. " - ::= { upsSyncCtrlGroupConfig 4 } - -upsSCGMultiCastIP OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The MultiCast IP address of the SCG Group." - ::= { upsSyncCtrlGroupConfig 5 } - --- the upsSyncCtrlGroupStatus group - -upsSCGNumOfGroupMembers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of active, communicating members in the Sync Control Group (SCG). - This variable indicates the number of rows in the SCG Status Table." - ::= { upsSyncCtrlGroupStatus 1 } - --- Sync Control Group Status Table - -upsSCGStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsSCGStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of SCG status table entries. The number of entries - is given by the value of upsSCGNumOfGroupMembers." - ::= { upsSyncCtrlGroupStatus 2 } - - upsSCGStatusEntry OBJECT-TYPE - SYNTAX UpsSCGStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular SCG Member." - INDEX { upsSCGStatusTableIndex } - ::= { upsSCGStatusTable 1 } - - UpsSCGStatusEntry ::= SEQUENCE { - upsSCGStatusTableIndex INTEGER, - upsSCGMemberIP IpAddress, - upsSCGACInputStatus INTEGER, - upsSCGACOutputStatus INTEGER - } - - upsSCGStatusTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a status entry for an active, communicating SCG member." - ::= { upsSCGStatusEntry 1 } - - upsSCGMemberIP OBJECT-TYPE - SYNTAX IpAddress - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The IP address of an active, communicating SCG Member." - ::= { upsSCGStatusEntry 2 } - - upsSCGACInputStatus OBJECT-TYPE - SYNTAX INTEGER { - acInGood(1), - acInBad(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID indicates the AC Input Status of the SCG Member. - acInGood(1) indicates the AC Input is within tolerance. - acInBad(2) indicates the AC Input is not within tolerance." - ::= { upsSCGStatusEntry 3 } - - upsSCGACOutputStatus OBJECT-TYPE - SYNTAX INTEGER { - acOutOn(1), - acOutOff(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID indicates the AC Output Status of the SCG Member. - acOutOn(1) indicates the UPS output is providing power to the load. - acOutOff(2) indicates the UPS output is not providing power to the load. " - ::= { upsSCGStatusEntry 4 } - --- the upsBasicState group - -upsBasicStateOutputState OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 64 flags representing - the current state(s) of the UPS. If the Network Card - is unable to determine the state of the UPS, this - variable is set to �UNKNOWN�. - - The flags are numbered 1 to 64, read from left to - right. The flags are defined as follows: - - Flag 1: Abnormal Condition Present - Flag 2: On Battery - Flag 3: Low Battery - Flag 4: On Line - - Flag 5: Replace Battery - Flag 6: Serial Communication Established - Flag 7: AVR Boost Active* - Flag 8: AVR Trim Active* - - Flag 9: Overload - Flag 10: Runtime Calibration - Flag 11: Batteries Discharged - Flag 12: Manual Bypass - - Flag 13: Software Bypass - Flag 14: In Bypass due to Internal Fault - Flag 15: In Bypass due to Supply Failure* - Flag 16: In Bypass due to Fan Failure* - - Flag 17: Sleeping on a Timer - Flag 18: Sleeping until Utility Power Returns - Flag 19: On - Flag 20: Rebooting - - Flag 21: Battery Communication Lost* - Flag 22: Graceful Shutdown Initiated - Flag 23: Smart Boost or Smart Trim Fault* - Flag 24: Bad Output Voltage* - - Flag 25: Battery Charger Failure* - Flag 26: High Battery Temperature - Flag 27: Self Test In Progress - Flag 28: Low Battery / On Battery - - Flag 29: Graceful Shutdown Issued by Upstream Device - Flag 30: Graceful Shutdown Issued by Downstream Device - Flag 31: No Batteries Attached* - Flag 32: Synchronized command is in progress - - Flag 33: <Not Used> - Flag 34: <Not Used> - Flag 35: <Not Used> - Flag 36: <Not Used> - - Flag 37: <Not Used> - Flag 38: <Not Used> - Flag 39: <Not Used> - Flag 40: <Not Used> - - Flag 41: <Not Used> - Flag 42: <Not Used> - Flag 43: <Not Used> - Flag 44: <Not Used> - - Flag 45: <Not Used> - Flag 46: <Not Used> - Flag 47: <Not Used> - Flag 48: <Not Used> - - Flag 49: <Not Used> - Flag 50: <Not Used> - Flag 51: <Not Used> - Flag 52: <Not Used> - - Flag 53: <Not Used> - Flag 54: <Not Used> - Flag 55: <Not Used> - Flag 56: <Not Used> - - Flag 57: <Not Used> - Flag 58: <Not Used> - Flag 59: <Not Used> - Flag 60: <Not Used> - - Flag 61: <Not Used> - Flag 62: <Not Used> - Flag 63: <Not Used> - Flag 64: <Not Used>" - - ::= { upsBasicState 1 } - --- the upsAdvState group - -upsAdvStateAbnormalConditions OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 32 flags representing - the current active UPS faults. If the Network Card - is unable to determine the values of the flags, this - variable is set to �UNKNOWN�. If this variable is not - supported by the connected UPS, this variable is set to - �NOT SUPPORTED�. - - The flags are numbered from 1 to 32, and read from left to - right. The flags are defined as follows: - - Flag 1: Power Module Failure - Flag 2: Main Intelligence Module Failure - Flag 3: Redundant Intelligence Module Failure - Flag 4: Battery Failure - - Flag 5: Load(kVA) Alarm Threshold Violation - Flag 6: Redundancy Lost - Flag 7: Redundancy Below Alarm Threshold - Flag 8: Bypass notin Range; Either Frequency or Voltage - - Flag 9: Bypass Contactor Stuck in Bypass Condition - Flag 10: Bypass Contactor Stuck in On-Line Condition - Flag 11: In Bypass due to an Internal Fault - Flag 12: In Bypass due to an Overload - - Flag 13: In Maintanence Bypass - Flag 14: Input Circuit Braker Tripped Open - Flag 15: System Level Fan Failure - Flag 16: Redundant Intelligent Module in Control - - Flag 17: IIC Inter-Module Communication Failure - Flag 18: No Working Power Modules - Flag 19: Load Shutdown From Bypass; Input Frequency - Flag 20: Runtime Below Alarm Threshold - - Flag 21: Extended Run Frame Fault - Flag 22: Output Voltage out of Range - Flag 23: UPS Not Synchronized - Flag 24: No Batteries Installed - - Flag 25: Battery Voltage High - Flag 26: UPS Specific Fault Detected - Flag 27: Site Wiring Fault - Flag 28: Backfeed Protection Relay Opened - - Flag 29: <Not Used> - Flag 30: <Not Used> - Flag 31: <Not Used> - Flag 32: <Not Used>" - ::= { upsAdvState 1 } - -upsAdvStateSymmetra3PhaseSpecificFaults OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 64 flags representing - the current active UPS specific faults for the Symmetra - 3-Phase UPS models. If the Network Card is unable to - determine the values of the flags, this variable is set - to �UNKNOWN�. If the connected UPS does not use this - variable, it is set to �NOT SUPPORTED�. - - The flags are numbered from 1 to 64, and read from left - to right. The bits are defined as follows: - - Flag 1: External Switch Gear Failure - Flag 2: External Transformer Over Temperature - Flag 3: External DC Circuit Breaker Tripped - Flag 4: System Power Supply Failure - - Flag 5: Battery Monitor Card Failure - Flag 6: Battery Monitor Card Removed - Flag 7: XR Communication Card Failure - Flag 8: XR Communication Card Removed - - Flag 9: External Switch Gear Monitoring Card Failure - Flag 10: External Switch Gear Monitoring Card Removed - Flag 11: Internal DC Circiut Breaker Tripped - Flag 12: Static Bypass Switch Failure - - Flag 13: System EEPROM Removed - Flag 14: System EEPROM Failure - Flag 15: UPS in Forced Bypass - Flag 16: <Not Used> - - Flag 17: <Not Used> - Flag 18: <Not Used> - Flag 19: <Not Used> - Flag 20: <Not Used> - - Flag 21: <Not Used> - Flag 22: <Not Used> - Flag 23: <Not Used> - Flag 24: <Not Used> - - Flag 25: <Not Used> - Flag 26: <Not Used> - Flag 27: <Not Used> - Flag 28: <Not Used> - - Flag 29: <Not Used> - Flag 30: <Not Used> - Flag 31: <Not Used> - Flag 32: <Not Used> - - Flag 33: <Not Used> - Flag 34: <Not Used> - Flag 35: <Not Used> - Flag 36: <Not Used> - - Flag 37: <Not Used> - Flag 38: <Not Used> - Flag 39: <Not Used> - Flag 40: <Not Used> - - Flag 41: <Not Used> - Flag 42: <Not Used> - Flag 43: <Not Used> - Flag 44: <Not Used> - - Flag 45: <Not Used> - Flag 46: <Not Used> - Flag 47: <Not Used> - Flag 48: <Not Used> - - Flag 49: <Not Used> - Flag 50: <Not Used> - Flag 51: <Not Used> - Flag 52: <Not Used> - - Flag 53: <Not Used> - Flag 54: <Not Used> - Flag 55: <Not Used> - Flag 56: <Not Used> - - Flag 57: <Not Used> - Flag 58: <Not Used> - Flag 59: <Not Used> - Flag 60: <Not Used> - - Flag 61: <Not Used> - Flag 62: <Not Used> - Flag 63: <Not Used> - Flag 64: <Not Used>" - ::= { upsAdvState 2 } - -upsAdvStateDP300ESpecificFaults OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 64 flags representing - the current active UPS specific faults for the Silcon - DP300E UPS models. If the Network Card is unable to - determine the values of the flags, this variable is set - to �UNKNOWN�. If the connected UPS does not use this - variable, it is set to �NOT SUPPORTED�. - - The flags are numbered from 1 to 64, and read from left - to right. The bits are defined as follows: - - Flag 1: Peak Current Limiter Avtive - Flag 2: Bypass Power Supply Fault - Flag 3: Delta Current LImiter Active - Flag 4: Fan Fault - - Flag 5: High DC warning - Flag 6: Inverter Voltage Error - Flag 7: Parallel Synchronization Error - Flag 8: Second Power Supply Fault - - Flag 9: Internal Power Supply Fault - Flag 10: <Not Used> - Flag 11: <Not Used> - Flag 12: <Not Used> - - Flag 13: <Not Used> - Flag 14: Bypass Static Switch High Temperature - Flag 15: High Battery Temperature - Flag 16: Battery Weak - - Flag 17: <Not Used> - Flag 18: System Locked in Operation Mode - Flag 19: RAM1 Memory Write Error - Flag 20: Memory Write Error - - Flag 21: Communication to VQ Bypass Lost - Flag 22: Communication to VQ Output Lost - Flag 23: Communication to DMU Lost - Flag 24: Communication to Controller Lost - - Flag 25: Communication to Parallel IF Lost - Flag 26: External Shutdown Accepted - Flag 27: DC Capacitor Charge Error - Flag 28: Communication to VQ Mains Lost - - Flag 29: Bypass Synchronization Error - Flag 30: Charge Error - Flag 31: <Not Used> - Flag 32: <Not Used> - - Flag 33: <Not Used> - Flag 34: <Not Used> - Flag 35: <Not Used> - Flag 36: <Not Used> - - Flag 37: <Not Used> - Flag 38: <Not Used> - Flag 39: <Not Used> - Flag 40: <Not Used> - - Flag 41: <Not Used> - Flag 42: <Not Used> - Flag 43: <Not Used> - Flag 44: <Not Used> - - Flag 45: <Not Used> - Flag 46: <Not Used> - Flag 47: <Not Used> - Flag 48: <Not Used> - - Flag 49: <Not Used> - Flag 50: <Not Used> - Flag 51: <Not Used> - Flag 52: <Not Used> - - Flag 53: <Not Used> - Flag 54: <Not Used> - Flag 55: <Not Used> - Flag 56: <Not Used> - - Flag 57: <Not Used> - Flag 58: <Not Used> - Flag 59: <Not Used> - Flag 60: <Not Used> - - Flag 61: <Not Used> - Flag 62: <Not Used> - Flag 63: <Not Used> - Flag 64: <Not Used>" - ::= { upsAdvState 3 } - - --- the upsBasicControl group - -upsBasicControlConserveBattery OBJECT-TYPE - SYNTAX INTEGER { - noTurnOffUps(1), - turnOffUpsToConserveBattery(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to turnUpsOffToConserveBattery(2) - causes a UPS on battery to be put into 'sleep' mode. The - UPS will turn back on when utility power is restored. - Attempting to turn off a UPS that is not on battery will - result in a badValue error. - - Setting this value to noTurnOffUps(1) has no - effect. - - The value noTurnOffUps(1) will always be returned - when the variable is read." -::= { upsBasicControl 1 } - - - --- the upsAdvControl group - -upsAdvControlUpsOff OBJECT-TYPE - SYNTAX INTEGER { - noTurnUpsOff(1), - turnUpsOff(2), - turnUpsOffGracefully(3), - turnUpsSyncGroupOff(4), - turnUpsSyncGroupOffAfterDelay(5), - turnUpsSyncGroupOffGracefully(6) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to turnUpsOff(2) causes - the UPS to shut off. When in this state, the UPS - will not provide output power regardless of the input - line state. - - Setting this variable to turnUpsOffGracefully(3) causes - the UPS to shut off after a delay period. This allows the - host to shut down in a graceful manner. When in this state, - the UPS will not provide output power regardless of the - input line state. - - If this UPS is an active member of a Synchronized - Control Group (SCG) the turnUpsSyncGroupOff(4) command - will perform a Synchronized Turn Off of all active Group - members regardless of their current AC output status. - - If this UPS is an active member of a Synchronized - Control Group (SCG) the turnUpsSyncGroupOffAfterDelay(5) - command will perform a Synchronized Turn Off After Delay - of all active Group members regardless of their current - AC output status. This unit's Shutdown Delay will be used - to execute the Turn Off After Delay command. - - If this UPS is an active member of an SCG, the - turnUpsSyncGroupOffGracefully(6) command will perform a - Synchronized Turn Off Gracefully of all active Group - members regardless of their current AC output status. - This unit's Maximum Shutdown Time and Shutdown Delay will - be used to execute the Turn Off Gracefully command. - - Setting this value to noTurnUpsOff(1) has no - effect. - - The value noTurnUpsOff(1) will always be returned - when the variable is read." - ::= { upsAdvControl 1 } - -upsAdvControlRebootUps OBJECT-TYPE - SYNTAX INTEGER { - noRebootUps(1), - rebootUps(2), - rebootUpsGracefully(3), - rebootSyncGroupUps(4), - rebootSyncGroupUpsGracefully(5) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to rebootUps(2) causes the - UPS to shut off and turn back on. - - Setting this variable to rebootUpsGracefully(3) causes the - UPS to shut off and turn back on after a delay period. - This allows the host to shut down in a graceful manner. - - If this UPS is an active member of a Synchronized Control - Group (SCG) the rebootSyncGroupUps(4) command will perform - a Synchronized Reboot of all active Group members regardless - of their current AC output status. This unit's Power - Synchronization Delay, Shutdown Delay, Return Delay, - Return Battery Capacity, and Return Battery Capacity Offset - will be used to execute the Reboot command. - - If this UPS is an active member of a SCG the - rebootSyncGroupUpsGracefully(5) command will perform a - Synchronized Reboot of all active Group members regardless - of their current AC output status. This unit's Power - Synchronization Delay, Maximum Shutdown Time, - Shutdown Delay, Return Delay, Return Battery Capacity, and - Return Battery Capacity Offset will be used - to execute the Reboot command. - - Setting this value to noRebootUps(1) has no effect. - - The value noRebootUps(1) will always be returned - when the variable is read." - ::= { upsAdvControl 2 } - -upsAdvControlUpsSleep OBJECT-TYPE - SYNTAX INTEGER { - noPutUpsToSleep(1), - putUpsToSleep(2), - putUpsToSleepGracefully(3), - putUpsSyncGroupToSleep(4), - putUpsSyncGroupToSleepGracefully(5) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to putUpsToSleep(2) causes - the UPS to go to sleep for the time specified by - upsAdvConfigUpsSleepTime. - - Setting this variable to putUpsToSleepGracefully(3) - causes the UPS to go to sleep for the time specified - by upsAdvConfigUpsSleepTime after a delay period. - This allows the host to shut down in a graceful manner. - - If this UPS is an active member of a Synchronized Control - Group (SCG), the putUpsSyncGroupToSleep(4) command will perform - a Synchronized Sleep of all active Group members regardless - of their current AC output status. This unit's Power - Synchronization Delay, Shutdown Delay, Sleep Time, - and Return Delay will be used to execute the sleep command. - - If this UPS is an active member of a SCG the - putUpsSyncGroupToSleepGracefully(5) command will perform a - Synchronized Sleep Gracefully of all active Group members - regardless of their current AC output status. This unit's - Power Synchronization Delay, Maximum Shutdown Time, Shutdown - Delay, Sleep Time, and Return Delay to execute the sleep - command. - - When in sleep mode, the UPS will not provide output - power regardless of the input line state. Once the - specified time has elapsed, output power will be - restored. - - Setting this value to noPutUpsToSleep(1) has no - effect. - - The value noPutUpsToSleep(1) will always be returned - when the variable is read." - ::= { upsAdvControl 3 } - - -upsAdvControlSimulatePowerFail OBJECT-TYPE - SYNTAX INTEGER { - noSimulatePowerFailure(1), - simulatePowerFailure(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to simulatePowerFailure(2) causes - the UPS switch to battery power. - - Setting this value to noSimulatePowerFailure(1) has no - effect. - - The value noSimulatePowerFailure(1) will always be returned - when the variable is read." - ::= { upsAdvControl 4 } - - -upsAdvControlFlashAndBeep OBJECT-TYPE - SYNTAX INTEGER { - noFlashAndBeep(1), - flashAndBeep(2), - flashAndBeepSyncGroup(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to flashAndBeep(2) causes the - UPS to beep and simultaneously turn on the UPS front - panel lights (Smart-UPS only). - - If this UPS is an active member of a Synchronized Control - Group (SCG), the flashAndBeepSyncGroup(3) command will - Flash and Beep all active Group members regardless of - current AC output status. - - Setting this value to noFlashAndBeep(1) has no - effect. - - The value noFlashAndBeep(1) will always be returned - when the variable is read." - ::= { upsAdvControl 5 } - - -upsAdvControlTurnOnUPS OBJECT-TYPE - SYNTAX INTEGER { - noTurnOnUPS(1), - turnOnUPS(2), - turnOnUPSSyncGroup(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to turnOnUPS(2) causes the - UPS to be turned on immediately. - - If this UPS is an active member of a Synchronized Control - Group (SCG), the turnOnUPSSyncGroup(3) command will perform - a Synchronized Turn On of all active Group members - regardless of their current AC output status. - - Setting this value to noTurnOnUPS(1) has no - effect. - - The value noTurnOnUPS(1) will always be returned - when the variable is read." - ::= { upsAdvControl 6 } - -upsAdvControlBypassSwitch OBJECT-TYPE - SYNTAX INTEGER { - noBypassSwitch (1), - switchToBypass (2), - switchOutOfBypass(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This switch puts the UPS in or out of bypass mode." - ::= { upsAdvControl 7 } - - --- the upsTest group - --- the upsBasicTest group - --- the upsAdvTest group - -upsAdvTestDiagnosticSchedule OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - biweekly(2), - weekly(3), - atTurnOn(4), - never(5) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The UPS system's automatic battery test schedule." - ::= { upsAdvTest 1 } - - -upsAdvTestDiagnostics OBJECT-TYPE - SYNTAX INTEGER { - noTestDiagnostics(1), - testDiagnostics(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to testDiagnostics(2) causes - the UPS to perform a diagnostic self test. - - Setting this value to noTestDiagnostics(1) has no - effect. - - The value noTestDiagnostics(1) will always be returned - when the variable is read." - ::= { upsAdvTest 2 } - -upsAdvTestDiagnosticsResults OBJECT-TYPE - SYNTAX INTEGER { - ok(1), - failed(2), - invalidTest(3), - testInProgress(4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The results of the last UPS diagnostics test performed." - ::= { upsAdvTest 3 } - -upsAdvTestLastDiagnosticsDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date the last UPS diagnostics test was performed in - mm/dd/yy format." - ::= { upsAdvTest 4 } - -upsAdvTestRuntimeCalibration OBJECT-TYPE - SYNTAX INTEGER { - noPerformCalibration(1), - performCalibration(2), - cancelCurrentCalibration(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to performCalibration(2) causes - the UPS to discharge to calibrate the UPS. - The test will only start if the battery capacity is 100%. - The test runs until capacity is less than 25%. - - Setting this variable to cancelCurrentCalibration(3) - after setting performCalibration(2) will cancel the - current discharge. - - Setting this variable to noPerformCalibration(1) - will have no effect. - - The value noPerformCalibration(1) will always be returned - when the variable is read. - - The result of the calibration will be saved in - upsAdvTestCalibrationResult." - ::= { upsAdvTest 5 } - -upsAdvTestCalibrationResults OBJECT-TYPE - SYNTAX INTEGER { - ok(1), - invalidCalibration(2), - calibrationInProgress(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The results of the last runtime calibration. - - Value ok(1) means a successful runtime calibration. - - Value invalidCalibration(2) indicates last calibration did - not take place since the battery capacity was below - 100%. - - Value calibrationInProgress(3) means a calibration - is occurring now. " - ::= { upsAdvTest 6 } - -upsAdvTestCalibrationDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date the last UPS runtime calibration was - performed in mm/dd/yy format." - ::= { upsAdvTest 7 } - --- the upsComm group - -upsCommStatus OBJECT-TYPE - SYNTAX INTEGER { - ok(1), - noComm(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of agent's communication with UPS. " - ::= { upsComm 1 } - - --- the measureUps group --- the Environ group - -mUpsEnvironAmbientTemperature OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The ambient temperature in Celsius for Probe 1." - ::= { mUpsEnviron 1 } - -mUpsEnvironRelativeHumidity OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The relative humidity as a percentage for Probe 1." - ::= { mUpsEnviron 2 } - - -mUpsEnvironAmbientTemperature2 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The ambient temperature in Celsius for Probe 2." - ::= { mUpsEnviron 3 } - -mUpsEnvironRelativeHumidity2 OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The relative humidity as a percentage for Probe 2." - ::= { mUpsEnviron 4 } - --- the mUpsContact group - -mUpsContactNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the Measure-UPS." - ::= { mUpsContact 1 } - -mUpsContactTable OBJECT-TYPE - SYNTAX SEQUENCE OF ContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Measure-UPS." - ::= { mUpsContact 2 } - -mUpsContactEntry OBJECT-TYPE - SYNTAX ContactEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A contact entry containing information for a given contact." - INDEX { contactNumber } - ::= { mUpsContactTable 1 } - -ContactEntry ::= - SEQUENCE { - contactNumber - INTEGER, - normalState - INTEGER, - description - DisplayString, - monitoringStatus - INTEGER, - currentStatus - INTEGER - } - -contactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An index identifying the contact on the Measure-UPS." - ::= { mUpsContactEntry 1 } - -normalState OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - open(2), - closed(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The normal operating position of the contact. If the normal - operating position cannot be set then it is controlled via the - dip switch on the Measure-UPS and is therefore read-only." - ::= { mUpsContactEntry 2 } - -description OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The description of the purpose/use of the contact." - ::= { mUpsContactEntry 3 } - -monitoringStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - enabled(2), - disabled(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A flag indicating whether this contact is - monitored, or not." - ::= { mUpsContactEntry 4 } - -currentStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - noFault(2), - fault(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value indicates the current state of the contact. - If the contact is not in its normal state. This value - is set to fault(2)." - ::= { mUpsContactEntry 5 } - --- Three Phase Group - --- --- Reset Max/Min Values Group --- - - upsPhaseResetMaxMinValues OBJECT-TYPE - SYNTAX INTEGER { - none (1), - reset (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Reset the maximum and minimum UPS values: - upsPhaseInputMaxVoltage, upsPhaseInputMinVoltage, - upsPhaseInputMaxCurrent, upsPhaseInputMinCurrent, - upsPhaseInputMaxPower, upsPhaseInputMinPower, - upsPhaseOutputMaxCurrent, upsPhaseOutputMinCurrent, - upsPhaseOutputMaxLoad, upsPhaseOutputMinLoad, - upsPhaseOutputMaxPercentLoad, upsPhaseOutputMinPercentLoad, - upsPhaseOutputMaxPower, upsPhaseOutputMinPower, - upsPhaseOutputMaxPercentPower, upsPhaseOutputMinPercentPower." - ::= { upsPhaseResetValues 1 } - --- --- Input Group --- - --- Number of Inputs - - upsPhaseNumInputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input feeds to this device. - This variable indicates the number of rows in the - input table." - ::= { upsPhaseInput 1 } - --- Input Table - - upsPhaseInputTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the value of upsPhaseNumInputs." - ::= { upsPhaseInput 2 } - - upsPhaseInputEntry OBJECT-TYPE - SYNTAX UpsPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input." - INDEX { upsPhaseInputTableIndex } - ::= { upsPhaseInputTable 1 } - - UpsPhaseInputEntry ::= SEQUENCE { - upsPhaseInputTableIndex INTEGER, - upsPhaseNumInputPhases INTEGER, - upsPhaseInputVoltageOrientation INTEGER, - upsPhaseInputFrequency INTEGER, - upsPhaseInputType INTEGER, - upsPhaseInputName DisplayString - } - - upsPhaseInputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { upsPhaseInputEntry 1 } - - upsPhaseNumInputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input phases utilized in this - device. The sum of all the upsPhaseNumInputPhases - variable indicates the number of rows in the - input phase table." - ::= { upsPhaseInputEntry 2 } - - upsPhaseInputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage orientation: - 1: unknown for this UPS - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { upsPhaseInputEntry 3 } - - upsPhaseInputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input frequency in 0.1 Hertz, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseInputEntry 4 } - - upsPhaseInputType OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - main(2), - bypass(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input type." - ::= { upsPhaseInputEntry 5 } - - upsPhaseInputName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A name given to a particular input." - ::= { upsPhaseInputEntry 6 } - --- Input Phase Table - - upsPhaseInputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the sum of the upsPhaseNumInputPhases." - ::= { upsPhaseInput 3 } - - upsPhaseInputPhaseEntry OBJECT-TYPE - SYNTAX UpsPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input phase." - INDEX { upsPhaseInputPhaseTableIndex, upsPhaseInputPhaseIndex } - ::= { upsPhaseInputPhaseTable 1 } - - UpsPhaseInputPhaseEntry ::= SEQUENCE { - upsPhaseInputPhaseTableIndex INTEGER, - upsPhaseInputPhaseIndex INTEGER, - upsPhaseInputVoltage INTEGER, - upsPhaseInputMaxVoltage INTEGER, - upsPhaseInputMinVoltage INTEGER, - upsPhaseInputCurrent INTEGER, - upsPhaseInputMaxCurrent INTEGER, - upsPhaseInputMinCurrent INTEGER, - upsPhaseInputPower INTEGER, - upsPhaseInputMaxPower INTEGER, - upsPhaseInputMinPower INTEGER - } - - upsPhaseInputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { upsPhaseInputPhaseEntry 1 } - - upsPhaseInputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input phase identifier." - ::= { upsPhaseInputPhaseEntry 2 } - - upsPhaseInputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage in VAC, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseInputPhaseEntry 3 } - - upsPhaseInputMaxVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input voltage in VAC measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 4 } - - upsPhaseInputMinVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input voltage in VAC measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 5 } - - upsPhaseInputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input current in 0.1 amperes, or -1 if it's - unsupported by this UPS." - ::= { upsPhaseInputPhaseEntry 6 } - - upsPhaseInputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 7 } - - upsPhaseInputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 8 } - - upsPhaseInputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input power in Watts, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseInputPhaseEntry 9 } - - upsPhaseInputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 10 } - - upsPhaseInputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseInputPhaseEntry 11 } - - -- - -- The Output group. - -- - - -- Number of Outputs - - upsPhaseNumOutputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output feeds to this device. - This variable indicates the number of rows in the - output table." - ::= { upsPhaseOutput 1 } - - -- Output Table - - upsPhaseOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of entries - is given by the value of upsOutputNumPhases." - ::= { upsPhaseOutput 2 } - - upsPhaseOutputEntry OBJECT-TYPE - SYNTAX UpsPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output." - INDEX { upsPhaseOutputTableIndex } - ::= { upsPhaseOutputTable 1 } - - UpsPhaseOutputEntry ::= SEQUENCE { - upsPhaseOutputTableIndex INTEGER, - upsPhaseNumOutputPhases INTEGER, - upsPhaseOutputVoltageOrientation INTEGER, - upsPhaseOutputFrequency INTEGER - } - - upsPhaseOutputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { upsPhaseOutputEntry 1 } - - upsPhaseNumOutputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output phases utilized in this - device. The sum of all the upsPhaseNumOutputPhases - variable indicates the number of rows in the - output phase table." - ::= { upsPhaseOutputEntry 2 } - - upsPhaseOutputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage orientation: - 1: unknown for this UPS - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { upsPhaseOutputEntry 3 } - - upsPhaseOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output frequency in 0.1 Hertz, or -1 if it's - unsupported by this UPS." - ::= { upsPhaseOutputEntry 4 } - - -- Output Phase Table - - upsPhaseOutputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of - entries is given by the sum of the upsPhaseNumOutputPhases." - ::= { upsPhaseOutput 3 } - - upsPhaseOutputPhaseEntry OBJECT-TYPE - SYNTAX UpsPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output phase." - INDEX { upsPhaseOutputPhaseTableIndex, upsPhaseOutputPhaseIndex } - ::= { upsPhaseOutputPhaseTable 1 } - - UpsPhaseOutputPhaseEntry ::= SEQUENCE { - upsPhaseOutputPhaseTableIndex INTEGER, - upsPhaseOutputPhaseIndex INTEGER, - upsPhaseOutputVoltage INTEGER, - upsPhaseOutputCurrent INTEGER, - upsPhaseOutputMaxCurrent INTEGER, - upsPhaseOutputMinCurrent INTEGER, - upsPhaseOutputLoad INTEGER, - upsPhaseOutputMaxLoad INTEGER, - upsPhaseOutputMinLoad INTEGER, - upsPhaseOutputPercentLoad INTEGER, - upsPhaseOutputMaxPercentLoad INTEGER, - upsPhaseOutputMinPercentLoad INTEGER, - upsPhaseOutputPower INTEGER, - upsPhaseOutputMaxPower INTEGER, - upsPhaseOutputMinPower INTEGER, - upsPhaseOutputPercentPower INTEGER, - upsPhaseOutputMaxPercentPower INTEGER, - upsPhaseOutputMinPercentPower INTEGER - } - - upsPhaseOutputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { upsPhaseOutputPhaseEntry 1 } - - upsPhaseOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output phase identifier." - ::= { upsPhaseOutputPhaseEntry 2 } - - upsPhaseOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage in VAC, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseOutputPhaseEntry 3 } - - upsPhaseOutputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output current in 0.1 amperes drawn - by the load on the UPS, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseOutputPhaseEntry 4 } - - upsPhaseOutputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 5 } - - upsPhaseOutputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output current in 0.1 amperes measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 6 } - - upsPhaseOutputLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output load in VA, or -1 if it's unsupported - by this UPS." - ::= { upsPhaseOutputPhaseEntry 7 } - - upsPhaseOutputMaxLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output load in VA measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 8 } - - upsPhaseOutputMinLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output load in VA measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 9 } - - upsPhaseOutputPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the UPS load capacity in VA at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this UPS." - ::= { upsPhaseOutputPhaseEntry 10 } - - upsPhaseOutputMaxPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the UPS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last reset - (upsPhaseResetMaxMinValues), or -1 if it's unsupported - by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 11 } - - upsPhaseOutputMinPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum percentage of the UPS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last reset - (upsPhaseResetMaxMinValues), or -1 if it's unsupported - by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 12 } - - upsPhaseOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output power in Watts, or -1 if it's - unsupported by this UPS." - ::= { upsPhaseOutputPhaseEntry 13 } - - upsPhaseOutputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 14 } - - upsPhaseOutputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output power in Watts measured - since the last reset (upsPhaseResetMaxMinValues), or - -1 if it's unsupported by this UPS. - Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 15 } - - upsPhaseOutputPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the UPS power capacity in Watts at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this UPS." - ::= { upsPhaseOutputPhaseEntry 16 } - - upsPhaseOutputMaxPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the UPS power capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last - reset (upsPhaseResetMaxMinValues), or -1 if it's - unsupported by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 17 } - - upsPhaseOutputMinPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the UPS power capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last - reset (upsPhaseResetMaxMinValues), or -1 if it's - unsupported by this UPS. Sampled every 30 seconds." - ::= { upsPhaseOutputPhaseEntry 18 } - --- the upsOutletGroupStatus group - -upsOutletGroupStatusTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlet groups for the UPS." - ::= { upsOutletGroupStatus 1 } - -upsOutletGroupStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsOutletGroupStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting status of the outlet groups. The number of - entries is contained in the upsOutletGroupStatusTableSize OID." - ::= { upsOutletGroupStatus 2 } - -upsOutletGroupStatusEntry OBJECT-TYPE - SYNTAX UpsOutletGroupStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet group status to get." - INDEX { upsOutletGroupStatusIndex} - ::= { upsOutletGroupStatusTable 1 } - -UpsOutletGroupStatusEntry ::= - SEQUENCE { - upsOutletGroupStatusIndex INTEGER, - upsOutletGroupStatusName DisplayString, - upsOutletGroupStatusGroupState INTEGER, - upsOutletGroupStatusCommandPending INTEGER - } - -upsOutletGroupStatusIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet group entry." - ::= { upsOutletGroupStatusEntry 1 } - -upsOutletGroupStatusName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet group. This OID is provided - for informational purposes only. This value is set - by the upsOutletGroupConfigName OID." - ::= { upsOutletGroupStatusEntry 2 } - -upsOutletGroupStatusGroupState OBJECT-TYPE - SYNTAX INTEGER { - upsOutletGroupStatusOn (1), - upsOutletGroupStatusOff (2), - upsOutletGroupStatusUnknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet group state. If the outlet - group is on, the upsOutletGroupStatusOn (1) value will be returned. If - the outlet group is off, the upsOutletGroupStatusOff (2) value will be - returned. If the state of the outlet group cannot be determined, the - upsOutletGroupStatusUnknown (3) value will be returned." - - ::= { upsOutletGroupStatusEntry 3 } - -upsOutletGroupStatusCommandPending OBJECT-TYPE - SYNTAX INTEGER { - upsOutletGroupCommandPending (1), - upsOutletGroupNoCommandPending (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet group. If a command is pending on the - outlet group, the upsOutletGroupCommandPending (1) value - will be returned. If there is not a command pending - on the outlet group, the upsOutletGroupNoCommandPending (2) - will be returned." - ::= { upsOutletGroupStatusEntry 4 } - --- the upsOutletGroupConfig group - -upsOutletGroupConfigTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlet groups for the UPS." - ::= { upsOutletGroupConfig 1 } - -upsOutletGroupConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsOutletGroupConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The list of outlet groups to configure. The number of entries - is defined by the upsOutletGroupConfigTableSize OID." - ::= { upsOutletGroupConfig 2 } - -upsOutletGroupConfigEntry OBJECT-TYPE - SYNTAX UpsOutletGroupConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet groups to configure." - INDEX { upsOutletGroupConfigIndex} - ::= { upsOutletGroupConfigTable 1 } - -UpsOutletGroupConfigEntry ::= - SEQUENCE { - upsOutletGroupConfigIndex INTEGER, - upsOutletGroupConfigName DisplayString, - upsOutletGroupConfigPowerOnDelay INTEGER, - upsOutletGroupConfigPowerOffDelay INTEGER, - upsOutletGroupConfigRebootDuration INTEGER - } - -upsOutletGroupConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet group entry." - ::= { upsOutletGroupConfigEntry 1 } - -upsOutletGroupConfigName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet group." - ::= { upsOutletGroupConfigEntry 2 } - -upsOutletGroupConfigPowerOnDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet group will delay - powering on when the delayed on or reboot command is applied. - Allowed values are -1 (for Never) or 0 to 600 seconds." - ::= { upsOutletGroupConfigEntry 3 } - -upsOutletGroupConfigPowerOffDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet group will delay - powering off when the delayed off command is applied. - Allowed values are 0 to 600 seconds." - ::= { upsOutletGroupConfigEntry 4 } - -upsOutletGroupConfigRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before initiating the power on sequence. - Allowed values are 0 to 600 seconds." - ::= { upsOutletGroupConfigEntry 5 } - --- the upsOutletGroupControl group - -upsOutletGroupControlTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlet groups for the UPS." - ::= { upsOutletGroupControl 1 } - -upsOutletGroupControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsOutletGroupControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet groups. The number of - entries is contained in the upsOutletGroupControlTableSize OID." - ::= { upsOutletGroupControl 2 } - -upsOutletGroupControlEntry OBJECT-TYPE - SYNTAX UpsOutletGroupControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet group to control." - INDEX { upsOutletGroupControlIndex} - ::= { upsOutletGroupControlTable 1 } - -UpsOutletGroupControlEntry ::= - SEQUENCE { - upsOutletGroupControlIndex INTEGER, - upsOutletGroupControlName DisplayString, - upsOutletGroupControlCommand INTEGER - } - -upsOutletGroupControlIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet group entry." - ::= { upsOutletGroupControlEntry 1 } - -upsOutletGroupControlName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet group. This OID is provided - for informational purposes only. This value is set - by the upsOutletGroupConfigName OID." - ::= { upsOutletGroupControlEntry 2 } - -upsOutletGroupControlCommand OBJECT-TYPE - SYNTAX INTEGER { - upsOutletGroupImmediateOn (1), - upsOutletGroupImmediateOff (2), - upsOutletGroupImmediateReboot (3), - upsOutletGroupDelayedOn (4), - upsOutletGroupDelayedOff (5), - upsOutletGroupDelayedReboot (6), - upsOutletGroupCancelPendingCommand (7), - upsOutletGroupControlUnknown (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet group state. If the outlet - group is on, the upsOutletGroupImmediateOn (1) value will be returned. If - the outlet group is off, the upsOutletGroupImmediateOff (2) value will be - returned. - - If the state of the outlet group cannot be determined, the - upsOutletGroupControlUnknown (8) value will be returned. - - Setting this variable to upsOutletGroupImmediateOn (1) will turn the - outlet group on. - - Setting this variable to upsOutletGroupImmediateOff (2) will turn the - outlet group off. - - Setting this variable to upsOutletGroupImmediateReboot (3) will turn the outlet - group off, wait the upsOutletGroupConfigRebootDuration OID time, wait the - upsOutletGroupConfigPowerOnDelay OID, and then turn the outlet group on. - - Setting this variable to upsOutletGroupDelayedOn (4) will turn the outlet - group on after the upsOutletGroupConfigPowerOnDelay OID has elapsed. - - Setting this variable to upsOutletGroupDelayedOff (5) will turn the outlet - group off after the upsOutletGroupConfigPowerOffDelay OID has elapsed. - - Setting this variable to upsOutletGroupDelayedReboot (6) will turn the outlet - group off after the upsOutletGroupConfigPowerOffDelay OID has elapsed, wait the - upsOutletGroupConfigRebootDuration OID time, wait the - upsOutletGroupConfigPowerOnDelay OID, and then turn the outlet group on. - - Setting this variable to upsOutletGroupCancelPendingCommand (7) will - cause any pending command to this outlet group to be canceled." - ::= { upsOutletGroupControlEntry 3 } - --- the upsDiagnosticIM group - -upsDiagIMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Intelligence Modules in or attached to the UPS." - ::= { upsDiagnosticIM 1 } - -upsDiagIMTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagIMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual Intelligence Modules. The number of - entries is contained in the upsDiagIMTableSize OID." - ::= { upsDiagnosticIM 2 } - -upsDiagIMEntry OBJECT-TYPE - SYNTAX UpsDiagIMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics and information of an Intelligence Module." - INDEX { upsDiagIMIndex} - ::= { upsDiagIMTable 1 } - -UpsDiagIMEntry ::= - SEQUENCE { - upsDiagIMIndex INTEGER, - upsDiagIMType INTEGER, - upsDiagIMStatus INTEGER, - upsDiagIMFirmwareRev DisplayString, - upsDiagIMSlaveFirmwareRev DisplayString, - upsDiagIMHardwareRev DisplayString, - upsDiagIMSerialNum DisplayString, - upsDiagIMManufactureDate DisplayString - } - -upsDiagIMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Intelligence Module entry." - ::= { upsDiagIMEntry 1 } - -upsDiagIMType OBJECT-TYPE - SYNTAX INTEGER { - imUnknown (1), - imMIM (2), - imRIM (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of the Intelligence Module. - imUnknown(1) indicates the IM type is unknown. - imMIM(2) indicates the IM type is a Main Intelligence Module. - imRIM(3) indicates the IM type is Redundant Intelligence Module." - ::= { upsDiagIMEntry 2 } - -upsDiagIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Intelligence Module. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagIMEntry 3 } - -upsDiagIMFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Intelligence Module." - ::= { upsDiagIMEntry 4 } - -upsDiagIMSlaveFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The slave firmware revision of the Intelligence Module." - ::= { upsDiagIMEntry 5 } - -upsDiagIMHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Intelligence Module." - ::= { upsDiagIMEntry 6 } - -upsDiagIMSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Intelligence Module." - ::= { upsDiagIMEntry 7 } - -upsDiagIMManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the Intelligence Module." - ::= { upsDiagIMEntry 8 } - --- the upsDiagnosticPowerModules group - -upsDiagPMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Power Modules in or attached to the UPS." - ::= { upsDiagnosticPowerModules 1 } - -upsDiagPMTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagPMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of Individual Power modules. The number of - entries is contained in the upsDiagPMTableSize OID." - ::= { upsDiagnosticPowerModules 2 } - -upsDiagPMEntry OBJECT-TYPE - SYNTAX UpsDiagPMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an Power Module." - INDEX { upsDiagPMIndex} - ::= { upsDiagPMTable 1 } - -UpsDiagPMEntry ::= - SEQUENCE { - upsDiagPMIndex INTEGER, - upsDiagPMStatus INTEGER, - upsDiagPMFirmwareRev DisplayString, - upsDiagPMHardwareRev DisplayString, - upsDiagPMSerialNum DisplayString, - upsDiagPMManufactureDate DisplayString - } - -upsDiagPMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Power Module entry." - ::= { upsDiagPMEntry 1 } - -upsDiagPMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Power Module. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagPMEntry 2 } - -upsDiagPMFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Power Module." - ::= { upsDiagPMEntry 3 } - -upsDiagPMHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Power Module." - ::= { upsDiagPMEntry 4 } - -upsDiagPMSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Power Module." - ::= { upsDiagPMEntry 5 } - -upsDiagPMManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the Power Module." - ::= { upsDiagPMEntry 6 } - --- the upsDiagnosticBatteries group - -upsDiagBatteryTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of batteries in or attached to the UPS." - ::= { upsDiagnosticBatteries 1 } - -upsDiagBatteryTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagBatteryEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual batteries. The number of - entries is contained in the upsDiagBattTableSize OID." - ::= { upsDiagnosticBatteries 2 } - -upsDiagBatteryEntry OBJECT-TYPE - SYNTAX UpsDiagBatteryEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a battery." - INDEX { upsDiagBatteryIndex} - ::= { upsDiagBatteryTable 1 } - -UpsDiagBatteryEntry ::= - SEQUENCE { - upsDiagBatteryFrameIndex INTEGER, - upsDiagBatteryIndex INTEGER, - upsDiagBatteryStatus INTEGER, - upsDiagBatterySerialNumber DisplayString, - upsDiagBatteryFirmwareRev DisplayString, - upsDiagBatteryManufactureDate DisplayString, - upsDiagBatteryType DisplayString - } - -upsDiagBatteryFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the battery frame entry. - Frame 0 indicates the Main frame. Extended Run (XR) frames - start from index 1." - ::= { upsDiagBatteryEntry 1 } - -upsDiagBatteryIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the battery entry." - ::= { upsDiagBatteryEntry 2 } - -upsDiagBatteryStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - failed (4), - highTemperature (5), - replaceImmediately (6), - lowCapacity (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the battery. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the battery status is OK. - failed(4) indicates the battery status is failed. - highTemperature(5) indicates the battery has a high temperature condition. - replaceImmediately(6) indicates the battery must be replaced immediately. - lowCapacity(7) indicates the battery has a low capacity." - ::= { upsDiagBatteryEntry 3 } - -upsDiagBatterySerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the battery." - ::= { upsDiagBatteryEntry 4 } - -upsDiagBatteryFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the battery." - ::= { upsDiagBatteryEntry 5 } - -upsDiagBatteryManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the battery." - ::= { upsDiagBatteryEntry 6 } - -upsDiagBatteryType OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The battery type or rating for the battery." - ::= { upsDiagBatteryEntry 7 } - --- the upsDiagnosticSubsystem group - -upsDiagSubSysFrameTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of frames attached to the UPS including the Main frame." - ::= { upsDiagnosticSubsystem 1 } - -upsDiagSubSysFrameTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysFrameEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual XR Frames." - ::= { upsDiagnosticSubsystem 2 } - -upsDiagSubSysFrameEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysFrameEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an XR Frame." - INDEX { upsDiagSubSysFrameIndex} - ::= { upsDiagSubSysFrameTable 1 } - -UpsDiagSubSysFrameEntry ::= - SEQUENCE { - upsDiagSubSysFrameIndex INTEGER, - upsDiagSubSysFrameType INTEGER, - upsDiagSubSysFrameFirmwareRev DisplayString, - upsDiagSubSysFrameHardwareRev DisplayString, - upsDiagSubSysFrameSerialNum DisplayString, - upsDiagSubSysFrameManufactureDate DisplayString - } - -upsDiagSubSysFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysFrameEntry 1 } - -upsDiagSubSysFrameType OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - frameTypeMain (3), - frameTypeXR (4), - frameTypeLXR (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The type of Frame. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - frameTypeMain(3) indicates the the frame type is the Main Frame. - frameTypeXR(4) indicates the frame type is an XR Frame. - frameTypeLXR(5) indicates the frame type is an LXR Frame." - ::= { upsDiagSubSysFrameEntry 2 } - -upsDiagSubSysFrameFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the frame." - ::= { upsDiagSubSysFrameEntry 3 } - -upsDiagSubSysFrameHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the frame." - ::= { upsDiagSubSysFrameEntry 4 } - -upsDiagSubSysFrameSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the frame." - ::= { upsDiagSubSysFrameEntry 5 } - -upsDiagSubSysFrameManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the frame." - ::= { upsDiagSubSysFrameEntry 6 } - -upsDiagSubSysIntBypSwitchTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Internal Bypass switches attached to the UPS." - ::= { upsDiagnosticSubsystem 3 } - -upsDiagSubSysIntBypSwitchTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysIntBypSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of the Internal Bypass Switch." - ::= { upsDiagnosticSubsystem 4 } - -upsDiagSubSysIntBypSwitchEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysIntBypSwitchEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of the Internal Bypass Switch." - INDEX { upsDiagSubSysIntBypSwitchIndex} - ::= { upsDiagSubSysIntBypSwitchTable 1 } - -UpsDiagSubSysIntBypSwitchEntry ::= - SEQUENCE { - upsDiagSubSysIntBypSwitchFrameIndex INTEGER, - upsDiagSubSysIntBypSwitchIndex INTEGER, - upsDiagSubSysIntBypSwitchStatus INTEGER, - upsDiagSubSysIntBypSwitchFirmwareRev DisplayString, - upsDiagSubSysIntBypSwitchHardwareRev DisplayString, - upsDiagSubSysIntBypSwitchSerialNum DisplayString, - upsDiagSubSysIntBypSwitchManufactureDate DisplayString - } - -upsDiagSubSysIntBypSwitchFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysIntBypSwitchEntry 1 } - -upsDiagSubSysIntBypSwitchIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Internal Bypass Switch index entry." - ::= { upsDiagSubSysIntBypSwitchEntry 2 } - -upsDiagSubSysIntBypSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Internal Bypass Switch status. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysIntBypSwitchEntry 3 } - -upsDiagSubSysIntBypSwitchFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 4 } - -upsDiagSubSysIntBypSwitchHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 5 } - -upsDiagSubSysIntBypSwitchSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 6 } - -upsDiagSubSysIntBypSwitchManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The manufacture date of the Internal Bypass Switch." - ::= { upsDiagSubSysIntBypSwitchEntry 7 } - -upsDiagSubSysBattMonitorTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Battery Monitor Boards attached to the UPS." - ::= { upsDiagnosticSubsystem 5 } - -upsDiagSubSysBattMonitorTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysBattMonitorEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of the Battery Monitor Board." - ::= { upsDiagnosticSubsystem 6 } - -upsDiagSubSysBattMonitorEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysBattMonitorEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of the Battery Monitor Board." - INDEX { upsDiagSubSysBattMonitorIndex} - ::= { upsDiagSubSysBattMonitorTable 1 } - -UpsDiagSubSysBattMonitorEntry ::= - SEQUENCE { - upsDiagSubSysBattMonitorFrameIndex INTEGER, - upsDiagSubSysBattMonitorIndex INTEGER, - upsDiagSubSysBattMonitorStatus INTEGER, - upsDiagSubSysBattMonitorFirmwareRev DisplayString, - upsDiagSubSysBattMonitorHardwareRev DisplayString, - upsDiagSubSysBattMonitorSerialNum DisplayString, - upsDiagSubSysBattMonitorManufactureDate DisplayString - } - -upsDiagSubSysBattMonitorFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysBattMonitorEntry 1 } - -upsDiagSubSysBattMonitorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 2 } - -upsDiagSubSysBattMonitorStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Battery Monitor Board. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysBattMonitorEntry 3 } - -upsDiagSubSysBattMonitorFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 4 } - -upsDiagSubSysBattMonitorHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 5 } - -upsDiagSubSysBattMonitorSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 6 } - -upsDiagSubSysBattMonitorManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the manufacture for the Battery Monitor Board." - ::= { upsDiagSubSysBattMonitorEntry 7 } - -upsDiagSubSysExternalSwitchGearTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of External Switch Gears attached to the UPS." - ::= { upsDiagnosticSubsystem 7 } - -upsDiagSubSysExternalSwitchGearTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysExternalSwitchGearEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of the individual External Switch Gear." - ::= { upsDiagnosticSubsystem 8 } - -upsDiagSubSysExternalSwitchGearEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysExternalSwitchGearEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an individual External Switch Gear." - INDEX { upsDiagSubSysExternalSwitchGearIndex} - ::= { upsDiagSubSysExternalSwitchGearTable 1 } - -UpsDiagSubSysExternalSwitchGearEntry ::= - SEQUENCE { - upsDiagSubSysExternalSwitchGearFrameIndex INTEGER, - upsDiagSubSysExternalSwitchGearIndex INTEGER, - upsDiagSubSysExternalSwitchGearStatus INTEGER, - upsDiagSubSysExternalSwitchGearFirmwareRev DisplayString, - upsDiagSubSysExternalSwitchGearHardwareRev DisplayString, - upsDiagSubSysExternalSwitchGearSerialNum DisplayString, - upsDiagSubSysExternalSwitchGearManufactureDate DisplayString - } - -upsDiagSubSysExternalSwitchGearFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysExternalSwitchGearEntry 1 } - -upsDiagSubSysExternalSwitchGearIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the External Switch Gear." - ::= { upsDiagSubSysExternalSwitchGearEntry 2 } - -upsDiagSubSysExternalSwitchGearStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the External Switch Gear. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysExternalSwitchGearEntry 3 } - -upsDiagSubSysExternalSwitchGearFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 4 } - -upsDiagSubSysExternalSwitchGearHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 5 } - -upsDiagSubSysExternalSwitchGearSerialNum OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The serial number of the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 6 } - -upsDiagSubSysExternalSwitchGearManufactureDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of the manufacture for the External Switch Gear monitor card." - ::= { upsDiagSubSysExternalSwitchGearEntry 7 } - -upsDiagSubSysDisplayInterfaceCardTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Display Interface Cards attached to the UPS." - ::= { upsDiagnosticSubsystem 9 } - -upsDiagSubSysDisplayInterfaceCardTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysDisplayInterfaceCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual Display Interface Cards." - ::= { upsDiagnosticSubsystem 10 } - -upsDiagSubSysDisplayInterfaceCardEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysDisplayInterfaceCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a Display Interface Card." - INDEX { upsDiagSubSysDisplayInterfaceCardIndex} - ::= { upsDiagSubSysDisplayInterfaceCardTable 1 } - -UpsDiagSubSysDisplayInterfaceCardEntry ::= - SEQUENCE { - upsDiagSubSysDisplayInterfaceCardFrameIndex INTEGER, - upsDiagSubSysDisplayInterfaceCardIndex INTEGER, - upsDiagSubSysDisplayInterfaceCardStatus INTEGER - } - -upsDiagSubSysDisplayInterfaceCardFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysDisplayInterfaceCardEntry 1 } - -upsDiagSubSysDisplayInterfaceCardIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Display Interface Card." - ::= { upsDiagSubSysDisplayInterfaceCardEntry 2 } - -upsDiagSubSysDisplayInterfaceCardStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Display Interface Card. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysDisplayInterfaceCardEntry 3 } - -upsDiagSubSysDCCircuitBreakerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC Circuit Breakers attached to the UPS." - ::= { upsDiagnosticSubsystem 11 } - -upsDiagSubSysDCCircuitBreakerTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysDCCircuitBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual DC Circuit Breakers." - ::= { upsDiagnosticSubsystem 12 } - -upsDiagSubSysDCCircuitBreakerEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysDCCircuitBreakerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a DC Circuit Breaker." - INDEX { upsDiagSubSysDCCircuitBreakerIndex} - ::= { upsDiagSubSysDCCircuitBreakerTable 1 } - -UpsDiagSubSysDCCircuitBreakerEntry ::= - SEQUENCE { - upsDiagSubSysDCCircuitBreakerFrameIndex INTEGER, - upsDiagSubSysDCCircuitBreakerIndex INTEGER, - upsDiagSubSysDCCircuitBreakerStatus INTEGER - } - -upsDiagSubSysDCCircuitBreakerFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysDCCircuitBreakerEntry 1 } - -upsDiagSubSysDCCircuitBreakerIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the DC Circuit Breaker." - ::= { upsDiagSubSysDCCircuitBreakerEntry 2 } - -upsDiagSubSysDCCircuitBreakerStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the DC Circuit Breaker. - unknown(1) indicates the circuit breaker status is unknown. - notInstalled(2) indicates the circuit breaker is not installed. - opened(3) indicates the circuit breaker is opened. - closed(4) indicates the circuit breaker is closed." - ::= { upsDiagSubSysDCCircuitBreakerEntry 3 } - -upsDiagSubSysSystemPowerSupplyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of System Power Supplies attached to the UPS." - ::= { upsDiagnosticSubsystem 13 } - -upsDiagSubSysSystemPowerSupplyTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysSystemPowerSupplyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual System Power Supplies." - ::= { upsDiagnosticSubsystem 14 } - -upsDiagSubSysSystemPowerSupplyEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysSystemPowerSupplyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a System Power Supply." - INDEX { upsDiagSubSysSystemPowerSupplyIndex} - ::= { upsDiagSubSysSystemPowerSupplyTable 1 } - -UpsDiagSubSysSystemPowerSupplyEntry ::= - SEQUENCE { - upsDiagSubSysSystemPowerSupplyFrameIndex INTEGER, - upsDiagSubSysSystemPowerSupplyIndex INTEGER, - upsDiagSubSysSystemPowerSupplyStatus INTEGER - } - -upsDiagSubSysSystemPowerSupplyFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysSystemPowerSupplyEntry 1 } - -upsDiagSubSysSystemPowerSupplyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a System Power Supply." - ::= { upsDiagSubSysSystemPowerSupplyEntry 2 } - -upsDiagSubSysSystemPowerSupplyStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the System Power Supply. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysSystemPowerSupplyEntry 3 } - -upsDiagSubSysXRCommunicationCardTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of XR Communication Cards attached to the UPS." - ::= { upsDiagnosticSubsystem 15 } - -upsDiagSubSysXRCommunicationCardTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysXRCommunicationCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual XR Communication Cards." - ::= { upsDiagnosticSubsystem 16 } - -upsDiagSubSysXRCommunicationCardEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysXRCommunicationCardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an XR Communication Card." - INDEX { upsDiagSubSysXRCommunicationCardIndex} - ::= { upsDiagSubSysXRCommunicationCardTable 1 } - -UpsDiagSubSysXRCommunicationCardEntry ::= - SEQUENCE { - upsDiagSubSysXRCommunicationCardFrameIndex INTEGER, - upsDiagSubSysXRCommunicationCardIndex INTEGER, - upsDiagSubSysXRCommunicationCardStatus INTEGER - } - -upsDiagSubSysXRCommunicationCardFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysXRCommunicationCardEntry 1 } - -upsDiagSubSysXRCommunicationCardIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an XR Communication Card." - ::= { upsDiagSubSysXRCommunicationCardEntry 2 } - -upsDiagSubSysXRCommunicationCardStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the XR Communication Card. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysXRCommunicationCardEntry 3 } - -upsDiagSubSysExternalPowerFrameBoardTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of External Power Frame Boards attached to the UPS." - ::= { upsDiagnosticSubsystem 17 } - -upsDiagSubSysExternalPowerFrameBoardTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysExternalPowerFrameBoardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual External Power Frame Boards." - ::= { upsDiagnosticSubsystem 18 } - -upsDiagSubSysExternalPowerFrameBoardEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysExternalPowerFrameBoardEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of an External Power Frame Board." - INDEX { upsDiagSubSysExternalPowerFrameBoardIndex} - ::= { upsDiagSubSysExternalPowerFrameBoardTable 1 } - -UpsDiagSubSysExternalPowerFrameBoardEntry ::= - SEQUENCE { - upsDiagSubSysExternalPowerFrameBoardFrameIndex INTEGER, - upsDiagSubSysExternalPowerFrameBoardIndex INTEGER, - upsDiagSubSysExternalPowerFrameBoardStatus INTEGER - } - -upsDiagSubSysExternalPowerFrameBoardFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysExternalPowerFrameBoardEntry 1 } - -upsDiagSubSysExternalPowerFrameBoardIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an External Power Frame Board." - ::= { upsDiagSubSysExternalPowerFrameBoardEntry 2 } - -upsDiagSubSysExternalPowerFrameBoardStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the External Power Frame Board. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysExternalPowerFrameBoardEntry 3 } - -upsDiagSubSysChargerTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of Chargers attached to the UPS." - ::= { upsDiagnosticSubsystem 19 } - - upsDiagSubSysChargerTable OBJECT-TYPE - SYNTAX SEQUENCE OF UpsDiagSubSysChargerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for diagnostics of individual chargers." - ::= { upsDiagnosticSubsystem 20 } - -upsDiagSubSysChargerEntry OBJECT-TYPE - SYNTAX UpsDiagSubSysChargerEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The diagnostics of a charger." - INDEX { upsDiagSubSysChargerIndex} - ::= { upsDiagSubSysChargerTable 1 } - -UpsDiagSubSysChargerEntry ::= - SEQUENCE { - upsDiagSubSysChargerFrameIndex INTEGER, - upsDiagSubSysChargerIndex INTEGER, - upsDiagSubSysChargerStatus INTEGER - } - -upsDiagSubSysChargerFrameIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The frame index entry." - ::= { upsDiagSubSysChargerEntry 1 } - -upsDiagSubSysChargerIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of a charger." - ::= { upsDiagSubSysChargerEntry 2 } - -upsDiagSubSysChargerStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - offOk (3), - onOk (4), - offFail (5), - onFail (6), - lostComm (7) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Charger. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - offOk(3) indicates the device status is off and OK. - onOk(4) indicates the device status is on and OK. - offFail(5) indicates the device status is off and failed. - onFail(6) indicates the device status is on and failed. - lostComm(7) indicates the device has lost communication." - ::= { upsDiagSubSysChargerEntry 3 } - --- the upsDiagnosticExternalDevices group - -upsDiagSwitchGearStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - fail (4), - lostComm (5), - overtemp (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - fail(4) indicates the device status has failed. - lostComm(5) indicates the device has lost communication. - overtemp(6) indicates the device has an over temperature condition." - ::= { upsDiagSwitchGear 1 } - -upsDiagSwitchGearInputSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear Input Switch. - unknown(1) indicates the switch status is unknown. - notInstalled(2) indicates the switch is not installed. - opened(3) indicates the switch is opened. - closed(4) indicates the switch is closed." - ::= { upsDiagSwitchGear 2 } - -upsDiagSwitchGearOutputSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear Output Switch. - unknown(1) indicates the switch status is unknown. - notInstalled(2) indicates the switch is not installed. - opened(3) indicates the switch is opened. - closed(4) indicates the switch is closed." - ::= { upsDiagSwitchGear 3 } - -upsDiagSwitchGearBypassSwitchStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Switch Gear Bypass Switch. - unknown(1) indicates the switch status is unknown. - notInstalled(2) indicates the switch is not installed. - opened(3) indicates the switch is opened. - closed(4) indicates the switch is closed." - ::= { upsDiagSwitchGear 4 } - -upsDiagMCCBBoxStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - opened (3), - closed (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the MCCB Box (Molded Case Circuit Breaker Box) external device. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - opened(3) indicates the circuit is opened. - closed(4) indicates the circuit is closed." - ::= { upsDiagMCCBBox 1 } - -upsDiagTransformerStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - fail (4), - lostComm (5), - overtemp (6), - opened (7), - closed (8) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the External Transformer. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - fail(4) indicates the device status has failed. - lostComm(5) indicates the device has lost communication. - overtemp(6) indicates the device has an over temperature condition. - opened(7) indicates the circuit is opened. - closed(8) indicates the circuit is closed." - ::= { upsDiagTransformer 1 } - --- the upsDiagnosticComBus group - -upsDiagComBusInternalMIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the internal MIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 1 } - -upsDiagComBusInternalRIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the internal RIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 2 } - -upsDiagComBusMIMtoRIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the MIM to RIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 3 } - -upsDiagComBusExternalMIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the external MIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 4 } - -upsDiagComBusExternalRIMStatus OBJECT-TYPE - SYNTAX INTEGER { - unknown (1), - notInstalled (2), - ok (3), - lostComm (4), - rxFailure (5), - txFailure (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the external RIM communication bus. - unknown(1) indicates the device status is unknown. - notInstalled(2) indicates the device is not installed. - ok(3) indicates the device status is OK. - lostComm(4) indicates the device has lost communication. - rxFailure(5) indicates the device has a receive failure. - txFailure(6) indicates the device has a transmit failure." - ::= { upsDiagnosticComBus 5 } - --- the serialPort2Config group - -serialPort2Mode OBJECT-TYPE - SYNTAX INTEGER { - localConsole(1), - passthrough(2) - } - ACCESS read-write - STATUS obsolete - DESCRIPTION - "Setting this variable to passthrough will enable mini's port2 - behave like a UPS port. Choosing localConsole will enable the port - to be used as local console." - ::= { serialPort2Config 1 } --- the serialPort2Control group - -setPulseOnTXD OBJECT-TYPE - SYNTAX INTEGER { - noSetPulseOnTXD(1), - setPulseOnTXD(2), - setTXDLow(3), - setTXDHigh(4) - - } - ACCESS read-write - STATUS obsolete - DESCRIPTION - "Setting this variable to setPulseOnTXD(2) - causes adapter to generate a PULSE on TXD pin of serial port 2. - The duration in the prototype implementation will be 1 second. - - Setting this value to noSetPulseOnTXD(1) has no - effect. - - The value noSetPulseOnTXD(1) will always be returned - when the variable is read. - - Setting this value to setTXDLow(3), or setTXDHigh(4) will keep TXD - always low or high respectively." - ::= { serialPort2Control 1 } - --- the sPDUIdent group - -sPDUIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the PDU. This value - is set at the factory." - ::= { sPDUIdent 1 } - -sPDUIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 8 byte ID string identifying the PDU firmware revision. - This value is set at the factory." - ::= { sPDUIdent 2 } - - -sPDUIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the PDU was manufactured in mm/dd/yy format. - This value is set at the factory. The year 2000 will be - represented by 00." - ::= { sPDUIdent 3 } - -sPDUIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 10-character string identifying the model number of - the PDU internal. This value is set at the factory." - ::= { sPDUIdent 4 } - -sPDUIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 12-character string identifying the serial number of - the PDU internal microprocessor. This value is set at - the factory." - ::= { sPDUIdent 5 } - - --- the sPDUMasterControl group - -sPDUMasterControlSwitch OBJECT-TYPE - SYNTAX INTEGER { - turnAllOnNow (1), - turnAllOnSequence (2), - turnAllOffNow (3), - rebootAllNow (4), - rebootAllSequence (5), - noCommand (6), - turnAllOffSequence (7) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to turnAllOnNow (1) will turn all outlets - on immediately. - - Setting this OID to turnAllOnSequence (2) will turn all outlets - on as defined by each outlet's sPDUOutletPowerOnTime OID value. - - Setting this OID to turnAllOff (3) will turn all outlets - off immediately. - - Setting this OID to rebootAllNow (4) will reboot all outlets - immediately. - - For MasterSwitch firmware version 1.X, setting this OID to - rebootAllSequence (5) reboots all outlets, with power returned - to the outlets in the sequence defined by each outlet's - sPDUOutletPowerOnTime OID value. - - For MasterSwitch firmware version 2.X, setting this OID to - rebootAllSequence (5) will cause a turnAllOffSequence to be performed. - Once all outlets are off, the MasterSwitch will then delay the - sPDUMasterConfigReboot OID time, and then perform a turnAllOnSequence. - - For MasterSwitch firmware version 2.X, setting this OID to - turnAllOffSequence (7) will turn all outlets off as defined by - each outlet's sPDUOutletPowerOffTime OID value. - - For MasterSwitch firmware version 1.X, setting this OID to - turnAllOffSequence (7) will have no effect. - - Getting this OID will return the noCommand (6) value." - - ::= { sPDUMasterControl 1 } - - -sPDUMasterState OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will cause the status of all outlets to be - returned. This OID is provided for informational purposes only. - To change the outlet state, the user should use the sPDUOutletCtl - OID in the sPDUOutletControlTable. - - The format of the data returned is a character string consisting - of the word 'On' if the outlet is on or 'Off' if the outlet is - off. At least one space will delimit each outlet entry in the - string. - - If the outlet states are unknown, the character string 'Unknown' - will be returned. This signifies that there is an inconsistancy - in the PDU. In the rare case that this should happen, the user - is advised to shut down all equipment powered by the PDU and - then cycle the PDU's power. This will put the PDU in a consistent - state." - - ::= { sPDUMasterControl 2 } - -sPDUMasterPending OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will cause the command pending status of all outlets to be returned. - - The format of the data returned is a character string consisting - of the word 'Yes' if a command is pending for the outlet or 'No' - if there is no command pending for the outlet. At least one - space will delimit each outlet entry in the string. - - If the pending states are unknown, the character string 'Unknown' - will be returned. This signifies that there is an inconsistancy - in the PDU. In the rare case that this should happen, the user - is advised to shut down all equipment powered by the PDU and then - cycle the PDU's power. This will put the PDU in a consistent state." - ::= { sPDUMasterControl 3 } - - --- the sPDUMasterConfig group - -sPDUMasterConfigPowerOn OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when - power is provided to the PDU and when the PDU - provides basic master power to the outlets. - - Allowed values are: - - -1 never apply power automatically. - 0 apply power immediately. - 15 apply power in 15 seconds. - 30 apply power in 30 seconds. - 45 apply power in 45 seconds. - 60 apply power in 60 seconds (1 minute). - 120 apply power in 120 seconds (2 minutes). - 300 apply power in 300 seconds (5 minutes). - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - - ::= { sPDUMasterConfig 1 } - -sPDUMasterConfigReboot OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed values are: - - 5 wait 5 seconds between off/on. - 10 wait 10 seconds between off/on. - 15 wait 15 seconds between off/on. - 20 wait 20 seconds between off/on. - 30 wait 30 seconds between off/on. - 45 wait 45 seconds between off/on. - 60 wait 60 seconds (1 minute) between off/on. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used. - - This OID is read-only for the MasterSwitch version 2.X and is the - maximum sPDUOutletRebootDuration OID of the individual outlets." - - ::= { sPDUMasterConfig 2 } - -sPDUMasterConfigPDUName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the PDU. The maximum value is 20 characters." - ::= { sPDUMasterConfig 3 } - - - --- the sPDUOutletControl group -sPDUOutletControlTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlets for the PDU." - ::= { sPDUOutletControl 1 } - - -sPDUOutletControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the sPDUOutletControlTableSize OID." - ::= { sPDUOutletControl 2 } - -sPDUOutletControlEntry OBJECT-TYPE - SYNTAX OutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletControlIndex} - ::= { sPDUOutletControlTable 1 } - -OutletControlEntry ::= - SEQUENCE { - sPDUOutletControlIndex INTEGER, - sPDUOutletPending INTEGER, - sPDUOutletCtl INTEGER, - sPDUOutletCtlName DisplayString - } - -sPDUOutletControlIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletControlEntry 1 } - -sPDUOutletPending OBJECT-TYPE - SYNTAX INTEGER{ - commandPending (1), - noCommandPending (2), - commandPendingUnknown (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Reports whether the current outlet has a pending command. - - If the commandPendingUnknown (3) value is returned, all - devices powered by the PDU should be shut down. The PDU's - power should then be cycled to clear this condition." - - ::= { sPDUOutletControlEntry 2 } - -sPDUOutletCtl OBJECT-TYPE - SYNTAX INTEGER { - outletOn (1), - outletOff (2), - outletReboot (3), - outletUnknown (4), - outletOnWithDelay (5), - outletOffWithDelay (6), - outletRebootWithDelay (7) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletOn (1) value will be returned. - If the outlet is off, the outletOff (2) value will be - returned. - - If the state of the outlet cannot be determined, the - outletUnknown (4) value will be returned. If the - outletUnknown condition should occur, all devices - powered by the PDU should be shut down. The PDU's power - should then be cycled to clear this condition. - - Setting this variable to outletOn (1) will turn the outlet on. - - Setting this variable to outletOff (2) will turn the outlet off. - - Setting this variable to outletReboot (3) will reboot the outlet. - - Setting this variable to outletOnWithDelay (5) will turn the outlet on - after the sPDUOutletPowerOnTime OID has elapsed. This option is not - valid for MasterSwitch firmware version 1.X. - - Setting this variable to outletOffWithDelay (6) will turn the outlet off - after the sPDUOutletPowerOffTime OID has elapsed. This option is not valid - for MasterSwitch firmware version 1.X. - - Setting this variable to outletRebootWithDelay (7) will turn the outlet off - after the sPDUOutletPowerOffTime OID has elapsed, wait the sPDUOutletRebootDuration - OID time, then turn the outlet back on. - This option is not valid for MasterSwitch firmware version 1.X." - - ::= { sPDUOutletControlEntry 3 } - -sPDUOutletCtlName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 20 characters. - This OID is provided for informational purposes only. - This value is set by the sPDUOutletName OID." - - ::= { sPDUOutletControlEntry 4 } - --- the sPDUOutletConfig group -sPDUOutletConfigTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of outlets for the PDU." - ::= { sPDUOutletConfig 1 } - -sPDUOutletConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF SPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The list of outlets to configure. The number of - entries is defined by the sPDUOutletConfigTableSize - OID." - - ::= { sPDUOutletConfig 2 } - -sPDUOutletConfigEntry OBJECT-TYPE - SYNTAX SPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletConfigIndex} - ::= { sPDUOutletConfigTable 1 } - -SPDUOutletConfigEntry ::= - SEQUENCE { - sPDUOutletConfigIndex INTEGER, - sPDUOutletPowerOnTime INTEGER, - sPDUOutletName DisplayString, - sPDUOutletPowerOffTime INTEGER, - sPDUOutletRebootDuration INTEGER - } - -sPDUOutletConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigEntry 1 } - -sPDUOutletPowerOnTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering on when the MasterSwitch is powered on. - - Allowed values are: - - -1 never power on automatically. - 0 power on with the Master Switch. - 15 power on 15 seconds after the MasterSwitch has power applied. - 30 power on 30 seconds after the MasterSwitch has power applied. - 45 power on 45 seconds after the MasterSwitch has power applied. - 60 power on 60 seconds (1 minute) after the MasterSwitch has power applied. - 120 power on 120 seconds (2 minutes) after the MasterSwitch has power applied. - 300 power on 300 seconds (5 minutes) after the MasterSwitch has power applied. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - - ::= { sPDUOutletConfigEntry 2 } - -sPDUOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 20 characters." - - ::= { sPDUOutletConfigEntry 3 } - -sPDUOutletPowerOffTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering off. - - Allowed values are: - - -1 never power off automatically. - 0 power off with the MasterSwitch. - 15 power off 15 seconds after being commanded. - 30 power off 30 seconds after being commanded. - 45 power off 45 seconds after being commanded. - 60 power off 60 seconds (1 minute) after being commanded. - 120 power off 120 seconds (2 minutes) after being commanded. - 300 power off 300 seconds (5 minutes) after being commanded. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used. - - This OID is not available for MasterSwitch firmware version 1.X." - - ::= { sPDUOutletConfigEntry 4 } - -sPDUOutletRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed values are: - - 5 wait 5 seconds between off/on. - 10 wait 10 seconds between off/on. - 15 wait 15 seconds between off/on. - 20 wait 20 seconds between off/on. - 30 wait 30 seconds between off/on. - 45 wait 45 seconds between off/on. - 60 wait 60 seconds (1 minute) between off/on. - - If a value other than a supported value is provided in a - set request, the PDU interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used. - - This OID is not available for MasterSwitch firmware version 1.X." - - ::= { sPDUOutletConfigEntry 5 } - - --- the sPDUIdentVM group - -sPDUIdentVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs controllable - by this IP address." - ::= { sPDUIdentVM 1 } - - -sPDUIdentVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for query of the individual MasterSwitch VMs. - The number of entries is contained in the - sPDUIdentVMTableSize OID." - ::= { sPDUIdentVM 2 } - -sPDUIdentVMEntry OBJECT-TYPE - SYNTAX IdentVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to query." - INDEX { sPDUIdentVMIndex} - ::= { sPDUIdentVMTable 1 } - -IdentVMEntry ::= - SEQUENCE { - sPDUIdentVMIndex INTEGER, - sPDUIdentNameVM DisplayString, - sPDUIdentHardwareRevVM DisplayString, - sPDUIdentFirmwareRevVM DisplayString, - sPDUIdentDateOfManufactureVM DisplayString, - sPDUIdentModelNumberVM DisplayString, - sPDUIdentSerialNumberVM DisplayString - } - -sPDUIdentVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUIdentVMEntry 1 } - -sPDUIdentNameVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 23-character string identifying the - MasterSwitch VM. " - ::= { sPDUIdentVMEntry 2 } - -sPDUIdentHardwareRevVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware version of the MasterSwitch VM. - This value is set at the factory." - ::= { sPDUIdentVMEntry 3 } - -sPDUIdentFirmwareRevVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 6-character ID string identifying the MasterSwitch VM - firmware version. This value is set at the factory." - ::= { sPDUIdentVMEntry 4 } - - -sPDUIdentDateOfManufactureVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the MasterSwitch VM was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { sPDUIdentVMEntry 5 } - -sPDUIdentModelNumberVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the model number of - the MasterSwitch VM. This value is set at the factory." - ::= { sPDUIdentVMEntry 6 } - -sPDUIdentSerialNumberVM OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the serial number of - the MasterSwitch VM. This value is set at the factory." - ::= { sPDUIdentVMEntry 7 } - - --- the sPDUMasterControlVM group - -sPDUMasterControlVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs controllable - by this IP address." - ::= { sPDUMasterControlVM 1 } - - -sPDUMasterControlVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of the individual MasterSwitch VMs. - The number of entries is contained in the - sPDUMasterControlVMTableSize OID." - ::= { sPDUMasterControlVM 2 } - -sPDUMasterControlVMEntry OBJECT-TYPE - SYNTAX MasterControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to control." - INDEX { sPDUMasterControlVMIndex} - ::= { sPDUMasterControlVMTable 1 } - -MasterControlVMEntry ::= - SEQUENCE { - sPDUMasterControlVMIndex INTEGER, - sPDUMasterControlVMName DisplayString, - sPDUMasterControlVMCommand INTEGER - } - -sPDUMasterControlVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUMasterControlVMEntry 1 } - -sPDUMasterControlVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigVMName OID." - ::= { sPDUMasterControlVMEntry 2 } - -sPDUMasterControlVMCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandAllVM (1), - immediateAllOnVM (2), - immediateAllOffVM (3), - immediateAllRebootVM (4), - delayedAllOnVM (5), - delayedAllOffVM (6), - sequencedAllRebootVM (7), - delayedAllRebootVM (8), - delayedSequenceAllRebootVM (9), - cancelAllPendingCommandsVM (10), - audioAlarmMute (11) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to immediateAllOnVM (2) will turn all outlets - on immediately. - - Setting this OID to immediateAllOffVM (3) will turn all outlets - off immediately. - - Setting this OID to immediateAllRebootVM (4) will reboot all outlets - immediately. - - Setting this OID to delayedAllOnVM (5) will turn all outlets on as - defined by each outlet's sPDUOutletConfigVMPowerOnTime OID value. - - Setting this OID to delayedAllOffVM (6) will turn all outlets - off as defined by each outlet's sPDUOutletConfigVMPowerOffTime OID value. - - Setting this OID to sequencedAllRebootVM (7) will cause a - immediateAllOffVM command to be performed. The MasterSwitch VM will - then delay the sPDUMasterStatusVMRebootDuration OID time, and then - perform a delayedAllOnVM command. - - Setting this OID to delayedAllRebootVM (8) will cause a delayedAllOffVM - command to be performed. Each outlet will then wait its - sPDUOutletConfigVMRebootDuration before returning power to the outlet. - - Setting this OID to delayedSequenceAllRebootVM (9) will cause a - delayedAllOffVM command to be performed. Once all outlets are off, - the MasterSwitch VM will then delay the sPDUMasterStatusVMRebootDuration - OID time, and then perform a delayedAllOnVM command. - - Setting this OID to cancelAllPendingCommandsVM (10) will cause all pending - commands on the MasterSwitch VM to be canceled. - - - Setting this OID to audioAlarmMute (11) will temporarily silence the audible - alarm for the duration of the current overload condition. The audible alarm - will be activated on subsequent overload alarms. - - Getting this OID will return the noCommandAllVM (1) value." - ::= { sPDUMasterControlVMEntry 3 } - - --- the sPDUMasterConfigVM group - -sPDUMasterConfigVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs configurable - by this IP address." - ::= { sPDUMasterConfigVM 1 } - - -sPDUMasterConfigVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of the individual MasterSwitch VMs. - The number of entries is contained in the - sPDUMasterConfigVMTableSize OID." - ::= { sPDUMasterConfigVM 2 } - -sPDUMasterConfigVMEntry OBJECT-TYPE - SYNTAX MasterConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to configure." - INDEX { sPDUMasterConfigVMIndex} - ::= { sPDUMasterConfigVMTable 1 } - -MasterConfigVMEntry ::= - SEQUENCE { - sPDUMasterConfigVMIndex INTEGER, - sPDUMasterConfigVMName DisplayString, - sPDUMasterConfigVMColdstartDelay INTEGER, - sPDUMasterConfigVMAudioAlarmActivated INTEGER, - sPDUMasterConfigVMHighLoadWarningThreshold INTEGER, - sPDUMasterConfigVMLowLoadWarningThreshold INTEGER, - sPDUMasterConfigVMOverloadRestriction INTEGER - } - -sPDUMasterConfigVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUMasterConfigVMEntry 1 } - - -sPDUMasterConfigVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUMasterConfigVMEntry 2 } - -sPDUMasterConfigVMColdstartDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when - power is provided to the MasterSwitch VM and - when the MasterSwitch VM provides basic master - power to the outlets. - - Allowed values are: - - -1 never apply power automatically. - 0 apply power immediately. - 15 apply power in 15 seconds. - 30 apply power in 30 seconds. - 45 apply power in 45 seconds. - 60 apply power in 60 seconds (1 minute). - 120 apply power in 120 seconds (2 minutes). - 300 apply power in 300 seconds (5 minutes). - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUMasterConfigVMEntry 3 } - -sPDUMasterConfigVMAudioAlarmActivated OBJECT-TYPE - SYNTAX INTEGER { - audioAlarmActiveNever (1), - audioAlarmActiveOnOverload (2), - audioAlarmActiveOnOverloadImminent (3) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to audioAlarmActiveNever (1) will disable - the audio alarm on the MasterSwitch VM. - - Setting this OID to audioAlarmActiveOnOverload (2) will - activate the audio alarm on the MasterSwitch VM when an - overload condition is present. - - Setting this OID to audioAlarmActiveOnOverloadImminent (3) - will activate the audio alarm on the MasterSwitch VM when - the load on the MasterSwitch VM has surpassed the - sPDUMasterConfigVMHighLoadWarningThreshold OID value." - ::= { sPDUMasterConfigVMEntry 4 } - -sPDUMasterConfigVMHighLoadWarningThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing an overload condition. It is - represented as a percentage of full load." - ::= { sPDUMasterConfigVMEntry 5 } - -sPDUMasterConfigVMLowLoadWarningThreshold OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing a low consumption condition. It is - represented as a percentage of full load." - ::= { sPDUMasterConfigVMEntry 6 } - -sPDUMasterConfigVMOverloadRestriction OBJECT-TYPE - SYNTAX INTEGER { - alwaysAllowTurnON (1), - restrictOnWarning (2), - restrictOnOverload (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID controls the behavior of the MasterSwitch VM - when an overload condition is possible and additional - outlets are requested to be turned on. - - Setting this OID to alwaysAllowTurnON (1) will always allow - the outlets to turn on. - - Setting this OID to restrictOnWarning (2) will not allow - outlets to turn on if the sPDUMasterConfigVMHighLoadWarningThreshold - OID is exceeded. - - Setting this OID to restrictOnOverload (3) will not allow - outlets to turn on if the MasterSwitch Vm is in an - overload condition." - ::= { sPDUMasterConfigVMEntry 7 } - --- the sPDUMasterStatusVM group - -sPDUMasterStatusVMTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch VMs at - this IP address." - ::= { sPDUMasterStatusVM 1 } - - -sPDUMasterStatusVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for gathering of status from the individual - MasterSwitch VMs. The number of entries is contained - in the sPDUMasterStatusVMTableSize OID." - ::= { sPDUMasterStatusVM 2 } - -sPDUMasterStatusVMEntry OBJECT-TYPE - SYNTAX MasterStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch VMs to gather status from." - INDEX { sPDUMasterStatusVMIndex} - ::= { sPDUMasterStatusVMTable 1 } - -MasterStatusVMEntry ::= - SEQUENCE { - sPDUMasterStatusVMIndex INTEGER, - sPDUMasterStatusVMName DisplayString, - sPDUMasterStatusVMCommandPending INTEGER, - sPDUMasterStatusVMOverloadCondition INTEGER, - sPDUMasterStatusVMLowLoadCondition INTEGER, - sPDUMasterStatusVMCurrentLoad INTEGER, - sPDUMasterStatusVMMaxLoad INTEGER, - sPDUMasterStatusVMOutletCount INTEGER, - sPDUMasterStatusVMRebootDuration INTEGER - } - -sPDUMasterStatusVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM entry." - ::= { sPDUMasterStatusVMEntry 1 } - -sPDUMasterStatusVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUMasterStatusVMEntry 2 } - -sPDUMasterStatusVMCommandPending OBJECT-TYPE - SYNTAX INTEGER { - commandPendingMasterTrueVM (1), - commandPendingMasterFalseVM (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return commandPendingMasterTrueVM (1) - if the MasterSwitch VM has a pending command on any of its - outlets. - - commandPendingMasterFalseVM (2) will be returned if there are - no pending commands." - ::= { sPDUMasterStatusVMEntry 3 } - -sPDUMasterStatusVMOverloadCondition OBJECT-TYPE - SYNTAX INTEGER { - overloadConditionTrueVM (1), - overloadConditionFalseVM (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return overloadConditionTrueVM (1) - if the sPDUMasterConfigVMHighLoadWarningThreshold OID is - violated. - - overloadConditionFalseVM (2) will be returned if the - sPDUMasterConfigVMHighLoadWarningThreshold OID is not - violated." - ::= { sPDUMasterStatusVMEntry 4 } - -sPDUMasterStatusVMLowLoadCondition OBJECT-TYPE - SYNTAX INTEGER { - lowLoadConditionTrueVM (1), - lowLoadConditionFalseVM (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return lowLoadConditionTrueVM (1) - if the sPDUMasterConfigVMLowLoadWarningThreshold OID is - violated. - - lowLoadConditionFalseVM (2) will be returned if the - sPDUMasterConfigVMHighLoadWarningThreshold OID is not - violated. " - ::= { sPDUMasterStatusVMEntry 5 } - -sPDUMasterStatusVMCurrentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the total amount of power - being consumed by the load. It is represented as a - percentage of full load." - ::= { sPDUMasterStatusVMEntry 6 } - -sPDUMasterStatusVMMaxLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the total amount of power - that this MasterSwitch VM can provide. It is represented - in Amps." - ::= { sPDUMasterStatusVMEntry 7 } - -sPDUMasterStatusVMOutletCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of controllable - outlets for this MasterSwitch VM." - ::= { sPDUMasterStatusVMEntry 8 } - -sPDUMasterStatusVMRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the largest - sPDUOutletConfigVMRebootDuration OID time - for this MasterSwitch VM." - ::= { sPDUMasterStatusVMEntry 9 } - --- the sPDUOutletControlVM group - - -sPDUOutletControlVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletControlVM 1 } - -sPDUOutletControlVMEntry OBJECT-TYPE - SYNTAX OutletControlVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletControlVMIndex, sPDUOutletControlVMOutletIndex } - ::= { sPDUOutletControlVMTable 1 } - -OutletControlVMEntry ::= - SEQUENCE { - sPDUOutletControlVMIndex INTEGER, - sPDUOutletControlVMName DisplayString, - sPDUOutletControlVMOutletIndex INTEGER, - sPDUOutletControlVMOutletName DisplayString, - sPDUOutletControlVMOutletCommand INTEGER - } - -sPDUOutletControlVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM." - ::= { sPDUOutletControlVMEntry 1 } - -sPDUOutletControlVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters. - This OID is provided for informational purposes only." - ::= { sPDUOutletControlVMEntry 2 } - -sPDUOutletControlVMOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletControlVMEntry 3 } - -sPDUOutletControlVMOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters. - This OID is provided for informational purposes only." - ::= { sPDUOutletControlVMEntry 4 } - -sPDUOutletControlVMOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOnVM (1), - immediateOffVM (2), - immediateRebootVM (3), - delayedOnVM (4), - delayedOffVM (5), - delayedRebootVM (6), - cancelPendingCommandVM (7) - - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOnVM (1) value will be returned. - If the outlet is off, the immediateOffVM (2) value will be - returned. - - - Setting this variable to immediateOnVM (1) will immediately turn the outlet on. - - Setting this variable to immediateOffVM (2) will immediately turn the outlet off. - - Setting this variable to immediateRebootVM (3) will immediately reboot the outlet. - - Setting this variable to delayedOnVM (4) will turn the outlet on - after the sPDUOutletConfigVMPowerOnTime OID time has elapsed. - - Setting this variable to delayedOffVM (5) will turn the outlet off - after the sPDUOutletConfigVMPowerOffTime OID time has elapsed. - - Setting this variable to delayedRebootVM (6) will cause the - MasterSwitch VM to perform a delayedOffVM command, wait the - sPDUOutletConfigVMRebootDuration OID time, and then perform the - immediateOnVM command. - - Setting this variable to cancelPendingCommandVM (7) will cause any - pending command to this outlet to be canceled." - ::= { sPDUOutletControlVMEntry 5 } - --- the sPDUOutletConfigVM group - -sPDUOutletConfigVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletConfigVM 1 } - -sPDUOutletConfigVMEntry OBJECT-TYPE - SYNTAX OutletConfigVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigVMIndex, sPDUOutletConfigVMOutletIndex } - ::= { sPDUOutletConfigVMTable 1 } - -OutletConfigVMEntry ::= - SEQUENCE { - sPDUOutletConfigVMIndex INTEGER, - sPDUOutletConfigVMName DisplayString, - sPDUOutletConfigVMOutletIndex INTEGER, - sPDUOutletConfigVMOutletName DisplayString, - sPDUOutletConfigVMPowerOnTime INTEGER, - sPDUOutletConfigVMPowerOffTime INTEGER, - sPDUOutletConfigVMRebootDuration INTEGER - } - -sPDUOutletConfigVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM." - ::= { sPDUOutletConfigVMEntry 1 } - -sPDUOutletConfigVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUOutletConfigVMEntry 2 } - -sPDUOutletConfigVMOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigVMEntry 3 } - - -sPDUOutletConfigVMOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters." - ::= { sPDUOutletConfigVMEntry 4 } - -sPDUOutletConfigVMPowerOnTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering on at coldstart or when a command that requires - a turn-on delay is issued. - - Allowed values are: - - -1 never power on. - 0 power on immediately. - 15 power on 15 seconds after being commanded. - 30 power on 30 seconds after being commanded. - 45 power on 45 seconds after being commanded. - 60 power on 60 seconds (1 minute) after being commanded. - 120 power on 120 seconds (2 minutes) after being commanded. - 300 power on 300 seconds (5 minutes) after being commanded. - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUOutletConfigVMEntry 5 } - - -sPDUOutletConfigVMPowerOffTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering off when a command that requires - a turn-off delay is issued. - - - Allowed values are: - - -1 never power off automatically. - 0 power off immediately. - 15 power off 15 seconds after being commanded. - 30 power off 30 seconds after being commanded. - 45 power off 45 seconds after being commanded. - 60 power off 60 seconds (1 minute) after being commanded. - 120 power off 120 seconds (2 minutes) after being commanded. - 300 power off 300 seconds (5 minutes) after being commanded. - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUOutletConfigVMEntry 6 } - -sPDUOutletConfigVMRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed values are: - - 5 wait 5 seconds between off/on. - 10 wait 10 seconds between off/on. - 15 wait 15 seconds between off/on. - 20 wait 20 seconds between off/on. - 30 wait 30 seconds between off/on. - 45 wait 45 seconds between off/on. - 60 wait 60 seconds (1 minute) between off/on. - - If a value other than a supported value is provided in a - set request, the MasterSwitch VM interprets it as the next lower - acceptable value. If the provided value is lower than - the lowest acceptable value, the lowest acceptable - value is used." - ::= { sPDUOutletConfigVMEntry 7 } - --- the sPDUOutletStatusVM group - -sPDUOutletStatusVMTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of individual outlets. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletStatusVM 1 } - -sPDUOutletStatusVMEntry OBJECT-TYPE - SYNTAX OutletStatusVMEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to gather status from." - INDEX { sPDUOutletStatusVMIndex, sPDUOutletStatusVMOutletIndex } - ::= { sPDUOutletStatusVMTable 1 } - -OutletStatusVMEntry ::= - SEQUENCE { - sPDUOutletStatusVMIndex INTEGER, - sPDUOutletStatusVMName DisplayString, - sPDUOutletStatusVMOutletIndex INTEGER, - sPDUOutletStatusVMOutletName DisplayString, - sPDUOutletStatusVMOutletState INTEGER, - sPDUOutletStatusVMCommandPending INTEGER - } - -sPDUOutletStatusVMIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch VM." - ::= { sPDUOutletStatusVMEntry 1 } - -sPDUOutletStatusVMName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch VM. Maximum size is 23 characters." - ::= { sPDUOutletStatusVMEntry 2 } - -sPDUOutletStatusVMOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletStatusVMEntry 3 } - -sPDUOutletStatusVMOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters." - ::= { sPDUOutletStatusVMEntry 4 } - -sPDUOutletStatusVMOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletStatusVMOn (1), - outletStatusVMOff (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletStatusOnVM (1) value will be returned. - If the outlet is off, the outletStatusOffVM (2) value will be - returned. " - ::= { sPDUOutletStatusVMEntry 5 } - -sPDUOutletStatusVMCommandPending OBJECT-TYPE - SYNTAX INTEGER { - outletStatusVMCommandPending (1), - outletStatusVMNoCommandPending (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet. If a command is pending on the - outlet, the outletStatusVMCommandPending (1) value - will be returned. If there is not a command pending - on the outlet, the outletStatusVMNoCommandPending (2) - will be returned." - ::= { sPDUOutletStatusVMEntry 6 } - --- the sPDUIdentMSP group - -sPDUIdentMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses controllable - by this IP address." - ::= { sPDUIdentMSP 1 } - - -sPDUIdentMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for query of the individual MasterSwitch pluses. - The number of entries is contained in the - sPDUIdentMSPTableSize OID." - ::= { sPDUIdentMSP 2 } - -sPDUIdentMSPEntry OBJECT-TYPE - SYNTAX IdentMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to query." - INDEX { sPDUIdentMSPIndex} - ::= { sPDUIdentMSPTable 1 } - -IdentMSPEntry ::= - SEQUENCE { - sPDUIdentMSPIndex INTEGER, - sPDUIdentNameMSP DisplayString, - sPDUIdentHardwareRevMSP DisplayString, - sPDUIdentFirmwareRevMSP DisplayString, - sPDUIdentDateOfManufactureMSP DisplayString, - sPDUIdentModelNumberMSP DisplayString, - sPDUIdentSerialNumberMSP DisplayString - } - -sPDUIdentMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUIdentMSPEntry 1 } - -sPDUIdentNameMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUIdentMSPEntry 2 } - -sPDUIdentHardwareRevMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware version of the MasterSwitch plus. - This value is set at the factory." - ::= { sPDUIdentMSPEntry 3 } - -sPDUIdentFirmwareRevMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 6-character ID string identifying the MasterSwitch plus - firmware version. This value is set at the factory." - ::= { sPDUIdentMSPEntry 4 } - -sPDUIdentDateOfManufactureMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the MasterSwitch plus was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { sPDUIdentMSPEntry 5 } - -sPDUIdentModelNumberMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the model number of - the MasterSwitch plus. This value is set at the factory." - ::= { sPDUIdentMSPEntry 6 } - -sPDUIdentSerialNumberMSP OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 17-character string identifying the serial number of - the MasterSwitch plus. This value is set at the factory." - ::= { sPDUIdentMSPEntry 7 } - - --- the sPDUMasterControlMSP group - -sPDUMasterControlMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses controllable - by this IP address." - ::= { sPDUMasterControlMSP 1 } - -sPDUMasterControlMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of the individual MasterSwitch pluses. - The number of entries is contained in the - sPDUMasterControlMSPTableSize OID." - ::= { sPDUMasterControlMSP 2 } - -sPDUMasterControlMSPEntry OBJECT-TYPE - SYNTAX MasterControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to control." - INDEX { sPDUMasterControlMSPIndex} - ::= { sPDUMasterControlMSPTable 1 } - -MasterControlMSPEntry ::= - SEQUENCE { - sPDUMasterControlMSPIndex INTEGER, - sPDUMasterControlMSPName DisplayString, - sPDUMasterControlMSPCommand INTEGER - } - -sPDUMasterControlMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUMasterControlMSPEntry 1 } - -sPDUMasterControlMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUMasterControlMSPEntry 2 } - -sPDUMasterControlMSPCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandAllMSP (1), - immediateAllOnMSP (2), - sequencedAllOnMSP (3), - immediateAllOffMSP (4), - gracefulAllRebootMSP (5), - immediateAllRebootMSP (6), - gracefulAllShutdownMSP (7), - overrideAllBatCapThreshMSP (8), - cancelAllPendingCommandsMSP (9), - restoreFactoryDefaultsMSP (10) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to immediateAllOnMSP (2) will turn all outlets - on immediately. - - Setting this OID to sequencedAllOnMSP (3) will turn all outlets - on as defined by each outlet's sPDUOutletConfigMSPPowerOnDelay OID value. - - Setting this OID to immediateAllOffMSP (4) will turn all outlets - off immediately. - - Setting this OID to gracefulAllRebootMSP (5) will reboot all outlets - (after the device running PowerChute confirms shutdown) as defined - by each outlet's sPDUOutletConfigMSPRebootDuration OID time value. - - Setting this OID to immediateAllRebootMSP (6) will reboot all outlets - immediately. - - Setting this OID to gracefulAllShutdownMSP (7) will shutdown all outlets - (after the device running PowerChute confirms shutdown) as defined - by each outlet's sPDUOutletConfigMSPPowerOffDelay OID time value. Each - outlet will then turn on after the sum of its - sPDUOutletConfigMSPRestartDelay and sPDUOutletConfigMSPPowerOnDelay OID - values. - - Setting this OID to overrideAllBatCapThreshMSP (8) will cause the - outlet to ignore the Battery Capacity Threshold and proceed turning on - the outlets as defined by each outlet's sPDUOutletConfigMSPPowerOnDelay - OID value. - - Setting this OID to cancelAllPendingCommandsMSP (9) will cause all pending - commands on the MasterSwitch plus to be canceled. - - Setting this OID to restoreFactoryDefaultsMSP (10) will cause the settings of - the MasterSwitch plus to be restored to the factory defaults. - - Getting this OID will return the noCommandAllMSP (1) value." - ::= { sPDUMasterControlMSPEntry 3 } - - --- the sPDUMasterConfigMSP group - -sPDUMasterConfigMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses configurable - by this IP address." - ::= { sPDUMasterConfigMSP 1 } - -sPDUMasterConfigMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterConfigMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of the individual MasterSwitch pluses. - The number of entries is contained in the - sPDUMasterConfigMSPTableSize OID." - ::= { sPDUMasterConfigMSP 2 } - -sPDUMasterConfigMSPEntry OBJECT-TYPE - SYNTAX MasterConfigMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to configure." - INDEX { sPDUMasterConfigMSPIndex} - ::= { sPDUMasterConfigMSPTable 1 } - -MasterConfigMSPEntry ::= - SEQUENCE { - sPDUMasterConfigMSPIndex INTEGER, - sPDUMasterConfigMSPName DisplayString, - sPDUMasterConfigMSPPowerOnTimeDelay INTEGER, - sPDUMasterConfigMSPManualButton INTEGER - } - -sPDUMasterConfigMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUMasterConfigMSPEntry 1 } - -sPDUMasterConfigMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. Maximum size is 23 characters." - ::= { sPDUMasterConfigMSPEntry 2 } - -sPDUMasterConfigMSPPowerOnTimeDelay OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when - power is provided to the MasterSwitch plus and - when the MasterSwitch plus provides basic master - power to the outlets. - - Allowed values are: - - 0 - 9999 seconds (0 - 2hrs, 46 mins, 39 secs). - 0 indicates to apply power immediately." - ::= { sPDUMasterConfigMSPEntry 3 } - - -sPDUMasterConfigMSPManualButton OBJECT-TYPE - SYNTAX INTEGER { - manualButtonDisabled (1), - manualButtonEnabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to manualButtonDisabled (1) will disable - the manual button on the MasterSwitch plus. - - Setting this OID to manualButtonEnabled (2) will enable - the manual button on the MasterSwitch plus." - ::= { sPDUMasterConfigMSPEntry 4 } - --- the sPDUMasterStatusMSP group - -sPDUMasterStatusMSPTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of MasterSwitch pluses at - this IP address." - ::= { sPDUMasterStatusMSP 1 } - - -sPDUMasterStatusMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF MasterStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for gathering of status from the individual - MasterSwitch pluses. The number of entries is contained - in the sPDUMasterStatusMSPTableSize OID." - ::= { sPDUMasterStatusMSP 2 } - -sPDUMasterStatusMSPEntry OBJECT-TYPE - SYNTAX MasterStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The MasterSwitch pluses to gather status from." - INDEX { sPDUMasterStatusMSPIndex} - ::= { sPDUMasterStatusMSPTable 1 } - -MasterStatusMSPEntry ::= - SEQUENCE { - sPDUMasterStatusMSPIndex INTEGER, - sPDUMasterStatusMSPName DisplayString, - sPDUMasterStatusMSPOutletCount INTEGER - } - -sPDUMasterStatusMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus entry." - ::= { sPDUMasterStatusMSPEntry 1 } - -sPDUMasterStatusMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUMasterStatusMSPEntry 2 } - -sPDUMasterStatusMSPOutletCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of controllable - outlets for this MasterSwitch plus." - ::= { sPDUMasterStatusMSPEntry 3 } - --- the sPDUOutletControlMSP group - -sPDUOutletControlMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletControlMSP 1 } - -sPDUOutletControlMSPEntry OBJECT-TYPE - SYNTAX OutletControlMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { sPDUOutletControlMSPIndex, sPDUOutletControlMSPOutletIndex } - ::= { sPDUOutletControlMSPTable 1 } - -OutletControlMSPEntry ::= - SEQUENCE { - sPDUOutletControlMSPIndex INTEGER, - sPDUOutletControlMSPName DisplayString, - sPDUOutletControlMSPOutletIndex INTEGER, - sPDUOutletControlMSPOutletName DisplayString, - sPDUOutletControlMSPOutletCommand INTEGER - } - -sPDUOutletControlMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletControlMSPEntry 1 } - -sPDUOutletControlMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletControlMSPEntry 2 } - -sPDUOutletControlMSPOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletControlMSPEntry 3 } - -sPDUOutletControlMSPOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletControlMSPEntry 4 } - -sPDUOutletControlMSPOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOnMSP (1), - delayedOnMSP (2), - immediateOffMSP (3), - gracefulRebootMSP (4), - immediateRebootMSP (5), - gracefulshutdownMSP (6), - overrideBatCapThreshMSP (7), - cancelPendingCommandMSP (8) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOnMSP (1) value will be returned. - If the outlet is off, the immediateOffMSP (3) value will be - returned. - - Setting this variable to immediateOnMSP (1) will immediately turn the outlet on. - - Setting this variable to delayedOnMSP (2) will turn the outlet on - after the sPDUOutletConfigMSPPowerOnDelay OID time has elapsed. - - Setting this variable to immediateOffMSP (3) will immediately turn the outlet off. - - Setting this variable to gracefulRebootMSP (4) will cause the outlet to wait for - device confirmation (if applicable) and then turn the outlet off after the - sPDUOutletConfigMSPPowerOffDelay OID time has elapsed. The outlet will then turn - on after the sPDUOutletConfigMSPRebootDuration OID time has elapsed. - - Setting this variable to immediateRebootMSP (5) will immediately reboot the outlet. - - Setting this variable to gracefulshutdownMSP (6) will cause the outlet to wait for - device confirmation (if applicable) and then turn the outlet off after the - sPDUOutletConfigMSPPowerOffDelay OID time has elapsed. The outlet will then turn - on after the sum of the sPDUOutletConfigMSPRestartTime OID time and the - sPDUOutletConfigMSPPowerOnDelay OID time has elapsed. - - Setting this variable to overrideBatCapThreshMSP (7) will cause the outlet to - ignore the Battery Capacity Threshold and proceed waiting on the - sPDUOutletConfigMSPPowerOnDelay OID time before turning the outlet on. - - Setting this variable to cancelPendingCommandMSP (8) will cause any - pending command to this outlet to be canceled." - ::= { sPDUOutletControlMSPEntry 5 } - --- the sPDUOutletConfigMSPall group - -sPDUOutletConfigMSPallTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPallEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPall 1 } - -sPDUOutletConfigMSPallEntry OBJECT-TYPE - SYNTAX OutletConfigMSPallEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPallIndex, sPDUOutletConfigMSPallOutletIndex } - ::= { sPDUOutletConfigMSPallTable 1 } - -OutletConfigMSPallEntry ::= - SEQUENCE { - sPDUOutletConfigMSPallIndex INTEGER, - sPDUOutletConfigMSPallName DisplayString, - sPDUOutletConfigMSPallOutletIndex INTEGER, - sPDUOutletConfigMSPallOutletName DisplayString, - sPDUOutletConfigMSPallOutletCtrlMode INTEGER - } - -sPDUOutletConfigMSPallIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPallEntry 1 } - -sPDUOutletConfigMSPallName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPallEntry 2 } - -sPDUOutletConfigMSPallOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPallEntry 3 } - -sPDUOutletConfigMSPallOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is 23 characters." - ::= { sPDUOutletConfigMSPallEntry 4 } - -sPDUOutletConfigMSPallOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to modeGracefulShutdown (1) will put this - outlet into the Graceful Shutdown control mode. - - Setting this OID to modeAnnunciator (2) will put this outlet - into the Annunciator control mode." - ::= { sPDUOutletConfigMSPallEntry 5 } - - --- the sPDUOutConfigMSPgs group - -sPDUOutletConfigMSPgsTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPgsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPgs 1 } - -sPDUOutletConfigMSPgsEntry OBJECT-TYPE - SYNTAX OutletConfigMSPgsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPgsIndex, sPDUOutletConfigMSPgsOutletIndex } - ::= { sPDUOutletConfigMSPgsTable 1 } - -OutletConfigMSPgsEntry ::= - SEQUENCE { - sPDUOutletConfigMSPgsIndex INTEGER, - sPDUOutletConfigMSPgsName DisplayString, - sPDUOutletConfigMSPgsOutletIndex INTEGER, - sPDUOutletConfigMSPgsOutletName DisplayString, - sPDUOutletConfigMSPgsOutletCtrlMode INTEGER, - sPDUOutletConfigMSPgsDeviceConfirm INTEGER, - sPDUOutletConfigMSPgsLowBattWarning INTEGER, - sPDUOutletConfigMSPgsLowBattMult INTEGER, - sPDUOutletConfigMSPgsRestartDelay INTEGER, - sPDUOutletConfigMSPgsPowerOnDelay INTEGER, - sPDUOutletConfigMSPgsPowerOffDelay INTEGER, - sPDUOutletConfigMSPgsBattCapThresh INTEGER, - sPDUOutletConfigMSPgsRebootDuration INTEGER - } - -sPDUOutletConfigMSPgsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPgsEntry 1 } - -sPDUOutletConfigMSPgsName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPgsEntry 2 } - -sPDUOutletConfigMSPgsOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPgsEntry 3 } - -sPDUOutletConfigMSPgsOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPgsEntry 4 } - -sPDUOutletConfigMSPgsOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Control Mode of the outlet. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPgsEntry 5 } - -sPDUOutletConfigMSPgsDeviceConfirm OBJECT-TYPE - SYNTAX INTEGER { - deviceConfirmNo (1), - deviceConfirmYes (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to deviceConfirmNo (1) cause the outlet to - NOT wait for device confirmation while performing graceful - operations. - - Setting this OID to deviceConfirmYes (2) cause the outlet to - wait for device confirmation while performing graceful - operations." - ::= { sPDUOutletConfigMSPgsEntry 6 } - -sPDUOutletConfigMSPgsLowBattWarning OBJECT-TYPE - SYNTAX INTEGER (-2..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in 6 second intervals, between - when the UPS goes on battery and the power down sequence for - the outlet is initiated. - - Allowed values are: - - -2 - Never initiate the power down sequence on low battery warning. - -1 - Initiate power down sequence based on remaining runtime. - 1 - 9999 six second intervals (6 secs - 16hrs, 39 mins, 54 secs). - 0 indicates to immediately initiate power down sequence on low - battery warning." - ::= { sPDUOutletConfigMSPgsEntry 7 } - -sPDUOutletConfigMSPgsLowBattMult OBJECT-TYPE - SYNTAX INTEGER (1..7) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " Only applicable if sPDUOutletConfigMSPgsLowBattWarning OID is - set to -1 (On Runtime Remaining). - - Allows you to set the value to stagger the shutdown sequence of the outlets. - 1 provides the longest delay (the outlet to shutoff first), and 7 would - provide the shortest delay (the outlet to shut off last). - - Allowed values are: - 1 - 7." - ::= { sPDUOutletConfigMSPgsEntry 8 } - -sPDUOutletConfigMSPgsRestartDelay OBJECT-TYPE - SYNTAX INTEGER (-1..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in 6 minute intervals, between - when the outlet is turned off and the outlet is turned back on - when performing a Graceful Shutdown. - - Allowed values are: - - -1 - Never turn outlet back on after a Graceful shutdown. - 0 - 9999 six minute intervals (0 - 999hrs, 54 mins)." - ::= { sPDUOutletConfigMSPgsEntry 9 } - -sPDUOutletConfigMSPgsPowerOnDelay OBJECT-TYPE - SYNTAX INTEGER (-1..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between the UPS entering - normal (on-line) state and the outlet being powered on. - - Allowed values are: - - -1 - Remain Off when the UPS enters the on-line state. - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPgsEntry 10 } - - -sPDUOutletConfigMSPgsPowerOffDelay OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, between when the server - shuts down and the outlet is powered off. - - Allowed values are: - - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPgsEntry 11 } - -sPDUOutletConfigMSPgsBattCapThresh OBJECT-TYPE - SYNTAX INTEGER (0..100) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The minimum battery capacity, as a percent (0-100%), required - of the UPS before an outlet will be allowed to power on. - - Allowed values are: - - 0 - 100 percent." - ::= { sPDUOutletConfigMSPgsEntry 12 } - -sPDUOutletConfigMSPgsRebootDuration OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of delay, in seconds, from outlet off until - outlet on during a reboot. - - Allowed values are: - - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPgsEntry 13 } - - --- the sPDUOutConfigMSPannun group - -sPDUOutletConfigMSPannunTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPannunEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPannun 1 } - -sPDUOutletConfigMSPannunEntry OBJECT-TYPE - SYNTAX OutletConfigMSPannunEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPannunIndex, sPDUOutletConfigMSPannunOutletIndex } - ::= { sPDUOutletConfigMSPannunTable 1 } - -OutletConfigMSPannunEntry ::= - SEQUENCE { - sPDUOutletConfigMSPannunIndex INTEGER, - sPDUOutletConfigMSPannunName DisplayString, - sPDUOutletConfigMSPannunOutletIndex INTEGER, - sPDUOutletConfigMSPannunOutletName DisplayString, - sPDUOutletConfigMSPannunOutletCtrlMode INTEGER, - sPDUOutletConfigMSPannunInitialState INTEGER, - sPDUOutletConfigMSPannunAlarmActionDly INTEGER - } - -sPDUOutletConfigMSPannunIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPannunEntry 1 } - -sPDUOutletConfigMSPannunName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPannunEntry 2 } - -sPDUOutletConfigMSPannunOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPannunEntry 3 } - -sPDUOutletConfigMSPannunOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPannunEntry 4 } - -sPDUOutletConfigMSPannunOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Control Mode of the outlet. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPannunEntry 5 } - -sPDUOutletConfigMSPannunInitialState OBJECT-TYPE - SYNTAX INTEGER { - initialStateOff (1), - initialStateOn (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to initialStateOff (1) causes the outlet - to default to off when in the non-alarmed condition. - - Setting this OID to initialStateOn (2) causes the outlet - to default to on when in the non-alarmed condition." - ::= { sPDUOutletConfigMSPannunEntry 6 } - -sPDUOutletConfigMSPannunAlarmActionDly OBJECT-TYPE - SYNTAX INTEGER (0..9999) - ACCESS read-write - STATUS mandatory - DESCRIPTION - " The amount of time, in seconds, that an enabled Measure-UPS - alarm must be asserted before an alarm condition is recognized. - - Allowed values are: - - 0 - 9999 seconds (0 - 2 hrs, 46 mins, 39 secs)." - ::= { sPDUOutletConfigMSPannunEntry 7 } - - --- the sPDUOutConfigMSPmups group - -sPDUOutletConfigMSPmupsTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletConfigMSPmupsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the sPDUMasterStatusMSPOutletCount OID." - ::= { sPDUOutletConfigMSPmups 1 } - -sPDUOutletConfigMSPmupsEntry OBJECT-TYPE - SYNTAX OutletConfigMSPmupsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { sPDUOutletConfigMSPmupsIndex, sPDUOutletConfigMSPmupsOutletIndex } - ::= { sPDUOutletConfigMSPmupsTable 1 } - -OutletConfigMSPmupsEntry ::= - SEQUENCE { - sPDUOutletConfigMSPmupsIndex INTEGER, - sPDUOutletConfigMSPmupsName DisplayString, - sPDUOutletConfigMSPmupsOutletIndex INTEGER, - sPDUOutletConfigMSPmupsOutletName DisplayString, - sPDUOutletConfigMSPmupsZone1 INTEGER, - sPDUOutletConfigMSPmupsZone2 INTEGER, - sPDUOutletConfigMSPmupsZone3 INTEGER, - sPDUOutletConfigMSPmupsZone4 INTEGER, - sPDUOutletConfigMSPmupsP1LowHum INTEGER, - sPDUOutletConfigMSPmupsP1HiHum INTEGER, - sPDUOutletConfigMSPmupsP1LowTemp INTEGER, - sPDUOutletConfigMSPmupsP1HiTemp INTEGER, - sPDUOutletConfigMSPmupsP2LowHum INTEGER, - sPDUOutletConfigMSPmupsP2HiHum INTEGER, - sPDUOutletConfigMSPmupsP2LowTemp INTEGER, - sPDUOutletConfigMSPmupsP2HiTemp INTEGER - } - -sPDUOutletConfigMSPmupsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch plus." - ::= { sPDUOutletConfigMSPmupsEntry 1 } - -sPDUOutletConfigMSPmupsName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletConfigMSPmupsEntry 2 } - -sPDUOutletConfigMSPmupsOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletConfigMSPmupsEntry 3 } - -sPDUOutletConfigMSPmupsOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletConfigMSPmupsEntry 4 } - -sPDUOutletConfigMSPmupsZone1 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 1 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 1 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 5 } - -sPDUOutletConfigMSPmupsZone2 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 2 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 2 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 6 } - -sPDUOutletConfigMSPmupsZone3 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 3 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 3 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 7 } - -sPDUOutletConfigMSPmupsZone4 OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Zone 4 alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Zone 4 alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 8 } - -sPDUOutletConfigMSPmupsP1LowHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 low humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 low humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 9 } - -sPDUOutletConfigMSPmupsP1HiHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 high humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 high humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 10 } - -sPDUOutletConfigMSPmupsP1LowTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 low temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 low temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 11 } - -sPDUOutletConfigMSPmupsP1HiTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 1 high temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 1 high temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 12 } - -sPDUOutletConfigMSPmupsP2LowHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 low humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 low humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 13 } - -sPDUOutletConfigMSPmupsP2HiHum OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 high humidity alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 high humidity alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 14 } - -sPDUOutletConfigMSPmupsP2LowTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 low temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 low temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 15 } - -sPDUOutletConfigMSPmupsP2HiTemp OBJECT-TYPE - SYNTAX INTEGER { - disableAlarm (1), - enableAlarm (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to disableAlarm (1) disables the - Probe 2 high temperature alarm for this outlet. - - Setting this OID to enableAlarm (2) enables the - Probe 2 high temperature alarm for this outlet." - ::= { sPDUOutletConfigMSPmupsEntry 16 } - --- the sPDUOutletStatusMSP group - -sPDUOutletStatusMSPTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of individual outlets. The number of - entries is contained in the sPDUMasterStatusOutletCount OID." - ::= { sPDUOutletStatusMSP 1 } - -sPDUOutletStatusMSPEntry OBJECT-TYPE - SYNTAX OutletStatusMSPEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to gather status from." - INDEX { sPDUOutletStatusMSPIndex, sPDUOutletStatusMSPOutletIndex } - ::= { sPDUOutletStatusMSPTable 1 } - -OutletStatusMSPEntry ::= - SEQUENCE { - sPDUOutletStatusMSPIndex INTEGER, - sPDUOutletStatusMSPName DisplayString, - sPDUOutletStatusMSPOutletIndex INTEGER, - sPDUOutletStatusMSPOutletName DisplayString, - sPDUOutletStatusMSPOutletState INTEGER, - sPDUOutletStatusMSPCommandPending INTEGER, - sPDUOutletStatusMSPOutletCtrlMode INTEGER - } - -sPDUOutletStatusMSPIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the MasterSwitch MSP." - ::= { sPDUOutletStatusMSPEntry 1 } - -sPDUOutletStatusMSPName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the MasterSwitch plus. The maximum - value is 23 characters. The name is set by - using the sPDUMasterConfigMSPName OID." - ::= { sPDUOutletStatusMSPEntry 2 } - -sPDUOutletStatusMSPOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { sPDUOutletStatusMSPEntry 3 } - -sPDUOutletStatusMSPOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. The maximum size is - 23 characters. The name is set by using the - sPDUOutletConfigMSPallOutletName OID. - This OID is provided for informational purposes only." - ::= { sPDUOutletStatusMSPEntry 4 } - -sPDUOutletStatusMSPOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletStatusMSPOn (1), - outletStatusMSPOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletStatusMSPOn (1) value will be returned. - If the outlet is off, the outletStatusMSPOff (2) value will be - returned. " - ::= { sPDUOutletStatusMSPEntry 5 } - -sPDUOutletStatusMSPCommandPending OBJECT-TYPE - SYNTAX INTEGER { - outletStatusMSPCommandPending (1), - outletStatusMSPNoCommandPending (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet. If a command is pending on the - outlet, the outletStatusMSPCommandPending (1) value - will be returned. If there is not a command pending - on the outlet, the outletStatusMSPNoCommandPending (2) - will be returned." - ::= { sPDUOutletStatusMSPEntry 6 } - -sPDUOutletStatusMSPOutletCtrlMode OBJECT-TYPE - SYNTAX INTEGER { - modeGracefulShutdown (1), - modeAnnunciator (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Control Mode of the outlet. - This OID is provided for informational purposes only." - ::= { sPDUOutletStatusMSPEntry 7 } - - --- the rPDUIdent group - -rPDUIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the Rack PDU. - The maximum string size is device dependent." - ::= { rPDUIdent 1 } - -rPDUIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Rack PDU. - This value is set at the factory." - ::= { rPDUIdent 2 } - -rPDUIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An 8-byte ID string identifying the Rack PDU firmware revision. - This value is set at the factory." - ::= { rPDUIdent 3 } - - -rPDUIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the Rack PDU was manufactured in mm/dd/yy format. - This value is set at the factory. The year 2000 will be - represented by 00." - ::= { rPDUIdent 4 } - -rPDUIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 10-character string identifying the model number of - the Rack PDU. This value is set at the factory." - ::= { rPDUIdent 5 } - -rPDUIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 12-character string identifying the serial number of - the Rack PDU. This value is set at the factory." - ::= { rPDUIdent 6 } - -rPDUIdentDeviceRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the electrical rating of the device." - - ::= { rPDUIdent 7 } - -rPDUIdentDeviceNumOutlets OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of outlets contained in the device." - - ::= { rPDUIdent 8 } - -rPDUIdentDeviceNumPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of phases supported by the device." - - ::= { rPDUIdent 9 } - -rPDUIdentDeviceNumBreakers OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the number of circuit breakers supported by the device. - This is the same as the number of banks of outlets." - - ::= { rPDUIdent 10 } - -rPDUIdentDeviceBreakerRating OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return rating of the circuit breakers on the device if it has any." - - ::= { rPDUIdent 11 } - -rPDUIdentDeviceOrientation OBJECT-TYPE - SYNTAX INTEGER { - orientHorizontal (1), - orientVertical (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the intended physical orientation of the device. - - OrientHorizonatal(1) indicates Horizontal. - OrientVertical(2) indicates Vertical." - - ::= { rPDUIdent 12 } - -rPDUIdentDeviceOutletLayout OBJECT-TYPE - SYNTAX INTEGER { - seqPhaseToNeutral (1), - seqPhaseToPhase (2), - seqPhToNeu21PhToPh (3), - seqPhToPhGrouped (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return outlet layout for the device. - - SeqPhaseToNeutral(1) indicates outlet layout as follows: - 1:1-N,2:2-N,3:3-N,4:1-N,5:2-N,... - - SeqPhaseToPhase(2) indicates outlet layout as follows: - 1:1-2,2:2-3,3:3-1,4:1-2,5:2-3,... - - SeqPhToNeu21PhToPh(3) indicates outlet layout as follows: - 1:1-N,2:2-N...21:3-N,22:1-2,23:2-3,24:3-1,... - - SeqPhToPhGrouped(4) indicates outlet layout as follows: - Otlts1-8::(3-1),Otlts9-16::(2-3),Otlts17-24::(1-2)." - ::= { rPDUIdent 13 } - - - --- the rPDULoadDevice group - -rPDULoadDevMaxPhaseLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the maximum rated power - that each phase of the Rack PDU can provide. It is - represented in Amps." - ::= { rPDULoadDevice 1 } - -rPDULoadDevNumPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of phases available with this Rack PDU." - ::= { rPDULoadDevice 2 } - -rPDULoadDevMaxBankLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the maximum rated power - that each bank of the Rack PDU can provide. It is - represented in Amps. - - 0 will be returned if the device does not have any banks." - - ::= { rPDULoadDevice 3 } - -rPDULoadDevNumBanks OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of banks of outlets available with this Rack PDU. - A bank of outlets has a unique circuit breaker for a subset - of the total number of outlets on the rPDU." - ::= { rPDULoadDevice 4 } - --- the rPDULoadPhaseConfig group - -rPDULoadPhaseConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF LoadPhaseConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of each Rack PDU phase. - The number of entries is contained in the - rPDULoadDevNumPhases OID." - ::= { rPDULoadPhaseConfig 1 } - -rPDULoadPhaseConfigEntry OBJECT-TYPE - SYNTAX LoadPhaseConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Rack PDU phase to configure." - INDEX { rPDULoadPhaseConfigIndex} - ::= { rPDULoadPhaseConfigTable 1 } - -LoadPhaseConfigEntry ::= - SEQUENCE { - rPDULoadPhaseConfigIndex INTEGER, - rPDULoadPhaseConfigLowLoadThreshold INTEGER, - rPDULoadPhaseConfigNearOverloadThreshold INTEGER, - rPDULoadPhaseConfigOverloadThreshold INTEGER - } - -rPDULoadPhaseConfigIndex OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Rack PDU phase entry." - ::= { rPDULoadPhaseConfigEntry 1 } - -rPDULoadPhaseConfigLowLoadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing a low consumption condition. It is - represented in amps. A warning will be issued when the - load is less than the threshold value. - - A threshold value of 0 amps effectively disables this - warning. - - Maximum value must be less than the value returned - by the rPDULoadPhaseConfigNearOverloadThreshold OID." - ::= { rPDULoadPhaseConfigEntry 2 } - -rPDULoadPhaseConfigNearOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than the value returned by - the rPDULoadPhaseConfigLowLoadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadPhaseConfigOverloadThreshold OID." - ::= { rPDULoadPhaseConfigEntry 3 } - -rPDULoadPhaseConfigOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load has entered an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than or equal to the value - returned by the rPDULoadPhaseConfigNearOverloadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadDevMaxPhaseLoad OID." - ::= { rPDULoadPhaseConfigEntry 4 } - - --- the rPDULoadStatus group - -rPDULoadStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF LoadStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of each Rack PDU phase/bank. - The number of entries is calculated by adding - the number of phases (rPDULoadDevNumPhases OID) and - the number of banks of outlets (rPDULoadDevNumBanks) - Number of entries = #phases + #banks. - NOTE: If a device has phase and bank information, all phase information - shall preceed the bank information." - ::= { rPDULoadStatus 1 } - -rPDULoadStatusEntry OBJECT-TYPE - SYNTAX LoadStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Rack PDU phase/bank to gather status from." - INDEX { rPDULoadStatusIndex} - ::= { rPDULoadStatusTable 1 } - -LoadStatusEntry ::= - SEQUENCE { - rPDULoadStatusIndex INTEGER, - rPDULoadStatusLoad Gauge, - rPDULoadStatusLoadState INTEGER, - rPDULoadStatusPhaseNumber INTEGER, - rPDULoadStatusBankNumber INTEGER - } - -rPDULoadStatusIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Rack PDU phase/bank entry. All phase information will preceed - any bank information" - ::= { rPDULoadStatusEntry 1 } - -rPDULoadStatusLoad OBJECT-TYPE - SYNTAX Gauge - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the phase/bank load measured - in tenths of amps." - ::= { rPDULoadStatusEntry 2 } - -rPDULoadStatusLoadState OBJECT-TYPE - SYNTAX INTEGER { - phaseLoadNormal (1), - phaseLoadLow (2), - phaseLoadNearOverload (3), - phaseLoadOverload (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return the phase/bank load state. - - phaseLoadNormal(1) indicates that the phase/bank is - operating properly within the rPDULoadConfigLowLoadThreshold - and rPDULoadConfigNearOverloadThreshold OID values. - - phaseLoadLow(2) indicates that the phase/bank load has - dropped below the rPDULoadConfigLowLoadThreshold OID value. - An SNMP trap will occur when this state is entered or cleared. - - phaseLoadNearOverload(3) indicates that the phase/bank load - is greater than or equal to the - rPDULoadConfigNearOverloadThreshold OID value. - An SNMP trap will occur when this state is entered or cleared. - - phaseLoadOverload(4) indicates that the phase/bank load is - greater than or equal to the rPDULoadConfigOverloadThreshold - OID value. - An SNMP trap will occur when this state is entered or cleared." - ::= { rPDULoadStatusEntry 3 } - -rPDULoadStatusPhaseNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase number to which this record refers. A value of 0 will be returned if - this is bank related information." - ::= { rPDULoadStatusEntry 4 } - -rPDULoadStatusBankNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank number to which this record refers. A value of 0 will be returned if - this is phase related information." - ::= { rPDULoadStatusEntry 5 } - --- the rPDULoadBankConfig group - -rPDULoadBankConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF LoadBankConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of each Rack PDU bank. - The number of entries is contained in the - rPDULoadDevNumBanks OID." - ::= { rPDULoadBankConfig 1 } - -rPDULoadBankConfigEntry OBJECT-TYPE - SYNTAX LoadBankConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Rack PDU bank to configure." - INDEX { rPDULoadBankConfigIndex} - ::= { rPDULoadBankConfigTable 1 } - -LoadBankConfigEntry ::= - SEQUENCE { - rPDULoadBankConfigIndex INTEGER, - rPDULoadBankConfigLowLoadThreshold INTEGER, - rPDULoadBankConfigNearOverloadThreshold INTEGER, - rPDULoadBankConfigOverloadThreshold INTEGER - } - -rPDULoadBankConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Rack PDU bank entry." - ::= { rPDULoadBankConfigEntry 1 } - -rPDULoadBankConfigLowLoadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing a low consumption condition. It is - represented in amps. A warning will be issued when the - load is less than the threshold value. - - A threshold value of 0 amps effectively disables this - warning. - - Maximum value must be less than the value returned - by the rPDULoadBankConfigNearOverloadThreshold OID. - - -1 will be returned if the device has no banks." - - ::= { rPDULoadBankConfigEntry 2 } - -rPDULoadBankConfigNearOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load is nearing an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than the value returned by - the rPDULoadBankConfigLowLoadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadBankConfigOverloadThreshold OID. - - -1 will be returned if the device has no banks." - - ::= { rPDULoadBankConfigEntry 3 } - -rPDULoadBankConfigOverloadThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A threshold that indicates the power consumption of - the load has entered an overload condition. It is - represented in amps. A warning will be issued when the - load is greater than or equal to the threshold value. - - Minimum value must be greater than or equal to the value - returned by the rPDULoadBankConfigNearOverloadThreshold OID. - - Maximum value must be less than or equal to the value - returned by the rPDULoadDevMaxBankLoad OID. - - -1 will be returned if the device has no banks." - - ::= { rPDULoadBankConfigEntry 4 } - - --- the rPDUOutletDevice group - -rPDUOutletDevCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandAll (1), - immediateAllOn (2), - immediateAllOff (3), - immediateAllReboot (4), - delayedAllOn (5), - delayedAllOff (6), - delayedAllReboot (7), - cancelAllPendingCommands (8), - gracefulAllOff (9), - gracefulAllReboot (10) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this OID to immediateAllOn (2) will turn all outlets - on immediately. - - Setting this OID to immediateAllOff (3) will turn all outlets - off immediately. - - Setting this OID to immediateAllReboot (4) will reboot all outlets - immediately. - - Setting this OID to delayedAllOn (5) will turn all outlets on as - defined by each outlet's rPDUOutletConfigPowerOnTime OID value. - - Setting this OID to delayedAllOff (6) will turn all outlets - off as defined by each outlet's rPDUOutletConfigPowerOffTime OID value. - - Setting this OID to delayedAllReboot (7) will cause a - delayedAllOff command to be performed. Once all outlets are off, - the Switched Rack PDU will then delay the largest - rPDUOutletConfigRebootDuration OID time, and then perform a - delayedAllOn command. - - Setting this OID to cancelAllPendingCommands (8) will cause all pending - commands on the Switched Rack PDU to be canceled. - - Setting this variable to gracefulAllOff (9) will cause the - Switched Rack PDU to shut all outlets off after it waits the - servers graceful shutdown time and each outlet's shutdown delay. - - Setting this variable to gracefulAllReboot (10) will cause the - Switched Rack PDU to shut all outlets off after it waits the - servers graceful shutdown time and each outlet's shutdown delay. - Once all outlet are off, it will wait until the UPS reaches the - configured minimum return battery capacity, then each outlet's - return delay before it turns the outlet back on. - - Getting this OID will return the noCommandAll (1) value." - ::= { rPDUOutletDevice 1 } - -rPDUOutletDevColdstartDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of delay, in seconds, between when - power is provided to the Switched Rack PDU and - when the Switched Rack PDU provides basic master - power to the outlets. - - Allowed values are: - - -1 - never apply power automatically. - 0 - apply power immediately. - 1 to 300 - delay up to 300 seconds (5 minutes)." - ::= { rPDUOutletDevice 2 } - -rPDUOutletDevNumCntrlOutlets OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of controlled outlets on this Switched Rack PDU." - ::= { rPDUOutletDevice 3 } - -rPDUOutletDevNumTotalOutlets OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of outlets on this Rack PDU." - ::= { rPDUOutletDevice 4 } - - --- the rPDUOutletPhase group - -rPDUOutletPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for management of outlets on a per phase basis." - ::= { rPDUOutletPhase 1 } - -rPDUOutletPhaseEntry OBJECT-TYPE - SYNTAX OutletPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The phase to manage." - INDEX { rPDUOutletPhaseIndex} - ::= { rPDUOutletPhaseTable 1 } - -OutletPhaseEntry ::= - SEQUENCE { - rPDUOutletPhaseIndex INTEGER, - rPDUOutletPhaseOverloadRestriction INTEGER - } - -rPDUOutletPhaseIndex OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Switched Rack PDU phase entry." - ::= { rPDUOutletPhaseEntry 1 } - -rPDUOutletPhaseOverloadRestriction OBJECT-TYPE - SYNTAX INTEGER { - alwaysAllowTurnON (1), - restrictOnNearOverload (2), - restrictOnOverload (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID controls the behavior of a Switched Rack PDU - phase when an overload condition is possible and - additional outlets are requested to be turned on. - - Setting this OID to alwaysAllowTurnON (1) will always allow - the outlets on the corresponding phase to turn on. - - Setting this OID to restrictOnNearOverload (2) will not allow - outlets on the corresponding phase to turn on if the - rPDULoadConfigNearOverloadThreshold OID is exceeded. - - Setting this OID to restrictOnOverload (3) will not allow - outlets on the corresponding phase to turn on if the - rPDULoadConfigOverloadThreshold OID is exceeded." - ::= { rPDUOutletPhaseEntry 2 } - - --- the rPDUOutletControl group - -rPDUOutletControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF RPDUOutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of the individual outlets. - The number of entries is contained in the - rPDUOutletDevNumCntrlOutlets OID." - ::= { rPDUOutletControl 1 } - -rPDUOutletControlEntry OBJECT-TYPE - SYNTAX RPDUOutletControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet to control." - INDEX { rPDUOutletControlIndex} - ::= { rPDUOutletControlTable 1 } - -RPDUOutletControlEntry ::= - SEQUENCE { - rPDUOutletControlIndex INTEGER, - rPDUOutletControlOutletName DisplayString, - rPDUOutletControlOutletPhase INTEGER, - rPDUOutletControlOutletCommand INTEGER, - rPDUOutletControlOutletBank INTEGER - } - -rPDUOutletControlIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { rPDUOutletControlEntry 1 } - -rPDUOutletControlOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is dependent on device. - An error will be returned if the set request exceeds the max size. - This OID is provided for informational purposes only." - ::= { rPDUOutletControlEntry 2 } - -rPDUOutletControlOutletPhase OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3), - phase1-2 (4), - phase2-3 (5), - phase3-1 (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase/s associated with this outlet. - - For single phase devices, this object will always - return phase1(1). - - For 3-phase devices, this object will return phase1 (1), - phase2 (2), or phase3 (3) for outlets tied to a single - phase. For outlets tied to two phases, this object will - return phase1-2 (4) for phases 1 and 2, phase2-3 (5) for - phases 2 and 3, and phase3-1 (6) for phases 3 and 1." - ::= { rPDUOutletControlEntry 3 } - -rPDUOutletControlOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOn (1), - immediateOff (2), - immediateReboot (3), - delayedOn (4), - delayedOff (5), - delayedReboot (6), - cancelPendingCommand (7), - gracefulOff (8), - gracefulReboot (9) - - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOn (1) value will be returned. - If the outlet is off, the immediateOff (2) value will be - returned. - - - Setting this variable to immediateOn (1) will immediately turn - the outlet on. - - Setting this variable to immediateOff (2) will immediately turn - the outlet off. - - Setting this variable to immediateReboot (3) will immediately - reboot the outlet. - - Setting this variable to delayedOn (4) will turn the outlet on - after the rPDUOutletConfigPowerOnTime OID time has elapsed. - - Setting this variable to delayedOff (5) will turn the outlet off - after the rPDUOutletConfigPowerOffTime OID time has elapsed. - - Setting this variable to delayedReboot (6) will cause the - Switched Rack PDU to perform a delayedOff command, wait the - rPDUOutletConfigRebootDuration OID time, and then perform a - delayedOn command. - - Setting this variable to cancelPendingCommand (7) will cause any - pending command to this outlet to be canceled. - - Setting this variable to gracefulOff (8) will cause the - Switched Rack PDU to shut the outlet off after it waits the - servers graceful shutdown time and the outlets shutdown delay. - - Setting this variable to gracefulReboot (9) will cause the - Switched Rack PDU to shut the outlet off after it waits the - servers graceful shutdown time and the outlets shutdown delay. - Once the outlet is off, it will wait until the UPS reaches the - configured minimum return battery capacity, then the outlets - return delay before it turns the outlet back on." - - ::= { rPDUOutletControlEntry 4 } - -rPDUOutletControlOutletBank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank associated with this outlet." - ::= { rPDUOutletControlEntry 5 } - - --- the rPDUOutletConfig group - -rPDUOutletConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF RPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the rPDUOutletDevNumCntrlOutlets OID." - ::= { rPDUOutletConfig 1 } - -rPDUOutletConfigEntry OBJECT-TYPE - SYNTAX RPDUOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet to configure." - INDEX { rPDUOutletConfigIndex} - ::= { rPDUOutletConfigTable 1 } - -RPDUOutletConfigEntry ::= - SEQUENCE { - rPDUOutletConfigIndex INTEGER, - rPDUOutletConfigOutletName DisplayString, - rPDUOutletConfigOutletPhase INTEGER, - rPDUOutletConfigPowerOnTime INTEGER, - rPDUOutletConfigPowerOffTime INTEGER, - rPDUOutletConfigRebootDuration INTEGER, - rPDUOutletConfigOutletBank INTEGER - } - -rPDUOutletConfigIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { rPDUOutletConfigEntry 1 } - -rPDUOutletConfigOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is dependent on device. - An error will be returned if the set request exceeds the max size." - ::= { rPDUOutletConfigEntry 2 } - -rPDUOutletConfigOutletPhase OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3), - phase1-2 (4), - phase2-3 (5), - phase3-1 (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase/s associated with this outlet. - - For single phase devices, this object will always - return phase1(1). - - For 3-phase devices, this object will return phase1 (1), - phase2 (2), or phase3 (3) for outlets tied to a single - phase. For outlets tied to two phases, this object will - return phase1-2 (4) for phases 1 and 2, phase2-3 (5) for - phases 2 and 3, and phase3-1 (6) for phases 3 and 1." - ::= { rPDUOutletConfigEntry 3 } - -rPDUOutletConfigPowerOnTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering on at coldstart or when a command that requires - a turn-on delay is issued. - - Allowed values are: - - -1 - never power on. - 0 - power on immediately. - 1 to 300 - power on up to 300 seconds (5 minutes) after being - commanded." - ::= { rPDUOutletConfigEntry 4 } - -rPDUOutletConfigPowerOffTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The amount of time (in seconds) the outlet will delay - powering off when a command that requires - a turn-off delay is issued. - - Allowed values are: - - -1 - never power off. - 0 - power off immediately. - 1 to 300 - power off up to 300 seconds (5 minutes) after being - commanded." - ::= { rPDUOutletConfigEntry 5 } - -rPDUOutletConfigRebootDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "During a reboot sequence, power is turned off and then - back on. This OID defines the amount of time to wait, - in seconds, after turning the power off, at the start - of the sequence, before turning power back on, at the - end of the reboot sequence. - - Allowed range is any value between 5 and 60 seconds (1 minute)." - ::= { rPDUOutletConfigEntry 6 } - -rPDUOutletConfigOutletBank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank associated with this outlet." - ::= { rPDUOutletConfigEntry 7 } - - --- the rPDUOutletStatus group - -rPDUOutletStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF RPDUOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting of status of individual outlets. The number of - entries is contained in the rPDUOutletDevNumCntrlOutlets OID." - ::= { rPDUOutletStatus 1 } - -rPDUOutletStatusEntry OBJECT-TYPE - SYNTAX RPDUOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlet to gather status from." - INDEX { rPDUOutletStatusIndex} - ::= { rPDUOutletStatusTable 1 } - -RPDUOutletStatusEntry ::= - SEQUENCE { - rPDUOutletStatusIndex INTEGER, - rPDUOutletStatusOutletName DisplayString, - rPDUOutletStatusOutletPhase INTEGER, - rPDUOutletStatusOutletState INTEGER, - rPDUOutletStatusCommandPending INTEGER, - rPDUOutletStatusOutletBank INTEGER - } - -rPDUOutletStatusIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { rPDUOutletStatusEntry 1 } - -rPDUOutletStatusOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. Maximum size is dependent on device. - An error will be returned if the set request exceeds the max size. - This OID is provided for informational purposes only." - ::= { rPDUOutletStatusEntry 2 } - -rPDUOutletStatusOutletPhase OBJECT-TYPE - SYNTAX INTEGER { - phase1 (1), - phase2 (2), - phase3 (3), - phase1-2 (4), - phase2-3 (5), - phase3-1 (6) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The phase/s associated with this outlet. - - For single phase devices, this object will always - return phase1(1). - - For 3-phase devices, this object will return phase1 (1), - phase2 (2), or phase3 (3) for outlets tied to a single - phase. For outlets tied to two phases, this object will - return phase1-2 (4) for phases 1 and 2, phase2-3 (5) for - phases 2 and 3, and phase3-1 (6) for phases 3 and 1." - ::= { rPDUOutletStatusEntry 3 } - -rPDUOutletStatusOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletStatusOn (1), - outletStatusOff (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the outletStatusOn (1) value will be returned. - If the outlet is off, the outletStatusOff (2) value will be - returned. " - ::= { rPDUOutletStatusEntry 4 } - -rPDUOutletStatusCommandPending OBJECT-TYPE - SYNTAX INTEGER { - outletStatusCommandPending (1), - outletStatusNoCommandPending (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the command pending - state of the outlet. If a command is pending on the - outlet, the outletStatusCommandPending (1) value - will be returned. If there is not a command pending - on the outlet, the outletStatusNoCommandPending (2) - will be returned." - ::= { rPDUOutletStatusEntry 5 } - -rPDUOutletStatusOutletBank OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The bank associated with this outlet." - ::= { rPDUOutletStatusEntry 6 } - - --- the rPDUOutletBank group - -rPDUOutletBankTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletBankEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for management of outlets on a per bank basis." - ::= { rPDUOutletBank 1 } - -rPDUOutletBankEntry OBJECT-TYPE - SYNTAX OutletBankEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The bank to manage." - INDEX { rPDUOutletBankIndex} - ::= { rPDUOutletBankTable 1 } - -OutletBankEntry ::= - SEQUENCE { - rPDUOutletBankIndex INTEGER, - rPDUOutletBankOverloadRestriction INTEGER - } - -rPDUOutletBankIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the Switched Rack PDU bank entry." - ::= { rPDUOutletBankEntry 1 } - -rPDUOutletBankOverloadRestriction OBJECT-TYPE - SYNTAX INTEGER { - alwaysAllowTurnON (1), - restrictOnNearOverload (2), - restrictOnOverload (3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID controls the behavior of a Switched Rack PDU - bank when an overload condition is possible and - additional outlets are requested to be turned on. - - Setting this OID to alwaysAllowTurnON (1) will always allow - the outlets on the corresponding bank to turn on. - - Setting this OID to restrictOnNearOverload (2) will not allow - outlets on the corresponding bank to turn on if the - rPDULoadConfigNearOverloadThreshold OID is exceeded. - - Setting this OID to restrictOnOverload (3) will not allow - outlets on the corresponding bank to turn on if the - rPDULoadConfigOverloadThreshold OID is exceeded." - ::= { rPDUOutletBankEntry 2 } - --- the rPDUPowerSupplyDevice group - -rPDUPowerSupply1Status OBJECT-TYPE - SYNTAX INTEGER { - powerSupply1Ok (1), - powerSupply1Failed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return powerSupply1Ok(1) if power - supply 1 is functioning normally. If not functioning normally, - this OID will return powerSupply1Failed(2)." - ::= { rPDUPowerSupplyDevice 1 } - -rPDUPowerSupply2Status OBJECT-TYPE - SYNTAX INTEGER { - powerSupply2Ok (1), - powerSupply2Failed (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return powerSupply2Ok(1) if power - supply 2 is functioning normally. If not functioning normally, - this OID will return powerSupply2Failed(2)." - ::= { rPDUPowerSupplyDevice 2 } - - - --- the dm3IdentSystem group - -dm3IdentSysDescriptionTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC description records." - ::= { dm3IdentSystem 1 } - -dm3IdentSysDescriptionTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing description records of the powerplant. The number of - entries is contained in the dm3IdentSysDescriptionTableSize OID." - ::= { dm3IdentSystem 2 } - -dm3IdentSysDescriptionEntry OBJECT-TYPE - SYNTAX IdentSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The powerplant description record to reference." - INDEX { dm3IdentSysDescriptionIndex } - ::= { dm3IdentSysDescriptionTable 1 } - -IdentSysDescriptionEntry ::= - SEQUENCE { - dm3IdentSysDescriptionIndex INTEGER, - dm3IdentSysDescriptionText DisplayString - } - -dm3IdentSysDescriptionIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant description record." - ::= { dm3IdentSysDescriptionEntry 1 } - -dm3IdentSysDescriptionText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A 16 character text field describing the DC power plant device. - This field can be configured from the dm3ConfigSysDescriptionText OID." - ::= { dm3IdentSysDescriptionEntry 2 } - -dm3IdentSysModel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Model type of the DC power plant." - ::= { dm3IdentSystem 3 } - -dm3IdentSysCntrlRev OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Integer representation of the hardware revision of the Master Controller board." - ::= { dm3IdentSystem 4 } - -dm3IdentSysFWVersion OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Integer representation of the power plant Master Controller firmware revision." - ::= { dm3IdentSystem 5 } - --- the dm3ConfigSystem group - -dm3ConfigSysDescriptionTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC description records." - ::= { dm3ConfigSystem 1 } - -dm3ConfigSysDescriptionTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing description records of the powerplant. The number of - entries is contained in the dm3ConfigSysDescriptionTableSize OID." - ::= { dm3ConfigSystem 2 } - -dm3ConfigSysDescriptionEntry OBJECT-TYPE - SYNTAX ConfigSysDescriptionEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The powerplant description record to reference." - INDEX { dm3ConfigSysDescriptionIndex } - ::= { dm3ConfigSysDescriptionTable 1 } - -ConfigSysDescriptionEntry ::= - SEQUENCE { - dm3ConfigSysDescriptionIndex INTEGER, - dm3ConfigSysDescriptionText DisplayString - } - -dm3ConfigSysDescriptionIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant description record." - - ::= { dm3ConfigSysDescriptionEntry 1 } - -dm3ConfigSysDescriptionText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "16 character text field describing the DC power plant device." - - ::= { dm3ConfigSysDescriptionEntry 2 } - -dm3ConfigSysHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Ambient high temperature threshold. Temperature sensor located on Master - Controller board. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigSystem 3 } - -dm3ConfigSysHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the System High Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigSystem 4 } - -dm3ConfigSysLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Ambient low temperature threshold. Temperature sensor located on Master - Controller board. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigSystem 5 } - -dm3ConfigSysLowTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the System Low Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigSystem 6 } - -dm3ConfigSysHardwareTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the System Hardware Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigSystem 7 } - -dm3ConfigSysRemoteAccess OBJECT-TYPE - SYNTAX INTEGER { - accessEnabled (1), - accessDisabled (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - " - This OID is used to disable remote write access to the power plant. - Setting this OID to accessEnabled (1) will have no affect. - Setting this OID to accessDisabled (2) will disable the ability to - remotely configure the DC powerplant. - - Once remote access is disabled, it can only be restored from the front - panel of the DC power plant." - ::= { dm3ConfigSystem 8 } - - --- the dm3ConfigLVD group - -dm3ConfigLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs controllable - by this IP address." - ::= { dm3ConfigLVD 1 } - -dm3ConfigLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the LVDs. The number of - entries is contained in the dm3ConfigLVDTableSize OID." - ::= { dm3ConfigLVD 2 } - -dm3ConfigLVDEntry OBJECT-TYPE - SYNTAX ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to configure." - INDEX { dm3ConfigLVDIndex } - ::= { dm3ConfigLVDTable 1 } - -ConfigLVDEntry ::= - SEQUENCE { - dm3ConfigLVDIndex INTEGER, - dm3ConfigLVDName DisplayString, - dm3ConfigLVDEnable INTEGER, - dm3ConfigLVDTripThresh INTEGER, - dm3ConfigLVDResetThresh INTEGER, - dm3ConfigLVDOpenAlarm INTEGER, - dm3ConfigLVDHWAlarm INTEGER - } - -dm3ConfigLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dm3ConfigLVDEntry 1 } - -dm3ConfigLVDName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the LVD. The maximum value is 16 characters." - ::= { dm3ConfigLVDEntry 2 } - -dm3ConfigLVDEnable OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is used to control and indicate if the LVD is on or off. - Setting this OID to enabledYes (1) will enable (turn on) the LVD. - Setting this OID to enabledNo (2) will disable (turn off) the LVD." - ::= { dm3ConfigLVDEntry 3 } - -dm3ConfigLVDTripThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Trip threshold. If voltage exceeds threshold, the LVD will trip. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigLVDEntry 4 } - -dm3ConfigLVDResetThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Reset threshold. If voltage exceeds threshold, the LVD will reset. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigLVDEntry 5 } - -dm3ConfigLVDOpenAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the LVD Open Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigLVDEntry 6 } - -dm3ConfigLVDHWAlarm OBJECT-TYPE -SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the LVD Hardware Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - ::= { dm3ConfigLVDEntry 7 } - - --- the dm3ConfigBattery group - -dm3ConfigBattFloatVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Float Voltage. This setting controls the power plant voltage. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 1 } - -dm3ConfigBattMaxRecharge OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Maximum Recharge Rate. This setting controls the battery max - recharge rate. The value is based on C/20 for 240 AHr battery string. - - Values are represented in thousandths of Amps (mA). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 2 } - -dm3ConfigBattDischargeThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery discharge threshold. If battery output current exceeds threshold - a battery discharge alarm will occur. - - Values are represented in thousandths of Amps (mA). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 3 } - -dm3ConfigBattDischargeAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Discharge Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 4 } - -dm3ConfigBattHighVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery high voltage threshold. If system battery voltage exceeds threshold - a battery high voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 5 } - -dm3ConfigBattHighVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery High Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 6 } - -dm3ConfigBattLowVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery low voltage threshold. If system battery voltage is under threshold - a battery low voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 7 } - -dm3ConfigBattLowVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Low Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 8 } - -dm3ConfigBattHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery high temperature threshold. If system battery temperature exceeds threshold - a battery high temperature alarm will occur. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - - ::= { dm3ConfigBattery 9 } - -dm3ConfigBattHighTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery High Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 10 } - -dm3ConfigBattLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery low temperature threshold. If system battery temperature is under threshold - a battery low temperature alarm will occur. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - - ::= { dm3ConfigBattery 11 } - -dm3ConfigBattLowTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Low Temperature Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 12 } - -dm3ConfigBattAmpHour OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Amp-Hour Size. Units are thousandths of Amp hours (mAHr). - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 13 } - -dm3ConfigCompMethod OBJECT-TYPE - SYNTAX INTEGER { - tempcompOn (1), - tempcompOff (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is used to configure and get the state of the battery - temperature compensation. - - Setting this OID to tempcompOn (1) will enable/turn on the battery temperature compensation. - Setting this OID to tempcompOff (2) will disable/turn off the battery temperature compensation." - ::= { dm3ConfigBattery 14 } - -dm3ConfigCompTempCoeff OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Compensation Temperature Coefficient. (uV/degC/cell). - - Units are presented in microvolts. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 15 } - -dm3ConfigHighKneeTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "High Knee for temperature compensation: Compensation temperature coefficient - becomes 0mV/degC/cell. - - Values are represented in thousandths of degrees Celcius. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 16 } - -dm3ConfigLowKneeTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Low Knee for temperature compensation: Compensation temperature coefficient - becomes 0mV/degC/cell. - - Values are represented in thousandths of degrees Celcius. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigBattery 17 } - -dm3ConfigBattHwCurrentAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Current Hardware Alarm (indicating current is outside realistic - limits, or a possible measurement fault; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 18 } - -dm3ConfigBattHwTempAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Battery Temperature Hardware Alarm (indicating temperature is outside realistic - limits, or a possible measurement fault; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBattery 19 } - - --- the dm3ConfigRectThresh group -dm3ConfigRectHighVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier high voltage threshold. If rectifier voltage exceeds threshold - a rectifier high voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 1 } - - -dm3ConfigRectLowVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier low voltage threshold. If rectifier voltage is under threshold - a rectifier low voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 2 } - -dm3ConfigRectFailSafe OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier Fail Safe point. This OID represents the value sent to rectifier controllers - to use in the event of communications loss with the Master Controller or Master Controller - board failure. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 3 } - -dm3ConfigRectFailComm OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Rectifier Communication Fail timeout. This OID represents the time interval in which there is no - communication between the rectifier and the master controller at which the rectifier will reset - all its values to default. - - Values are represented in hundredths of Seconds. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigRectThresh 4 } - --- the dm3ConfigRectAlarms group - -dm3ConfigRectHighVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier High Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 1 } - -dm3ConfigRectLowVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Low Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 2 } - -dm3ConfigRectConfigAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This alarm is activated when a new rectifier is detected; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 3 } - -dm3ConfigRect1ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting indicates the action if ONE rectifier of a N+1 system has failed; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 4 } - -dm3ConfigRect2ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This setting indicates the action if TWO OR MORE rectifiers of a N+1 system have failed; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 5 } - -dm3ConfigRectDiagAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Controller Diagnostics Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 6 } - -dm3ConfigRectImbalanceAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Imbalance Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 7 } - -dm3ConfigRectCurrLimitAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Current Limit Alarm (indicating rectifier in the Current Limit state); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 8 } - -dm3ConfigRectStandbyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Standby Alarm (indicating output DC has been turned off); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 9 } - -dm3ConfigRectFanFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Fan Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 10 } - -dm3ConfigRectFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigRect1ofNAlarm OID - to be activated if ONE rectifier fails in an N+1 system. It causes the alarm specified in the - dm3ConfigRect2ofNAlarm OID to be activated if TWO OR MORE rectifiers fail in an N+1 system." - - ::= { dm3ConfigRectAlarms 11 } - -dm3ConfigRectHwVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Rectifier Hardware Voltage Alarm (indicating voltage outside realistic limits, - or a possible measurement fault); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigRectAlarms 12 } - - --- the dm3ConfigConvThresh group - -dm3ConfigConvHighVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter high voltage threshold. If converter voltage exceeds threshold - a converter high voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - - ::= { dm3ConfigConvThresh 1 } - -dm3ConfigConvLowVoltThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter low voltage threshold. If converter voltage exceeds threshold - a converter low voltage alarm will occur. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 2 } - -dm3ConfigConvFailSafe OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Fail Safe point. This OID represents the value sent to converter controllers - to use in the event of communications loss with the Master Controller or Master Controller - board failure. - - Values are represented in thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 3 } - -dm3ConfigConvSetPoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Set point. This OID represents the initial set point used in the - voltage control loop. - - Units are thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 4 } - -dm3ConfigConvFailMax OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Fail Maximum limit. This OID represents the value sent to the converter - controllers to define the maximum set point allowed. - - Units are thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 5 } - -dm3ConfigConvFailMin OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Fail Minimum limit. This OID represents the value sent to the converter - controllers to define the minimum set point allowed. - - Units are thousandths of Volts (mV). - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 6 } - -dm3ConfigConvFailComm OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Converter Communication Fail timeout. This OID represents the time interval in which there is no - communication between the converter and the master controller at which the converter will reset - all its values to default. - - Values are represented in hundredths of Seconds. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigConvThresh 7 } - --- the dm3ConfigConvAlarms group -dm3ConfigConvHighVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter High Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 1 } - -dm3ConfigConvLowVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Low Voltage Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 2 } - -dm3ConfigConvConfigAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Configuration Alarm (indicating a new converter has been detected); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 3 } - -dm3ConfigConv1ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter 1ofN Alarm (indicating action if ONE converter of a N+1 system has failed); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 4 } - -dm3ConfigConv2ofNAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter 2ofN Alarm (indicating action if TWO OR MORE converters of a N+1 system has failed); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigConvAlarms 5 } - -dm3ConfigConvDiagAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Diagnostics Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 6 } - -dm3ConfigConvImbalanceAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Imbalance Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 7 } - -dm3ConfigConvCurrLimitAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Current Limit Alarm (indicating the converter is in the Current Limit state); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 8 } - -dm3ConfigConvStandbyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Standby Alarm (indicating the converter is in the Standby state); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 9 } - -dm3ConfigConvFanFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Fan Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 10 } - -dm3ConfigConvFailAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Fail Alarm; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 11 } - -dm3ConfigConvHwVoltAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9), - alarmNofN (10) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "For the Converter Voltage Alarm (indicating voltage outside realistic limits, or a - possible measurement fault); - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - Setting this OID to alarmNofN (10) causes the alarm specified in the dm3ConfigConv1ofNAlarm OID - to be activated if ONE converter fails in an N+1 system. It causes the alarm specified in the - dm3ConfigConv2ofNAlarm OID to be activated if TWO OR MORE converters fail in an N+1 system." - - ::= { dm3ConfigConvAlarms 12 } - - --- the dm3ConfigOutputRelays group - -dm3ConfigOutRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant Output Relays controllable - by this IP address." - ::= { dm3ConfigOutputRelays 1 } - -dm3ConfigOutRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the Output Relays. The number of - entries is contained in the dm3ConfigOutRlyTableSize OID." - ::= { dm3ConfigOutputRelays 2 } - -dm3ConfigOutRlyEntry OBJECT-TYPE - SYNTAX ConfigOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relay to configure." - INDEX { dm3ConfigOutRlyIndex } - ::= { dm3ConfigOutRlyTable 1 } - -ConfigOutRlyEntry ::= - SEQUENCE { - dm3ConfigOutRlyIndex INTEGER, - dm3ConfigOutRlyName DisplayString, - dm3ConfigOutRlyDelay INTEGER, - dm3ConfigOutRlyAlarm INTEGER - } - -dm3ConfigOutRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant output relay." - ::= { dm3ConfigOutRlyEntry 1 } - -dm3ConfigOutRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the output relay. The maximum value is 16 characters." - ::= { dm3ConfigOutRlyEntry 2 } - -dm3ConfigOutRlyDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Output Relay Delay. This OID represents the time delay from the initiation of an - output relay action to when the output relay action does occur. If the alarm condition - disappears before the end of the delay, no action will occur. Delay for Major - and Minor alarms is not configurable and is always set to 0. - - Values are represented in hundredths of seconds. - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigOutRlyEntry 3 } - -dm3ConfigOutRlyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Output Relay Alarm. This setting indicates what action to perform in the event of - an output relay alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition. - - Relay Alarm for Major and Minor alarms is not configurable and is always set to - alarmMajor and alarmMinor respectively." - - ::= { dm3ConfigOutRlyEntry 4 } - - --- the dm3ConfigInputRelays group - -dm3ConfigInRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant Input Relays controllable - by this IP address." - ::= { dm3ConfigInputRelays 1 } - -dm3ConfigInRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the Input Relays. The number of - entries is contained in the dm3ConfigInRlyTableSize OID." - ::= { dm3ConfigInputRelays 2 } - -dm3ConfigInRlyEntry OBJECT-TYPE - SYNTAX ConfigInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input relay to configure." - INDEX { dm3ConfigInRlyIndex } - ::= { dm3ConfigInRlyTable 1 } - -ConfigInRlyEntry ::= - SEQUENCE { - dm3ConfigInRlyIndex INTEGER, - dm3ConfigInRlyName DisplayString, - dm3ConfigInRlyDelay INTEGER, - dm3ConfigInRlyAlarm INTEGER - } - -dm3ConfigInRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant input relay." - ::= { dm3ConfigInRlyEntry 1 } - -dm3ConfigInRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the input relay. The maximum value is 16 characters." - - ::= { dm3ConfigInRlyEntry 2 } - -dm3ConfigInRlyDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Input Relay Delay. This OID represents the time delay from the initiation of an - input relay action to when the input relay action does occur. If the alarm condition - disappears before the end of the delay, no action will occur. - - Values are represented in hundredths of seconds. - - Attempts to set the value above or below the acceptable range of the powerplant - will cause the value to be set at the high or low point of the range respectively." - ::= { dm3ConfigInRlyEntry 3 } - -dm3ConfigInRlyAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Input Relay Alarm. This setting indicates what action to perform in the event of - an input relay alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigInRlyEntry 4 } - --- the dm3ConfigBreakers group - -dm3ConfigBreakersTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant circuit breakers controllable - by this IP address." - ::= { dm3ConfigBreakers 1 } - -dm3ConfigBreakersTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the circuit breakers. The number of - entries is contained in the dm3ConfigBreakersTableSize OID." - ::= { dm3ConfigBreakers 2 } - -dm3ConfigBreakersEntry OBJECT-TYPE - SYNTAX ConfigBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The circuit breaker to configure." - INDEX { dm3ConfigBreakersIndex } - ::= { dm3ConfigBreakersTable 1 } - -ConfigBreakersEntry ::= - SEQUENCE { - dm3ConfigBreakersIndex INTEGER, - dm3ConfigBreakersName DisplayString, - dm3ConfigBreakersAlarm INTEGER - } - -dm3ConfigBreakersIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant circuit breaker." - ::= { dm3ConfigBreakersEntry 1 } - -dm3ConfigBreakersName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the circuit breaker. The maximum value is 16 characters." - ::= { dm3ConfigBreakersEntry 2 } - -dm3ConfigBreakersAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Circuit Breaker Alarm. This setting indicates what action to perform in the event of - a circuit breaker alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigBreakersEntry 3 } - --- the dm3ConfigFuses group - -dm3ConfigFusesTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant Fuses controllable - by this IP address." - ::= { dm3ConfigFuses 1 } - -dm3ConfigFusesTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the Fuses. The number of - entries is contained in the dm3ConfigFusesTableSize OID." - ::= { dm3ConfigFuses 2 } - -dm3ConfigFusesEntry OBJECT-TYPE - SYNTAX ConfigFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The fuse to configure." - INDEX { dm3ConfigFusesIndex } - ::= { dm3ConfigFusesTable 1 } - -ConfigFusesEntry ::= - SEQUENCE { - dm3ConfigFusesIndex INTEGER, - dm3ConfigFusesName DisplayString, - dm3ConfigFusesAlarm INTEGER - } - -dm3ConfigFusesIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant fuse." - ::= { dm3ConfigFusesEntry 1 } - -dm3ConfigFusesName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the fuse. The maximum value is 16 characters." - ::= { dm3ConfigFusesEntry 2 } - -dm3ConfigFusesAlarm OBJECT-TYPE - SYNTAX INTEGER { - alarmIgnore (1), - alarmRelay1 (2), - alarmRelay2 (3), - alarmRelay3 (4), - alarmRelay4 (5), - alarmRelay5 (6), - alarmRelay6 (7), - alarmMinor (8), - alarmMajor (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Fuses Alarm. This setting indicates what action to perform in the event of - a Fuse alarm condition; - Setting this OID to alarmIgnore (1) results in the alarm condition being ignored. - Setting this OID to alarmRelay1 (2) causes relay 1 to be activated for an - alarm condition. - Setting this OID to alarmRelay2 (3) causes relay 2 to be activated for an - alarm condition. - Setting this OID to alarmRelay3 (4) causes relay 3 to be activated for an - alarm condition. - Setting this OID to alarmRelay4 (5) causes relay 4 to be activated for an - alarm condition. - Setting this OID to alarmRelay5 (6) causes relay 5 to be activated for an - alarm condition. - Setting this OID to alarmRelay6 (7) causes relay 6 to be activated for an - alarm condition. - Setting this OID to alarmMinor (8) causes the Minor relay to be activated for an - alarm condition. - Setting this OID to alarmMajor (9) causes the Major relay to be activated for an - alarm condition." - - ::= { dm3ConfigFusesEntry 3 } - --- the dm3StatusSystem group - -dm3StatusSystemTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System temperature based on sensor on Master Controller PCB. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dm3StatusSystem 1 } - -dm3StatusSystemStart OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Time stamp at DC powerplant initialization. - The time is represented as MMM,DD,YYYY,HH:MM:SS." - ::= { dm3StatusSystem 2 } - -dm3StatusSysRemoteAccess OBJECT-TYPE - SYNTAX INTEGER { - accessEnabled (1), - accessDisabled (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Remote Access indicator - This setting indicates if configuration (write) access to the powerplant is enabled or - disabled at the powerplant level. - This value will be accessEnabled (1) if remote configuration is enabled, and - accessDisabled (2) if remote configuration is disabled." - ::= { dm3StatusSystem 3 } - -dm3StatusSysSecurityLevel OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable shows the current active security access level of controller. This - can only be changed directly from the front panel." - ::= { dm3StatusSystem 4 } - -dm3StatusSysTempSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System temperature sanity indicator. Indicates if the system temperature is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates temperature is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusSystem 5 } - -dm3StatusSysAlarmState OBJECT-TYPE - SYNTAX INTEGER{ - alarmMinor (1), - alarmMajor (2), - alarmBoth (3), - alarmNone (4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System Alarm State. Reflects the alarm status of the overall DC system. - If a minor alarm is present, the value will be alarmMinor(1). - If a major alarm is present, the value will be alarmMajor(2). - If both minor and a major alarm is present, the value will be alarmBoth(3). - If no alarm is present, the value will be alarmNone(4)." - ::= { dm3StatusSystem 6 } - -dm3StatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the DC system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { dm3StatusSystem 7 } - - --- the dm3StatusAlarms group - -dm3StatusAlarmsTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant alarms viewable - by this IP address." - ::= { dm3StatusAlarms 1 } - -dm3StatusAlarmsTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing system alarms. The number of - entries is contained in the dm3StatusAlarmsTableSize OID." - ::= { dm3StatusAlarms 2 } - -dm3StatusAlarmsEntry OBJECT-TYPE - SYNTAX StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm to display." - INDEX { dm3StatusAlarmsIndex } - ::= { dm3StatusAlarmsTable 1 } - -StatusAlarmsEntry ::= - SEQUENCE { - dm3StatusAlarmsIndex INTEGER, - dm3StatusAlarmsText DisplayString - } - -dm3StatusAlarmsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the system alarm." - ::= { dm3StatusAlarmsEntry 1 } - -dm3StatusAlarmsText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The 16 character text describing the active alarm condition." - ::= { dm3StatusAlarmsEntry 2 } - --- the dm3StatusBattery group - -dm3StatusBattCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Current: This OID shows the battery current in thousandths of Amps (mA)." - ::= { dm3StatusBattery 1 } - -dm3StatusBattTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Temperature: - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dm3StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dm3StatusBattery 2 } - -dm3StatusBattCurrentSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery current sanity indicator. Indicates if the battery current is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates current is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusBattery 3 } - -dm3StatusBattTempSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery temperature sanity indicator. Indicates if the battery temperature is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates temperature is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusBattery 4 } - --- the dm3StatusOEM group - -dm3StatusOEMrectOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier offset value in thousandths of Volts (mV)." - ::= { dm3StatusOEM 1 } - -dm3StatusOEMrectGain OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier gain value in thousandths of Volts (mV/V)." - ::= { dm3StatusOEM 2 } - -dm3StatusOEMconvOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter offset value in thousandths of Volts (mV)." - ::= { dm3StatusOEM 3 } - -dm3StatusOEMconvGain OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter gain value in thousandths of Volts (mV/V)." - ::= { dm3StatusOEM 4 } - -dm3StatusOEMshuntOffset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the shunt offset value in thousandths of Amps (mA)." - ::= { dm3StatusOEM 5 } - -dm3StatusOEMshuntGain OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the shunt gain value in thousandths of Amps (mA/A)." - ::= { dm3StatusOEM 6 } - --- the dm3StatusLVD group - -dm3StatusLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs viewable - by this IP address." - ::= { dm3StatusLVD 1 } - -dm3StatusLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the LVDs. The number of - entries is contained in the dm3StatusLVDTableSize OID." - ::= { dm3StatusLVD 2 } - -dm3StatusLVDEntry OBJECT-TYPE - SYNTAX StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to gather status from." - INDEX { dm3StatusLVDIndex } - ::= { dm3StatusLVDTable 1 } - -StatusLVDEntry ::= - SEQUENCE { - dm3StatusLVDIndex INTEGER, - dm3StatusLVDName DisplayString, - dm3StatusLVDState INTEGER, - dm3StatusLVDHwFault INTEGER - } - -dm3StatusLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dm3StatusLVDEntry 1 } - -dm3StatusLVDName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the LVD. The maximum size is - 16 characters. The name is set by using the - dm3ConfigLVDName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusLVDEntry 2 } - -dm3StatusLVDState OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpened (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the LVD is closed. - statusOpened (2) will be returned if the LVD is opened." - ::= { dm3StatusLVDEntry 3 } - -dm3StatusLVDHwFault OBJECT-TYPE - SYNTAX INTEGER { - statusFault (1), - statusNofault (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusFault (1) if the LVD is faulted. - statusNofault (2) will be returned if the LVD is not faulted." - ::= { dm3StatusLVDEntry 4 } - --- the dm3StatusRectifier group - -dm3StatusRectTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant rectifiers viewable - by this IP address." - ::= { dm3StatusRectifier 1 } - -dm3StatusRectTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the rectifiers. The number of - entries is contained in the dm3StatusRectTableSize OID." - ::= { dm3StatusRectifier 2 } - -dm3StatusRectEntry OBJECT-TYPE - SYNTAX StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The rectifier to gather status from." - INDEX { dm3StatusRectIndex } - ::= { dm3StatusRectTable 1 } - -StatusRectEntry ::= - SEQUENCE { - dm3StatusRectIndex INTEGER, - dm3StatusRectID INTEGER, - dm3StatusRectDesc DisplayString, - dm3StatusRectCurrent INTEGER, - dm3StatusRectCurrentLimit INTEGER, - dm3StatusRectStandby INTEGER, - dm3StatusRectFanFail INTEGER, - dm3StatusRectFail INTEGER, - dm3StatusRectDevType INTEGER, - dm3StatusRectPhyAddr INTEGER, - dm3StatusRectCfg INTEGER, - dm3StatusRectPcbRev INTEGER, - dm3StatusRectFwVer INTEGER, - dm3StatusRectPresent INTEGER, - dm3StatusRectDiagPass INTEGER, - dm3StatusRectState INTEGER - } - -dm3StatusRectIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant rectifier." - ::= { dm3StatusRectEntry 1 } - -dm3StatusRectID OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier ID. This enumerates the number of the rectifier within - a group of rectifiers." - ::= { dm3StatusRectEntry 2 } - -dm3StatusRectDesc OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the 16-character rectifier description." - ::= { dm3StatusRectEntry 3 } - -dm3StatusRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier current in thousandths of Amps (mA)." - ::= { dm3StatusRectEntry 4 } - -dm3StatusRectCurrentLimit OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is in the Current Limit state. - statusFalse (2) will be returned if the rectifier is not in the Current Limit state." - ::= { dm3StatusRectEntry 5 } - -dm3StatusRectStandby OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is in the Standby state. - statusFalse (2) will be returned if the rectifier is not in the Standby state." - ::= { dm3StatusRectEntry 6 } - -dm3StatusRectFanFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier Fan has failed. - statusFalse (2) will be returned if the rectifier Fan has not failed." - ::= { dm3StatusRectEntry 7 } - -dm3StatusRectFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier has failed. - statusFalse (2) will be returned if the rectifier has not failed." - ::= { dm3StatusRectEntry 8 } - -dm3StatusRectDevType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device type." - ::= { dm3StatusRectEntry 9 } - -dm3StatusRectPhyAddr OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier physical address (the address on the bus)." - ::= { dm3StatusRectEntry 10 } - -dm3StatusRectCfg OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is present after - power-up or set-configuration. - statusFalse (2) will be returned if the rectifier is not configured." - ::= { dm3StatusRectEntry 11 } - -dm3StatusRectPcbRev OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device PCB serial number." - ::= { dm3StatusRectEntry 12 } - -dm3StatusRectFwVer OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device firmware revision." - ::= { dm3StatusRectEntry 13 } - -dm3StatusRectPresent OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is present. - statusFalse (2) will be returned if the rectifier is not present." - ::= { dm3StatusRectEntry 14 } - -dm3StatusRectDiagPass OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier diagnostics have passed. - statusFalse (2) will be returned if the rectifier diagnostics have not passed." - ::= { dm3StatusRectEntry 15 } - -dm3StatusRectState OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device state as defined by the device status register." - ::= { dm3StatusRectEntry 16 } - -dm3StatusSysRectVoltSanity OBJECT-TYPE - SYNTAX INTEGER { - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Rectifier voltage sanity indicator. Indicates if the rectifier voltage is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates voltage is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusRectifier 3 } - -dm3StatusSysRectAvailable OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier is available. - statusFalse (2) will be returned if the rectifier is not available." - ::= { dm3StatusRectifier 4 } - -dm3StatusSysRectType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the type of rectifier the system has. There can only be a single type of - rectifier in the power plant" - ::= { dm3StatusRectifier 5 } - -dm3StatusSysRectVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level rectifier voltage in thousandths of Volts (mV)." - ::= { dm3StatusRectifier 6 } - -dm3StatusSysRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level rectifier current in thousandths of Amps (mA)." - ::= { dm3StatusRectifier 7 } - - --- the dm3StatusConverter group - -dm3StatusConvTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant converters viewable - by this IP address." - ::= { dm3StatusConverter 1 } - -dm3StatusConvTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusConvEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the converters. The number of - entries is contained in the dm3StatusConvTableSize OID." - ::= { dm3StatusConverter 2 } - -dm3StatusConvEntry OBJECT-TYPE - SYNTAX StatusConvEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The converter to gather status from." - INDEX { dm3StatusConvIndex } - ::= { dm3StatusConvTable 1 } - -StatusConvEntry ::= - SEQUENCE { - dm3StatusConvIndex INTEGER, - dm3StatusConvID INTEGER, - dm3StatusConvDesc DisplayString, - dm3StatusConvCurrent INTEGER, - dm3StatusConvCurrentLimit INTEGER, - dm3StatusConvStandby INTEGER, - dm3StatusConvFanFail INTEGER, - dm3StatusConvFail INTEGER, - dm3StatusConvDevType INTEGER, - dm3StatusConvPhyAddr INTEGER, - dm3StatusConvCfg INTEGER, - dm3StatusConvPcbRev INTEGER, - dm3StatusConvFwVer INTEGER, - dm3StatusConvPresent INTEGER, - dm3StatusConvDiagPass INTEGER, - dm3StatusConvState INTEGER - } - -dm3StatusConvIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant converter." - ::= { dm3StatusConvEntry 1 } - -dm3StatusConvID OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter ID. This enumerates the number of the converter within - a group of converters." - ::= { dm3StatusConvEntry 2 } - -dm3StatusConvDesc OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the 16 character converter description." - ::= { dm3StatusConvEntry 3 } - -dm3StatusConvCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter current in thousandths of Amps (mA)." - ::= { dm3StatusConvEntry 4 } - -dm3StatusConvCurrentLimit OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is in the Current Limit state. - statusFalse (2) will be returned if the converter is not in the Current Limit state." - ::= { dm3StatusConvEntry 5 } - -dm3StatusConvStandby OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is in the Standby state. - statusFalse (2) will be returned if the converter is not in the Standby state." - ::= { dm3StatusConvEntry 6 } - -dm3StatusConvFanFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter Fan has failed. - statusFalse (2) will be returned if the converter Fan has not failed." - ::= { dm3StatusConvEntry 7 } - -dm3StatusConvFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter has failed. - statusFalse (2) will be returned if the converter has not failed." - ::= { dm3StatusConvEntry 8 } - -dm3StatusConvDevType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter device type." - ::= { dm3StatusConvEntry 9 } - -dm3StatusConvPhyAddr OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter physical address (the address on the bus)." - ::= { dm3StatusConvEntry 10 } - -dm3StatusConvCfg OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is present after - power-up or set-configuration. - statusFalse (2) will be returned if the converter is not configured." - ::= { dm3StatusConvEntry 11 } - -dm3StatusConvPcbRev OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter device PCB serial number." - ::= { dm3StatusConvEntry 12 } - -dm3StatusConvFwVer OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter device firmware version." - ::= { dm3StatusConvEntry 13 } - -dm3StatusConvPresent OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is present. - statusFalse (2) will be returned if the converter is not present." - ::= { dm3StatusConvEntry 14 } - -dm3StatusConvDiagPass OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter diagnostics have passed. - statusFalse (2) will be returned if the converter diagnostics have not passed." - ::= { dm3StatusConvEntry 15 } - -dm3StatusConvState OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter state as defined by the device status register." - ::= { dm3StatusConvEntry 16 } - -dm3StatusSysConvVoltSanity OBJECT-TYPE - SYNTAX INTEGER{ - saneYES (1), - saneNO (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Converter voltage sanity indicator. Indicates if the converter voltage is - reasonable. Reasonable is defined based on powerplant type. A value of saneYes (1) - indicates voltage is reasonable, a value of saneNo (2) indicates it is not." - ::= { dm3StatusConverter 3 } - -dm3StatusSysConvAvailable OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the converter is available. - statusFalse (2) will be returned if the converter is not available." - ::= { dm3StatusConverter 4 } - -dm3StatusSysConvType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the converter type." - ::= { dm3StatusConverter 5 } - -dm3StatusSysConvVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level converter voltage in thousandths of volts (mV)." - ::= { dm3StatusConverter 6 } - -dm3StatusSysConvCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the system level converter current in thousandths of Amps (mA)." - ::= { dm3StatusConverter 7 } - --- the dm3StatusOutputRelays group - -dm3StatusOutRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant output relays viewable - by this IP address." - ::= { dm3StatusOutputRelays 1 } - -dm3StatusOutRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the output relays. The number of - entries is contained in the dm3StatusOutRlyTableSize OID." - ::= { dm3StatusOutputRelays 2 } - -dm3StatusOutRlyEntry OBJECT-TYPE - SYNTAX StatusOutRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relay to gather status from." - INDEX { dm3StatusOutRlyIndex } - ::= { dm3StatusOutRlyTable 1 } - -StatusOutRlyEntry ::= - SEQUENCE { - dm3StatusOutRlyIndex INTEGER, - dm3StatusOutRlyName DisplayString, - dm3StatusOutRlyStatus INTEGER - } - -dm3StatusOutRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant output relay." - ::= { dm3StatusOutRlyEntry 1 } - -dm3StatusOutRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the output relay. The maximum size is - 16 characters. The name is set by using the - dm3ConfigOutRlyName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusOutRlyEntry 2 } - -dm3StatusOutRlyStatus OBJECT-TYPE - SYNTAX INTEGER { - statusOn (1), - statusOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusOn (1) if the output relay is enabled/on. - statusOff (2) will be returned if the output relay is disabled/off." - ::= { dm3StatusOutRlyEntry 3 } - - --- the dm3StatusInputRelays group - -dm3StatusInRlyTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant input relays viewable - by this IP address." - ::= { dm3StatusInputRelays 1 } - -dm3StatusInRlyTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the input relays. The number of - entries is contained in the dm3StatusInRlyTableSize OID." - ::= { dm3StatusInputRelays 2 } - - -dm3StatusInRlyEntry OBJECT-TYPE - SYNTAX StatusInRlyEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input relays to gather status from." - INDEX { dm3StatusInRlyIndex } - ::= { dm3StatusInRlyTable 1 } - -StatusInRlyEntry ::= - SEQUENCE { - dm3StatusInRlyIndex INTEGER, - dm3StatusInRlyName DisplayString, - dm3StatusInRlyStatus INTEGER - } - -dm3StatusInRlyIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant input relay." - ::= { dm3StatusInRlyEntry 1 } - -dm3StatusInRlyName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the input relay. The maximum size is - 16 characters. The name is set by using the - dm3ConfigInRlyName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusInRlyEntry 2 } - -dm3StatusInRlyStatus OBJECT-TYPE - SYNTAX INTEGER { - statusOn (1), - statusOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusOn (1) if the input relay is enabled/on. - statusOff (2) will be returned if the input relay is disabled/off." - ::= { dm3StatusInRlyEntry 3 } - --- the dm3StatusBreakers group - -dm3StatusBreakersTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant circuit breakers viewable - by this IP address." - ::= { dm3StatusBreakers 1 } - -dm3StatusBreakersTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the circuit breakers. The number of - entries is contained in the dm3StatusBreakersTableSize OID." - ::= { dm3StatusBreakers 2 } - -dm3StatusBreakersEntry OBJECT-TYPE - SYNTAX StatusBreakersEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The circuit breaker to gather status from." - INDEX { dm3StatusBreakersIndex } - ::= { dm3StatusBreakersTable 1 } - -StatusBreakersEntry ::= - SEQUENCE { - dm3StatusBreakersIndex INTEGER, - dm3StatusBreakersName DisplayString, - dm3StatusBreakersStatus INTEGER - } - -dm3StatusBreakersIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant circuit breaker." - ::= { dm3StatusBreakersEntry 1 } - -dm3StatusBreakersName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the circuit breaker. The maximum size is - 16 characters. The name is set by using the - dm3ConfigBreakersName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusBreakersEntry 2 } - -dm3StatusBreakersStatus OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpen (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the circuit breaker is closed. - statusOpen (2) will be returned if the circuit breaker is open." - ::= { dm3StatusBreakersEntry 3 } - --- the dm3StatusFuses group - -dm3StatusFusesTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant fuses controllable - by this IP address." - ::= { dm3StatusFuses 1 } - -dm3StatusFusesTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for viewing status of the fuses. The number of - entries is contained in the dm3StatusFusesTableSize OID." - ::= { dm3StatusFuses 2 } - -dm3StatusFusesEntry OBJECT-TYPE - SYNTAX StatusFusesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The fuse to gather status from." - INDEX { dm3StatusFusesIndex } - ::= { dm3StatusFusesTable 1 } - -StatusFusesEntry ::= - SEQUENCE { - dm3StatusFusesIndex INTEGER, - dm3StatusFusesName DisplayString, - dm3StatusFusesStatus INTEGER - } - -dm3StatusFusesIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant fuse." - ::= { dm3StatusFusesEntry 1 } - -dm3StatusFusesName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the fuse. The maximum size is - 16 characters. The name is set by using the - dm3ConfigFuseName OID. - This OID is provided for informational purposes only." - ::= { dm3StatusFusesEntry 2 } - -dm3StatusFusesStatus OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpen (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the fuse is closed. - statusOpen (2) will be returned if the fuse is open." - ::= { dm3StatusFusesEntry 3 } - --- the atsIdent group - -atsIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware version of the Automatic Transfer Switch. - This value is set at the factory." - ::= { atsIdent 1 } - -atsIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string identifying the Automatic Transfer Switch - firmware version." - ::= { atsIdent 2 } - -atsIdentFirmwareDate OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date of release for this Automatic Transfer Switch - firmware version. " - ::= { atsIdent 3 } - -atsIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the Automatic Transfer Switch was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { atsIdent 4 } - -atsIdentModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string identifying the model number of the Automatic Transfer Switch. - This value is set at the factory." - ::= { atsIdent 5 } - -atsIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A string identifying the serial number of - the Automatic Transfer Switch. This value is set at the factory." - ::= { atsIdent 6 } - -atsIdentNominalLineVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "RMS Utility Voltage measured in V." - ::= { atsIdent 7 } - -atsIdentNominalLineFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Utility Power Frequency measured in Hz." - ::= { atsIdent 8 } - --- the atsCalibration group - --- Input Voltage Calibration Factor table - - atsCalibrationNumInputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of inputs to this device." - ::= { atsCalibrationInput 1 } - - atsCalibrationNumInputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of phases per input for this device." - ::= { atsCalibrationInput 2 } - - atsCalibrationInputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSCalibrationInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The number of phases per input line to this device." - ::= { atsCalibrationInput 3 } - - atsCalibrationInputPhaseEntry OBJECT-TYPE - SYNTAX ATSCalibrationInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing calibration information applicable to a - particular input phase." - INDEX { atsCalibrationInputTableIndex, atsCalibrationInputPhaseTableIndex } - ::= { atsCalibrationInputTable 1 } - - ATSCalibrationInputPhaseEntry ::= SEQUENCE { - atsCalibrationInputTableIndex INTEGER, - atsCalibrationInputPhaseTableIndex INTEGER, - atsLineVoltageCalibrationFactor INTEGER - } - - atsCalibrationInputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { atsCalibrationInputPhaseEntry 1 } - - atsCalibrationInputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input phase identifier." - ::= { atsCalibrationInputPhaseEntry 2 } - - atsLineVoltageCalibrationFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Line Voltage Calibration factor. - This value is set at the factory." - ::= { atsCalibrationInputPhaseEntry 3 } - --- Power Supply Voltage Calibration table - - atsCalibrationPowerSupplyVoltages OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of power supply voltages supported by this device. - This variable indicates the number of rows in the - atsCalibrationPowerSupplyTable. There is one entry per - supported voltage: 24V, 12V and 5V" - ::= { atsCalibrationPowerSupply 1 } - - atsCalibrationPowerSupplyVoltageTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSCalibrationPowerSupplyVoltageEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of Power Supply table entries." - ::= { atsCalibrationPowerSupply 2 } - - atsCalibrationPowerSupplyVoltageEntry OBJECT-TYPE - SYNTAX ATSCalibrationPowerSupplyVoltageEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular Power Supply Voltage." - INDEX { atsCalibrationPowerSupplyVoltageTableIndex } - ::= { atsCalibrationPowerSupplyVoltageTable 1 } - - ATSCalibrationPowerSupplyVoltageEntry ::= SEQUENCE { - atsCalibrationPowerSupplyVoltageTableIndex INTEGER, - atsCalibrationPowerSupplyVoltage INTEGER, - atsPowerSupplyVoltageCalibrationFactor INTEGER - } - - atsCalibrationPowerSupplyVoltageTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The power supply voltage identifier. - Three power supply voltages are supported by the ATS: - 24V , 12V and 5V . - The value of this index indicates the power supply voltage: - 1 = 24V - 2 = 12V - 3 = 5V" - ::= { atsCalibrationPowerSupplyVoltageEntry 1 } - - atsCalibrationPowerSupplyVoltage OBJECT-TYPE - SYNTAX INTEGER { - powerSupply24V(1), - powerSupply12V(2), - powerSupply(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This value describes the power supply voltage." - ::= { atsCalibrationPowerSupplyVoltageEntry 2 } - - atsPowerSupplyVoltageCalibrationFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The Line Voltage Calibration factor. - This value is set at the factory." - ::= { atsCalibrationPowerSupplyVoltageEntry 3 } - --- Output Current Calibration table - - atsCalibrationNumOutputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output lines from this device. - This variable indicates the number of rows in the - atsCalibrationOutputTable." - ::= { atsCalibrationOutput 1 } - - atsCalibrationNumOutputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output phases utilized in this - device." - ::= { atsCalibrationOutput 2 } - - atsCalibrationOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSCalibrationOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries." - ::= { atsCalibrationOutput 3 } - - atsCalibrationOutputEntry OBJECT-TYPE - SYNTAX ATSCalibrationOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output." - INDEX { atsCalibrationOutputTableIndex, atsCalibrationOutputPhasesTableIndex } - ::= { atsCalibrationOutputTable 1 } - - ATSCalibrationOutputEntry ::= SEQUENCE { - atsCalibrationOutputTableIndex INTEGER, - atsCalibrationOutputPhasesTableIndex INTEGER, - atsOutputCurrentCalibrationFactor INTEGER - } - - atsCalibrationOutputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { atsCalibrationOutputEntry 1 } - - atsCalibrationOutputPhasesTableIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3), - neutral(4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each calibration factor for each - output phase utilized in this device and one for neutral. " - ::= { atsCalibrationOutputEntry 2 } - - atsOutputCurrentCalibrationFactor OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output current calibration factor measured in Amps." - ::= { atsCalibrationOutputEntry 3 } - - --- the atsControl group - -atsControlResetATS OBJECT-TYPE - SYNTAX INTEGER { - none(1), - reset(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable will cause the Automatic Transfer Switch to - perform a power-on reset." - ::= { atsControl 1 } - -atsControlClearAllAlarms OBJECT-TYPE - SYNTAX INTEGER { - none(1), - clear(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable will clear all alarms in the Automatic Transfer Switch." - ::= { atsControl 2 } - --- the atsConfig group - -atsConfigProductName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A configurable character string." - ::= { atsConfig 1 } - -atsConfigPreferredSource OBJECT-TYPE - SYNTAX INTEGER { - sourceA(1), - sourceB(2), - none(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This variable returns the preferred source of power when both sources are OK." - ::= { atsConfig 2 } - -atsConfigFrontPanelLockout OBJECT-TYPE - SYNTAX INTEGER { - disableFrontPanel(1), - enableFrontPanel(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Setting this variable to disableFrontPanel(1) will disallow source - preference configuration of the Automatic Transfer Switch via the - Front Panel. Once this value is set, it can only be re-enabled through - the serial interface of the ATS. - When this variable is set to enableFrontPanel(2), source preference - configuration of the Automatic Transfer Switch via the Front Panel - is allowed." - ::= { atsConfig 3 } - -atsConfigVoltageSensitivity OBJECT-TYPE - SYNTAX INTEGER { - high(1), - low(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This variable defines the sensitivity to changes in voltage: - high(1) for best protection, low(2) for frequent small line - voltage changes." - ::= { atsConfig 4 } - -atsConfigTransferVoltageRange OBJECT-TYPE - SYNTAX INTEGER { - wide(1), - medium(2), - narrow(3) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This variable defines the range of acceptable voltage from a power source. - If the voltage measured from the selected input source is not within this - range, the Automatic Transfer Switch will switch over (transfer) to the - alternate power source." - - ::= { atsConfig 5 } - -atsConfigCurrentLimit OBJECT-TYPE - SYNTAX INTEGER (0..20) - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The threshold (in Amps) at which an Over Current Alarm will be generated." - - ::= { atsConfig 6 } - - -atsConfigResetValues OBJECT-TYPE - SYNTAX INTEGER { - none(1), - reset(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Resets the ATS configuration to its default values." - - ::= { atsConfig 7 } - --- the atsStatus group - - atsStatusCommStatus OBJECT-TYPE - SYNTAX INTEGER { - atsNeverDiscovered(1), - atsCommEstablished(2), - atsCommLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current communication status - of the Automatic Transfer Switch. " - ::= { atsStatusDeviceStatus 1 } - - atsStatusSelectedSource OBJECT-TYPE - SYNTAX INTEGER { - sourceA(1), - sourceB(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current source of power. " - ::= { atsStatusDeviceStatus 2 } - - atsStatusRedundancyState OBJECT-TYPE - SYNTAX INTEGER { - atsRedundancyLost(1), - atsFullyRedundant(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current redundancy state of the ATS. - atsRedundancyLost(1) indicates that the ATS is unable to - switch over to the alternate power source if the current source fails. - atsFullyRedundant(2) indicates that the ATS will switch over to - the alternate power source if the current source fails." - ::= { atsStatusDeviceStatus 3 } - - atsStatusOverCurrentState OBJECT-TYPE - SYNTAX INTEGER { - atsOverCurrent(1), - atsCurrentOK(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the output current state of the ATS. - atsOverCurrent(1) indicates that the ATS has exceeded the output - current threshold and will not allow a switch over to the alternate power - source if the current source fails. - atsCurrentOK(2) indicates that the output current is below the - output current threshold." - ::= { atsStatusDeviceStatus 4 } - - atsStatus5VPowerSupply OBJECT-TYPE - SYNTAX INTEGER { - atsPowerSupplyFailure(1), - atsPowerSupplyOK(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current state of the ATS 5-volt power supply. - atsPowerSupplyFailure(1) indicates the 5-volt power supply has failed - and that the ATS serial port Configuration Menu is not accessible . - atsPowerSupplyOK(2) indicates that the ATS 5-volt power supply - is operating within tolerance." - ::= { atsStatusDeviceStatus 5 } - - atsStatus24VPowerSupply OBJECT-TYPE - SYNTAX INTEGER { - atsPowerSupplyFailure(1), - atsPowerSupplyOK(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This variable returns the current state of the ATS 24-volt power supply. - atsPowerSupplyFailure(1) indicates the 24-volt power supply has failed - and the ATS is unable to switch over to the alternate power source if - the current source fails. - atsPowerSupplyOK(2) indicates that the ATS 24-volt power supply - is operating within tolerance." - ::= { atsStatusDeviceStatus 6 } - - atsStatusResetMaxMinValues OBJECT-TYPE - SYNTAX INTEGER { - none(1), - reset(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Resets the maximum and minimum ATS values: - atsInputMaxVoltage, atsInputMinVoltage, - atsInputMaxCurrent, atsInputMinCurrent, - atsInputMaxPower, atsInputMinPower, - atsOutputMaxCurrent, atsOutputMinCurrent, - atsOutputMaxLoad, atsOutputMinLoad, - atsOutputMaxPercentLoad, atsOutputMinPercentLoad, - atsOutputMaxPower, atsOutputMinPower, - atsOutputMaxPercentPower, atsOutputMinPercentPower. - These variables represent the maximum and minimum ATS values - since the last time they were read or reset by this OID. - Values unsupported by this ATS will return (-1)." - ::= { atsStatusResetValues 1 } - --- --- Input Group --- - --- Number of Inputs - - atsNumInputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input feeds to this device. - This variable indicates the number of rows in the - input table." - ::= { atsStatusInput 1 } - --- Input Table - - atsInputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the value of atsNumInputs." - ::= { atsStatusInput 2 } - - atsInputEntry OBJECT-TYPE - SYNTAX ATSPhaseInputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input." - INDEX { atsInputTableIndex } - ::= { atsInputTable 1 } - - ATSPhaseInputEntry ::= SEQUENCE { - atsInputTableIndex INTEGER, - atsNumInputPhases INTEGER, - atsInputVoltageOrientation INTEGER, - atsInputFrequency INTEGER, - atsInputType INTEGER, - atsInputName DisplayString - } - - atsInputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { atsInputEntry 1 } - - atsNumInputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of input phases utilized in this - device. The sum of all the atsNumInputPhases - variable indicates the number of rows in the - input phase table." - ::= { atsInputEntry 2 } - - atsInputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage orientation: - 1: unknown for this Source - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { atsInputEntry 3 } - - atsInputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input frequency in Hertz, or -1 if it's unsupported - by this Source." - ::= { atsInputEntry 4 } - - atsInputType OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - main(2), - bypass(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input type." - ::= { atsInputEntry 5 } - - atsInputName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A name given to a particular input." - ::= { atsInputEntry 6 } - --- Input Phase Table - - atsInputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of input table entries. The number of entries - is given by the sum of the atsNumInputPhases." - ::= { atsStatusInput 3 } - - atsInputPhaseEntry OBJECT-TYPE - SYNTAX ATSPhaseInputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular input phase." - INDEX { atsInputPhaseTableIndex, atsInputPhaseIndex } - ::= { atsInputPhaseTable 1 } - - ATSPhaseInputPhaseEntry ::= SEQUENCE { - atsInputPhaseTableIndex INTEGER, - atsInputPhaseIndex INTEGER, - atsInputVoltage INTEGER, - atsInputMaxVoltage INTEGER, - atsInputMinVoltage INTEGER, - atsInputCurrent INTEGER, - atsInputMaxCurrent INTEGER, - atsInputMinCurrent INTEGER, - atsInputPower INTEGER, - atsInputMaxPower INTEGER, - atsInputMinPower INTEGER - } - - atsInputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input identifier." - ::= { atsInputPhaseEntry 1 } - - atsInputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input phase identifier." - ::= { atsInputPhaseEntry 2 } - - atsInputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input voltage in VAC, or -1 if it's unsupported - by this Source." - ::= { atsInputPhaseEntry 3 } - - atsInputMaxVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input voltage in VAC measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 4 } - - atsInputMinVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input voltage in VAC measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 5 } - - atsInputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input current in amperes, or -1 if it's - unsupported by this Source." - ::= { atsInputPhaseEntry 6 } - - atsInputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input current in amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 7 } - - atsInputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input current in amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 8 } - - atsInputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The input power in Watts, or -1 if it's unsupported - by this Source." - ::= { atsInputPhaseEntry 9 } - - atsInputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum input power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 10 } - - atsInputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum input power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsInputPhaseEntry 11 } - - -- - -- The Output group. - -- - - -- Number of Outputs - - atsNumOutputs OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output feeds to this device. - This variable indicates the number of rows in the - output table." - ::= { atsStatusOutput 1 } - - -- Output Table - - atsOutputTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of entries - is given by the value of atsOutputNumPhases." - ::= { atsStatusOutput 2 } - - atsOutputEntry OBJECT-TYPE - SYNTAX ATSPhaseOutputEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output." - INDEX { atsOutputTableIndex } - ::= { atsOutputTable 1 } - - ATSPhaseOutputEntry ::= SEQUENCE { - atsOutputTableIndex INTEGER, - atsNumOutputPhases INTEGER, - atsOutputVoltageOrientation INTEGER, - atsOutputFrequency INTEGER - } - - atsOutputTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { atsOutputEntry 1 } - - atsNumOutputPhases OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output phases utilized in this - device. The sum of all the atsNumOutputPhases - variable indicates the number of rows in the - output phase table." - ::= { atsOutputEntry 2 } - - atsOutputVoltageOrientation OBJECT-TYPE - SYNTAX INTEGER { - unknown(1), - singlePhase(2), - splitPhase(3), - threePhasePhaseToNeutral(4), - threePhasePhaseToPhase(5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage orientation: - 1: unknown for this ATS - 2: singlePhase - phase 1 voltage is between Phase 1 - and Neutral. - 3: splitPhase - phase 1 voltage is between Phase 1 and - Neutral; phase 2 voltage is between Phase 2 and Neutral; - phase 3 voltage is between Phase 1 and Phase2. - 4: threePhasePhaseToNeutral - phase 1 voltage is between - Phase 1 and Neutral; phase 2 voltage is between Phase 2 - and Neutral; phase 3 voltage is between Phase3 and - Neutral. - 5: threePhasePhaseToPhase - phase 1 voltage is between - Phase 1 and Phase 2; phase 2 voltage is between Phase 2 - and Phase 3; phase 3 voltage is between Phase 3 and - Phase 1." - ::= { atsOutputEntry 3 } - - atsOutputFrequency OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output frequency in Hertz, or -1 if it's - unsupported by this ATS." - ::= { atsOutputEntry 4 } - - -- Output Phase Table - - atsOutputPhaseTable OBJECT-TYPE - SYNTAX SEQUENCE OF ATSPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output table entries. The number of - entries is given by the sum of the atsNumOutputPhases." - ::= { atsStatusOutput 3 } - - atsOutputPhaseEntry OBJECT-TYPE - SYNTAX ATSPhaseOutputPhaseEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "An entry containing information applicable to a - particular output phase." - INDEX { atsOutputPhaseTableIndex, atsOutputPhaseIndex } - ::= { atsOutputPhaseTable 1 } - - ATSPhaseOutputPhaseEntry ::= SEQUENCE { - atsOutputPhaseTableIndex INTEGER, - atsOutputPhaseIndex INTEGER, - atsOutputVoltage INTEGER, - atsOutputCurrent INTEGER, - atsOutputMaxCurrent INTEGER, - atsOutputMinCurrent INTEGER, - atsOutputLoad INTEGER, - atsOutputMaxLoad INTEGER, - atsOutputMinLoad INTEGER, - atsOutputPercentLoad INTEGER, - atsOutputMaxPercentLoad INTEGER, - atsOutputMinPercentLoad INTEGER, - atsOutputPower INTEGER, - atsOutputMaxPower INTEGER, - atsOutputMinPower INTEGER, - atsOutputPercentPower INTEGER, - atsOutputMaxPercentPower INTEGER, - atsOutputMinPercentPower INTEGER - } - - atsOutputPhaseTableIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output identifier." - ::= { atsOutputPhaseEntry 1 } - - atsOutputPhaseIndex OBJECT-TYPE - SYNTAX INTEGER{ - phase1(1), - phase2(2), - phase3(3), - neutral(4) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Description of each output phase utilized in - this device and one for neutral. " - ::= { atsOutputPhaseEntry 2 } - - atsOutputVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output voltage in VAC, or -1 if it's unsupported - by this ATS." - ::= { atsOutputPhaseEntry 3 } - - atsOutputCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output current in 0.1 amperes drawn - by the load on the ATS, or -1 if it's unsupported - by this ATS." - ::= { atsOutputPhaseEntry 4 } - - atsOutputMaxCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output current in 0.1 amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 5 } - - atsOutputMinCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output current in 0.1 amperes measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 6 } - - atsOutputLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output load in VA, or -1 if it's unsupported - by this ATS." - ::= { atsOutputPhaseEntry 7 } - - atsOutputMaxLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output load in VA measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 8 } - - atsOutputMinLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output load in VA measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 9 } - - atsOutputPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the ATS load capacity in VA at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this ATS." - ::= { atsOutputPhaseEntry 10 } - - atsOutputMaxPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the ATS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 11 } - - atsOutputMinPercentLoad OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum percentage of the ATS load capacity in - VA measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 12 } - - atsOutputPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The output power in Watts, or -1 if it's - unsupported by this ATS." - ::= { atsOutputPhaseEntry 13 } - - atsOutputMaxPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum output power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 14 } - - atsOutputMinPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum output power in Watts measured - since the last time this variable was read - or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 15 } - - atsOutputPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The percentage of the ATSpower capacity in Watts at - redundancy @ (n + x) presently being used on this - output phase, or -1 if it's unsupported by this ATS." - ::= { atsOutputPhaseEntry 16 } - - atsOutputMaxPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The maximum percentage of the ATSpower capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 17 } - - atsOutputMinPercentPower OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The minimum percentage of the ATSpower capacity - in Watts measured at redundancy @ (n + x) presently - being used on this output phase since the last time - this variable was read or reset (atsStatusResetMaxMinValues). - Returns (-1) if unsupported." - ::= { atsOutputPhaseEntry 18 } - --- the dcmim2IdentSystem group - -dcmim2IdentSysFWVersion OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Integer representation of the power plant Master Controller firmware revision." - ::= { dcmim2IdentSystem 1 } - - --- the dcmim2ControlSystem group - -dcmim2ControlRunFunctBatteryTest OBJECT-TYPE - SYNTAX INTEGER { - battTestOff (1), - battTestOn (2) -} - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this OID will return the battery functional test state. If - the test is off, the battTestOff (1) value will be returned. - If the test is on, the battTestOn (2) value will be - returned. - - Setting this OID to battTestOff (1) will turn the battery functional test off. - Setting this OID to battTestOn (2) will turn the battery functional test on." - - ::= { dcmim2ControlSystem 1 } - -dcmim2ControlRunCapacityBatteryTest OBJECT-TYPE - SYNTAX INTEGER { - battTestOff (1), - battTestOn (2) -} - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this OID will return the battery capacity test state. If - the test is off, the battTestOff (1) value will be returned. - If the test is on, the battTestOn (2) value will be - returned. - - Setting this OID to battTestOff (1) will turn the battery capacity test off. - Setting this OID to battTestOn (2) will turn the battery capacity test on." - - ::= { dcmim2ControlSystem 2 } - - --- the dcmim2ConfigSystem group - -dcmim2ConfigSysHighTempTrip OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Trip level (threshold) at which System High Temp alarm condition is created. - Range 28 to 100 (degC). - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - - ::= { dcmim2ConfigSystem 1 } - -dcmim2ConfigSysHighTempReset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Level at which System High Temp alarm condition is reset (cleared). - Range 25 to (upper temp - 3) (degC). - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dcmim2ConfigSystem 2 } - -dcmim2ConfigSysLowTempTrip OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Trip level (threshold) at which System Low Temp alarm condition is created. - Range -100 to 10 (degC). - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dcmim2ConfigSystem 3 } - -dcmim2ConfigSysLowTempReset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Level at which System Low Temp alarm condition is reset (cleared). - Range (lower temp + 3) to 13 (degC). - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - - ::= { dcmim2ConfigSystem 4 } - --- the dcmim2ConfigBattery group - -dcmim2ConfigBattFloatVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Float Voltage defined at 25 degrees Celsius. - - Values are represented in thousandths of Volts (mV)." - - ::= { dcmim2ConfigBattery 1 } - -dcmim2ConfigBattMaxRecharge OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery Maximum Recharge Rate. This is the maximum current used - during battery charging. - - Values are represented in thousandths of Amps (mA)." - - ::= { dcmim2ConfigBattery 2 } - -dcmim2ConfigBattMfgCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Battery capacity (Amp-Hour Size) as specified by the battery manufacturer. - - Values are represented in thousandths of Amp hours (mAHr)." - - ::= { dcmim2ConfigBattery 3 } - -dcmim2ConfigBattType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Type of battery in the powerplant - - Valid values range from 0 to 254." - - ::= { dcmim2ConfigBattery 4 } - -dcmim2ConfigBattFunctTestDuration OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Duration of the battery functional test. - - Values are represented in thousandths of seconds (mSecs)." - - ::= { dcmim2ConfigBattery 5 } - -dcmim2ConfigBattFunctTestThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold the battery voltage of the system must remain above - in order to pass the battery functional test. - - Values are represented in thousandths of Volts (mV)." - - ::= { dcmim2ConfigBattery 6 } - -dcmim2ConfigBattCapacityTestPercent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Threshold for good battery capacity test results. - - Values range from 0 to 100 percent." - - ::= { dcmim2ConfigBattery 7 } - -dcmim2ConfigBattCapacityTestEndThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Safeguard voltage at which battery capacity test will end - if there is a battery problem. - - Values are represented in thousandths of Volts (mV)." - - ::= { dcmim2ConfigBattery 8 } - -dcmim2ConfigBattCapacityTestCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Constant current value used during battery capacity testing. - - Values are represented in thousandths of Amps (mA)." - - ::= { dcmim2ConfigBattery 9 } - - --- the dcmim2ConfigLVD group - -dcmim2ConfigLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs controllable - by this IP address." - ::= { dcmim2ConfigLVD 1 } - -dcmim2ConfigLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the LVDs. The number of - entries is contained in the dcmim2ConfigLVDTableSize OID." - ::= { dcmim2ConfigLVD 2 } - -dcmim2ConfigLVDEntry OBJECT-TYPE - SYNTAX DC2ConfigLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to configure." - INDEX { dcmim2ConfigLVDIndex } - ::= { dcmim2ConfigLVDTable 1 } - -DC2ConfigLVDEntry ::= - SEQUENCE { - dcmim2ConfigLVDIndex INTEGER, - dcmim2ConfigLVDTrip INTEGER, - dcmim2ConfigLVDReset INTEGER, - dcmim2ConfigLVDState INTEGER - } - -dcmim2ConfigLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dcmim2ConfigLVDEntry 1 } - -dcmim2ConfigLVDTrip OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Trip threshold. System bus voltage at which LVD will trip (open) - during a battery backup operation. - - Values are represented in thousandths of Volts (mV)." - ::= { dcmim2ConfigLVDEntry 2 } - -dcmim2ConfigLVDReset OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "LVD Reset threshold. System bus voltage at which LVD will reset (close) - after AC power has been restored. - - Values are represented in thousandths of Volts (mV)." - ::= { dcmim2ConfigLVDEntry 3 } - -dcmim2ConfigLVDState OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpened (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the LVD is closed. - statusOpened (2) will be returned if the LVD is opened." - ::= { dcmim2ConfigLVDEntry 4 } - - --- the dcmim2StatusSystem group - -dcmim2StatusSysRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System (Total Rectifier) current in thousandths of Amps (mA)." - ::= { dcmim2StatusSystem 1 } - -dcmim2StatusSysLoadCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Load current in thousandths of Amps (mA)." - ::= { dcmim2StatusSystem 2 } - -dcmim2StatusSysBusVoltage OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System bus voltage in thousandths of Volts (mV)." - ::= { dcmim2StatusSystem 3 } - -dcmim2StatusSysAmbientTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "System temperature based on sensor on Master Controller PCB. - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - ::= { dcmim2StatusSystem 4 } - -dcmim2StatusSysUpTime OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Length of time since the DC Powerplant controller has been powered up." - ::= { dcmim2StatusSystem 5 } - -dcmim2StatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the DC system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { dcmim2StatusSystem 6 } - - --- the dcmim2StatusRectifier group - -dcmim2StatusRectTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant rectifiers viewable - by this IP address." - ::= { dcmim2StatusRectifier 1 } - -dcmim2StatusRectTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing settings of the rectifiers. The number of - entries is contained in the dcmim2StatusRectTableSize OID." - ::= { dcmim2StatusRectifier 2 } - -dcmim2StatusRectEntry OBJECT-TYPE - SYNTAX DC2StatusRectEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The rectifier to gather status from." - INDEX { dcmim2StatusRectIndex } - ::= { dcmim2StatusRectTable 1 } - -DC2StatusRectEntry ::= - SEQUENCE { - dcmim2StatusRectIndex INTEGER, - dcmim2StatusRectDevType INTEGER, - dcmim2StatusRectID INTEGER, - dcmim2StatusRectPhyAddr INTEGER, - dcmim2StatusRectFail INTEGER, - dcmim2StatusRectCurrent INTEGER - } - -dcmim2StatusRectIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant rectifier." - ::= { dcmim2StatusRectEntry 1 } - -dcmim2StatusRectDevType OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier device type." - ::= { dcmim2StatusRectEntry 2 } - -dcmim2StatusRectID OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier ID. This enumerates the number of the rectifier within - a group of rectifiers." - ::= { dcmim2StatusRectEntry 3 } - -dcmim2StatusRectPhyAddr OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the rectifier physical address (the address on the bus)." - ::= { dcmim2StatusRectEntry 4 } - -dcmim2StatusRectFail OBJECT-TYPE - SYNTAX INTEGER { - statusTrue (1), - statusFalse (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusTrue (1) if the rectifier has failed. - statusFalse (2) will be returned if the rectifier has not failed." - ::= { dcmim2StatusRectEntry 5 } - -dcmim2StatusRectCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID shows the individual rectifier current in thousandths of Amps (mA)." - ::= { dcmim2StatusRectEntry 6 } - - --- the dcmim2StatusBattery group - -dcmim2StatusBattFloatVolt OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Float Voltage represented in thousandths of Volts (mV)." - ::= { dcmim2StatusBattery 1 } - -dcmim2StatusBattCurrent OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Current: This OID shows the battery current in thousandths of Amps (mA)." - ::= { dcmim2StatusBattery 2 } - -dcmim2StatusBattTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery Temperature: - - Values are represented in thousandths of a degree. - Units are displayed in the scale shown in - the 'dcmim2StatusSysTempUnits' OID (Celsius or Fahrenheit)." - ::= { dcmim2StatusBattery 3 } - -dcmim2StatusBattMfgCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery capacity (Amp-Hour Size) as specified by the battery manufacturer. - Values are represented in thousandths of Amp hours (mAHr)." - ::= { dcmim2StatusBattery 4 } - -dcmim2StatusBattTestCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Battery capacity (Amp-Hour Size) as determined by the battery capacity test. - Values are represented in thousandths of Amp hours (mAHr)." - ::= { dcmim2StatusBattery 5 } - -dcmim2StatusBattFunctTestResult OBJECT-TYPE - SYNTAX INTEGER{ - functTestNotPerformed (1), - functTestInProcess (2), - functTestInterrupted (3), - functTestPass (4), - functTestFail (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Results of the last battery functional test that was run." - ::= { dcmim2StatusBattery 6 } - -dcmim2StatusBattCapacityTestResult OBJECT-TYPE - SYNTAX INTEGER{ - capacityTestNotPerformed (1), - capacityTestInProcess (2), - capacityTestInterrupted (3), - capacityTestPass (4), - capacityTestFail (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Results of the last battery capacity test that was run." - ::= { dcmim2StatusBattery 7 } - - --- the dcmim2StatusLVD group - -dcmim2StatusLVDTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant LVDs accessible - by this IP address." - ::= { dcmim2StatusLVD 1 } - -dcmim2StatusLVDTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing the LVDs. The number of - entries is contained in the dcmim2StatusLVDTableSize OID." - ::= { dcmim2StatusLVD 2 } - -dcmim2StatusLVDEntry OBJECT-TYPE - SYNTAX DC2StatusLVDEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The LVD to access." - INDEX { dcmim2StatusLVDIndex } - ::= { dcmim2StatusLVDTable 1 } - -DC2StatusLVDEntry ::= - SEQUENCE { - dcmim2StatusLVDIndex INTEGER, - dcmim2StatusLVDState INTEGER - } - -dcmim2StatusLVDIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the DC powerplant LVD." - ::= { dcmim2StatusLVDEntry 1 } - -dcmim2StatusLVDState OBJECT-TYPE - SYNTAX INTEGER { - statusClosed (1), - statusOpened (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this OID will return statusClosed (1) if the LVD is closed. - statusOpened (2) will be returned if the LVD is opened." - ::= { dcmim2StatusLVDEntry 2 } - - --- the dcmim2StatusAlarms group - -dcmim2StatusAlarmsTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of DC powerplant alarms viewable - by this IP address." - ::= { dcmim2StatusAlarms 1 } - -dcmim2StatusAlarmsTable OBJECT-TYPE - SYNTAX SEQUENCE OF DC2StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for accessing system alarms. The number of - entries is contained in the dcmim2StatusAlarmsTableSize OID." - ::= { dcmim2StatusAlarms 2 } - -dcmim2StatusAlarmsEntry OBJECT-TYPE - SYNTAX DC2StatusAlarmsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm to display." - INDEX { dcmim2StatusAlarmsIndex } - ::= { dcmim2StatusAlarmsTable 1 } - -DC2StatusAlarmsEntry ::= - SEQUENCE { - dcmim2StatusAlarmsIndex INTEGER, - dcmim2StatusAlarmsText DisplayString - } - -dcmim2StatusAlarmsIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the system alarm." - ::= { dcmim2StatusAlarmsEntry 1 } - -dcmim2StatusAlarmsText OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The 16 character text describing the active alarm condition." - ::= { dcmim2StatusAlarmsEntry 2 } - --- External Environmental Monitor - -emIdentFirmwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the Environmental Monitor." - ::= { emIdent 1 } - -emConfigProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of temperature and humidity probes available." - ::= { emConfig 1 } - -emConfigProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their configurations." - ::= { emConfig 2 } - -emConfigProbesEntry OBJECT-TYPE - SYNTAX EmConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor probe configurations." - INDEX { emConfigProbeNumber } - ::= { emConfigProbesTable 1 } - -EmConfigProbesEntry ::= - SEQUENCE { - emConfigProbeNumber - INTEGER, - emConfigProbeName - DisplayString, - emConfigProbeHighTempThreshold - INTEGER, - emConfigProbeLowTempThreshold - INTEGER, - emConfigProbeTempUnits - INTEGER, - emConfigProbeHighHumidThreshold - INTEGER, - emConfigProbeLowHumidThreshold - INTEGER, - emConfigProbeHighTempEnable - INTEGER, - emConfigProbeLowTempEnable - INTEGER, - emConfigProbeHighHumidEnable - INTEGER, - emConfigProbeLowHumidEnable - INTEGER - } - -emConfigProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index into an Environmental Monitor probe entry." - ::= { emConfigProbesEntry 1 } - -emConfigProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name of the probe set by the user, - possibly denoting its location or purpose." - ::= { emConfigProbesEntry 2 } - -emConfigProbeHighTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm threshold for the probe. - Units are displayed in the scale selected in - the 'emConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { emConfigProbesEntry 3 } - -emConfigProbeLowTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm threshold for the probe. - Units are displayed in the scale selected in - the 'emConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { emConfigProbesEntry 4 } - -emConfigProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { emConfigProbesEntry 5 } - -emConfigProbeHighHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm threshold for the probe in - percent relative humidity." - ::= { emConfigProbesEntry 6 } - -emConfigProbeLowHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm threshold for the probe in - percent relative humidity." - ::= { emConfigProbesEntry 7 } - -emConfigProbeHighTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 8 } - -emConfigProbeLowTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 9 } - -emConfigProbeHighHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 10 } - -emConfigProbeLowHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { emConfigProbesEntry 11 } - -emConfigContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the Environmental - Monitor." - ::= { emConfig 3 } - -emConfigContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their configurations." - ::= { emConfig 4 } - -emConfigContactsEntry OBJECT-TYPE - SYNTAX EmConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor contact configurations." - INDEX { emConfigContactNumber } - ::= { emConfigContactsTable 1 } - -EmConfigContactsEntry ::= - SEQUENCE { - emConfigContactNumber - INTEGER, - emConfigContactName - DisplayString, - emConfigContactEnable - INTEGER - } - -emConfigContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an Environmental Monitor contact." - ::= { emConfigContactsEntry 1 } - -emConfigContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name for an Environmental Monitor - contact set by the user, possibly denoting its - location or purpose." - ::= { emConfigContactsEntry 2 } - -emConfigContactEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An Environmental Monitor contact alarm enable/disable. - No alarm will be generated if the contact is disabled(1). - An alarm will be generated if the contact is enabled(2) - and the contact has been faulted." - ::= { emConfigContactsEntry 3 } - -emStatusCommStatus OBJECT-TYPE - SYNTAX INTEGER { - noComm(1), - comm(2), - commLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The communication status between the agent - and the Environmental Monitor. - - noComm(1), Communication has never been established. - comm(2), Communication has been established. - commLost(3), Communication was established, but was lost." - ::= { emStatus 1 } - -emStatusProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of available probes on the Environmental - Monitor." - ::= { emStatus 2 } - -emStatusProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their status." - ::= { emStatus 3 } - -emStatusProbesEntry OBJECT-TYPE - SYNTAX EmStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the probe." - INDEX { emStatusProbeNumber } - ::= { emStatusProbesTable 1 } - -EmStatusProbesEntry ::= - SEQUENCE { - emStatusProbeNumber - INTEGER, - emStatusProbeName - DisplayString, - emStatusProbeStatus - INTEGER, - emStatusProbeCurrentTemp - INTEGER, - emStatusProbeTempUnits - INTEGER, - emStatusProbeCurrentHumid - INTEGER, - emStatusProbeHighTempViolation - INTEGER, - emStatusProbeLowTempViolation - INTEGER, - emStatusProbeHighHumidViolation - INTEGER, - emStatusProbeLowHumidViolation - INTEGER - } - -emStatusProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the probe." - ::= { emStatusProbesEntry 1 } - -emStatusProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the probe set by the user, - possibly denoting its location or purpose." - ::= { emStatusProbesEntry 2 } - -emStatusProbeStatus OBJECT-TYPE - SYNTAX INTEGER { - disconnected(1), - connected(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The connected status of the probe, either - disconnected(1) or connected(2)." - ::= { emStatusProbesEntry 3 } - -emStatusProbeCurrentTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current temperature reading from the probe displayed - in the units shown in the 'emStatusProbeTempUnits' OID - (Celsius or Fahrenheit)." - ::= { emStatusProbesEntry 4 } - -emStatusProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { emStatusProbesEntry 5 } - -emStatusProbeCurrentHumid OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current humidity reading from the probe in - percent relative humidity." - ::= { emStatusProbesEntry 6 } - -emStatusProbeHighTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a highTempViolation(2) - if the current temperature reading shown in the - 'emStatusProbeCurrentTemp' OID is greater than or equal to - the high temperature threshold value, the - 'emConfigProbeHighTempThreshold' OID, and the value of the - 'emConfigProbeHighTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'emConfigProbeHighTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { emStatusProbesEntry 7 } - -emStatusProbeLowTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a lowTempViolation(2) - if the current temperature reading shown in the - 'emStatusProbeCurrentTemp' OID is less than or equal to - the low temperature threshold value, the - 'emConfigProbeLowTempThreshold' OID, and the value of the - 'emConfigProbeLowTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'emConfigProbeLowTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { emStatusProbesEntry 8 } - -emStatusProbeHighHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high humidity violation status of the probe humidity - reading. This OID will show a highTempViolation(2) - if the current humidity reading shown in the - 'emStatusProbeCurrentHumid' OID is greater than or equal to - the high humidity threshold value, the - 'emConfigProbeHighHumidThreshold' OID, and the value of the - 'emConfigProbeHighHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'emConfigProbeHighHumidEnable' OID is - disabled, this OID will show disabled(3)" - ::= { emStatusProbesEntry 9 } - -emStatusProbeLowHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The low humidity violation status of the probe humidity - reading. This OID will show a lowTempViolation(2) - if the current humidity reading shown in the - 'emStatusProbeCurrentHumid' OID is less than or equal to - the low humidity threshold value, the - 'emConfigProbeLowHumidThreshold' OID, and the value of the - 'emConfigProbeLowHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'emConfigProbeLowHumidEnable' OID is - disabled, this OID will show disabled(3)." - ::= { emStatusProbesEntry 10 } - -emStatusContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported by the - Environmental Monitor." - ::= { emStatus 4 } - -emStatusContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF EmStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their status." - ::= { emStatus 5 } - -emStatusContactsEntry OBJECT-TYPE - SYNTAX EmStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the contact." - INDEX { emStatusContactNumber } - ::= { emStatusContactsTable 1 } - -EmStatusContactsEntry ::= - SEQUENCE { - emStatusContactNumber - INTEGER, - emStatusContactName - DisplayString, - emStatusContactStatus - INTEGER - } - -emStatusContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Environmental Monitor contact." - ::= { emStatusContactsEntry 1 } - -emStatusContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the Environmental Monitor contact - set by the user, possibly denoting its location or purpose." - ::= { emStatusContactsEntry 2 } - -emStatusContactStatus OBJECT-TYPE - SYNTAX INTEGER { - noFault(1), - fault(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Environmental Monitor contact. The status - will show noFault(1) if the contact is in the normal state - and the 'emConfigContactEnable' OID is enabled. The status will - show a fault(2) if the contact is faulted and the - 'emContactEnable' OID is enabled. If the 'emConfigContactEnable' - OID is disabled, the status will show disabled(3)." - ::= { emStatusContactsEntry 3 } - --- Integrated Environmental Monitor (IEM) - -iemIdentHardwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the Integrated Environmental - Monitor." - ::= { iemIdent 1 } - -iemConfigProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of temperature and humidity probes available." - ::= { iemConfig 1 } - -iemConfigProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their configurations." - ::= { iemConfig 2 } - -iemConfigProbesEntry OBJECT-TYPE - SYNTAX IemConfigProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor probe configurations." - INDEX { iemConfigProbeNumber } - ::= { iemConfigProbesTable 1 } - -IemConfigProbesEntry ::= - SEQUENCE { - iemConfigProbeNumber - INTEGER, - iemConfigProbeName - DisplayString, - iemConfigProbeHighTempThreshold - INTEGER, - iemConfigProbeLowTempThreshold - INTEGER, - iemConfigProbeTempUnits - INTEGER, - iemConfigProbeHighHumidThreshold - INTEGER, - iemConfigProbeLowHumidThreshold - INTEGER, - iemConfigProbeHighTempEnable - INTEGER, - iemConfigProbeLowTempEnable - INTEGER, - iemConfigProbeHighHumidEnable - INTEGER, - iemConfigProbeLowHumidEnable - INTEGER - } - -iemConfigProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to a Environmental Monitor probe entry." - ::= { iemConfigProbesEntry 1 } - -iemConfigProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name for the probe set by the user, - possibly denoting its location or purpose." - ::= { iemConfigProbesEntry 2 } - -iemConfigProbeHighTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm threshold for the probe. - Units are displayed in the scale selected in the - 'iemConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { iemConfigProbesEntry 3 } - -iemConfigProbeLowTempThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm threshold for the probe. - Units are displayed in the scale selected in the - 'iemConfigProbeTempUnits' OID (Celsius or Fahrenheit)." - ::= { iemConfigProbesEntry 4 } - -iemConfigProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { iemConfigProbesEntry 5 } - -iemConfigProbeHighHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm threshold for the probe in - percent relative humidity." - ::= { iemConfigProbesEntry 6 } - -iemConfigProbeLowHumidThreshold OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm threshold for the probe in - percent relative humidity." - ::= { iemConfigProbesEntry 7 } - -iemConfigProbeHighTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 8 } - -iemConfigProbeLowTempEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low temperature alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 9 } - -iemConfigProbeHighHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The high humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 10 } - -iemConfigProbeLowHumidEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The low humidity alarm enable/disable for the - probe. No alarm will be generated if this value - is set to disabled(1). The alarm will be - generated if this value is set to enabled(2) and - the threshold has been violated." - ::= { iemConfigProbesEntry 11 } - -iemConfigContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts available on the Environmental - Monitor." - ::= { iemConfig 3 } - -iemConfigContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their configurations." - ::= { iemConfig 4 } - -iemConfigContactsEntry OBJECT-TYPE - SYNTAX IemConfigContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The Environmental Monitor contact configurations." - INDEX { iemConfigContactNumber } - ::= { iemConfigContactsTable 1 } - -IemConfigContactsEntry ::= - SEQUENCE { - iemConfigContactNumber - INTEGER, - iemConfigContactName - DisplayString, - iemConfigContactEnable - INTEGER - } - -iemConfigContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of an Environmental Monitor contact." - ::= { iemConfigContactsEntry 1 } - -iemConfigContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "A descriptive name for the Environmental Monitor contact - set by the user, possibly denoting its location or purpose." - ::= { iemConfigContactsEntry 2 } - -iemConfigContactEnable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "An Environmental Monitor contact alarm enable/disable." - ::= { iemConfigContactsEntry 3 } - - -iemStatusProbesNumProbes OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of available probes on the Environmental - Monitor." - ::= { iemStatus 1 } - -iemStatusProbesTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of probes supported by the Environmental Monitor - and their status." - ::= { iemStatus 2 } - -iemStatusProbesEntry OBJECT-TYPE - SYNTAX IemStatusProbesEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the probe." - INDEX { iemStatusProbeNumber } - ::= { iemStatusProbesTable 1 } - -IemStatusProbesEntry ::= - SEQUENCE { - iemStatusProbeNumber - INTEGER, - iemStatusProbeName - DisplayString, - iemStatusProbeStatus - INTEGER, - iemStatusProbeCurrentTemp - INTEGER, - iemStatusProbeTempUnits - INTEGER, - iemStatusProbeCurrentHumid - INTEGER, - iemStatusProbeHighTempViolation - INTEGER, - iemStatusProbeLowTempViolation - INTEGER, - iemStatusProbeHighHumidViolation - INTEGER, - iemStatusProbeLowHumidViolation - INTEGER - } - -iemStatusProbeNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the probe." - ::= { iemStatusProbesEntry 1 } - -iemStatusProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the probe set by the user, - denoting its location or purpose." - ::= { iemStatusProbesEntry 2 } - -iemStatusProbeStatus OBJECT-TYPE - SYNTAX INTEGER { - disconnected(1), - connected(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The connected status of the probe, either - disconnected(1) or connected(2)." - ::= { iemStatusProbesEntry 3 } - -iemStatusProbeCurrentTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current temperature reading from the probe displayed - in the units shown in the 'iemStatusProbeTempUnits' OID - (Celsius or Fahrenheit)." - ::= { iemStatusProbesEntry 4 } - -iemStatusProbeTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - thresholds of the probe, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { iemStatusProbesEntry 5 } - -iemStatusProbeCurrentHumid OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current humidity reading from the probe in percent - relative humidity." - ::= { iemStatusProbesEntry 6 } - -iemStatusProbeHighTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a highTempViolation(2) - if the current temperature reading shown in the - 'iemStatusProbeCurrentTemp' OID is greater than or equal to - the high temperature threshold value, the - 'iemConfigProbeHighTempThreshold' OID, and the value of the - 'iemConfigProbeHighTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'iemConfigProbeHighTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { iemStatusProbesEntry 7 } - -iemStatusProbeLowTempViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowTempViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high temperature violation status of the probe - temperature reading. This OID will show a lowTempViolation(2) - if the current temperature reading shown in the - 'iemStatusProbeCurrentTemp' OID is less than or equal to - the low temperature threshold value, the - 'iemConfigProbeLowTempThreshold' OID, and the value of the - 'iemPConfigrobeLowTempEnable' OID is enabled. Otherwise it will show - noViolation(1). If the 'iemConfigProbeLowTempEnable' OID is disabled, - this OID will show disabled(3)." - ::= { iemStatusProbesEntry 8 } - -iemStatusProbeHighHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - highHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The high humidity violation status of the probe humidity - reading. This OID will show a highTempViolation(2) - if the current humidity reading shown in the - 'iemStatusProbeCurrentHumid' OID is greater than or equal to - the high humidity threshold value, the - 'iemConfigProbeHighHumidThreshold' OID, and the value of the - 'iemConfigProbeHighHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'iemConfigProbeHighHumidEnable' OID is - disabled, this OID will show disabled(3)." - ::= { iemStatusProbesEntry 9 } - -iemStatusProbeLowHumidViolation OBJECT-TYPE - SYNTAX INTEGER { - noViolation(1), - lowHumidViolation(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The low humidity violation status of the probe humidity - reading. This OID will show a lowTempViolation(2) - if the current humidity reading shown in the - 'iemStatusProbeCurrentHumid' OID is less than or equal to - the low humidity threshold value, the - 'iemConfigProbeLowHumidThreshold' OID, and the value of the - 'iemConfigProbeLowHumidEnable' OID is enabled. Otherwise it will - show noViolation(1). If the 'iemConfigProbeLowHumidEnable' OID is - disabled, this OID will show disabled(3)." - ::= { iemStatusProbesEntry 10 } - -iemStatusContactsNumContacts OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of contacts supported on the - Environmental Monitor." - ::= { iemStatus 3 } - -iemStatusContactsTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of contacts supported by the Environmental Monitor - and their status." - ::= { iemStatus 4 } - -iemStatusContactsEntry OBJECT-TYPE - SYNTAX IemStatusContactsEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the contact." - INDEX { iemStatusContactNumber } - ::= { iemStatusContactsTable 1 } - -IemStatusContactsEntry ::= - SEQUENCE { - iemStatusContactNumber - INTEGER, - iemStatusContactName - DisplayString, - iemStatusContactStatus - INTEGER - } - -iemStatusContactNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the Environmental Monitor contact." - ::= { iemStatusContactsEntry 1 } - -iemStatusContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the Environmental Monitor contact - set by the user, denoting its location or purpose." - ::= { iemStatusContactsEntry 2 } - -iemStatusContactStatus OBJECT-TYPE - SYNTAX INTEGER { - noFault(1), - fault(2), - disabled(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the Environmental Monitor contact. The status - will show noFault(1) if the contact is in the normal state - and the 'iemConfigContactEnable' OID is enabled. The status will - show a fault(2) if the contact is faulted and the - 'iemConfigContactEnable' OID is enabled. If the - 'iemConfigContactEnable' OID is disabled, the status will show - disabled(3)." - ::= { iemStatusContactsEntry 3 } - -iemStatusRelaysNumRelays OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of output relays supported on the - Environmental Monitor." - ::= { iemStatus 6 } - -iemStatusRelaysTable OBJECT-TYPE - SYNTAX SEQUENCE OF IemStatusRelaysEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "A list of output relays supported by the - Environmental Monitor and their status." - ::= { iemStatus 7 } - -iemStatusRelaysEntry OBJECT-TYPE - SYNTAX IemStatusRelaysEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The status of the relay." - INDEX { iemStatusRelayNumber } - ::= { iemStatusRelaysTable 1 } - -IemStatusRelaysEntry ::= - SEQUENCE { - iemStatusRelayNumber - INTEGER, - iemStatusRelayName - DisplayString, - iemStatusRelayStatus - INTEGER - } - -iemStatusRelayNumber OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the output relay." - ::= { iemStatusRelaysEntry 1 } - -iemStatusRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A descriptive name for the output relay set by the - user, denoting its location or purpose." - ::= { iemStatusRelaysEntry 2 } - -iemStatusRelayStatus OBJECT-TYPE - SYNTAX INTEGER { - faultState(1), - normalState(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the output relay, either faultState(1) or - normalState(2)." - ::= { iemStatusRelaysEntry 3 } - --- Environmental Management System (EMS) - --- EMS IDENT - -emsIdentEMSName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { emsIdent 1 } - -emsIdentProductNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the model number of - the device. This value is set at the factory." - ::= { emsIdent 2 } - -emsIdentFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The firmware revision of the device." - ::= { emsIdent 3 } - -emsIdentHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The hardware revision of the device. - This value is set at the factory." - ::= { emsIdent 4 } - -emsIdentDateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The date when the device was manufactured in mm/dd/yyyy format. - This value is set at the factory. " - ::= { emsIdent 5 } - -emsIdentSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the serial number of - the device. This value is set at the factory." - ::= { emsIdent 6 } - --- EMS CONTROL - --- EMS OUTPUT RELAY CONTROL STATUS TABLE - -emsOutputRelayControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutputRelayControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual output relays. The number of - entries is contained in the emsStatusOutputRelayCount OID." - ::= { emsOutputRelayControl 1 } - -emsOutputRelayControlEntry OBJECT-TYPE - SYNTAX OutputRelayControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relays to control." - INDEX { emsOutputRelayControlOutputRelayIndex } - ::= { emsOutputRelayControlTable 1 } - -OutputRelayControlEMSEntry ::= - SEQUENCE { - emsOutputRelayControlOutputRelayIndex INTEGER, - emsOutputRelayControlOutputRelayName DisplayString, - emsOutputRelayControlOutputRelayCommand INTEGER - } - -emsOutputRelayControlOutputRelayIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the output relay entry." - ::= { emsOutputRelayControlEntry 1 } - -emsOutputRelayControlOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the output relay. - This OID is provided for informational purposes only." - ::= { emsOutputRelayControlEntry 2 } - -emsOutputRelayControlOutputRelayCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateCloseEMS (1), - immediateOpenEMS (2) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the output relay state. If - the output relay is closed, the immediateCloseEMS (1) value will be returned. - If the output relay is open, the immediateOpenEMS (2) value will be - returned. - - Setting this variable to immediateCloseEMS (1) will immediately close the relay. - - Setting this variable to immediateOpenEMS (2) will immediately open the relay." - ::= { emsOutputRelayControlEntry 3 } - --- EMS OUTLET CONTROL TABLE - -emsOutletControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF OutletControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual outlet switches. The number of - entries is contained in the emsStatusOutletCount OID." - ::= { emsOutletControl 1 } - -emsOutletControlEntry OBJECT-TYPE - SYNTAX OutletControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to control." - INDEX { emsOutletControlOutletIndex } - ::= { emsOutletControlTable 1 } - -OutletControlEMSEntry ::= - SEQUENCE { - emsOutletControlOutletIndex INTEGER, - emsOutletControlOutletName DisplayString, - emsOutletControlOutletCommand INTEGER - } - -emsOutletControlOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { emsOutletControlEntry 1 } - -emsOutletControlOutletName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet. - This OID is provided for informational purposes only." - ::= { emsOutletControlEntry 2 } - -emsOutletControlOutletCommand OBJECT-TYPE - SYNTAX INTEGER { - immediateOnEMS (1), - immediateOffEMS (2) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the outlet state. If - the outlet is on, the immediateOnEMS (1) value will be returned. - If the outlet is off, the immediateOffEMS (2) value will be - returned. - - Setting this variable to immediateOnEMS (1) will immediately turn the outlet on. - - Setting this variable to immediateOffEMS (2) will immediately turn the outlet off." - ::= { emsOutletControlEntry 3 } - --- EMS SENSOR CONTROL TABLE - -emsSensorControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSSensorControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control/reset of individual sensors. The number of - entries is contained in the emsStatusSensorCount OID." - ::= { emsSensorControl 1 } - -emsSensorControlEntry OBJECT-TYPE - SYNTAX EMSSensorControlEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The sensors to control/reset." - INDEX { emsSensorControlSensorIndex } - ::= { emsSensorControlTable 1 } - -EMSSensorControlEntry ::= - SEQUENCE { - emsSensorControlSensorIndex INTEGER, - emsSensorControlSensorSystemName DisplayString, - emsSensorControlSensorUserName DisplayString, - emsSensorControlSensorCommand INTEGER - } - -emsSensorControlSensorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the sensor entry." - ::= { emsSensorControlEntry 1 } - -emsSensorControlSensorSystemName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system name of the sensor. This describes the hardware system - intent of this sensor." - ::= { emsSensorControlEntry 2 } - -emsSensorControlSensorUserName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the sensor as given by the system user." - ::= { emsSensorControlEntry 3 } - -emsSensorControlSensorCommand OBJECT-TYPE - SYNTAX INTEGER { - noCommandEMS (1), - resetCommandEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return noCommandEMS(1). - - Setting this variable to resetCommandEMS(2) will issue a reset command to the - sensor. Some sensors cannot be manually reset and will not be affected - by this command." - ::= { emsSensorControlEntry 4 } - --- EMS ALARM DEVICE CONTROL TABLE - -emsAlarmDeviceControlTable OBJECT-TYPE - SYNTAX SEQUENCE OF AlarmDeviceControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for control of individual alarm devices. - Note: Some alarm devices are not controllable. The number of - entries is contained in the emsStatusAlarmDeviceCount OID." - ::= { emsAlarmDeviceControl 1 } - -emsAlarmDeviceControlEntry OBJECT-TYPE - SYNTAX AlarmDeviceControlEMSEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm devices to control." - INDEX { emsAlarmDeviceControlDeviceIndex } - ::= { emsAlarmDeviceControlTable 1 } - -AlarmDeviceControlEMSEntry ::= - SEQUENCE { - emsAlarmDeviceControlDeviceIndex INTEGER, - emsAlarmDeviceControlDeviceName DisplayString, - emsAlarmDeviceControlDeviceCommand INTEGER - } - -emsAlarmDeviceControlDeviceIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the alarm device entry." - ::= { emsAlarmDeviceControlEntry 1 } - -emsAlarmDeviceControlDeviceName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the alarm device. - This OID is provided for informational purposes only." - ::= { emsAlarmDeviceControlEntry 2 } - -emsAlarmDeviceControlDeviceCommand OBJECT-TYPE - SYNTAX INTEGER { - alarmDeviceOnEMS (1), - alarmDeviceOffEMS (2), - alarmDeviceNotInstalledEMS (3) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the device state. If - the device is active, the alarmDeviceOnEMS (1) value will be returned. - If the device is inactive, the alarmDeviceOffEMS (2) value will be - returned. If the device is not installed, the - alarmDeviceNotInstalledEMS (3) value will be returned. - - Actions resulting from setting this variable are device-dependent. - - Setting this variable to alarmDeviceOnEMS (1) will turn that device (ex. Beacon) on. - Setting this variable to alarmDeviceOffEMS (2) will turn that device off." - - ::= { emsAlarmDeviceControlEntry 3 } - - --- EMS CONFIG - -emsConfigName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the device." - ::= { emsConfig 1 } - -emsConfigCheckLogLight OBJECT-TYPE - SYNTAX INTEGER { - lightDisabled (1), - lightOnInformational (2), - lightOnWarning (3), - lightOnSevere (4) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The setting of this OID determines the level of event that will - trigger the check-log light on the EMS. This is not available on the EMU2. - - lightDisabled (1) disables the check-log light. - lightOnInformational (2) lights check-log for any event of - informational severity or above. - lightOnWarning (3) lights check-log for any event of - warning severity or above. - lightOnSevere (4) lights check-log for any event of severe severity." - - ::= { emsConfig 2 } - --- EMS PROBE CONFIG TABLE - -emsProbeConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSProbeConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual probes. The number of - entries is contained in the emsStatusProbeCount OID." - ::= { emsProbeConfig 1 } - -emsProbeConfigEntry OBJECT-TYPE - SYNTAX EMSProbeConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The probes to configure." - INDEX { emsProbeConfigProbeIndex } - ::= { emsProbeConfigTable 1 } - -EMSProbeConfigEntry ::= - SEQUENCE { - emsProbeConfigProbeIndex INTEGER, - emsProbeConfigProbeName DisplayString, - emsProbeConfigProbeHighTempThresh INTEGER, - emsProbeConfigProbeLowTempThresh INTEGER, - emsProbeConfigProbeHighHumidityThresh INTEGER, - emsProbeConfigProbeLowHumidityThresh INTEGER, - emsProbeConfigProbeMaxTempThresh INTEGER, - emsProbeConfigProbeMinTempThresh INTEGER, - emsProbeConfigProbeDeltaTemp INTEGER, - emsProbeConfigProbeMaxHumidityThresh INTEGER, - emsProbeConfigProbeMinHumidityThresh INTEGER, - emsProbeConfigProbeDeltaHumidity INTEGER, - emsProbeConfigProbeSTIncTempVariance INTEGER, - emsProbeConfigProbeSTIncTempTime INTEGER, - emsProbeConfigProbeSTDecTempVariance INTEGER, - emsProbeConfigProbeSTDecTempTime INTEGER, - emsProbeConfigProbeLTIncTempVariance INTEGER, - emsProbeConfigProbeLTIncTempTime INTEGER, - emsProbeConfigProbeLTDecTempVariance INTEGER, - emsProbeConfigProbeLTDecTempTime INTEGER - } - -emsProbeConfigProbeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the probe entry." - ::= { emsProbeConfigEntry 1 } - -emsProbeConfigProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the probe." - ::= { emsProbeConfigEntry 2 } - -emsProbeConfigProbeHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe high temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 3 } - -emsProbeConfigProbeLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe low temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 4 } - -emsProbeConfigProbeHighHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe high humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 5 } - -emsProbeConfigProbeLowHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe low humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 6 } - -emsProbeConfigProbeMaxTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe maximum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 7 } - -emsProbeConfigProbeMinTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe minimum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 8 } - -emsProbeConfigProbeDeltaTemp OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe delta temperature. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 9 } - -emsProbeConfigProbeMaxHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe maximum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 10 } - -emsProbeConfigProbeMinHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe minimum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 11 } - -emsProbeConfigProbeDeltaHumidity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe delta humidity. - - Values are represented in whole number percentage." - ::= { emsProbeConfigEntry 12 } - -emsProbeConfigProbeSTIncTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term increasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 13 } - -emsProbeConfigProbeSTIncTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term increasing temperature time used for rate of change alarms. - - Values are represented in whole number minutes." - ::= { emsProbeConfigEntry 14 } - -emsProbeConfigProbeSTDecTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term decreasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 15 } - -emsProbeConfigProbeSTDecTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe short-term decreasing temperature time used for rate of change alarms. - - Values are represented in whole number minutes." - ::= { emsProbeConfigEntry 16 } - -emsProbeConfigProbeLTIncTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term increasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 17 } - -emsProbeConfigProbeLTIncTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term increasing temperature time used for rate of change alarms. - - Values are represented in whole number hours." - ::= { emsProbeConfigEntry 18 } - -emsProbeConfigProbeLTDecTempVariance OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term decreasing temperature variance used for rate of change alarms. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeConfigEntry 19 } - -emsProbeConfigProbeLTDecTempTime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Probe long-term decreasing temperature time used for rate of change alarms. - - Values are represented in whole number hours." - ::= { emsProbeConfigEntry 20 } - - --- EMS INPUT CONTACT CONFIG STATUS TABLE - -emsInputContactConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSInputContactConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual input contacts. The number of - entries is contained in the emsStatusInputContactCount OID." - ::= { emsInputContactConfig 1 } - -emsInputContactConfigEntry OBJECT-TYPE - SYNTAX EMSInputContactConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input contacts to configure." - INDEX { emsInputContactConfigInputContactIndex } - ::= { emsInputContactConfigTable 1 } - -EMSInputContactConfigEntry ::= - SEQUENCE { - emsInputContactConfigInputContactIndex INTEGER, - emsInputContactConfigInputContactName DisplayString, - emsInputContactConfigInputContactNormalState INTEGER - } - -emsInputContactConfigInputContactIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the input contact entry." - ::= { emsInputContactConfigEntry 1 } - -emsInputContactConfigInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the input contact." - ::= { emsInputContactConfigEntry 2 } - -emsInputContactConfigInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the input contact. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned. - - Setting this variable will change the normal state of the input contact" - ::= { emsInputContactConfigEntry 3 } - --- EMS OUTPUT RELAY CONFIG STATUS TABLE - -emsOutputRelayConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutputRelayConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual output relays. The number of - entries is contained in the emsStatusOutputRelayCount OID." - ::= { emsOutputRelayConfig 1 } - -emsOutputRelayConfigEntry OBJECT-TYPE - SYNTAX EMSOutputRelayConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relays to configure." - INDEX { emsOutputRelayConfigOutputRelayIndex } - ::= { emsOutputRelayConfigTable 1 } - -EMSOutputRelayConfigEntry ::= - SEQUENCE { - emsOutputRelayConfigOutputRelayIndex INTEGER, - emsOutputRelayConfigOutputRelayName DisplayString, - emsOutputRelayConfigOutputRelayNormalState INTEGER - } - -emsOutputRelayConfigOutputRelayIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the output relay entry." - ::= { emsOutputRelayConfigEntry 1 } - -emsOutputRelayConfigOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the output relay." - ::= { emsOutputRelayConfigEntry 2 } - -emsOutputRelayConfigOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the output relay. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned. - - Setting this variable will change the normal state of the output relay" - ::= { emsOutputRelayConfigEntry 3 } - --- EMS OUTLET CONFIG TABLE - -emsOutletConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual outlets. The number of - entries is contained in the emsStatusOutletCount OID." - ::= { emsOutletConfig 1 } - -emsOutletConfigEntry OBJECT-TYPE - SYNTAX EMSOutletConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to configure." - INDEX { emsOutletConfigOutletIndex } - ::= { emsOutletConfigTable 1 } - -EMSOutletConfigEntry ::= - SEQUENCE { - emsOutletConfigOutletIndex INTEGER, - emsOutletConfigOutletName DisplayString, - emsOutletConfigOutletNormalState INTEGER - } - -emsOutletConfigOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { emsOutletConfigEntry 1 } - -emsOutletConfigOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the outlet." - ::= { emsOutletConfigEntry 2 } - -emsOutletConfigOutletNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyOnEMS (1), - normallyOffEMS (2) - } - - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the outlet. If - the normal state is on, the normallyOnEMS (1) value will be returned. - If the normal state is off, the normallyOffEMS (2) value will be - returned. - - Setting this variable will change the normal state of the outlet" - ::= { emsOutletConfigEntry 3 } - --- EMS SENSOR CONFIG TABLE - -emsSensorConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSSensorConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual sensors. The number of - entries is contained in the emsStatusSensorCount OID." - ::= { emsSensorConfig 1 } - -emsSensorConfigEntry OBJECT-TYPE - SYNTAX EMSSensorConfigEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The sensors to configure." - INDEX { emsSensorConfigSensorIndex } - ::= { emsSensorConfigTable 1 } - -EMSSensorConfigEntry ::= - SEQUENCE { - emsSensorConfigSensorIndex INTEGER, - emsSensorConfigSensorSystemName DisplayString, - emsSensorConfigSensorUserName DisplayString, - emsSensorConfigSensorNormalState INTEGER, - emsSensorConfigSensorAlarmDelay INTEGER - } - -emsSensorConfigSensorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the sensor entry." - ::= { emsSensorConfigEntry 1 } - -emsSensorConfigSensorSystemName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system name of the sensor. This describes the hardware system - intent of this sensor." - ::= { emsSensorConfigEntry 2 } - -emsSensorConfigSensorUserName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the sensor as given by the system user." - ::= { emsSensorConfigEntry 3 } - -emsSensorConfigSensorNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the sensor. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned. - - Setting this variable will change the normal state of the sensor. Note: - Only the AUX sensor in the EMS has a configurable Normal State" - ::= { emsSensorConfigEntry 4 } - -emsSensorConfigSensorAlarmDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The delay (in seconds) after a sensor detects an alarm condition before the - condition is reported." - ::= { emsSensorConfigEntry 5 } - --- EMS STATUS ---- EMS MASTER status - -emsStatusEMSName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { emsStatus 1 } - -emsStatusCommStatus OBJECT-TYPE - SYNTAX INTEGER { - noComm(1), - comm(2), - commLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The communication status between the agent - and the device. - - noComm(1), Communication has never been established. - comm(2), Communication has been established. - commLost(3), Communication was established, but was lost." - ::= { emsStatus 2 } - -emsStatusProbeCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of T/H probes (both local and remote) that - is supported by this device." - ::= { emsStatus 3 } - -emsStatusInputContactCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of Input Contacts that - is supported by this device." - ::= { emsStatus 4 } - -emsStatusOutputRelayCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of Output Relays that - is supported by this device." - ::= { emsStatus 5 } - -emsStatusOutletCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of AC Outlets that - is supported by this device." - ::= { emsStatus 6 } - -emsStatusSensorCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of Sensors that - is supported by this device." - ::= { emsStatus 7 } - -emsStatusAlinkAruDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of remote Aru's supported by this device." - ::= { emsStatus 8 } - -emsStatusAlinkProbeDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of remote T/H probes supported by this device." - ::= { emsStatus 9 } - -emsStatusAlarmDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of alarm devices supported by this device." - ::= { emsStatus 10 } - -emsStatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { emsStatus 11 } - -emsStatusCheckLogLight OBJECT-TYPE - SYNTAX INTEGER { - lightOff (1), - lightOn (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the check-log light on the device. - For the EMU2, this will always indicate lightOff(1). - - lightOff (1) indicates the light is off (no new log entries). - lightOn (2) indicates the light is on (new log entries present)." - - ::= { emsStatus 12 } - -emsStatusHardwareStatus OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the EMS hardware. This integer should be interpreted - as a bit map, with each bit representing the presence or absence of - a specific hardware error condition. - - 0 indicates there are no error conditions detected in the EMS hardware. - 1 indicates a Current Limit error condition related to the Alink port. - 2 indicates incorrect hardware is plugged into an EMS port. - 3 indicates that both of these error conditions are present." - - ::= { emsStatus 13 } - --- EMS PROBE STATUS TABLE - -emsProbeStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSProbeStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual probes. The number of - entries is contained in the emsStatusProbeCount OID." - ::= { emsProbeStatus 1 } - -emsProbeStatusEntry OBJECT-TYPE - SYNTAX EMSProbeStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The probes to access." - INDEX { emsProbeStatusProbeIndex } - ::= { emsProbeStatusTable 1 } - -EMSProbeStatusEntry ::= - SEQUENCE { - emsProbeStatusProbeIndex INTEGER, - emsProbeStatusProbeName DisplayString, - emsProbeStatusProbeTemperature INTEGER, - emsProbeStatusProbeHighTempThresh INTEGER, - emsProbeStatusProbeLowTempThresh INTEGER, - emsProbeStatusProbeHumidity INTEGER, - emsProbeStatusProbeHighHumidityThresh INTEGER, - emsProbeStatusProbeLowHumidityThresh INTEGER, - emsProbeStatusProbeSerialNumber DisplayString, - emsProbeStatusProbeCommStatus INTEGER, - emsProbeStatusProbeAlarmStatus INTEGER, - emsProbeStatusProbeMaxTempThresh INTEGER, - emsProbeStatusProbeMinTempThresh INTEGER, - emsProbeStatusProbeMaxHumidityThresh INTEGER, - emsProbeStatusProbeMinHumidityThresh INTEGER - } - -emsProbeStatusProbeIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the probe entry." - ::= { emsProbeStatusEntry 1 } - -emsProbeStatusProbeName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the probe." - ::= { emsProbeStatusEntry 2 } - -emsProbeStatusProbeTemperature OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe temperature reading. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 3 } - -emsProbeStatusProbeHighTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe high temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 4 } - -emsProbeStatusProbeLowTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe low temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 5 } - -emsProbeStatusProbeHumidity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe humidity reading. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 6 } - -emsProbeStatusProbeHighHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe high humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 7 } - -emsProbeStatusProbeLowHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe low humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 8 } - -emsProbeStatusProbeSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A label indicating the type (Local[L] or Remote[R]) and Number - of the probe. For example, the first local probe would be L1 and - the third remote probe would be R3." - ::= { emsProbeStatusEntry 9 } - -emsProbeStatusProbeCommStatus OBJECT-TYPE - SYNTAX INTEGER { - commsNeverDiscovered(1), - commsEstablished(2), - commsLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - " The state of communications to the probe. - commNeverDiscovered(1) indicates there has never been communications with this device. - commsEstablished(2) indicates communication is normal and active with this device. - commsLost(3) indicates communication had been established, but is no longer." - ::= { emsProbeStatusEntry 10 } - -emsProbeStatusProbeAlarmStatus OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The alarm status of the probe. This integer should be interpreted - as a bit map, with each bit representing the presence or absence of - the specific alarm conditions listed below. The bit will be '1' if - the condition is present, and '0' if the condition is not present. - - Bit Hex. Value Description - 1 0x0001 Maximum temperature exceeded. - 2 0x0002 High temperature exceeded. - 3 0x0004 Low temperature exceeded. - 4 0x0008 Minimum temperature exceeded. - 5 0x0010 Short-term increasing temperature rate exceeded. - 6 0x0020 Short-term decreasing temperature rate exceeded. - 7 0x0040 Long-term increasing temperature rate exceeded. - 8 0x0080 Long-term decreasing temperature rate exceeded. - 9 0x0100 Maximum humidity exceeded. - 10 0x0200 High humidity exceeded. - 11 0x0400 Low humidity exceeded. - 12 0x0800 Minimum humidity exceeded." - ::= { emsProbeStatusEntry 11 } - -emsProbeStatusProbeMaxTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe maximum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 12 } - -emsProbeStatusProbeMinTempThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe minimum temperature threshold. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the emsStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { emsProbeStatusEntry 13 } - -emsProbeStatusProbeMaxHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe maximum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 14 } - -emsProbeStatusProbeMinHumidityThresh OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Probe minimum humidity threshold. - - Values are represented in whole number percentage." - ::= { emsProbeStatusEntry 15 } - - --- EMS INPUT CONTACT STATUS TABLE - -emsInputContactStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSInputContactStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual input contacts. The number of - entries is contained in the emsStatusInputContactCount OID." - ::= { emsInputContactStatus 1 } - -emsInputContactStatusEntry OBJECT-TYPE - SYNTAX EMSInputContactStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The input contacts to access." - INDEX { emsInputContactStatusInputContactIndex } - ::= { emsInputContactStatusTable 1 } - -EMSInputContactStatusEntry ::= - SEQUENCE { - emsInputContactStatusInputContactIndex INTEGER, - emsInputContactStatusInputContactName DisplayString, - emsInputContactStatusInputContactState INTEGER, - emsInputContactStatusInputContactNormalState INTEGER - } - -emsInputContactStatusInputContactIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the input contact entry." - ::= { emsInputContactStatusEntry 1 } - -emsInputContactStatusInputContactName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the input contact." - ::= { emsInputContactStatusEntry 2 } - -emsInputContactStatusInputContactState OBJECT-TYPE - SYNTAX INTEGER { - contactClosedEMS (1), - contactOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the state of the input contact. If - the input contact is closed, the contactClosedEMS (1) value will be returned. - If the input contact state is open, the contactOpenEMS (2) value will be - returned. " - - ::= { emsInputContactStatusEntry 3 } - -emsInputContactStatusInputContactNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the input contact. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is open, the normallyOpenEMS (2) value will be - returned. " - - ::= { emsInputContactStatusEntry 4 } - - --- EMS OUTPUT RELAY STATUS TABLE - -emsOutputRelayStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutputRelayStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual output relays. The number of - entries is contained in the emsStatusOutputRelayCount OID." - ::= { emsOutputRelayStatus 1 } - -emsOutputRelayStatusEntry OBJECT-TYPE - SYNTAX EMSOutputRelayStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The output relays to access." - INDEX { emsOutputRelayStatusOutputRelayIndex } - ::= { emsOutputRelayStatusTable 1 } - -EMSOutputRelayStatusEntry ::= - SEQUENCE { - emsOutputRelayStatusOutputRelayIndex INTEGER, - emsOutputRelayStatusOutputRelayName DisplayString, - emsOutputRelayStatusOutputRelayState INTEGER, - emsOutputRelayStatusOutputRelayNormalState INTEGER - } - -emsOutputRelayStatusOutputRelayIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the output relay entry." - ::= { emsOutputRelayStatusEntry 1 } - -emsOutputRelayStatusOutputRelayName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the output relay." - ::= { emsOutputRelayStatusEntry 2 } - -emsOutputRelayStatusOutputRelayState OBJECT-TYPE - SYNTAX INTEGER { - relayClosedEMS (1), - relayOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the state of the output relay. If - the output relay is closed, the relayClosedEMS (1) value will be returned. - If the output relay is open, the relayOpenEMS (2) value will be - returned. " - - ::= { emsOutputRelayStatusEntry 3 } - -emsOutputRelayStatusOutputRelayNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the output relay. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is open, the normallyOpenEMS (2) value will be - returned. " - - ::= { emsOutputRelayStatusEntry 4 } - --- EMS OUTLET STATUS TABLE - -emsOutletStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual outlets. The number of - entries is contained in the emsStatusOutletCount OID." - ::= { emsOutletStatus 1 } - -emsOutletStatusEntry OBJECT-TYPE - SYNTAX EMSOutletStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The outlets to access." - INDEX { emsOutletStatusOutletIndex } - ::= { emsOutletStatusTable 1 } - -EMSOutletStatusEntry ::= - SEQUENCE { - emsOutletStatusOutletIndex INTEGER, - emsOutletStatusOutletName DisplayString, - emsOutletStatusOutletState INTEGER, - emsOutletStatusOutletNormalState INTEGER - } - -emsOutletStatusOutletIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the outlet entry." - ::= { emsOutletStatusEntry 1 } - -emsOutletStatusOutletName OBJECT-TYPE - SYNTAX DisplayString ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the outlet." - ::= { emsOutletStatusEntry 2 } - -emsOutletStatusOutletState OBJECT-TYPE - SYNTAX INTEGER { - outletOnEMS (1), - outletOffEMS (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the state of the outlet. If - the outlet is on, the outletOnEMS (1) value will be returned. - If the outlet is off, the outletOffEMS (2) value will be - returned. " - - ::= { emsOutletStatusEntry 3 } - -emsOutletStatusOutletNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyOnEMS (1), - normallyOffEMS (2) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the outlet. If - the normal state is on, the normallyOnEMS (1) value will be returned. - If the normal state is off, the normallyOffEMS (2) value will be - returned. " - - ::= { emsOutletStatusEntry 4 } - --- EMS ALARM DEVICE STATUS TABLE - -emsAlarmDeviceStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSAlarmDeviceStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual alarm devices. The number of - entries is contained in the emsStatusAlarmDeviceCount OID." - ::= { emsAlarmDeviceStatus 1 } - -emsAlarmDeviceStatusEntry OBJECT-TYPE - SYNTAX EMSAlarmDeviceStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The alarm devices to access." - INDEX { emsAlarmDeviceStatusDeviceIndex } - ::= { emsAlarmDeviceStatusTable 1 } - -EMSAlarmDeviceStatusEntry ::= - SEQUENCE { - emsAlarmDeviceStatusDeviceIndex INTEGER, - emsAlarmDeviceStatusDeviceName DisplayString, - emsAlarmDeviceStatusDeviceState INTEGER - } - -emsAlarmDeviceStatusDeviceIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the alarm device entry." - ::= { emsAlarmDeviceStatusEntry 1 } - -emsAlarmDeviceStatusDeviceName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the alarm device. - This OID is provided for informational purposes only." - ::= { emsAlarmDeviceStatusEntry 2 } - -emsAlarmDeviceStatusDeviceState OBJECT-TYPE - SYNTAX INTEGER { - alarmDeviceOnEMS (1), - alarmDeviceOffEMS (2), - alarmDeviceNotInstalledEMS (3) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the device state. If - the device is active, the alarmDeviceOnEMS (1) value will be returned. - If the device is inactive, the alarmDeviceOffEMS (2) value will be - returned. If the device is not installed, the - alarmDeviceNotInstalledEMS (3) value will be returned." - - ::= { emsAlarmDeviceStatusEntry 3 } - - --- EMS SENSOR STATUS TABLE - -emsSensorStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF EMSSensorStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual sensors. The number of - entries is contained in the emsStatusSensorCount OID." - ::= { emsSensorStatus 1 } - -emsSensorStatusEntry OBJECT-TYPE - SYNTAX EMSSensorStatusEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The sensors to access." - INDEX { emsSensorStatusSensorIndex } - ::= { emsSensorStatusTable 1 } - -EMSSensorStatusEntry ::= - SEQUENCE { - emsSensorStatusSensorIndex INTEGER, - emsSensorStatusSensorSystemName DisplayString, - emsSensorStatusSensorName DisplayString, - emsSensorStatusSensorState INTEGER, - emsSensorStatusSensorNormalState INTEGER, - emsSensorStatusSensorAlarmDelay INTEGER - } - -emsSensorStatusSensorIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the sensor entry." - ::= { emsSensorStatusEntry 1 } - -emsSensorStatusSensorSystemName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system name of the sensor. This describes the hardware system - intent of this sensor." - ::= { emsSensorStatusEntry 2 } - -emsSensorStatusSensorName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the sensor as given by the system user." - ::= { emsSensorStatusEntry 3 } - -emsSensorStatusSensorState OBJECT-TYPE - SYNTAX INTEGER { - sensorFaultedEMS (1), - sensorOKEMS (2), - sensorNotInstalledEMS (3) - } - - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the sensor state. If the sensor is faulted, - the sensorFaultedEMS (1) value will be returned. - If the sensor is not faulted, the sensorOKEMS (2) value will be - returned. If the sensor is not installed, the sensorNotInstalledEMS (3) - value will be returned." - ::= { emsSensorStatusEntry 4 } - -emsSensorStatusSensorNormalState OBJECT-TYPE - SYNTAX INTEGER { - normallyClosedEMS (1), - normallyOpenEMS (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "Getting this variable will return the normal state of the sensor. If - the normal state is closed, the normallyClosedEMS (1) value will be returned. - If the normal state is closed, the normallyOpenEMS (2) value will be - returned." - ::= { emsSensorStatusEntry 5 } - -emsSensorStatusSensorAlarmDelay OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The delay (in seconds) after a sensor detects an alarm condition before the - condition is reported." - ::= { emsSensorStatusEntry 6 } - - - --- airFM AIR CONDITIONER IDENT - -airFMIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { airFMIdent 1 } - -airFMIdentTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the airFMIdentTable. " - ::= { airFMIdent 2 } - -airFMIdentTable OBJECT-TYPE - SYNTAX SEQUENCE OF AirFMIdentTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting identification information - from each module in the system. " - ::= { airFMIdent 3 } - -airFMIdentTableEntry OBJECT-TYPE - SYNTAX AirFMIdentTableEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The module to get information from." - INDEX { airFMIdentModuleIndex } - ::= { airFMIdentTable 1 } - -AirFMIdentTableEntry ::= - SEQUENCE { - airFMIdentModuleIndex INTEGER, - airFMIdentModuleModelNumber DisplayString, - airFMIdentModuleDateOfMfg DisplayString, - airFMIdentModuleSerialNumber DisplayString, - airFMIdentModuleFirmwareRev DisplayString, - airFMIdentModuleHardwareRev DisplayString - } - -airFMIdentModuleIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the module information." - ::= { airFMIdentTableEntry 1 } - -airFMIdentModuleModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - model number. " - ::= { airFMIdentTableEntry 2 } - -airFMIdentModuleDateOfMfg OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - manufacture date. " - ::= { airFMIdentTableEntry 3 } - -airFMIdentModuleSerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - unit serial number. " - ::= { airFMIdentTableEntry 4 } - -airFMIdentModuleFirmwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - firmware revision. " - ::= { airFMIdentTableEntry 5 } - -airFMIdentModuleHardwareRev OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - hardware revision. " - ::= { airFMIdentTableEntry 6 } - --- airFM AIR CONDITIONER STATUS - -airFMStatusSystemOn OBJECT-TYPE - SYNTAX INTEGER { - statusOn (1), - statusOff (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The operating state of the system. " - ::= { airFMStatus 1 } - -airFMStatusSystemAverageRetTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system average return air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 2 } - -airFMStatusSystemAverageRetTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system average return air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 3 } - -airFMStatusSystemAverageRetHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system average return air - humidity. " - ::= { airFMStatus 4 } - -airFMStatusSystemActionTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system action air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 5 } - -airFMStatusSystemActionTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system action air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 6 } - -airFMStatusSystemActionHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system action air humidity. " - ::= { airFMStatus 7 } - -airFMStatusSystemRemoteHighTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote high air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 8 } - -airFMStatusSystemRemoteHighTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote high air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 9 } - -airFMStatusSystemRemoteAvgTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote average air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 10 } - -airFMStatusSystemRemoteAvgTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote average air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 11 } - -airFMStatusSystemRemoteAvgHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote average air - humidity. " - ::= { airFMStatus 12 } - -airFMStatusSystemRemoteLowTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote low air - temperature in tenths of degrees Celsius. " - ::= { airFMStatus 13 } - -airFMStatusSystemRemoteLowTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The system remote low air - temperature in tenths of degrees Fahrenheit. " - ::= { airFMStatus 14 } - -airFMStatusSystemCoolingEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system cooling - function enable. " - ::= { airFMStatus 15 } - -airFMStatusSystemReheatingEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system reheating - function enable. " - ::= { airFMStatus 16 } - -airFMStatusSystemHumidifyEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system humidify - function enable. " - ::= { airFMStatus 17 } - -airFMStatusSystemDehumidifyEnabled OBJECT-TYPE - SYNTAX INTEGER { - enabledYes (1), - enabledNo (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of the system dehumidify - function enable. " - ::= { airFMStatus 18 } - -airFMStatusModuleTableSize OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of entries in the airFMStatusModuleTable. " - ::= { airFMStatus 19 } - -airFMStatusModuleTable OBJECT-TYPE - SYNTAX SEQUENCE OF AirFMStatusModuleEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for getting information from each module - in the system. " - ::= { airFMStatus 20 } - -airFMStatusModuleEntry OBJECT-TYPE - SYNTAX AirFMStatusModuleEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The module to get status from." - INDEX { airFMStatusModuleIndex } - ::= { airFMStatusModuleTable 1 } - -AirFMStatusModuleEntry ::= - SEQUENCE { - airFMStatusModuleIndex INTEGER, - airFMStatusModuleOutputCapacity INTEGER, - airFMStatusModuleSupplyTempC INTEGER, - airFMStatusModuleSupplyTempF INTEGER, - airFMStatusModuleSupplyHum INTEGER, - airFMStatusModuleReturnTempC INTEGER, - airFMStatusModuleReturnTempF INTEGER, - airFMStatusModuleReturnHum INTEGER - } - -airFMStatusModuleIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index of the module information." - ::= { airFMStatusModuleEntry 1 } - -airFMStatusModuleOutputCapacity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module output capacity in kilowatts." - ::= { airFMStatusModuleEntry 2 } - -airFMStatusModuleSupplyTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module supply air temperature in - tenths of degrees Celsius. " - ::= { airFMStatusModuleEntry 3 } - -airFMStatusModuleSupplyTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module supply air temperature in - tenths of degrees Fahrenheit. " - ::= { airFMStatusModuleEntry 4 } - -airFMStatusModuleSupplyHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module supply air humidity. " - ::= { airFMStatusModuleEntry 5 } - -airFMStatusModuleReturnTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module return air temperature in - tenths of degrees Celsius. " - ::= { airFMStatusModuleEntry 6 } - -airFMStatusModuleReturnTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module return air temperature in - tenths of degrees Fahrenheit. " - ::= { airFMStatusModuleEntry 7 } - -airFMStatusModuleReturnHum OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The module return air humidity. " - ::= { airFMStatusModuleEntry 8 } - --- airFM AIR CONDITIONER GROUP DATA - -airFMGroupSysStatus OBJECT-TYPE - SYNTAX INTEGER { - statusOnLine (1), - statusIdle (2), - statusLoadShare (3), - statusOffLine (4), - statusFailed (5) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of this system within the group. " - ::= { airFMGroup 1 } - -airFMGroupSysRuntime OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The number of hours the system has been running. " - ::= { airFMGroup 2 } - -airFMGroupSysRole OBJECT-TYPE - SYNTAX INTEGER { - rolePrimary (1), - roleBackup (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The role of this system within the group. " - ::= { airFMGroup 3 } - --- airPA Portable Air Conditioner Ident - -airPAIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device name. " - ::= { airPAIdent 1 } - -airPAModelNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device model number. " - ::= { airPAIdent 2 } - -airPADateOfManufacture OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying when the device was produced. " - ::= { airPAIdent 3 } - -airPASerialNumber OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device serial number. " - ::= { airPAIdent 4 } - -airPAFirmwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device firmware revision. " - ::= { airPAIdent 5 } - -airPAHardwareRevision OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the device hardware revision. " - ::= { airPAIdent 6 } - --- airPA Portable Air Conditioner Status - -airPASystemPower OBJECT-TYPE - SYNTAX INTEGER { - powerON (1), - powerOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The status of the unit's system power setting. - - ON(1) The system power is turned on. - OFF(2) The system power is turned off. " - ::= { airPAStatus 1 } - -airPAOperatingMode OBJECT-TYPE - SYNTAX INTEGER { - modeOFF (1), - modeVENTING (2), - modeCOOLING (3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The current operating mode of the unit. - - OFF(1) The system is off. - VENTING(2) The system's venting function is active. - COOLING(3) The system's cooling function is active. " - ::= { airPAStatus 2 } - -airPASetpointTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature setpoint in Fahrenheit to which the unit is controlling. " - ::= { airPAStatus 3 } - -airPASetpointTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature setpoint in Celsius to which the unity is controlling. " - ::= { airPAStatus 4 } - -airPABlowerSpeed OBJECT-TYPE - SYNTAX INTEGER { - speedLOW (1), - speedHIGH (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's blower speed setting. - - LOW(1) The blower speed is low. - HIGH(2) The blower speed is high. " - ::= { airPAStatus 5 } - -airPACompressor OBJECT-TYPE - SYNTAX INTEGER { - statusON (1), - statusOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's compressor status. - - ON(1) The compressor is turned on. - OFF(2) The compressor is turned off. " - ::= { airPAStatus 6 } - -airPACondenserFan OBJECT-TYPE - SYNTAX INTEGER { - statusON (1), - statusOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's condenser fan status. - - ON(1) The condenser fan is turned on. - OFF(2) The condenser fan is turned off. " - ::= { airPAStatus 7 } - -airPACondensatePump OBJECT-TYPE - SYNTAX INTEGER { - statusON (1), - statusOFF (2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The unit's condensate pump status. - - ON(1) The condensate pump is turned on. - OFF(2) The condensate pump is turned off. " - ::= { airPAStatus 8 } - -airPASupplyTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The supply temperature in degrees Fahrenheit. " - ::= { airPAStatus 9 } - -airPASupplyTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The supply temperature in degrees Celsius. " - ::= { airPAStatus 10 } - -airPAReturnTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The return temperature in degrees Fahrenheit. " - ::= { airPAStatus 11 } - -airPAReturnTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The return temperature in degrees Celsius. " - ::= { airPAStatus 12 } - -airPARemoteTempF OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remote temperature in degrees Fahrenheit. " - ::= { airPAStatus 13 } - -airPARemoteTempC OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remote temperature in degrees Celsius. " - ::= { airPAStatus 14 } - -airPARemoteHumidity OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The remote humidity. " - ::= { airPAStatus 15 } - --- RACK AIR REMOVAL UNIT IDENT - -rARUIdentTable OBJECT-TYPE - SYNTAX SEQUENCE OF IdentRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for query of the individual devices. - The number of entries is contained in the - rARUStatusAruDeviceCount OID." - ::= { rARUIdent 1 } - -rARUIdentEntry OBJECT-TYPE - SYNTAX IdentRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The device to query." - INDEX { rARUIdentIndex} - ::= { rARUIdentTable 1 } - -IdentRARUEntry ::= - SEQUENCE { - rARUIdentIndex INTEGER, - rARUIdentName DisplayString - } - -rARUIdentIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the device entry." - ::= { rARUIdentEntry 1 } - -rARUIdentName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "A character string identifying the - device. " - ::= { rARUIdentEntry 2 } - - --- RACK AIR REMOVAL UNIT CONFIGURATION - -rARUConfigTable OBJECT-TYPE - SYNTAX SEQUENCE OF ConfigRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for configuration of individual ARUs. The number of - entries is contained in the rARUStatusAruDeviceCount OID." - ::= { rARUConfig 1 } - -rARUConfigEntry OBJECT-TYPE - SYNTAX ConfigRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The ARUs to configure." - INDEX { rARUConfigAruIndex } - ::= { rARUConfigTable 1 } - -ConfigRARUEntry ::= - SEQUENCE { - rARUConfigAruIndex INTEGER, - rARUConfigAruName DisplayString, - rARUConfigAruRemoteSetpoint INTEGER, - rARUConfigAruTempOvrdEnableDisable INTEGER, - rARUConfigAruTempOvrdSetpoint INTEGER - } - -rARUConfigAruIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the device entry." - ::= { rARUConfigEntry 1 } - -rARUConfigAruName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-write - STATUS mandatory - DESCRIPTION - "The name of the ARU." - ::= { rARUConfigEntry 2 } - -rARUConfigAruRemoteSetpoint OBJECT-TYPE - SYNTAX INTEGER { - aruOff (1), - aru85F-29C (2), - aru90F-32C (3), - aru95F-35C (4), - aru100F-38C (5), - aru7kW (6), - aru5kW (7), - aru3kW (8), - aru2kW (9) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is the Remote setpoint of the ARU. - NOTE: -1 will be returned if the ARU is not communicating." - - ::= { rARUConfigEntry 3 } - -rARUConfigAruTempOvrdEnableDisable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is used to enable/disable the remote temperature override setting of the ARU. - - If this OID is set to 1, the remote setting for temperature override is disabled. - If this OID is set to 2, the remote setting for temperature override is enabled." - ::= { rARUConfigEntry 4 } - -rARUConfigAruTempOvrdSetpoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-write - STATUS mandatory - DESCRIPTION - "This OID is the Temperature Override setpoint of the ARU. - NOTE: -1 will be returned if the ARU is not communicating." - - ::= { rARUConfigEntry 5 } - --- RACK AIR REMOVAL UNIT STATUS - -rARUStatusAruDeviceCount OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The total number of ARUs accessible from this IP." - ::= { rARUStatus 1 } - -rARUStatusSysTempUnits OBJECT-TYPE - SYNTAX INTEGER { - celsius(1), - fahrenheit(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The temperature scale used to display the temperature - in the system, Celsius(1) or Fahrenheit(2). - This setting is based on the system preferences - configuration in the agent." - ::= { rARUStatus 2 } - -rARUStatusTable OBJECT-TYPE - SYNTAX SEQUENCE OF StatusRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "Allows for access of individual ARUs. The number of - entries is contained in the rARUStatusAruDeviceCount OID." - ::= { rARUStatus 3 } - -rARUStatusEntry OBJECT-TYPE - SYNTAX StatusRARUEntry - ACCESS not-accessible - STATUS mandatory - DESCRIPTION - "The ARUs to access." - INDEX { rARUStatusAruIndex } - ::= { rARUStatusTable 1 } - -StatusRARUEntry ::= - SEQUENCE { - rARUStatusAruIndex INTEGER, - rARUStatusAruName DisplayString, - rARUStatusAruRemoteSetpoint INTEGER, - rARUStatusAruManualSetpoint INTEGER, - rARUStatusAruTemp1 INTEGER, - rARUStatusAruTemp2 INTEGER, - rARUStatusAruTemp3 INTEGER, - rARUStatusAruTempOvrdEnableDisable INTEGER, - rARUStatusAruTempOvrdSetpoint INTEGER, - rARUStatusAruAlarmState DisplayString, - rARUStatusAruCommStatus INTEGER - } - -rARUStatusAruIndex OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The index to the ARU entry." - ::= { rARUStatusEntry 1 } - -rARUStatusAruName OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The name of the ARU." - ::= { rARUStatusEntry 2 } - -rARUStatusAruRemoteSetpoint OBJECT-TYPE - SYNTAX INTEGER { - aruOff (1), - aru85F-29C (2), - aru90F-32C (3), - aru95F-35C (4), - aru100F-38C (5), - aru7kW (6), - aru5kW (7), - aru3kW (8), - aru2kW (9) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU remote setpoint temperature setting. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 3 } - -rARUStatusAruManualSetpoint OBJECT-TYPE - SYNTAX INTEGER { - aruOff (1), - aru85F-29C (2), - aru90F-32C (3), - aru95F-35C (4), - aru100F-38C (5), - aru7kW (6), - aru5kW (7), - aru3kW (8), - aru2kW (9), - aruRem (10) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU manual setpoint temperature setting. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - If the manual setpoint is set to Remote, this OID will return 0. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 4 } - -rARUStatusAruTemp1 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU temperature probe #1 reading. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 5 } - -rARUStatusAruTemp2 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU temperature probe #2 reading. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 6 } - -rARUStatusAruTemp3 OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU temperature probe #3 reading. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 7 } - -rARUStatusAruTempOvrdEnableDisable OBJECT-TYPE - SYNTAX INTEGER { - disabled(1), - enabled(2) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "This OID indicates whether the ARU remote temperature override is enabled or disabled. - If this OID is a 1, the remote setting for temperature override is disabled. - If this OID is a 2, the remote setting for temperature override is enabled." - ::= { rARUStatusEntry 8 } - -rARUStatusAruTempOvrdSetpoint OBJECT-TYPE - SYNTAX INTEGER - ACCESS read-only - STATUS mandatory - DESCRIPTION - "ARU remote temperature override setpoint setting. - - NOTE: -1 will be returned if the ARU is not communicating. - - Values are represented in whole number degrees. - Units are displayed in the scale shown in - the rARUStatusSysTempUnits OID (Celsius or Fahrenheit)." - ::= { rARUStatusEntry 9 } - -rARUStatusAruAlarmState OBJECT-TYPE - SYNTAX DisplayString - ACCESS read-only - STATUS mandatory - DESCRIPTION - "An ASCII string containing the 8 flags representing - the current alarm state of the ARU. If the state of - the ARU is unknown, this variable is set to �UNKNOWN�. - - The flags are numbered 1 to 8, read from left to - right. The flags are defined as follows: - - Flag 1: Fan Fail 1 - Flag 2: Fan Fail 2 - Flag 3: Fan Fail 3 - Flag 4: Smoke - - Flag 5: High Temp (Out of Thermal Control) - Flag 6: Over Temp (Exhaust Temp. Exceeds Override Setpoint) - Flag 7: Reserved - Flag 8: Reserved" - ::= { rARUStatusEntry 10 } - -rARUStatusAruCommStatus OBJECT-TYPE - SYNTAX INTEGER { - commsNeverDiscovered(1), - commsEstablished(2), - commsLost(3) - } - ACCESS read-only - STATUS mandatory - DESCRIPTION - "The state of communications to the device. - commNeverDiscovered(1) indicates there has never been communications with this device. - commsEstablished(2) indicates communication is normal and active with this device. - commsLost(3) indicates communication had been established, but is no device." - ::= { rARUStatusEntry 11 } - --- Traps --- Annotations are provided for Novell's NMS product --- --- Each trap has at least one variable (mtrapargsString) which always appears --- as the last variable in the list. This variable contains either a static --- or dynamically-constructed string which provides an enhanced description of --- the trap's purpose and any pertinent information about the trap. - -communicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communication to the UPS has been lost. Steps - to reestablish communication are in progress." - --#TYPE "APC UPS: Communication lost" - --#SUMMARY "Communication lost between the agent and the UPS." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 1 - -upsOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS has sensed a load greater than 100 percent - of its rated capacity." - --#TYPE "APC UPS: Overload" - --#SUMMARY "The UPS has sensed a load greater than 100 percent of its rated capacity." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 2 - -upsDiagnosticsFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS failed its internal diagnostic self-test." - --#TYPE "APC UPS: Failed self-test" - --#SUMMARY "The UPS has failed its internal self-test." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 3 - -upsDischarged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS batteries are discharged; if utility power fails - an immediate low battery condition will exist. Sufficient runtime - for necessary action cannot be guaranteed." - --#TYPE "APC UPS: batteries are discharged" - --#SUMMARY "The UPS batteries are discharged." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 4 - -upsOnBattery TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has switched to battery backup power." - --#TYPE "APC UPS: On battery" - --#SUMMARY "The UPS has switched to battery backup power." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 5 - -smartBoostOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has enabled SmartBoost(TM)." - --#TYPE "APC UPS: SmartBoost(TM)" - --#SUMMARY "The UPS has enabled SmartBoost(TM); low incoming line voltage." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 6 - -lowBattery TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The UPS batteries are low and will soon be exhausted. - If utility power is not restored the UPS will put itself - to 'sleep' and immediately cut power to the load." - --#TYPE "APC UPS: Low battery" - --#SUMMARY "The UPS system's batteries are low and will soon be exhausted." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 7 - -communicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication with the UPS has been established." - --#TYPE "APC UPS: Communication established" - --#SUMMARY "UPS communication has been established." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 8 - -powerRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Utility power has been restored." - --#TYPE "APC UPS: Utility power restored" - --#SUMMARY "Returned from battery backup power; utility power restored." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 9 - -upsDiagnosticsPassed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS passed its internal self-test." - --#TYPE "APC UPS: Passed self-test" - --#SUMMARY "The UPS passed internal self-test." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 10 - -returnFromLowBattery TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has returned from a low battery - condition." - --#TYPE "APC UPS: Returned from Low-Battery condition" - --#SUMMARY "The UPS has returned from a Low-Battery condition." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 11 - -upsTurnedOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has been turned 'off' by the management station." - --#TYPE "APC UPS: Turned off" - --#SUMMARY "The UPS has been switched off by a management station." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 12 - -upsSleeping TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS is entering 'sleep' mode. Power - to the load will be cut off." - --#TYPE "APC UPS: Entered sleep mode" - --#SUMMARY "The UPS entered sleep mode. Power to the load will be cut off." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 13 - -upsWokeUp TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATION: The UPS has returned from 'sleep' mode. Power - to the load has been restored." - --#TYPE "APC UPS: Wake up" - --#SUMMARY "The UPS has returned from sleep mode. Power to the load has been restored." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 14 - -upsRebootStarted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has started its reboot sequence. - The UPS will reboot itself at this time." - --#TYPE "APC UPS: Starting reboot" - --#SUMMARY "The UPS has started its reboot sequence." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 15 - -upsDipSwitchChanged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The dip switch settings on the UPS have been - changed, possibly altering UPS performance." - --#TYPE "APC UPS: DIP switch altered" - --#SUMMARY "The DIP switch settings on the UPS have been changed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 16 - -upsBatteryNeedsReplacement TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: The batteries of the UPS need immediate replacement." - --#TYPE "APC UPS: UPS batteries need replacement" - --#SUMMARY "The UPS batteries require immediate replacement." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 17 - - --- the Environmental Monitor traps - -contactFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: One of the contacts on the Environmental Monitor has - changed from its default position. The first variable is - the contact number that is faulted." - --#TYPE "APC Environment: Contact fault" - --#SUMMARY "An Environment contact closure has faulted." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 18 - -contactFaultResolved TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A fault on one of the Environmental Monitor contacts - has been resolved. The first variable is - the contact number that has been resolved." - --#TYPE "APC Environment: Contact fault cleared." - --#SUMMARY "A Environment contact closure has returned to it's default state." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 19 - --- the Matrix-UPS traps - -hardwareFailureBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: UPS on bypass due to internal fault" - --#TYPE "APC UPS: On bypass due to internal fault" - --#SUMMARY "The UPS is on bypass due to an internal fault." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 20 - -softwareBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: UPS on bypass - user set via software or panel" - --#TYPE "APC UPS: On bypass by user via software or panel" - --#SUMMARY "UPS put on bypass by user via software or front UPS panel." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 21 - -switchedBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: UPS on bypass - initiated by user" - --#TYPE "APC UPS: On bypass initiated by user" - --#SUMMARY "UPS put on bypass by user." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 22 - -returnFromBypass TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: UPS has returned from bypass" - --#TYPE "APC UPS: UPS has returned from bypass" - --#SUMMARY "The UPS has returned from bypass mode." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 23 - -bypassPowerSupplyFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Base module bypass power supply needs repair" - --#TYPE "APC UPS: Base module bypass power supply needs repair" - --#SUMMARY "The base module bypass power supply needs repair." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 24 - -baseFanFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Base module fan needs repair" - --#TYPE "APC UPS: Base module fan needs repair" - --#SUMMARY "The base module fan needs repair." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 25 - -batteryPackCommLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Check installation of external battery packs signal cable" - --#TYPE "APC UPS: Communication lost with battery packs" - --#SUMMARY "Communication lost with external battery packs, check battery signal cable." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 26 - -batteryPackCommEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: UPS is communicating with the external battery packs." - --#TYPE "APC UPS: Communication established with battery packs" - --#SUMMARY "Communication established with external battery packs." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 27 - -calibrationStart TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A battery calibration test has been initiated on the UPS." - --#TYPE "APC UPS: Calibration initiated" - --#SUMMARY "A battery run time calibration test has been initiated." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 28 - --- Misc. Traps - -restartAgent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Agent restarting as commanded by manager." - --#TYPE "APC SNMP Agent: Agent restarting" - --#SUMMARY "Agent restarting as commanded by manager." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 29 - -upsTurnedOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A UPS is turned on." - --#TYPE "APC UPS: A UPS is turned on." - --#SUMMARY " A UPS is turned on." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 30 - -smartAvrReducing TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS is reducing the line voltage via SmartTrim(TM)." - --#TYPE "APC UPS: SmartTrim(TM) reducing" - --#SUMMARY "The UPS has enabled SmartTrim(TM) voltage reduction." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 31 - -codeAuthenticationDone TRAP-TYPE - ENTERPRISE apc - VARIABLES { mconfigTFTPServerIP, newCodeAuthentViaTFTP } - DESCRIPTION - "INFORMATIONAL: Authentication on agent code image is done." - --#TYPE "APC CODE: Authentication on agent code image is done." - --#SUMMARY "Authentication on agent code image is done." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 32 - -upsOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The overload condition has been cleared." - --#TYPE "APC UPS: Overload cleared." - --#SUMMARY "The overload condition has been cleared. ." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 33 - -smartBoostOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has returned from SmartBoost(TM)." - --#TYPE "APC UPS: SmartBoost(TM) off." - --#SUMMARY "The UPS has returned from SmartBoost(TM)." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 34 - -smartAvrReducingOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has returned from SmartTrim(TM)." - --#TYPE "APC UPS: SmartTrim(TM) reducing off" - --#SUMMARY "The UPS has returned from SmartTrim(TM) voltage reduction." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 35 - -upsBatteryReplaced TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A bad battery fault has been cleared." - --#TYPE "APC UPS: Bad battery replaced" - --#SUMMARY "The UPS has returned from a bad battery fault." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 36 - -calibrationEnd TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS has finished calibrating." - --#TYPE "APC UPS: Calibration end" - --#SUMMARY "The UPS has finished calibrating" - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 37 - -dischargeCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A UPS discharge condition has been cleared." - --#TYPE "APC UPS: Discharge cleared." - --#SUMMARY "The UPS discharge condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 38 - -gracefullShutdown TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A graceful shutdown has been initiated." - --#TYPE "APC UPS: A graceful shutdown has been initiated." - --#SUMMARY "A graceful shutdown has been initiated." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 39 - - -outletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletControlIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has turned on. - If sPDUOutletControlIndex equals zero, then all outlets have - turned on." - --#TYPE "APC PDU: Outlet has been turned on." - --#SUMMARY "Outlet has been turned on" - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 41 - - -outletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletControlIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has turned off. - If sPDUOutletControlIndex equals zero, then all outlets - have turned off." - --#TYPE "APC PDU: Outlet has turned off." - --#SUMMARY "Outlet has turned off." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 42 - -outletReboot TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletControlIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has rebooted. - If sPDUOutletControlIndex equals zero, then all outlets - have rebooted." - --#TYPE "APC PDU: Outlet has rebooted." - --#SUMMARY "Outlet has rebooted." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 43 - -configChangeSNMP TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The SNMP configuration has been changed." - --#TYPE "APC: The SNMP configuration has been changed." - --#SUMMARY "The SNMP configuration has been changed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 44 - - -configChangeOutlet TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUOutletConfigIndex } - DESCRIPTION - "WARNING: The specified PDU outlet has changed configuration. - If sPDUOutletConfigIndex equals zero, then the Master outlet - has changed configuration." - --#TYPE "APC PDU: Outlet configuration has been changed." - --#SUMMARY "Outlet configuration has been changed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 45 - -accessViolationConsole TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Someone has attempted to login via the console with the incorrect password." - --#TYPE "APC: Access violation via the console." - --#SUMMARY "Three unsuccessful logins have been attempted via the console." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 46 - -accessViolationHTTP TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Someone has attempted to login via HTTP with the incorrect password." - --#TYPE "APC: Access violation via HTTP." - --#SUMMARY "An unsuccessful attempt to login via HTTP." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 47 - -passwordChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The password for the device has been changed." - --#TYPE "APC: Password change for the device." - --#SUMMARY "Someone has changed the password on the device." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 48 - -badVoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The output voltage is not within acceptable range." - --#TYPE "APC UPS: Bad output voltage." - --#SUMMARY "The output voltage is not within acceptable range." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 49 - -badVoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The output voltage has returned to an acceptable level." - --#TYPE "APC UPS: The bad voltage output condition has been cleared." - --#SUMMARY "The output voltage has returned to an acceptable level." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 50 - -chargerFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The battery charger has failed." - --#TYPE "APC UPS: The battery charger has failed." - --#SUMMARY "The battery charger has failed." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 51 - -chargerFailureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The battery charger failure condition has been cleared." - --#TYPE "APC UPS: The battery charger failure condition cleared" - --#SUMMARY "The battery charger failure condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 52 - -batteryOverTemperature TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The battery temperature threshold has been violated." - --#TYPE "APC UPS: The battery temperature threshold has been violated." - --#SUMMARY "The battery temperature threshold has been violated." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 53 - -batteryOverTemperatureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The battery over temperature has been cleared." - --#TYPE "APC UPS: The battery over temperature has been cleared." - --#SUMMARY "The battery over temperature has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 54 - - smartRelayFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: SmartBoost(TM) or SmartTrim(TM) relay fault." - --#TYPE "APC UPS: SmartBoost(TM) or SmartTrim(TM) relay fault." - --#SUMMARY "SmartBoost(TM) or SmartTrim(TM) relay fault." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 55 - -smartRelayFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: SmartBoost(TM) or SmartTrim(TM) relay fault has been cleared." - --#TYPE "APC UPS: SmartBoost(TM) or SmartTrim(TM) relay fault cleared." - --#SUMMARY "SmartBoost(TM) or SmartTrim(TM) relay fault has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 56 - -humidityThresholdViolation1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Probe 1 humidity threshold violated. The - first variable is the current humidity." - --#TYPE "APC Environmental Monitor: Probe 1 humidity threshold violation" - --#SUMMARY "A humidity threshold has been violated on probe 1." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 57 - -humidityThresholdViolationCleared1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor humidity threshold violation has been cleared on probe 1." - --#TYPE "APC Environmental Monitor: Probe 1 humidity violation cleared" - --#SUMMARY "A humidity threshold violation has been cleared on probe 1." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 58 - -temperatureThresholdViolation1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Environmental Monitor temperature threshold has been violated on probe 1. - The first variable is the current temperature." - --#TYPE "APC Environmental Monitor: Probe 1 temperature violation" - --#SUMMARY "A temperature threshold has been violated on probe 1." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 59 - -temperatureThresholdViolationCleared1 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor temperature threshold violation has been cleared on probe 1." - --#TYPE "APC Environmental Monitor: Probe 1 temperature violation cleared" - --#SUMMARY "A temperature threshold violation has been cleared on probe 1." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 60 - -humidityThresholdViolation2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Environmental Monitor humidity threshold has been violated on probe 2. - The first variable is the current humidity." - --#TYPE "APC Environmental Monitor: Probe 2 humidity violation" - --#SUMMARY "A humidity threshold has been violated on probe 2." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 61 - -humidityThresholdViolationCleared2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor humidity threshold violation has been cleared on probe 2." - --#TYPE "APC Environmental Monitor: Probe 2 humidity violation cleared" - --#SUMMARY "A humidity threshold violation has been cleared on probe 2." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 62 - -temperatureThresholdViolation2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Environmental Monitor temperature threshold has been violated on probe 2. - The first variable is the current temperature." - --#TYPE "APC Environmental Monitor: Probe 2 temperature violation" - --#SUMMARY "A temperature threshold has been violated on probe 2." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 63 - -temperatureThresholdViolationCleared2 TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Environmental Monitor temperature threshold violation has been cleared on probe 2." - --#TYPE "APC Environmental Monitor: Probe 2 temperature violation cleared" - --#SUMMARY "A temperature threshold violation has been cleared on probe 2." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 64 - -mupsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication with the Environmental Monitor has been established." - --#TYPE "APC Environmental Monitor: Communication established" - --#SUMMARY "Communication established between the agent and the Environmental Monitor." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 65 - -mupsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communication to the Environmental Monitor has been lost. Steps - to reestablish communication are in progress." - --#TYPE "APC Environmental Monitor: Communication failure" - --#SUMMARY "Communication lost between the agent and the Environmental Monitor." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 66 - -batteryIncrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of batteries has increased." - --#TYPE "APC UPS: The number of batteries has increased." - --#SUMMARY "The number of batteries has increased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 67 - -batteryDecrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of batteries has decreased." - --#TYPE "APC UPS: The number of batteries has decreased." - --#SUMMARY "The number of batteries has decreased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 68 - -powerModuleIncrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of power modules has increased." - --#TYPE "APC UPS: The number of power modules has increased." - --#SUMMARY "The number of power modules has increased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 69 - -powerModuleDecrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of power modules has decreased." - --#TYPE "APC UPS: The number of power modules has decreased." - --#SUMMARY "The number of power modules has decreased." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 70 - -intelligenceModuleInserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An intelligence module has been inserted." - --#TYPE "APC UPS: An intelligence module has been inserted." - --#SUMMARY "An intelligence module has been inserted." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 71 - -intelligenceModuleRemoved TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An intelligence module has been removed." - --#TYPE "APC UPS: An intelligence module has been removed." - --#SUMMARY "An intelligence module has been removed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 72 - -rintelligenceModuleInserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A redundant intelligence module has been inserted." - --#TYPE "APC UPS: A redundant intelligence module has been inserted." - --#SUMMARY "A redundant intelligence module has been inserted." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 73 - -rintelligenceModuleRemoved TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A redundant intelligence module has been removed." - --#TYPE "APC UPS: A redundant intelligence module has been removed." - --#SUMMARY "A redundant intelligence module has been removed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 74 - -extBatteryFrameIncease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An external battery frame has been added." - --#TYPE "APC UPS: An external battery frame has been added." - --#SUMMARY "An external battery frame has been added." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 75 - -extBatteryFrameDecrease TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An external battery frame has been removed." - --#TYPE "APC UPS: An external battery frame has been removed." - --#SUMMARY "An external battery frame has been removed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 76 - -abnormalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An abnormal condition has been detected. - The first variable is the fault condition." - --#TYPE "APC: An abnormal condition has been detected." - --#SUMMARY "An abnormal condition has been detected." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 77 - -abnormalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An abnormal condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC: An abnormal condition has been cleared." - --#SUMMARY "An abnormal condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 78 - -deviceStatusChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString} - DESCRIPTION - "INFORMATIONAL: The status of the device being monitored has changed." - --#TYPE "APC : The status of the device being monitored has changed." - --#SUMMARY "The status of the device being monitored has changed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 79 - -noBatteries TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The UPS has no batteries attached." - --#TYPE "APC UPS: No batteries attached." - --#SUMMARY "The UPS has no batteries attached." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 80 - -noBatteriesCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The UPS's batteries have been attached." - --#TYPE "APC UPS: The no batteries attached condition has been cleared." - --#SUMMARY "The UPS's batteries have been attached." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 81 - -userAdded TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A new user has been added." - --#TYPE "APC: A new user has been added." - --#SUMMARY "A new user has been added." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 82 - -userDeleted TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user has been deleted." - --#TYPE "APC: A user has been deleted." - --#SUMMARY "A user has been deleted." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 83 - -userModified TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user has been modified." - --#TYPE "APC: A user has been modified." - --#SUMMARY "A user has been modified." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 84 - --- MasterSwitch Vm Traps - -msvmCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the MasterSwitch VM has been established." - --#TYPE "APC: Communications established with the MasterSwitch VM." - --#SUMMARY "Communications with the MasterSwitch VM has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 85 - -msvmCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the MasterSwitch VM has been lost." - --#TYPE "APC: Communications lost with the MasterSwitch VM." - --#SUMMARY "Communications with the MasterSwitch VM has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 86 - -msvmOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "SEVERE: The MasterSwitch VM in an overload condition." - --#TYPE "APC: The MasterSwitch VM is near or at an overload condition." - --#SUMMARY "The MasterSwitch VM is near or at an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 87 - -msvmOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The overload condition on the MasterSwitch VM has been cleared." - --#TYPE "APC: The overload condition cleared on the MasterSwitch VM." - --#SUMMARY "The overload condition on the MasterSwitch VM has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 88 - -msvmOutletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, - sPDUOutletControlVMOutletIndex, sPDUOutletControlVMOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch VM has turned on." - --#TYPE "APC: An outlet on the MasterSwitch VM has turned on." - --#SUMMARY "An outlet on the MasterSwitch VM has turned on." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 89 - -msvmOutletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, - sPDUOutletControlVMOutletIndex, sPDUOutletControlVMOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch VM has turned off." - --#TYPE "APC: An outlet on the MasterSwitch VM has turned off." - --#SUMMARY "An outlet on the MasterSwitch VM has turned off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 90 - -msvmDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on a MasterSwitch VM." - --#TYPE "APC: A device configuration change on a MasterSwitch VM." - --#SUMMARY "A device configuration change has been made on a MasterSwitch VM." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 91 - -msvmOutletConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, - sPDUOutletControlVMOutletIndex, sPDUOutletControlVMOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet configuration change has been made on a MasterSwitch VM." - --#TYPE "APC: An outlet configuration change on a MasterSwitch VM." - --#SUMMARY "An outlet configuration change has been made on a MasterSwitch VM." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 92 - -msvmLowLoad TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The MasterSwitch VM has violated the low load threshold." - --#TYPE "APC: The MasterSwitch VM has violated the low load threshold." - --#SUMMARY "The MasterSwitch VM has violated the low load threshold." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 93 - -msvmLowLoadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The low load condition on the MasterSwitch VM has been cleared." - --#TYPE "APC: The low load condition cleared on the MasterSwitch VM." - --#SUMMARY "The low load condition on the MasterSwitch VM has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 94 - -msvmNearOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "SEVERE: The MasterSwitch VM is approaching an overload condition." - --#TYPE "APC: The MasterSwitch VM is near or at an overload condition." - --#SUMMARY "The MasterSwitch VM is near or at an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 95 - -msvmNearOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The near overload condition on the MasterSwitch VM has been cleared." - --#TYPE "APC: The overload condition cleared on the MasterSwitch VM." - --#SUMMARY "The overload condition on the MasterSwitch VM has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 96 - -msvmPowerSupplyStatusChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlVMIndex, sPDUMasterControlVMName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The power supply status of the MasterSwitch VM has changed." - --#TYPE "APC: The power supply status changed on MasterSwitch VM" - --#SUMMARY "The power supply status of the MasterSwitch VM has changed." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 97 - --- MasterSwitch plus (MSP) Traps - -mspCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the MasterSwitch plus has been established." - --#TYPE "APC: Communications established with the MasterSwitch plus." - --#SUMMARY "Communications with the MasterSwitch plus has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 98 - -mspCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the MasterSwitch plus has been lost." - --#TYPE "APC: Communications lost with the MasterSwitch plus." - --#SUMMARY "Communications with the MasterSwitch plus has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 99 - -mspOutletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, - sPDUOutletControlMSPOutletIndex, sPDUOutletControlMSPOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch plus has turned on." - --#TYPE "APC: An outlet on the MasterSwitch plus has turned on." - --#SUMMARY "An outlet on the MasterSwitch plus has turned on." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 100 - -mspOutletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, - sPDUOutletControlMSPOutletIndex, sPDUOutletControlMSPOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the MasterSwitch plus has turned off." - --#TYPE "APC: An outlet on the MasterSwitch plus has turned off." - --#SUMMARY "An outlet on the MasterSwitch plus has turned off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 101 - -mspDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on a MasterSwitch plus." - --#TYPE "APC: A device configuration change on a MasterSwitch plus." - --#SUMMARY "A device configuration change has been made on a MasterSwitch plus." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 102 - -mspOutletConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { sPDUMasterControlMSPIndex, sPDUMasterControlMSPName, sPDUOutletControlMSPOutletIndex, sPDUOutletControlMSPOutletName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet configuration change has been made on a MasterSwitch plus." - --#TYPE "APC: An outlet configuration change on a MasterSwitch plus." - --#SUMMARY "An outlet configuration change has been made on a MasterSwitch plus." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 103 - -rsSourceSwitched TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger02, mtrapargsString03, mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Redundant Switch has switched source. - The first variable is an integer representing the current source: 0=A, 1=B. - The second variable is the 32-character name of the current source. - The third variable is an integer representing the transfer cause: - 0=No Transfers Recorded, 1=Due to user action or preferred switching, - 3=Due to line notch or spike, 5=Due to low line voltage, - 7=Transfer due to high line voltage, - 9=Transfer due to frequency out of range. - The fourth variable is a character string listing the transfer cause." - --#TYPE "APC Redundant Switch: The Redundant Switch has switched source" - --#SUMMARY "The Redundant Switch has switched source." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 104 - -rsLostRedundancy TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: The Redundant Switch has lost redundancy. - The first variable is an integer representing the source which is no longer available: 0=A, 1=B. - The second variable is the 32-character name of the source which is no longer available." - --#TYPE "APC Redundant Switch: The Redundant Switch has lost redundancy" - --#SUMMARY "The Redundant Switch has has lost redundancy." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 105 - -rsRedundancyRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Redundancy has been restored to the Redundant Switch . - The first variable is an integer representing the source which has been restored: 0=A, 1=B. - The second variable is the 32-character name of the source which has been restored." - --#TYPE "APC Redundant Switch: Redundancy has been restored." - --#SUMMARY "Redundancy has been restored to the Redundant Switch ." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 106 - -rsConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A configuration change has been made on a Redundant Switch." - --#TYPE "APC: A configuration change on a Redundant Switch." - --#SUMMARY "A configuration change has been made on a Redundant Switch." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 107 - -rsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the Redundant Switch has been established." - --#TYPE "APC: Communications established with the Redundant Switch." - --#SUMMARY "Communications with the Redundant Switch has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 108 - -rsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the Redundant Switch has been lost." - --#TYPE "APC: Communications lost with the Redundant Switch." - --#SUMMARY "Communications with the Redundant Switch has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 109 - -dcCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the DC power plant has been established." - --#TYPE "APC: Communications established with the DC power plant." - --#SUMMARY "Communications with the DC power plant has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 110 - -dcCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the DC power plant has been lost." - --#TYPE "APC: Communications lost with the DC power plant." - --#SUMMARY "Communications with the DC power plant has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 111 - -dcPINChanged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The active PIN on the DC controller has been changed." - --#TYPE "APC: The active PIN on the DC controller has been changed." - --#SUMMARY "The active PIN on the DC controller has been changed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 112 - -dcMajorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: A Major alarm is active in the DC power plant." - --#TYPE "APC: A Major alarm is active in the DC power plant." - --#SUMMARY "A Major alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 113 - -dcMajorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Major alarm is no longer active in the DC power plant." - --#TYPE "APC: A Major alarm is no longer active in the DC power plant." - --#SUMMARY "A Major alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 114 - -dcMinorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Minor alarm is active in the DC power plant." - --#TYPE "APC: A Minor alarm is active in the DC power plant." - --#SUMMARY "A Minor alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 115 - -dcMinorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Minor alarm is no longer active in the DC power plant." - --#TYPE "APC: A Minor alarm is no longer active in the DC power plant." - --#SUMMARY "A Minor alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 116 - -dcOutputRelayOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusOutRlyIndex, dm3StatusOutRlyName, mtrapargsString } - DESCRIPTION - "WARNING: An output relay for the powerplant has been activated (state changed to on). - The first variable is an integer representing the output relay number that has gone on. - The second variable is the 16-character name of the output relay." - --#TYPE "APC: An output relay has gone on." - --#SUMMARY "An output relay has gone on in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 117 - -dcOutputRelayOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusOutRlyIndex, dm3StatusOutRlyName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An output relay for the powerplant has been deactivated (state changed to off). - The first variable is an integer representing the output relay number that has gone off. - The second variable is the 16-character name of the output relay." - --#TYPE "APC: An output relay has gone off." - --#SUMMARY "An output relay has gone off in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 118 - -dcInputRelayOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusInRlyIndex, dm3StatusInRlyName, mtrapargsString } - DESCRIPTION - "WARNING: An input relay for the powerplant has been activated (state changed to on). - The first variable is an integer representing the input relay number that has gone on. - The second variable is the 16-character name of the input relay." - --#TYPE "APC: An input relay has gone on." - --#SUMMARY "An input relay has gone on in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 119 - -dcInputRelayOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { dm3StatusInRlyIndex, dm3StatusInRlyName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An input relay for the powerplant has been deactivated (state changed to off). - The first variable is an integer representing the input relay number that has gone off. - The second variable is the 16-character name of the input relay." - --#TYPE "APC: An input relay has gone off." - --#SUMMARY "An input relay has gone off in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 120 - -logicPowerSuppliesIncreased TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of system power supplies has increased." - --#TYPE "APC UPS: The number of system power supplies has increased." - --#SUMMARY "The number of system power supplies has increased." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 121 - -logicPowerSuppliesDecreased TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The number of system power supplies has decreased." - --#TYPE "APC UPS: The number of system power supplies has decreased." - --#SUMMARY "The number of system power supplies has decreased." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 122 - -externalSwitchGearClosed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: External Switch Gear closed." - --#TYPE "APC UPS: External Switch Gear closed." - --#SUMMARY "External Switch Gear closed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 123 - -externalSwitchGearOpened TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: External Switch Gear opened." - --#TYPE "APC UPS: External Switch Gear opened." - --#SUMMARY "External Switch Gear opened." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 124 - -generalDeviceEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: APC Device event." - --#TYPE "APC Device event" - --#SUMMARY "APC Device event." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 125 - -atsSourceSwitched TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Automatic Transfer Switch has switched source. - The first variable is an integer representing the current source: 0=A, 1=B. - The second variable is the 32-character name of the current source." - --#TYPE "APC Automatic Transfer Switch: The ATS has switched source" - --#SUMMARY "The Automatic Transfer Switch has switched source." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 126 - -atsLostRedundancy TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: The Automatic Transfer Switch has lost redundancy. - The first variable is an integer representing the source which is no longer available: 0=A, 1=B. - The second variable is the 32-character name of the source which is no longer available." - --#TYPE "APC Automatic Transfer Switch: The ATS has lost redundancy. " - --#SUMMARY "The Automatic Transfer Switch has has lost redundancy." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 127 - -atsRedundancyRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Redundancy has been restored to the Automatic Transfer Switch . - The first variable is an integer representing the source which has been restored: 0=A, 1=B. - The second variable is the 32-character name of the source which has been restored." - --#TYPE "APC Automatic Transfer Switch: Redundancy has been restored." - --#SUMMARY "Redundancy has been restored to the Automatic Transfer Switch ." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 128 - -atsConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A configuration change has been made on the Automatic Transfer Switch. - The first variable is an integer representing the configuration setting which changed: - 0=Transfer Voltage Range, 1=Sensitivity 2=Preferred Source - 3=Front Panel Lockout 4=Current Limit" - --#TYPE "APC Automatic Transfer Switch: ATS configuration changed." - --#SUMMARY "A configuration change has been made on a Automatic Transfer Switch." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 129 - -atsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communications with the Automatic Transfer Switch has been established." - --#TYPE "APC Automatic Transfer Switch: Communications established." - --#SUMMARY "Communications with the Automatic Transfer Switch has been established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 130 - -atsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Communications with the Automatic Transfer Switch has been lost." - --#TYPE "APC Automatic Transfer Switch: Communications lost." - --#SUMMARY "Communications with the Automatic Transfer Switch has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 131 - -atsOverCurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Output Current has exceeded threshold." - --#TYPE "APC Automatic Transfer Switch: Output Current exceeded threshold" - --#SUMMARY "Output Current has exceeded Threshold. " - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 132 - -atsOverCurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Output Current has returned below threshold." - --#TYPE "APC Automatic Transfer Switch: Output Current below threshold." - --#SUMMARY "Output Current has returned below threshold." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 133 - -atsPowerSupplyFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The Automatic Transfer Switch Power Supply has failed. - The first variable is an integer representing the Power Supply which - has failed: 0=24V, 1=12V 2=5V." - --#TYPE "APC Automatic Transfer Switch: The ATS Power Supply has failed." - --#SUMMARY "The Automatic Transfer Switch Power Supply has failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 134 - -atsPowerSupplyFailureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Automatic Transfer Power Supply Failure Cleared. - The first variable is an integer representing the Power Supply which - has cleared: 0=24V, 1=12V 2=5V." - --#TYPE "APC Automatic Transfer Switch: Power Supply Failure Cleared." - --#SUMMARY "The Automatic Transfer Switch Power Supply Failure Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 135 - -dcMainsFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Mains Fail alarm is active in the DC power plant." - --#TYPE "APC: A Mains Fail alarm is active in the DC power plant." - --#SUMMARY "A Mains Fail alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 136 - -dcMainsFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Mains Fail alarm is no longer active in the DC power plant." - --#TYPE "APC: Mains Fail alarm is no longer active in the DC power plant." - --#SUMMARY "Mains Fail alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 137 - -dcFanFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Fan Fail alarm is active in the DC power plant." - --#TYPE "APC: A Fan Fail alarm is active in the DC power plant." - --#SUMMARY "A Fan Fail alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 138 - -dcFanFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Fan Fail alarm is no longer active in the DC power plant." - --#TYPE "APC: A Fan Fail alarm is no longer active in the DC power plant." - --#SUMMARY "A Fan Fail alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 139 - -dcRectifierOvertempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Rect. Overtemp alarm is active in the power plant." - --#TYPE "APC: Rect. Overtemp alarm is active in the power plant." - --#SUMMARY "Rect. Overtemp alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 140 - -dcRectifierOvertempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Rect. Overtemp alarm is no longer active in the power plant." - --#TYPE "APC: Rect. Overtmp alarm is no longer active in the power plant." - --#SUMMARY "Rect. Overtmp alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 141 - -dcCurrentLimitAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Current Limit alarm is active in the power plant." - --#TYPE "APC: A Current Limit alarm is active in the power plant." - --#SUMMARY "A Current Limit alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 142 - -dcCurrentLimitAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Current Limit alarm is no longer active in the power plant." - --#TYPE "APC: Current Limit alarm is no longer active in the power plant." - --#SUMMARY "Current Limit alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 143 - -dcRectifierFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Rect. Fail alarm is active in the power plant." - --#TYPE "APC: A Rect. Fail alarm is active in the power plant." - --#SUMMARY "A Rect. Fail alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 144 - -dcRectifierFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Rect. Fail alarm is no longer active in the power plant." - --#TYPE "APC: Rect. Fail alarm is no longer active in the power plant." - --#SUMMARY "Rect. Fail alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 145 - -dcMultRectFailAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Multiple Rect. Fail alarm is active in the powerplant." - --#TYPE "APC: Multiple Rect. Fail alarm is active in the powerplant." - --#SUMMARY "Multiple Rect. Fail alarm is active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 146 - -dcMultRectFailAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Mult Rect Fail alarm is no longer active in the powerplant." - --#TYPE "APC: Mult Rect Fail alarm is no longer active in the powerplant." - --#SUMMARY "Mult Rect Fail alarm is no longer active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 147 - -dcBatteryBreakerAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: Batt. Breaker alarm is active in the power plant." - --#TYPE "APC: Batt. Breaker alarm is active in the power plant." - --#SUMMARY "Batt. Breaker alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 148 - -dcBatteryBreakerAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Batt. Breaker alarm is no longer active in the power plant." - --#TYPE "APC: Batt. Breaker alarm is no longer active in the power plant." - --#SUMMARY "Batt. Breaker alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 149 - -dcRectifierOVPAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Rect. OVP alarm is active in the power plant." - --#TYPE "APC: A Rect. OVP alarm is active in the power plant." - --#SUMMARY "A Rect. OVP alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 150 - -dcRectifierOVPAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Rect. OVP alarm is no longer active in the power plant." - --#TYPE "APC: A Rect. OVP alarm is no longer active in the power plant." - --#SUMMARY "A Rect. OVP alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 151 - -dcLVDImminentAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A LVD Imminent alarm is active in the powerplant." - --#TYPE "APC: A LVD Imminent alarm is active in the powerplant." - --#SUMMARY "A LVD Imminent alarm is active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 152 - -dcLVDImminentAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A LVD Imminent alarm is no longer active in the powerplant." - --#TYPE "APC: A LVD Imminent alarm is no longer active in the powerplant." - --#SUMMARY "A LVD Imminent alarm is no longer active in the powerplant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 153 - -dcFuseCBAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Fuse/CB alarm is active in the DC power plant." - --#TYPE "APC: A Fuse/CB alarm alarm is active in the DC power plant." - --#SUMMARY "A Fuse/CB alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 154 - -dcFuseCBAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Fuse/CB alarm is no longer active in the DC power plant." - --#TYPE "APC: A Fuse/CB alarm is no longer active in the DC power plant." - --#SUMMARY "A Fuse/CB alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 155 - -dcBatteryTestFail TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Battery Test failed in the DC power plant." - --#TYPE "APC: A Battery Test failed in the DC power plant." - --#SUMMARY "A Battery Test failed in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 156 - -dcTemperatureAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Temperature is active in the power plant." - --#TYPE "APC: A Temperature alarm is active in the power plant." - --#SUMMARY "A Temperature alarm is active in the power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 157 - -dcTemperatureAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Temperature alarm is no longer active in the power plant." - --#TYPE "APC: A Temperature alarm is no longer active in the power plant." - --#SUMMARY "A Temperature alarm is no longer active in the power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 158 - -dcHumidityAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: A Humidity alarm is active in the DC power plant." - --#TYPE "APC: A Humidity alarm is active in the DC power plant." - --#SUMMARY "A Humidity alarm is active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 159 - -dcHumidityAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Humidity alarm is no longer active in the DC power plant." - --#TYPE "APC: A Humidity alarm is no longer active in the DC power plant." - --#SUMMARY "A Humidity alarm is no longer active in the DC power plant." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 160 - -dcBBCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Power plant bridging board communications established." - --#TYPE "APC: Power plant bridging board communications established." - --#SUMMARY "Power plant bridging board communications established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 161 - -dcBBCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "SEVERE: Power plant bridging board communications lost." - --#TYPE "APC: Power plant bridging board communications lost." - --#SUMMARY "Power plant bridging board communications lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 162 - -iemHighTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentTemp, iemStatusProbeTempUnits, iemStatusProbeNumber, - iemStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: High temperature threshold violated on Integrated - Environmental Monitor probe. The first variable is the - current temperature. The second variable is the temperature - scale. The third variable is the probe number. The fourth - variable is the probe name." - --#TYPE "APC IEM: High temperature threshold violation." - --#SUMMARY "High temperature threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 163 - -iemHighTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High temperature threshold violated on Integrated - Environmental Monitor probe has been cleared. The first variable - is the probe number. The second variable is the probe name." - --#TYPE "APC IEM: High temperature threshold violation cleared." - --#SUMMARY "High temperature threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 164 - -iemLowTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentTemp, iemStatusProbeTempUnits, iemStatusProbeNumber, - iemStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Low temperature threshold violated on integrated - probe. The first variable is the current temperature. The - second variable is the temperature scale. The third - variable is the probe number. The fourth variable is the - probe name." - --#TYPE "APC IEM: Low temperature threshold violation." - --#SUMMARY "Low temperature threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 165 - -iemLowTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low temperature threshold violated on integrated - probe has been cleared. The first variable is the probe number. - The second variable is the probe name." - --#TYPE "APC IEM: Low temperature threshold violation cleared." - --#SUMMARY "Low temperature threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 166 - -iemHighHumidThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentHumid, iemStatusProbeNumber, iemStatusProbeName, - mtrapargsString } - DESCRIPTION - "SEVERE: High humidity threshold violated on integrated - probe. The first variable is the current humidity. The - second variable is the probe number. The third variable - is the probe name." - --#TYPE "APC IEM: High humidity threshold violation." - --#SUMMARY "High humidity threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 167 - -iemHighHumidThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High humidity threshold violated on integrated - probe cleared. The first variable is the probe number. The second - variable is the probe name." - --#TYPE "APC IEM: High humidity threshold violation cleared." - --#SUMMARY "High humidity threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 168 - -iemLowHumidThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeCurrentHumid, iemStatusProbeNumber, iemStatusProbeName, - mtrapargsString } - DESCRIPTION - "SEVERE: Low humidity threshold violated on integrated - probe. The first variable is the current humidity. The - second variable is the probe number. The third variable - is the probe name." - --#TYPE "APC IEM: Low humidity threshold violation." - --#SUMMARY "Low humidity threshold violation." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 169 - -iemLowHumidThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusProbeNumber, iemStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low humidity threshold violated on integrated - probe cleared. The first variable is the probe number. The second - variable is the probe name." - --#TYPE "APC IEM: Low humidity threshold violation cleared." - --#SUMMARY "Low humidity threshold violation has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 170 - -iemProbeDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The temperature/humidity probe on the Integrated - Environmental Monitor has been disconnected. This trap is - generated when a probe that has been in communication with - the Environmental Monitor has been disconnected or can no - longer communicate." - --#TYPE "APC IEM: Probe disconnected." - --#SUMMARY "Probe has been disconnected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 171 - -iemProbeConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The temperature/humidity probe on the Integrated - Environmental Monitor has been connected. This trap is generated - when the Environmental Monitor establishes communication with a - probe that had previously not been connected." - --#TYPE "APC IEM: Probe Connected." - --#SUMMARY "Probe has been connected." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 172 - -iemContactFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusContactNumber, iemStatusContactName, mtrapargsString } - DESCRIPTION - "SEVERE: There is a contact fault on the Integrated - Environmental Monitor. The first argument is the number - of the contact. The second argument is the name of the - contact." - --#TYPE "APC IEM: Contact fault." - --#SUMMARY "Contact fault." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 173 - -iemContactFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusContactNumber, iemStatusContactName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The contact fault on the Integrated - Environmental Monitor has been cleared. The first - argument is the number of the contact. The second - argument is the name of the contact." - --#TYPE "APC IEM: Contact fault." - --#SUMMARY "Contact fault cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 174 - -iemRelayFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusRelayNumber, iemStatusRelayName, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: The output relay on the Integrated Environmental - Monitor has switched to the fault state. The first - argument is the number of the output relay. The second - argument is the name of the output relay. The third - argument is the event that caused the fault." - --#TYPE "APC IEM: Output relay fault." - --#SUMMARY "Output relay has faulted." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 175 - -iemRelayFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { iemStatusRelayNumber, iemStatusRelayName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The fault condition on the output relay on the - Integrated Environmental Monitor has cleared. The first - argument is the number of the output relay. The second - argument is the name of the output relay." - --#TYPE "APC IEM: Output relay fault condition cleared." - --#SUMMARY "Output relay fault cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 176 - -bmBatManCommEstab TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Serial Communications Established with Battery Manager." - --#TYPE "BatMan : Communications Established." - --#SUMMARY "Communications Established." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 177 - -bmBatManCommLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Serial Communications Lost with Battery Manager." - --#TYPE "BatMan : Communications Lost." - --#SUMMARY "Communications Lost." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 178 - -bmBatManKneeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Battery Voltage Knee Threshold Alarm Detected." - --#TYPE "BatMan : Knee Alarm Detected." - --#SUMMARY "Knee Alarm Detected." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 179 - -bmBatManKneeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Battery Voltage Knee Threshold Alarm Cleared." - --#TYPE "BatMan : Knee Alarm Cleared." - --#SUMMARY "Knee Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 180 - -bmBatManChargerAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Charger Alarm Detected." - --#TYPE "BatMan : Charger Alarm Detected." - --#SUMMARY "Charger Alarm Detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 181 - -bmBatManChargerAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Charger Alarm Cleared." - --#TYPE "BatMan : Charger Alarm Cleared." - --#SUMMARY "Charger Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 182 - -bmBatManBatteryAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Battery Alarm Detected." - --#TYPE "BatMan : Battery Alarm Detected." - --#SUMMARY "Battery Alarm Detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 183 - -bmBatManBatteryAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Battery Alarm Cleared." - --#TYPE "BatMan : Battery Alarm Cleared." - --#SUMMARY "Battery Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 184 - -bmBatManEnvironmentAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Environment Alarm Detected." - --#TYPE "BatMan : Environment Alarm Detected." - --#SUMMARY "Environment Alarm Detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 185 - -bmBatManEnvironmentAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Environment Alarm Cleared." - --#TYPE "BatMan : Environment Alarm Cleared." - --#SUMMARY "Environment Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 186 - -bmBatManMaintenanceAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Maintenance Alarm Detected." - --#TYPE "BatMan : Maintenance Due Alarm Detected." - --#SUMMARY "Maintenance Due Alarm Detected." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 187 - -bmBatManMaintenanceAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Maintenance Alarm Cleared." - --#TYPE "BatMan : Maintenance Due Alarm Cleared." - --#SUMMARY "Maintenance Due Alarm Cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 188 - -pduCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication Established. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 189 - -pduCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Communication Lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 190 - -pduUtilityLineUndervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Utility Line Undervoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Undervoltage." - --#SUMMARY "Utility Line Undervoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 191 - -pduUtilityLineUndervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Utility Line Undervoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Undervoltage Cleared." - --#SUMMARY "Utility Line Undervoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 192 - -pduUtilityLineOvervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Utility Line Overvoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Overvoltage." - --#SUMMARY "Utility Line Overvoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 193 - -pduUtilityLineOvervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Utility Line Overvoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Utility Line Overvoltage Cleared." - --#SUMMARY "Utility Line Overvoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 194 - -pduGroundOvercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Ground Overcurrent. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Ground Overcurrent." - --#SUMMARY "Ground Overcurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 195 - -pduGroundOvercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Ground Overcurrent Cleared. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Ground Overcurrent Cleared." - --#SUMMARY "Ground Overcurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 196 - -pduCircuitPanelInputUndervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Undervoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undervoltage." - --#SUMMARY "Circuit Panel Input Undervoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 197 - -pduCircuitPanelInputUndervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Undervoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undervoltage Cleared." - --#SUMMARY "Circuit Panel Input Undervoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 198 - -pduCircuitPanelInputOvervoltage TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Overvoltage. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overvoltage." - --#SUMMARY "Circuit Panel Input Overvoltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 199 - -pduCircuitPanelInputOvervoltageCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Overvoltage Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overvoltage Cleared." - --#SUMMARY "Circuit Panel Input Overvoltage Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 200 - -pduCircuitPanelInputUndercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Undercurrent. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undercurrent." - --#SUMMARY "Circuit Panel Input Undercurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 201 - -pduCircuitPanelInputUndercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Undercurrent Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Undercurrent Cleared." - --#SUMMARY "Circuit Panel Input Undercurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 202 - -pduCircuitPanelInputOvercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Overcurrent. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overcurrent." - --#SUMMARY "Circuit Panel Input Overcurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 203 - -pduCircuitPanelInputOvercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Overcurrent Cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: Circuit Panel Input Overcurrent Cleared." - --#SUMMARY "Circuit Panel Input Overcurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 204 - -pduCircuitPanelFrequencyOutOfRange TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Frequency Out Of Range. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Frequency Out Of Range." - --#SUMMARY "Circuit Panel Input Frequency Out Of Range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 205 - -pduCircuitPanelFrequencyOutofRangeCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Frequency No Longer Out Of Range. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Frequency No Longer Out Of Range." - --#SUMMARY "Circuit Panel Input Frequency No Longer Out Of Range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 206 - -pduCircuitPanelNeutralOvercurrent TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Circuit Panel Input Neutral Overcurrent. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Neutral Overcurrent." - --#SUMMARY "Circuit Panel Input Neutral Overcurrent." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 207 - -pduCircuitPanelNeutralOvercurrentCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Circuit Panel Input Neutral Overcurrent Cleared. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Circuit Panel Input Neutral Overcurrent Cleared." - --#SUMMARY "Circuit Panel Input Neutral Overcurrent Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 208 - -pduSystemOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: PDU System Off. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: System Off." - --#SUMMARY "PDU System Off." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 209 - -pduOnBatteryMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: PDU is in On Battery Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: On Battery Mode." - --#SUMMARY "PDU is in On Battery Mode." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 210 - -pduMaintenanceBypassMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: PDU is in Maintenance Bypass Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Maintenance Bypass Mode." - --#SUMMARY "PDU is in Maintenance Bypass Mode." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 211 - -pduAtypicalBypassMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "WARNING: PDU is in Atypical Bypass Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Atypical Bypass Mode." - --#SUMMARY "PDU is in Atypical Bypass Mode." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 212 - -pduNoPanelFeedMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: PDU is in No Panel Feed Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: No Panel Feed Mode." - --#SUMMARY "PDU is in No Panel Feed Mode." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 213 - -pduUpsOperationMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: PDU is in Ups Operation Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Ups Operation Mode." - --#SUMMARY "PDU is in Ups Operation Mode." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 214 - -pduForcedBypassMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "WARNING: PDU is in Forced Bypass Mode. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Forced Bypass Mode." - --#SUMMARY "PDU is in Forced Bypass Mode." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 215 - -pduInputTransformerOverTemperature TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Input Transformer Over Temperature. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Input Transformer Over Temperature." - --#SUMMARY "Input Transformer Over Temperature." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 216 - -pduInputTransformerOverTemperatureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Input Transformer Over Temperature Cleared. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC PDU: Input Transformer Over Temperature Cleared." - --#SUMMARY "Input Transformer Over Temperature Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 217 - -pduUPSInputVoltageLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: UPS Input Voltage phase-N Lost. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: UPS Input Voltage phase-N Lost." - --#SUMMARY "UPS Input Voltage phase-N Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 218 - -pduUPSInputVoltageRestored TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: UPS Input Voltage phase-N Restored. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC PDU: UPS Input Voltage phase-N Restored." - --#SUMMARY "UPS Input Voltage phase-N Restored." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 219 - -pduContactFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: A contact closure in the PDU is in an abnormal position. - The first argument is the serial number. - The second argument is the device name. - The third argument is the number of the contact." - --#TYPE "APC PDU: Contact Abnormal." - --#SUMMARY "Contact Abnormal." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 220 - -pduContactFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A contact closure in the PDU is in a normal position. - The first argument is the serial number. - The second argument is the device name. - The third argument is the number of the contact." - --#TYPE "APC PDU: Contact Normal." - --#SUMMARY "Contact Normal." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 221 - -rPDUBankPhaseLowLoad TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A bank or phase on the Rack PDU has violated the low load threshold. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Violation of bank or phase low load threshold." - --#SUMMARY "A bank or phase on the Rack PDU has violated the low load threshold." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 222 - -rPDUBankPhaseLowLoadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The bank or phase low load condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase low load condition cleared." - --#SUMMARY "The bank or phase low load condition on a Rack PDU has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 223 - -rPDUBankPhaseNearOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A bank or phase of the Rack PDU is near an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase near an overload condition." - --#SUMMARY "A bank or phase of the Rack PDU is near an overload condition." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 224 - -rPDUBankPhaseNearOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The bank or phase near overload condition on a Rack PDU has - been cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase near overload condition has cleared." - --#SUMMARY "Rack PDU bank or phase near overload condition has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 225 - -rPDUBankPhaseOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "SEVERE: A bank or phase of the Rack PDU is in an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase overload condition." - --#SUMMARY "A bank or phase of the Rack PDU is in an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 226 - -rPDUBankPhaseOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusBankNumber, rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The bank or phase overload condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the bank number (0 if this is phase data). - The fourth argument is the phase number (0 if this is bank data)." - --#TYPE "APC Rack PDU: Bank or phase overload condition has cleared." - --#SUMMARY "The bank or phase overload condition on a Rack PDU has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 227 - -aruDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Device Configurtion change. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: ARU Device configuration change." - --#SUMMARY "ARU device configuration change." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 228 - -rmPDUCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString03, mtrapargsString02, mtrapargsString } - DESCRIPTION - "SEVERE: Communication Lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC RM PDU: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 229 - -emsCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication Established. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC EMS: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 230 - -emsCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: Communication Lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC EMS: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 231 - -emsProbeConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A probe has been connected to the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC EMS: Probe Connected." - --#SUMMARY "Probe Connected." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 232 - -emsProbeDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: A probe has been disconnected from the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC EMS: Probe Disconnected." - --#SUMMARY "Probe Disconnected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 233 - -emsSensorConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A sensor has been connected to the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Connected." - --#SUMMARY "Sensor Connected." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 234 - -emsSensorDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "SEVERE: A sensor has been disconnected from the EMS. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Disconnected." - --#SUMMARY "Sensor Disconnected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 235 - -emsSensorFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "SEVERE: A EMS sensor is in the fault condition. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Fault." - --#SUMMARY "Sensor Fault." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 236 - -emsSensorFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsSensorStatusSensorIndex, emsSensorStatusSensorName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A EMS sensor fault condition has cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the sensor number. - The fourth argument is the sensor name." - --#TYPE "APC EMS: Sensor Fault Cleared." - --#SUMMARY "Sensor Fault Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 237 - -emsBeaconConnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A beacon has been connected to the EMS. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon Connected." - --#SUMMARY "Beacon Connected." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 238 - -emsBeaconDisconnected TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: A beacon has been disconnected from the EMS. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon Disconnected." - --#SUMMARY "Beacon Disconnected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 239 - -emsBeaconOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A EMS beacon has gone on. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon On." - --#SUMMARY "Beacon On." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 240 - -emsBeaconOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A EMS beacon has gone off. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Beacon Off." - --#SUMMARY "Beacon Off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 241 - -emsMajorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: A Major Alarm is present in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Major Alarm." - --#SUMMARY "Major Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 242 - -emsMajorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Major Alarm condition has been cleared in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Major Alarm Cleared." - --#SUMMARY "Major Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 243 - -emsMinorAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: A Minor Alarm is present in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Minor Alarm." - --#SUMMARY "Minor Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 244 - -emsMinorAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Minor Alarm condition has been cleared in the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC EMS: Minor Alarm Cleared." - --#SUMMARY "Minor Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 245 - -emsOutletStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutletStatusOutletIndex, emsOutletStatusOutletName, - emsOutletStatusOutletState, emsOutletStatusOutletNormalState, mtrapargsString } - DESCRIPTION - "WARNING: An outlet on the EMS has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the outlet number. - The fourth argument is the outlet name. - The fifth argument is the current outlet state (1=ON, 2=OFF). - The sixth argument is the configured normal outlet state (1=ON, 2=OFF)." - --#TYPE "APC EMS: Outlet has changed to its abnormal state." - --#SUMMARY "Outlet has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 246 - -emsOutletStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutletStatusOutletIndex, emsOutletStatusOutletName, - emsOutletStatusOutletState, emsOutletStatusOutletNormalState, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on the EMS has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the outlet number. - The fourth argument is the outlet name. - The fifth argument is the current outlet state (1=ON, 2=OFF). - The sixth argument is the configured normal outlet state (1=ON, 2=OFF)." - --#TYPE "APC EMS: Outlet has changed to its normal state." - --#SUMMARY "Outlet has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 247 - -emsInputContactStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsInputContactStatusInputContactIndex, - emsInputContactStatusInputContactName, emsInputContactStatusInputContactState, - emsInputContactStatusInputContactNormalState, mtrapargsString } - DESCRIPTION - "WARNING: An input contact on the EMS has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal input contact state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Input contact has changed to its abnormal state." - --#SUMMARY "Input contact has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 248 - -emsInputContactStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsInputContactStatusInputContactIndex, - emsInputContactStatusInputContactName, emsInputContactStatusInputContactState, - emsInputContactStatusInputContactNormalState, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An input contact on the EMS has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal input contact state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Input contact has changed to its normal state." - --#SUMMARY "Input contact has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 249 - -emsOutputRelayStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutputRelayStatusOutputRelayIndex, - emsOutputRelayStatusOutputRelayName, emsOutputRelayStatusOutputRelayState, - emsOutputRelayStatusOutputRelayNormalState, mtrapargsString } - DESCRIPTION - "WARNING: An output relay on the EMS has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the output relay number. - The fourth argument is the output relay name. - The fifth argument is the current output relay state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal output relay state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Output Relay has changed to its abnormal state." - --#SUMMARY "Output Relay has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 250 - -emsOutputRelayStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsOutputRelayStatusOutputRelayIndex, - emsOutputRelayStatusOutputRelayName, emsOutputRelayStatusOutputRelayState, - emsOutputRelayStatusOutputRelayNormalState, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An output relay on the EMS has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the output relay number. - The fourth argument is the output relay name. - The fifth argument is the current output relay state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal output relay state (1=CLOSED, 2=OPEN)." - --#TYPE "APC EMS: Output Relay has changed to its normal state." - --#SUMMARY "Output Relay has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 251 - -emsDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on the EMS. - The first argument is the EMS serial number. - The second argument is the EMS name." - --#TYPE "APC: A device configuration change on a EMS." - --#SUMMARY "A device configuration change has been made on a EMS." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 252 - -envHighTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: High temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: High temperature threshold violation." - --#SUMMARY "High temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 253 - -envHighTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: High temperature threshold violation cleared." - --#SUMMARY "High temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 254 - -envLowTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Low temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Low temperature threshold violation." - --#SUMMARY "Low temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 255 - -envLowTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Low temperature threshold violation cleared." - --#SUMMARY "Low temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 256 - -envHighHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: High humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: High humidity threshold violation." - --#SUMMARY "High humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 257 - -envHighHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: High humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: High humidity threshold violation cleared." - --#SUMMARY "High humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 258 - -envLowHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Low humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Low humidity threshold violation." - --#SUMMARY "Low humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 259 - -envLowHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Low humidity threshold violation cleared." - --#SUMMARY "Low humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 260 - - --- Switched and Metered Rack PDU Traps - -rPDUCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Communication with a Rack PDU has been established. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Communication established." - --#SUMMARY "Communication with a Rack PDU established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 266 - -rPDUCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "SEVERE: Communication with a Rack PDU has been lost. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Communication lost." - --#SUMMARY "Communication with a Rack PDU has been lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 267 - -rPDUOutletOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on a Switched Rack PDU has turned on. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number. - The fourth argument is the outlet name." - --#TYPE "APC Switched Rack PDU: An outlet has turned on." - --#SUMMARY "An outlet on a Switched Rack PDU has turned on." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 268 - -rPDUOutletOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet on a Switched Rack PDU has turned off. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number. - The fourth argument is the outlet name." - --#TYPE "APC Switched Rack PDU: An outlet has turned off." - --#SUMMARY "An outlet on a Switched Rack PDU has turned off." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 269 - -rPDUDeviceConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A device configuration change has been made on a - Rack PDU. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Device configuration change made." - --#SUMMARY "Device configuration change has been made on a Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 270 - -rPDUOutletConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An outlet configuration change has been made on a - Switched Rack PDU. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number. - The fourth argument is the outlet name." - --#TYPE "APC Switched Rack PDU: Outlet configuration change made." - --#SUMMARY "Outlet configuration change has been made on a Switched Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 271 - -rPDULowLoad TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A Rack PDU has violated the low load threshold. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Violation of low load threshold." - --#SUMMARY "A Rack PDU has violated the low load threshold." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 272 - -rPDULowLoadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The low load condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Low load condition cleared." - --#SUMMARY "The low load condition on a Rack PDU has been cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 273 - -rPDUNearOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "WARNING: A Rack PDU is near an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Near an overload condition." - --#SUMMARY "A Rack PDU is near an overload condition." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 274 - -rPDUNearOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The near overload condition on a Rack PDU has - been cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Near overload condition has cleared." - --#SUMMARY "Rack PDU near overload condition has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 275 - -rPDUOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "SEVERE: A Rack PDU is in an overload condition. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Overload condition." - --#SUMMARY "A Rack PDU is in an overload condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 276 - -rPDUOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadStatusPhaseNumber, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The overload condition on a Rack PDU has been - cleared. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase number." - --#TYPE "APC Rack PDU: Overload condition has cleared." - --#SUMMARY "The overload condition on a Rack PDU has cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 277 - -rPDUPowerSupply1Fail TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "SEVERE: Power Supply 1 on Rack PDU is in FAIL state. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 1 is in FAIL state." - --#SUMMARY "Power Supply 1 on Rack PDU is in FAIL state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 278 - -rPDUPowerSupply1Ok TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Power Supply 1 on Rack PDU is operating normally. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 1 is operating normally." - --#SUMMARY "Power Supply 1 on Rack PDU is operating normally." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 279 - -rPDUPowerSupply2Fail TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "SEVERE: Power Supply 2 on Rack PDU is in FAIL state. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 2 is in FAIL state." - --#SUMMARY "Power Supply 2 on Rack PDU is in FAIL state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 280 - -rPDUPowerSupply2Ok TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Power Supply 2 on Rack PDU is operating normally. - The first argument is the serial number. - The second argument is the device name." - --#TYPE "APC Rack PDU: Power Supply 2 is operating normally." - --#SUMMARY "Power Supply 2 on Rack PDU is operating normally." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 281 - -rPDUPhaseConfigChange TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDULoadPhaseConfigIndex, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A phase configuration change has been made on a - Rack PDU. - The first argument is the serial number. - The second argument is the device name. - The third argument is the phase index number." - --#TYPE "APC Rack PDU: Phase configuration change made." - --#SUMMARY "Phase configuration change has been made on a Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 282 - -rPDUCancelPendingCommand TRAP-TYPE - ENTERPRISE apc - VARIABLES { rPDUIdentSerialNumber, rPDUIdentName, - rPDUOutletControlIndex, rPDUOutletControlOutletName, - mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A cancel pending command has been made on a - Switched Rack PDU. - The first argument is the serial number. - The second argument is the device name. - The third argument is the outlet index number (0 indicates all outlets). - The fourth argument is the outlet name (or device name if all outlets)." - --#TYPE "APC Switched Rack PDU: Cancel Pending Command made." - --#SUMMARY "A Cancel Pending Command has been made on a Switched Rack PDU." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 283 - -aruAlinkCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Communication Established. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 284 - -aruAlinkCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Communication Lost. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 285 - -aruFanFail TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Fan Fail. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Fan Fail." - --#SUMMARY "Fan Fail." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 286 - -aruFanFailCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Fan Fail Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Fan Fail Cleared." - --#SUMMARY "Fan Fail Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 287 - -aruSmokeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Smoke Alarm. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Smoke Alarm." - --#SUMMARY "Smoke Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 288 - -aruSmokeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Smoke Alarm Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Smoke Alarm Cleared." - --#SUMMARY "Smoke Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 289 - -aruHighTemperatureAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU High Temperature Alarm. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: High Temperature Alarm." - --#SUMMARY "High Temperature Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 290 - -aruHighTemperatureAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU High Temperature Alarm Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: High Temperature Alarm Cleared." - --#SUMMARY "High Temperature Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 291 - -aruExhaustTemperatureAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote ARU Exhaust Temperature Alarm. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Exhaust Temperature Alarm." - --#SUMMARY "Exhaust Temperature Alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 292 - -aruExhaustTemperatureAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - rARUStatusAruIndex, rARUStatusAruName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote ARU Exhaust Temperature Alarm Cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the ARU number. - The fourth argument is the ARU name." - --#TYPE "APC ARU: Exhaust Temperature Alarm Cleared." - --#SUMMARY "Exhaust Temperature Alarm Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 293 - -envAlinkCommunicationEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Remote Probe Communication Established. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC ENV: Communication Established." - --#SUMMARY "Communication Established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 294 - -envAlinkCommunicationLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Remote Probe Communication Lost. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the probe number. - The fourth argument is the probe name." - --#TYPE "APC ENV: Communication Lost." - --#SUMMARY "Communication Lost." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 295 - -emsAlinkPowerOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: Alink Power Overload. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Alink Power Overload." - --#SUMMARY "Alink Power Overload." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 296 - -emsAlinkPowerOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Alink Power Overload Cleared. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC EMS: Alink Power Overload Cleared." - --#SUMMARY "Alink Power Overload Cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 297 - -upsOutletGroupTurnedOn TRAP-TYPE - ENTERPRISE apc - VARIABLES { upsOutletGroupControlIndex, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The specified Outlet Group turned on." - --#TYPE "APC UPS: Outlet Group turned on." - --#SUMMARY "Outlet Group turned on" - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 298 - -upsOutletGroupTurnedOff TRAP-TYPE - ENTERPRISE apc - VARIABLES { upsOutletGroupControlIndex, mtrapargsString } - DESCRIPTION - "WARNING: The specified Outlet Group turned off." - --#TYPE "APC UPS: Outlet Group turned off." - --#SUMMARY "Outlet Group turned off." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 299 - -smwCriticalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "SEVERE: A Symmetra MW UPS critical condition has been detected. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A critical condition has been detected." - --#SUMMARY "A critical condition has been detected." - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 300 - -smwCriticalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Symmetra MW UPS critical condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A critical condition has been cleared." - --#SUMMARY "A critical condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 301 - -smwWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "WARNING: A Symmetra MW UPS warning condition has been detected. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A warning condition has been detected." - --#SUMMARY "A warning condition has been detected." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 302 - -smwWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "WARNING: A Symmetra MW UPS warning condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: A warning condition has been cleared." - --#SUMMARY "A warning condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 303 - -smwInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Symmetra MW UPS informational condition has been detected. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: Informational condition detected." - --#SUMMARY "An informational condition has been detected." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 304 - -smwInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsGauge, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Symmetra MW UPS informational condition has been cleared. - The first variable is the fault condition." - --#TYPE "APC Symmetra MW UPS: Informational condition cleared." - --#SUMMARY "An informational condition has been cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 305 - -airCriticalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An Air critical condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A critical condition was detected. " - --#SUMMARY "A critical condition was detected. " - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 306 - -airCriticalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Air critical condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A critical condition was cleared. " - --#SUMMARY "A critical condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 307 - -airWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: An Air warning condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A warning condition was detected. " - --#SUMMARY "A warning condition was detected. " - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 308 - -airWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: An Air warning condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: A warning condition was cleared. " - --#SUMMARY "A warning condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 309 - -airInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Air informational condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: Informational condition detected. " - --#SUMMARY "An informational condition was detected. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 310 - -airInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Air informational condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC Air: Informational condition was cleared. " - --#SUMMARY "An informational condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 311 - --- xPDU Traps (part 1) - -xPDUInputVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase - (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XPDU: Main input voltage out-of-range alarm." - --#SUMMARY "Input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 312 - -xPDUInputVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Main input voltage back in range." - --#SUMMARY "Input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 313 - - -xPDUInputVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase - (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm was generated." - --#TYPE "APC XPDU: Main input voltage out-of-range alarm." - --#SUMMARY "Input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 314 - -xPDUInputVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Main input voltage back in range." - --#SUMMARY "Input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 315 - -xPDUBypassVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase bypass input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XPDU: Bypass input voltage out-of-range alarm." - --#SUMMARY "Bypass input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 316 - -xPDUBypassVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase bypass input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Bypass input voltage back in range." - --#SUMMARY "Bypass input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 317 - -xPDUBypassVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: Three-phase bypass input voltage to the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm was generated." - --#TYPE "APC XPDU: Bypass input voltage out-of-range alarm." - --#SUMMARY "Bypass input voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 318 - -xPDUBypassVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Three-phase bypass input voltage to the device is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Bypass input voltage back in range." - --#SUMMARY "Bypass input voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 319 - -xPDUOutputVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XPDU: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 320 - -xPDUOutputVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 321 - -xPDUOutputVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm was generated." - --#TYPE "APC XPDU: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 322 - -xPDUOutputVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XPDU: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 323 - -xPDUOutputCurrentLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in Amps, from which the alarm was generated." - --#TYPE "APC XPDU: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 324 - -xPDUOutputCurrentLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 325 - -xPDUOutputCurrentHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in Amps, above which the alarm was generated." - --#TYPE "APC XPDU: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 326 - -xPDUOutputCurrentHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 327 - -xPDUOutputFrequencyAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The devices output frequency is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the frequency deviation from the nominal in tenths of Hertz." - --#TYPE "APC XPDU: Output frequency out-of-range alarm." - --#SUMMARY "Output frequency is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 328 - -xPDUOutputFrequencyAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices output frequency is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Output frequency back in range." - --#SUMMARY "Output frequency in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 329 - -xPDUSystemGroundCurrentAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The devices earth ground current is over the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Earth ground current over range alarm." - --#SUMMARY "Earth ground current is over limit." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 330 - -xPDUSystemGroundCurrentAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices earth ground current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Earth ground current back in range." - --#SUMMARY "Earth ground current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 331 - -xPDUInputContactStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: A user input contact on the device has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Input contact has changed to its abnormal state." - --#SUMMARY "Input contact has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 332 - -xPDUInputContactStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user input contact on the device has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=CLOSED, 2=OPEN). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Input contact has changed to its normal state." - --#SUMMARY "Input contact has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 333 - -xPDUOutputRelayStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "WARNING: An Output Relay on the device has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the Output Relay number. - The fourth argument is the Output Relay name. - The fifth argument is the current Output Relay state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal Output Relay state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Output Relay has changed to its abnormal state." - --#SUMMARY "Output Relay has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 334 - -xPDUOutputRelayStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: An Output Relay on the device has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the Output Relay number. - The fourth argument is the Output Relay name. - The fifth argument is the current Output Relay state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal Output Relay state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Output Relay has changed to its normal state." - --#SUMMARY "Output Relay has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 335 - -xPDUCoolingFanAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's internal cooling fans have failed. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Cooling fan failure alarm." - --#SUMMARY "Cooling fan failure." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 336 - -xPDUCoolingFanAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's cooling fans are now functioning properly. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Cooling fan alarm cleared." - --#SUMMARY "Cooling fan alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 337 - -xPDUTransformerTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's isolation transformer is over temperature. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Isolation transformer over temperature alarm." - --#SUMMARY "Transformer temp alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 338 - -xPDUTransformerTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's isolation transformer is no longer over temperature. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Isolation transformer over temperature alarm cleared." - --#SUMMARY "Transformer temp alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 339 - -xPDUBranchCurrentLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The current in a branch circuit is outside the limits specified for that - branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in tenth of Amps, from which the alarm was generated." - --#TYPE "APC XPDU: Branch circuit current out-of-range alarm." - --#SUMMARY "Branch circuit current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 340 - -xPDUBranchCurrentLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The current in a branch circuit is back within the limits - specified for that branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Branch circuit current back in range." - --#SUMMARY "Branch circuit current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 341 - -xPDUBranchCurrentHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The current in a branch circuit is outside the limits specified for that - branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps. - The fifth argument is the threshold, in tenth of Amps, above which the alarm was generated." - --#TYPE "APC XPDU: Branch circuit current out-of-range alarm." - --#SUMMARY "Branch circuit current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 342 - -xPDUBranchCurrentHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The current in a branch circuit is back within the limits - specified for that branch circuit. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the panel position of the branch circuit (1-based index). - The fourth argument is the measured current in tenths of Amps." - --#TYPE "APC XPDU: Branch circuit current back in range." - --#SUMMARY "Branch circuit current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 343 - - -xPDUInternalCommError TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: There is an internal communication error in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Internal communication error." - --#SUMMARY "Internal communication error." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 344 - -emsHardwareStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's hardware is improperly configured and operating outside - normal bounds for the hardware. This can be caused by improper devices being - connected to the EMS ports or Alink Current limit detection." - --#TYPE "APC EMS: Hardware is in an abnormal state." - --#SUMMARY "Hardware is in an abnormal state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 345 - -emsHardwareStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's hardware is in its normal operational state. - The first argument is the host device serial number." - --#TYPE "APC EMS: Hardware is in a normal state." - --#SUMMARY "Hardware is in its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 346 - -ceSevereCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: A Custom Event severe condition was detected. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A severe condition was detected. " - --#SUMMARY "A severe condition was detected. " - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 347 - -ceSevereConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event severe condition was cleared. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A severe condition was cleared. " - --#SUMMARY "A severe condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 348 - -ceWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: A Custom Event warning condition was detected. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A warning condition was detected. " - --#SUMMARY "A warning condition was detected. " - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 349 - -ceWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event warning condition was cleared. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: A warning condition was cleared. " - --#SUMMARY "A warning condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 350 - -ceInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event informational condition was detected. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: Informational condition detected. " - --#SUMMARY "An informational condition was detected. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 351 - -ceInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Custom Event informational condition was cleared. - The first variable is the custom event text message. - The second variable is the custom event number." - --#TYPE "APC CustomEvent: Informational condition was cleared. " - --#SUMMARY "An informational condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 352 - -upsInternalOverTemperature TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "WARNING: The internal over temperature condition exists." - --#TYPE "APC UPS: The internal over temperature condition exists." - --#SUMMARY "The internal over temperature condition exists." - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 353 - -upsInternalOverTemperatureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The internal over temperature condition cleared." - --#TYPE "APC UPS: The internal over temperature condition cleared." - --#SUMMARY "The internal over temperature condition cleared." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 354 - -upsMpuReset TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The MPU has been reset." - --#TYPE "APC UPS: The MPU has been reset." - --#SUMMARY "The MPU has been reset." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 355 - -upsOutputSwitchClosed TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Output Switch is closed." - --#TYPE "APC UPS: The Output Switch is closed." - --#SUMMARY "The Output Switch is closed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 356 - -upsOutputSwitchOpened TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Output Switch is open." - --#TYPE "APC UPS: The Output Switch is open." - --#SUMMARY "The Output Switch is open." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 357 - -upsCalibrationStackChanged TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A calibration value in the stack was changed." - --#TYPE "APC UPS: A calibration value in the stack was changed." - --#SUMMARY "A calibration value in the stack was changed." - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 358 - - --- Upgraded EMS now has more env traps - -envMaxTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Max temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Max temperature threshold violation." - --#SUMMARY "Max temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 359 - -envMaxTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Max temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Max temperature threshold violation cleared." - --#SUMMARY "Max temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 360 - -envMinTempThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Min temperature threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Min temperature threshold violation." - --#SUMMARY "Min temperature threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 361 - -envMinTempThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Min temperature threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Min temperature threshold violation cleared." - --#SUMMARY "Min temperature threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 362 - -envMaxHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Max humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Max humidity threshold violation." - --#SUMMARY "Max humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 363 - -envMaxHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Max humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Max humidity threshold violation cleared." - --#SUMMARY "Max humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 364 - -envMinHumidityThresholdViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Min humidity threshold violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Min humidity threshold violation." - --#SUMMARY "Min humidity threshold violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 365 - -envMinHumidityThresholdViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeHumidity, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Min humidity threshold violation cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current humidity. - The fourth argument is the probe number. - The fifth argument is the probe name." - --#TYPE "APC ENV: Min humidity threshold violation cleared." - --#SUMMARY "Min humidity threshold violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 366 - -envSTIncTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Short-term increasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term inc. temp rate violation." - --#SUMMARY "Short-term inc. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 367 - -envSTIncTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Short-term increasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term inc. temp rate violation cleared." - --#SUMMARY "Short-term inc. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 368 - -envSTDecTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Short-term decreasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term dec. temp rate violation." - --#SUMMARY "Short-term dec. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 369 - -envSTDecTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Short-term decreasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Short-term dec. temp rate violation cleared." - --#SUMMARY "Short-term dec. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 370 - -envLTIncTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Long-term increasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term inc. temp rate violation." - --#SUMMARY "Long-term inc. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 371 - -envLTIncTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Long-term increasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term inc. temp rate violation cleared." - --#SUMMARY "Long-term inc. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 372 - -envLTDecTempRateViolation TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "SEVERE: Long-term decreasing temperature rate violated on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term dec. temp rate violation." - --#SUMMARY "Long-term dec. temp rate violation." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 373 - -envLTDecTempRateViolationCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { emsIdentSerialNumber, emsIdentEMSName, emsProbeStatusProbeTemperature, emsStatusSysTempUnits, - emsProbeStatusProbeIndex, emsProbeStatusProbeName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Long-term decreasing temperature rate cleared on the probe. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the current temperature. - The fourth argument is the temperature scale. - The fifth argument is the probe number. - The sixth argument is the probe name." - --#TYPE "APC ENV: Long-term dec. temp rate violation cleared." - --#SUMMARY "Long-term dec. temp rate violation cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 374 - --- Battery Management System Traps - -bmsCriticalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: A Battery Management System critical condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A critical condition was detected. " - --#SUMMARY "A critical condition was detected. " - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 375 - -bmsCriticalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Battery Management System critical condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A critical condition was cleared. " - --#SUMMARY "A critical condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 376 - -bmsWarningCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: A Battery Management System warning condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A warning condition was detected. " - --#SUMMARY "A warning condition was detected. " - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 377 - -bmsWarningConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: A Battery Management System warning condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: A warning condition was cleared. " - --#SUMMARY "A warning condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 378 - -bmsInformationalCondition TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Battery Management System informational condition was detected. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: Informational condition detected. " - --#SUMMARY "An informational condition was detected. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 379 - -bmsInformationalConditionCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsString02, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A Battery Management System informational condition was cleared. - The first variable is the error condition text message. - The second variable is the error number." - --#TYPE "APC BMS: Informational condition was cleared. " - --#SUMMARY "An informational condition was cleared. " - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 380 - --- xATS Traps - -xATSOutputVoltageLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, from which the alarm was generated." - --#TYPE "APC XATS: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 381 - -xATSOutputVoltageLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XATS: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 382 - -xATSOutputVoltageHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The device three-phase output voltage of the device is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts. - The fifth argument is the threshold, in tenths of Volts, above which the alarm is generated." - --#TYPE "APC XATS: Output voltage out-of-range alarm." - --#SUMMARY "Output voltage is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 383 - -xATSOutputVoltageHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output voltage is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1-N, 2=L2-N, 3=L3-N, 4=unused, 5=L1-L2, 6=L2-L3, 7=L3-L1). - The fourth argument is the measured voltage in tenths of Volts." - --#TYPE "APC XATS: Output voltage back in range." - --#SUMMARY "Output voltage in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 384 - -xATSOutputCurrentLowAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral, 5=L1-2, 6=L2-3, 7=L3-1). - The fourth argument is the measured current in Amps. - The fifth argument is the threshold, in Amps, from which the alarm was generated." - --#TYPE "APC XATS: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 385 - -xATSOutputCurrentLowAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral). - The fourth argument is the measured current in Amps." - --#TYPE "APC XATS: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 386 - -xATSOutputCurrentHighAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: The devices three-phase load current is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral). - The fourth argument is the measured current in Amps. - The fifth argument is the threshold, in Amps, from which the alarm was generated." - --#TYPE "APC XATS: Output (load) current out-of-range alarm." - --#SUMMARY "Output current is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 387 - -xATSOutputCurrentHighAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices three-phase output current is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3, 4=Neutral). - The fourth argument is the measured current in Amps." - --#TYPE "APC XATS: Output (load) current back in range." - --#SUMMARY "Output current in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 388 - - -xATSOutputFrequencyAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "SEVERE: The devices output frequency is outside the specified limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the frequency deviation from the nominal in tenths of Hertz. - The fourth argument is the frequency deviation threshold in tenths of Hertz, - from which the alarm was generated." - --#TYPE "APC XATS: Output frequency out-of-range alarm." - --#SUMMARY "Output frequency is out-of-range." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 389 - -xATSOutputFrequencyAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The devices output frequency is back within the specified limits. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Output frequency back in range." - --#SUMMARY "Output frequency in range." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 390 - -xATSInternalCommError TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: There is an internal communication error in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Internal communication error." - --#SUMMARY "Internal communication error." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 391 - -xATSInternalCommErrorCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Internal communication has been restored. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Internal Communication error cleared." - --#SUMMARY "ATS Communication error cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 392 - -xATSDataCommMismatchError TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: A data incompatibility exists within the device. This - is typically the result of mismatches between firmware revisions - of the transfer switch controller and the Network Management interface. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Data mismatch error." - --#SUMMARY "ATS data mismatch error." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 393 - -xATSDataCommMismatchErrorCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The internal data incompatibility has been resolved. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: data mismatch error cleared." - --#SUMMARY "ATS data mismatch error cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 394 - -xATSGenCommLost TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The XATS cannot communicate with the generator. - This will make unavailable all the xATSGenerator OIDs. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: No communication with generator." - --#SUMMARY "ATS/Generator communication lost." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 395 - -xATSGenCommEstablished TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The XATS has established communication with the generator. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Communication with generator established." - --#SUMMARY "ATS/generator communication established." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 396 - -xATSNeutralPosition TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsString } - DESCRIPTION - "WARNING: XATS has transferred to neutral position. - In this position neither Source 1 nor Source 2 is selected, - and the XATS will have no output voltage. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the mode in which the switch is operating - (1=Auto, 2=Not-in-Auto, Abnormal Condition 3=Not-in-Auto, manual)." - --#TYPE "APC XATS: Transferred to the neutral (no output power) position." - --#SUMMARY "Transferred to neutral." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 397 - -xATSSwitchTransferEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: XATS has transferred from one source to the other. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the mode in which the switch is operating. - (1=Auto, 2=Not-in-Auto, Abnormal Condition 3=Not-in-Auto, manual). - The fourth argument is the input source selected (1=Source 1, 2=Source 2). - The fifth argument is type of transfer that took place. (1=Closed, 2=Open, 3=Unknown)" - --#TYPE "APC XATS: Transferred from Source-X to Source-Y." - --#SUMMARY "Source-to-Source transfer." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 398 - -xATSInternalATSFault TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: An internal XATS fault has been detected. - The XATS may have forced itself to not-in-auto mode (abnormal condition), - as indicated by the xATSSwitchStatusAutoSwitchOperationalMode OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the detected fault. - - 1=Cannot Close S1 - 2=Cannot Close S2 - 3=Cannot Open S1 - 4=Cannot Open S2 - 5=Cannot Trip Open S1 - 6=Cannot Trip Open S2 - 7=Start Contact Failure - 8=Voltage Sensing Failure" - - --#TYPE "APC XATS: Internal fault detected." - --#SUMMARY "ATS internal fault detected." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 399 - -xATSInternalATSFaultCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected internal XATS fault has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the detected fault. - - 1=Cannot Close S1 - 2=Cannot Close S2 - 3=Cannot Open S1 - 4=Cannot Open S2 - 5=Cannot Trip Open S1 - 6=Cannot Trip Open S2 - 7=Start Contact Failure - 8=Voltage Sensing Failure" - - --#TYPE "APC XATS: Internal fault cleared." - --#SUMMARY "ATS internal fault cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 400 - -xATSEngineStartAsserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The XATS has asserted the Engine Start contact. - This should result in the generator producing output voltage. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the reason that the start signal was asserted - 1=Unknown, 2=S1 Low Voltage, 3=S1 High Voltage, 4=S1 Line Imbalance, - 5=S1 Freq Range, 6=S1 Bad Rotation." - --#TYPE "APC XATS: Engine Start signal asserted." - --#SUMMARY "Engine Start asserted." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 401 - -xATSEngineStopAsserted TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The XATS has de-asserted the Engine Start contact. - This should result in the generator shutting down, and producing no output voltage. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Engine Stop signal asserted." - --#SUMMARY "Engine Stop asserted." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 402 - -xATSStartFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The generator failed to start. After assertion of the - Engine Start signal, the quality of Source 2 was not seen as good. - This alarm can be cleared using the xATSSwitchStatusClearLatchedAlarms OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument indicates the line quality at S2 - 1=Unknown, 2=S2 Low Voltage, 3=S2 High Voltage, 4=S2 Line Imbalance, - 4=S2 Freq Range, 5=S2 Bad Rotation." - --#TYPE "APC XATS: Generator failed to start alarm." - --#SUMMARY "Generator failed to start." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 403 - -xATSStopFailure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The generator failed to stop. After de-assertion of the - Engine Start signal, the quality of Source 2 continued to be seen as good. - This alarm can be cleared using the xATSSwitchStatusClearLatchedAlarms OID. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator failed to stop alarm." - --#SUMMARY "Generator failed to stop." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 404 - -xATSNotInAutomaticMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: Automatic Transfer Switch is not in automatic mode. - The first argument is the host device serial number. - The second argument is the host device name. - The xATSSwitchStatusAutoSwitchStatus OID and the - xATSSwitchStatusAutoSwitchOperationalMode OID - can provide more information about the state of the XATS." - --#TYPE "APC XATS: XATS is not-in-automatic mode." - --#SUMMARY "ATS not in auto." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 405 - -xATSNotInAutomaticModeCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Automatic Transfer Switch is in automatic mode. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: XATS in auto mode." - --#SUMMARY "ATS in auto mode." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 406 - -xATSEpoTripped TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The device's Emergency Power Off (EPO) circuit is tripped. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) tripped." - --#SUMMARY "EPO tripped." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 407 - -xATSEpoReset TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's Emergency Power Off (EPO) circuit has been - reset to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) reset." - --#SUMMARY "EPO armed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 408 - -xATSEpoTestMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The device's Emergency Power Off (EPO) circuit has been - switched back to the test position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) in test mode." - --#SUMMARY "EPO disabled." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 409 - -xATSEpoArmed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's Emergency Power Off (EPO) circuit has been - switched back to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Emergency Power Off (EPO) enabled." - --#SUMMARY "EPO armed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 410 - -xATSTestInitiated TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A scheduled test has been initiated. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of test initiated (1=scheduled, 2=manual)." - --#TYPE "APC XATS: Test initiated." - --#SUMMARY "Test initiated." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 411 - -xATSTestCancelled TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The scheduled test has been canceled - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of test initiated (1=scheduled, 2=manual)." - --#TYPE "APC XATS: Test cancelled." - --#SUMMARY "Test cancelled." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 412 - -xATSTestFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The initiated test has failed. - This alarm can be cleared using the xATSSwitchStatusClearLatchedAlarms OID. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Initiated test failed." - --#SUMMARY "Initiated test failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 413 - -xATSTestPassed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The initiated test has passed - switched back to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Initiated test passed." - --#SUMMARY "Initiated test passed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 414 - -xATSInputContactStateAbnormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "SEVERE: A user input contact on the device has changed to its abnormal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XATS: Input contact has changed to its abnormal state." - --#SUMMARY "Input contact has changed to its abnormal state." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 415 - -xATSInputContactStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, - mtrapargsString02, mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A user input contact on the device has changed to its normal state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the input contact number. - The fourth argument is the input contact name. - The fifth argument is the input contact state (1=OPEN, 2=CLOSED). - The sixth argument is the configured normal input contact state (1=OPEN, 2=CLOSED)." - --#TYPE "APC XATS: Input contact has changed to its normal state." - --#SUMMARY "Input contact has changed to its normal state." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 416 - -xATSRemoteStartContactMismatch TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: The state of the generator's Remote Start input - and the ATS's Engine Start output do not match. - This indicates something wrong in the Engine Start wiring, - which must be corrected. This condition will prevent the - generator from being started when needed. - - (See also: xATSGeneratorStatusRemoteStart - and xATSSwitchStatusEngineStartSignal OIDs) - - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator/ATS start contact mismatch." - --#SUMMARY "Generator/ATS start contact mismatch." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 417 - -xATSRemoteStartContactMismatchCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Mismatch in the state of the generator's - Remote Start input and the ATS's Engine Start output as been resolved. - This indicates something wrong in the Engine Start wiring, - which must be corrected. This condition will prevent the - generator from being started when needed. - - (See also: xATSGeneratorStatusRemoteStart - and xATSSwitchStatusEngineStartSignal OIDs) - - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator/ATS start contact mismatch cleared." - --#SUMMARY "Generator/ATS start contact mismatch cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 418 - -xATSDoorOpenAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The XATS exterior panel door is open. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Panel door is open alarm." - --#SUMMARY "Panel door open alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 419 - -xATSDoorOpenAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The external door to the device is closed. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Panel door open alarm cleared." - --#SUMMARY "Panel door open alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 420 - -xATSDCBackupAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The XATS's DC backup has been lost. The XATS will lose power - on Source 1 failure, causing the Engine Start signal to be asserted. - The XATS will then restart from Source 2. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: DC backup failure." - --#SUMMARY "ATS DC backup failure." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 421 - -xATSDCBackupAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: DC backup alarm has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: DC backup alarm cleared." - --#SUMMARY "DC backup alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 422 - --- xATS Generator Traps - -xATSGeneratorLowCoolantLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Low coolant level has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant level alarm." - --#SUMMARY "Generator low coolant level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 423 - -xATSGeneratorLowCoolantLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low coolant level has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant level alarm cleared." - --#SUMMARY "Generator low coolant level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 424 - -xATSGeneratorVeryLowCoolantLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Very low coolant level has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very low coolant level alarm." - --#SUMMARY "Generator very low coolant level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 425 - -xATSGeneratorVeryLowCoolantLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected Very low coolant level has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very low coolant level alarm cleared." - --#SUMMARY "Generator very low coolant level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 426 - -xATSGeneratorHighCoolantTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: High coolant temperature has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high coolant temperature alarm." - --#SUMMARY "Generator high coolant temperature alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 427 - -xATSGeneratorHighCoolantTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected high coolant temperature has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high coolant temperature alarm cleared." - --#SUMMARY "Generator high coolant temperature alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 428 - -xATSGeneratorVeryHighCoolantTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Very high coolant temperature has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very high coolant temperature alarm." - --#SUMMARY "Generator very high coolant temperature alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 429 - -xATSGeneratorVeryHighCoolantTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The Very high coolant temperature condition has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator very high coolant temperature alarm cleared." - --#SUMMARY "Generator very high coolant temperature alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 430 - -xATSGeneratorLowCoolantTempAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Low coolant temperature has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant temperature alarm." - --#SUMMARY "Generator low coolant temperature alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 431 - -xATSGeneratorLowCoolantTempAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The low coolant temperature condition has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low coolant temperature alarm cleared." - --#SUMMARY "Generator low coolant temperature alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 432 - -xATSGeneratorLowOilLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: Low oil level has been detected in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil level alarm." - --#SUMMARY "Generator low oil level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 433 - -xATSGeneratorLowOilLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Low oil level alarm has been cleared in the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil level alarm cleared." - --#SUMMARY "Generator low oil level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 434 - -xATSGeneratorLowBatteryVoltDuringCrankAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's battery voltage has been detected - as low while cranking the engine. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Low batt. voltage while cranking alarm." - --#SUMMARY "Generator low battery volts while cranking alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 435 - -xATSGeneratorLowBatteryVoltDuringCrankAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's low battery voltage while - cranking condition has been cleared. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "XGEN: Generator low batt. voltage while cranking alarm cleared." - --#SUMMARY "Generator low battery volts while cranking alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 436 - -xATSGeneratorVeryLowBatteryVoltDuringCrankAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's battery voltage has been detected - as very low while cranking the engine. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "XGEN: Generator v.low battery voltage while cranking alarm." - --#SUMMARY "Generator v.low battery volts while cranking alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 437 - -xATSGeneratorVeryLowBatteryVoltDuringCrankAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's high battery voltage while - cranking condition has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "XGEN: Generator v.low batt volt, while cranking alarm cleared." - --#SUMMARY "Generator v.low battery volts while cranking alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 438 - -xATSGeneratorEStop TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's emergency stop input has been activated. - After the emergency stop signal has been removed, the E-Stop condition - must be cleared before the generator can be started again. - E-Stop conditions can only be cleared via the generator front panel. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code. - The fourth argument is the type of E-Stop (1=LOCAL, 2=REMOTE)." - --#TYPE "APC XGEN: Generator emergency stop engaged." - --#SUMMARY "Generator emergency stop engaged." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 439 - -xATSGeneratorEStopCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's emergency stop condition has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code. - The fourth argument is the type of E-Stop (1=LOCAL, 2=REMOTE)." - --#TYPE "APC XGEN: Generator emergency stop condition cleared." - --#SUMMARY "Generator emergency stop condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 440 - -xATSGeneratorHighBatteryVolt TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The generator's battery voltage has been detected as high. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high battery voltage." - --#SUMMARY "Generator high battery volts." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 441 - -xATSGeneratorHighBatteryVoltCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected high battery voltage has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator high battery voltage condition cleared." - --#SUMMARY "Generator high battery volts condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 442 - -xATSGeneratorLowBatteryVolt TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's battery voltage has been detected as low. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low battery voltage." - --#SUMMARY "Generator low battery volts." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 443 - -xATSGeneratorLowBatteryVoltCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low battery voltage has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low battery voltage condition cleared." - --#SUMMARY "Generator low battery volts condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 444 - -xATSGeneratorControlSwitchNotAuto TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The control switch on the generator is not in auto position. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator not-in-automatic mode." - --#SUMMARY "Generator not-in-auto." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 445 - -xATSGeneratorControlSwitchNotAutoCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The control switch on the generator is in auto position. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator automatic mode restored." - --#SUMMARY "Generator not-in-auto cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 446 - -xATSGeneratorLowOilPressure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's oil pressure has been detected as low. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil pressure." - --#SUMMARY "Generator low oil pressure." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 447 - -xATSGeneratorLowOilPressureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low oil pressure has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator low oil pressure condition cleared." - --#SUMMARY "Generator low oil pressure condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 448 - -xATSGeneratorVeryLowOilPressure TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator's oil pressure has been detected as very low. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator v.low oil pressure." - --#SUMMARY "Generator v.low oil pressure." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 449 - -xATSGeneratorVeryLowOilPressureCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected v.low oil pressure has been cleared, on the generator. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator v.low oil pressure condition cleared." - --#SUMMARY "Generator v.low oil pressure condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 450 - -xATSGeneratorOverload TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator is overloaded. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator is in overload event." - --#SUMMARY "Generator on overload event." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 451 - -xATSGeneratorOverloadCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator is running within loading limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator is in overload event cleared." - --#SUMMARY "Generator on overload event cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 452 - -xATSGeneratorLowACVEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator AC voltage is outside the acceptable bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage." - --#SUMMARY " State of the Generator ac voltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 453 - -xATSGeneratorLowACVEventCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator AC voltage is within normal bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage cleared." - --#SUMMARY "State of the Generator ac voltage cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 454 - -xATSGeneratorHighACVEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator AC voltage is outside the acceptable bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage." - --#SUMMARY " State of the Generator ac voltage." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 455 - -xATSGeneratorHighACVEventCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator AC voltage is within normal bounds. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: State of the Generator ac voltage cleared." - --#SUMMARY "State of the Generator ac voltage cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 456 - -xATSGeneratorOverspeed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator is running over the acceptable RPM. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator overspeed condition." - --#SUMMARY "Generator overspeed condition." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 457 - -xATSGeneratorOverspeedCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator overspeed shutdown has been cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator overspeed condition cleared." - --#SUMMARY "Generator overspeed condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 458 - -xATSGeneratorEngineCold TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator engine is cold, may not start. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator engine is cold, may not start." - --#SUMMARY "Generator engine is cold." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 459 - -xATSGeneratorEngineColdCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The engine is not cold to start. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Engine is cold to start condition cleared." - --#SUMMARY "Engine is cold to start condition cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 460 - -xATSGeneratorOutputBreakerOpen TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generators output breaker has been detected as open. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator output breaker open alarm." - --#SUMMARY "Generator output breaker open." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE NONOPERATIONAL - ::= 461 - -xATSGeneratorOutputBreakerOpenCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The engine is not cold to start. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator output breaker open alarm cleared." - --#SUMMARY "Generator output breaker open cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 462 - -xATSGeneratorLowFuelLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The tank fuel level is below the limits specified - in the xATSGeneratorFuelSystemLowFuelLevelThreshold OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured fuel level in percent of full." - --#TYPE "APC XGEN: Low fuel level alarm." - --#SUMMARY "Generator low fuel level alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 463 - -xATSGeneratorLowFuelLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The tank fuel level is back above the specified limit. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Low fuel level alarm cleared." - --#SUMMARY "Generator low fuel level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 464 - -xATSGeneratorVeryLowFuelLevelAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The tank fuel level is below the low threshold limits. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the measured tank fuel level in percent of full." - --#TYPE "APC XGEN: Very Low fuel level alarm." - --#SUMMARY "Generator very low fuel level alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 465 - -xATSGeneratorVeryLowFuelLevelAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low tank level has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Very low fuel level alarm cleared." - --#SUMMARY "Generator very low fuel level alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 466 - -xATSGeneratorLowRunTimeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The estimated runtime is below the limits specified. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the estimated runtime in hours." - --#TYPE "APC XGEN: Low run time alarm." - --#SUMMARY "Generator low run time alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 467 - -xATSGeneratorLowRunTimeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low runtime has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Low run time alarm cleared." - --#SUMMARY "Generator low run time alarm." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 468 - -xATSGeneratorVeryLowRunTimeAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The estimated runtime is below the limits specified - in the xATSGeneratorFuelSystemVeryLowRunTimeThreshold OID. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the estimated runtime in hours." - --#TYPE "APC XGEN: Very low run time alarm." - --#SUMMARY "Generator very low run time alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 469 - -xATSGeneratorVeryLowRunTimeAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The detected low runtime has been cleared in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XGEN: Very low run time alarm cleared." - --#SUMMARY "Generator very low run time alarm." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 470 - -xATSGeneratorServiceDueAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The generator is due for scheduled service. - Generation of this alarm is based on calender days since - and/or actual generator run-hours since last service. - This alarm is cleared using the xATSGeneratorServiceResetRecord OID. - - (See also: xATSGeneratorServiceCalendarIntervalThreshold - and xATSGeneratorServiceRunHoursThreshold OIDs) - - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator scheduled maintenance is due." - --#SUMMARY "Generator maintenance due." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 471 - -xATSGeneratorServiceDueAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator's service registers have been reset. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Generator service due alarm is cleared." - --#SUMMARY "Generator service alarm is cleard." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 472 - -xATSGeneratorShutdown TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator is shutdown. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator shutdown." - --#SUMMARY "Generator shutdown" - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 473 - -xATSGeneratorShutdownCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The generator shutdown alarm is cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator shutdown is cleared." - --#SUMMARY "Generator shutdown is cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 474 - -xATSGeneratorBatteryCharger TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: The generator battery charger is nonfunctional. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator batt. charger is nonfunctional." - --#SUMMARY "Generator battery charger is nonfunctional" - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 475 - -xATSGeneratorBatteryChargerCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: nonfunctionality of the generator battery is cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: " Nonfunctionality of battery charger is cleared." - --#SUMMARY "non-functionality of Generator battery charger is cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 476 - -xATSGeneratorGenericEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: Any generic generator event. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generator generic event." - --#SUMMARY "Generator generic event." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 477 - -xATSGeneratorGenericEventCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xATSIdentSerialNumber, xATSIdentProductName, mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Generated generic generator event is cleared. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the OEM's fault/event code." - --#TYPE "APC XGEN: Generic generator event is cleared." - --#SUMMARY "Generic generator event is cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 478 - --- xPDU Traps (part 2) - -xPDUInternalCommErrorCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Internal communication has been restored. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Internal Communication error cleared." - --#SUMMARY "Communication error cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 479 - -xPDUSystemStateAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "WARNING: The PDU's breakers (Q1, Q2 & Q3) are in a configuration that might lead - to system unavailability. it may signify a temporary condition, when the breakers - are placed in an atypical manner as the user transitions to (UPS OPERATION or MAINTENANCE BYPASS) - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of alarm - (1=NO UPS INPUT, 2=NO PANEL FEED, 3=ATYPICAL BYPASS MODE)." - --#TYPE "APC XPDU: System state alarm ." - --#SUMMARY "PDU state alarm." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 480 - -xPDUSystemStateNormal TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The PDU's breakers (Q1, Q2 & Q3) are set in a configuration - that is a non-alarm state. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the type of alarm (1=UPS OPERATION, 2=MAINTENANCE BYPASS)." - --#TYPE "APC XPDU: System state returned to normal." - --#SUMMARY "PDU state normal." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 481 - -xPDUEpoTestMode TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "WARNING: The device's Emergency Power Off (EPO) circuit has been - switched back to the test position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Emergency Power Off (EPO) in test mode." - --#SUMMARY "EPO disabled." - --#ARGUMENTS { } - --#SEVERITY WARNING - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 482 - -xPDUEpoArmed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: The device's Emergency Power Off (EPO) circuit has been - switched back to the armed position. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Emergency Power Off (EPO) enabled." - --#SUMMARY "EPO armed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 483 - -xPDUFuseBlownAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "SEVERE: One or more fuses in this PDU have been detected as open. - These fuses are in the feed to the UPS associated with this PDU. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3)." - --#TYPE "APC XPDU: Check fuse alarm." - --#SUMMARY "Fuse detected opened." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 484 - -xPDUFuseBlownAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A previous check fuse alarm in this PDU has cleared. - These fuses are in the feed to the UPS associated with this PDU. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the phase (1=L1, 2=L2, 3=L3)." - --#TYPE "APC XPDU: Check fuse alarm cleared." - --#SUMMARY "Fuse alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 485 - -xPDUBreakerPositionAlarm TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsInteger02, mtrapargsString } - DESCRIPTION - "SEVERE: A PDU breaker is in a state that compromises system availability. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the breaker (1=MAIN INPUT, 2=BYPASS INPUT, 3=CROSS TIE). - The fourth argument is the breaker position (1=OPEN, 2=CLOSED)." - --#TYPE "APC XPDU: Breaker position alarm." - --#SUMMARY "Breaker position alarm." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 486 - -xPDUBreakerPositionAlarmCleared TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, - mtrapargsInteger, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A PDU breaker is no longer in a state that compromises system availability. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the breaker (1=MAIN INPUT, 2=BYPASS INPUT, 3=CROSS TIE)." - --#TYPE "APC XPDU: Breaker position alarm cleared." - --#SUMMARY "Breaker alarm cleared." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 487 - -xPDUBreakerChangeEvent TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsInteger, - mtrapargsInteger02, mtrapargsInteger03, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: A system breaker or switch within the device has changed state. - They are generated when any of the Q1, Q2 or Q3 breakers have changed states. - The first argument is the host device serial number. - The second argument is the host device name. - The third argument is the breaker that has changed - (1=UPS FEED (Q1), 2=UPS OUTPUT(Q2), 3=MAINTENANCE BYPASS (Q3). - The fourth argument is the state of the breaker that has changed (1=OPEN, 2=CLOSED). - The fifth argument is a 8-bit field representing the state of all breakers in the system, - when any of one of the Q1, Q2 or Q3 breakers have changed state. - - The bit map is represented in the following manner (b7, b6 ... b0) - b0 - UPS FEED (Q1) - b1 - MAINTENANCE BYPASS (Q3) - b2 - UPS OUTPUT (Q2) - b3 - MAIN INPUT - b4 - BYPASS INPUT - b5 - CROSS-TIE OUTPUT - - Example: value of 60 (0x3C) indicates that the CROSS_TIE, BYPASS and MAIN INPUT, and Q2 breakers - are CLOSED and Q2, Q1 breakers are OPEN." - --#TYPE "APC XPDU: Breaker/switch change event." - --#SUMMARY "Breaker/switch change event." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 488 - -xPDUControllerFirmwareUpdateTransferStart TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Start Controller firmware transfer in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Start controller firmware transfer." - --#SUMMARY "Start controller firmware transfer." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 489 - -xPDUControllerFirmwareUpdateTransferComplete TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Transfer of Controller firmware was completed in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Controller firmware transfer completed." - --#SUMMARY "Controller firmware transfer completed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 490 - -xPDUControllerFirmwareUpdateTransferFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: Transfer of Controller firmware has failed in the PDU. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XPDU: Controller firmware transfer failed." - --#SUMMARY "Controller firmware transfer failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 491 - -xATSControllerFirmwareUpdateTransferStart TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Start Controller firmware transfer in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Start controller firmware transfer." - --#SUMMARY "Start controller firmware transfer." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 492 - -xATSControllerFirmwareUpdateTransferComplete TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "INFORMATIONAL: Transfer of Controller firmware was completed in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Controller firmware transfer completed." - --#SUMMARY "Controller firmware transfer completed." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 493 - -xATSControllerFirmwareUpdateTransferFailed TRAP-TYPE - ENTERPRISE apc - VARIABLES { xPDUIdentSerialNumber, xPDUIdentProductName, mtrapargsString } - DESCRIPTION - "SEVERE: Transfer of Controller firmware has failed in the device. - The first argument is the host device serial number. - The second argument is the host device name." - --#TYPE "APC XATS: Controller firmware transfer failed." - --#SUMMARY "Controller firmware transfer failed." - --#ARGUMENTS { } - --#SEVERITY SEVERE - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE DEGRADED - ::= 494 - -apcDeviceShutdownHeartbeat TRAP-TYPE - ENTERPRISE apc - VARIABLES { mtrapargsInteger, mtrapargsTimeTicks, mtrapargsString} - DESCRIPTION - "INFORMATIONAL: " - --#TYPE "APC X:" - --#SUMMARY "." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 999 - -apcDiscoveryAlarmStateTableUpdate TRAP-TYPE - ENTERPRISE apc - VARIABLES { apcDiscoveryDeviceAlarmStateChangeCount } - DESCRIPTION - "INTERNAL: A Discovery Alarm State Table Update trap is sent - when any data alarm state is added, removed, or its parameters - are changed in the condition table. This trap is - only for machine-to-machine communication. " - --#TYPE "APC X:" - --#SUMMARY "." - --#ARGUMENTS { } - --#SEVERITY INFORMATIONAL - --#TIMEINDEX 1 - --#HELP "" - --#HELPTAG 0 - --#STATE OPERATIONAL - ::= 1000 - -END diff --git a/fence/agents/baytech/Makefile b/fence/agents/baytech/Makefile deleted file mode 100644 index 8012dc3..0000000 --- a/fence/agents/baytech/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_baytech.py -TARGET= fence_baytech - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_baytech: fence_baytech.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/baytech/fence_baytech.pl b/fence/agents/baytech/fence_baytech.pl deleted file mode 100755 index e42e1d9..0000000 --- a/fence/agents/baytech/fence_baytech.pl +++ /dev/null @@ -1,685 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -# This fencing agent is written for the Baytech RPC27-20nc in conjunction with -# a Cyclades terminal server. The Cyclades TS exports the RPC's serial port -# via a Telnet interface. Other interfaces, such as SSH, are possible. -# However, this script relys upon the assumption that Telnet is used. Future -# features to this agent would allow the agent to work with a mulitude of -# different communication protocols such as Telnet, SSH or Kermit. -# -# The other assumption that is made is that Outlet names do not end in space. -# The name "Foo" and "Foo " are identical when the RPC prints them with -# the status command. - -use Net::Telnet; -use Getopt::Std; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - - -sub rpc_error -{ - if (defined $error_message && $error_message ne "") - { - chomp $error_message; - die "$error_message\n"; - } - else - { - die "read timed-out\n" - } -} - -sub usage -{ - - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a host host to connect to\n"; - print " -D debugging output\n"; - print " -h usage\n"; - print " -l string user name\n"; - print " -o string action: On,Off,Status or Reboot (default)\n"; - print " -n string outlet name\n"; - print " -p string password\n"; - print " -S path script to run to retrieve password\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg)=@_; - print $msg."\n" unless defined $quiet; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -# Get operating paramters, either with getopts or from STDIN -sub get_options -{ - $action = "Reboot"; - if (@ARGV > 0) { - getopts("n:l:p:S:o:a:VhD") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - } else { - get_options_stdin(); - } - - fail "failed: must specify hostname" unless defined $opt_a; - $host=$opt_a; - $port=23 unless ($opt_a =~ /:/); - - $action = $opt_o if defined $opt_o; - fail "failed: unrecognised action: $action" - unless $action=~ /^(Off|On|Reboot|status)$/i; - - fail "failed: no outletname" unless defined $opt_n; - $outlet = $opt_n; - - $debug=$opt_D if defined $opt_D; - $quiet=$opt_q if defined $opt_q; - $user=$opt_l if defined $opt_l; - $passwd=$opt_p if defined $opt_p; - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $passwd=$pwd_script_out; - } - } - - if(defined $passwd && !defined $user) - { - fail "failed: password given without username"; - } -} - -# Get options from STDIN -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "host" ) - { - $opt_a = $val; - } - - elsif ($name eq "login" ) - { - $opt_l = $val; - } - - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - - elsif ($name eq "passwd_script") { - $opt_S = $val; - } - - elsif ($name eq "action" ) - { - $opt_o = $val; - } - - elsif ($name eq "outlet" ) - { - $opt_n = $val; - } - - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -# Get a bunch of lines. The newlines must terminate complete lines. -sub getlines -{ - my $data=$t->get(); - return undef unless defined $data; - my @chars = split //,$data; - my @lines; - my $line=""; - - for (my $i=0;$i<@chars;$i++) - { - $line = $line.$chars[$i]; - next unless $chars[$i] eq "\n"; - $lines[@lines] = $line; - $line = ""; - } - $lines[@lines] = $line unless $line eq ""; - - return @lines; -} - -# Fill the global input buffer of lines read. All lines are terminated with -# a newline. If a line is not terminated, the next call to fill buffer will -# append the last line of the input buffer with the first line that it gets from -# getlines() -sub fill_buffer -{ - my @lines = getlines(); - return undef unless @lines; - - if(@buffer) - { - if ( $buffer[$#buffer]=~/\n/) { } - else - { - $buffer[$#buffer] = $buffer[$#buffer].$lines[0]; - shift @lines; - } - } - - foreach (@lines) - { - push @buffer,$_; - } -} - - - -# -# ($p_index,@data) = get_match @patterns; -# -# searches the input buffers for the patterns specified by the regeps in -# @patterns, when a match is found, all the lines through the matched -# pattern line are removed from the global input buffer and returned in the -# array @data. The index into @patterns for the matching pattern is also -# returned. -sub get_match -{ - my (@patterns) = @_; - $b_index = 0 unless defined $b_index; - - fill_buffer() unless defined @buffer; - - for(;;) - { - for(my $bi=$b_index; $bi<@buffer; $bi++) - { - for(my $pat=0; $pat<@patterns; $pat++) - { - if($buffer[$bi] =~ /$patterns[$pat]/) - { - $b_index = 0; - my @rtrn = splice(@buffer,0,$bi); - shift @buffer; - - if($debug) - { - foreach (@rtrn) { print $_ } - print "$patterns[$pat] "; - } - - return ($pat,@rtrn); - } - } - $b_index = $bi; - } - - fill_buffer(); - } -} - -# -# ($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet,@data; -# -# This parses the data @data and searches for an outlet named $outlet. -# The data will be in the form: -# -# Average Power: 0 Watts Apparent Power: 17 VA -# -# True RMS Voltage: 120.0 Volts -# -# True RMS Current: 0.1 Amps Maximum Detected: 0.2 Amps -# -# Internal Temperature: 19.5 C -# -# Outlet Circuit Breaker: Good -# -# 1)...Outlet 1 : Off 2)...Outlet 2 : Off -# 3)...Outlet 3 : On 4)...Outlet 4 : On -# 5)...Outlet 5 : On 6)...Outlet 6 : On -# 7)...Outlet 7 : On 8)...Outlet 8 : On -# 9)...Outlet 9 : On 10)...Outlet 10 : On -# 11)...Outlet 11 : On 12)...Outlet 12 : On -# 13)...Outlet 13 : On 14)...Outlet 14 : On -# 15)...Outlet 15 : On 16)...Outlet 16 : On -# 17)...Outlet 17 : On 18)...Outlet 18 : On -# 19)...Outlet 19 : On 20)...Outlet 20 : On Locked -# -sub parse_status -{ - my $outlet = shift; - my @data = @_; - - my $bt_num=""; - my $bt_name=""; - my $bt_state=""; - my $bt_locked=""; - - # Verify that the Outlet name exists - foreach my $line (@data) - { - next unless $line =~ /^[ 12][0-9]).../; - - my @entries = split /([ 12][0-9])).../,$line; - - foreach my $entry (@entries) - { - next if $entry eq ""; - - if($entry =~ /^([ 12][0-9])$/) - { - $bt_num = $1; - } - elsif($entry =~ /^(.{15}) : (On|Off)(.*)/) - { - - $bt_name = $1; - $bt_state = $2; - $bt_locked = $3; - - $_ = $bt_name; - s/\s*$//; - $bt_name = $_; - - $_ = $bt_locked; - s/\s*$//; - $bt_locked = $_; - - last if ($bt_name eq $outlet); - - $bt_name = ""; - next; - } - else - { - die "parse error: $entry"; - } - } - last if ($bt_name ne ""); - } - - if ($bt_name eq "") - { - $bt_num=undef; - $bt_name=undef; - $bt_state=undef; - $bt_locked=undef; - } - - return ($bt_num,$bt_name,$bt_state,$bt_locked); -} - -########################################################################## -# -# Main - -get_options; - - -if (defined $port) -{ - $t = new Net::Telnet(Host=>$host, Port=>$port) or - die "Unable to connect to $host:$port: ".($!?$!:$_)."\n"; -} -else -{ - $t = new Net::Telnet(Host=>$host) or - die "Unable to connect to $host: ".($!?$!:$_)."\n"; -} - - - -#> DEBUG $t->dump_log("LOG"); - -$t->print("\n"); - -my @patterns; -$prompt_user="^Enter user name:"; -$prompt_pass="^Enter Password:"; -$prompt_cmd="^RPC-27>"; -$prompt_confirm_yn="^.*\(Y/N\)\?"; - -$patterns[0]=$prompt_user; -$patterns[1]=$prompt_pass; -$patterns[2]=$prompt_cmd; -$patterns[3]=$prompt_confirm_yn; - -my $p_index; -my @data; - -my $bt_num=""; -my $bt_name=""; -my $bt_state=""; -my $bt_locked=""; -my $exit=1; - -($p_index,@data) = get_match @patterns; - -# -# Set errmode after first get_match. This allows for more descriptive errors -# when handling unexpected error conditions -# -$t->errmode(&rpc_error); - -# At this point, the username is unknown. We'll just -# pass in an empty passwd so that we can get back to the -# login prompt. -# -# FIXME -# If this is the third login failure for this switch, an -# additional newline will need to be made sent. This script -# does not handle that case at this time. This will cause -# a timeout on read and cause this to fail. Rerunning the -# script ought to work though. -if ($patterns[$p_index] eq $prompt_pass) -{ - $t->print("\n"); - ($p_index,@data) = get_match @patterns; -} - -# Enter user name: -# -# Depending how the RPC is configured, a user name may not be required. -# We will only deal with usernames if prompted. -# -# If there is no user/passwd given as a parameter, but the switch -# expects one, rather than just fail, we will first try to -# get the switch in a known state -my $warn_user="yes"; -my $warn_passwd="yes"; - -$error_message = "Invalid user/password"; - -for (my $retrys=0; $patterns[$p_index] eq $prompt_user ; $retrys++) -{ - $warn_passwd = "yes"; - if(defined $user) - { - $t->print("$user\n"); - $warn_user = "no"; - } - else - { - $t->print("\n"); - - } - ($p_index,@data) = get_match @patterns; - - # Enter Password: - # - # Users don't have to have passwords either. We will only check - # that the user specified a password if we were prompted by the - # RPC. - if ($patterns[$p_index] eq $prompt_pass) - { - if(defined $passwd) - { - $t->print("$passwd\n"); - $warn_passwd = "no"; - } - else - { - $t->print("\n"); - } - - ($p_index,@data) = get_match @patterns; - } - - - # - # If a valid user name is given, but not a valid password, we - # will loop forever unless we limit the number of retries - # - # set the user to "" so we stop entering a valid username and - # force the login proccess to fail - # - if ($retrys>2) - { - $user = ""; - } - elsif ($retrys>10) - { - die "maximum retry count exceeded\n"; - } -} - -# -# reset errmode to die() -# -$t->errmode("die"); - -# all through with the login/passwd. If we see any other prompt it is an -# error. -if ($patterns[$p_index] ne $prompt_cmd) -{ - $t->print("\n"); - die "bad state: '$patterns[$p_index]'"; -} - -if (defined $user && ($warn_user eq "yes")) -{ - warn "warning: user parameter ignored\n"; -} - -if (defined $passwd && ($warn_passwd eq "yes")) -{ - warn "warning: passwd parameter ignored\n"; -} - - - - -# We are now logged in, no need for these patterns. We'll strip these -# so that we don't have to keep searching for patterns that shouldn't -# appear. -shift @patterns; -shift @patterns; - -# Get the current status of a particular outlet. Explicitly pass -# the status command in case the RPC is not configured to report the -# status on each command completion. -$t->print("status\n"); -($p_index,@data) = get_match @patterns; -($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet,@data; - -if (!defined $bt_name ) -{ - # We have problems if there is not outlet named $outlet - print "Outlet '$outlet' not found\n"; - $exit=1; -} -elsif ($action =~ /status/i) -{ - print "Outlet '$bt_name' is $bt_state and is ". - (($bt_locked eq "")?"not ":"")."Locked\n"; - $exit=0; -} -elsif ($bt_locked ne "") -{ - # Report an error if an outlet is locked since we can't actually - # issue commands on a Locked outlet. This will prevent false - # successes. - print "Outlet '$bt_name' is Locked\n"; - $exit=1; -} -elsif (($action =~ /on/i && $bt_state eq "On") || - ($action =~ /off/i && $bt_state eq "Off") ) -{ - # No need to issue the on/off command since we are already in - # the desired state - print "Outlet '$bt_name' is already $bt_state\n"; - $exit=0; -} -elsif ($action =~ /o(n|ff)/i) -{ - # On/Off command - $t->print("$action $bt_num\n"); - ($p_index,@data) = get_match @patterns; - - # Confirmation prompting maybe enabled in the switch. If it is, - # we enter 'Y' for yes. - if ($patterns[$p_index] eq $prompt_confirm_yn) - { - $t->print("y\n"); - ($p_index,@data) = get_match @patterns; - } - - $t->print("status\n"); - ($p_index,@data) = get_match @patterns; - - ($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet,@data; - - if ($bt_state =~ /$action/i) - { - print "success: outlet='$outlet' action='$action'\n"; - $exit=0; - } - else - { - print "fail: outlet='$outlet' action='$action'\n"; - $exit=1; - } -} -elsif ($action =~ /reboot/i) -{ - # Reboot command - $t->print("$action $bt_num\n"); - ($p_index,@data) = get_match @patterns; - - # Confirmation prompting maybe enabled in the switch. If it is, - # we enter 'Y' for yes. - if ($patterns[$p_index] eq $prompt_confirm_yn) - { - $t->print("y\n"); - ($p_index,@data) = get_match @patterns; - } - - # The reboot command is annoying. It reports that the outlet will - # reboot in 9 seconds. Then it has a countdown timer. We first - # look for the "Rebooting... 9" message, then we parse the remaining - # output to verify that it reaches 0 without skipping anything. - my $pass=0; - foreach (@data) - { - chomp; - my $line = $_; - - # There is a countdown timer that prints a number, then sleeps a - # second, then prints a backspace and then another number - # - # /^Rebooting... 9\b8\b7\b6\b5\b4\b3\b2\b1\b0\b$/ - if($line =~/^Rebooting....*0[\b]$/) - { - $pass=1; - last; - } - } - - if ($pass) - { - print "success: outlet='$outlet' action='$action'\n"; - $exit=0; - } - else - { - print "fail: outlet='$outlet' action='$action'\n"; - $exit=1; - } -} -else -{ - die "bad state"; -} - -# Clean up. If we don't tell it to logout, then anybody else can log onto -# the serial port and have access to the switch without authentication (when -# enabled) -$t->print("logout\n"); -$t->close; -exit $exit; diff --git a/fence/agents/baytech/fence_baytech.py b/fence/agents/baytech/fence_baytech.py deleted file mode 100755 index 376235c..0000000 --- a/fence/agents/baytech/fence_baytech.py +++ /dev/null @@ -1,283 +0,0 @@ -#!/usr/bin/python - -############################################################################### -############################################################################### -## -## Copyright (C) 2006 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -## Matt Roman of lxd inc. laid the groundwork for this file. Thanks, Matt. ## -## -############################################################################### - - -import getopt, sys -import os -import socket -import time - -from telnetlib import Telnet - -TELNET_TIMEOUT=30 #How long to wait for a response from a telnet try - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def usage(): - print "Usage:" - print "fence_baytech [options]" - print "Options:" - print " -a <ipaddress> ip or hostname of baytech switch" - print " -h print out help" - print " -l [login] login name" - print " -p [password] password" - print " -S [path] script to run to retrieve password" - print " -o [action] Reboot (default), Off, or On" - print " -n [outlet] Switch outlet number to control" - print " -v Verbose Verbose mode" - print " -V Print Version, then exit" - - sys.exit (0) - -def version(): - print "fence_baytech %s %s\n" % (FENCE_RELEASE_NAME, BUILD_DATE) - print "%s\n" % REDHAT_COPYRIGHT - sys.exit(0) - -def main(): - - POWER_OFF = 0 - POWER_ON = 1 - POWER_STATUS = 2 - POWER_REBOOT = 3 - - address = "" - login = "" - passwd = "" - passwd_script = "" - port_num = "" - action = POWER_REBOOT #default action - verbose = False - - standard_err = 2 - - #set up regex list - USERNAME = 0 - PASSWORD = 1 - PROMPT = 2 - regex_list = list() - regex_list.append("Enter user name:") - regex_list.append("Enter Password:") - regex_list.append("RPC-6>") - - if len(sys.argv) > 1: - try: - opts, args = getopt.getopt(sys.argv[1:], "a:hl:o:n:p:S:vV", ["help", "output="]) - except getopt.GetoptError: - #print help info and quit - usage() - sys.exit(2) - - - for o, a in opts: - if o == "-v": - verbose = True - if o == "-V": - version() - if o in ("-h", "--help"): - usage() - sys.exit(0) - if o == "-l": - login = a - if o == "-n": - port_num = a - if o == "-p": - passwd = a - if o == "-S": - passwd_script = a - if o == "-o": - if a == "Off" or a == "OFF" or a == "off": - action = POWER_OFF - elif a == "On" or a == "ON" or a == "on": - action = POWER_ON - elif a == "Reboot" or a == "REBOOT" or a == "reboot": - action = POWER_REBOOT - else: - usage() - sys.exit(1) - if o == "-a": - address = a - if address == "" or login == "" or (passwd == "" and passwd_script == "") or port_num == "": - usage() - sys.exit(1) - - else: #Take args from stdin... - params = {} - #place params in dict - for line in sys.stdin: - val = line.split("=") - if len(val) == 2: - params[val[0].strip()] = val[1].strip() - - try: - address = params["ipaddr"] - except KeyError, e: - os.write(standard_err, "FENCE: Missing ipaddr param for fence_baytech...exiting") - sys.exit(1) - - try: - login = params["login"] - except KeyError, e: - os.write(standard_err, "FENCE: Missing login param for fence_baytech...exiting") - sys.exit(1) - - try: - port_num = params["port"] - except KeyError, e: - os.write(standard_err, "FENCE: Missing port param for fence_baytech...exiting") - sys.exit(1) - - try: - if 'passwd' in params: - passwd = params["passwd"] - if 'passwd_script' in params: - passwd_script = params['passwd_script'] - if passwd == "" and passwd_script == "": - raise "missing password" - except KeyError, e: - os.write(standard_err, "FENCE: Missing passwd param for fence_baytech...exiting") - sys.exit(1) - - try: - a = params["option"] - if a == "Off" or a == "OFF" or a == "off": - action = POWER_OFF - elif a == "On" or a == "ON" or a == "on": - action = POWER_ON - elif a == "Reboot" or a == "REBOOT" or a == "reboot": - action = POWER_REBOOT - except KeyError, e: - action = POWER_REBOOT - - ####End of stdin section - - - # retrieve passwd from passwd_script (if specified) - passwd_scr = '' - if len(passwd_script): - try: - if not os.access(passwd_script, os.X_OK): - raise 'script not executable' - p = os.popen(passwd_script, 'r', 1024) - passwd_scr = p.readline().strip() - if p.close() != None: - raise 'script failed' - except: - sys.stderr.write('password-script "%s" failed\n' % passwd_script) - passwd_scr = '' - - if passwd == "" and passwd_scr == "": - sys.stderr.write('password not available, exiting...') - sys.exit(1) - elif passwd == passwd_scr: - pass - elif passwd and passwd_scr: - # execute self, with password_scr as passwd, - # if that fails, continue with "passwd" argument as password - if len(sys.argv) > 1: - comm = sys.argv[0] - skip_next = False - for w in sys.argv[1:]: - if skip_next: - skip_next = False - elif w in ['-p', '-S']: - skip_next = True - else: - comm += ' ' + w - comm += ' -p ' + passwd_scr - ret = os.system(comm) - if ret != -1 and os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == 0: - # success - sys.exit(0) - else: - sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n') - else: # use stdin - p = os.popen(sys.argv[0], 'w', 1024) - for par in params: - if par not in ['passwd', 'passwd_script']: - p.write(par + '=' + params[par] + '\n') - p.write('passwd=' + passwd_scr + '\n') - p.flush() - if p.close() == None: - # success - sys.exit(0) - else: - sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n') - elif passwd_scr: - passwd = passwd_scr - # passwd all set - - - - ##Time to open telnet session and log in. - try: - sock = Telnet(address.strip()) - except socket.error, (errno, msg): - my_msg = "FENCE: A problem was encountered opening a telnet session with " + address - os.write(standard_err, my_msg) - os.write(standard_err, ("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))) - os.write(standard_err, "Firewall issue? Correct address?\n") - sys.exit(1) - - if verbose: - print "socket open to %s\n" % address - - ##This loop offers all expected responses in the regex_list, and - ##handles responses accordingly. - while 1: - i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) - if i == USERNAME: - if verbose: - print "Sending login: %s\n" % login - sock.write(login + "\r") - elif i == PASSWORD: - if verbose: - print "Sending password: %s\n" % passwd - sock.write(passwd + "\r") - elif i == PROMPT: - if verbose: - print "Evaluating prompt...%s\n" % txt - if action == POWER_OFF: - if verbose: - print "Sending power off command to port number %s\n" % port_num - sock.write("off " + port_num + " \r") - time.sleep(2) - break - if action == POWER_ON: - if verbose: - print "Sending power on command to port number %s" % port_num - sock.write("on " + port_num + "\r") - time.sleep(2) - break - if action == POWER_REBOOT: - if verbose: - print "Rebooting port number %s..." % port_num - sock.write("reboot " + port_num + "\r") - time.sleep(2) - break - - sock.close() - -if __name__ == "__main__": - main() diff --git a/fence/agents/bladecenter/Makefile b/fence/agents/bladecenter/Makefile deleted file mode 100644 index 5a617df..0000000 --- a/fence/agents/bladecenter/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_bladecenter.py -TARGET= fence_bladecenter - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_bladecenter: fence_bladecenter.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/bladecenter/fence_bladecenter.pl b/fence/agents/bladecenter/fence_bladecenter.pl deleted file mode 100755 index 8c0d44c..0000000 --- a/fence/agents/bladecenter/fence_bladecenter.pl +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -# -# Tested against: -# Firmware Type Build ID File Name Released Revision -# ---------------- -------- ------------ -------- -------- -# Main application BRET67D CNETMNUS.PKT 07-22-04 16 -# Boot ROM BRBR67D CNETBRUS.PKT 07-22-04 16 -# Remote control BRRG67D CNETRGUS.PKT 07-22-04 16 -# -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -$action = "reboot"; # Default fence action - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of blade center\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -n <num> blade number to operate on\n"; - print " -o <string> Action: on, off, reboot (default) or status\n"; - print " -p <string> Password for login\n"; - print " -S <path> Script to run to retrieve password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $quiet; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "ipaddr" ) - { - $host = $val; - } - elsif ($name eq "login" ) - { - $login = $val; - } - elsif ($name eq "option" ) - { - $action = $val; - } - elsif ($name eq "passwd" ) - { - $passwd = $val; - } - elsif ($name eq "passwd_script" ) { - $passwd_script = $val; - } - elsif ($name eq "blade" ) - { - $bladenum = $val; - } - elsif ($name eq "debuglog" ) - { - $verbose = $val; - } - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -sub get_power_state -{ - my ($junk) = @_; - fail "illegal argument to get_power_state()" if defined $junk; - - my $state=""; - - $t->print("env -T system:blade[$bladenum]"); - ($text, $match) = $t->waitfor("/system:blade\[$bladenum\]>/"); - - $t->print("power -state"); - ($text, $match) = $t->waitfor("/system:blade\[$bladenum\]>/"); - - if ($text =~ /power -state\n(on|off)/im ) - { - $state = $1; - } - else - { - fail "unexpected powerstate"; - } - - $t->print("env -T system"); - ($text, $match) = $t->waitfor("/system>/"); - - $_=$state; -} - -sub set_power_state -{ - my ($set,$junk) = @_; - fail "missing argument to set_power_state()" unless defined $set; - fail "illegal argument to set_power_state()" if defined $junk; - - my $state=""; - - $t->print("env -T system:blade[$bladenum]"); - ($text, $match) = $t->waitfor("/system:blade\[$bladenum\]>/"); - - $t->print("power -$set"); - ($text, $match) = $t->waitfor("/system:blade\[$bladenum\]>/"); - - fail "unexpected powerstate" unless ($text =~ /power -$set\nOK/im ); - - $t->print("env -T system"); - ($text, $match) = $t->waitfor("/system>/"); - - # need to sleep a few seconds to make sure that the bladecenter - # has time to issue the power on/off command - sleep 5; - - $_=$state; -} - -# MAIN - -if (@ARGV > 0) -{ - getopts("a:hl:n:o:p:S:qv:V") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - $host = $opt_a if defined $opt_a; - $login = $opt_l if defined $opt_l; - $passwd = $opt_p if defined $opt_p; - $action = $opt_o if defined $opt_o; - $bladenum = $opt_n if defined $opt_n; - $verbose = $opt_v if defined $opt_v; - $quiet = $opt_q if defined $opt_q; - - if (defined $opt_S) { - $pwd_script_output = `$opt_S`; - chomp($pwd_script_output); - if ($pwd_script_output) { - $passwd = $pwd_script_output; - } - } - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $host; - fail_usage "No '-n' flag specified." unless defined $bladenum; - fail_usage "No '-l' flag specified." unless defined $login; - fail_usage "No '-p' or '-S' flag specified." unless defined $passwd; - fail_usage "Unrecognised action '$action' for '-o' flag" - unless $action =~ /^(on|off|reboot|status)$/i; -} -else -{ - get_options_stdin(); - - fail "failed: no IP address" unless defined $host; - fail "failed: no blade number" unless defined $bladenum; - fail "failed: no login name" unless defined $login; - fail "failed: unrecognised action: $action" - unless $action =~ /^(on|off|reboot|status)$/i; - - if (defined $passwd_script) { - $pwd_script_output = `$passwd_script`; - chomp($pwd_script_output); - if ($pwd_script_output) { - $passwd = $pwd_script_output; - } - } - fail "failed: no password" unless defined $passwd; -} - -# convert $action to lower case -$_=$action; -if (/^on$/i) { $action = "on"; } -elsif (/^off$/i) { $action = "off"; } -elsif (/^reboot$/i) { $action = "reboot"; } -elsif (/^status$/i) { $action = "status"; } - -# -# Set up and log in -# -$t = new Net::Telnet; - -$t->input_log($verbose) if $verbose; -$t->open($host); - -$t->waitfor('/username:/'); -$t->print($login); - -$t->waitfor('/password:/'); -$t->print($passwd); - -($text, $match) = $t->waitfor("/system>/"); - -# -# Do the command -# -$success=0; -$_ = $action; -if (/(on|off)/) -{ - set_power_state $action; - get_power_state; - $success = 1 if (/^$action$/i); -} -elsif (/reboot/) -{ - set_power_state off; - get_power_state; - - if (/^off$/i) - { - set_power_state on; - get_power_state; - $success = 1 if (/^on$/i); - } -} -elsif (/status/) -{ - get_power_state; - $state=$_; - $success = 1 if defined $state; -} -else -{ - fail "fail: illegal action"; -} - -$t->print("exit"); -sleep 1; -$t->close(); - - -if ($success) -{ - print "success: blade$bladenum $action". ((defined $state) ? ": $state":"") - ."\n" unless defined $quiet; - exit 0; -} -else -{ - fail "fail: blade$bladenum $action"; - exit 1 -} diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py deleted file mode 100755 index 518f6a6..0000000 --- a/fence/agents/bladecenter/fence_bladecenter.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -## The Following Agent Has Been Tested On: -## -## Model Firmware -## +--------------------+---------------------------+ -## (1) Main application BRET85K, rev 16 -## Boot ROM BRBR67D, rev 16 -## Remote Control BRRG67D, rev 16 -## -##### - -import sys, re, pexpect, exceptions -sys.path.append("/usr/lib/fence") -from fencing import * - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - try: - node_cmd = "system:blade[" + options["-n"] + "]>" - - conn.send("env -T system:blade[" + options["-n"] + "]\r\n") - i = conn.log_expect(options, [ node_cmd, "system>" ] , SHELL_TIMEOUT) - if i == 1: - ## Given blade number does not exist - fail(EC_STATUS) - conn.send("power -state\r\n") - conn.log_expect(options, node_cmd, SHELL_TIMEOUT) - status = conn.before.splitlines()[-1] - conn.send("env -T system\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - return status.lower().strip() - -def set_power_status(conn, options): - action = { - 'on' : "powerup", - 'off': "powerdown" - }[options["-o"]] - - try: - node_cmd = "system:blade[" + options["-n"] + "]>" - - conn.send("env -T system:blade[" + options["-n"] + "]\r\n") - conn.log_expect(options, node_cmd, SHELL_TIMEOUT) - conn.send("power -"+options["-o"]+"\r\n") - conn.log_expect(options, node_cmd, SHELL_TIMEOUT) - conn.send("env -T system\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "cmd_prompt", "secure", "port", "identity_file" ] - - options = check_input(device_opt, process_input(device_opt)) - - ## - ## Fence agent specific defaults - ##### - if 0 == options.has_key("-c"): - options["-c"] = "system>" - - ## - ## Operate the fencing device - ###### - conn = fence_login(options) - fence_action(conn, options, set_power_status, get_power_status) - - ## - ## Logout from system - ###### - try: - conn.send("exit\r\n") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/brocade/Makefile b/fence/agents/brocade/Makefile deleted file mode 100644 index 445a39b..0000000 --- a/fence/agents/brocade/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_brocade.pl -TARGET= fence_brocade - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/brocade/fence_brocade.pl b/fence/agents/brocade/fence_brocade.pl deleted file mode 100755 index d75f368..0000000 --- a/fence/agents/brocade/fence_brocade.pl +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -$opt_o = 'disable'; # Default fence action - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of switch\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -n <num> Port number to operate on\n"; - print " -o <string> Action: disable (default) or enable\n"; - print " -p <string> Password for login\n"; - print " -S <path> Script to run to retrieve password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - - -if (@ARGV > 0) { - getopts("a:hl:n:o:p:S:qV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-a' flag specified." unless defined $opt_a; - fail_usage "No '-n' flag specified." unless defined $opt_n; - fail_usage "No '-l' flag specified." unless defined $opt_l; - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(disable|enable)$/i; - -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $opt_a; - fail "failed: no plug number" unless defined $opt_n; - fail "failed: no login name" unless defined $opt_l; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail "failed: no password" unless defined $opt_p; - fail "failed: unrecognised action: $opt_o" - unless $opt_o =~ /^(disable|enable)$/i; -} - -if ( $opt_o =~ /^(disable|enable)$/i ) -{ - $opt_o = "port".$1; -} - - -# -# Set up and log in -# - -$t = new Net::Telnet; - -$t->open($opt_a); - -$t->waitfor('/login:/'); - -$t->print($opt_l); - -$t->waitfor('/assword:/'); - -$t->print($opt_p); - -$t->waitfor('/>/'); - - - -# -# Do the command -# - -$cmd = "$opt_o $opt_n"; -$t->print($cmd); - - -# -# Assume here that the word "error" will appear after errors (bad assumption! see next check) -# - -($text, $match) = $t->waitfor('/>/'); -if ($text =~ /error/) -{ - fail "failed: error from switch\n"; -} - - -# -# Do a portshow on the port and look for the DISABLED string to verify success -# - -$t->print("portshow $opt_n"); -($text, $match) = $t->waitfor('/>/'); - -if ( $opt_o eq "portdisable" && !($text =~ /DISABLED/) ) -{ - fail "failed: portshow $opt_n does not show DISABLED\n"; -} -elsif ( $opt_o eq "portenable" && ($text =~ /DISABLED/) ) -{ - fail "failed: portshow $opt_n shows DISABLED\n"; -} - - -print "success: $opt_o $opt_n\n" unless defined $opt_q; -exit 0; - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - # FIXME -- depricated. use "port" instead. - elsif ($name eq "fm" ) - { - (my $dummy,$opt_n) = split /\s+/,$val; - print STDERR "Depricated "fm" entry detected. refer to man page.\n"; - } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - elsif ($name eq "login" ) - { - $opt_l = $val; - } - - # FIXME -- depreicated residue of old fencing system - elsif ($name eq "name" ) { } - - elsif ($name eq "option" ) - { - $opt_o = $val; - } - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "passwd_script") { - $opt_S = $val; - } - elsif ($name eq "port" ) - { - $opt_n = $val; - } - # elsif ($name eq "test" ) - # { - # $opt_T = $val; - # } - - # FIXME should we do more error checking? - # Excess name/vals will be eaten for now - else - { - fail "parse error: unknown option "$opt""; - } - } -} diff --git a/fence/agents/bullpap/Makefile b/fence/agents/bullpap/Makefile deleted file mode 100644 index 486c38e..0000000 --- a/fence/agents/bullpap/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_bullpap.pl -TARGET= fence_bullpap - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/bullpap/fence_bullpap.pl b/fence/agents/bullpap/fence_bullpap.pl deleted file mode 100755 index 5cad62f..0000000 --- a/fence/agents/bullpap/fence_bullpap.pl +++ /dev/null @@ -1,369 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -use Getopt::Std; -use POSIX; - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -$action = "reboot"; # Default fence action -my $bulldir = "/usr/local/bull/NSMasterHW/bin"; - -stat($bulldir); -die "NSMasterHW not installed correctly" if ! -d _; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of PAP console\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -d <domain> Domain to operate on\n"; - print " -o <string> Action: on, off, reboot (default) or status\n"; - print " -p <string> Password for login\n"; - print " -S <path> Script to run to retrieve password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - print "\n"; - print "When run with no arguments, $pname takes arguments from "; - print "standard\ninput, one line per option. They are as follows:\n"; - print "\n"; - print " ipaddr=<ip> Same as -a command line option\n"; - print " login=<name> Same as -l command line option\n"; - print " domain=<domain> Same as -d command line option\n"; - print " option=<string> Same as -o command line option\n"; - print " passwd=<string> Same as -p command line option\n"; - print " passwd_script=<path> Same as -S command line option\n\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $quiet; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "ipaddr" ) - { - $host = $val; - } - elsif ($name eq "login" ) - { - $login = $val; - } - elsif ($name eq "option" ) - { - $action = $val; - } - elsif ($name eq "passwd" ) - { - $passwd = $val; - } - elsif ($name eq "password" ) - { - $passwd = $val; - } - elsif ($name eq "passwd_script" ) { - $passwd_script = $val; - } - elsif ($name eq "domain" ) - { - $domain = $val; - } - elsif ($name eq "debuglog" ) - { - $verbose = $val; - } - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -sub get_power_state -{ - my ($ip,$dom,$user,$pass,$junk) = @_; - fail "missing IP address in get_power_state()" unless defined $ip; - fail "missing domain to get_power_state()" unless defined $dom; - fail "illegal argument to get_power_state()" if defined $junk; - - my $state=""; - my $cmd = $bulldir . "/pampower.pl"; - - $cmd = $cmd . " -a status"; - $cmd = $cmd . " -M $ip -D $dom"; - if (defined $user) { - $cmd = $cmd . " -u $user"; - } - if (defined $pass) { - $cmd = $cmd . " -p $pass"; - } - - $state=system($cmd); - WIFEXITED($state) || die "child killed abnormally"; - - $state=WEXITSTATUS($state); - if ($state == 0) { - $state = "ON"; - } elsif ($state == 1) { - $state = "OFF"; - } else { - $state = "$state TRANSITION"; - } - - $_=$state; -} - -sub set_power_state -{ - my ($ip,$dom,$set,$user,$pass,$junk) = @_; - fail "missing action to set_power_state()" unless defined $set; - fail "missing IP address in set_power_state()" unless defined $ip; - fail "missing domain to set_power_state()" unless defined $dom; - fail "illegal argument to set_power_state()" if defined $junk; - - my $state=""; - my $cmd = $bulldir . "/pampower.pl"; - - if ($set =~ /on/) { - $cmd = $cmd . " -a on"; - } else { - $cmd = $cmd . " -a off_force"; - } - - $cmd = $cmd . " -M $ip -D $dom"; - if (defined $user) { - $cmd = $cmd . " -u $user"; - } - if (defined $pass) { - $cmd = $cmd . " -p $pass"; - } - - $state=system "$cmd"; - - $_=$state; -} - -# MAIN - -if (@ARGV > 0) -{ - getopts("a:hl:d:o:p:S:qv:V") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - $host = $opt_a if defined $opt_a; - $login = $opt_l if defined $opt_l; - $passwd = $opt_p if defined $opt_p; - $action = $opt_o if defined $opt_o; - $domain = $opt_d if defined $opt_d; - $verbose = $opt_v if defined $opt_v; - $quiet = $opt_q if defined $opt_q; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $passwd = $pwd_script_out; - } - } - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $host; - fail_usage "No '-d' flag specified." unless defined $domain; - fail_usage "No '-l' flag specified." unless defined $login; - fail_usage "No '-p' or '-S' flag specified." unless defined $passwd; - fail_usage "Unrecognised action '$action' for '-o' flag" - unless $action =~ /^(on|off|reboot|status)$/i; -} -else -{ - get_options_stdin(); - - fail "failed: no IP address" unless defined $host; - fail "failed: no domain" unless defined $domain; - fail "failed: no login name" unless defined $login; - fail "failed: unrecognized action: $action" - unless $action =~ /^(on|off|reboot|status)$/i; - - if (defined $passwd_script) { - $pwd_script_out = `$passwd_script`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $passwd = $pwd_script_out; - } - } - fail "failed: no password" unless defined $passwd; -} - -# convert $action to lower case -$_=$action; -if (/^on$/i) { $action = "on"; } -elsif (/^off$/i) { $action = "off"; } -elsif (/^reboot$/i) { $action = "reboot"; } -elsif (/^status$/i) { $action = "status"; } - -# -# If if pampower / pamreset don't exist, we're done. -# -# -M -- the maintenance port on the NovaScale Windows 2000 master server -# -D -- the Domain to reboot -# -u -- User name -# -p -- Password -# -#/usr/local/bull/NSMasterHW/bin/pamreset.pl -# -M 192.168.78.169 -D Domaine2-8CPU -u Administrator -p administrator -# -#/usr/local/bull/NSMasterHW/bin/pampower.pl -a off_force -# -M 192.168.78.169 -D Domaine2-8CPU -u Administrator -p administrator -# -#/usr/local/bull/NSMasterHW/bin/pampower.pl -a on -# -M 192.168.78.169 -D Domaine2-8CPU -u Administrator -p administrator -# -# Do the command -# -$success=0; -$_ = $action; -if (/(on|off)/) -{ - my $timeout = 120; # 120 = max of (60, 120). Max timeout for "on" - # on 32-way bull machines - - set_power_state $host,$domain,$action,$login,$passwd; - do { - sleep 5; - $state=get_power_state $host,$domain,$login,$passwd; - $timeout -= 5; - } while ($timeout > 0 && !($state =~ /^$action$/i)); - - $success = 1 if ($state=~/^$action$/i); -} -elsif (/reboot/) -{ - my $timeout = 60; # 60 seconds for "off" for 32-way bull machines - - set_power_state $host,$domain,"off",$login,$passwd; - do { - sleep 5; - $state=get_power_state $host,$domain,$login,$passwd; - $timeout -= 5; - } while ($timeout > 0 && $state != 0); - - if ($timeout <= 0) { - $success = 0; - } else { - $timeout = 120; # 120 seconds for on, for 32-way bull machines - set_power_state $host,$domain,"on",$login,$passwd; - do { - sleep 5; - $state=get_power_state $host,$domain,$login,$passwd; - $timeout -= 5; - } while ($timeout > 0 && $state != 0); - - $success = 1 if ($state == 0); - } -} -elsif (/status/) -{ - get_power_state $host,$domain,$login,$passwd; - $state=$_; - $success = 1 if defined $state; -} -else -{ - fail "fail: illegal action"; -} - -if ($success) -{ - print "success: domain $domain $action". ((defined $state) ? ": $state":"") - ."\n" unless defined $quiet; - exit 0; -} -else -{ - fail "fail: domain $domain $action"; - exit 1 -} - - diff --git a/fence/agents/cpint/Makefile b/fence/agents/cpint/Makefile deleted file mode 100644 index ec68b78..0000000 --- a/fence/agents/cpint/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_cpint.pl -TARGET= fence_cpint - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/cpint/fence_cpint.pl b/fence/agents/cpint/fence_cpint.pl deleted file mode 100755 index ca5eac4..0000000 --- a/fence/agents/cpint/fence_cpint.pl +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -$comm_prog = "hcp"; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -h usage\n"; - print " -u <string> userid of the virtual machine to fence\n"; - print " -q quiet mode\n"; - print " -V Version\n"; - - exit 0; -} - -sub fail -{ - ($msg)=@_; - print "failed: " . $msg . "\n" unless defined $opt_q; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_q; - print stderr $msg."\n" if $msg; - print stderr "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print stderr "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced or stomithd - elsif ($name eq "agent" ) { } - - # FIXME -- depricated. use "userid" and "password" instead. - elsif ($name eq "fm" ) - { - (my $dummy,$opt_u,$opt_p) = split /\s+/,$val; - print STDERR "Depricated "fm" entry detected. refer to man page.\n"; - } - - # FIXME -- depreicated residue of old fencing system - elsif ($name eq "name" ) { } - - elsif ($name eq "userid" ) - { - $opt_u = $val; - } - - else - { - print stderr "parse error: unknown option "$opt"\n"; - #> exit 2; - } - } -} - -if (@ARGV > 0){ - getopts("hqu:V") || fail_usage; - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - fail_usage "No '-u' flag specified." unless defined $opt_u; -} else { - get_options_stdin(); - - fail "no userid" unless defined $opt_u; -} - -$ret_val = system("$comm_prog send cp $opt_u logoff > /dev/null 2>&1") >> 8; -fail "$comm_prog failed ($ret_val)" unless ($ret_val == 0 || $ret_val == 45); -$ret_val = system("$comm_prog send cp $opt_u > /dev/null 2>&1") >> 8; -fail "$userid isn't logged off. $comm_prog return ($ret_val)" unless ($ret_val == 45); - -print "success: booted userid $opt_u\n" unless defined $opt_q; -exit 0; diff --git a/fence/agents/drac/Makefile b/fence/agents/drac/Makefile deleted file mode 100644 index 914d2c9..0000000 --- a/fence/agents/drac/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE1= fence_drac.pl -TARGET1= fence_drac - -SOURCE2= fence_drac5.py -TARGET2= fence_drac5 - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET1) $(TARGET2) - -fence_drac: fence_drac.pl - : > $(TARGET1) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE1) >> $(TARGET1) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET1) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET1) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET1) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE1) >> $(TARGET1) - chmod +x $(TARGET1) - -fence_drac5: fence_drac5.py - : > $(TARGET2) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE2) >> $(TARGET2) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET2) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET2) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET2) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE2) >> $(TARGET2) - chmod +x $(TARGET2) - -copytobin: ${TARGET1} ${TARGET2} - cp ${TARGET1} ${top_srcdir}/bin/${TARGET1} - cp ${TARGET2} ${top_srcdir}/bin/${TARGET2} - -clean: - rm -f $(TARGET1) $(TARGET2) diff --git a/fence/agents/drac/fence_drac.pl b/fence/agents/drac/fence_drac.pl deleted file mode 100755 index 7b8f51e..0000000 --- a/fence/agents/drac/fence_drac.pl +++ /dev/null @@ -1,668 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -# The following agent has been tested on: -# -# Model DRAC Version Firmware -# ------------------- -------------- ---------------------- -# PowerEdge 750 DRAC III/XT 3.20 (Build 10.25) -# Dell Remote Access Controller - ERA and DRAC III/XT, v.3.20, A00 -# -# PowerEdge 1855 DRAC/MC 1.1 (Build 03.03) -# PowerEdge 1855 DRAC/MC 1.2 (Build 03.03) -# PowerEdge 1855 DRAC/MC 1.3 (Build 06.12) -# PowerEdge 1850 DRAC 4/I 1.35 (Build 09.27) -# PowerEdge 1850 DRAC 4/I 1.40 (Build 08.24) -# PowerEdge 1950 DRAC 5 1.0 (Build 06.05.12) -# - -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -my $telnet_timeout = 10; # Seconds to wait for matching telent response -my $power_timeout = 20; # time to wait in seconds for power state changes -$action = 'reboot'; # Default fence action. - -my $logged_in = 0; -my $quiet = 0; - -my $t = new Net::Telnet; - -my $DRAC_VERSION_UNKNOWN = '__unknown__'; -my $DRAC_VERSION_III_XT = 'DRAC III/XT'; -my $DRAC_VERSION_MC = 'DRAC/MC'; -my $DRAC_VERSION_4I = 'DRAC 4/I'; -my $DRAC_VERSION_4P = 'DRAC 4/P'; -my $DRAC_VERSION_5 = 'DRAC 5'; - -my $PWR_CMD_SUCCESS = "/^OK/"; -my $PWR_CMD_SUCCESS_DRAC5 = "/^Server power operation successful$/"; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of DRAC\n"; - print " -c <cmd_prompt> force DRAC command prompt\n"; - print " -d <dracversion> force DRAC version to use\n"; - print " -D <debugfile> debugging output file\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -m <modulename> DRAC/MC module name\n"; - print " -o <string> Action: reboot (default), off or on\n"; - print " -p <string> Login password\n"; - print " -S <path> Script to run to retrieve password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - print "\n"; - print "CCS Options:\n"; - print " action = "string" Action: reboot (default), off or on\n"; - print " debug = "debugfile" debugging output file\n"; - print " ipaddr = "ip" IP address or hostname of DRAC\n"; - print " login = "name" Login name\n"; - print " passwd = "string" Login password\n"; - print " passwd_script = "path" Script to run to retrieve password\n"; - - exit 0; -} - -sub msg -{ - ($msg)=@_; - print $msg."\n" unless $quiet; -} - -sub fail -{ - ($msg)=@_; - print $msg."\n" unless $quiet; - - if (defined $t) - { - # make sure we don't get stuck in a loop due to errors - $t->errmode('return'); - - logout() if $logged_in; - $t->close - } - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - exit 0; -} - - -sub login -{ - $t->open($address) or - fail "failed: telnet open failed: ". $t->errmsg."\n"; - - # Expect 'Login: ' - ($_) = $t->waitfor(Match => "/[Ll]ogin: /", Timeout=>15) or - fail "failed: telnet failed: ". $t->errmsg."\n" ; - - # Determine DRAC version - if (/Dell Embedded Remote Access Controller (ERA)\nFirmware Version/m) - { - $drac_version = $DRAC_VERSION_III_XT; - } else { - if (/.*((DRAC[^)]*))/m) - { - print "detected drac version '$1'\n" if $verbose; - $drac_version = $1 unless defined $drac_version; - - print "WARNING: detected drac version '$1' but using " - . "user defined version '$drac_version'\n" - if ($drac_version ne $1); - } - else - { - $drac_version = $DRAC_VERSION_UNKNOWN; - } - } - - # Setup prompt - if ($drac_version =~ /$DRAC_VERSION_III_XT/) - { - $cmd_prompt = "/\[$login\]# /" - unless defined $cmd_prompt; - } - elsif ($drac_version =~ /$DRAC_VERSION_MC/) - { - $cmd_prompt = "/DRAC\/MC:/" - unless defined $cmd_prompt; - } - elsif ($drac_version =~ /$DRAC_VERSION_4I/) - { - $cmd_prompt = "/\[$login\]# /" - unless defined $cmd_prompt; - } - elsif ($drac_version =~ /$DRAC_VERSION_4P/) - { - $cmd_prompt = "/\[$login\]# /" - unless defined $cmd_prompt; - } - else - { - $drac_version = $DRAC_VERSION_UNKNOWN; - } - - # Take a guess as to what the prompt might be if not already defined - $cmd_prompt="/(\[$login\]# |DRAC\/MC:|\$ )/" unless defined $cmd_prompt; - - - # Send login - $t->print($login); - - # Expect 'Password: ' - $t->waitfor("/Password: /") or - fail "failed: timeout waiting for password"; - - # Send password - $t->print($passwd); - - # DRAC5 prints version controller version info - # only after you've logged in. - if ($drac_version eq $DRAC_VERSION_UNKNOWN) { - if ($t->waitfor(Match => "/.*($DRAC_VERSION_5)/m")) { - $drac_version = $DRAC_VERSION_5; - $cmd_prompt = "/\$ /"; - $PWR_CMD_SUCCESS = $PWR_CMD_SUCCESS_DRAC5; - } else { - print "WARNING: unable to detect DRAC version '$_'\n"; - } - } - - $t->waitfor($cmd_prompt) or - fail "failed: invalid username or password"; - - if ($drac_version eq $DRAC_VERSION_UNKNOWN) { - print "WARNING: unsupported DRAC version '$drac_version'\n"; - } - - $logged_in = 1; -} - -# -# Set the power status of the node -# -sub set_power_status -{ - my ($state,$dummy) = @_; - my $cmd,$svr_action; - - if ( $state =~ /^on$/) { $svr_action = "powerup" } - elsif( $state =~ /^off$/) { $svr_action = "powerdown" } - - if ($drac_version eq $DRAC_VERSION_MC) - { - $cmd = "serveraction -m $modulename -d 0 $svr_action"; - } - elsif ($drac_version eq $DRAC_VERSION_5) { - $cmd = "racadm serveraction $svr_action"; - } else - { - $cmd = "serveraction -d 0 $svr_action"; - } - - $t->print($cmd); - - # Expect /$cmd_prompt/ - ($_) = $t->waitfor($cmd_prompt) or - fail "failed: unexpected serveraction response"; - - my @cmd_out = split /\n/; - - # discard command sent to DRAC - $_ = shift @cmd_out; - s/\e[(([0-9]+;)*[0-9]+)*[ABCDfHJKmsu]//g; #strip ansi chars - s/^.*\x0D//; - - fail "failed: unkown dialog exception: '$_'" unless (/^$cmd$/); - - # Additional lines of output probably means an error. - # Aborting to be safe. Note: additional user debugging will be - # necessary, run with -D and -v flags - my $err; - while (@cmd_out) - { - $_ = shift @cmd_out; - #firmware vers 1.2 on DRAC/MC sends ansi chars - evil - s/\e[(([0-9]+;)*[0-9]+)*[ABCDfHJKmsu]//g; - s/^.*\x0D//; - - next if (/^\s*$/); # skip empty lines - if (defined $err) - { - $err = $err."\n$_"; - } - else - { - next if ($PWR_CMD_SUCCESS); - $err = $_; - } - } - fail "failed: unexpected response: '$err'" if defined $err; -} - - -# -# get the power status of the node and return it in $status and $_ -# -sub get_power_status -{ - my $status; - my $modname = $modulename; - my $cmd; - - if ($drac_version eq $DRAC_VERSION_5) { - $cmd = "racadm serveraction powerstatus"; - } else { - $cmd = "getmodinfo"; - } - - $t->print($cmd); - - ($_) = $t->waitfor($cmd_prompt); - - my $found_header = 0; - my $found_module = 0; - - my @cmd_out = split /\n/; - - # discard command sent to DRAC - $_ = shift @cmd_out; - #strip ansi control chars - s/\e[(([0-9]+;)*[0-9]+)*[ABCDfHJKmsu]//g; - s/^.*\x0D//; - - fail "failed: unkown dialog exception: '$_'" unless (/^$cmd$/); - - if ($drac_version ne $DRAC_VERSION_5) { - #Expect: - # #<group> <module> <presence> <pwrState> <health> <svcTag> - # 1 ----> chassis Present ON Normal CQXYV61 - # - # Note: DRAC/MC has many entries in the table whereas DRAC III has only - # a single table entry. - - while (1) - { - $_ = shift @cmd_out; - if (/^#<group>\s*<module>\s*<presence>\s*<pwrState>\s*<health>\s*<svcTag>/) - { - $found_header = 1; - last; - } - } - fail "failed: invalid 'getmodinfo' header: '$_'" unless $found_header; - } - - foreach (@cmd_out) - { - s/^\s+//g; #strip leading space - s/\s+$//g; #strip training space - - if ($drac_version eq $DRAC_VERSION_5) { - if(m/^Server power status: (\w+)/) { - $status = lc($1); - } - } else { - my ($group,$arrow,$module,$presence,$pwrstate,$health, - $svctag,$junk) = split /\s+/; - - if ($drac_version eq $DRAC_VERSION_III_XT || $drac_version eq $DRAC_VERSION_4I || $drac_version eq $DRAC_VERSION_4P) - { - fail "failed: extraneous output detected from 'getmodinfo'" if $found_module; - $found_module = 1; - $modname = $module; - } - - if ($modname eq $module) - { - fail "failed: duplicate module names detected" if $status; - $found_module = 1; - - fail "failed: module not reported present" unless ($presence =~ /Present/); - $status = $pwrstate; - } - - } - } - - if ($drac_version eq $DRAC_VERSION_MC) - { - fail "failed: module '$modulename' not detected" unless $found_module; - } - - $_=$status; - if(/^(on|off)$/i) - { - # valid power states - } - elsif ($status) - { - fail "failed: unknown power state '$status'"; - } - else - { - fail "failed: unable to determine power state"; - } -} - - -# Wait upto $power_timeout seconds for node power state to change to -# $state before erroring out. -# -# return 1 on success -# return 0 on failure -# -sub wait_power_status -{ - my ($state,$dummy) = @_; - my $status; - - $state = lc $state; - - for (my $i=0; $i<$power_timeout ; $i++) - { - get_power_status; - $status = $_; - my $check = lc $status; - - if ($state eq $check ) { return 1 } - sleep 1; - } - $_ = "timed out waiting to power $state"; - return 0; -} - -# -# logout of the telnet session -# -sub logout -{ - $t->print(""); - $t->print("exit"); -} - -# -# error routine for Net::Telnet instance -# -sub telnet_error -{ - fail "failed: telnet returned: ".$t->errmsg."\n"; -} - -# -# execute the action. Valid actions are 'on' 'off' 'reboot' and 'status'. -# TODO: add 'configure' that uses racadm rpm to enable telnet on the drac -# -sub do_action -{ - get_power_status; - my $status = $_; - - if ($action =~ /^on$/i) - { - if ($status =~ /^on$/i) - { - msg "success: already on"; - return; - } - - set_power_status on; - fail "failed: $_" unless wait_power_status on; - - msg "success: powered on"; - } - elsif ($action =~ /^off$/i) - { - if ($status =~ /^off$/i) - { - msg "success: already off"; - return; - } - - set_power_status off; - fail "failed: $_" unless wait_power_status off; - - msg "success: powered off"; - } - elsif ($action =~ /^reboot$/i) - { - if ( !($status =~ /^off$/i) ) - { - set_power_status off; - } - fail "failed: $_" unless wait_power_status off; - - set_power_status on; - fail "failed: $_" unless wait_power_status on; - - msg "success: rebooted"; - } - elsif ($action =~ /^status$/i) - { - msg "status: $status"; - return; - } - else - { - fail "failed: unrecognised action: '$action'"; - } -} - -# -# Decipher STDIN parameters -# -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) - { - } - elsif ($name eq "ipaddr" ) - { - $address = $val; - } - elsif ($name eq "login" ) - { - $login = $val; - } - elsif ($name eq "action" ) - { - $action = $val; - } - elsif ($name eq "passwd" ) - { - $passwd = $val; - } - elsif ($name eq "passwd_script" ) - { - $passwd_script = $val; - } - elsif ($name eq "debug" ) - { - $debug = $val; - } - elsif ($name eq "modulename" ) - { - $modulename = $val; - } - elsif ($name eq "drac_version" ) - { - $drac_version = $val; - } - elsif ($name eq "cmd_prompt" ) - { - $cmd_prompt = $val; - } - # Excess name/vals will fail - else - { - fail "parse error: unknown option "$opt""; - } - } -} - - -### MAIN ####################################################### - -# -# Check parameters -# -if (@ARGV > 0) { - getopts("a:c:d:D:hl:m:o:p:S:qVv") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - $quiet = 1 if defined $opt_q; - $debug = $opt_D; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - $address = $opt_a; - - fail_usage "No '-l' flag specified." unless defined $opt_l; - $login = $opt_l; - - $modulename = $opt_m if defined $opt_m; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - $passwd = $opt_p; - - $verbose = $opt_v if defined $opt_v; - - $cmd_prompt = $opt_c if defined $opt_c; - $drac_version = $opt_d if defined $opt_d; - - if ($opt_o) - { - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(Off|On|Reboot|status)$/i; - $action = $opt_o; - } - -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $address; - fail "failed: no login name" unless defined $login; - - if (defined $passwd_script) { - $pwd_script_out = `$passwd_script`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $passwd = $pwd_script_out; - } - } - - fail "failed: no password" unless defined $passwd; - fail "failed: unrecognised action: $action" - unless $action =~ /^(Off|On|Reboot|status)$/i; -} - - -$t->timeout($telnet_timeout); -$t->input_log($debug) if $debug; -$t->errmode('return'); - -login; - -# Abort on failure beyond here -$t->errmode(&telnet_error); - -if ($drac_version eq $DRAC_VERSION_III_XT) -{ - fail "failed: option 'modulename' not compatilble with DRAC version '$drac_version'" - if defined $modulename; -} -elsif ($drac_version eq $DRAC_VERSION_MC) -{ - fail "failed: option 'modulename' required for DRAC version '$drac_version'" - unless defined $modulename; -} - -do_action; - -logout; - -exit 0; - - diff --git a/fence/agents/drac/fence_drac5.py b/fence/agents/drac/fence_drac5.py deleted file mode 100644 index cefe673..0000000 --- a/fence/agents/drac/fence_drac5.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/python - -##### -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -## The Following Agent Has Been Tested On: -## -## DRAC Version Firmware -## +-----------------+---------------------------+ -## DRAC 5 1.0 (Build 06.05.12) -## DRAC 5 1.21 (Build 07.05.04) -## -##### - -import sys, re, pexpect, exceptions -sys.path.append("/usr/lib/fence") -from fencing import * - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - try: - if options["model"] == "DRAC CMC": - conn.sendline("racadm serveraction powerstatus -m " + options["-m"]) - elif options["model"] == "DRAC 5": - conn.sendline("racadm serveraction powerstatus") - - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - status = re.compile("(^|: )(ON|OFF|Powering ON|Powering OFF)\s*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(2) - if status.lower().strip() in ["on", "powering on", "powering off"]: - return "on" - else: - return "off" - -def set_power_status(conn, options): - action = { - 'on' : "powerup", - 'off': "powerdown" - }[options["-o"]] - - try: - if options["model"] == "DRAC CMC": - conn.sendline("racadm serveraction " + action + " -m " + options["-m"]) - elif options["model"] == "DRAC 5": - conn.sendline("racadm serveraction " + action) - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "cmd_prompt", "secure", "drac_version", "module_name" ] - - options = check_input(device_opt, process_input(device_opt)) - - ## - ## Fence agent specific defaults - ##### - if 0 == options.has_key("-c"): - options["-c"] = "$" - - ## - ## Operate the fencing device - ###### - conn = fence_login(options) - - if conn.before.find("CMC") >= 0: - if 0 == options.has_key("-m"): - fail_usage("Failed: You have to enter module name (-m)") - - options["model"]="DRAC CMC" - elif conn.before.find("DRAC 5") >= 0: - options["model"]="DRAC 5" - else: - ## Assume this is DRAC 5 by default as we don't want to break anything - options["model"]="DRAC 5" - - fence_action(conn, options, set_power_status, get_power_status) - - ## - ## Logout from system - ###### - try: - conn.sendline("exit") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/drac/test_drac.sh b/fence/agents/drac/test_drac.sh deleted file mode 100755 index 55ebc4d..0000000 --- a/fence/agents/drac/test_drac.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash - -verbose="-D /dev/stdout -v " -passwd="calvin" -login="root" - -drac="drac.localhost.localdomain" -modulename=" -m Server-1 " - - -fence_drac="./fence_drac.pl" -i=0 - -cmd() -{ - echo $* - out=$(echo $*; $*) - out_exit=$? - - echo "$out" > out.log.$i - echo "Exit $out_exit" >> out.log.$i - - if [ $out_exit -ne 0 ] - then - echo "ASSERTION FAILURE: command failed: see out.log.$i" >&2 - exit 1 - fi - - : $((i++)) -} - -pause() -{ - echo "press ENTER to continue" - read -} - -assert() -{ - get_status - if [ "$status" != "$1" ] - then - echo "ASSERTION FAILURE: power status is '$status' not '$1'" >&2 - exit 1 - fi -} - -get_status() -{ - cmd $fence_drac -o status -a $drac -l $login -p $passwd $modulename $verbose - status=$(echo "$out" | awk '($1 == "status:") { print tolower($2)}') - echo "status -> $status" -} - -get_status -pause - -cmd $fence_drac -o off -a $drac -l $login -p $passwd $modulename $verbose -assert off - -cmd $fence_drac -o on -a $drac -l $login -p $passwd $modulename $verbose -assert on - -cmd $fence_drac -o off -a $drac -l $login -p $passwd $modulename $verbose -assert off - -cmd $fence_drac -o reboot -a $drac -l $login -p $passwd $modulename $verbose -assert on - -cmd $fence_drac -o on -a $drac -l $login -p $passwd $modulename $verbose -assert on - -cmd $fence_drac -o reboot -a $drac -l $login -p $passwd $modulename $verbose -assert on - -cmd $fence_drac -o off -a $drac -l $login -p $passwd $modulename $verbose -assert off - -cmd $fence_drac -o off -a $drac -l $login -p $passwd $modulename $verbose -assert off - -echo SUCCESS -exit 0 diff --git a/fence/agents/egenera/Makefile b/fence/agents/egenera/Makefile deleted file mode 100644 index a5f9215..0000000 --- a/fence/agents/egenera/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_egenera.pl -TARGET= fence_egenera -LOGDIR= /var/log/cluster - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_egenera: fence_egenera.pl - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - sed -ie 's#@''LOGDIR@#${LOGDIR}#g' $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - install -d ${DESTDIR}/${LOGDIR} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/egenera/fence_egenera.pl b/fence/agents/egenera/fence_egenera.pl deleted file mode 100755 index 1c75090..0000000 --- a/fence/agents/egenera/fence_egenera.pl +++ /dev/null @@ -1,442 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use IPC::Open3; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=("Copyright (C) Red Hat, Inc. 2004 All rights reserved."); -$BUILD_DATE=""; -#END_VERSION_GENERATION - -# Get the program name from $0 and strip directory names -$_=$0; -$|=1; -s/.*///; -my $pname = $_; - -$esh="/opt/panmgr/bin/esh"; - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -c <string> cserver\n"; - print " -h help\n"; - print " -l <string> lpan\n"; - print " -o <string> Action: reboot (default), off, on or status\n"; - print " -p <string> pserver\n"; - print " -u <string> username (default=root)\n"; - print " -q quiet mode\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg)=@_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -if (@ARGV > 0) -{ - getopts("c:hl:o:p:u:qV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - $cserv = $opt_c if defined $opt_c; - $lpan = $opt_l if defined $opt_l; - $pserv = $opt_p if defined $opt_p; - $action = $opt_o if defined $opt_o; - $user = $opt_u if defined $opt_u; -} -else -{ - get_options_stdin(); -} - -$action = "reboot" unless defined $action; -$user = "root" unless defined $user; - -fail "failed: no cserver defined" unless defined $cserv; -fail "failed: no lpan defined" unless defined $lpan; -fail "failed: no pserver defined" unless defined $pserv; - -fail "failed: unrecognised action: $action" - unless $action =~ /^(off|on|reboot|status|pblade)$/i; - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - elsif ($name eq "agent" ) - { - # DO NOTHING -- this field is used by fenced - } - - elsif ($name eq "cserver" ) - { - $cserv = $val; - } - - elsif ($name eq "lpan" ) - { - $lpan = $val; - } - - elsif ($name eq "pserver" ) - { - $pserv = $val; - } - - elsif ($name eq "action" ) - { - $action = $val; - } - - elsif ($name eq "esh" ) - { - $esh = $val; - } - elsif ($name eq "user" ) - { - $user = $val; - } - - # FIXME should we do more error checking? - # Excess name/vals will be eaten for now - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -# _pserver_query_field -- query the state of the pBlade or Status field -# and return it's value in $_. -# Return 0 on success, or non-zero on error -sub _pserver_query_field -{ - my ($field,$junk) = @_; - - if ($field ne "pBlade" && $field ne "Status") - { - $_="Error _pserver_query_field: unknown field of type '$field'"; - return 1; - } - - my $val; - - my $cmd = "ssh -l $user $cserv $esh pserver $lpan/$pserv"; - my $pid = open3 (*WTR, *RDR,*RDR, $cmd) - or die "error open3(): $!"; - - while(<RDR>) - { - chomp; - my $line = $_; - my @fields = split /\s+/,$line; - - if ($fields[0] eq "Error:") - { - $val=$line; - print "Debug ERROR: $val\n"; - last; - } - elsif ($fields[0] eq $pserv) - { - if ( $field eq "Status" ) - { - $val=$fields[1]; - } - elsif ($field eq "pBlade" ) - { - # grrr... Status can be "Shutting down" - if ($fields[1] ne "Shutting") - { - $val=$fields[3]; - } - else - { - $val=$fields[4]; - } - } - } - } - - close WTR; - close RDR; - - waitpid $pid,0; - my $rtrn = $?>>8; - $_=$val if defined $val; - return $rtrn; -} - -# return the pBlade of an lpan/pserver in $_. -# Return 0 on success or non=zero on error -sub pserver_pblade -{ - _pserver_query_field "pBlade"; -} - -# return the Status of an lpan/pserver in $_. -# Return 0 on success or non=zero on error -sub pserver_status -{ - _pserver_query_field "Status"; -} - -# boot an lpan/pserver. -# Return 0 if the status is "Booted" or "Booting" or non-zero on failure. -# Continue checking the value until the status is "Boot" or "Booting" or -# until a timeout of 120 seconds has been reached. -sub pserver_boot -{ - my $rtrn=1; - - # It seems it can take a while for a pBlade to - # boot sometimes. We shall wait for 120 seconds - # before giving up on a node returning failure - for (my $trys=0; $trys<120; $trys++) - { - last if (pserver_status != 0); - - my $status = $_; - if ( $status eq "Booted" || $status eq "Booting") - { - $rtrn=0; - last; - } - - if(pserver_pblade) - { - die "error getting pBlade info"; - } - - # Is there any harm in sending this command multiple times? - my $cmd = "ssh -l $user $cserv $esh pserver -b $lpan/$pserv"; - my $pid = open3 (*WTR, *RDR,*RDR, $cmd) - or die "error open3(): $!"; - - close WTR; - close RDR; - - waitpid $pid,0; - $rtrn = $?>>8; - - sleep 1; - } - return $rtrn; -} - -# boot an lpan/pserver. -# Return 0 if the status is "Shutdown" or non-zero on failure. -# Continue checking the value until the status is "Shutdown" or -# until a timeout of 20 seconds has been reached. -sub pserver_shutdown -{ - my $rtrn=1; - local *egen_log; - open(egen_log,">>/@LOGDIR@/eglog"); - print egen_log "Attempting shutdown at ".`date`."\n"; - for (my $trys=0; $trys<20; $trys++) - { - last if (pserver_status != 0); - - - my $status = $_; - print egen_log "shutdown: $trys $status\n"; - if (/^Shutdown/) - { - $rtrn=0; - last; - } - elsif (/^Shutting/) - { - # We are already in the process of shutting down. - # do I need to do anything here? - # We'll just wait for now - } - elsif (/^Booting/) - { - # Server is already on the way back up. Do nothing - $rtrn=0; - last; - } - elsif (/^Booted(KDB)/ || /^Debugging/ ) - { - print egen_log "shutdown: crash dump being performed. Waiting\n"; - $rtrn=0; - last; - } - else - { - if (pserver_pblade) - { - die "error getting pBlade info: $_"; - } - - # is there any harm in sending this command multiple - # times? - my $cmd = "ssh -l $user $cserv $esh blade -s $_"; - print egen_log "shutdown: $cmd being called, before open3\n"; - my $pid = open3 (*WTR, *RDR,*RDR, $cmd) - or die "error open3(): $!"; - print egen_log "shutdown: after calling open3\n"; - @outlines = <RDR>; - print egen_log "shutdown: Open3 result: ", @outlines, "\n"; - - close WTR; - close RDR; - - waitpid $pid,0; - $rtrn = $?>>8; - } - - sleep 1; - } - print egen_log "shutdown: Returning from pserver_shutdown with return code $rtrn\n"; - return $rtrn; -} - - -$_=$action; -if (/^status$/i) -{ - if (pserver_status==0) - { - print "$lpan/$pserv is $_\n" unless defined $opt_q; - exit 0; - } - else - { - fail "failed to get status of $lpan/$pserv: $_"; - } -} -elsif (/^pblade$/i) -{ - if (pserver_pblade==0) - { - print "$lpan/$pserv is $_\n" unless defined $opt_q; - exit 0; - } - else - { - fail "failed to get pblade of $lpan/$pserv: $_"; - } -} -elsif (/^off$/i) -{ - if (pserver_shutdown==0) - { - print "success: $lpan/$pserv has been shutdown\n" - unless defined $opt_q; - exit 0; - } - else - { - fail "failed to shutdown $lpan/$pserv"; - } -} -elsif (/^on$/i) -{ - if (pserver_boot==0) - { - print "success: $lpan/$pserv has been turned on\n" - unless defined $opt_q; - exit 0; - } - else - { - fail "failed to turn on $lpan/$pserv"; - } -} -elsif (/^reboot$/i) -{ - if (pserver_shutdown!=0) - { - fail "failed to shutdown $lpan/$pserv"; - } - - if (pserver_boot==0) - { - print "success: $lpan/$pserv has been rebooted\n" - unless defined $opt_q; - exit 0; - } - else - { - fail "failed to turn on $lpan/$pserv"; - } -} -else -{ - die "unknown action: $action"; -} diff --git a/fence/agents/eps/Makefile b/fence/agents/eps/Makefile deleted file mode 100644 index 3e086c9..0000000 --- a/fence/agents/eps/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_eps.py -TARGET= fence_eps - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_eps: fence_eps.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -install: all - if [ ! -d ${sbindir} ]; then \ - install -d ${sbindir}; \ - fi - install -m755 ${TARGET} ${sbindir} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/eps/fence_eps.py b/fence/agents/eps/fence_eps.py deleted file mode 100644 index 69068b1..0000000 --- a/fence/agents/eps/fence_eps.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/python - -# The Following Agent Has Been Tested On: -# ePowerSwitch 8M+ version 1.0.0.4 - -import sys, re, time -import httplib, base64, string,socket -sys.path.append("/usr/lib/fence") -from fencing import * - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -# Log actions and results from EPS device -def eps_log(options,str): - if options["log"]>=LOG_MODE_VERBOSE: - options["debug_fh"].write(str) - -# Run command on EPS device. -# @param options Device options -# @param params HTTP GET parameters (without ?) -def eps_run_command(options, params): - try: - # New http connection - conn = httplib.HTTPConnection(options["-a"]) - - request_str="/"+options["-c"] - - if (params!=""): - request_str+="?"+params - - eps_log(options,"GET "+request_str+"\n") - conn.putrequest('GET', request_str) - - if (options.has_key("-l")): - if (not options.has_key("-p")): - options["-p"]="" # Default is empty password - - # String for Authorization header - auth_str = 'Basic ' + string.strip(base64.encodestring(options["-l"]+':'+options["-p"])) - eps_log(options,"Authorization:"+auth_str+"\n") - conn.putheader('Authorization',auth_str) - - conn.endheaders() - - response = conn.getresponse() - - eps_log(options,"%d %s\n"%(response.status,response.reason)) - - #Response != OK -> couldn't login - if (response.status!=200): - fail(EC_LOGIN_DENIED) - - result=response.read() - eps_log(options,result+"\n") - conn.close() - - except socket.timeout: - fail(EC_TIMED_OUT) - except socket.error: - fail(EC_LOGIN_DENIED) - - return result - -def get_power_status(conn, options): - result = "" - - ret_val=eps_run_command(options,"") - - status=re.search("p"+options["-n"].lower()+"=(0|1)\s*<br>",ret_val.lower()) - if status==None: - fail_usage("Failed: You have to enter existing physical plug!") - - result=(status.group(1)=="1" and "on" or "off") - - return result - -def set_power_status(conn, options): - ret_val=eps_run_command(options,"P%s=%s"%(options["-n"],(options["-o"]=="on" and "1" or "0"))) - -# Define new option -def eps_define_new_opts(): - all_opt["hidden_page"]={ - "getopt":"c:", - "help":"-c <page> Name of hidden page (default hidden.htm)", - "order": 1} - -# Starting point of fence agent -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "test", "port", "hidden_page", "no_login", "no_password" ] - - eps_define_new_opts() - - options = check_input(device_opt,process_input(device_opt)) - - if (not options.has_key("-c")): - options["-c"]="hidden.htm" - - #Run fence action. Conn is None, beacause we always need run new curl command - fence_action(None, options, set_power_status, get_power_status) - -if __name__ == "__main__": - main() diff --git a/fence/agents/ibmblade/Makefile b/fence/agents/ibmblade/Makefile deleted file mode 100644 index 794064a..0000000 --- a/fence/agents/ibmblade/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_ibmblade.pl -TARGET= fence_ibmblade - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/ibmblade/fence_ibmblade.pl b/fence/agents/ibmblade/fence_ibmblade.pl deleted file mode 100755 index ecf8b44..0000000 --- a/fence/agents/ibmblade/fence_ibmblade.pl +++ /dev/null @@ -1,277 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use Net::SNMP; - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -my $sleep_time = 10; -my $snmp_timeout = 10; -$opt_o = "reboot"; -$opt_u = 161; - -my $oid_powerState = ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4"; # remoteControlBladePowerState -my $oid_powerChange = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7"; # powerOnOffBlade -my $oid_resetPower = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.8"; # restartBlade - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of BladeCenter\n"; - print " -h usage\n"; - print " -c <community> SNMP Community\n"; - print " -n <num> Port number to disable\n"; - print " -o <string> Action: Reboot (default), On or Off\n"; - print " -u <udpport> UDP port to use (default: 161)\n"; - print " -q quiet mode\n"; - print " -t test power state\n"; - print " -V version\n"; - - exit 0; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - elsif ($name eq "community" ) - { - $opt_c = $val; - } - - elsif ($name eq "option" ) - { - $opt_o = $val; - } - elsif ($name eq "port" ) - { - $opt_n = $val; - } - elsif ($name eq "udpport" ) - { - $opt_u = $val; - } - - # FIXME should we do more error checking? - # Excess name/vals will be eaten for now - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -# ---------------------------- MAIN -------------------------------- - -if (@ARGV > 0) { - getopts("a:hc:n:o:qu:tV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - fail_usage "No '-n' flag specified." unless defined $opt_n; - fail_usage "No '-c' flag specified." unless defined $opt_c; - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(reboot|on|off)$/i; - -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $opt_a; - fail "failed: no plug number" unless defined $opt_n; - fail "failed: no SNMP community" unless defined $opt_c; - fail "failed: unrecognised action: $opt_o" - unless $opt_o =~ /^(reboot|on|off)$/i; -} - -my ($snmpsess, $error) = Net::SNMP->session ( - -hostname => $opt_a, - -version => "snmpv1", - -port => $opt_u, - -community => $opt_c, - -timeout => $snmp_timeout); - -if (!defined ($snmpsess)) { - printf("$FENCE_RELEASE_NAME ERROR: %s.\n", $error); - exit 1; -}; - -# first check in what state are we now -my $oid = $oid_powerState . "." . $opt_n; -my $oid_val = ""; -my $result = $snmpsess->get_request ( - -varbindlist => [$oid] -); -if (!defined($result)) { - printf("$FENCE_RELEASE_NAME ERROR: %s.\n", $snmpsess->error); - $snmpsess->close; - exit 1; -} - -if (defined ($opt_t)) { - printf ("$FENCE_RELEASE_NAME STATE: Port %d on %s returned %d\n", $opt_n, $opt_a, $result->{$oid}); - exit 1; -}; - -if ($opt_o =~ /^(reboot|off)$/i) { - if ($result->{$oid} == "0") { - printf ("$FENCE_RELEASE_NAME WARNING: Port %d on %s already down.\n", $opt_n, $opt_a); - $snmpsess->close; - exit 0; - }; -} else { - if ($result->{$oid} == "1") { - printf ("$FENCE_RELEASE_NAME WARNING: Port %d on %s already up.\n", $opt_n, $opt_a); - $snmpsess->close; - exit 0; - }; -}; - -# excellent, now change the state -if ($opt_o =~ /^reboot$/i) { - # reboot - $oid = $oid_resetPower . "." . $opt_n; - $oid_val = "1"; -} elsif ($opt_o =~ /^on$/i) { - # power on - $oid = $oid_powerChange . "." . $opt_n; - $oid_val = "1"; -} else { - # power down - $oid = $oid_powerChange . "." . $opt_n; - $oid_val = "0"; -}; - -$result = $snmpsess->set_request ( - -varbindlist => [$oid, INTEGER, $oid_val] -); - -if (!defined ($result)) { - # ignore this for now, seems like IBM BladeCenter has a broken SNMPd - # it almost always timeouts -}; - -# now, wait a bit and see if we have done it -sleep($sleep_time); - -$oid = $oid_powerState . "." . $opt_n; - -undef $result; -$result = $snmpsess->get_request ( - -varbindlist => [$oid] -); - -if (!defined($result)) { - # this is a real error - printf("$FENCE_RELEASE_NAME ERROR: %s.\n", $snmpsess->error); - $snmpsess->close; - exit 1; -}; - -if ($opt_o =~ /^(off)$/i) { - if ($result->{$oid} == "1") { - printf ("$FENCE_RELEASE_NAME ERROR: Port %d on %s still up.\n", $opt_n, $opt_a); - $snmpsess->close; - exit 1; - }; -} else { - if ($result->{$oid} == "0") { - printf ("$FENCE_RELEASE_NAME ERROR: Port %d on %s still down.\n", $opt_n, $opt_a); - $snmpsess->close; - exit 1; - }; -}; - -# everything's a ok :) -$snmpsess->close; - -printf ("$FENCE_RELEASE_NAME SUCCESS: Port %d on %s changed state to %s\n", $opt_n, $opt_a, $opt_o) unless defined $opt_q; -exit 0; - diff --git a/fence/agents/ilo/Makefile b/fence/agents/ilo/Makefile deleted file mode 100644 index 794eb13..0000000 --- a/fence/agents/ilo/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_ilo.py -TARGET= fence_ilo - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_ilo: $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/ilo/fence_ilo.pl b/fence/agents/ilo/fence_ilo.pl deleted file mode 100755 index 1b5fe0a..0000000 --- a/fence/agents/ilo/fence_ilo.pl +++ /dev/null @@ -1,659 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -$|=1; - -eval { $ssl_mod="Net::SSL" if require Net::SSL} || -eval { $ssl_mod="Net::SSLeay::Handle" if require Net::SSLeay::Handle } || - die "Net::SSL.pm or Net::SSLeay::Handle.pm not found.\n". - "Please install the perl-Crypt-SSLeay package from RHN (http://rhn.redhat.com)%5Cn". - "or Net::SSLeay from CPAN (http://www.cpan.org)%5Cn"; - -use IO::Socket; -use Getopt::Std; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - - -################################################################################ -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of iLO card\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -o <string> Action: reboot (default), off, on or status\n"; - print " -p <string> Login password\n"; - print " -S <path> Script to run to retrieve login password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - print " -v verbose\n"; - exit 0; -} - - -sub fail -{ - ($msg)=@_; - print $msg unless defined $quiet; - exit 1; -} - - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - exit 0; -} - - -sub sendsock -{ - my ($sock, $msg, $junk) = @_; - - $sock->print($msg); - if ($verbose) - { - chomp $msg; - print "SEND: $msg\n" - } -} - - -# This will slurp up all the data on the socket. The SSL connection -# automatically times out after 10 seconds. If $mode is defined, the -# function will return immediately following the initial packet -# terminator "<END_RIBCL/>" or "</RIBCL>" -# RIBCL VERSION=1.2 -> <END_RIBCL/> -# RIBCL VERSION=2.0 -> </RIBCL> -sub receive_response -{ - my ($sock,$mode) = @_; - $mode = 0 unless defined $mode; - my $count=0; - - my $buf; - my $buffer = ""; - - ### sock should automatically be closed by iLO after 10 seconds - ### XXX read buf length of 256. Is this enough? Do I need to buffer? - while ($ssl_mod eq "Net::SSLeay::Handle" ? $buf=<$sock> : $sock->read($buf,256) ) - { - $rd = length($buf); - last unless ($rd); - - $buffer="$buffer$buf"; - if ($verbose) - { - chomp $buf; - print "READ:($rd,$mode) $buf\n"; - } - - # RIBCL VERSION=1.2 - last if ( $buffer =~ /<END_RIBCL/>$/mi && $mode==1 ); - - # RIBCL VERSION=2.0 - last if ( $buffer =~ /</RIBCL>$/mi && $mode==1 ); - } - - ### Determine version of RIBCL if not already defined - if (!defined $ribcl_vers) - { - if ($buffer =~ /<RIBCL VERSION="([0-9.]+)"/m) - { - $ribcl_vers=$1; - print "ribcl_vers=$ribcl_vers\n" if ($verbose); - } - else - { - fail "unable to detect RIBCL version\n"; - } - } - - return $buffer; -} - - -sub open_socket -{ - print "opening connection to $hostname:$port\n" if $verbose; - - if ($ssl_mod eq "Net::SSLeay::Handle") - { - # neat little trick I found in the man page for Net::SSLeay::Handle - tie (*SSL,"Net::SSLeay::Handle",$hostname,$port) - or fail "unable to connect to $hostname:$port $@\n"; - $ssl = *SSL; - } - else - { - $ssl = Net::SSL->new( PeerAddr => $hostname, - PeerPort => $port ); - $ssl->configure(); - $ssl->connect($port,inet_aton($hostname)) or - fail "unable to connect to $hostname:$port $@\n"; - } - return $ssl; -} - - -sub close_socket -{ - my ($sock, $junk) = @_; - #shutdown ($sock,1); - close $sock; -} - - -# power_off() -- power off the node -# return 0 on success, non-zero on failure -sub power_off -{ - my $response = set_power_state ("N"); - my @response = split /\n/,$response; - my $no_err=0; - my $agent_status = -1; - - foreach my $line (@response) - { - if ($line =~ /MESSAGE='(.*)'/) - { - my $msg = $1; - if ($msg eq "No error") - { - $no_err++; - next; - } - elsif ($msg eq "Host power is already OFF.") - { - $agent_status = 0; - print "warning: $msg\n" unless defined $quiet; - } - else - { - $agent_status = 1; - print STDERR "error: $msg\n"; - } - } - } - - # There should be about 6 or more response packets on a successful - # power off command. - if ($agent_status<0) - { - $agent_status = ($no_err<5) ? 1 : 0; - } - - return $agent_status; -} - - -# power_on() -- power on the node -# return 0 on success, non-zero on failure -sub power_on -{ - my $response = set_power_state ("Y"); - my @response = split /\n/,$response; - my $no_err=0; - my $agent_status = -1; - - foreach my $line (@response) - { - if ($line =~ /MESSAGE='(.*)'/) - { - my $msg = $1; - if ($msg eq "No error") - { - $no_err++; - next; - } - elsif ($msg eq "Host power is already ON.") - { - $agent_status = 0; - print "warning: $msg\n" unless defined $quiet; - } - else - { - $agent_status = 1; - print STDERR "error: $msg\n"; - } - } - } - - # There should be about 6 or more response packets on a successful - # power on command. - if ($agent_status<0) - { - $agent_status = ($no_err<5) ? 1 : 0; - } - - return $agent_status; -} - -# power_status() -- print the power status of the node -# return 0 on success, non-zero on failure -# set $? to power status from ilo ("ON" or "OFF") -sub power_status -{ - my $response = get_power_state (); - my @response = split /\n/,$response; - my $agent_status = -1; - my $power_status = "UNKNOWN"; - - foreach my $line (@response) - { - if ($line =~ /FIRMWARE_VERSION\s*=\s*"(.*)"/) { - $firmware_rev = $1; - } - if ($line =~ /MANAGEMENT_PROCESSOR\s*=\s*"(.*)"/) { - if ($1 eq "iLO2") { - $ilo_vers = 2; - print "power_status: reporting iLO2 $firmware_rev\n" if ($verbose); - } - } - - if ($line =~ /MESSAGE='(.*)'/) - { - my $msg = $1; - if ($msg eq "No error") - { - next; - } - else - { - $agent_status = 1; - print STDERR "error: $msg\n"; - } - } - # RIBCL VERSION=1.2 - elsif ($line =~ /HOST POWER="(.*)"/) - { - $agent_status = 0; - $power_status = $1; - } - - # RIBCL VERSION=2.0 - elsif ($line =~ /HOST_POWER="(.*)"/) - { - $agent_status = 0; - $power_status = $1; - } - - } - $_ = $power_status; - print "power_status: reporting power is $_\n" if ($verbose); - return $agent_status; -} - -sub set_power_state -{ - my $state = shift; - my $response = ""; - - if (!defined $state || ( $state ne "Y" && $state ne "N") ) - { - fail "illegal state\n"; - } - - $socket = open_socket; - - sendsock $socket, "<?xml version=\"1.0\"?>\r\n"; - $response = receive_response($socket,1); - - print "Sending power-o".(($state eq "Y")?"n":"ff")."\n" if ($verbose); - - if ($ribcl_vers < 2 ) - { - sendsock $socket, "<RIBCL VERSION="1.2">\n"; - } - else - { - # It seems the firmware can't handle the <LOCFG> tag - # RIBCL VERSION=2.0 - #> sendsock $socket, "<LOCFG VERSION="2.21">\n"; - sendsock $socket, "<RIBCL VERSION="2.0">\n"; - } - sendsock $socket, "<LOGIN USER_LOGIN = "$username" PASSWORD = "$passwd">\n"; - sendsock $socket, "<SERVER_INFO MODE = "write">\n"; - - if ($ilo_vers == 2) { - # iLO2 with RIBCL v2.22 behaves differently from - # iLO with RIBCL v2.22. For the former, HOLD_PWR_BTN is - # used to both power the machine on and off; when the power - # is off, PRESS_PWR_BUTTON has no effect. For the latter, - # HOLD_PWR_BUTTON is used to power the machine off, and - # PRESS_PWR_BUTTON is used to power the machine on; - # when the power is off, HOLD_PWR_BUTTON has no effect. - if ($firmware_rev > 1.29) { - sendsock $socket, "<HOLD_PWR_BTN TOGGLE="Yes" />\n"; - } else { - sendsock $socket, "<HOLD_PWR_BTN/>\n"; - } - } - # As of firmware version 1.71 (RIBCL 2.21) The SET_HOST_POWER command - # is no longer available. HOLD_PWR_BTN and PRESS_PWR_BTN are used - # instead now :( - elsif ($ribcl_vers < 2.21) - { - sendsock $socket, "<SET_HOST_POWER HOST_POWER = "$state"/>\n"; - } - else - { - if ($state eq "Y" ) - { - sendsock $socket, "<PRESS_PWR_BTN/>\n"; - } - else - { - sendsock $socket, "<HOLD_PWR_BTN/>\n"; - } - } - - sendsock $socket, "</SERVER_INFO>\n"; - sendsock $socket, "</LOGIN>\n"; - sendsock $socket, "</RIBCL>\n"; - - # It seems the firmware can't handle the <LOCFG> tag - # RIBCL VERSION=2.0 - #> sendsock $socket, "</LOCFG>\n" if ($ribcl_vers >= 2) ; - - $response = receive_response($socket); - - print "Closing connection\n" if ($verbose); - close_socket($socket); - - return $response; -} - -sub get_power_state -{ - my $response = ""; - - $socket = open_socket; - - sendsock $socket, "<?xml version=\"1.0\"?>\r\n"; - $response = receive_response($socket,1); - - print "Sending get-status\n" if ($verbose); - - if ($ribcl_vers < 2 ) - { - sendsock $socket, "<RIBCL VERSION="1.2">\n"; - } - else - { - # It seems the firmware can't handle the <LOCFG> tag - # RIBCL VERSION=2.0 - #> sendsock $socket, "<LOCFG VERSION="2.21">\n"; - sendsock $socket, "<RIBCL VERSION="2.0">\n"; - } - sendsock $socket, "<LOGIN USER_LOGIN = "$username" PASSWORD = "$passwd">\n"; - if ($ribcl_vers >= 2) { - sendsock $socket, "<RIB_INFO MODE="read"><GET_FW_VERSION/></RIB_INFO>\n"; - } - sendsock $socket, "<SERVER_INFO MODE = "read">\n"; - sendsock $socket, "<GET_HOST_POWER_STATUS/>\n"; - sendsock $socket, "</SERVER_INFO>\n"; - sendsock $socket, "</LOGIN>\n"; - sendsock $socket, "</RIBCL>\n"; - - # It seems the firmware can't handle the <LOCFG> tag - # RIBCL VERSION=2.0 - #> sendsock $socket, "</LOCFG>\r\n" if ($ribcl_vers >= 2) ; - - $response = receive_response($socket); - - print "Closing connection\n" if ($verbose); - close_socket($socket); - - return $response; -} - - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - elsif ($name eq "action" || $name eq "option") - { - $action = $val; - } - - # DO NOTHING -- this field is used by fenced or stomithd - elsif ($name eq "agent" ) { } - - elsif ($name eq "hostname" ) - { - $hostname = $val; - } - elsif ($name eq "login" ) - { - $username = $val; - } - elsif ($name eq "passwd" ) - { - $passwd = $val; - } - elsif ($name eq "passwd_script" ) - { - $passwd_script = $val; - } - elsif ($name eq "ribcl" ) - { - $ribcl_vers = $val; - } - elsif ($name eq "verbose" ) - { - $verbose = $val; - } - - else - { - fail "parse error: unknown option "$opt"\n"; - } - } -} - -################################################################################ -# MAIN - -$action = "reboot"; -$ribcl_vers = undef; # undef = autodetect -$ilo_vers = 1; -$firmware_rev = 0; - -if (@ARGV > 0) { - getopts("a:hl:n:o:p:S:r:qvV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - $hostname = $opt_a; - - fail_usage "No '-l' flag specified." unless defined $opt_l; - $username = $opt_l; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - $passwd = $opt_p; - - $action = $opt_o if defined $opt_o; - fail_usage "Unrecognised action '$action' for '-o' flag" - unless $action=~ /^(off|on|reboot|status)$/; - - $localport = $opt_n if defined $opt_n; - - $quiet = 1 if defined $opt_q; - - $verbose = 1 if defined $opt_v; - - $ribcl_vers = $opt_r if defined $opt_r; - -} else { - get_options_stdin(); - - fail "no host\n" unless defined $hostname; - fail "no login name\n" unless defined $username; - - if (defined $passwd_script) { - $pwd_script_out = `$passwd_script`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $passwd = $pwd_script_out; - } - } - - fail "no password\n" unless defined $passwd; - - fail "unrecognised action: $action\n" - unless $action=~ /^(off|on|reboot|status)$/; -} - -# Parse user specified port from apaddr parameter -($hostname_tmp,$port,$junk) = split(/:/,$hostname); -fail "bad hostname/ipaddr format: $hostname\n" if defined $junk; -$hostname = $hostname_tmp; -$port = 443 unless defined $port; - -print "ssl module: $ssl_mod\n" if $verbose; - - -$_=$action; -if (/on/) -{ - fail "power_status: unexpected error\n" if power_status; - - if (! /^on$/i) - { - fail "power_on: unexpected error\n" if power_on; - fail "power_status: unexpected error\n" if power_status; - fail "failed to turn on\n" unless (/^on$/i); - } - else - { - print "power is already on\n" unless defined $quiet; - } -} -elsif (/off/) -{ - fail "power_status: unexpected error\n" if power_status; - - if (! /^off$/i) - { - fail "power_off: unexpected error\n" if power_off; - fail "power_status: unexpected error\n" if power_status; - fail "failed to turn off\n" unless (/^off$/i); - } - else - { - print "power is already off\n" unless defined $quiet; - } -} -elsif (/reboot/) -{ - fail "power_status: unexpected error\n" if power_status; - - if (! /^off$/i) - { - fail "power_off: unexpected error\n" if power_off; - fail "power_status: unexpected error\n" if power_status; - fail "failed to turn off\n" unless (/^off$/i); - } - - if (/^off$/i) - { - fail "power_on: unexpected error\n" if power_on; - fail "power_status: unexpected error\n" if power_status; - fail "failed to turn on\n" unless (/^on$/i); - } - else - { - fail "unexpected power state: '$_'\n"; - } -} -elsif (/status/) -{ - fail "power_status: unexpected error\n" if power_status; - print "power is $_\n"; -} -else -{ - fail "illegal action: '$_'\n"; -} - -print "success\n" unless defined $quiet; -exit 0 - -################################################################################ diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py deleted file mode 100755 index f1719b0..0000000 --- a/fence/agents/ilo/fence_ilo.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -## The Following Agent Has Been Tested On: -## -## iLO Version -## +---------------------------------------------+ -## iLO / firmware 1.91 / RIBCL 2.22 -## iLO2 / firmware 1.22 / RIBCL 2.22 -## iLO2 / firmware 1.50 / RIBCL 2.22 -##### - -import sys, re, pexpect, socket -sys.path.append("/usr/lib/fence") -from fencing import * -from OpenSSL import SSL - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - conn.send("<LOGIN USER_LOGIN = "" + options["-l"] + """ + \ - " PASSWORD = "" + options["-p"] + "">\r\n") - conn.send("<SERVER_INFO MODE = "read"><GET_HOST_POWER_STATUS/>\r\n") - conn.send("</SERVER_INFO></LOGIN>\r\n") - try: - conn.log_expect(options, "HOST_POWER="(.*?)"", POWER_TIMEOUT) - except pexpect.EOF, e: - fail(EC_STATUS) - except pexpect.TIMEOUT, e: - fail(EC_TIMED_OUT) - - status = conn.match.group(1) - return status.lower().strip() - -def set_power_status(conn, options): - conn.send("<LOGIN USER_LOGIN = "" + options["-l"] + """ + \ - " PASSWORD = "" + options["-p"] + "">\r\n") - conn.send("<SERVER_INFO MODE = "write">") - - if options.has_key("fw_processor") and options["fw_processor"] == "iLO2": - if options["fw_version"] > 1.29: - conn.send("<HOLD_PWR_BTN TOGGLE="yes" />\r\n") - else: - conn.send("<HOLD_PWR_BTN />\r\n") - elif options["-r"] < 2.21: - conn.send("<SET_HOST_POWER HOST_POWER = "" + options["-o"] + "" />\r\n") - else: - if options["-o"] == "off": - conn.send("<HOLD_PWR_BTN/>\r\n") - else: - conn.send("<PRESS_PWR_BTN/>\r\n") - conn.send("</SERVER_INFO></LOGIN>\r\n") - - return - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "ssl", "ribcl", "power_wait" ] - - options = check_input(device_opt, process_input(device_opt)) - - options["-z"] = 1 - LOGIN_TIMEOUT = 10 - - ## - ## Login and get version number - #### - conn = fence_login(options) - try: - conn.send("<?xml version=\"1.0\"?>\r\n") - conn.log_expect(options, [ "</RIBCL>", "<END_RIBCL/>" ], LOGIN_TIMEOUT) - version = re.compile("<RIBCL VERSION="(.*?)"", re.IGNORECASE).search(conn.before).group(1) - if options.has_key("-r") == 0: - options["-r"] = float(version) - - if options["-r"] >= 2: - conn.send("<RIBCL VERSION="2.0">\r\n") - else: - conn.send("<RIBCL VERSION="1.2">\r\n") - - conn.send("<LOGIN USER_LOGIN = "" + options["-l"] + """ + \ - " PASSWORD = "" + options["-p"] + "">\r\n") - if options["-r"] >= 2: - conn.send("<RIB_INFO MODE="read"><GET_FW_VERSION />\r\n") - conn.send("</RIB_INFO>\r\n") - conn.log_expect(options, "<GET_FW_VERSION\s*\n", SHELL_TIMEOUT) - conn.log_expect(options, "/>", SHELL_TIMEOUT) - options["fw_version"] = float(re.compile("FIRMWARE_VERSION\s*=\s*"(.*?)"", re.IGNORECASE).search(conn.before).group(1)) - options["fw_processor"] = re.compile("MANAGEMENT_PROCESSOR\s*=\s*"(.*?)"", re.IGNORECASE).search(conn.before).group(1) - conn.send("</LOGIN>\r\n") - except pexpect.TIMEOUT: - fail(EC_LOGIN_DENIED) - except pexpect.EOF: - fail(EC_LOGIN_DENIED) - - ## - ## Fence operations - #### - fence_action(conn, options, set_power_status, get_power_status) - -if __name__ == "__main__": - main() diff --git a/fence/agents/ipmilan/Makefile b/fence/agents/ipmilan/Makefile deleted file mode 100644 index 937d808..0000000 --- a/fence/agents/ipmilan/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= fence_ipmilan - -fence_ipmilan_SOURCE= expect.c ipmilan.c - -top_srcdir=../.. - - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -DFENCE_RELEASE_NAME="${RELEASE}" -DFENCE - -all: ${TARGET} - -fence_ipmilan: ${fence_ipmilan_SOURCE:.c=.o} - ${CC} ${CFLAGS} ${LDFLAGS} ${fence_ipmilan_SOURCE:.c=.o} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/fence/agents/ipmilan/expect.c b/fence/agents/ipmilan/expect.c deleted file mode 100644 index 26b0ff6..0000000 --- a/fence/agents/ipmilan/expect.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * - * Copyright (c) 2000 Alan Robertson alanr@unix.sh - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -/** @file - * Simple expect module for the STONITH library. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <libintl.h> -#include <sys/wait.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <time.h> -#include <sys/time.h> -#include <sys/times.h> -#ifdef _POSIX_PRIORITY_SCHEDULING -# include <sched.h> -#endif - -#include "expect.h" - -#ifndef EOS -# define EOS '\0' -#endif - - -/* - * Just incase we are on an out of date system - */ -#ifndef CLOCKS_PER_SEC -# ifndef CLK_TCK -# error Neither CLOCKS_PER_SEC nor CLK_TCK (obsolete) are defined -# endif /* CLK_TCK */ -# define CLOCKS_PER_SEC CLK_TCK -#endif /* CLOCKS_PER_SEC */ - - -void close_all_files (void); - -/** - * Look for ('expect') any of a series of tokens in the input - * Return the token type for the given token or -1 on error. - * - * @param fd The file descriptor to watch. - * @param toklist The series of tokens to look for. - * @param to_secs Timeout (in seconds). - * @param buf Receive buffer (preallocated). - * @param maxline Length of receive buffer. - */ -int -ExpectToken(int fd, struct Etoken * toklist, int to_secs, char * buf -, int maxline) -{ - clock_t starttime; - clock_t endtime; - int wraparound=0; - int tickstousec = (1000000/CLOCKS_PER_SEC); - clock_t now; - clock_t ticks; - int nchars = 1; /* reserve space for an EOS */ - struct timeval tv; - - struct Etoken * this; - - /* Figure out when to give up. Handle lbolt wraparound */ - if (fd < 0) { - errno = EINVAL; - return -1; - } - - starttime = times(NULL); - ticks = (to_secs*CLOCKS_PER_SEC); - endtime = starttime + ticks; - - if (endtime < starttime) { - wraparound = 1; - } - - if (buf) { - *buf = EOS; - } - - for (this=toklist; this->string; ++this) { - this->matchto = 0; - } - - - while (now = times(NULL), - (wraparound && (now > starttime || now <= endtime)) - || (!wraparound && now <= endtime)) { - - fd_set infds; - char ch; - clock_t timeleft; - int retval; - - timeleft = endtime - now; - - tv.tv_sec = timeleft / CLOCKS_PER_SEC; - tv.tv_usec = (timeleft % CLOCKS_PER_SEC) * tickstousec; - - if (tv.tv_sec == 0 && tv.tv_usec < tickstousec) { - /* Give 'em a little chance */ - tv.tv_usec = tickstousec; - } - - /* Watch our FD to see when it has input. */ - FD_ZERO(&infds); - FD_SET(fd, &infds); - - retval = select(fd+1, &infds, NULL, NULL, &tv); - if (retval <= 0) { - errno = ETIMEDOUT; - return(-1); - } - /* Whew! All that work just to read one character! */ - - if (read(fd, &ch, sizeof(ch)) <= 0) { - return(-1); - } - /* Save the text, if we can */ - if (buf && nchars < maxline-1) { - *buf = ch; - ++buf; - *buf = EOS; - ++nchars; - } -#if 0 - fprintf(stderr, "%c", ch); -#endif - - /* See how this character matches our expect strings */ - - for (this=toklist; this->string; ++this) { - - if (ch == this->string[this->matchto]) { - - /* It matches the current token */ - - ++this->matchto; - if (this->string[this->matchto] == EOS){ - /* Hallelujah! We matched */ - return(this->toktype); - } - }else{ - - /* It doesn't appear to match this token */ - - int curlen; - int nomatch=1; - /* - * If we already had a match (matchto is - * greater than zero), we look for a match - * of the tail of the pattern matched so far - * (with the current character) against the - * head of the pattern. - */ - - /* - * This is to make the string "aab" match - * the pattern "ab" correctly - * Painful, but nice to do it right. - */ - - for (curlen = (this->matchto) - ; nomatch && curlen >= 0 - ; --curlen) { - const char * tail; - tail=(this->string) - + this->matchto - - curlen; - - if (strncmp(this->string, tail - , curlen) == 0 - && this->string[curlen] == ch) { - - if (this->string[curlen+1]==EOS){ - /* We matched! */ - /* (can't happen?) */ - return(this->toktype); - } - this->matchto = curlen+1; - nomatch=0; - } - } - if (nomatch) { - this->matchto = 0; - } - } - } - } - errno = ETIMEDOUT; - return(-1); -} - -/** - * Start a process with its stdin and stdout redirected to pipes - * so the parent process can talk to it. - * - * @param cmd Command line to run. - * @param readfd Filled with a pipe to the the output of the - * new child. - * @param writefd Filled with a pipe to the input of the new - * child. - * @param redir_err 0, 1 = stderr, 2 = setsid, 3 = both - * @return -1 on failure (with errno set appropriately) or - * or the PID of the new child process. - */ -int -StartProcess(const char * cmd, int * readfd, int * writefd, int flags) -{ - pid_t pid; - int wrpipe[2]; /* The pipe the parent process writes to */ - /* (which the child process reads from) */ - int rdpipe[2]; /* The pipe the parent process reads from */ - /* (which the child process writes to) */ - - if (pipe(wrpipe) < 0) { - perror("cannot create pipe\n"); - return(-1); - } - if (pipe(rdpipe) < 0) { - perror("cannot create pipe\n"); - close(wrpipe[0]); - close(wrpipe[1]); - return(-1); - } - switch(pid=fork()) { - case -1: - perror("cannot StartProcess cmd"); - close(rdpipe[0]); - close(rdpipe[1]); - close(wrpipe[0]); - close(wrpipe[1]); - return(-1); - - case 0: - /* We are the child */ - /* Redirect stdin */ - if (wrpipe[0] != 0) { - close(0); - if(dup2(wrpipe[0], 0) < 0) { - syslog(LOG_CRIT, - "StartProcess: dup2(%d,0) failed: %s\n", - wrpipe[0], - strerror(errno)); - exit(1); - } - close(wrpipe[0]); - } - close(wrpipe[1]); - - /* Redirect stdout */ - if (rdpipe[1] != 1) { - close(1); - if(dup2(rdpipe[1], 1) < 0) { - syslog(LOG_CRIT, - "StartProcess: dup2(%d,1) failed: %s\n", - rdpipe[1], - strerror(errno)); - exit(1); - } - close(rdpipe[1]); - } - close(rdpipe[0]); - - if (flags & EXP_STDERR) { - /* Redirect stderr */ - close(2); - if(dup2(1, 2) < 0) { - syslog(LOG_CRIT, - "StartProcess: dup2(1,2) failed: %s\n", - strerror(errno)); - exit(1); - } - } - - if (flags & EXP_NOCTTY) - setsid(); - close_all_files(); /* Workaround telnet bugs */ -#if defined(SCHED_OTHER) - { - /* - * Try and (re)set our scheduling to "normal" - * Sometimes our callers run in soft - * real-time mode. The program we exec might - * not be very well behaved - this is bad for - * operation in high-priority (soft real-time) - * mode. In particular, telnet is prone to - * going into infinite loops when killed. - */ - struct sched_param sp; - memset(&sp, 0, sizeof(sp)); - sp.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &sp); - } -#endif - execlp("/bin/sh", "sh", "-c", cmd, NULL); - perror("cannot exec shell!"); - exit(1); - - default: /* We are the parent */ - *readfd = rdpipe[0]; - close(rdpipe[1]); - *writefd = wrpipe[1]; - close(wrpipe[0]); - return(pid); - } - /*NOTREACHED*/ - return(-1); -} - -/** - * Close all file descriptors in a child process. - * - * Open fd's are inherited across exec unless they are - * marked close on exec, which must be done explicitly - * with fcntl(). While this should not affect the operation of - * telnet, it was found that in some cases it did. Its easier to - * just fix it this way than to fix telnet. - */ -void -close_all_files (void) -{ - register int i, fd_table_size; - - fd_table_size = getdtablesize (); - if (fd_table_size > 256)/* clamp to a reasonable value */ - fd_table_size = 256; - - for (i = 3; i < fd_table_size; i++) - close (i); -} diff --git a/fence/agents/ipmilan/expect.h b/fence/agents/ipmilan/expect.h deleted file mode 100644 index 4bcd643..0000000 --- a/fence/agents/ipmilan/expect.h +++ /dev/null @@ -1,68 +0,0 @@ -/** @file - * Header for expect.c. - * - * Expect simple tokens. Simple expect infrastructure for STONITH API - * - * Copyright (c) 2000 Alan Robertson alanr@unix.sh - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __EXPECT_H -# define __EXPECT_H -/* - * If we find any of the given tokens in the input stream, - * we return it's "toktype", so we can tell which one was - * found. - * - */ - -/** - * A token we pass to ExpectToken() - */ -struct Etoken { - const char * string; /**< The token to look for */ - int toktype; /**< The type to return on match */ - int matchto; /**< Modified during matches */ -}; - -int ExpectToken(int fd -, struct Etoken * toklist /* List of tokens to match against */ - /* Final token has NULL string */ -, int to_secs /* Timeout value in seconds */ -, char * buf /* If non-NULL, then all the text - * matched/skipped over by this match */ -, int maxline); /* Size of 'buf' area in bytes */ - - -/* - * A handy little routine. It runs the given process - * with it's standard output redirected into our *readfd, and - * its standard input redirected from our *writefd - * - * Doing this with all the pipes, etc. required for doing this - * is harder than it sounds :-) - */ - -int StartProcess(const char * cmd, int* readfd, int* writefd, int redir_err); - -#define EXP_STDERR 1 -#define EXP_NOCTTY 2 - -#ifndef EOS -# define EOS '\0' -#endif -#endif /*__EXPECT_H*/ diff --git a/fence/agents/ipmilan/ipmilan.c b/fence/agents/ipmilan/ipmilan.c deleted file mode 100644 index a4c91d2..0000000 --- a/fence/agents/ipmilan/ipmilan.c +++ /dev/null @@ -1,1237 +0,0 @@ -/** @file - * clumanager 1.2.x STONITH and/or linux-cluster fence and/or GFS fence - * module for Intel/Bull/Dell Tiger4 machines via IPMI over lan. - * (Probably works with anything ipmitool can control, though.) - * - * Note: REQUIRES ipmitool to operate. On certain machines, the hardware - * manufacturer provides this tool for you. Otherwise, check: - * - * http://ipmitool.sourceforge.net - * - * Copyright 2005-2007 Red Hat, Inc. - * author: Lon Hohberger <lhh at redhat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <libintl.h> - -#ifndef FENCE -#include <syslog.h> -#include "stonith.h" -#define log(lvl, fmt, args...) \ -do { \ - syslog(lvl, fmt, ##args); \ - fprintf(stderr, "%s: " fmt, #lvl, ##args); \ -} while(0) -#else -/* fenced doesn't use the remote calls */ -#define ST_STATUS 0 -#define ST_POWERON 1 -#define ST_POWEROFF 2 -#define ST_GENERIC_RESET 3 -#define ST_CYCLE 4 - -#define DEFAULT_TIMEOUT 10 - -#define DEFAULT_METHOD "onoff" - -#define log(lvl, fmt, args...) fprintf(stderr, fmt, ##args) -#include <libgen.h> - -#ifndef TESTING -#include <copyright.cf> -#else -#define REDHAT_COPYRIGHT "Copyright (C) 2005 Red Hat, Inc.\n" -#define FENCE_RELEASE_NAME "TEST ONLY; Not for distribution\n" - -#endif -#endif - -#include "expect.h" - -#define IPMIID "IPMI over LAN driver" -#define NOTIPMI "Destroyed IPMI over LAN driver" - - -#define dbg_printf(i, lvl, fmt, args...) \ -do { \ - if ( (i)->i_verbose >= lvl) { \ - printf(fmt, ##args); \ - fflush(stdout); \ - } \ -} while (0) - - - -struct ipmi { - char *i_id; - const char *i_ipmitool; - char *i_host; - char *i_user; - char *i_authtype; - char *i_password; - int i_rdfd; - int i_wrfd; - pid_t i_pid; - int i_config; - int i_verbose; - int i_lanplus; - int i_timeout; -}; - - -/* - Supported installation paths - */ -const char *ipmitool_paths[] = { - "/usr/local/bull/NSMasterHW/bin/ipmitool", - "/usr/bin/ipmitool", - "/usr/sbin/ipmitool", - "/bin/ipmitool", - "/sbin/ipmitool", - "/usr/local/bin/ipmitool", - "/usr/local/sbin/ipmitool", - NULL -}; - -#define ESTATE (8192*2) -static struct Etoken power_on_complete[] = { - {"Password:", EPERM, 0}, - {"Unable to establish LAN", EAGAIN, 0}, /* Retry */ - {"IPMI mutex", EFAULT, 0}, /* Death */ - {"Up/On", 0, 0}, - {NULL, 0, 0} -}; - -static struct Etoken power_off_complete[] = { - {"Password:", EPERM, 0}, - {"Unable to establish LAN", EAGAIN, 0}, /* Retry */ - {"IPMI mutex", EFAULT, 0}, /* Death */ - {"Down/Off", 0, 0}, - {NULL, 0, 0} -}; - -/** Powercycle operation */ -static struct Etoken power_cycle_complete[] = { - {"Password:", EPERM, 0}, - {"Unable to establish LAN", EAGAIN, 0}, /* Retry */ - {"IPMI mutex", EFAULT, 0}, /* Death */ -// {"Unsupported cipher suite ID", ECIPHER,0}, -// {"read_rakp2_message: no support for", ECIPHER,0}, - {"Command not supported in present state", ESTATE, 0}, - {": Cycle", 0, 0}, - {NULL, 0, 0} -}; - -#define STATE_OFF 4096 -#define STATE_ON 8192 -static struct Etoken power_status[] = { - {"Password:", EPERM, 0}, - {"Unable to establish LAN", EAGAIN, 0}, /* Retry */ - {"IPMI mutex", EFAULT, 0}, /* Death */ - {"Chassis Power is off", STATE_OFF, 0}, - {"Chassis Power is on", STATE_ON, 0}, - {NULL, 0, 0} -}; - - -/* - Search for ipmitool - */ -static const char * -ipmitool_path(void) -{ - char *p; - int x = 0; - struct stat sb; - - for (x = 0; ipmitool_paths[x]; x++) { - p = (char *)ipmitool_paths[x]; - if (stat(p, &sb) != 0) - continue; - - if (!S_ISREG(sb.st_mode)) - continue; - - /* executable? */ - if ((sb.st_mode & S_IXUSR) == 0) - continue; - - return (const char *)p; - } - - return NULL; -} - - -/** Prepare string for use in sh style environment. This function take source - string and prepend/append quote (') to start/end of source string to dest - string. Any occurence of quote in source string is replaced by ''' sequence. - Dest string must be preallocated. - - @param dest Destination string - @param source Source string - @param max_len Maximum length of data written to dest string (including end 0) - @return Pointer to start of destination string. -*/ -char *str_prepare_for_sh(char *dest,char *source,int max_len) { - char *dest_p=dest; - char *max_dest=dest+max_len; - - if (dest_p+1>=max_dest) {*dest_p=0;return dest;} - *dest_p++='''; - - while (*source) { - if (*source==''') { - if (dest_p+4>=max_dest) {*dest_p=0;return dest;} - - memcpy(dest_p,"'\''",4);dest_p+=4; - } else { - if (dest_p+1>=max_dest) {*dest_p=0;return dest;} - - *dest_p++=*source; - } - source++; - } - - if (dest_p+2>=max_dest) {*dest_p=0;return dest;} - - *dest_p++=''';*dest_p=0; - - return dest; -} - -static int -build_cmd(char *command, size_t cmdlen, struct ipmi *ipmi, int op) -{ - char cmd[2048]; - char arg[2048]; - char tmp[2048]; - int x; - - /* Store path */ - if (ipmi->i_lanplus) { - snprintf(cmd, sizeof(cmd), "%s -I lanplus -H %s", - ipmi->i_ipmitool, - str_prepare_for_sh(tmp,ipmi->i_host,sizeof(tmp))); - } else { - snprintf(cmd, sizeof(cmd), "%s -I lan -H %s", ipmi->i_ipmitool, - str_prepare_for_sh(tmp,ipmi->i_host,sizeof(tmp))); - } - - if (ipmi->i_user) { - snprintf(arg, sizeof(arg), " -U %s", str_prepare_for_sh(tmp,ipmi->i_user,sizeof(tmp))); - strncat(cmd, arg, sizeof(cmd) - strlen(arg)); - } - - if (ipmi->i_authtype) { - snprintf(arg, sizeof(arg), " -A %s", str_prepare_for_sh(tmp,ipmi->i_authtype,sizeof(tmp))); - strncat(cmd, arg, sizeof(cmd) - strlen(arg)); - } - - if (ipmi->i_password) { - snprintf(arg, sizeof(arg), " -P %s", str_prepare_for_sh(tmp,ipmi->i_password,sizeof(tmp))); - strncat(cmd, arg, sizeof(cmd) - strlen(arg)); - } else { - snprintf(arg, sizeof(arg), " -P ''"); - strncat(cmd, arg, sizeof(cmd) - strlen(arg)); - } - - /* Tack on the -v flags for ipmitool; in most cases, i_verbose - will be 0 */ - for (x = 0; x < ipmi->i_verbose; x++) { - snprintf(arg, sizeof(arg), " -v"); - strncat(cmd, arg, sizeof(cmd) - strlen(arg)); - } - - switch(op) { - case ST_POWERON: - snprintf(arg, sizeof(arg), - "%s chassis power on", cmd); - break; - case ST_POWEROFF: - snprintf(arg, sizeof(arg), - "%s chassis power off", cmd); - break; - case ST_STATUS: - snprintf(arg, sizeof(arg), - "%s chassis power status", cmd); - break; - case ST_CYCLE: - snprintf(arg, sizeof(arg), - "%s chassis power cycle", cmd); - break; - } - - strncpy(command, arg, cmdlen); - return 0; -} - - -static int -ipmi_spawn(struct ipmi *ipmi, const char *cmd) -{ - dbg_printf(ipmi, 1, "Spawning: '%s'...\n", cmd); - if (!ipmi) { - errno = EINVAL; - return -1; - } - - if (ipmi->i_pid != -1) { - dbg_printf(ipmi, 1, "Can't spawn: PID %d running\n", - (int)ipmi->i_pid); - errno = EINPROGRESS; - return -1; - } - - if ((ipmi->i_pid = StartProcess(cmd, &ipmi->i_rdfd, - &ipmi->i_wrfd, - EXP_STDERR|EXP_NOCTTY)) >= 0) { - dbg_printf(ipmi, 2, "Spawned: '%s' - PID %d\n", cmd, - (int)ipmi->i_pid); - return 0; - } - return -1; -} - - -static int -ipmi_reap(struct ipmi *ipmi) -{ - if (ipmi->i_pid >= 0) { - dbg_printf(ipmi, 2, "Reaping pid %d\n", ipmi->i_pid); - kill(ipmi->i_pid, 9); - waitpid(ipmi->i_pid, NULL, 0); - } - ipmi->i_pid = -1; - if (ipmi->i_rdfd >= 0) { - close(ipmi->i_rdfd); - ipmi->i_rdfd = -1; - } - if (ipmi->i_wrfd >= 0) { - close(ipmi->i_wrfd); - ipmi->i_wrfd = -1; - } - return 0; -} - - -static int -ipmi_expect(struct ipmi *ipmi, struct Etoken *toklist, int timeout) -{ - int ret; - char buf[32768]; /* XX hope this is enough */ - - dbg_printf(ipmi, 3, "Looking for: \n"); - for (ret = 0; toklist[ret].string; ret++) { - dbg_printf(ipmi, 3, " '%s', val = %d\n", - toklist[ret].string, - toklist[ret].toktype); - } - - ret = ExpectToken(ipmi->i_rdfd, toklist, timeout, buf, sizeof(buf)); - dbg_printf(ipmi, 3, "ExpectToken returned %d\n", ret); - if (ret == -1) { - ret = errno; - dbg_printf(ipmi, 3, "ExpectToken failed. Info returned:\n"); - dbg_printf(ipmi, 3, ">>>>>\n%s\n<<<<<\nError = %d (%s)\n", - buf, - ret, - strerror(ret)); - } - - return ret; -} - - -static int -ipmi_op(struct ipmi *ipmi, int op, struct Etoken *toklist) -{ - char cmd[2048]; - int ret; - - build_cmd(cmd, sizeof(cmd), ipmi, op); - - if (ipmi_spawn(ipmi, cmd) != 0) - return -1; - ret = ipmi_expect(ipmi, toklist, ipmi->i_timeout); - ipmi_reap(ipmi); - - if (ret == EFAULT) { - log(LOG_CRIT, "ipmilan: ipmitool failed to create " - "mutex; unable to complete operation\n"); - return ret; - } - - if (ret == ESTATE) { - log(LOG_CRIT, "ipmilan: ipmitool failed to complete " - "command in current state\n"); - return ret; - } - - if (ret == ETIMEDOUT) { - /*!!! Still couldn't get through?! */ - log(LOG_WARNING, - "ipmilan: Failed to connect after %d seconds\n",ipmi->i_timeout); - } - - return ret; -} - - -static int -ipmi_off(struct ipmi *ipmi) -{ - int ret, retries = 7; - - ret = ipmi_op(ipmi, ST_STATUS, power_status); - switch(ret) { - case STATE_ON: - break; - case STATE_OFF: - return 0; - default: - return ret; - } - - while (retries>=0) { - ret = ipmi_op(ipmi, ST_POWEROFF, power_off_complete); - if (ret != 0) - return ret; - - sleep(2); - --retries; - ret = ipmi_op(ipmi, ST_STATUS, power_status); - - switch(ret) { - case STATE_OFF: - return 0; - case EFAULT: - /* We're done. */ - retries = 0; - break; - case STATE_ON: - default: - continue; - } - } - log(LOG_WARNING, "ipmilan: Power still on\n"); - - return ret; -} - - -static int -ipmi_on(struct ipmi *ipmi) -{ - int ret, retries = 7; - - ret = ipmi_op(ipmi, ST_STATUS, power_status); - switch(ret) { - case STATE_ON: - return 0; - case STATE_OFF: - break; - default: - return ret; - } - - while (retries>=0) { - ret = ipmi_op(ipmi, ST_POWERON, power_on_complete); - if (ret != 0) - return ret; - - sleep(2); - --retries; - ret = ipmi_op(ipmi, ST_STATUS, power_status); - - switch(ret) { - case STATE_ON: - return 0; - case EFAULT: - /* We're done. */ - retries = 0; - break; - case STATE_OFF: - default: - continue; - } - } - log(LOG_WARNING, "ipmilan: Power still off\n"); - - return ret; -} - -static int -ipmi_cycle(struct ipmi *ipmi) -{ - int ret; - - ret = ipmi_op(ipmi, ST_CYCLE, power_cycle_complete); - - return ret; -} - - -/** - Squash all our private data - */ -static void -ipmi_destroy(struct ipmi *i) -{ - ipmi_reap(i); - if (i->i_user) { - free(i->i_user); - i->i_user = NULL; - } - if (i->i_password) { - free(i->i_password); - i->i_password= NULL; - } - if (i->i_host) { - free(i->i_host); - i->i_host = NULL; - } - i->i_config = 0; - i->i_id = NOTIPMI; -} - - -/** - Multipurpose initializer. Used to either create a new, blank ipmi, - or update an existing one, or both. - */ -static struct ipmi * -ipmi_init(struct ipmi *i, char *host, char *authtype, - char *user, char *password, int lanplus, int verbose,int timeout) -{ - const char *p; - - if (!i || !i->i_ipmitool) - p = ipmitool_path(); - else - p = i->i_ipmitool; - - if (!p) { - log(LOG_WARNING, "ipmilan: ipmitool not found!\n"); - return NULL; - } - - if (!i) - i = malloc (sizeof(*i)); - if (!i) - return NULL; - - if (host && strlen(host)) { - i->i_host = strdup(host); - if (!i->i_host) { - free(i); - return NULL; - } - } else - i->i_host = NULL; - - if (password && strlen(password)) { - i->i_password = strdup(password); - if (!i->i_password) { - free(i->i_host); - free(i); - return NULL; - } - } else - i->i_password = NULL; - - if (authtype && strlen(authtype)) { - i->i_authtype = strdup(authtype); - if (!i->i_authtype) { - free(i->i_host); - if (i->i_password) - free(i->i_password); - free(i); - return NULL; - } - } else - i->i_authtype = NULL; - - - if (user && strlen(user)) { - i->i_user= strdup(user); - if (!i->i_user) { - free(i->i_host); - if (i->i_authtype) - free(i->i_authtype); - if (i->i_password) - free(i->i_password); - free(i); - return NULL; - } - } else - i->i_user = NULL; - i->i_ipmitool = p; - i->i_rdfd = -1; - i->i_wrfd = -1; - i->i_pid = -1; - i->i_id = IPMIID; - i->i_verbose = verbose; - i->i_lanplus = lanplus; - i->i_timeout = timeout; - - return i; -} - - -#ifndef FENCE -/** - STONITH operations - */ -#define ISIPMI(s) (s && s->pinfo && ((struct ipmi *)s->pinfo)->i_id == IPMIID) - -const char * -st_getinfo(Stonith * __attribute__ ((unused)) s, int __attribute__((unused))i) -{ - return "Not really useful info"; -} - -void -st_destroy(Stonith *s) -{ - struct ipmi *i; - - if (!ISIPMI(s)) { - log(LOG_ERR, "st_destroy(IPMI): Invalid Argument"); - return; - } - - i = (struct ipmi *)s->pinfo; - ipmi_destroy(i); -} - - -void * -st_new(void) -{ - struct ipmi *i; - - i = malloc(sizeof(*i)); - if (!i) { - log(LOG_ERR, "st_new(IPMI) %s", strerror(errno)); - return NULL; - } - - memset((void *)i, 0, sizeof(*i)); - ipmi_init(i, NULL, NULL, NULL, NULL, 0, 0); - return i; -} - - -int -st_status(Stonith *s) -{ - int ret; - - if (!ISIPMI(s)) - return S_OOPS; - - ret = ipmi_op((struct ipmi *)s->pinfo, ST_STATUS, power_status); - if (ret == STATE_ON || ret == STATE_OFF) - return S_OK; - - /* Permission denied? */ - if (ret == EPERM) - return S_BADCONFIG; - - return S_OOPS; -} - - -int -st_reset(Stonith *s, int req, char * port) -{ - int ret; - - switch(req) { - case ST_POWERON: - ret = ipmi_on((struct ipmi *)s->pinfo); - break; - case ST_POWEROFF: - ret = ipmi_off((struct ipmi *)s->pinfo); - break; - case ST_GENERIC_RESET: - /* Could use chassis power cycle, but this works too*/ - ret = ipmi_off((struct ipmi *)s->pinfo); - if (ret == 0) - ipmi_on((struct ipmi *)s->pinfo); - break; - default: - return S_OOPS; - } - - switch(ret) { - case 0: - /* Success */ - return S_OK; - case EFAULT: - log(LOG_CRIT, "ipmilan: unable to complete request\n"); - return S_OOPS; - case EPERM: - return S_BADCONFIG; - case ETIMEDOUT: - return S_BADCONFIG; - case STATE_ON: - log(LOG_ERR, "Power to host %s still ON\n", port); - break; - case STATE_OFF: - log(LOG_WARNING, "Power to host %s still OFF\n", port); - break; - } - - return S_RESETFAIL; -} - - -/** - Complicated parser. Has to deal with whitespace as well as the - possibility of having 1, 2, or 3 arguments. - */ -static int -_ipmilan_setconfinfo(Stonith *s, const char *info) -{ - char info_priv[1024]; - char *host = info_priv; - char *user = NULL; - char *passwd = NULL; - char *end = NULL; - struct ipmi *i; - size_t len; - int lanplus = 0; - - if (!ISIPMI(s)) - return S_OOPS; - i = (struct ipmi *)s->pinfo; - - snprintf(info_priv, sizeof(info_priv), "%s", info); - len = strcspn(host, "\n\r\t "); - if (len >= strlen(host)) - user = NULL; - else - user = host + len; - if (user) { - *user = 0; - user++; - if (*user && *user == '+') { - lanplus = 1; - user++; - } - } - - /* No separator or end of string reached */ - if (user && *user) { - - len = strcspn(user, "\n\r\t "); - if (len >= strlen(user)) - passwd = NULL; - else - passwd = user + len; - if (passwd) { - *passwd = 0; - passwd++; - } - - /* We don't need a username for this one */ - if (!passwd || !*passwd) { - passwd = user; - user = NULL; - } - - len = strcspn(passwd, "\n\r\t "); - end = passwd + len; - if (*end) - *end = 0; - } - - if (!*user || !strcmp(user, "(null)")) - user = NULL; - - /* IPMI auth type not supported on RHEL3 */ - i = ipmi_init(i, host, NULL, user, passwd, lanplus, 0); - if (!i) - return S_OOPS; - i->i_config = 1; - - return S_OK; -} - - -int -st_setconfinfo(Stonith *s, const char *info) -{ - /* XXX dlmap collisions? */ - return _ipmilan_setconfinfo(s, info); -} - - -/* -- Ripped from old STONITH drivers. - * Parse the information in the given configuration file, - * and stash it away... - */ -int -st_setconffile(Stonith* s, const char * configname) -{ - FILE * cfgfile; - char sid[256]; - - if (!ISIPMI(s)) - return S_OOPS; - - if ((cfgfile = fopen(configname, "r")) == NULL) { - printf("Can't open %s\n", configname); - log(LOG_ERR, "Cannot open %s", configname); - return(S_BADCONFIG); - } - while (fgets(sid, sizeof(sid), cfgfile) != NULL){ - if (*sid == '#' || *sid == '\n' || *sid == EOS) { - continue; - } - fclose(cfgfile); - return _ipmilan_setconfinfo(s, sid); - } - fclose(cfgfile); - return(S_BADCONFIG); -} - -#else - -/* Fence module instead of STONITH module */ -/** - Remove leading and trailing whitespace from a line of text. - */ -int -cleanup(char *line, size_t linelen) -{ - char *p; - size_t x; - - /* Remove leading whitespace. */ - p = line; - for (x = 0; x <= linelen; x++) { - switch (line[x]) { - case '\t': - case ' ': - break; - case '\n': - case '\r': - return -1; - default: - goto eol; - } - } -eol: - /* Move the remainder down by as many whitespace chars as we - chewed up */ - if (x) - memmove(p, &line[x], linelen-x); - - /* Remove trailing whitespace. */ - for (x=0; x <= linelen; x++) { - switch(line[x]) { - case '\t': - case ' ': - case '\r': - case '\n': - line[x] = 0; - case 0: - /* End of line */ - return 0; - } - } - - return -1; -} - - -/** - Parse args from stdin. Dev + devlen + op + oplen must be valid. - */ -int -get_options_stdin(char *ip, size_t iplen, - char *authtype, size_t atlen, - char *passwd, size_t pwlen, - char *pwd_script, size_t pwd_script_len, - char *user, size_t userlen, - char *op, size_t oplen, - int *lanplus, int *verbose,int *timeout, - char *method, int methodlen) -{ - char in[256]; - int line = 0; - char *name, *val; - - op[0] = 0; - method[0] = 0; - - while (fgets(in, sizeof(in), stdin)) { - ++line; - - if (in[0] == '#') - continue; - - if (cleanup(in, sizeof(in)) == -1) - continue; - - name = in; - if ((val = strchr(in, '='))) { - *val = 0; - ++val; - } - - if (!strcasecmp(name, "agent")) { - /* Used by fenced? */ - } else if (!strcasecmp(name, "verbose")) { - *verbose = 1; - } else if (!strcasecmp(name, "ipaddr")) { - /* IP address to use. E.g. 10.1.1.2 */ - if (val) - strncpy(ip, val, iplen); - else - ip[0] = 0; - - } else if (!strcasecmp(name, "auth")) { - /* Authtype to use */ - if (val) - strncpy(authtype, val, atlen); - else - authtype[0] = 0; - - } else if (!strcasecmp(name, "passwd")) { - /* password */ - if (val) - strncpy(passwd, val, pwlen); - else - passwd[0] = 0; - - } else if (!strcasecmp(name, "passwd_script")) { - if (val) { - strncpy(pwd_script, val, pwd_script_len); - pwd_script[pwd_script_len - 1] = '\0'; - } else - pwd_script[0] = '\0'; - } else if (!strcasecmp(name, "user") || !strcasecmp(name, "login")) { - /* username */ - if (val) - strncpy(user, val, userlen); - else - user[0] = 0; - } else if (!strcasecmp(name, "lanplus")) { - (*lanplus) = 1; - } else if (!strcasecmp(name,"timeout")) { - if ((sscanf(val,"%d",timeout)!=1) || *timeout<1) { - *timeout=DEFAULT_TIMEOUT; - } - } else if (!strcasecmp(name,"method")) { - strncpy (method, val, methodlen); - } else if (!strcasecmp(name, "option") || - !strcasecmp(name, "operation") || - !strcasecmp(name, "action")) { - if (val) - strncpy(op, val, oplen); - else - op[0] = 0; - } - } - - return 0; -} - - -/** - Print a message to stderr and call exit(1). - */ -void -fail_exit(char *msg) -{ - fprintf(stderr, "failed: %s\n", msg); - exit(1); -} - -void -usage_exit(char *pname) -{ -printf("usage: %s <options>\n", pname); -printf(" -A <authtype> IPMI Lan Auth type (md5, password, or none)\n"); -printf(" -a <ipaddr> IPMI Lan IP to talk to\n"); -printf(" -i <ipaddr> IPMI Lan IP to talk to (deprecated, use -a)\n"); -printf(" -p <password> Password (if required) to control power on\n" - " IPMI device\n"); -printf(" -P Use Lanplus\n"); -printf(" -S <path> Script to retrieve password (if required)\n"); -printf(" -l <login> Username/Login (if required) to control power\n" - " on IPMI device\n"); -printf(" -o <op> Operation to perform.\n"); -printf(" Valid operations: on, off, reboot, status\n"); -printf(" -t <timeout> Timeout (sec) for IPMI operation (default %d)\n",DEFAULT_TIMEOUT); -printf(" -M <method> Method to fence (onoff or cycle (default %s)\n", DEFAULT_METHOD); -printf(" -V Print version and exit\n"); -printf(" -v Verbose mode\n\n"); -printf("If no options are specified, the following options will be read\n"); -printf("from standard input (one per line):\n\n"); -printf(" auth=<auth> Same as -A\n"); -printf(" ipaddr=<#> Same as -a\n"); -printf(" passwd=<pass> Same as -p\n"); -printf(" passwd_script=<path> Same as -S\n"); -printf(" lanplus Same as -P\n"); -printf(" login=<login> Same as -u\n"); -printf(" option=<op> Same as -o\n"); -printf(" operation=<op> Same as -o\n"); -printf(" action=<op> Same as -o\n"); -printf(" timeout=<timeout> Same as -t\n"); -printf(" method=<method> Same as -M\n"); -printf(" verbose Same as -v\n\n"); - exit(1); -} - - -int -main(int argc, char **argv) -{ - extern char *optarg; - int opt, ret = -1; - char authtype[64]; - char ip[64]; - char passwd[64]; - char user[64]; - char op[64]; - char method[64]; - char pwd_script[PATH_MAX] = { 0, }; - int lanplus=0; - int verbose=0; - char *pname = basename(argv[0]); - struct ipmi *i; - int timeout=DEFAULT_TIMEOUT; - - memset(ip, 0, sizeof(ip)); - memset(authtype, 0, sizeof(authtype)); - memset(passwd, 0, sizeof(passwd)); - memset(user, 0, sizeof(user)); - memset(op, 0, sizeof(op)); - memset(method, 0 ,sizeof(method)); - - if (argc > 1) { - /* - Parse command line options if any were specified - */ - while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:M:")) != EOF) { - switch(opt) { - case 'A': - /* Auth type */ - strncpy(authtype, optarg, sizeof(authtype)); - break; - case 'a': - case 'i': - /* IP address */ - strncpy(ip, optarg, sizeof(ip)); - break; - case 'l': - /* user / login */ - strncpy(user, optarg, sizeof(user)); - break; - case 'p': - /* password */ - strncpy(passwd, optarg, sizeof(passwd)); - break; - case 'P': - lanplus = 1; - break; - case 'S': - strncpy(pwd_script, optarg, sizeof(pwd_script)); - pwd_script[sizeof(pwd_script) - 1] = '\0'; - break; - case 'o': - /* Operation */ - strncpy(op, optarg, sizeof(op)); - break; - case 't': - /* Timeout */ - if ((sscanf(optarg,"%d",&timeout)!=1) || timeout<1) { - fail_exit("Timeout option expects positive number parameter"); - } - break; - case 'M': - /* Reboot method */ - strncpy(method, optarg, sizeof(method)); - break; - case 'v': - verbose++; - break; - case 'V': - printf("%s %s (built %s %s)\n", pname, - FENCE_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", - REDHAT_COPYRIGHT); - return 0; - default: - usage_exit(pname); - } - } - } else { - /* - No command line args? Get stuff from stdin - */ - if (get_options_stdin(ip, sizeof(ip), - authtype, sizeof(authtype), - passwd, sizeof(passwd), - pwd_script, sizeof(pwd_script), - user, sizeof(user), - op, sizeof(op), &lanplus, &verbose,&timeout, - method, sizeof(method)) != 0) - return 1; - } - - if (pwd_script[0] != '\0') { - char pwd_buf[1024]; - FILE *fp; - fp = popen(pwd_script, "r"); - if (fp != NULL) { - ssize_t len = fread(pwd_buf, 1, sizeof(pwd_buf), fp); - if (len > 0) { - char *p; - p = strchr(pwd_buf, '\n'); - if (p != NULL) - *p = '\0'; - p = strchr(pwd_buf, '\r'); - if (p != NULL) - *p = '\0'; - strncpy(passwd, pwd_buf, sizeof(passwd)); - passwd[sizeof(passwd) - 1] = '\0'; - } - pclose(fp); - } - } - - /* - Validate the operating parameters - */ - if (strlen(ip) == 0) - fail_exit("no IP address specified"); - - if (!strlen(op)) - snprintf(op,sizeof(op), "reboot"); - - if (!strlen(method)) - snprintf(method, sizeof(method), "onoff"); - - if (strcasecmp(op, "off") && strcasecmp(op, "on") && - strcasecmp(op, "status") && strcasecmp(op, "reboot")) { - fail_exit("operation must be 'on', 'off', 'status', " - "or 'reboot'"); - } - - if (strlen(authtype) && - strcasecmp(authtype, "md5") && - strcasecmp(authtype, "password") && - strcasecmp(authtype, "none")) { - fail_exit("authtype, if included, must be 'md5', 'password'," - " 'none'."); - } - - if (strcasecmp(method, "onoff") && - strcasecmp(method, "cycle")) { - fail_exit("method, if included, muse be 'onoff', 'cycle'."); - } - - if (!strcasecmp(method, "cycle") && - (!strcasecmp(op, "on") || !strcasecmp(op, "off"))) { - fail_exit("cycle method supports only 'reboot' operation (not 'on' or 'off')."); - } - - /* Ok, set up the IPMI struct */ - i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout); - if (!i) - fail_exit("Failed to initialize\n"); - - /* - Perform the requested operation - */ - if (!strcasecmp(op, "reboot")) { - printf("Rebooting machine @ IPMI:%s...", ip); - fflush(stdout); - if (!strcasecmp(method, "cycle")) { - ret = ipmi_op(i, ST_STATUS, power_status); - - if (ret == STATE_OFF) { - /* State is off -> use onoff method because cycle is not able to turn on*/ - snprintf(method, sizeof(method), "onoff"); - } - } - - if (!strcasecmp(method, "cycle")) { - ret = ipmi_cycle(i); - } else { - /* Original onoff method */ - ret = ipmi_off(i); - if (ret != 0) - goto out; - ret = ipmi_on(i); - } - } else if (!strcasecmp(op, "on")) { - printf("Powering on machine @ IPMI:%s...", ip); - fflush(stdout); - ret = ipmi_on(i); - - } else if (!strcasecmp(op, "off")) { - printf("Powering off machine @ IPMI:%s...", ip); - fflush(stdout); - ret = ipmi_off(i); - } else if (!strcasecmp(op, "status")) { - printf("Getting status of IPMI:%s...",ip); - fflush(stdout); - ret = ipmi_op(i, ST_STATUS, power_status); - switch(ret) { - case STATE_ON: - printf("Chassis power = On\n"); - ret = 0; - break; - case STATE_OFF: - printf("Chassis power = Off\n"); - ret = 0; - break; - default: - printf("Chassis power = Unknown\n"); - ret = 1; - break; - } - } - - -out: - ipmi_destroy(i); - free(i); - if (ret == 0) - printf("Done\n"); - else - printf("Failed\n"); - return ret; -} -#endif /* fence */ diff --git a/fence/agents/lib/Makefile b/fence/agents/lib/Makefile deleted file mode 100644 index 2214ea6..0000000 --- a/fence/agents/lib/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE1= fencing.py.py -TARGET1= fencing.py - -SOURCE2= telnet_ssl.py -TARGET2= telnet_ssl - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET1) $(TARGET2) - -$(TARGET1): $(SOURCE1) - : > $(TARGET1) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE1) >> $(TARGET1) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET1) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET1) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET1) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE1) >> $(TARGET1) - chmod +x $(TARGET1) - -$(TARGET2): $(SOURCE2) - : > $(TARGET2) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE2) >> $(TARGET2) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET2) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET2) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET2) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE2) >> $(TARGET2) - chmod +x $(TARGET2) - -copytobin: ${TARGET1} ${TARGET2} - cp ${TARGET1} ${top_srcdir}/bin/${TARGET1} - cp ${TARGET2} ${top_srcdir}/bin/${TARGET2} - -clean: - rm -f $(TARGET1) $(TARGET2) diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py deleted file mode 100644 index 086b4e1..0000000 --- a/fence/agents/lib/fencing.py.py +++ /dev/null @@ -1,492 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -##### -import sys, getopt, time, os -import pexpect, re -import telnetlib - -## do not add code here. -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -POWER_TIMEOUT = 20 -SHELL_TIMEOUT = 3 -LOGIN_TIMEOUT = 5 - -LOG_MODE_VERBOSE = 100 -LOG_MODE_QUIET = 0 - -EC_GENERIC_ERROR = 1 -EC_BAD_ARGS = 2 -EC_LOGIN_DENIED = 3 -EC_CONNECTION_LOST = 4 -EC_TIMED_OUT = 5 -EC_WAITING_ON = 6 -EC_WAITING_OFF = 7 -EC_STATUS = 8 -EC_STATUS_HMC = 9 - -TELNET_PATH = "/usr/bin/telnet" -SSH_PATH = "/usr/bin/ssh" -SSL_PATH = "/usr/lib/fence/telnet_ssl" - -all_opt = { - "help" : { - "getopt" : "h", - "help" : "-h Display this help and exit", - "order" : 54 }, - "version" : { - "getopt" : "V", - "help" : "-V Output version information and exit", - "order" : 53 }, - "quiet" : { - "getopt" : "q", - "help" : "-q Quiet mode", - "order" : 50 }, - "verbose" : { - "getopt" : "v", - "help" : "-v Verbose mode", - "order" : 51 }, - "debug" : { - "getopt" : "D:", - "help" : "-D <debugfile> Debugging to output file", - "order" : 52 }, - "agent" : { - "getopt" : "", - "help" : "", - "order" : 1 }, - "action" : { - "getopt" : "o:", - "help" : "-o <action> Action: status, reboot (default), off or on", - "order" : 1 }, - "io_fencing" : { - "getopt" : "o:", - "longopt" : "action", - "help" : "-o, --action=<action> Action: status, enable or disable", - "required" : "1", - "shortdesc" : "Fencing Action", - "default" : "disable", - "order" : 1 }, - "ipaddr" : { - "getopt" : "a:", - "help" : "-a <ip> IP address or hostname of fencing device", - "order" : 1 }, - "login" : { - "getopt" : "l:", - "help" : "-l <name> Login name", - "order" : 1 }, - "no_login" : { - "getopt" : "", - "help" : "", - "order" : 1 }, - "no_password" : { - "getopt" : "", - "help" : "", - "order" : 1 }, - "passwd" : { - "getopt" : "p:", - "help" : "-p <password> Login password or passphrase", - "order" : 1 }, - "passwd_script" : { - "getopt" : "S:", - "help" : "-S <script> Script to run to retrieve password", - "order" : 1 }, - "identity_file" : { - "getopt" : "k:", - "help" : "-k <filename> Identity file (private key) for ssh ", - "order" : 1 }, - "module_name" : { - "getopt" : "m:", - "help" : "-m <module> DRAC/MC module name", - "order" : 1 }, - "drac_version" : { - "getopt" : "d:", - "help" : "-d <version> Force DRAC version to use", - "order" : 1 }, - "hmc_version" : { - "getopt" : "H:", - "longopt" : "hmc-version", - "help" : "-H <version> Force HMC version to use: 3, 4 (default)", - "order" : 1 }, - "ribcl" : { - "getopt" : "r:", - "help" : "-r <version> Force ribcl version to use", - "order" : 1 }, - "login_eol_lf" : { - "getopt" : "", - "help" : "", - "order" : 1 - }, - "cmd_prompt" : { - "getopt" : "c:", - "help" : "-c <prompt> Force command prompt", - "order" : 1 }, - "secure" : { - "getopt" : "x", - "help" : "-x Use ssh connection", - "order" : 1 }, - "ssl" : { - "getopt" : "z", - "help" : "-z Use ssl connection", - "order" : 1 }, - "port" : { - "getopt" : "n:", - "help" : "-n <id> Physical plug number on device", - "order" : 1 }, - "switch" : { - "getopt" : "s:", - "help" : "-s <id> Physical switch number on device", - "order" : 1 }, - "partition" : { - "getopt" : "n:", - "help" : "-n <id> Name of the partition", - "order" : 1 }, - "managed" : { - "getopt" : "s:", - "help" : "-s <id> Name of the managed system", - "order" : 1 }, - "power_wait" : { - "getopt" : "G:", - "help" : "-G <seconds> Wait X seconds after issuing ON/OFF", - "order" : 1 }, - "test" : { - "getopt" : "T", - "help" : "", - "order" : 1, - "obsolete" : "use -o status instead" } -} - -class fspawn(pexpect.spawn): - def log_expect(self, options, pattern, timeout): - result = self.expect(pattern, timeout) - if options["log"] >= LOG_MODE_VERBOSE: - options["debug_fh"].write(self.before + self.after) - return result - -def version(command, release, build_date, copyright_notice): - print command, " ", release, " ", build_date - if len(copyright_notice) > 0: - print copyright_notice - -def fail_usage(message = ""): - if len(message) > 0: - sys.stderr.write(message+"\n") - sys.stderr.write("Please use '-h' for usage\n") - sys.exit(EC_BAD_ARGS) - -def fail(error_code): - message = { - EC_LOGIN_DENIED : "Unable to connect/login to fencing device", - EC_CONNECTION_LOST : "Connection lost", - EC_TIMED_OUT : "Connection timed out", - EC_WAITING_ON : "Failed: Timed out waiting to power ON", - EC_WAITING_OFF : "Failed: Timed out waiting to power OFF", - EC_STATUS : "Failed: Unable to obtain correct plug status or plug is not available", - EC_STATUS_HMC : "Failed: Either unable to obtaion correct plug status, partition is not available or incorrect HMC version used" - }[error_code] + "\n" - sys.stderr.write(message) - sys.exit(error_code) - -def usage(avail_opt): - global all_opt - - print "Usage:" - print "\t" + os.path.basename(sys.argv[0]) + " [options]" - print "Options:" - - sorted_list = [ (key, all_opt[key]) for key in avail_opt ] - sorted_list.sort(lambda x, y: cmp(x[1]["order"], y[1]["order"])) - - for key, value in sorted_list: - if len(value["help"]) != 0: - print " " + value["help"] - -def process_input(avail_opt): - global all_opt - - ## - ## Set standard environment - ##### - os.putenv("LANG", "C") - os.putenv("LC_ALL", "C") - - ## - ## Prepare list of options for getopt - ##### - getopt_string = "" - for k in avail_opt: - if all_opt.has_key(k): - getopt_string += all_opt[k]["getopt"] - else: - fail_usage("Parse error: unknown option '"+k+"'") - - ## - ## Read options from command line or standard input - ##### - if len(sys.argv) > 1: - try: - opt, args = getopt.gnu_getopt(sys.argv[1:], getopt_string) - except getopt.GetoptError, error: - fail_usage("Parse error: " + error.msg) - - ## Compatibility Layer - ##### - z = dict(opt) - if z.has_key("-T") == 1: - z["-o"] = "status" - - opt = z - ## - ##### - else: - opt = { } - name = "" - for line in sys.stdin.readlines(): - line = line.strip() - if ((line.startswith("#")) or (len(line) == 0)): - continue - - (name, value) = (line + "=").split("=", 1) - value = value[:-1] - - ## Compatibility Layer - ###### - if name == "blade": - name = "port" - elif name == "option": - name = "action" - elif name == "fm": - name = "port" - elif name == "hostname": - name = "ipaddr" - elif name == "modulename": - name = "module_name" - elif name == "action" and 1 == avail_opt.count("io_fencing"): - name = "io_fencing" - - ## - ###### - if avail_opt.count(name) == 0: - fail_usage("Parse error: Unknown option '"+line+"'") - - if all_opt[name]["getopt"].endswith(":"): - opt["-"+all_opt[name]["getopt"].rstrip(":")] = value - elif ((value == "1") or (value.lower() == "yes")): - opt["-"+all_opt[name]["getopt"]] = "1" - return opt - -## -## This function checks input and answers if we want to have same answers -## in each of the fencing agents. It looks for possible errors and run -## password script to set a correct password -###### -def check_input(device_opt, opt): - options = dict(opt) - options["device_opt"] = device_opt - - if options.has_key("-h"): - usage(device_opt) - sys.exit(0) - - if options.has_key("-V"): - print FENCE_RELEASE_NAME, BUILD_DATE - print REDHAT_COPYRIGHT - sys.exit(0) - - if options.has_key("-v"): - options["log"] = LOG_MODE_VERBOSE - else: - options["log"] = LOG_MODE_QUIET - - # Convert action to lowercase - options["-o"]=options["-o"].lower() - - if 0 == device_opt.count("io_fencing"): - if 0 == options.has_key("-o"): - options["-o"] = "reboot" - if 0 == ["on", "off", "reboot", "status"].count(options["-o"].lower()): - fail_usage("Failed: Unrecognised action '" + options["-o"] + "'") - else: - if 0 == options.has_key("-o"): - options["-o"] = "disable" - if 0 == ["enable", "disable", "status"].count(options["-o"].lower()): - fail_usage("Failed: Unrecognised action '" + options["-o"] + "'") - - if (0 == options.has_key("-l")) and device_opt.count("login") and (device_opt.count("no_login") == 0): - fail_usage("Failed: You have to set login name") - - if 0 == options.has_key("-a"): - fail_usage("Failed: You have to enter fence address") - - if (device_opt.count("no_password") == 0): - if 0 == device_opt.count("identity_file"): - if 0 == (options.has_key("-p") or options.has_key("-S")): - fail_usage("Failed: You have to enter password or password script") - else: - if 0 == (options.has_key("-p") or options.has_key("-S") or options.has_key("-k")): - fail_usage("Failed: You have to enter password, password script or identity file") - - if 0 == options.has_key("-x") and 1 == options.has_key("-k"): - fail_usage("Failed: You have to use identity file together with ssh connection (-x)") - - if 1 == options.has_key("-k"): - if 0 == os.path.isfile(options["-k"]): - fail_usage("Failed: Identity file " + options["-k"] + " does not exist") - - if (0 == options.has_key("-n")) and (device_opt.count("port")): - fail_usage("Failed: You have to enter plug number") - - if options.has_key("-S"): - options["-p"] = os.popen(options["-S"]).read().rstrip() - - if options.has_key("-D"): - try: - options["debug_fh"] = file (options["-D"], "w") - except IOError: - fail_usage("Failed: Unable to create file "+options["-D"]) - - if options.has_key("-v") and options.has_key("debug_fh") == 0: - options["debug_fh"] = sys.stderr - - return options - -def wait_power_status(tn, options, get_power_fn): - for dummy in xrange(POWER_TIMEOUT): - if get_power_fn(tn, options) != options["-o"]: - time.sleep(1) - else: - return 1 - return 0 - -def fence_action(tn, options, set_power_fn, get_power_fn): - status = get_power_fn(tn, options) - - if status != "on" and status != "off": - fail(EC_STATUS) - - if options["-o"] == "enable": - options["-o"] = "on" - if options["-o"] == "disable": - options["-o"] = "off" - - if options["-o"] == "on": - if status == "on": - print "Success: Already ON" - else: - set_power_fn(tn, options) - if wait_power_status(tn, options, get_power_fn): - print "Success: Powered ON" - else: - fail(EC_WAITING_ON) - elif options["-o"] == "off": - if status == "off": - print "Success: Already OFF" - else: - set_power_fn(tn, options) - if wait_power_status(tn, options, get_power_fn): - print "Success: Powered OFF" - else: - fail(EC_WAITING_OFF) - elif options["-o"] == "reboot": - if status != "off": - options["-o"] = "off" - set_power_fn(tn, options) - if wait_power_status(tn, options, get_power_fn) == 0: - fail(EC_WAITING_OFF) - if options.has_key("-G"): - time.sleep(int(options["-G"])) - options["-o"] = "on" - set_power_fn(tn, options) - if wait_power_status(tn, options, get_power_fn) == 0: - sys.stderr.write('Timed out waiting to power ON\n') - print "Success: Rebooted" - elif options["-o"] == "status": - print "Status: " + status.upper() - -def fence_login(options): - if (options["device_opt"].count("login_eol_lf")): - login_eol = "\n" - else: - login_eol = "\r\n" - - if (options["device_opt"].count("login_eol_lf")): - login_eol = "\n" - else: - login_eol = "\r\n" - - try: - re_login = re.compile("(login: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE) - re_pass = re.compile("password", re.IGNORECASE) - - if options.has_key("-z"): - command = '%s %s %s' % (SSL_PATH, options["-a"], "443") - try: - conn = fspawn(command) - except pexpect.ExceptionPexpect, ex: - ## SSL telnet is part of the fencing package - sys.stderr.write(str(ex) + "\n") - sys.exit(EC_GENERIC_ERROR) - elif options.has_key("-x") and 0 == options.has_key("-k"): - command = '%s %s@%s' % (SSH_PATH, options["-l"], options["-a"]) - if options.has_key("ssh_options"): - command += ' ' + options["ssh_options"] - try: - conn = fspawn(command) - except pexpect.ExceptionPexpect, ex: - sys.stderr.write(str(ex) + "\n") - sys.stderr.write("Due to limitations, binary dependencies on fence agents " - "are not in the spec file and must be installed separately." + "\n") - sys.exit(EC_GENERIC_ERROR) - - result = conn.log_expect(options, [ "ssword:", "Are you sure you want to continue connecting (yes/no)?" ], LOGIN_TIMEOUT) - if result == 1: - conn.sendline("yes") - conn.log_expect(options, "ssword:", LOGIN_TIMEOUT) - conn.sendline(options["-p"]) - conn.log_expect(options, options["-c"], LOGIN_TIMEOUT) - elif options.has_key("-x") and 1 == options.has_key("-k"): - command = '%s %s@%s -i %s' % (SSH_PATH, options["-l"], options["-a"], options["-k"]) - try: - conn = fspawn(command) - except pexpect.ExceptionPexpect, ex: - sys.stderr.write(str(ex) + "\n") - sys.stderr.write("Due to limitations, binary dependencies on fence agents " - "are not in the spec file and must be installed separately." + "\n") - sys.exit(EC_GENERIC_ERROR) - - result = conn.log_expect(options, [ options["-c"], "Are you sure you want to continue connecting (yes/no)?", "Enter passphrase for key '"+options["-k"]+"':" ], LOGIN_TIMEOUT) - if result == 1: - conn.sendline("yes") - conn.log_expect(options, [ options["-c"], "Enter passphrase for key '"+options["-k"]+"':"] , LOGIN_TIMEOUT) - if result != 0: - if options.has_key("-p"): - conn.sendline(options["-p"]) - conn.log_expect(options, options["-c"], LOGIN_TIMEOUT) - else: - fail_usage("Failed: You have to enter passphrase (-p) for identity file") - else: - command = '%s %s' % (TELNET_PATH, options["-a"]) - try: - conn = fspawn(command) - except pexpect.ExceptionPexpect, ex: - sys.stderr.write(str(ex) + "\n") - sys.stderr.write("Due to limitations, binary dependencies on fence agents " - "are not in the spec file and must be installed separately." + "\n") - sys.exit(EC_GENERIC_ERROR) - - conn.log_expect(options, re_login, LOGIN_TIMEOUT) - conn.send(options["-l"] + login_eol) - conn.log_expect(options, re_pass, SHELL_TIMEOUT) - conn.send(options["-p"] + login_eol) - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_LOGIN_DENIED) - except pexpect.TIMEOUT: - fail(EC_LOGIN_DENIED) - return conn diff --git a/fence/agents/lib/telnet_ssl.py b/fence/agents/lib/telnet_ssl.py deleted file mode 100755 index dfa23b8..0000000 --- a/fence/agents/lib/telnet_ssl.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/python - -##### -## simple telnet client with SSL support -## -## ./telnet_ssl host port -##### - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -import sys, socket, string, fcntl, os , time -from OpenSSL import SSL - -def main(): - hostname = None - port = None - - if (len(sys.argv) != 3): - print "Error: You have to enter hostname and port number\n" - sys.exit(-1) - - hostname = sys.argv[1] - port = int(sys.argv[2]) - - try: - s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) - s.connect((hostname,port)) - ctx = SSL.Context(SSL.SSLv23_METHOD) - conn = SSL.Connection(ctx, s) - conn.set_connect_state() - except socket.error, e: - print "Error: Unable to connect to %s:%s %s" % (hostname, port, str(e)) - sys.exit(-1) - - fcntl.fcntl(sys.stdin, fcntl.F_SETFL, os.O_NONBLOCK) - s.settimeout(0) - - while 1: - try: - write_buff = sys.stdin.readline() - if (len(write_buff) > 0): - write_buff = string.rstrip(write_buff) - i = 10 - while i > 0: - i = i-1 - try: - conn.send(write_buff + "\r\n") - i = -1 - except SSL.WantReadError: - ## We have to wait for connect, mostly just for first time - time.sleep(1) - if i == 0: - sys.exit(-2) - except IOError: - 1 - - try: - read_buff = conn.recv(4096) - print read_buff - sys.stdout.flush() - except SSL.WantReadError: - 1 - except SSL.ZeroReturnError: - break - - -if __name__ == "__main__": - main() diff --git a/fence/agents/lpar/Makefile b/fence/agents/lpar/Makefile deleted file mode 100644 index 2f5f88d..0000000 --- a/fence/agents/lpar/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_lpar.py -TARGET= fence_lpar - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_lpar: fence_lpar.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py deleted file mode 100755 index ffa2be8..0000000 --- a/fence/agents/lpar/fence_lpar.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -## The Following Agent Has Been Tested On: -## -## Version -## +---------------------------------------------+ -## Tested on HMC -## -##### - -import sys, re, pexpect, exceptions -sys.path.append("/usr/lib/fence") -from fencing import * - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - if options["-H"] == "3": - try: - conn.send("lssyscfg -r lpar -m " + options["-s"] + " -n " + options["-n"] + " -F name,state\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - try: - status = re.compile("^" + options["-n"] + ",(.*?),.*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(1) - except AttributeError: - fail(EC_STATUS_HMC) - elif options["-H"] == "4": - try: - conn.send("lssyscfg -r lpar -m "+ options["-s"] +" --filter 'lpar_names=" + options["-n"] + "'\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - try: - status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1) - except AttributeError: - fail(EC_STATUS_HMC) - - ## - ## Transformation to standard ON/OFF status if possible - if status in ["Running", "Open Firmware", "Shutting Down", "Starting"]: - status = "on" - else: - status = "off" - - return status - -def set_power_status(conn, options): - if options["-H"] == "3": - try: - conn.send("chsysstate -o " + options["-o"] + " -r lpar -m " + options["-s"] - + " -n " + options["-n"] + "\n") - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - elif options["-H"] == "4": - try: - if options["-o"] == "on": - conn.send("chsysstate -o on -r lpar -m " + options["-s"] + - " -n " + options["-n"] + - " -f `lssyscfg -r lpar -F curr_profile " + - " -m " + options["-s"] + - " --filter "lpar_names="+ options["-n"] +""`\n" ) - else: - conn.send("chsysstate -o shutdown -r lpar --immed" + - " -m " + options["-s"] + " -n " + options["-n"] + "\n") - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "secure", "partition", "managed", "hmc_version", "cmd_prompt" ] - - options = check_input(device_opt, process_input(device_opt)) - options["-x"] = 1 - - ## - ## Fence agent specific defaults - ##### - if 0 == options.has_key("-c"): - options["-c"] = [ ":~>", "]$" ] - - if 0 == options.has_key("-H"): - options["-H"] = "4" - - if 0 == options.has_key("-s"): - fail_usage("Failed: You have to enter name of managed system") - - if 0 == options.has_key("-n"): - fail_usage("Failed: You have to enter name of the partition") - - if 1 == options.has_key("-H") and (options["-H"] != "3" and options["-H"] != "4"): - fail_usage("Failed: You have to enter valid version number: 3 or 4") - - ## - ## Operate the fencing device - #### - conn = fence_login(options) - fence_action(conn, options, set_power_status, get_power_status) - - ## - ## Logout from system - ###### - try: - conn.send("quit\r\n") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/manual/Makefile b/fence/agents/manual/Makefile deleted file mode 100644 index 7cc753b..0000000 --- a/fence/agents/manual/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= fence_manual fence_ack_manual - -fence_manual_SOURCE= manual.c -fence_ack_manual_SOURCE= ack.c - -top_srcdir=../.. - - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config -I${incdir} - - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -DFENCE_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -fence_manual: ${fence_manual_SOURCE:.c=.o} - ${CC} ${CFLAGS} ${LDFLAGS} ${fence_manual_SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@ - -fence_ack_manual: ${fence_ack_manual_SOURCE:.c=.o} - ${CC} ${CFLAGS} ${LDFLAGS} ${fence_ack_manual_SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/fence/agents/manual/ack.c b/fence/agents/manual/ack.c deleted file mode 100644 index 7fd6f5e..0000000 --- a/fence/agents/manual/ack.c +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/wait.h> - -#include "copyright.cf" - -#define FIFO_DIR "/tmp" - -char *pname = NULL; -char fname[256]; -int quiet_flag = 0; -int override_flag = 0; - - -void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options]\n" - "\n" - "Options:\n" - " -h usage\n" - " -O override\n" - " -n <nodename> Name of node that was manually fenced\n" - " -s <ip> IP address of machine that was manually fenced (deprecated)\n" - " -V Version information\n", pname); -} - -int main(int argc, char **argv) -{ - int error, fd; - char line[256]; - char *ipaddr = NULL; - char response[3]; - int c; - - memset(line, 0, 256); - - pname = argv[0]; - - while ((c = getopt(argc, argv, "hOs:n:qV")) != -1) - { - switch(c) - { - case 'h': - print_usage(); - exit(0); - - case 'O': - override_flag = 1; - break; - - case 's': - ipaddr = optarg; - break; - - case 'n': - ipaddr = optarg; - break; - - case 'q': - quiet_flag = 1; - break; - - case 'V': - printf("%s %s (built %s %s)\n", pname, FENCE_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - break; - - default: - fprintf(stderr, "Bad programmer! You forgot to catch the %c flag\n", c); - exit(1); - break; - - } - } - - if (!ipaddr) - { - if(!quiet_flag) - print_usage(); - exit(1); - } - - if(!override_flag) - { - printf("\nWarning: If the node "%s" has not been manually fenced\n" - "(i.e. power cycled or disconnected from shared storage devices)\n" - "the GFS file system may become corrupted and all its data\n" - "unrecoverable! Please verify that the node shown above has\n" - "been reset or disconnected from storage.\n", ipaddr); - - printf("\nAre you certain you want to continue? [yN] "); - scanf("%s", response); - - if (tolower(response[0] != 'y')) - { - printf("%s operation canceled.\n", pname); - exit(1); - } - } - - memset(fname, 0, 256); - sprintf(fname, "%s/fence_manual.fifo", FIFO_DIR); - - fd = open(fname, O_WRONLY | O_NONBLOCK); - if (fd < 0) - { - perror("can't open /tmp/fence_manual.fifo"); - exit(1); - } - - sprintf(line, "meatware ok\n"); - - error = write(fd, line, 256); - if (error < 0) - { - perror("can't write to /tmp/fence_manual.fifo"); - exit(1); - } - - if(!quiet_flag) - printf("done\n"); - - return(0); -} - - diff --git a/fence/agents/manual/manual.c b/fence/agents/manual/manual.c deleted file mode 100644 index 569c579..0000000 --- a/fence/agents/manual/manual.c +++ /dev/null @@ -1,329 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <stdint.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <syslog.h> - -#include <cluster/cnxman-socket.h> -#include "copyright.cf" - -/* FIFO_DIR needs to agree with the same in manual/ack.c */ - -#define OPTION_STRING "hn:s:p:qV" -#define LOCK_DIR "/var/lock" -#define FIFO_DIR "/tmp" - -char path[256]; -char lockdir[256]; -char fifodir[256]; -char fname[256]; - -char args[256]; -char agent[256]; -char victim[256]; - -char *prog_name; - -int quiet_flag; -int fifo_fd; -int cl_sock; - - -void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options]\n", prog_name); - printf("\n"); - printf("Options:\n"); - printf(" -h usage\n"); - printf(" -q quiet\n"); - printf(" -n <nodename> node to fence\n"); - printf(" -V version\n"); -} - -void get_options(int argc, char **argv) -{ - int c, rv; - char *curr; - char *rest; - char *value; - - if (argc > 1) { - while ((c = getopt(argc, argv, OPTION_STRING)) != -1) { - switch(c) { - case 'h': - print_usage(); - exit(0); - - case 'n': - if (strlen(optarg) > 255) { - fprintf(stderr, "node name too long\n"); - exit(1); - } - strcpy(victim, optarg); - break; - - case 'q': - quiet_flag = 1; - break; - - case 'p': - if (strlen(optarg) > 200) { - fprintf(stderr, "path name too long\n"); - exit(1); - } - strncpy(path, optarg, 200); - break; - - case 'V': - printf("%s %s (built %s %s)\n", prog_name, - FENCE_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - break; - - default: - fprintf(stderr, "unknown option: %c\n", c); - exit(1); - break; - - } - } - } else { - if ((rv = read(0, args, 255)) < 0) { - if (!quiet_flag) - printf("failed: no input\n"); - exit(1); - } - - curr = args; - - while ((rest = strchr(curr, '\n')) != NULL) { - *rest = 0; - rest++; - if ((value = strchr(curr, '=')) == NULL) { - printf("failed: invalid input\n"); - exit(1); - } - *value = 0; - value++; - if (!strcmp(curr, "agent")){ - strcpy(agent, value); - prog_name = agent; - } - if (!strcmp(curr, "nodename")) - strcpy(victim, value); - /* deprecated */ - if (!strcmp(curr, "ipaddr")) - strcpy(victim, value); - curr = rest; - } - } - - if (!strlen(path)) - strcpy(lockdir, LOCK_DIR); - else - strcpy(lockdir, path); - - strcpy(fifodir, FIFO_DIR); -} - -void lockfile(void) -{ - int fd, error; - struct flock lock; - - memset(fname, 0, 256); - sprintf(fname, "%s/fence_manual.lock", lockdir); - - fd = open(fname, O_WRONLY | O_CREAT | O_NONBLOCK, - (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); - if (fd < 0) { - if (!quiet_flag) - printf("failed: %s %s lockfile open error\n", - prog_name, victim); - exit(1); - } - - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - error = fcntl(fd, F_SETLKW, &lock); - if (error < 0) { - if (!quiet_flag) - printf("failed: fcntl errno %d\n", errno); - exit(1); - } -} - -void setup_fifo(void) -{ - int fd, error; - - memset(fname, 0, 256); - sprintf(fname, "%s/fence_manual.fifo", fifodir); - - umask(0); - - error = mkfifo(fname, (S_IRUSR | S_IWUSR)); - if (error && errno != EEXIST) { - if (!quiet_flag) - printf("failed: %s mkfifo error\n", prog_name); - exit(1); - } - - fd = open(fname, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - if (!quiet_flag) - printf("failed: %s %s open error\n", prog_name, victim); - exit(1); - } - - fifo_fd = fd; -} - -void setup_sock(void) -{ - cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cl_sock < 0) - cl_sock = 0; -} - -int check_ack(void) -{ - int error; - char line[256], *mw, *ok; - - memset(line, 0, 256); - - error = read(fifo_fd, line, 256); - if (error < 0) - return error; - if (error == 0) - return 0; - - mw = strstr(line, "meatware"); - ok = strstr(line, "ok"); - - if (!mw || !ok) - return -ENOMSG; - - return 1; -} - -int check_cluster(void) -{ - struct cl_cluster_node cl_node; - int error; - - if (!cl_sock) - return 0; - - memset(&cl_node, 0, sizeof(cl_node)); - - strcpy(cl_node.name, victim); - - error = ioctl(cl_sock, SIOCCLUSTER_GETNODE, &cl_node); - if (error < 0) - return 0; - - if (cl_node.state == NODESTATE_MEMBER || - cl_node.state == NODESTATE_JOINING) - return 1; - - return 0; -} - -void cleanup(void) -{ - memset(fname, 0, 256); - sprintf(fname, "%s/fence_manual.fifo", fifodir); - unlink(fname); -} - -int main(int argc, char **argv) -{ - int rv; - - prog_name = argv[0]; - - get_options(argc, argv); - - if (victim[0] == 0) { - if (!quiet_flag) - printf("failed: %s no node name\n", agent); - exit(1); - } - - lockfile(); - - openlog("fence_manual", 0, LOG_DAEMON); - - syslog(LOG_CRIT, "Node %s needs to be reset before recovery can " - "procede. Waiting for %s to rejoin the cluster " - "or for manual acknowledgement that it has been reset " - "(i.e. fence_ack_manual -n %s)\n", - victim, victim, victim); - - setup_fifo(); - setup_sock(); - - for (;;) { - rv = check_ack(); - if (rv) - break; - - rv = check_cluster(); - if (rv) - break; - - sleep(1); - } - - if (rv < 0) { - if (!quiet_flag) - printf("failed: %s %s rv %d\n", prog_name, victim, rv); - cleanup(); - exit(1); - } else { - if (!quiet_flag) - printf("success: %s %s\n", prog_name, victim); - cleanup(); - exit(0); - } - - return 0; -} - diff --git a/fence/agents/mcdata/Makefile b/fence/agents/mcdata/Makefile deleted file mode 100644 index cf3cd9b..0000000 --- a/fence/agents/mcdata/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_mcdata.pl -TARGET= fence_mcdata - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/mcdata/fence_mcdata.pl b/fence/agents/mcdata/fence_mcdata.pl deleted file mode 100755 index 0ce9f6a..0000000 --- a/fence/agents/mcdata/fence_mcdata.pl +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -# This works on the following firmware versions: -# 01.03.00 -# 02.00.00 -# 04.01.00 -# 04.01.02 - -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -$opt_o = 'disable'; # Default fence action - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of switch\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -n <num> Port number to disable\n"; - print " -o <string> Action: disable (default) or enable\n"; - print " -p <string> Password for login\n"; - print " -S <path> Script to run to retrieve login password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - elsif ($name eq "login" ) - { - $opt_l = $val; - } - elsif ($name eq "option" ) - { - $opt_o = $val; - } - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "passwd_script" ) - { - $opt_S = $val; - } - elsif ($name eq "port" ) - { - $opt_n = $val; - } - - # FIXME should we do more error checking? - # Excess name/vals will be eaten for now - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -sub telnet_error -{ - fail "failed: telnet returned: ".$t->errmsg; -} - -######################################################################33 -# MAIN - -if (@ARGV > 0) { - getopts("a:hl:n:o:p:S:qV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - fail_usage "No '-n' flag specified." unless defined $opt_n; - fail_usage "No '-l' flag specified." unless defined $opt_l; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(disable|enable)$/i; - -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $opt_a; - fail "failed: no plug number" unless defined $opt_n; - fail "failed: no login name" unless defined $opt_l; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail "failed: no password" unless defined $opt_p; - fail "failed: unrecognised action: $opt_o" - unless $opt_o =~ /^(disable|enable)$/i; -} - - -my $block=1; -$_=$opt_o; -if(/disable/) -{ - $block=1 -} -elsif(/enable/) -{ - $block=0 -} -else -{ - fail "failed: unrecognised action: $opt_o" -} - -# -# Set up and log in -# - -$t = new Net::Telnet; - -$t->errmode(&telnet_error); -$t->open($opt_a); - -$t->waitfor('/sername:/'); - -# Send Username -$t->print($opt_l); - -# Send Password -$t->waitfor('/assword:/'); -$t->print($opt_p); -$t->waitfor('/>/'); - -#> # Set switch to comma delimited output -#> $t->print("commadelim 1"); -#> $t->waitfor('/>/'); - -# Block/Unblock the desired port -$t->print("config port blocked $opt_n $block"); -($text, $match) = $t->waitfor('/>/'); - -# Verfiy that the port has been blocked/unblocked -$t->print("config port show $opt_n"); -($text, $match) = $t->waitfor('/>/'); - -# scan the port configurations to make sure that -# the port is in the state we told it to be in -# -# Output from the prvious command will look like: -# -# Root> config port show 0 -# -# Port Information -# Port Number: 0 -# Name: name -# Blocked: true -# Extended Distance: false -# Type: gPort -# -my $fail=1; - -@lines = split /\n/,$text; -foreach my $line (@lines) -{ - my $field = ""; - my $b_state = ""; - - if ( $line =~ /^(.*):\s*(\S*)/ ) - { - $field = $1; - $b_state = $2; - } - next unless ( $field eq "Blocked" ); - if ( ($block && $b_state eq "true") || - (!$block && $b_state eq "false") || - ($block && $b_state eq "Blocked") || - (!$block && $b_state eq "Unblocked") ) - { - $fail = 0; - } - last; -} - -# log out of the switch -$t->print("logout"); -$t->close(); - -if($fail) -{ - print "failed: unexpected port state\n" unless $opt_q; -} -else -{ - print "success: port $opt_n ".($block?"disabled":"enabled")."\n" - unless defined $opt_q; -} - -exit $fail; - - diff --git a/fence/agents/rackswitch/Makefile b/fence/agents/rackswitch/Makefile deleted file mode 100644 index f13ccb5..0000000 --- a/fence/agents/rackswitch/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= fence_rackswitch - -SOURCE= do_rack.c - -top_srcdir=../.. - -ccs_libdir=${top_srcdir}/ccs/lib - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -DFENCE_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -fence_rackswitch: ${SOURCE:.c=.o} - ${CC} ${CFLAGS} ${LDFLAGS} ${SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - - -clean: - rm -f *.o ${TARGET} *~ - diff --git a/fence/agents/rackswitch/do_rack.c b/fence/agents/rackswitch/do_rack.c deleted file mode 100644 index d0e2764..0000000 --- a/fence/agents/rackswitch/do_rack.c +++ /dev/null @@ -1,748 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include "do_rack.h" - -char *pname = "fence_rack"; - -int quiet_flag = 0; -int verbose_flag = 0; -int debug_flag = 0; - -char ipaddr[256]; -char portnumber[256]; -char username[256]; -char password[256]; -char arg[256]; -char name[256]; -char pwd_script[PATH_MAX] = { 0, }; - -char readbuf[MAXBUF]; -char writebuf[MAXBUF]; -int sock; - -char op_login = 0x7e; /* 126*/ -char op_action = 0x66; /* 102 */ -char ack_login = 0x7D; /* 125 */ - -char action_idle = 0x00; -char action_reset = 0x01; -char action_off = 0x02; -char action_offon = 0x03; - -char configuration_request = 0x5b; /* 91 */ -char config_reply = 0x5c; /* 92 */ -char config_general = 0x01; -char config_section1 = 0x02; -char config_section2 = 0x03; -char config_section3 = 0x04; - -char message_status = 0x65; /* 101 */ - -char login_deny = 0xFF; - -int time_out = 60; - -void ignore_message_status(void); -int wait_frame(char); - -/* - * scan input, waiting for a given frame - */ -int wait_frame(char frame_id) -{ - int read_more = 1; - int success = 0; - int n; - char target = frame_id; - - if(debug_flag){printf("%s: Looking for frametype 0x%.2x\n",name,target);} - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); - if(debug_flag){printf("%s: Found frametype 0x%.2x\n",name,readbuf[0]);} - if(readbuf[0] == target){ - read_more = 0; - success = 1; - } - else{ - if(readbuf[0] == message_status){ - ignore_message_status(); - read_more = 1; - } - else{ - if(debug_flag){printf("%s: Got unexpected frame from switch\n",name);} - read_more = 0; - success = 0; - } - } - } - return(success); -} - -void ignore_message_status(void) -{ - int n,i; - int read_more = 1; - int number_of_temp; - int number_of_config_mobo; - - if(debug_flag){printf("%s: Ignoring message-status\n",name);} - read_more=1; - while(read_more){ - n = read(sock,readbuf,1); /* status */ - if(n == 1) - read_more = 0; - } - - read_more = 1; - while(read_more){ /* Date & time */ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - - read_more = 1; - number_of_temp = 0; - n = read(sock,readbuf,1); /* Temprature Input count */ - number_of_temp = (int)readbuf[0]; - - for(i=0;i<number_of_temp;i++){ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); /* Temprature input ID */ - n = read(sock,readbuf,8); /* Temprature Value, Fahrenheit */ - n = read(sock,readbuf,8); /* Temprature Vaule, Celcius */ - n = read(sock,readbuf,1); /* Temprature Alarm */ - } - } - number_of_config_mobo = 0; - for(i=4;i>0;i--){ - read_more = 1; - while(read_more){ - n=read(sock,readbuf,1); - if(n == 1){ - read_more = 0; - number_of_config_mobo = number_of_config_mobo + (int)(readbuf[0]<<(8*(i-1))); - } - } - } - for(i=0;i<number_of_config_mobo;i++){ - n = read(sock,readbuf,4); /* Motherboard ID */ - n = read(sock,readbuf,1); /* Motherboard status */ - } -} - - - -void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options]\n" - "\n" - "Options:\n" - " -h usage\n" - " -a <ip> IP address for RackSwitch\n" - " -n <dec num> Physical plug number on RackSwitch\n" - " -l <string> Username\n" - " -p <string> Password\n" - " -S <path> Script to retrieve password\n" - " -v Verbose\n" - " -q Quiet\n" - " -V Version information\n", pname); -} - - - -void get_options(int argc, char **argv) -{ - int c; - char *value; - - if (argc > 1){ - /* - * Command line input - */ - while ((c = getopt(argc, argv, "ha:n:l:p:S:vqVd")) != -1) - { - switch(c) - { - case 'h': - print_usage(); - exit(DID_SUCCESS); - - case 'a': - strncpy(ipaddr,optarg,254); - break; - - case 'n': - strncpy(portnumber,optarg,254); - break; - - case 'l': - strncpy(username,optarg,254); - break; - - case 'p': - strncpy(password,optarg,254); - break; - - case 'S': - strncpy(pwd_script, optarg, sizeof(pwd_script)); - pwd_script[sizeof(pwd_script) - 1] = '\0'; - break; - - case 'v': - verbose_flag = 1; - break; - - case 'q': - quiet_flag = 1; - break; - - case 'd': - debug_flag = 1; - break; - - case 'V': - printf("%s %s (built %s %s)\n", pname, FENCE_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(DID_SUCCESS); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(DID_FAILURE); - break; - - default: - fprintf(stderr, "Bad programmer! You forgot to catch the %c flag\n", c); - exit(DID_FAILURE); - break; - - } - } - strcpy(name, pname); - } - else{ - errno = 0; - while(fgets(arg, 256, stdin) != NULL){ - if( (value = strchr(arg, '\n')) == NULL){ - fprintf(stderr, "line too long: '%s'\n", arg); - exit(DID_FAILURE); - } - *value = 0; - if( (value = strchr(arg, '=')) == NULL){ - fprintf(stderr, "invalid input: '%s'\n", arg); - exit(DID_FAILURE); - } - *value = 0; - value++; - /* bahfuck. "agent" is not passed to us anyway - * if (!strcmp(arg, "agent")){ - * strcpy(name, value); - * pname = name; - *} - */ - strcpy(name, pname); - if (!strcmp(arg, "ipaddr")) - strcpy(ipaddr, value); - - if (!strcmp(arg, "portnumber")) - strcpy(portnumber, value); - - if (!strcmp(arg, "username")) - strcpy(username, value); - - if (!strcmp(arg, "password")) - strcpy(password, value); - - if (!strcasecmp(arg, "passwd_script")) { - strncpy(pwd_script, optarg, sizeof(pwd_script)); - pwd_script[sizeof(pwd_script) - 1] = '\0'; - } - } - errno = 0; - - } - - if (pwd_script[0] != '\0') { - FILE *fp; - char pwd_buf[1024]; - - fp = popen(pwd_script, "r"); - if (fp != NULL) { - ssize_t len = fread(pwd_buf, 1, sizeof(pwd_buf), fp); - if (len > 0) { - char *p; - p = strchr(pwd_buf, '\n'); - if (p != NULL) - *p = '\0'; - p = strchr(pwd_buf, '\r'); - if (p != NULL) - *p = '\0'; - strncpy(password, pwd_buf, sizeof(password)); - password[sizeof(password) - 1] = '\0'; - } - pclose(fp); - } - } -} - -static void sig_alarm(int sig) -{ - if(!quiet_flag){ - fprintf(stderr,"failed: %s: Timeout, nothing happened for %d seconds.\n", pname, time_out); - fprintf(stderr,"failed: %s: Perhaps you should inspect the RackSwitch at %s\n",pname,ipaddr); - } - exit(DID_FAILURE); -} - - -int main(int argc, char **argv) -{ - int n,i,j,pnumb; - int ip_portnumber = 1025; - char boardnum = 0x00; - /*char number_of_action = 0x01;*/ - int number_of_config_mobo = 0; - int number_of_section_config_mobo = 0; - int exit_status= 0; - int success_off = 0; - /*int success_on = 0;*/ - int read_more = 1; - struct sockaddr_in rackaddr; - - /*char mobo_enabled = 0x01;*/ - /*char mobo_default_status = 0x00;*/ - /*char mobo_output_status = 0x00;*/ - int this_mobo = 0; - /*int mobo_id = 0;*/ - /*int our_mobo = 0;*/ - int number_of_temp = 0; - - memset(arg, 0, 256); - memset(name, 0, 256); - memset(ipaddr, 0, 256); - memset(portnumber,0,256); - memset(username,0,256); - memset(password,0,256); - - /* - * Ensure that we always get out of the fencing agent - * even if things get fucked up and we get no replies - */ - signal(SIGALRM, &sig_alarm); - alarm(time_out); - get_options(argc, argv); - - if(name[0] == '\0') - { - if(!quiet_flag) - fprintf(stderr,"failed: no name for this program\n"); - exit(DID_FAILURE); - } - - if(ipaddr[0] == '\0') - { - if(!quiet_flag) - fprintf(stderr,"failed: %s, no IP address given\n",name); - exit(DID_FAILURE); - } - if (portnumber[0] == '\0') - { - if(!quiet_flag) - fprintf(stderr,"failed: %s, no portnumber given\n",name); - exit(DID_FAILURE); - } - if (username[0] == '\0') - { - if(!quiet_flag) - fprintf(stderr,"failed: %s, no username given\n",name); - exit(DID_FAILURE); - } - - if (password[0] == '\0') - { - if(!quiet_flag) - fprintf(stderr,"failed: %s, no password given\n",name); - exit(DID_FAILURE); - } - /* - * Port number given to us as a string. - * Does the number make sense? - */ - pnumb = 0; - for(n=0;(portnumber[n]!='\0');n++){ - if((portnumber[n] < 48) || (portnumber[n] > 57)){ - if(!quiet_flag) - fprintf(stderr,"failed: %s, invalid port number\n",name); - exit(1); - } - pnumb = ((pnumb * 10) + ((int)(portnumber[n]) - 48)); - } - /* - * what section of the rack is this port part of? - * The switch has 4 "subsections", called boardnum here - */ - if((pnumb > 0) && (pnumb < 47)) - boardnum = 0x02; - if((pnumb > 46) && (pnumb < 94)) - boardnum = 0x03; - if((pnumb > 93) && (pnumb < 137)) - boardnum = 0x04; - if((pnumb < 1) || (pnumb> 136)){ - boardnum = 0x00; - if(!quiet_flag) - fprintf(stderr,"failed: %s, the portnumber given is not in the range [1 - 136]\n",name); - exit(DID_FAILURE); - } - /********************************************* - *** - *** set up TCP connection to the rackswitch - *** - ********************************************/ - if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0){ - fprintf(stderr,"failed: %s: socket error, %s\n",name,strerror(errno)); - exit(DID_FAILURE); - } - - bzero(&rackaddr,sizeof(rackaddr)); - rackaddr.sin_family = AF_INET; - rackaddr.sin_port = htons(ip_portnumber); - - if(inet_pton(AF_INET,ipaddr,&rackaddr.sin_addr) <= 0){ - fprintf(stderr,"failed: %s: inet_pton error\n", name); - } - - if(connect(sock,(SA *) &rackaddr,sizeof(rackaddr)) < 0){ - fprintf(stderr,"failed: %s: connect error to %s, %s\n", name, ipaddr,strerror(errno)); - exit(DID_FAILURE); - } - /********************************************** - *** - *** Send Login Frame - *** - *********************************************/ - writebuf[0] = op_login; - - for(n=0;n<=(strlen(username));n++){ - writebuf[sizeof(char)+n] = username[n]; - } - writebuf[sizeof(char)+(strlen(username))+1] ='\n'; - - for(n=0;n<=(strlen(password))+1;n++){ - writebuf[sizeof(char)+strlen(username)+1+n] = password[n]; - } - writebuf[sizeof(char)+(strlen(username))+1+(strlen(password))+1] ='\n'; - - write(sock,writebuf,sizeof(char)+strlen(username)+strlen(password)+2); - - /******************************************** - *** - *** Read Login Reply - *** - *******************************************/ - if(wait_frame(ack_login)){ - n=read(sock,readbuf,1); - if(readbuf[0] == login_deny){ - if(!quiet_flag){fprintf(stderr,"failed: %s: Not able to log into RackSwitch\n",name);} - exit(DID_FAILURE); - } - else{ - if(verbose_flag){printf("%s: Successfully logged into RackSwitch\n",name);} - } - } - - /******************************************** - *** - *** Send Configuration Request Message - *** - *******************************************/ - - writebuf[0] = configuration_request; - writebuf[1] = config_general; - write(sock,writebuf,2*(sizeof(char))); - - /******************************************** - *** - *** Read General Configuration Message - *** - *******************************************/ - - if(wait_frame(config_reply)){ - n = read(sock,readbuf,1); - if(readbuf[0] == config_general){ - - /* Configuration Status, one byte */ - n = read(sock,readbuf,1); - - /* Switch description, string */ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - - /* Serial number, string */ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - - /* Version number, string */ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - - /* number of configured temps, 1 byte */ - number_of_temp = 0; - n = read(sock,readbuf,1); - number_of_temp = (int)readbuf[0]; - - for(i=0;i<number_of_temp;i++){ - - /* Temprature description, string */ - read_more = 1; - while(read_more){ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - } - - n = read(sock,readbuf,1); /* Temprature input ID */ - n = read(sock,readbuf,1); /* Tempratue unit */ - n = read(sock,readbuf,8); /* Temprature HI alarm */ - n = read(sock,readbuf,8); /* Temprature LO alarm */ - n = read(sock,readbuf,1); /* Temprature HI Alarm */ - n = read(sock,readbuf,1); /* Temprature LO Alarm */ - n = read(sock,readbuf,1); /* Temprature Alarm email */ - } - /* Number of configured motherboards */ - number_of_config_mobo = 0; - for(i=4;i>0;i--){ - read_more = 1; - while(read_more){ - n=read(sock,readbuf,1); - if(n == 1){ - read_more = 0; - number_of_config_mobo = number_of_config_mobo + (int)(readbuf[0]<<(8*(i-1))); - } - } - } - /* - * make sure the motherboard we are asked to turn of is configured - */ - if(pnumb > number_of_config_mobo){ - if(!quiet_flag){ - fprintf(stderr,"failed: %s asked to reboot port %d, but there are only %d ports configured\n",name,pnumb,number_of_config_mobo); - exit(DID_FAILURE); - } - } - n = read(sock,readbuf,1); /* email alarms */ - n = read(sock,readbuf,4); /* email alarm delay */ - - /* email addresses, string */ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - - n = read(sock,readbuf,4); /* reset action duration */ - n = read(sock,readbuf,4); /* power off action duration */ - n = read(sock,readbuf,4); /* power on action duration */ - } - else{ - if(debug_flag){fprintf(stderr,"failed: %s: Did not receive general configuration frame when requested\n",name);} - exit(DID_FAILURE); - } - } - else{ - if(debug_flag){fprintf(stderr,"failed: %s: Did not receive configuration frame when requested\n",name);} - exit(DID_FAILURE); - } - - - - /****************************************** - *** - *** Send Action packet to switch - *** Off/On port <portnum> - *** - *****************************************/ - memset(writebuf,0,sizeof(writebuf)); - writebuf[0] = op_action; - writebuf[1] = (char)(number_of_config_mobo >> 24); - writebuf[2] = (char)(number_of_config_mobo >> 16); - writebuf[3] = (char)(number_of_config_mobo >> 8); - writebuf[4] = (char)(number_of_config_mobo); - - writebuf[(pnumb*5)+0] = (char)(pnumb >> 24); - writebuf[(pnumb*5)+1] = (char)(pnumb >> 16); - writebuf[(pnumb*5)+2] = (char)(pnumb >> 8); - writebuf[(pnumb*5)+3] = (char)(pnumb); - writebuf[(pnumb*5)+4] = action_offon; - - write(sock,writebuf,(pnumb*5)+5); - if(verbose_flag){ - printf("%s: sending action frame to switch:\n",name); - for(i=0;i<(pnumb*5)+5;i++) - printf("0x%.2x ",writebuf[i]); - printf("\n"); - } - - /****************************************** - *** - *** Send Configuration Request packet to switch - *** - *****************************************/ - memset(writebuf,0,sizeof(writebuf)); - writebuf[0] = configuration_request; - writebuf[1] = boardnum; - - write(sock,writebuf,2*(sizeof(char))); - if(verbose_flag){ - printf("%s: sending Request Configuration Frame from switch:\n",name); - printf("0x%.2x 0x%.2x\n",writebuf[0],writebuf[1]); - } - - /******************************************* - *** - *** Read Switch Status Message - *** - ******************************************/ - while(success_off == 0){ - if(debug_flag){ - printf("%s: Status does not indicate port %d being rebooted. Looking again\n",name,pnumb);} - if(wait_frame(message_status)){ - n = read(sock,readbuf,1); /* Rackswitch status */ - - read_more = 1; - while(read_more){ /* Date & time */ - n = read(sock,readbuf,1); - if(readbuf[0] == '\0'){ - read_more = 0; - } - else{ - read_more = 1; - } - } - number_of_temp = 0; - n = read(sock,readbuf,1); - number_of_temp = readbuf[0]; - for(i=0;i<number_of_temp;i++){ - read_more = 1; - while(read_more){ - n = read(sock,readbuf,1); /* Temprature input ID */ - n = read(sock,readbuf,8); /* Temprature Value, Fahrenheit */ - n = read(sock,readbuf,8); /* Temprature Vaule, Celcius */ - n = read(sock,readbuf,1); /* Temprature Alarm */ - } - } - - /* number of motherboards, 4 byte */ - number_of_section_config_mobo = 0; - for(i=4;i>0;i--){ - read_more = 1; - while(read_more){ - n=read(sock,readbuf,1); - if(n == 1){ - read_more = 0; - number_of_section_config_mobo = number_of_section_config_mobo + (int)(readbuf[0]<<(8*(i-1))); - } - } - } - - for(i=0;i<number_of_section_config_mobo;i++){ - - this_mobo = 0; - for(j=4;j>0;j--){ - read_more = 1; - while(read_more){ - n=read(sock,readbuf,1); - if(n == 1){ - read_more = 0; - this_mobo = this_mobo + (int)(readbuf[0]<<(8*(j-1))); - } - } - } - if(debug_flag){printf("%s: port %d is currently ",name,this_mobo);} - n = read(sock,readbuf,1); /* Motherboard status */ - if(debug_flag){printf("0x%.2x\n",readbuf[0]);} - if((pnumb == this_mobo) && ((readbuf[0] == 0x02)||(readbuf[0] == 0x03))){ - success_off = 1; - if(verbose_flag){printf("%s: Status shows port %d being rebooted\n",name,this_mobo);} - } - } /* end number_of_section_mobo loop */ - if(!success_off){ - if(verbose_flag){printf("%s: Status shows port %d NOT being rebooted, asking for status again\n",name,pnumb);} - } - } - else{ - if(debug_flag){fprintf(stderr,"%s: Did not receive Switch Status Message\n",name);} - exit(DID_FAILURE); - } - } - - - if(success_off){ - if(!quiet_flag){ - printf("success: %s: successfully told RackSwitch to reboot port %d\n",name,pnumb); - } - alarm(0); - exit_status = DID_SUCCESS; - } - return(exit_status); -} -/* And that is it. There is no more. - * Maybe there should be more? - * Or maybe not? - * But there is no more - */ diff --git a/fence/agents/rackswitch/do_rack.h b/fence/agents/rackswitch/do_rack.h deleted file mode 100644 index 613a021..0000000 --- a/fence/agents/rackswitch/do_rack.h +++ /dev/null @@ -1,31 +0,0 @@ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> - -#include <sys/socket.h> -#include <sys/types.h> - -#include <linux/net.h> -#include <linux/fs.h> -#include <linux/socket.h> -/*#include <linux/in.h>*/ -#include <arpa/inet.h> - -#include <signal.h> - -#include "copyright.cf" - -#define SA struct sockaddr - - -#define MAXBUF 1200 - -#define DID_SUCCESS 0 -#define DID_FAILURE 1 - diff --git a/fence/agents/rps10/Makefile b/fence/agents/rps10/Makefile deleted file mode 100644 index f68ff47..0000000 --- a/fence/agents/rps10/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= fence_rps10 - -fence_rps10_SOURCE= rps10.c - -top_srcdir=../.. - - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -DFENCE_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -fence_rps10: ${fence_rps10_SOURCE:.c=.o} - ${CC} ${CFLAGS} ${LDFLAGS} ${fence_rps10_SOURCE:.c=.o} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/fence/agents/rps10/rps10.c b/fence/agents/rps10/rps10.c deleted file mode 100644 index 08efd94..0000000 --- a/fence/agents/rps10/rps10.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Fencing agent for WTI RPS-10 (serial) power devices. Based on - * the fence_apc agent from linux-cluster, and the prb utility (which - * controls RPS-10s and PRB-5 rev 1 remote power switches). - * - * Only works in 2-node clusters because of the requirement that each node - * be able to fence each other node. This driver does not support using the - * 'all ports' directive; cluster machines with multiple power supplies will - * need to have their configuration updated accordingly if they are upgrading - * from clumanager 1.0.x or 1.2.x. - */ -#include <stdio.h> -#include <termios.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/select.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <sys/ioctl.h> -#include <libgen.h> -#include "copyright.cf" - - -/* - * Salt to taste. - */ -#define DEFAULT_DEVICE "/dev/ttyS0" -#define DEFAULT_SPEED B9600 -#define RPS10_CMD_STR "\x02\x18\x18\x02\x18\x18%d%c\r" - - -/** - Open a serial port and lock it. - */ -int -open_port(char *file, int speed) -{ - struct termios ti; - int fd; - struct flock lock; - - if ((fd = open(file, O_RDWR | O_EXCL)) == -1) { - perror("open"); - return -1; - } - - memset(&lock,0,sizeof(lock)); - lock.l_type = F_WRLCK; - if (fcntl(fd, F_SETLK, &lock) == -1) { - perror("Failed to lock serial port"); - close(fd); - return -1; - } - - memset(&ti, 0, sizeof(ti)); - ti.c_cflag = (speed | CLOCAL | CRTSCTS | CREAD | CS8); - - if (tcsetattr(fd, TCSANOW, &ti) < 0) { - perror("tcsetattr"); - close(fd); - return -1; - } - - tcflush(fd, TCIOFLUSH); - - return fd; -} - - -/** - Toggle data terminal ready (basically, hangup). This will cause the RPS-10 - to print a "RPS-10 Ready" message. - */ -void -hangup(int fd, int delay) -{ - unsigned int bits; - - if (ioctl(fd, TIOCMGET, &bits)) { - perror("ioctl1"); - return; - } - - bits &= ~(TIOCM_DTR | TIOCM_CTS | TIOCM_RTS | TIOCM_DSR | TIOCM_CD); - - if (ioctl(fd, TIOCMSET, &bits)) { - perror("ioctl2"); - return; - } - - usleep(delay); - - bits |= (TIOCM_DTR | TIOCM_CTS | TIOCM_RTS | TIOCM_DSR | TIOCM_CD); - - if (ioctl(fd, TIOCMSET, &bits)) { - perror("ioctl3"); - return; - } -} - - -int -char_to_speed(char *speed) -{ - if (!strcmp(speed, "300")) - return B300; - if (!strcmp(speed, "1200")) - return B1200; - if (!strcmp(speed, "2400")) - return B2400; - if (!strcmp(speed, "9600")) - return B9600; - return -1; -} - - -void -usage_exit(char *pname) -{ -printf("usage: %s <options>\n", pname); -printf(" -n <#> Specify RPS-10 port number <#>. Default=0\n" - " Valid ports: 0-9\n"); -printf(" -d <device> Use serial device <dev>. Default=%s\n", - DEFAULT_DEVICE); -printf(" -s <speed> Use speed <speed>. Default=9600\n" - " Valid speeds: 300, 1200, 2400, 9600\n"); -printf(" -o <op> Operation to perform.\n"); -printf(" Valid operations: on, off, [reboot]\n"); -printf(" -V Print version and exit\n"); -printf(" -v Verbose mode\n\n"); -printf("If no options are specified, the following options will be read\n"); -printf("from standard input (one per line):\n\n"); -printf(" port=<#> Same as -n\n"); -printf(" device=<dev> Same as -d\n"); -printf(" speed=<speed> Same as -s\n"); -printf(" option=<op> Same as -o\n"); -printf(" operation=<op> Same as -o\n"); -printf(" action=<op> Same as -o\n"); -printf(" verbose Same as -v\n\n"); - exit(1); -} - - -/** - Perform an operation on an RPS-10. - */ -int -rps10_port_op(int fd, int port, char cmd) -{ - char buf[30]; - - snprintf(buf, sizeof(buf), RPS10_CMD_STR, port, cmd); - if (write(fd, buf, strlen(buf)) != strlen(buf)) - return -1; - - return 0; -} - - -/** - Toggle = ^B^X^X^B^X^X<port>T^M - */ -int -rps10_toggle_port(int fd, int port) -{ - return rps10_port_op(fd, port, 'T'); -} - - -/** - Power-off = ^B^X^X^B^X^X<port>0^M - */ -int -rps10_port_off(int fd, int port) -{ - return rps10_port_op(fd, port, '0'); -} - - -/** - Power-on = ^B^X^X^B^X^X<port>1^M - */ -int -rps10_port_on(int fd, int port) -{ - return rps10_port_op(fd, port, '1'); -} - - -/** - Super-simple expect code. - */ -int -wait_for(int fd, char *what, int timeout) -{ - char *wp, *wend, c; - struct timeval tv; - fd_set rfds; - int l; - - if (!what) - return -1; - - l = strlen(what); - - if (!l) - return -1; - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - wp = what; - wend = what + l; - - while (wp != wend) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - switch(select(fd+1, &rfds, NULL, NULL, &tv)) { - case -1: - return -1; - case 0: - errno = ETIMEDOUT; - return -1; - } - - if (read(fd, &c, 1) == -1) - return -1; - - if (*wp == c) - wp++; - else - wp = what; - } - - return 0; -} - - -/** - Remove leading and trailing whitespace from a line of text. - */ -int -cleanup(char *line, size_t linelen) -{ - char *p; - int x; - - /* Remove leading whitespace. */ - p = line; - for (x = 0; x <= linelen; x++) { - switch (line[x]) { - case '\t': - case ' ': - break; - case '\n': - case '\r': - return -1; - default: - goto eol; - } - } -eol: - /* Move the remainder down by as many whitespace chars as we - chewed up */ - if (x) - memmove(p, &line[x], linelen-x); - - /* Remove trailing whitespace. */ - for (x=0; x <= linelen; x++) { - switch(line[x]) { - case '\t': - case ' ': - case '\r': - case '\n': - line[x] = 0; - case 0: - /* End of line */ - return 0; - } - } - - return -1; -} - - -/** - Parse args from stdin. Dev + devlen + op + oplen must be valid. - */ -int -get_options_stdin(char *dev, size_t devlen, int *speed, int *port, - char *op, size_t oplen, int *verbose) -{ - char in[256]; - int line = 0; - char *name, *val; - - while (fgets(in, sizeof(in), stdin)) { - ++line; - - if (in[0] == '#') - continue; - - if (cleanup(in, sizeof(in)) == -1) - continue; - - name = in; - if ((val = strchr(in, '='))) { - *val = 0; - ++val; - } - - if (!strcasecmp(name, "agent")) { - /* Used by fenced? */ - } else if (!strcasecmp(name, "verbose")) { - *verbose = 1; - } else if (!strcasecmp(name, "device")) { - /* Character device to use. E.g. /dev/ttyS0 */ - if (val) - strncpy(dev, val, devlen); - else - dev[0] = 0; - - } else if (!strcasecmp(name, "port")) { - /* Port number */ - if (val) - *port = atoi(val); - else - *port = -1; - - } else if (!strcasecmp(name, "speed")) { - /* Speed in bits per second */ - if (val) - *speed = char_to_speed(val); - else - *speed = -1; - } else if (!strcasecmp(name, "option") || - !strcasecmp(name, "operation") || - !strcasecmp(name, "action")) { - if (val) - strncpy(op, val, oplen); - else - op[0] = 0; - } else { - fprintf(stderr, - "parse error: illegal name on line %d\n", - line); - return 1; - } - } - - return 0; -} - - -/** - Print a message to stderr and call exit(1). - */ -void -fail_exit(char *msg) -{ - fprintf(stderr, "failed: %s\n", msg); - exit(1); -} - - -int -main(int argc, char **argv) -{ - int fd, speed = DEFAULT_SPEED, opt, ret = 1; - extern char *optarg; - char dev[256]; - char op[256]; - int port = 0, verbose=0; - char *pname = basename(argv[0]); - - strncpy(dev, DEFAULT_DEVICE, sizeof(dev)); - strncpy(op, "reboot", sizeof(op)); - - if (argc > 1) { - /* - Parse command line options if any were specified - */ - while ((opt = getopt(argc, argv, "s:d:n:ro:vV?hH")) != EOF) { - switch(opt) { - case 's': - /* Speed */ - speed = char_to_speed(optarg); - if (speed == -1) - usage_exit(pname); - - break; - case 'd': - /* Device to open */ - strncpy(dev, optarg, sizeof(dev)); - break; - case 'n': - port = atoi(optarg); - break; - case 'o': - /* Operation */ - strncpy(op, optarg, sizeof(op)); - break; - case 'v': - verbose++; - break; - case 'V': - printf("%s %s (built %s %s)\n", pname, - FENCE_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", - REDHAT_COPYRIGHT); - return 0; - default: - usage_exit(pname); - } - } - } else { - /* - No command line args? Get stuff from stdin - */ - if (get_options_stdin(dev, sizeof(dev), &speed, &port, - op, sizeof(op), &verbose) != 0) - return 1; - } - - /* - Validate the operating parameters - */ - if (strlen(dev) == 0) - fail_exit("no device specified"); - - if (speed == -1) - fail_exit("invalid serial port speed"); - - if (strcasecmp(op, "off") && strcasecmp(op, "on") && - strcasecmp(op, "reboot")) { - fail_exit("operation must be 'on', 'off', or 'reboot'"); - } - - if ((port < 0) && (port != 9)) - fail_exit("port must be between 0 and 9, inclusive"); - - /* - Open the serial port up - */ - fd = open_port(dev, speed); - if (fd == -1) - exit(1); - - if (verbose) { - printf("Toggling DTR..."); - fflush(stdout); - } - hangup(fd, 500000); - if (verbose) - printf("Done\n"); - - /* - Some misc. RPS-10s return PRS for some reason... - */ - if (verbose) { - printf("Waiting for Ready signal..."); - fflush(stdout); - } - if (wait_for(fd, "S-10 Ready", 10) == -1) { - perror("wait_for"); - return -1; - } - if (verbose) - printf("Done\n"); - - /* - Perform the requested operation - */ - if (!strcasecmp(op, "reboot")) { - printf("Rebooting port %d...", port); - fflush(stdout); - if (rps10_toggle_port(fd, port) < 0) - goto out; - - if (wait_for(fd, " Off", 10) < 0) - goto out; - - /* turning on doesn't require a failure check */ - if (wait_for(fd, " On", 10) != 0) - printf("<warn: " - "Plug %d might still be off>", port); - - ret = 0; - - } else if (!strcasecmp(op, "on")) { - printf("Powering on port %d...", port); - fflush(stdout); - if (rps10_port_on(fd, port) < 0) - goto out; - - if (wait_for(fd, " On", 10) < 0) - goto out; - - ret = 0; - - } else if (!strcasecmp(op, "off")) { - printf("Powering off port %d...", port); - fflush(stdout); - if (rps10_port_off(fd, port) < 0) - goto out; - - if (wait_for(fd, " Off", 10) < 0) - goto out; - - ret = 0; - } - -out: - if (ret == 0) - printf("Done\n"); - else - printf("Failed\n"); - return ret; -} diff --git a/fence/agents/rsa/Makefile b/fence/agents/rsa/Makefile deleted file mode 100644 index 1252056..0000000 --- a/fence/agents/rsa/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_rsa.py -TARGET= fence_rsa - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_rsa: fence_rsa.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py deleted file mode 100755 index e54133c..0000000 --- a/fence/agents/rsa/fence_rsa.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/python - -##### -## -## The Following Agent Has Been Tested On: -## Main GFEP25A & Boot GFBP25A -## -##### - -import sys, re, pexpect, exceptions -sys.path.append("@FENCEAGENTSLIBDIR@") -from fencing import * - -#BEGIN_VERSION_GENERATION -RELEASE_VERSION="New RSA2 Agent - test release on steroids" -REDHAT_COPYRIGHT="" -BUILD_DATE="March, 2009" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - try: - conn.send("power state\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - status = re.compile("Power: (.*)", re.IGNORECASE).search(conn.before).group(1) - return status.lower().strip() - -def set_power_status(conn, options): - try: - conn.send("power " + options["-o"] + "\r\n") - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "cmd_prompt", "secure" ] - - options = check_input(device_opt, process_input(device_opt)) - - ## - ## Fence agent specific defaults - ##### - if 0 == options.has_key("-c"): - options["-c"] = ">" - - # This device will not allow us to login even with LANG=C - options["ssh_options"] = "-F /dev/null" - - ## - ## Operate the fencing device - ###### - conn = fence_login(options) - fence_action(conn, options, set_power_status, get_power_status, None) - - ## - ## Logout from system - ###### - try: - conn.sendline("exit") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/rsb/Makefile b/fence/agents/rsb/Makefile deleted file mode 100644 index 32fc244..0000000 --- a/fence/agents/rsb/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_rsb.py -TARGET= fence_rsb - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -fence_rsb: fence_rsb.py - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py deleted file mode 100755 index ecb830d..0000000 --- a/fence/agents/rsb/fence_rsb.py +++ /dev/null @@ -1,387 +0,0 @@ -#!/usr/bin/python - -############################################################################### -############################################################################### -## -## Copyright (C) 2006 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -import getopt, sys -import os -import socket -import time - -from telnetlib import Telnet - -TELNET_TIMEOUT=30 #How long to wait for a response from a telnet try -MAX_TRIES = 20 - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def usage(): - print "Usage:" - print "fence_rsb [options]" - print "Options:" - print " -a <ipaddress> ip or hostname of rsb" - print " -h print out help" - print " -l [login] login name" - print " -n [telnet port] telnet port" - print " -p [password] password" - print " -S [path] script to run to retrieve password" - print " -o [action] Reboot (default), Off, On, or Status" - print " -v Verbose Verbose mode" - print " -V Print Version, then exit" - - sys.exit (0) - -def version(): - print "fence_rsb %s %s\n" % (FENCE_RELEASE_NAME, BUILD_DATE) - print "%s\n" % REDHAT_COPYRIGHT - sys.exit(0) - -def main(): - depth = 0 - POWER_OFF = 0 - POWER_ON = 1 - POWER_STATUS = 2 - POWER_REBOOT = 3 - - power_command_issued = 0 - - address = "" - login = "" - passwd = "" - passwd_script = "" - action = POWER_REBOOT #default action - telnet_port = 3172 - verbose = False - power_state = None - - standard_err = 2 - - #set up regex list - USERNAME = 0 - PASSWORD = 1 - PROMPT = 2 - STATE = 3 - ERROR = 4 - CONT = 5 - CONFIRM = 6 - DONE = 7 - - regex_list = list() - regex_list.append("user name\s*:") - regex_list.append("pass phrase\s*:") - regex_list.append("[Ee]nter\s+[Ss]election[^\r\n]*:") - regex_list.append("[pP]ower Status:") - regex_list.append("[Ee]rror\s*:") - regex_list.append("[Pp]ress any key to continue") - regex_list.append("really want to") - regex_list.append("CLOSING TELNET CONNECTION") - - if len(sys.argv) > 1: - try: - opts, args = getopt.getopt(sys.argv[1:], "a:hl:n:o:p:S:vV", ["help", "output="]) - except getopt.GetoptError: - #print help info and quit - usage() - sys.exit(2) - - for o, a in opts: - if o == "-v": - verbose = True - if o == "-V": - version() - if o in ("-h", "--help"): - usage() - sys.exit(0) - if o == "-l": - login = a - if o == "-n": - telnet_port = a - if o == "-p": - passwd = a - if o == "-S": - passwd_script = a - if o == "-o": - if a == "Off" or a == "OFF" or a == "off": - action = POWER_OFF - elif a == "On" or a == "ON" or a == "on": - action = POWER_ON - elif a == "Status" or a == "STATUS" or a == "status": - action = POWER_STATUS - elif a == "Reboot" or a == "REBOOT" or a == "reboot": - action = POWER_REBOOT - else: - usage() - sys.exit(1) - if o == "-a": - address = a - if address == "" or login == "" or (passwd == "" and passwd_script == ""): - usage() - sys.exit(1) - - else: #Take args from stdin... - params = {} - #place params in dict - for line in sys.stdin: - val = line.split("=") - if len(val) == 2: - params[val[0].strip()] = val[1].strip() - - try: - address = params["ipaddr"] - except KeyError, e: - os.write(standard_err, "FENCE: Missing ipaddr param for fence_rsb...exiting") - sys.exit(1) - - try: - login = params["login"] - except KeyError, e: - os.write(standard_err, "FENCE: Missing login param for fence_rsb...exiting") - sys.exit(1) - - try: - if 'passwd' in params: - passwd = params["passwd"] - if 'passwd_script' in params: - passwd_script = params['passwd_script'] - if passwd == "" and passwd_script == "": - raise "missing password" - except KeyError, e: - os.write(standard_err, "FENCE: Missing passwd param for fence_rsb...exiting") - sys.exit(1) - - try: - telnet_port = params["telnet_port"] - except KeyError, e: - pass - - try: - a = params["option"] - if a == "Off" or a == "OFF" or a == "off": - action = POWER_OFF - elif a == "On" or a == "ON" or a == "on": - action = POWER_ON - elif a == "Reboot" or a == "REBOOT" or a == "reboot": - action = POWER_REBOOT - except KeyError, e: - action = POWER_REBOOT - - ####End of stdin section - - - # retrieve passwd from passwd_script (if specified) - passwd_scr = '' - if len(passwd_script): - try: - if not os.access(passwd_script, os.X_OK): - raise 'script not executable' - p = os.popen(passwd_script, 'r', 1024) - passwd_scr = p.readline().strip() - if p.close() != None: - raise 'script failed' - except: - sys.stderr.write('password-script "%s" failed\n' % passwd_script) - passwd_scr = '' - - if passwd == "" and passwd_scr == "": - sys.stderr.write('password not available, exiting...') - sys.exit(1) - elif passwd == passwd_scr: - pass - elif passwd and passwd_scr: - # execute self, with password_scr as passwd, - # if that fails, continue with "passwd" argument as password - if len(sys.argv) > 1: - comm = sys.argv[0] - skip_next = False - for w in sys.argv[1:]: - if skip_next: - skip_next = False - elif w in ['-p', '-S']: - skip_next = True - else: - comm += ' ' + w - comm += ' -p ' + passwd_scr - ret = os.system(comm) - if ret != -1 and os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == 0: - # success - sys.exit(0) - else: - sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n') - else: # use stdin - p = os.popen(sys.argv[0], 'w', 1024) - for par in params: - if par not in ['passwd', 'passwd_script']: - p.write(par + '=' + params[par] + '\n') - p.write('passwd=' + passwd_scr + '\n') - p.flush() - if p.close() == None: - # success - sys.exit(0) - else: - sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n') - elif passwd_scr: - passwd = passwd_scr - # passwd all set - - - - try: - telnet_port = int(telnet_port) - except: - os.write(standard_err, ("FENCE: Invalid telnet port: %s\n" % telnet_port)) - sys.exit(1) - - ##Time to open telnet session and log in. - try: - sock = Telnet(address.strip(), telnet_port) - except socket.error, (errno, msg): - my_msg = "FENCE: A problem was encountered opening a telnet session with " + address - os.write(standard_err, my_msg) - os.write(standard_err, ("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))) - os.write(standard_err, "Firewall issue? Correct address?\n") - sys.exit(1) - - if verbose: - #sock.set_debuglevel(10000) - print "socket open to %s %d\n" % (address, telnet_port) - - tries = MAX_TRIES - while 1: - i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT) - if i == ERROR: - os.write(standard_err,("FENCE: An error was encountered when communicating with the rsb device at %s" % address)) - buf = sock.read_eager() - os.write(standard_err,("FENCE: The error message is - %s" % txt + " " + buf)) - sock.close() - sys.exit(1) - - buf = sock.read_eager() - if i == USERNAME: - if verbose: - print "Sending login: %s\n" % login - sock.write(login + "\r") - - elif i == PASSWORD: - if verbose: - print "Sending password: %s\n" % passwd - sock.write(passwd + "\r") - - elif i == CONT: - if verbose: - print "Sending continue char..." - sock.write("\r") - time.sleep(2) - - elif i == CONFIRM: - if verbose: - print "Confirming..." - sock.write("yes\r") - - elif i == PROMPT: - if verbose: - print "Evaluating prompt...\n" - - if depth == 0: - sock.write("2\r") - depth += 1 - elif depth == 1: - if action == POWER_OFF or action == POWER_REBOOT: - if power_command_issued == 0: - if verbose: - print "Sending power off %s" % address - sock.write("1\r") - power_command_issued += 1 - time.sleep(2) - elif power_command_issued and power_state == 0: - if verbose: - print "Power off was successful" - if action == POWER_OFF: - depth += 1 - sock.write("0\r") - else: - action = POWER_ON - power_command_issued = 0 - sock.write("\r") - elif tries > 0: - if verbose: - print "Waiting for power off to complete" - tries -= 1 - sock.write("\r") - time.sleep(2) - else: - os.write(standard_err, "FENCE: Unable to power off server") - depth += 1 - sock.write("0\r") - - elif action == POWER_ON: - if power_command_issued == 0: - if verbose: - print "Sending power on %s" % address - sock.write("4\r") - power_command_issued += 1 - time.sleep(2) - elif power_command_issued and power_state == 1: - if verbose: - print "Power on was successful" - depth += 1 - sock.write("0\r") - elif tries > 0: - if verbose: - print "Waiting for power on to complete" - tries -= 1 - sock.write("\r") - time.sleep(2) - else: - os.write(standard_err, "FENCE: Unable to power on server") - depth += 1 - sock.write("0\r") - else: - sock.write("0\r") - - elif i == STATE: - if buf.find(" On") != (-1): - power_state = 1 - elif buf.find(" Off") != (-1): - power_state = 0 - else: - power_state = None - - if action == POWER_STATUS: - if verbose: - print "Determining power state..." - if power_state == 1: - print "Server is On" - elif power_state == 0: - print "Server is Off" - else: - os.write(standard_err, ("FENCE: Cannot determine power state: %s" % buf)) - sys.exit(1) - depth = 2 - - elif i == DONE: - break - - else: - sock.write("\r") - - sock.close() - -if __name__ == "__main__": - main() diff --git a/fence/agents/sanbox2/Makefile b/fence/agents/sanbox2/Makefile deleted file mode 100644 index 489c64f..0000000 --- a/fence/agents/sanbox2/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_sanbox2.py -TARGET= fence_sanbox2 - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py deleted file mode 100644 index 7e7c9b3..0000000 --- a/fence/agents/sanbox2/fence_sanbox2.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/python - -##### -## -## The Following Agent Has Been Tested On: -## -## Version Firmware -## +-----------------+---------------------------+ -##### - -import sys, re, pexpect -sys.path.append("@FENCEAGENTSLIBDIR@") -from fencing import * - -#BEGIN_VERSION_GENERATION -RELEASE_VERSION="New Sanbox2 Agent - test release on steroids" -REDHAT_COPYRIGHT="" -BUILD_DATE="March, 2008" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - status_trans = { - 'online' : "on", - 'offline' : "off" - } - try: - conn.send("show port " + options["-n"] + "\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - try: - conn.send("admin end\n") - conn.send("exit\n") - conn.close() - except: - pass - fail(EC_TIMED_OUT) - - status = re.compile(".*AdminState\s+(online|offline)\s+", re.IGNORECASE | re.MULTILINE).search(conn.before).group(1) - - try: - return status_trans[status.lower().strip()] - except KeyError: - return "PROBLEM" - -def set_power_status(conn, options): - action = { - 'on' : "online", - 'off' : "offline" - }[options["-o"]] - - try: - conn.send("set port " + options["-n"] + " state " + action + "\n") - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - try: - conn.send("admin end\n") - conn.send("exit\n") - conn.close() - except: - pass - fail(EC_TIMED_OUT) - - try: - conn.send("set port " + options["-n"] + " state " + action + "\n") - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - try: - conn.send("admin end\n") - conn.send("exit\n") - conn.close() - except: - pass - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "io_fencing", "ipaddr", "login", "passwd", "passwd_script", - "cmd_prompt", "port", "login_eol_lf" ] - - options = check_input(device_opt, process_input(device_opt)) - - ## - ## Fence agent specific defaults - ##### - if 0 == options.has_key("-c"): - options["-c"] = [ " #> " ] - - ## - ## Operate the fencing device - ## - conn = fence_login(options) - - conn.send("admin start\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - - if (re.search("(admin)", conn.before, re.MULTILINE) == None): - ## Someone else is in admin section, we can't enable/disable - ## ports so we will rather exit - sys.stderr.write("Failed: Unable to switch to admin section\n") - sys.exit(EC_GENERIC_ERROR) - - fence_action(conn, options, set_power_status, get_power_status) - - ## - ## Logout from system - ###### - try: - conn.send("admin end\n") - conn.send("exit\n") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/scsi/Makefile b/fence/agents/scsi/Makefile deleted file mode 100644 index b11407a..0000000 --- a/fence/agents/scsi/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2006 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_scsi.pl -TARGET= fence_scsi -SCRIPT= scsi_reserve - -TEST_SOURCE= fence_scsi_test.pl -TEST_TARGET= fence_scsi_test - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) $(TEST_TARGET) - -fence_scsi: fence_scsi.pl - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -fence_scsi_test: fence_scsi_test.pl - : > $(TEST_TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(TEST_SOURCE) >> $(TEST_TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TEST_TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TEST_TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TEST_TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(TEST_SOURCE) >> $(TEST_TARGET) - chmod +x $(TEST_TARGET) - -copytobin: ${TARGET} ${TEST_TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - cp ${TEST_TARGET} ${top_srcdir}/bin/${TEST_TARGET} - -clean: - rm -f $(TARGET) $(TEST_TARGET) diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl deleted file mode 100755 index 7ab621e..0000000 --- a/fence/agents/scsi/fence_scsi.pl +++ /dev/null @@ -1,401 +0,0 @@ -#!/usr/bin/perl - -use Getopt::Std; -use XML::LibXML; -use POSIX; - -my $ME = $0; - -END { - defined fileno STDOUT or return; - close STDOUT and return; - warn "$ME: failed to close standard output: $!\n"; - $? ||= 1; -} - -my @device_list; - -$_ = $0; -s/.*///; -my $pname = $_; - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -sub usage -{ - print "Usage\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options\n"; - print " -n <node> IP address or hostname of node to fence\n"; - print " -h usage\n"; - print " -V version\n"; - print " -v verbose\n"; - - exit 0; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub fail -{ - ($msg)=@_; - - print $msg."\n" unless defined $opt_q; - - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - - exit 1; -} - -sub get_cluster_id -{ - my $cluster_id; - - my $cmd = "cman_tool status"; - my @out = qx { $cmd }; - - die "Unable to execute cman_tool.\n" if ($?>>8); - - foreach (@out) - { - chomp; - - my ($param, $value) = split(/\s*:\s*/, $_); - - if ($param =~ /^cluster\s+id/i) { - $cluster_id = $value; - last; - } - } - - print "[$pname]: get_cluster_id: cluster_id=$cluster_id\n" if $opt_v; - - return $cluster_id; -} - -sub get_node_id -{ - ($node)=@_; - - my $xml = XML::LibXML->new(); - my $tree = $xml->parse_file("/etc/cluster/cluster.conf"); - - my $xpath = "//cluster/clusternodes/clusternode[@name='$node']/@nodeid"; - - my $node_id = $tree->findvalue($xpath); - - print "[$pname]: get_node_id ($node): node_id=$node_id\n" if $opt_v; - - return $node_id; -} - -sub get_node_name -{ - print "[$pname]: get_hode_name: node_name=$opt_n\n" if $opt_v; - - return $opt_n; -} - -sub get_host_id -{ - my $host_id; - - my $cmd = "cman_tool status"; - my @out = qx { $cmd }; - - die "Unable to execute cman_tool.\n" if ($?>>8); - - foreach (@out) - { - chomp; - - my ($param, $value) = split(/\s*:\s*/, $_); - - if ($param =~ /^node\s+id/i) { - $host_id = $value; - last; - } - } - - print "[$pname]: get_host_id: host_id=$host_id\n" if $opt_v; - - return $host_id; -} - -sub get_host_name -{ - my $host_name; - - my $cmd = "cman_tool status"; - my @out = qx { $cmd }; - - die "Unable to execute cman_tool.\n" if ($?>>8); - - foreach (@out) - { - chomp; - - my ($param, $value) = split(/\s*:\s*/, $_); - - if ($param =~ /^node\s+name/i) { - $host_name = $value; - last; - } - } - - print "[$pname]: get_host_name: host_name=$host_name\n" if $opt_v; - - return $host_name; -} - -sub get_key -{ - ($node)=@_; - - my $cluster_id = get_cluster_id; - my $node_id = get_node_id($node); - - if ($node_id == 0) { - die "Unable to determine nodeid for $node.\n"; - } - - my $key = sprintf "%x%.4x", $cluster_id, $node_id; - - print "[$pname]: get_key ($node): key=$key\n" if $opt_v; - - return $key; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - - while (defined($in = <>)) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line += 1; - $opt = $_; - - next unless $opt; - - ($name, $val) = split(/\s*=\s*/, $opt); - - if ($name eq "") - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - elsif ($name eq "agent") - { - } - elsif ($name eq "node") - { - $opt_n = $val; - } - elsif ($name eq "nodename") - { - $opt_n = $val; - } - elsif ($name eq "verbose") - { - $opt_v = $val; - } - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -sub get_key_list -{ - ($dev) = @_; - - my $cmd = "sg_persist -d $dev -i -k"; - my @out = qx { $cmd }; - - die "Unable to execute sg_persist.\n" if ($?>>8); - - my %key_list; - - foreach (@out) - { - chomp; - - if ($_ =~ /^\s*0x/) - { - s/^\s+0x//; - s/\s+$//; - - $key_list{$_} = undef; - } - } - - # DEBUG: use -v option - # - if ($opt_v) - { - my $count = keys %key_list; - my $index = 0; - - print "[$pname]: get_key_list: found $count keys registered with $dev\n"; - - for $key (keys %key_list) - { - print "[$pname]: ($index) key=$key\n"; - $index++; - } - } - - return %key_list; -} - -sub get_scsi_devices -{ - my $cmd = "vgs --config 'global { locking_type = 0 }'" . - " --noheadings --separator : -o vg_attr,pv_name"; - - my @out = qx { $cmd 2> /dev/null}; - - die "Unable to execute vgs.\n" if ($?>>8); - - foreach (@out) - { - chomp; - - my ($vg_attrs, $dev) = split(/:/, $_); - - if ($vg_attrs =~ /.*c$/) - { - $dev =~ s/(.*)//; - push(@device_list, $dev); - } - } - - # DEBUG: use -v flag - # - if ($opt_v) - { - my $count = scalar @device_list; - my $index = 0; - - print "[$pname]: get_scsi_devices: found $count devices\n"; - - for $dev (@device_list) - { - print "[$pname]: ($index) dev=$dev\n"; - $index++; - } - } -} - -sub check_sg_persist -{ - my $cmd = "sg_persist -V"; - my $out = qx { $cmd }; - - die "Unable to execute sg_persist.\n" if ($?>>8); -} - -sub fence_node -{ - my $host_name = get_host_name(); - my $node_name = get_node_name(); - - my $host_key = get_key($host_name); - my $node_key = get_key($node_name); - - my ($in, $out, $err); - - foreach $dev (@device_list) - { - my %key_list = get_key_list($dev); - - # DEBUG: use -v option - # - if ($opt_v) - { - print "[$pname]: unregister key 0x$node_key from device $dev\n"; - } - - if (! exists $key_list{$host_key}) - { - fail "Unable to perform fence operation."; - } - - if (! exists $key_list{$node_key}) - { - next; - } - - if ($host_key eq $node_key) - { - $cmd = "sg_persist -n -d $dev -o -G -K $host_key -S 0"; - } - else - { - $cmd = "sg_persist -n -d $dev -o -A -K $host_key -S $node_key -T 5"; - } - - my $out = qx { $cmd }; - - die "Unable to execute sg_persist ($dev).\n" if ($?>>8); - } -} - -### MAIN ####################################################### - -if (@ARGV > 0) { - - getopts("n:hqvV") || fail_usage; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-n' flag specified." unless defined $opt_n; - -} else { - - get_options_stdin(); - - fail "failed: missing 'node'" unless defined $opt_n; - -} - -check_sg_persist; - -get_scsi_devices; - -fence_node; diff --git a/fence/agents/scsi/fence_scsi_test.pl b/fence/agents/scsi/fence_scsi_test.pl deleted file mode 100755 index 59e65f9..0000000 --- a/fence/agents/scsi/fence_scsi_test.pl +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/perl - -use POSIX; -use IPC::Open3; -use XML::LibXML; -use Getopt::Std; - -my @devices; -my %results; - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - -sub get_scsi_block_devices -{ - my $block_dir = "/sys/block"; - - opendir(DIR, $block_dir) or die "$!\n"; - - my @block_devices = grep { /^sd*/ } readdir(DIR); - - closedir(DIR); - - for $block_dev (@block_devices) - { - push(@devices, "/dev/" . $block_dev); - } -} - -sub get_cluster_vol_devices -{ - my ($in, $out, $err); - - my $cmd = "vgs --config 'global { locking_type = 0 }'" . - " --noheadings --separator : -o vg_attr,pv_name"; - - my $pid = open3($in, $out, $err, $cmd) or die "$!\n"; - - waitpid($pid, 0); - - die "[error] unable to execute vgs command.\n" if WEXITSTATUS($?); - - while (<$out>) - { - chomp; - - my ($vg_attr, $pv_name) = split(/:/, $_); - - if ($vg_attr =~ /.*c$/) - { - ###### DEBUG ###### - print "DEBUG: pv_name = $pv_name\n"; - - push(@devices, $pv_name); - } - } - - close($in); - close($out); - close($err); -} - -sub register_device -{ - my ($dev, $key) = @_; - my ($in, $out, $err); - - my $cmd = "sg_persist -n -d $dev -o -G -S $key"; - my $pid = open3($in, $out, $err, $cmd) or die "$!\n"; - - waitpid($pid, 0); - - $results{$dev}[0] = WEXITSTATUS($?); - - close($in); - close($out); - close($err); -} - -sub unregister_device -{ - my ($dev, $key) = @_; - my ($in, $out, $err); - - my $cmd = "sg_persist -n -d $dev -o -G -K $key -S 0"; - my $pid = open3($in, $out, $err, $cmd) or die "$!\n"; - - waitpid($pid, 0); - - $results{$dev}[1] = WEXITSTATUS($?); - - close($in); - close($out); - close($err); -} - -sub test_devices -{ - my $key = "0xDEADBEEF"; - - foreach $dev (@devices) - { - register_device($dev, $key); - unregister_device($dev, $key); - } -} - -sub check_config_fence -{ - my $xml = XML::LibXML->new(); - my $tree = $xml->parse_file("/etc/cluster/cluster.conf"); - my $root = "//cluster/fencedevices/fencedevice"; - - my $xpath_fence = "count(${root}[@agent='fence_scsi'])"; - - return ( ! $tree->findvalue($xpath_fence)); -} - -sub check_config_nodes -{ - my $xml = XML::LibXML->new(); - my $tree = $xml->parse_file("/etc/cluster/cluster.conf"); - my $root = "//cluster/clusternodes/clusternode"; - - my $xpath_name = "count(${root}/@name)"; - my $xpath_nodeid = "count(${root}/@nodeid)"; - - return ($tree->findvalue($xpath_name) != $tree->findvalue($xpath_nodeid)); -} - -sub print_results -{ - my $device_count = scalar(@devices); - - my $failure_count = 0; - my $success_count = 0; - - print "\nAttempted to register with devices:\n"; - print "-------------------------------------\n"; - - for $dev (@devices) - { - print "\t$dev\t"; - if ($results{$dev}[0] == 0) - { - $success_count++; - print "Success\n"; - } - else - { - $failure_count++; - print "Failure\n"; - } - } - - print "-------------------------------------\n"; - print "Number of devices tested: $device_count\n"; - print "Number of devices passed: $success_count\n"; - print "Number of devices failed: $failure_count\n\n"; - - if ($failure_count != 0) - { - exit(1); - } -} - -sub print_usage -{ - print "\nUsage: fence_scsi_test [-c|-s] [-d] [-h]\n\n"; - - print "Options:\n\n"; - - print " -c Cluster mode. This mode is intended to test\n"; - print " SCSI persistent reservation capabilties for\n"; - print " devices that are part of existing clustered\n"; - print " volumes. Only devices in LVM cluster volumes\n"; - print " will be tested.\n\n"; - print " -s SCSI mode. This mode is intended to test SCSI\n"; - print " persistent reservation capabilities for all SCSI\n"; - print " devices visible on a node.\n\n"; - print " -d Debug flag. This will print debugging information\n"; - print " such as the actual commands being run to register\n"; - print " and unregister a device.\n\n"; - print " -h Help. Prints out this usage information.\n\n"; -} - -sub test_tools_path -{ - my $tool_name = "sg_persist"; - - for my $path ( split /:/, $ENV{PATH} ) { - if ( -f "$path/$tool_name" && -x _ ) { - return; - } - } - - die "No $tool_name command available, please install the sg3_utils package.\n" -} - -### MAIN ####################################################################### - -test_tools_path; - -if (getopts("cdhst:v") == 0) -{ - print_usage; - exit(1); -} - -if ($opt_h) -{ - print_usage; - exit(0); -} - -if ($opt_c) -{ - print "\nTesting devices in cluster volumes...\n"; - get_cluster_vol_devices; - test_devices; - print_results; -} - -if ($opt_s) -{ - print "\nTesting all SCSI block devices...\n"; - get_scsi_block_devices; - test_devices; - print_results; -} - -if ($opt_t) -{ - if ($opt_t eq "fence") - { - exit check_config_fence; - } - if ($opt_t eq "nodes") - { - exit check_config_nodes; - } -} - -if (!$opt_c && !$opt_s && !$opt_t) -{ - print "\nPlease specify either cluster or SCSI mode.\n"; - print_usage; - exit(1); -} diff --git a/fence/agents/scsi/scsi_reserve b/fence/agents/scsi/scsi_reserve deleted file mode 100755 index 34f25e5..0000000 --- a/fence/agents/scsi/scsi_reserve +++ /dev/null @@ -1,303 +0,0 @@ -#!/bin/bash -# -# scsi_reserve: -# -# chkconfig: 345 25 75 -# description: start/stop persistent reservation service for lvm -# config: /etc/sysconfig/scsi_reserve - -. /etc/init.d/functions - -# read in config file if it exists -# -if [ -f /etc/sysconfig/scsi_reserve ] ; then - . /etc/sysconfig/scsi_reserve -fi - -# check if cluster is configured for fence_scsi -# -if ! fence_scsi_test -t fence ; then - logger -t scsi_reserve \ - "[error] cluster not configured for scsi reservations" - exit 1 -fi - -# check for nodeids in config file -# -if ! fence_scsi_test -t nodes ; then - logger -t scsi_reserve \ - "[error] cluster must define nodeid for all nodes" - exit 1 -fi - -# check for sg_persist command provided by sg3_utils package -# -if ! sg_persist -V &> /dev/null ; then - logger -t scsi_reserve \ - "[error] unable to exec sg_persist" - exit 1 -fi - -# check that cman is running -# -if ! cman_tool status &> /dev/null ; then - logger -t scsi_reserve \ - "[error] cman does not appear to be running" - exit 1 -fi - -# get physical volumes (devices) that are part of cluster volumes -# -scsi_devices=$( vgs --config 'global { locking_type = 0 }' \ - --noheadings -o vg_attr,pv_name 2> /dev/null \ - | awk ' $1 ~ /.*c$/ { print $2 } ' ) - -if [ -z "$scsi_devices" ] ; then - logger -t scsi_reserve \ - "[error] did not find devices in cluster volumes" - exit 1 -fi - -# get the cluster id from cman -# -cluster_id=$( cman_tool status | grep -i "Cluster ID" \ - | awk -F": " '{ print $2 }' ) - -if [ -z "$cluster_id" ] ; then - logger -s -t scsi_reserve \ - "[error] unable to determine cluster id" - exit 1 -fi - -# get the node id from cman -# -node_id=$( cman_tool status | grep -i "Node ID" \ - | awk -F": " '{ print $2 }' ) - -if [ -z "$node_id" ] ; then - logger -t scsi_reserve \ - "[error] unable to determine node id" - exit 1 -fi - -# generate unique key using cluster_id and node_id -# -key=$( printf "%x%.4x" $cluster_id $node_id ) - -if [ -z "$key" ] ; then - logger -t scsi_reserve \ - "[error] unable to generate key" - exit 1 -fi - -################################################################################ - -case $1 in - - start) - - error=0 - count=0 - - echo -n "Starting scsi_reserve:" - - for dev in $scsi_devices - do - # check if our key is already resgistered with this device - # - if sg_persist -n -d $dev -i -k | grep -qiE "^[[:space:]]*0x$key" ; then - logger -t scsi_reserve \ - "[info] already registered with $dev (key=0x$key)" - continue - fi - - # create the scsi registration - # - if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then - logger -t scsi_reserve \ - "[error] unable to register device $dev (key=0x$key)" - : $[ count = $count + 1 ] - error=1 - else - logger -t scsi_reserve \ - "[info] registered with device $dev (key=0x$key)" - fi - - # check to see if reservation already exists - # - if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then - logger -t scsi_reserve \ - "[info] reservation already exists on $dev" - continue - fi - - # create the scsi reservation - # - if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then - logger -t scsi_reserver \ - "[error] unable to create reservation on $dev (key=0x$key)" - : $[ count = $count + 1 ] - error=1 - fi - done - - # leave fence domain if any errors occured during registration - # - if [ $error -eq 0 ] ; then - success - else - logger -t scsi_reserve \ - "[info] $count errors during registration" - logger -t scsi_reserve \ - "[info] leaving the fence domain" - fence_tool leave - failure - fi - - echo - - ;; # end of start - - stop) - - error=0 - count=0 - - echo -n "Stopping scsi_reserve:" - - for dev in $scsi_devices - do - # get list of keys registered with this device - # - key_list=$( sg_persist -n -d $dev -i -k | grep -iE "^[[:space:]]*0x" ) - - # check that our key is registered with this device - # - if ! sg_persist -d $dev -i -k | grep -qiE "^[[:space:]]*0x$key" ; then - logger -t scsi_reserve \ - "[info] not registered with $dev (key=0x$key)" - continue - fi - - # check if our key is the reservation holder - # - if sg_persist -n -d $dev -i -r 2>/dev/null | grep -qiE "$key" ; then - if echo "$key_list" | grep -qivE "$key" ; then - logger -t scsi_reserve \ - "[error] unable to remove registration on $dev (key=0x$key)" - : $[ count = $count + 1 ] - error=1 - continue - fi - fi - - # remove registration for this device - # - if ! sg_persist -n -d $dev -o -G -K $key -S 0 &> /dev/null ; then - logger -t scsi_reserve \ - "[error] failed to remove registration on $dev (key=0x$key)" - : $[ count = $count + 1 ] - error=1 - else - logger -t scsi_reserve \ - "[info] removed registration on $dev (key=0x$key)" - fi - - done - - # report success or failure - # - if [ $error -eq 0 ] ; then - success - else - logger -t scsi_reserve \ - "[info] $count errors occured during unregistration" - failure - fi - - echo - - ;; # end of stop - - restart) - - error=0 - - echo -n "Retarting scsi_reserve:" - - for dev in $scsi_devices - do - # recreate the scsi registration - # - if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then - logger -t scsi_reserve \ - "[error] unable to register device $dev (key=0x$key)" - : $[ count = $count + 1 ] - error=1 - else - logger -t scsi_reserve \ - "[info] registered with device $dev (key=0x$key)" - fi - - # check to see if reservation already exists - # - if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then - logger -t scsi_reserve \ - "[info] reservation already exists on $dev" - continue - fi - - # recreate the scsi reservation - # - if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then - logger -t scsi_reserver \ - "[error] unable to create reservation on $dev (key=0x$key)" - : $[ count = $count + 1 ] - error=1 - fi - done - - # leave fence domain if any errors occured during registration - # - if [ $error -eq 0 ] ; then - success - else - logger -t scsi_reserve \ - "[info] $count errors during registration" - logger -t scsi_reserve \ - "[info] leaving the fence domain" - fence_tool leave - failure - fi - - echo - - ;; # end of restart - - status) - - error=0 - - for dev in $scsi_devices - do - if sg_persist -n -d $dev -i -k | grep -qiE "$key" ; then - devices[${#devices[@]}]=$dev - fi - done - - if [ -z "$devices" ] ; then - echo "No registered devices found." - else - echo "Found ${#devices[@]} registered device(s):" - - for i in "${devices[@]}" - do - echo $i - done - fi - - ;; # end of status - -esac - -exit $error diff --git a/fence/agents/vixel/Makefile b/fence/agents/vixel/Makefile deleted file mode 100644 index f7e9041..0000000 --- a/fence/agents/vixel/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_vixel.pl -TARGET= fence_vixel - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/vixel/fence_vixel.pl b/fence/agents/vixel/fence_vixel.pl deleted file mode 100755 index 4a82df3..0000000 --- a/fence/agents/vixel/fence_vixel.pl +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n\n"; - print "$pname [options]\n\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of switch\n"; - print " -h Usage\n"; - print " -n <num> Port number to disable\n"; - print " -p <string> Password for login\n"; - print " -S <path> Script to run to retrieve login password\n"; - print " -V version\n\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg) = @_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -if (@ARGV > 0) { - getopts("a:hn:p:S:V") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - fail_usage "No '-n' flag specified." unless defined $opt_n; - -} else { - get_options_stdin(); - - fail "failed: no IP address for the Vixel." unless defined $opt_a; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail "failed: no password provided." unless defined $opt_p; - fail "failed: no port number specified." unless defined $opt_n; -} - -# -# Set up and log in -# - -$t = new Net::Telnet; - -$t->open($opt_a); - -$t->waitfor('/assword:/'); - -$t->print($opt_p); - -($out, $match)= $t->waitfor(Match => '/>/', Match => '/assword:/'); - -if ($match =~ /assword:/) { - fail "failed: incorrect password\n"; -} elsif ( $match !~ />/ ) { - fail "failed: timed out waiting for prompt\n"; -} - -$t->print("config"); - -$t->waitfor('/(config)>/'); - -$t->print("zone"); - -$t->waitfor('/(config/zone)>/'); - -# -# Do the command -# - -$cmd = "config $opt_n """; -$t->print($cmd); - -$t->waitfor('/(config/zone)>/'); - -$t->print("apply"); - -($text, $match) = $t->waitfor('/>/'); -if ($text !~ /[Oo][Kk]/) { - fail "failed: error from switch\n"; -} - -$t->print("exit"); - -print "success: zonedisable $opt_n\n"; -exit 0; - - -sub get_options_stdin -{ - my $opt; - my $line = 0; - - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) { - print("parse error: illegal name in option $line\n"); - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - # FIXME -- depricated. use "port" instead. - elsif ($name eq "fm" ) { - (my $dummy,$opt_n) = split /\s+/,$val; - print STDERR "Depricated "fm" entry detected. refer to man page.\n"; - } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - - elsif ($name eq "name" ) { } - - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "passwd_script" ) - { - $opt_S = $val; - } - - elsif ($name eq "port" ) - { - $opt_n = $val; - } - - # FIXME should we do more error checking? - # Excess name/vals will be eaten for now - else - { - fail "parse error: unknown option: $opt"; - #> exit 2; - } - } -} - diff --git a/fence/agents/wti/Makefile b/fence/agents/wti/Makefile deleted file mode 100644 index 50d6672..0000000 --- a/fence/agents/wti/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_wti.py -TARGET= fence_wti - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) - echo "BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - diff --git a/fence/agents/wti/fence_wti.pl b/fence/agents/wti/fence_wti.pl deleted file mode 100755 index 8ae45af..0000000 --- a/fence/agents/wti/fence_wti.pl +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use Net::Telnet (); - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of NPS\n"; - print " -h usage\n"; - print " -n <num> Physical plug number on NPS\n"; - print " -p <string> Password if NPS requires one\n"; - print " -S <path> Script to run to retrieve login password\n"; - print " -o <operation> Operation to perform (on, off, reboot)\n"; - print " -q quiet mode\n"; - print " -T test reports state of plug (no power cycle)\n"; - print " -V Version\n"; - - exit 0; -} - -sub fail -{ - ($msg)=@_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -$opt_o = "reboot"; -if (@ARGV > 0) { - getopts("a:hn:p:S:qTVo:") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - fail_usage "No '-n' flag specified." unless defined $opt_n; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $opt_a; - fail "failed: no plug number" unless defined $opt_n; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail "failed: no password" unless defined $opt_p; -} - -$t = new Net::Telnet; - -$t->open($opt_a); - -$expr = '/:|\n/'; - -while (1) -{ - ($line, $match) = $t->waitfor($expr); - - if ($line =~ /assword/) - { - fail "failed: no password" unless defined $opt_p; - $t->print($opt_p); - $expr = '/\n/'; - } - - elsif ($line =~ /v\d.\d+/) - { - $line =~ /\D*(\d).(\d+).*/; - $ver1 = $1; - $ver2 = $2; - - $t->waitfor('/(TPS|IPS|RPC|NPS|NBB)>/'); - last; - } -} - - -if (defined $opt_T) -{ - &test($t); - exit 0; -} - - -# to be most certain of success, turn off, check for OFF status, turn ON, check -# for ON status -if (($opt_o eq "off") || ($opt_o eq "reboot")) { - $t->print("/off $opt_n"); - ($line, $match) = $t->waitfor('/(Y/N)|(TPS|IPS|RPC|NPS|NBB)>/'); - - if ($match =~ /Y/N/) - { - $t->print("y"); - $t->waitfor('/(TPS|IPS|RPC|NPS|NBB)>/'); - } - - $t->print("/s"); - - while (1) - { - ($line, $match) = $t->waitfor('/\n|(TPS|IPS|RPC|NPS|NBB)>/'); - - if ($match =~ /(TPS|IPS|RPC|NPS|NBB)>/) - { - print "failed: plug number "$opt_n" not found\n" - unless defined $opt_q; - exit 1; - } - - $line =~ /^\s+(\d+).*/; - - if ($1 == $opt_n) - { - # For (TPS|IPS|RPC|NPS) - if($line =~ /^\s+(\d+)\s+|\s+\S+\s+|\s+(\w+).*/){ - $state = $2; - # For NBB - } elsif($line =~ /^\s+(\d+)\s+|\s+\S+\s+|\s+\S+\s+|\s+(\w+).*/){ - $state = $2; - } - - if ($state =~ /OFF/) - { - $t->waitfor('/(TPS|IPS|RPC|NPS|NBB)>/'); - last; - } - - print "failed: plug not off ($state)\n" - unless defined $opt_q; - exit 1; - } - } -} - - -# at this point, failing to turn the machine back on shouldn't be a failure - -if (($opt_o eq "on") || ($opt_o eq "reboot")) { - sleep 5; - $t->print("/on $opt_n"); - ($line, $match) = $t->waitfor('/(Y/N)|(TPS|IPS|RPC|NPS|NBB)>/'); - - if ($match =~ /Y/N/) - { - $t->print("y"); - $t->waitfor('/(TPS|IPS|RPC|NPS|NBB)>/'); - } - - $t->print("/s"); - - while (1) - { - ($line, $match) = $t->waitfor('/\n|(TPS|IPS|RPC|NPS|NBB)>/'); - - if ($match =~ /(TPS|IPS|RPC|NPS|NBB)>/) - { - print "success: plug-on warning\n" - unless defined $opt_q; - exit 0; - } - - $line =~ /^\s+(\d+).*/; - - if ($1 == $opt_n) - { - # For (TPS|IPS|RPC|NPS) - if($line =~ /^\s+(\d+)\s+|\s+\S+\s+|\s+(\w+).*/){ - $state = $2; - # For NBB - } elsif($line =~ /^\s+(\d+)\s+|\s+\S+\s+|\s+\S+\s+|\s+(\w+).*/){ - $state = $2; - } - - if ($state =~ /ON/) - { - $t->waitfor('/(TPS|IPS|RPC|NPS|NBB)>/'); - last; - } - - print "success: plug state warning ($state)\n" - unless defined $opt_q; - - exit 0; - } - } -} - -print "success: $opt_o operation on plug $opt_n\n" unless defined $opt_q; - -exit 0; - - - -sub test -{ - local($t) = @_; - - $t->print("/s"); - - while (1) - { - ($line, $match) = $t->waitfor('/\n|(TPS|IPS|RPC|NPS|NBB)>/'); - - if ($match =~ /(TPS|IPS|RPC|NPS|NBB)>/) - { - print "failed: plug number "$opt_n" not found\n" - unless defined $opt_q; - exit 1; - } - - $line =~ /^\s+(\d+).*/; - - if ($1 == $opt_n) - { - # For (TPS|IPS|RPC|NPS) - if($line =~ /^\s+(\d+)\s+|\s+\S+\s+|\s+(\w+).*/){ - $state = $2; - # For NBB - } elsif($line =~ /^\s+(\d+)\s+|\s+\S+\s+|\s+\S+\s+|\s+(\w+).*/){ - $state = $2; - } - - if ($state =~ /ON|OFF/) - { - print "success: current plug state "$state"\n" - unless defined $opt_q; - } - - else - { - print "failed: unknown plug state "$state"\n" - unless defined $opt_q; - } - - last; - } - } -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - # FIXME -- deprecated. use "port" instead. - elsif ($name eq "fm" ) - { - (my $dummy,$opt_n) = split /\s+/,$val; - print STDERR "Deprecated "fm" entry detected. refer to man page.\n"; - } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - - # FIXME -- depreicated residue of old fencing system - elsif ($name eq "name" ) { } - - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "passwd_script" ) - { - $opt_S = $val; - } - elsif ($name eq "port" ) - { - $opt_n = $val; - } - elsif ($name eq "option" ) - { - $opt_o = $val; - } - # elsif ($name eq "test" ) - # { - # $opt_T = $val; - # } - - # FIXME should we do more error checking? - # Excess name/vals will be eaten for now - else - { - fail "parse error: unknown option "$opt"\n"; - } - } -} diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py deleted file mode 100755 index f43f88b..0000000 --- a/fence/agents/wti/fence_wti.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/python - -## -## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. -## -## The Following Agent Has Been Tested On: -## -## Version Firmware -## +-----------------+---------------------------+ -## WTI RSM-8R4 ?? unable to find out ?? -## WTI MPC-??? ?? unable to find out ?? -## WTI IPS-800-CE v1.40h (no username) -##### - -import sys, re, pexpect, exceptions -sys.path.append("/usr/lib/fence") -from fencing import * - -#BEGIN_VERSION_GENERATION -FENCE_RELEASE_NAME="" -REDHAT_COPYRIGHT="" -BUILD_DATE="" -#END_VERSION_GENERATION - -def get_power_status(conn, options): - try: - conn.send("/S"+"\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - - plug_section = 0 - for line in conn.before.splitlines(): - if (plug_section == 2) and line.find("|") >= 0: - plug_line = [x.strip().lower() for x in line.split("|")] - if len(plug_line) < len(plug_header): - plug_section = -1 - pass - if options["-n"].lower() == plug_line[plug_index]: - return plug_line[status_index] - elif (plug_section == 1): - plug_section = 2 - pass - elif (line.upper().startswith("PLUG")): - plug_section = 1 - plug_header = [x.strip().lower() for x in line.split("|")] - plug_index = plug_header.index("plug") - status_index = plug_header.index("status") - - return "PROBLEM" - -def set_power_status(conn, options): - action = { - 'on' : "/on", - 'off': "/off" - }[options["-o"]] - - try: - conn.send(action + " " + options["-n"] + ",y\r\n") - conn.log_expect(options, options["-c"], POWER_TIMEOUT) - except pexpect.EOF: - fail(EC_CONNECTION_LOST) - except pexpect.TIMEOUT: - fail(EC_TIMED_OUT) - -def main(): - device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", - "action", "ipaddr", "login", "passwd", "passwd_script", - "cmd_prompt", "secure", "port", "no_login", "no_password", - "test" ] - - options = check_input(device_opt, process_input(device_opt)) - - ## - ## Fence agent specific defaults - ##### - if 0 == options.has_key("-c"): - options["-c"] = [ "RSM>", "MPC>", "IPS>" ] - - ## - ## Operate the fencing device - ## - ## @note: if it possible that this device does not need either login, password or both of them - ##### - if 0 == options.has_key("-x"): - try: - try: - conn = fspawn('%s %s' % (TELNET_PATH, options["-a"])) - except pexpect.ExceptionPexpect, ex: - sys.stderr.write(str(ex) + "\n") - sys.stderr.write("Due to limitations, binary dependencies on fence agents " - "are not in the spec file and must be installed separately." + "\n") - sys.exit(EC_GENERIC_ERROR) - - re_login = re.compile("(login: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE) - re_prompt = re.compile("|".join(map (lambda x: "(" + x + ")", options["-c"])), re.IGNORECASE) - - result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], SHELL_TIMEOUT) - if result == 0: - if options.has_key("-l"): - conn.send(options["-l"]+"\r\n") - result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], SHELL_TIMEOUT) - else: - fail_usage("Failed: You have to set login name") - - if result == 1: - if options.has_key("-p"): - conn.send(options["-p"]+"\r\n") - conn.log_expect(options, options["-c"], SHELL_TIMEOUT) - else: - fail_usage("Failed: You have to enter password or password script") - except pexpect.EOF: - fail(EC_LOGIN_DENIED) - except pexpect.TIMEOUT: - fail(EC_LOGIN_DENIED) - else: - conn = fence_login(options) - - fence_action(conn, options, set_power_status, get_power_status) - - ## - ## Logout from system - ###### - try: - conn.send("/X"+"\r\n") - conn.close() - except exceptions.OSError: - pass - except pexpect.ExceptionPexpect: - pass - -if __name__ == "__main__": - main() diff --git a/fence/agents/xcat/Makefile b/fence/agents/xcat/Makefile deleted file mode 100644 index b065307..0000000 --- a/fence/agents/xcat/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2002 All rights reserved. -## -############################################################################### -############################################################################### - -SOURCE= fence_xcat.pl -TARGET= fence_xcat - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/xcat/fence_xcat.pl b/fence/agents/xcat/fence_xcat.pl deleted file mode 100755 index 97879ab..0000000 --- a/fence/agents/xcat/fence_xcat.pl +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -############################################################################### -############################################################################### - -use Getopt::Std; - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -$opt_o = 'reset'; # Default fence action -$opt_r = 'rpower'; # Default fence action - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -h usage\n"; - print " -n <name> nodename\n"; - print " -o <string> Action: on | off | reset (default) | stat\n"; - print " -r <rpower> rpower command\n"; - print " -q quiet mode\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "action" ) - { - $opt_o = $val; - } - elsif ($name eq "nodename" ) - { - $opt_n = $val; - } - elsif ($name eq "rpower" ) - { - $opt_r = $val; - } - - else - { - fail "parse error: unknown option "$opt""; - } - } -} - -######################################################################33 -# MAIN - -if (@ARGV > 0) { - getopts("hn:o:r:qV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-n' flag specified." unless defined $opt_n; - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(on|off|reset|stat)$/; - -} else { - get_options_stdin(); - - fail "failed: no plug number" unless defined $opt_n; - fail "failed: unrecognised action: $opt_o" - unless $opt_o =~ /^(on|off|reset|stat)$/; -} - -pipe (RDR,WTR); - -if ( $pid=fork() == 0 ) -{ - close RDR; - - open STDOUT, ">&WTR"; - exec "$opt_r $opt_n $opt_o" or die "failed to exec "$opt_r"\n"; -} - -close WTR; - -wait; - -if ( $? != 0 ) -{ - die "failed: rpower error: exit $?\n" -} - -$found=0; -$status=""; -while (<RDR>) -{ - chomp; - - if ( $_ =~ /^(\S+): (\S+)$/) - { - if ($opt_n eq $1) - { - $status = $2; - - if (($opt_o eq $2) || ($opt_o eq "stat")) - { - $found=1; - last; - } - } - } -} - -print (($found ? "success":"failed") . ": $opt_n $status\n") - unless defined $opt_q; - -exit ($found ? 0 : 1 ); - - - - - - - - - diff --git a/fence/agents/xvm/Makefile b/fence/agents/xvm/Makefile deleted file mode 100644 index a49f531..0000000 --- a/fence/agents/xvm/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2006 Red Hat, Inc. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -TARGETS=fence_xvm - -fence_xvm_SOURCE = fence_xvm.c mcast.c ip_lookup.c simple_auth.c tcp.c \ - options.c debug.c - -# -# RHEL4 branch notes! -# -# RHEL4 includes seamonkey-nss and seamonkey-nspr; we need both -# seamonkey-nss-devel and seamonkey-nspr-devel to be installed in -# order to build. On RHEL4, these provide pkgconfig (note: -# mozilla-config does not work) scripts to determine their -# include locations. -# -INCLUDE=-I${top_srcdir}/include -I${top_srcdir}/config \ - $(shell pkg-config --cflags mozilla-nss mozilla-nspr) \ - -I../../../ccs/lib - -CFLAGS+=-DFENCE_RELEASE_NAME="${RELEASE}" \ - -Wall -Werror -Wstrict-prototypes -Wshadow -ggdb -D_GNU_SOURCE - -LIBS+=-L../../../ccs/lib -lnss3 - -all: ${TARGETS} - -fence_xvm: ${fence_xvm_SOURCE:.c=.o} - gcc -o $@ $^ $(LIBS) - -%.o: %.c - gcc $(CFLAGS) -c -o $@ $^ $(INCLUDES) - -clean: - rm -f $(TARGETS) *~ *.o - -install: all - if [ ! -d ${sbindir} ]; then \ - install -d ${sbindir}; \ - fi - install -m755 ${TARGETS} ${sbindir} - -copytobin: all - cp ${TARGETS} ${top_srcdir}/bin - - diff --git a/fence/agents/xvm/README b/fence/agents/xvm/README deleted file mode 100644 index 401666d..0000000 --- a/fence/agents/xvm/README +++ /dev/null @@ -1,182 +0,0 @@ -I. Fence_xvm - virtual machine fencing agent - -Fence_xvm is an agent which establishes a communications link between -a cluster of virtual machines (VC) and a cluster of domain0/physical -nodes which are hosting the virtual cluster. Its operations are -fairly simple. - - (a) Start a listener service. - (b) Send a multicast packet requesting that a VM be fenced. - (c) Authenticate client. - (e) Read response. - (f) Exit with success/failure, depending on the response received. - -If any of the above steps fail, the fencing agent exits with a failure -code and fencing is retried by the virtual cluster at a later time. -Because of the simplicty of fence_xvm, it is not necessary that -fence_xvm be run from within a virtualized guest - all it needs is -libnspr and libnss and a shared private key (for authentication; we -would hate to receive a false positive response from a node not in the -cluster!). - - -II. Fence_xvmd - The virtual machine fencing host - -Fence_xvmd is a daemon which runs on physical hosts (e.g. in domain0) -of the cluster hosting the virtual cluster. It listens on a port -for multicast traffic from virtual cluster(s), and takes actions. -Multiple disjoint virtual clusters can coexist on a single physical -host cluster, but this requires multiple instances of fence_xvmd. - -NOTE: fence_xvmd *MUST* be run on ALL nodes in a given cluster which -will be hosting virtual machines if fence_xvm is to be used for -fencing! - -There are a couple of ways the multicast packet is handled, -depending on the state of the host OS. It might be hosting the VM, -or it might not. Furthermore, the VM might "reside" on a host which -has failed. - -In order to be able to guarantee safe fencing of a VM even if the -last- known host is down, we must store the last-known locations of -each virtual machine in some sort of cluster-wide way. For this, we -use the AIS Checkpointing API, which is provided by OpenAIS. Every -few seconds, fence_xvmd queries the hypervisor via libvirt and -stores any local VM states in a checkpoint. In the event of a -physical node failure (which consequently causes the failure of one -or more guests), we can then read the checkpoint section corresponding -to the guest we need to fence to find out the previous -owner. With that information, we can then check with CMAN to see if -the last-known host node has been fenced. If so, then the VM is -clean as well. The physical cluster must, therefore, have fencing -in order for fence_xvmd to work. - -Operation of a node hosting a VM which needs to be fenced: - - (a) Receive multicast packet - (b) Authenticate multicast packet - (c) Open connection to host contained within multicast - packet. - (d) Authenticate server. - (e) Carry out fencing operation (e.g. call libvirt to destroy or - reboot the VM; there is no "on" method at this point). - (f) If operation succeeds, send success response. - -Operation of high-node-ID: - - (a) Receive multicast packet - (b) Authenticate multicast packet - (c) Read VM state from checkpoint - (d) Check liveliness of nodeID hosting VM (if alive, do nothing) - (e) Open connection to host contained within multicast - packet. - (f) Check with CMAN to see if last-known host has been fenced. - (If it has not; do nothing -- this is why the physical - cluster also needs fencing!) - (g) Authenticate server & send response. - (h) If last-known host has been fenced, send success response. - -NOTE: There is always a possibility that a VM is started again -before the fencing operation and checkpoint update for that VM -occurs. If the VM has booted and rejoined the cluster, fencing will -not be necessary. If it is in the process of booting, but has not -yet joined the cluster, fencing will also not be necessary - because -it will not be using cluster resources yet. - - -III. Security considerations - -While fencing is generally expected to run on a more or less trusted -network, there are cases where it may not be. - -* The multicast packet is subject to replay attacks, but because no -fencing action is taken based solely on the information contained -within the packet, this should not allow an attacker to maliciously -fence a VM from outside the cluster, though it may be possible to -cause a DoS of fence_xvmd if enough multicast packets are sent. - -* The only currently supported authentication mechanisms are simple -challenge-response based on a shared private key and pseudorandom -number generation. - -* An attacker with access to the shared key(s) can easily fence any -known VM, even if they are not on a cluster node. - -* Different shared keys should be used for different virtual -clusters on the same subnet (whether in the same physical cluster -or not). Additionally, multiple fence_xvmd instances must be run -(each listening on a different multicast IP + port combination). - -IV. Configuration - -Generate a random key file. An example of how to generate it is: - - dd if=/dev/urandom of=/etc/cluster/fence_xvm.key bs=4096 count=1 - -Distribute the generated key file to all virtual machines in a -cluster as well as all physical host nodes which will be hosting -that particular cluster of guests. More simply, everything involved -with hosting the virtual cluster as well as the virtual cluster -itself must have the same key file; it acts as a password. - -The key should not be placed on shared file systems (because shared -file systems require the cluster, which requires fencing...). -Furthermore, it is considered 'unsupported' to join a host cluster -and a guest cluster in one management domain. - -A. Configuring the host (physical) cluster - -On the host cluster, you need to add the following tag as a -child of the <cluster> tag in /etc/cluster/cluster.conf: - - <fence_xvmd/> - -(Do not forget to increment the configuration version number and -run 'ccs_tool update /etc/cluster/cluster.conf' !). - -Start fence_xvmd on all host nodes if it isn't already running. -Just run 'fence_xvmd'. The next time the cluster is restarted, -fence_xvmd will start automatically; it is started by the cman -script if you have the above tag in cluster.conf. - -B. Configuring the guest (virtual) cluster - -On the guest cluster, you need to set up per-node fencing. This -is a fairly simple task as well. First, you need to add a fence -device for 'xvm'. Simply add the following to the <fencedevices/> -tag in the guest cluster's cluster.conf: - - <fencedevice name="xvm" agent="fence_xvm"/> - -After doing this, each node also needs individual fencing set up. -For each <clusternode/> tag, you will need to add something like -the following: - - <fence> - <method name="1"> - <device name="xvm" domain="doman-name"/> - </method> - </fence> - -For example, if you have a virtual host named 'vm1.test.com' with a -corresponding virtual domain name of 'domU-vm1' in the dom0 cluster, -and a node ID of 1, the <clusternode> tag for that virtual machine -would look like so: - - <clusternode name="vm1.test.com" nodeid="1" votes="1"> - <fence> - <method name="1"> - <device name="xvm" domain="domU-vm1"/> - </method> - </fence> - </clusternode> - -C. Advanced configuration - -Any advanced configuration parameters (e.g. changing authentication, -hashing, key file, etc.) should be included in the <fence_xvmd/> tag -in the host cluster and the <fencedevice .../> tag in the guest -cluster. For a complete list of advanced parameters, see: - - fence_xvmd -h - fence_xvm -h diff --git a/fence/agents/xvm/TODO b/fence/agents/xvm/TODO deleted file mode 100644 index 0158742..0000000 --- a/fence/agents/xvm/TODO +++ /dev/null @@ -1,33 +0,0 @@ -High Priority / Blockers: - -* Nothing at this time. - -Medium Priority: - -* Need to add ability for fence_xvmd to forcefully fence the host -dom0 if it's not responding. Medium because it should not be the -default behavior since fencing a host can affect multiple domains -across potentially multiple domU clusters. This will be a server- -side configuration option; domUs will not be able to override it. - -* Support multiple authentication keys in fence_xvmd simultaneously -so that we can fence multiple clusters with only one instance of -fence_xvmd running on a given dom0. - -Low Priority: - -* Turn README in to man pages. - -* Make sure CMAN is running and/or restart/reconnect if CMAN goes -away and comes back. (If CMAN dies, we have big problems anyway) - -* Add SSL connection support. (Challenge/response on a trusted -network should be okay.) - -* Make sure addresses contained in the multicast packet are always -in network-byte order. Low because it will be unlikely that the -host-byte ordering of a domU and its dom0 will be different. - -* Make sure node IDs and VM states stored in openais checkpoints -are in network-byte order and swap back/forth if not. - diff --git a/fence/agents/xvm/debug.c b/fence/agents/xvm/debug.c deleted file mode 100644 index 1605767..0000000 --- a/fence/agents/xvm/debug.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <stdio.h> -#include "debug.h" - -static int _debug = 0; - -inline void -dset(int threshold) -{ - _debug = threshold; - dbg_printf(3, "Debugging threshold is now %d\n", threshold); -} - -inline int -dget(void) -{ - return _debug; -} diff --git a/fence/agents/xvm/debug.h b/fence/agents/xvm/debug.h deleted file mode 100644 index ded2181..0000000 --- a/fence/agents/xvm/debug.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _DBG_H -#define _DBG_H - -inline void dset(int); -inline int dget(void); - -#define dbg_printf(level, fmt, args...) \ -do { \ - if (dget()>=level) \ - printf(fmt, ##args); \ -} while(0) - -#endif diff --git a/fence/agents/xvm/fence_xvm.c b/fence/agents/xvm/fence_xvm.c deleted file mode 100644 index bd1eba9..0000000 --- a/fence/agents/xvm/fence_xvm.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/* - * @file fence_xvmd.c: Implementation of server daemon for Xen virtual - * machine fencing. This uses SA AIS CKPT b.1.0 checkpointing API to - * store virtual machine states. - * - * Author: Lon Hohberger <lhh at redhat.com> - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/un.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netdb.h> -#include <sys/time.h> -#include <fcntl.h> -#include <errno.h> -#include <pthread.h> -#include <libgen.h> -#include <nss.h> - -/* Local includes */ -#include "xvm.h" -#include "ip_lookup.h" -#include "simple_auth.h" -#include "options.h" -#include "tcp.h" -#include "mcast.h" -#include "debug.h" - - -int -tcp_wait_connect(int lfd, int retry_tenths) -{ - int fd; - fd_set rfds; - int n; - struct timeval tv; - - dbg_printf(3, "Waiting for connection from XVM host daemon.\n"); - FD_ZERO(&rfds); - FD_SET(lfd, &rfds); - tv.tv_sec = retry_tenths / 10; - tv.tv_usec = (retry_tenths % 10) * 100000; - - n = select(lfd + 1, &rfds, NULL, NULL, &tv); - if (n == 0) { - errno = ETIMEDOUT; - return -1; - } else if (n < 0) { - return -1; - } - - fd = accept(lfd, NULL, 0); - if (fd < 0) - return -1; - - return fd; -} - - -int -tcp_exchange(int fd, fence_auth_type_t auth, void *key, - size_t key_len, int timeout) -{ - char ret; - fd_set rfds; - struct timeval tv; - - /* Ok, we're connected */ - dbg_printf(3, "Issuing TCP challenge\n"); - if (tcp_challenge(fd, auth, key, key_len, timeout) <= 0) { - /* Challenge failed */ - printf("Invalid response to challenge\n"); - return 0; - } - - /* Now they'll send us one, so we need to respond here */ - dbg_printf(3, "Responding to TCP challenge\n"); - if (tcp_response(fd, auth, key, key_len, timeout) <= 0) { - printf("Invalid response to challenge\n"); - return 0; - } - - dbg_printf(2, "TCP Exchange + Authentication done... \n"); - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = timeout; - tv.tv_usec = 0; - - ret = 1; - dbg_printf(3, "Waiting for return value from XVM host\n"); - if (select(fd + 1, &rfds, NULL, NULL, &tv) <= 0) - return -1; - - /* Read return code */ - read(fd, &ret, 1); - close(fd); - if (ret == 0) - printf("Remote: Operation was successful\n"); - else - printf("Remote: Operation failed\n"); - return ret; -} - - -int -send_multicast_packets(ip_list_t *ipl, fence_xvm_args_t *args, void *key, - size_t key_len) -{ - fence_req_t freq; - int mc_sock; - ip_addr_t *ipa; - struct sockaddr_in tgt4; - struct sockaddr_in6 tgt6; - struct sockaddr *tgt; - socklen_t tgt_len; - - for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) { - - if (ipa->ipa_family != args->family) { - dbg_printf(2, "Ignoring %s: wrong family\n", ipa->ipa_address); - continue; - } - - if (args->family == PF_INET) { - mc_sock = ipv4_send_sk(ipa->ipa_address, args->addr, - args->port, - (struct sockaddr *)&tgt4, - sizeof(struct sockaddr_in)); - tgt = (struct sockaddr *)&tgt4; - tgt_len = sizeof(tgt4); - - } else if (args->family == PF_INET6) { - mc_sock = ipv6_send_sk(ipa->ipa_address, args->addr, - args->port, - (struct sockaddr *)&tgt6, - sizeof(struct sockaddr_in6)); - tgt = (struct sockaddr *)&tgt6; - tgt_len = sizeof(tgt6); - } else { - dbg_printf(2, "Unsupported family %d\n", args->family); - return -1; - } - - if (mc_sock < 0) - continue; - - /* Build our packet */ - memset(&freq, 0, sizeof(freq)); - strncpy((char *)freq.domain, args->domain, - sizeof(freq.domain)); - freq.request = args->op; - freq.hashtype = args->hash; - - /* Store source address */ - if (ipa->ipa_family == PF_INET) { - freq.addrlen = sizeof(struct in_addr); - /* XXX Swap order for in_addr ? XXX */ - inet_pton(PF_INET, ipa->ipa_address, freq.address); - } else if (ipa->ipa_family == PF_INET6) { - freq.addrlen = sizeof(struct in6_addr); - inet_pton(PF_INET6, ipa->ipa_address, freq.address); - } - - freq.flags = 0; - if (args->flags & F_USE_UUID) - freq.flags |= RF_UUID; - freq.family = ipa->ipa_family; - freq.port = args->port; - - sign_request(&freq, key, key_len); - - dbg_printf(3, "Sending to %s via %s\n", args->addr, - ipa->ipa_address); - - sendto(mc_sock, &freq, sizeof(freq), 0, - (struct sockaddr *)tgt, tgt_len); - - close(mc_sock); - } - - return 0; -} - - -/* TODO: Clean this up!!! */ -int -fence_xen_domain(fence_xvm_args_t *args) -{ - ip_list_t ipl; - char key[4096]; - int lfd, key_len = 0, fd; - int attempts = 0; - - if (args->auth != AUTH_NONE || args->hash != HASH_NONE) { - key_len = read_key_file(args->key_file, key, sizeof(key)); - if (key_len < 0) { - printf("Could not read %s; trying without " - "authentication\n", args->key_file); - args->auth = AUTH_NONE; - args->hash = HASH_NONE; - } - } - - /* Do the real work */ - if (ip_build_list(&ipl) < 0) { - printf("Error building IP address list\n"); - return 1; - } - - switch (args->auth) { - case AUTH_NONE: - case AUTH_SHA1: - case AUTH_SHA256: - case AUTH_SHA512: - if (args->family == PF_INET) { - lfd = ipv4_listen(args->port, 10); - } else { - lfd = ipv6_listen(args->port, 10); - } - break; - /*case AUTH_X509:*/ - /* XXX Setup SSL listener socket here */ - default: - return 1; - } - - if (lfd < 0) { - printf("Failed to listen: %s\n", strerror(errno)); - return 1; - } - - attempts = args->timeout * 10 / args->retr_time; - - do { - if (send_multicast_packets(&ipl, args, key, key_len)) { - return -1; - } - - switch (args->auth) { - case AUTH_NONE: - case AUTH_SHA1: - case AUTH_SHA256: - case AUTH_SHA512: - fd = tcp_wait_connect(lfd, args->retr_time); - if (fd < 0 && (errno == ETIMEDOUT || - errno == EINTR)) - continue; - break; - /* case AUTH_X509: - ... = ssl_wait_connect... */ - break; - default: - return 1; - } - - break; - } while (--attempts); - - if (fd < 0) { - if (attempts <= 0) { - printf("Timed out waiting for response\n"); - return 1; - } - printf("Fencing failed: %s\n", strerror(errno)); - return -1; - } - - switch (args->auth) { - case AUTH_NONE: - case AUTH_SHA1: - case AUTH_SHA256: - case AUTH_SHA512: - return tcp_exchange(fd, args->auth, key, key_len, - args->timeout); - break; - /* case AUTH_X509: - return ssl_exchange(...); */ - default: - return 1; - } - - return 1; -} - - -int -main(int argc, char **argv) -{ - fence_xvm_args_t args; - char *my_options = "di:a:p:r:C:c:k:H:uo:t:?hV"; - - args_init(&args); - if (argc == 1) { - args_get_stdin(my_options, &args); - } else { - args_get_getopt(argc, argv, my_options, &args); - } - - if (args.flags & F_HELP) { - args_usage(argv[0], my_options, 0); - args_usage(argv[0], my_options, 1); - exit(0); - } - - if (args.flags & F_VERSION) { - printf("%s %s\n", basename(argv[0]), XVM_VERSION); -#ifdef FENCE_RELEASE_NAME - printf("fence release %s\n", FENCE_RELEASE_NAME); -#endif - exit(0); - } - - args_finalize(&args); - dset(args.debug); - - if (args.debug > 0) - args_print(&args); - - /* Additional validation here */ - if (!args.domain) { - printf("No domain specified!\n"); - args.flags |= F_ERR; - } - - if (args.flags & F_ERR) { - args_usage(argv[0], my_options, (argc == 1)); - exit(1); - } - - /* Initialize NSS; required to do hashing, as silly as that - sounds... */ - if (NSS_NoDB_Init(NULL) != SECSuccess) { - printf("Could not initialize NSS\n"); - return 1; - } - - return fence_xen_domain(&args); -} diff --git a/fence/agents/xvm/ip_lookup.c b/fence/agents/xvm/ip_lookup.c deleted file mode 100644 index 646725e..0000000 --- a/fence/agents/xvm/ip_lookup.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004, 2006 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Build lists of IPs on the system, excepting loopback ipv6 link-local - */ -#include <asm/types.h> -#include <sys/types.h> -#include <arpa/inet.h> -#include <sys/socket.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <netdb.h> - -#ifndef IFA_MAX -#include <linux/if_addr.h> -#endif - -/* Local includes */ -#include "ip_lookup.h" -#include "debug.h" - -static int -send_addr_dump(int fd, int family) -{ - struct nlmsghdr *nh; - struct rtgenmsg *g; - char buf[256]; - struct sockaddr_nl addr; - - memset(&addr,0,sizeof(addr)); - addr.nl_family = PF_NETLINK; - - memset(buf, 0, sizeof(buf)); - nh = (struct nlmsghdr *)buf; - g = (struct rtgenmsg *)(buf + sizeof(struct nlmsghdr)); - - nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); - nh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP; - nh->nlmsg_type = RTM_GETADDR; - g->rtgen_family = family; - - return sendto(fd, buf, nh->nlmsg_len, 0, (struct sockaddr *)&addr, - sizeof(addr)); -} - - -static int -add_ip(ip_list_t *ipl, char *ipaddr, char family) -{ - ip_addr_t *ipa; - - if (family == PF_INET6) { - /* Avoid loopback */ - if (!strcmp(ipaddr, "::1")) - return -1; - - /* Avoid link-local addresses */ - if (!strncmp(ipaddr, "fe80", 4)) - return -1; - if (!strncmp(ipaddr, "fe90", 4)) - return -1; - if (!strncmp(ipaddr, "fea0", 4)) - return -1; - if (!strncmp(ipaddr, "feb0", 4)) - return -1; - } - - dbg_printf(4, "Adding IP %s to list (family %d)\n", ipaddr, family); - - ipa = malloc(sizeof(*ipa)); - memset(ipa, 0, sizeof(*ipa)); - ipa->ipa_family = family; - ipa->ipa_address = strdup(ipaddr); - - TAILQ_INSERT_TAIL(ipl, ipa, ipa_entries); - - return 0; -} - - -static int -add_ip_addresses(int family, ip_list_t *ipl) -{ - /* List ipv4 addresses */ - struct nlmsghdr *nh; - struct ifaddrmsg *ifa; - struct rtattr *rta, *nrta; - struct nlmsgerr *err; - char buf[10240]; - char outbuf[256]; - int x, fd, len; - - dbg_printf(5, "Connecting to Netlink...\n"); - fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); - if (fd < 0) { - perror("socket"); - exit(1); - } - - dbg_printf(5, "Sending address dump request\n"); - send_addr_dump(fd, family); - memset(buf, 0, sizeof(buf)); - - dbg_printf(5, "Waiting for response\n"); - x = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0); - if (x < 0) { - perror("recvfrom"); - return -1; - } - - dbg_printf(5, "Received %d bytes\n", x); - - nh = (struct nlmsghdr *)buf; - while (NLMSG_OK(nh, x)) { - - switch(nh->nlmsg_type) { - case NLMSG_DONE: - close(fd); - return 0; - - case NLMSG_ERROR: - err = (struct nlmsgerr*)NLMSG_DATA(nh); - if (nh->nlmsg_len < - NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated"); - } else { - errno = -err->error; - perror("RTNETLINK answers"); - } - close(fd); - return -1; - - case RTM_NEWADDR: - break; - - default: - nh = NLMSG_NEXT(nh, x); - continue; - } - - /* RTM_NEWADDR */ - len = NLMSG_PAYLOAD(nh,0); - ifa = NLMSG_DATA(nh); - - /* Make sure we got the type we expect back */ - if (ifa->ifa_family != family) { - nh = NLMSG_NEXT(nh, x); - continue; - } - - rta = (struct rtattr *)((void *)ifa + sizeof(*ifa)); - len -= sizeof(*ifa); - do { - /* Make sure we've got a valid rtaddr field */ - if (!RTA_OK(rta, len)) { - dbg_printf(5, "!RTA_OK(rta, len)\n"); - break; - } - - if (rta->rta_type == IFA_ADDRESS) { - inet_ntop(family, RTA_DATA(rta), outbuf, - sizeof(outbuf) ); - add_ip(ipl, outbuf, family); - } - - if (rta->rta_type == IFA_LABEL) { - dbg_printf(5, "Skipping label: %s\n", - (char *)RTA_DATA(rta)); - } - - nrta = RTA_NEXT(rta, len); - if (!nrta) - break; - - len -= ((void *)nrta - (void *)rta); - rta = nrta; - } while (RTA_OK(rta, len)); - - nh = NLMSG_NEXT(nh, x); - } - - dbg_printf(5, "Closing Netlink connection\n"); - close(fd); - return 0; -} - - -int -ip_search(ip_list_t *ipl, char *ip_name) -{ - ip_addr_t *ipa; - - dbg_printf(5, "Looking for IP address %s in IP list %p...", ip_name, ipl); - ipa = ipl->tqh_first; - for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) { - if (!strcmp(ip_name, ipa->ipa_address)) { - dbg_printf(4,"Found\n"); - return 0; - } - } - dbg_printf(5, "Not found\n"); - return 1; -} - - -int -ip_free_list(ip_list_t *ipl) -{ - ip_addr_t *ipa; - - dbg_printf(5, "Tearing down IP list @ %p\n", ipl); - while ((ipa = ipl->tqh_first)) { - TAILQ_REMOVE(ipl, ipa, ipa_entries); - free(ipa->ipa_address); - free(ipa); - } - return 0; -} - - -int -ip_build_list(ip_list_t *ipl) -{ - dbg_printf(5, "Build IP address list\n"); - TAILQ_INIT(ipl); - if (add_ip_addresses(PF_INET6, ipl) < 0) { - ip_free_list(ipl); - return -1; - } - if (add_ip_addresses(PF_INET, ipl) < 0) { - ip_free_list(ipl); - return -1; - } - return 0; -} - - -/** - Look up the interface name which corresponds to the given hostname and - return the list of matching attrinfo structures. We do this by looking - up all the possible physical and virtual network interfaces on the machine - and checking the hostname/IP mappings for each active IP address incurred. - - @param nodename Interface name - @param ret_ai Structure pointer to allocate & return. - @return -1 on failure or 0 on success. - */ -int -ip_lookup(char *nodename, struct addrinfo **ret_ai) -{ - char ip_name[256]; - struct addrinfo *ai = NULL; - struct addrinfo *n; - void *p; - ip_list_t ipl; - int ret = -1; - - dbg_printf(5, "Looking for IP matching %s\n", nodename); - /* Build list of IP addresses configured locally */ - if (ip_build_list(&ipl) < 0) - return -1; - - /* Get list of addresses for the host-name/ip */ - if (getaddrinfo(nodename, NULL, NULL, &ai) != 0) - return -1; - - - /* Traverse list of addresses for given host-name/ip */ - for (n = ai; n; n = n->ai_next) { - if (n->ai_family != PF_INET && n->ai_family != PF_INET6) - continue; - - if (n->ai_family == PF_INET) - p = &(((struct sockaddr_in *)n->ai_addr)->sin_addr); - else - p = &(((struct sockaddr_in6 *)n->ai_addr)->sin6_addr); - - if (!inet_ntop(n->ai_family, p, ip_name, - sizeof(ip_name))) - continue; - - /* Search local interfaces for this IP address */ - if (ip_search(&ipl, ip_name) != 0) - continue; - - /* Found it */ - ret = 0; - break; - } - - /* Clean up */ - if (!ret_ai) - freeaddrinfo(ai); - else - *ret_ai = ai; - - ip_free_list(&ipl); - - return ret; -} - diff --git a/fence/agents/xvm/ip_lookup.h b/fence/agents/xvm/ip_lookup.h deleted file mode 100644 index 3386c71..0000000 --- a/fence/agents/xvm/ip_lookup.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004,2006 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -*/ -/** @file - * Header for ip_lookup.c - */ -#ifndef _IP_LOOKUP_H -#define _IP_LOOKUP_H - -#include <sys/queue.h> - -typedef struct _ip_address { - TAILQ_ENTRY(_ip_address) ipa_entries; - char ipa_family; - char *ipa_address; -} ip_addr_t; - -typedef TAILQ_HEAD(_ip_list, _ip_address) ip_list_t; - -int ip_search(ip_list_t *ipl, char *ip_name); -int ip_free_list(ip_list_t *ipl); -int ip_build_list(ip_list_t *ipl); -int ip_lookup(char *, struct addrinfo **); - -#endif diff --git a/fence/agents/xvm/mcast.c b/fence/agents/xvm/mcast.c deleted file mode 100644 index e755ec0..0000000 --- a/fence/agents/xvm/mcast.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - Copyright Red Hat, Inc. 2003, 2004, 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/* - * Author: Lon Hohberger <lhh at redhat.com> - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/un.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netdb.h> -#include <sys/time.h> -#include <fcntl.h> -#include <errno.h> -#include <pthread.h> - -/* Local includes */ -#include "mcast.h" -#include "debug.h" - -/** - Sets up a multicast receive socket - */ -int -ipv4_recv_sk(char *addr, int port) -{ - int sock; - struct ip_mreq mreq; - struct sockaddr_in sin; - - /* Store multicast address */ - if (inet_pton(PF_INET, addr, - (void *)&mreq.imr_multiaddr.s_addr) < 0) { - printf("Invalid multicast address: %s\n", addr); - return -1; - } - - /******************************** - * SET UP MULTICAST RECV SOCKET * - ********************************/ - dbg_printf(4, "Setting up ipv4 multicast receive (%s:%d)\n", addr, port); - sock = socket(PF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - printf("socket: %s\n", strerror(errno)); - close(sock); - sock = -1; - return 1; - } - - /* - * When using Multicast, bind to the LOCAL address, not the MULTICAST - * address. - */ - sin.sin_family = PF_INET; - sin.sin_port = htons(port); - sin.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(sock, (struct sockaddr *) &sin, - sizeof(struct sockaddr_in)) < 0) { - printf("bind failed: %s\n", strerror(errno)); - close(sock); - return -1; - } - - /* - * Join multicast group - */ - /* mreq.imr_multiaddr.s_addr is set above */ - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - dbg_printf(4, "Joining multicast group\n"); - if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, - &mreq, sizeof(mreq)) == -1) { - printf("Failed to bind multicast receive socket to " - "%s: %s\n", addr, strerror(errno)); - printf("Check network configuration.\n"); - close(sock); - return -1; - } - - dbg_printf(4, "%s: success, fd = %d\n", __FUNCTION__, sock); - return sock; -} - - -/** - Set up multicast send socket - */ -int -ipv4_send_sk(char *send_addr, char *addr, int port, struct sockaddr *tgt, - socklen_t tgt_len) -{ - int val; - struct ip_mreq mreq; - struct sockaddr_in mcast; - struct sockaddr_in src; - int sock; - - if (tgt_len < sizeof(struct sockaddr_in)) { - errno = EINVAL; - return -1; - } - - /* Store multicast address */ - mcast.sin_family = PF_INET; - mcast.sin_port = htons(port); - if (inet_pton(PF_INET, addr, - (void *)&mcast.sin_addr.s_addr) < 0) { - printf("Invalid multicast address: %s\n", addr); - return -1; - } - mreq.imr_multiaddr.s_addr = mcast.sin_addr.s_addr; - - /* Store sending address */ - src.sin_family = PF_INET; - src.sin_port = htons(port); - if (inet_pton(PF_INET, send_addr, - (void *)&src.sin_addr.s_addr) < 0) { - printf("Invalid source address: %s\n", send_addr); - return -1; - } - mreq.imr_interface.s_addr = src.sin_addr.s_addr; - - - /************************* - * SET UP MULTICAST SEND * - *************************/ - dbg_printf(4, "Setting up ipv4 multicast send (%s:%d)\n", addr, port); - sock = socket(PF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - perror("socket"); - return -1; - } - - /* - * Join Multicast group. - */ - dbg_printf(4, "Joining IP Multicast group (pass 1)\n"); - if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)) == -1) { - printf("Failed to add multicast membership to transmit " - "socket %s: %s\n", addr, strerror(errno)); - close(sock); - return -1; - } - - /* - * Join Multicast group. - */ - dbg_printf(4, "Joining IP Multicast group (pass 2)\n"); - if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &src.sin_addr, - sizeof(src.sin_addr)) == -1) { - printf("Failed to bind multicast transmit socket to " - "%s: %s\n", addr, strerror(errno)); - close(sock); - return -1; - } - - /* - * set time to live to 2 hops. - */ - dbg_printf(4, "Setting TTL to 2 for fd%d\n", sock); - val = 2; - if (setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &val, - sizeof(val))) - printf("warning: setting TTL failed %s\n", strerror(errno)); - - memcpy((struct sockaddr_in *)tgt, &mcast, sizeof(struct sockaddr_in)); - - dbg_printf(4, "%s: success, fd = %d\n", __FUNCTION__, sock); - return sock; -} - - - -/** - Sets up a multicast receive (ipv6) socket - */ -int -ipv6_recv_sk(char *addr, int port) -{ - int sock, val; - struct ipv6_mreq mreq; - struct sockaddr_in6 sin; - - memset(&mreq, 0, sizeof(mreq)); - memset(&sin, 0, sizeof(sin)); - sin.sin6_family = PF_INET6; - sin.sin6_port = htons(port); - if (inet_pton(PF_INET6, addr, - (void *)&sin.sin6_addr) < 0) { - printf("Invalid multicast address: %s\n", addr); - return -1; - } - - memcpy(&mreq.ipv6mr_multiaddr, &sin.sin6_addr, - sizeof(struct in6_addr)); - - - /******************************** - * SET UP MULTICAST RECV SOCKET * - ********************************/ - dbg_printf(4, "Setting up ipv6 multicast receive (%s:%d)\n", addr, port); - sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) { - printf("socket: %s\n", strerror(errno)); - close(sock); - sock = -1; - return 1; - } - - /* - * When using Multicast, bind to the LOCAL address, not the MULTICAST - * address. - */ - memset(&sin, 0, sizeof(sin)); - sin.sin6_family = PF_INET6; - sin.sin6_port = htons(port); - sin.sin6_addr = in6addr_any; - if (bind(sock, (struct sockaddr *) &sin, - sizeof(struct sockaddr_in6)) < 0) { - printf("bind failed: %s\n", strerror(errno)); - close(sock); - return -1; - } - - dbg_printf(4, "Disabling IP Multicast loopback\n"); - val = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, - sizeof(val)) != 0) { - printf("Failed to disable multicast loopback\n"); - close(sock); - return -1; - } - - /* - * Join multicast group - */ - dbg_printf(4, "Joining IP Multicast group\n"); - if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)) == -1) { - printf("Failed to add multicast to socket %s: %s\n", - addr, strerror(errno)); - close(sock); - return -1; - } - - dbg_printf(4, "%s: success, fd = %d\n", __FUNCTION__, sock); - return sock; -} - - -/** - Set up ipv6 multicast send socket - */ -int -ipv6_send_sk(char *send_addr, char *addr, int port, struct sockaddr *tgt, - socklen_t tgt_len) -{ - int val; - struct ipv6_mreq mreq; - struct sockaddr_in6 mcast; - struct sockaddr_in6 src; - int sock; - - if (tgt_len < sizeof(struct sockaddr_in6)) { - errno = EINVAL; - return -1; - } - - memset(&mreq, 0, sizeof(mreq)); - - /* Store multicast address */ - mcast.sin6_family = PF_INET6; - mcast.sin6_port = htons(port); - if (inet_pton(PF_INET6, addr, - (void *)&mcast.sin6_addr) < 0) { - printf("Invalid multicast address: %s\n", addr); - return -1; - } - - memcpy(&mreq.ipv6mr_multiaddr, &mcast.sin6_addr, - sizeof(struct in6_addr)); - - /* Store sending address */ - src.sin6_family = PF_INET6; - src.sin6_port = htons(port); - if (inet_pton(PF_INET6, send_addr, - (void *)&src.sin6_addr) < 0) { - printf("Invalid source address: %s\n", send_addr); - return -1; - } - - /************************* - * SET UP MULTICAST SEND * - *************************/ - dbg_printf(4, "Setting up ipv6 multicast send (%s:%d)\n", addr, port); - sock = socket(PF_INET6, SOCK_DGRAM, 0); - if (sock < 0) { - perror("socket"); - return -1; - } - - dbg_printf(4, "Disabling IP Multicast loopback\n"); - val = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, - sizeof(val)) != 0) { - printf("Failed to disable multicast loopback\n"); - close(sock); - return -1; - } - - /* - * Join Multicast group. - */ - dbg_printf(4, "Joining IP Multicast group\n"); - if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)) == -1) { - printf("Failed to add multicast membership to transmit " - "socket %s: %s\n", addr, strerror(errno)); - close(sock); - return -1; - } - - /* - * Join Multicast group (part 2) - */ - /* - if (setsockopt(sock, IPPROTO_IPV6, IP_MULTICAST_IF, &src.sin6_addr, - sizeof(src.sin6_addr)) == -1) { - printf("Failed to bind multicast transmit socket to " - "%s: %s\n", addr, strerror(errno)); - close(sock); - return -1; - } - */ - - /* - * set time to live to 2 hops. - */ - val = 2; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, - sizeof(val))) - printf("warning: setting TTL failed %s\n", strerror(errno)); - - memcpy((struct sockaddr_in *)tgt, &mcast, sizeof(struct sockaddr_in6)); - - dbg_printf(4, "%s: success, fd = %d\n", __FUNCTION__, sock); - return sock; -} diff --git a/fence/agents/xvm/mcast.h b/fence/agents/xvm/mcast.h deleted file mode 100644 index 2da33cb..0000000 --- a/fence/agents/xvm/mcast.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _XVM_MCAST_H -#define _XVM_MCAST_H - -#define IPV4_MCAST_DEFAULT "225.0.0.12" -#define IPV6_MCAST_DEFAULT "ff05::3:1" - -int ipv4_recv_sk(char *addr, int port); -int ipv4_send_sk(char *src_addr, char *addr, int port, - struct sockaddr *src, socklen_t slen); -int ipv6_recv_sk(char *addr, int port); -int ipv6_send_sk(char *src_addr, char *addr, int port, - struct sockaddr *src, socklen_t slen); - -#endif diff --git a/fence/agents/xvm/options.c b/fence/agents/xvm/options.c deleted file mode 100644 index 1e02cfc..0000000 --- a/fence/agents/xvm/options.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/un.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netdb.h> -#include <sys/time.h> -#include <fcntl.h> -#include <errno.h> - -/* Local includes */ -#include "xvm.h" -#include "simple_auth.h" -#include "mcast.h" -#include "options.h" - - - -/* Assignment functions */ - -static inline void -assign_debug(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - if (!value) { - /* GNU getopt sets optarg to NULL for options w/o a param - We rely on this here... */ - args->debug++; - return; - } - - args->debug = atoi(value); - if (args->debug < 0) { - args->debug = 1; - } -} - - -static inline void -assign_foreground(fence_xvm_args_t *args, struct arg_info *arg, - char *value) -{ - args->flags |= F_FOREGROUND; -} - - -static inline void -assign_family(fence_xvm_args_t *args, struct arg_info *arg, - char *value) -{ - if (!strcasecmp(value, "ipv4")) { - args->family = PF_INET; - } else if (!strcasecmp(value, "ipv6")) { - args->family = PF_INET6; - } else if (!strcasecmp(value, "auto")) { - args->family = 0; - } else { - printf("Unsupported family: '%s'\n", value); - args->flags |= F_ERR; - } -} - - -static inline void -assign_address(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->addr = strdup(value); -} - - -static inline void -assign_port(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->port = atoi(value); - if (args->port <= 0 || args->port >= 65500) { - printf("Invalid port: '%s'\n", value); - args->flags |= F_ERR; - } -} - - -static inline void -assign_retrans(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->retr_time = atoi(value); - if (args->retr_time <= 0) { - printf("Invalid retransmit time: '%s'\n", value); - args->flags |= F_ERR; - } -} - -static inline void -assign_hash(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - if (!strcasecmp(value, "none")) { - args->hash = HASH_NONE; - } else if (!strcasecmp(value, "sha1")) { - args->hash = HASH_SHA1; - } else if (!strcasecmp(value, "sha256")) { - args->hash = HASH_SHA256; - } else if (!strcasecmp(value, "sha512")) { - args->hash = HASH_SHA512; - } else { - printf("Unsupported hash: %s\n", value); - args->flags |= F_ERR; - } -} - - -static inline void -assign_auth(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - if (!strcasecmp(value, "none")) { - args->auth = AUTH_NONE; - } else if (!strcasecmp(value, "sha1")) { - args->auth = AUTH_SHA1; - } else if (!strcasecmp(value, "sha256")) { - args->auth = AUTH_SHA256; - } else if (!strcasecmp(value, "sha512")) { - args->auth = AUTH_SHA512; - } else { - printf("Unsupported auth type: %s\n", value); - args->flags |= F_ERR; - } -} - -static inline void -assign_key(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - struct stat st; - - args->key_file = strdup(value); - - if (stat(value, &st) == -1) { - printf("Invalid key file: '%s' (%s)\n", value, - strerror(errno)); - args->flags |= F_ERR; - } -} - - -static inline void -assign_op(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - if (!strcasecmp(value, "null")) { - args->op = FENCE_NULL; - } else if (!strcasecmp(value, "off")) { - args->op = FENCE_OFF; - } else if (!strcasecmp(value, "reboot")) { - args->op = FENCE_REBOOT; - } else { - printf("Unsupported operation: %s\n", value); - args->flags |= F_ERR; - } -} - - -static inline void -assign_domain(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - if (args->domain) { - printf("Domain/UUID may not be specified more than once\n"); - args->flags |= F_ERR; - return; - } - - args->domain = strdup(value); - - if (strlen(value) <= 0) { - printf("Invalid domain name\n"); - args->flags |= F_ERR; - } - - if (strlen(value) >= MAX_DOMAINNAME_LENGTH) { - errno = ENAMETOOLONG; - printf("Invalid domain name: '%s' (%s)\n", - value, strerror(errno)); - args->flags |= F_ERR; - } -} - - -static inline void -assign_uuid_lookup(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - if (!value) { - /* GNU getopt sets optarg to NULL for options w/o a param - We rely on this here... */ - args->flags |= F_USE_UUID; - return; - } - - args->flags |= ( !!atoi(value) ? F_USE_UUID : 0); -} - - -static inline void -assign_timeout(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->timeout = atoi(value); - if (args->timeout <= 0) { - printf("Invalid timeout: '%s'\n", value); - args->flags |= F_ERR; - } -} - - -static inline void -assign_help(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->flags |= F_HELP; -} - - -static inline void -assign_version(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->flags |= F_VERSION; -} - - -static inline void -assign_noccs(fence_xvm_args_t *args, struct arg_info *arg, char *value) -{ - args->flags |= F_NOCCS; -} - - -/** ALL valid command line and stdin arguments for this fencing agent */ -static struct arg_info _arg_info[] = { - { '\xff', NULL, "agent", - "Not user serviceable", - NULL }, - - { '\xff', NULL, "self", - "Not user serviceable", - NULL }, - - { 'd', "-d", "debug", - "Enable debugging mode", - assign_debug }, - - { 'f', "-f", NULL, - "Foreground mode (do not fork)", - assign_foreground }, - - { 'i', "-i <family>", "ip_family", - "IP Family ([auto], ipv4, ipv6)", - assign_family }, - - { 'a', "-a <address>", "multicast_address", - "Multicast address (default=225.0.0.12 / ff02::3:1)", - assign_address }, - - { 'p', "-p <port>", "port", - "IP port (default=1229)", - assign_port }, - - { 'r', "-r <retrans>", "retrans", - "Multicast retransmit time (in 1/10sec; default=20)", - assign_retrans }, - - { 'c', "-c <hash>", "hash", - "Packet hash strength (none, sha1, [sha256], sha512)", - assign_hash }, - - { 'C', "-C <auth>", "auth", - "Authentication (none, sha1, [sha256], sha512)", - assign_auth }, - - { 'k', "-k <file>", "key_file", - "Shared key file (default=/etc/cluster/fence_xvm.key)", - assign_key }, - - { 'o', "-o <operation>", "option", - "Fencing operation (null, off, [reboot])", - assign_op }, - - { 'H', "-H <domain>", "domain", - "Xen host (domain name) to fence", - assign_domain }, - - { 'u', "-u", "use_uuid", - "Treat <domain> as UUID instead of domain name", - assign_uuid_lookup }, - - { 't', "-t <timeout>", "timeout", - "Fencing timeout (in seconds; default=30)", - assign_timeout }, - - { 'h', "-h", NULL, - "Help", - assign_help }, - - { '?', "-?", NULL, - "Help (alternate)", - assign_help }, - - { 'X', "-X", NULL, - "Do not connect to CCS for configuration", - assign_noccs }, - - { 'V', "-V", NULL, - "Display version and exit", - assign_version }, - - /* Terminator */ - { 0, NULL, NULL, NULL, NULL } -}; - - -struct arg_info * -find_arg_by_char(char arg) -{ - int x = 0; - - for (x = 0; _arg_info[x].opt != 0; x++) { - if (_arg_info[x].opt == arg) - return &_arg_info[x]; - } - - return NULL; -} - - -struct arg_info * -find_arg_by_string(char *arg) -{ - int x = 0; - - for (x = 0; _arg_info[x].opt != 0; x++) { - if (!_arg_info[x].stdin_opt) - continue; - if (!strcasecmp(_arg_info[x].stdin_opt, arg)) - return &_arg_info[x]; - } - - return NULL; -} - - -/* ============================================================= */ - -/** - Initialize an args structure. - - @param args Pointer to args structure to initialize. - */ -void -args_init(fence_xvm_args_t *args) -{ - args->addr = NULL; - args->domain = NULL; - args->key_file = DEFAULT_KEY_FILE; - args->op = FENCE_REBOOT; - args->hash = DEFAULT_HASH; - args->auth = DEFAULT_AUTH; - args->port = 1229; - args->family = PF_INET; - args->timeout = 30; - args->retr_time = 20; - args->flags = 0; - args->debug = 0; -} - - -#define _pr_int(piece) printf(" %s = %d\n", #piece, piece) -#define _pr_str(piece) printf(" %s = %s\n", #piece, piece) - - -/** - Prints out the contents of an args structure for debugging. - - @param args Pointer to args structure to print out. - */ -void -args_print(fence_xvm_args_t *args) -{ - printf("-- args @ %p --\n", args); - _pr_str(args->addr); - _pr_str(args->domain); - _pr_str(args->key_file); - _pr_int(args->op); - _pr_int(args->hash); - _pr_int(args->auth); - _pr_int(args->port); - _pr_int(args->family); - _pr_int(args->timeout); - _pr_int(args->retr_time); - _pr_int(args->flags); - _pr_int(args->debug); - printf("-- end args --\n"); -} - - -/** - Print out arguments and help information based on what is allowed in - the getopt string optstr. - - @param progname Program name. - @param optstr Getopt(3) style options string - @param print_stdin 0 = print command line options + description, - 1 = print fence-style stdin args + description - */ -void -args_usage(char *progname, char *optstr, int print_stdin) -{ - int x; - struct arg_info *arg; - - if (print_stdin) { - printf("With no command line argument, arguments are " - "read from standard input.\n"); - printf("Arguments read from standard input take " - "the form of:\n\n"); - printf(" arg1=value1\n"); - printf(" arg2=value2\n\n"); - } else { - if (progname) { - printf("usage: %s [args]\n", progname); - } else { - printf("usage: fence_xvm [args]\n"); - } - } - - for (x = 0; x < strlen(optstr); x++) { - arg = find_arg_by_char(optstr[x]); - if (!arg) - continue; - - if (print_stdin) { - if (arg && arg->stdin_opt) - printf(" %-20.20s %-55.55s\n", - arg->stdin_opt, arg->desc); - } else { - printf(" %-20.20s %-55.55s\n", arg->opt_desc, - arg->desc); - } - } - - printf("\n"); -} - - -/** - Remove leading and trailing whitespace from a line of text. - - @param line Line to clean up - @param linelen Max size of line - @return 0 on success, -1 on failure - */ -int -cleanup(char *line, size_t linelen) -{ - char *p; - int x; - - /* Remove leading whitespace. */ - p = line; - for (x = 0; x <= linelen; x++) { - switch (line[x]) { - case '\t': - case ' ': - break; - case '\n': - case '\r': - return -1; - default: - goto eol; - } - } -eol: - /* Move the remainder down by as many whitespace chars as we - chewed up */ - if (x) - memmove(p, &line[x], linelen-x); - - /* Remove trailing whitespace. */ - for (x=0; x <= linelen; x++) { - switch(line[x]) { - case '\t': - case ' ': - case '\r': - case '\n': - line[x] = 0; - case 0: - /* End of line */ - return 0; - } - } - - return -1; -} - - -/** - Parse args from stdin and assign to the specified args structure. - - @param optstr Command line option string in getopt(3) format - @param args Args structure to fill in. - */ -void -args_get_stdin(char *optstr, fence_xvm_args_t *args) -{ - char in[256]; - int line = 0; - char *name, *val; - struct arg_info *arg; - - while (fgets(in, sizeof(in), stdin)) { - ++line; - - if (in[0] == '#') - continue; - - if (cleanup(in, sizeof(in)) == -1) - continue; - - name = in; - if ((val = strchr(in, '='))) { - *val = 0; - ++val; - } - - arg = find_arg_by_string(name); - if (!arg || (arg->opt != '\xff' && - !strchr(optstr, arg->opt))) { - fprintf(stderr, - "parse warning: " - "illegal variable '%s' on line %d\n", name, - line); - continue; - } - - if (arg->assign) - arg->assign(args, arg, val); - } -} - - -/** - Parse args from stdin and assign to the specified args structure. - - @param optstr Command line option string in getopt(3) format - @param args Args structure to fill in. - */ -void -args_get_getopt(int argc, char **argv, char *optstr, fence_xvm_args_t *args) -{ - int opt; - struct arg_info *arg; - - while ((opt = getopt(argc, argv, optstr)) != EOF) { - - arg = find_arg_by_char(opt); - - if (!arg) { - args->flags |= F_ERR; - continue; - } - - if (arg->assign) - arg->assign(args, arg, optarg); - } -} - - -void -args_finalize(fence_xvm_args_t *args) -{ - char *addr = NULL; - - if (!args->addr) { - switch(args->family) { - case 0: - case PF_INET: - addr = IPV4_MCAST_DEFAULT; - break; - case PF_INET6: - addr = IPV6_MCAST_DEFAULT; - break; - default: - args->flags |= F_ERR; - break; - } - } - - if (!args->addr) - args->addr = addr; - - if (!args->addr) { - printf("No multicast address available\n"); - args->flags |= F_ERR; - } - - if (!args->addr) - return; - if (args->family) - return; - - /* Set family */ - if (strchr(args->addr, ':')) - args->family = PF_INET6; - if (strchr(args->addr, '.')) - args->family = PF_INET; - if (!args->family) { - printf("Could not determine address family\n"); - args->flags |= F_ERR; - } -} diff --git a/fence/agents/xvm/options.h b/fence/agents/xvm/options.h deleted file mode 100644 index 5558212..0000000 --- a/fence/agents/xvm/options.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _XVM_OPTIONS_H -#define _XVM_OPTIONS_H - -typedef enum { - F_FOREGROUND = 0x1, - F_NOCCS = 0x2, - F_ERR = 0x4, - F_HELP = 0x8, - F_USE_UUID = 0x10, - F_VERSION = 0x20, - F_CCSERR = 0x40, - F_CCSFAIL = 0x80 -} arg_flags_t; - - -typedef struct { - char *addr; - char *domain; - char *key_file; - fence_cmd_t op; - fence_hash_t hash; - fence_auth_type_t auth; - int port; - int family; - int timeout; - int retr_time; - arg_flags_t flags; - int debug; -} fence_xvm_args_t; - -/* Private structure for commandline / stdin fencing args */ -struct arg_info { - char opt; - char *opt_desc; - char *stdin_opt; - char *desc; - void (*assign)(fence_xvm_args_t *, struct arg_info *, char *); -}; - - -/* Get options */ -void args_init(fence_xvm_args_t *args); -void args_finalize(fence_xvm_args_t *args); - -void args_get_getopt(int argc, char **argv, char *optstr, - fence_xvm_args_t *args); -void args_get_stdin(char *optstr, fence_xvm_args_t *args); -void args_get_ccs(char *optstr, fence_xvm_args_t *args); -void args_usage(char *progname, char *optstr, int print_stdin); -void args_print(fence_xvm_args_t *args); - -#endif diff --git a/fence/agents/xvm/simple_auth.c b/fence/agents/xvm/simple_auth.c deleted file mode 100644 index 2f8f959..0000000 --- a/fence/agents/xvm/simple_auth.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <sys/types.h> -#include <string.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sechash.h> -#include <fcntl.h> -#include <stdio.h> -#include <errno.h> - -/* Local includes */ -#include "xvm.h" -#include "simple_auth.h" -#include "debug.h" - - -void -print_hash(unsigned char *hash, size_t hashlen) -{ - int x; - - for (x = 0; x < hashlen; x++) - printf("%02x", (hash[x]&0xff)); -} - - -static void -sha_sign(fence_req_t *req, void *key, size_t key_len) -{ - unsigned char hash[SHA512_LENGTH]; - HASHContext *h; - HASH_HashType ht; - unsigned int rlen; - int devrand; - - switch(req->hashtype) { - case HASH_SHA1: - ht = HASH_AlgSHA1; - break; - case HASH_SHA256: - ht = HASH_AlgSHA256; - break; - case HASH_SHA512: - ht = HASH_AlgSHA512; - break; - default: - return; - } - - dbg_printf(4, "Opening /dev/urandom\n"); - devrand = open("/dev/urandom", O_RDONLY); - if (devrand >= 0) { - if (read(devrand, req->random, sizeof(req->random)) < 0) { - perror("read /dev/urandom"); - } - close(devrand); - } - - memset(hash, 0, sizeof(hash)); - h = HASH_Create(ht); - if (!h) - return; - - HASH_Begin(h); - HASH_Update(h, key, key_len); - HASH_Update(h, (void *)req, sizeof(*req)); - HASH_End(h, hash, &rlen, sizeof(hash)); - HASH_Destroy(h); - - memcpy(req->hash, hash, sizeof(req->hash)); -} - - -static int -sha_verify(fence_req_t *req, void *key, size_t key_len) -{ - unsigned char hash[SHA512_LENGTH]; - unsigned char pkt_hash[SHA512_LENGTH]; - HASHContext *h = NULL; - HASH_HashType ht; - unsigned int rlen; - int ret; - - switch(req->hashtype) { - case HASH_SHA1: - ht = HASH_AlgSHA1; - break; - case HASH_SHA256: - ht = HASH_AlgSHA256; - break; - case HASH_SHA512: - ht = HASH_AlgSHA512; - break; - default: - dbg_printf(3, "%s: no-op (HASH_NONE)\n", __FUNCTION__); - return 0; - } - - memset(hash, 0, sizeof(hash)); - h = HASH_Create(ht); - if (!h) - return 0; - - memcpy(pkt_hash, req->hash, sizeof(pkt_hash)); - memset(req->hash, 0, sizeof(req->hash)); - - HASH_Begin(h); - HASH_Update(h, key, key_len); - HASH_Update(h, (void *)req, sizeof(*req)); - HASH_End(h, hash, &rlen, sizeof(hash)); - HASH_Destroy(h); - - memcpy(req->hash, pkt_hash, sizeof(req->hash)); - - ret = !memcmp(hash, pkt_hash, sizeof(hash)); - if (!ret) { - printf("Hash mismatch:\nPKT = "); - print_hash(pkt_hash, sizeof(pkt_hash)); - printf("\nEXP = "); - print_hash(hash, sizeof(hash)); - printf("\n"); - } - - return ret; -} - - -int -sign_request(fence_req_t *req, void *key, size_t key_len) -{ - memset(req->hash, 0, sizeof(req->hash)); - switch(req->hashtype) { - case HASH_NONE: - dbg_printf(3, "%s: no-op (HASH_NONE)\n", __FUNCTION__); - return 0; - case HASH_SHA1: - case HASH_SHA256: - case HASH_SHA512: - sha_sign(req, key, key_len); - return 0; - default: - break; - } - return -1; -} - - -int -verify_request(fence_req_t *req, fence_hash_t min, - void *key, size_t key_len) -{ - if (req->hashtype < min) { - printf("Hash type not strong enough (%d < %d)\n", - req->hashtype, min); - return 0; - } - switch(req->hashtype) { - case HASH_NONE: - return 1; - case HASH_SHA1: - case HASH_SHA256: - case HASH_SHA512: - return sha_verify(req, key, key_len); - default: - break; - } - return 0; -} - - -int -sha_challenge(int fd, fence_auth_type_t auth, void *key, - size_t key_len, int timeout) -{ - fd_set rfds; - struct timeval tv; - unsigned char hash[MAX_HASH_LENGTH]; - unsigned char challenge[MAX_HASH_LENGTH]; - unsigned char response[MAX_HASH_LENGTH]; - int devrand; - int ret; - HASHContext *h; - HASH_HashType ht; - unsigned int rlen; - - devrand = open("/dev/urandom", O_RDONLY); - if (read(devrand, challenge, sizeof(challenge)) < 0) { - perror("read /dev/urandom"); - return 0; - } - close(devrand); - - if (write(fd, challenge, sizeof(challenge)) < 0) { - perror("write"); - return 0; - } - - switch(auth) { - case HASH_SHA1: - ht = HASH_AlgSHA1; - break; - case HASH_SHA256: - ht = HASH_AlgSHA256; - break; - case HASH_SHA512: - ht = HASH_AlgSHA512; - break; - default: - return 0; - } - - memset(hash, 0, sizeof(hash)); - h = HASH_Create(ht); - if (!h) - return 0; - - HASH_Begin(h); - HASH_Update(h, key, key_len); - HASH_Update(h, challenge, sizeof(challenge)); - HASH_End(h, hash, &rlen, sizeof(hash)); - HASH_Destroy(h); - - memset(response, 0, sizeof(response)); - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = timeout; - tv.tv_usec = 0; - if (select(fd + 1, &rfds, NULL, NULL, &tv) <= 0) { - perror("select"); - return 0; - } - - if (read(fd, response, sizeof(response)) < sizeof(response)) { - perror("read"); - return 0; - } - - ret = !memcmp(response, hash, sizeof(response)); - if (!ret) { - printf("Hash mismatch:\nC = "); - print_hash(challenge, sizeof(challenge)); - printf("\nH = "); - print_hash(hash, sizeof(hash)); - printf("\nR = "); - print_hash(response, sizeof(response)); - printf("\n"); - } - - return ret; -} - - -int -sha_response(int fd, fence_auth_type_t auth, void *key, - size_t key_len, int timeout) -{ - fd_set rfds; - struct timeval tv; - unsigned char challenge[MAX_HASH_LENGTH]; - unsigned char hash[MAX_HASH_LENGTH]; - HASHContext *h; - HASH_HashType ht; - unsigned int rlen; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = timeout; - tv.tv_usec = 0; - if (select(fd + 1, &rfds, NULL, NULL, &tv) <= 0) { - perror("select"); - return 0; - } - - if (read(fd, challenge, sizeof(challenge)) < 0) { - perror("read"); - return 0; - } - - switch(auth) { - case AUTH_SHA1: - ht = HASH_AlgSHA1; - break; - case AUTH_SHA256: - ht = HASH_AlgSHA256; - break; - case AUTH_SHA512: - ht = HASH_AlgSHA512; - break; - default: - dbg_printf(3, "%s: no-op (AUTH_NONE)\n", __FUNCTION__); - return 0; - } - - memset(hash, 0, sizeof(hash)); - h = HASH_Create(ht); /* */ - if (!h) - return 0; - - HASH_Begin(h); - HASH_Update(h, key, key_len); - HASH_Update(h, challenge, sizeof(challenge)); - HASH_End(h, hash, &rlen, sizeof(hash)); - HASH_Destroy(h); - - if (write(fd, hash, sizeof(hash)) < sizeof(hash)) { - perror("read"); - return 0; - } - - return 1; -} - - -int -tcp_challenge(int fd, fence_auth_type_t auth, void *key, size_t key_len, - int timeout) -{ - switch(auth) { - case AUTH_NONE: - dbg_printf(3, "%s: no-op (AUTH_NONE)\n", __FUNCTION__); - return 1; - case AUTH_SHA1: - case AUTH_SHA256: - case AUTH_SHA512: - return sha_challenge(fd, auth, key, key_len, timeout); - default: - break; - } - return -1; -} - - -int -tcp_response(int fd, fence_auth_type_t auth, void *key, size_t key_len, - int timeout) -{ - switch(auth) { - case AUTH_NONE: - dbg_printf(3, "%s: no-op (AUTH_NONE)\n", __FUNCTION__); - return 1; - case AUTH_SHA1: - case AUTH_SHA256: - case AUTH_SHA512: - return sha_response(fd, auth, key, key_len, timeout); - default: - break; - } - return -1; -} - - -int -read_key_file(char *file, char *key, size_t max_len) -{ - int fd; - int nread, remain = max_len; - char *p; - - dbg_printf(3, "Reading in key file %s into %p (%d len)", - file, key, (int)max_len); - fd = open(file, O_RDONLY); - if (fd < 0) { - return -1; - } - - memset(key, 0, max_len); - p = key; - remain = max_len; - - while (remain) { - nread = read(fd, p, remain); - if (nread < 0) { - dbg_printf(2, "Error from read: %s\n", strerror(errno)); - close(fd); - return -1; - } - - if (nread == 0) { - dbg_printf(3, "Stopped reading @ %d bytes", - (int)max_len-remain); - break; - } - - p += nread; - remain -= nread; - } - - close(fd); - dbg_printf(3, "Actual key length = %d bytes", (int)max_len-remain); - - return (int)(max_len - remain); -} diff --git a/fence/agents/xvm/simple_auth.h b/fence/agents/xvm/simple_auth.h deleted file mode 100644 index eb65836..0000000 --- a/fence/agents/xvm/simple_auth.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _XVM_SIMPLE_AUTH_H -#define _XVM_SIMPLE_AUTH_H - -#include <sys/types.h> - -/* 2-way challenge/response simple auth */ -#define DEFAULT_KEY_FILE "/etc/cluster/fence_xvm.key" - -int read_key_file(char *, char *, size_t); -int tcp_challenge(int, fence_auth_type_t, void *, size_t, int); -int tcp_response(int, fence_auth_type_t, void *, size_t, int); -int sign_request(fence_req_t *, void *, size_t); -int verify_request(fence_req_t *, fence_hash_t, void *, size_t); - -/* SSL certificate-based authentication TBD */ - -#endif diff --git a/fence/agents/xvm/tcp.c b/fence/agents/xvm/tcp.c deleted file mode 100644 index 3d05628..0000000 --- a/fence/agents/xvm/tcp.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2004, 2006 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * - * @author Lon H. Hohberger <lhh at redhat.com> - * @author Jeff Moyer <jmoyer at redhat.com> - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/types.h> -#include <arpa/inet.h> - -#include "debug.h" - -static int connect_nb(int fd, struct sockaddr *dest, socklen_t len, int timeout); - -/** - Set close-on-exec bit option for a socket. - - @param fd Socket to set CLOEXEC flag - @return 0 on success, -1 on failure - @see fcntl - */ -static int -set_cloexec(int fd) -{ - int flags = fcntl(fd, F_GETFD, 0); - flags |= FD_CLOEXEC; - return fcntl(fd, F_SETFD, flags); -} - - -/** - Bind to a port on the local IPv6 stack - - @param port Port to bind to - @param backlog same as backlog for listen(2) - @return 0 on success, -1 on failure - @see ipv4_bind - */ -int -ipv6_listen(uint16_t port, int backlog) -{ - struct sockaddr_in6 _sin6; - int fd, ret; - - dbg_printf(4, "%s: Setting up ipv6 listen socket\n", __FUNCTION__); - fd = socket(PF_INET6, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - memset(&_sin6, 0, sizeof(_sin6)); - _sin6.sin6_family = PF_INET6; - _sin6.sin6_port = htons(port); - _sin6.sin6_flowinfo = 0; - _sin6.sin6_addr = in6addr_any; - - ret = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ret, sizeof (ret)); - - ret = set_cloexec(fd); - if (ret < 0) { - close(fd); - return -1; - } - - ret = bind(fd, (struct sockaddr *)&_sin6, sizeof(_sin6)); - if (ret < 0) { - close(fd); - return -1; - } - - if (listen(fd, backlog) < 0){ - close(fd); - return -1; - } - - dbg_printf(4, "%s: Success; fd = %d\n", __FUNCTION__, fd); - return fd; -} - - -/** - Bind to a port on the local IPv4 stack - - @param port Port to bind to - @param backlog same as backlog for listen(2) - @return 0 on success, -1 on failure - @see ipv6_bind - */ -int -ipv4_listen(uint16_t port, int backlog) -{ - struct sockaddr_in _sin; - int fd, ret; - - dbg_printf(4, "%s: Setting up ipv4 listen socket\n", __FUNCTION__); - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - _sin.sin_family = PF_INET; - _sin.sin_port = htons(port); - _sin.sin_addr.s_addr = htonl(INADDR_ANY); - - ret = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ret, sizeof (ret)); - - ret = set_cloexec(fd); - if (ret < 0) { - close(fd); - return -1; - } - - ret = bind(fd, (struct sockaddr *)&_sin, sizeof(_sin)); - if (ret < 0) { - close(fd); - return -1; - } - - if (listen(fd, backlog) < 0){ - close(fd); - return -1; - } - - dbg_printf(4, "%s: Success; fd = %d\n", __FUNCTION__, fd); - return fd; -} - - - -/** - Connect via ipv6 socket to a given IP address and port. - - @param in6_addr IPv6 address to connect to - @param port Port to connect to - @param timeout Timeout, in seconds, to wait for a completed - connection - @return 0 on success, -1 on failure - @see connect_nb, ipv4_connect - */ -int -ipv6_connect(struct in6_addr *in6_addr, uint16_t port, int timeout) -{ - struct sockaddr_in6 _sin6; - int fd, ret; - - dbg_printf(4, "%s: Connecting to client\n", __FUNCTION__); - fd = socket(PF_INET6, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - memset(&_sin6, 0, sizeof(_sin6)); - _sin6.sin6_family = PF_INET6; - _sin6.sin6_port = htons(port); - _sin6.sin6_flowinfo = 0; - memcpy(&_sin6.sin6_addr, in6_addr, sizeof(_sin6.sin6_addr)); - - ret = connect_nb(fd, (struct sockaddr *)&_sin6, sizeof(_sin6), timeout); - if (ret < 0) { - close(fd); - return -1; - } - dbg_printf(4, "%s: Success; fd = %d\n", __FUNCTION__, fd); - return fd; -} - - -/** - Connect via ipv4 socket to a given IP address and port. - - @param in_addr IPv4 address to connect to - @param port Port to connect to - @param timeout Timeout, in seconds, to wait for a completed - connection - @return 0 on success, -1 on failure - @see connect_nb, ipv6_connect - */ -int -ipv4_connect(struct in_addr *in_addr, uint16_t port, int timeout) -{ - struct sockaddr_in _sin; - int fd, ret; - - dbg_printf(4, "%s: Connecting to client\n", __FUNCTION__); - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - _sin.sin_family = PF_INET; - _sin.sin_port = htons(port); - memcpy(&_sin.sin_addr, in_addr, sizeof(_sin.sin_addr)); - - ret = connect_nb(fd, (struct sockaddr *)&_sin, sizeof(_sin), timeout); - if (ret < 0) { - close(fd); - return -1; - } - - dbg_printf(4, "%s: Success; fd = %d\n", __FUNCTION__, fd); - return fd; -} - - -/** - Connect in a non-blocking fashion to the designated address. - - @param fd File descriptor to connect - @param dest sockaddr (ipv4 or ipv6) to connect to. - @param len Length of dest - @param timeout Timeout, in seconds, to wait for a completed - connection. - @return 0 on success, -1 on failure. - */ -static int -connect_nb(int fd, struct sockaddr *dest, socklen_t len, int timeout) -{ - int ret, flags = 1, err; - unsigned l; - fd_set rfds, wfds; - struct timeval tv; - - /* - * Use TCP Keepalive - */ - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, - sizeof(flags))<0) - return -1; - - /* - Set up non-blocking connect - */ - flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); - - ret = connect(fd, dest, len); - - if ((ret < 0) && (errno != EINPROGRESS)) - return -1; - - if (ret != 0) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - FD_ZERO(&wfds); - FD_SET(fd, &wfds); - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - if (select(fd + 1, &rfds, &wfds, NULL, &tv) == 0) { - errno = ETIMEDOUT; - return -1; - } - /* XXX check for -1 from select */ - - if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds)) { - l = sizeof(err); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, - (void *)&err, &l) < 0) { - close(fd); - return -1; - } - - if (err != 0) { - close(fd); - errno = err; - return -1; - } - - fcntl(fd, F_SETFL, flags); - return 0; - } - } - - errno = EIO; - return -1; -} diff --git a/fence/agents/xvm/tcp.h b/fence/agents/xvm/tcp.h deleted file mode 100644 index addf987..0000000 --- a/fence/agents/xvm/tcp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _XVM_TCP_H -#define _XVM_TCP_H - -int ipv4_connect(struct in_addr *in_addr, uint16_t port, int timeout); -int ipv6_connect(struct in6_addr *in6_addr, uint16_t port, int timeout); -int ipv4_listen(uint16_t port, int backlog); -int ipv6_listen(uint16_t port, int backlog); - -#endif diff --git a/fence/agents/xvm/xvm.h b/fence/agents/xvm/xvm.h deleted file mode 100644 index a423e67..0000000 --- a/fence/agents/xvm/xvm.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _XVM_H -#define _XVM_H - -#include <stdint.h> -#include <sechash.h> -#include <netinet/in.h> - -#define XVM_VERSION "0.9.3" - -#define MAX_DOMAINNAME_LENGTH 64 /* XXX MAXHOSTNAMELEN */ -#define MAX_ADDR_LEN sizeof(struct sockaddr_in6) -#define DOMAIN0NAME "Domain-0" -#define DOMAIN0UUID "00000000-0000-0000-0000-000000000000" - -typedef enum { - HASH_NONE = 0x0, /* No packet signing */ - HASH_SHA1 = 0x1, /* SHA1 signing */ - HASH_SHA256 = 0x2, /* SHA256 signing */ - HASH_SHA512 = 0x3 /* SHA512 signing */ -} fence_hash_t; - -#define DEFAULT_HASH HASH_SHA256 - -typedef enum { - AUTH_NONE = 0x0, /* Plain TCP */ - AUTH_SHA1 = 0x1, /* Challenge-response (SHA1) */ - AUTH_SHA256 = 0x2, /* Challenge-response (SHA256) */ - AUTH_SHA512 = 0x3, /* Challenge-response (SHA512) */ - /* AUTH_SSL_X509 = 0x10 SSL X509 certificates */ -} fence_auth_type_t; - -#define DEFAULT_AUTH AUTH_SHA256 - -typedef enum { - FENCE_NULL = 0x0, - FENCE_OFF = 0x1, /* Turn the VM off */ - FENCE_REBOOT = 0x2 /* Hit the reset button */ - /* FENCE_ON = 0x3 Turn the VM on */ -} fence_cmd_t; - -#define MAX_HASH_LENGTH SHA512_LENGTH - -typedef struct __attribute__ ((packed)) _fence_req { - uint8_t request; /* Fence request */ - uint8_t hashtype; /* Hash type used */ - uint8_t addrlen; /* Length of address */ - uint8_t flags; /* Special flags */ -#define RF_UUID 0x1 /* Flag specifying UUID */ - uint8_t domain[MAX_DOMAINNAME_LENGTH]; /* Domain to fence*/ - uint8_t address[MAX_ADDR_LEN]; /* We're this IP */ - uint16_t port; /* Port we bound to */ - uint8_t random[10]; /* Random Data */ - uint32_t family; /* Address family */ - uint8_t hash[MAX_HASH_LENGTH]; /* Binary hash */ -} fence_req_t; - - -#endif diff --git a/fence/agents/zvm/Makefile b/fence/agents/zvm/Makefile deleted file mode 100644 index 8717b16..0000000 --- a/fence/agents/zvm/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -SOURCE= fence_zvm.pl -TARGET= fence_zvm - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -all: $(TARGET) - -$(TARGET): $(SOURCE) - : > $(TARGET) - awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) - echo "$$FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) - ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl REDHAT_COPYRIGHT >> $(TARGET) - echo "$$BUILD_DATE="(built `date`)";" >> $(TARGET) - awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) - chmod +x $(TARGET) - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin/${TARGET} - -clean: - rm -f $(TARGET) - - diff --git a/fence/agents/zvm/fence_zvm.pl b/fence/agents/zvm/fence_zvm.pl deleted file mode 100755 index a5ee0d0..0000000 --- a/fence/agents/zvm/fence_zvm.pl +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use IPC::Open2; - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*///; -my $pname = $_; - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -$comm_program = s3270; -$debug = 0; -$max_loops = 10; - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of the physical s390\n"; - print " -h usage\n"; - print " -u <string> userid of the virtual machine to fence\n"; - print " -p <string> Password\n"; - print " -S <path> Script to run to retrieve login password\n"; - print " -q quiet mode\n"; - print " -r <devnum> ipl device <devnum>\n"; - print " -V Version\n"; - - exit 0; -} - -sub fail -{ - ($msg)=@_; - print "failed: " . $msg . "\n" unless defined $opt_q; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print stderr $msg."\n" if $msg; - print stderr "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - - -sub do_read -{ - my($line); - - $line = <READ_H>; - - if ($debug) - { - my($l) = ($line); - $l =~ s/\n//; - print "read: $l\n"; - } - - return $line; -} - -sub do_write -{ - my($line) = @_; - - if ($debug) - { - my($l) = ($line); - $l =~ s/\n//; - print "write: $l\n"; - } - - print WRITE_H $line; -} - - -sub look_for -{ - my ($text, $found); - $found = 0; - ($text) = @_; - &do_write("ascii\n"); - while(1){ - $_ = &do_read; - last unless (/^data:/); - $found = 1 if (/$text/); - } - $_ = &do_read; - fail "error while looking for string '$text'." unless (/ok/); - return $found; -} - -sub in_cp_read_state -{ - my ($prev); - $_ = ""; - &do_write("ascii\n"); - while (1){ - $prev = $_; - $_ = &do_read; - last unless (/^data:/); - } - $_ = &do_read; - fail "error while looking for machine state." unless (/ok/); - return 1 if ($prev =~ /CP READ/i); - return 0; -} - -sub send_wait -{ - &do_write("wait\n"); - $_ = &do_read; - $_ = &do_read; - if (/ok/){ - return 1; - } - return 0; -} - -sub send_string -{ - my ($cmd); - ($cmd) = @_; - &do_write('string "' . $cmd . '\n"' . "\n"); - $_ = &do_read; - $_ = &do_read; - if (/ok/){ - return send_wait; - } - return 0; -} - -sub send_cmd -{ - my ($cmd); - ($cmd) = @_; - &do_write($cmd . "\n"); - $_ = &do_read; - $_ = &do_read; - if (/ok/){ - return send_wait; - } - return 0; -} - -sub wait_for_response -{ - my ($pass, $failure, $msg, $found, $loops); - $loops = 0; - $found = 0; - ($pass, $failure, $msg) = @_; - while (1){ - $loops = $loops + 1; - fail "timed out waiting for '$pass'" if ($loops > $max_loops); - &do_write("ascii\n"); - while(1){ - $_ = &do_read; - chomp; - last unless (/^data:/); - $found = 1 if (/$pass/); - if ($failure){ - fail("$msg '$_'") if (/$failure/); - } - } - $_ = &do_read; - fail "wait for response failed '$_'" unless (/ok/); - last if $found; - sleep 1; - } - return 0; -} - -sub check_response -{ - ($action) = @_; - $_ = &do_read; - $_ = &do_read; - fail "$action failed." unless (/ok/); -} - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print stderr "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced or stomithd - elsif ($name eq "agent" ) { } - - # FIXME -- depricated. use "userid" and "password" instead. - elsif ($name eq "fm" ) - { - (my $dummy,$opt_u,$opt_p) = split /\s+/,$val; - print STDERR "Depricated "fm" entry detected. refer to man page.\n"; - } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - - elsif ($name eq "ipl" ) - { - $opt_r = $val; - } - - # FIXME -- depreicated residue of old fencing system - elsif ($name eq "name" ) { } - - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "passwd_script" ) - { - $opt_S = $val; - } - elsif ($name eq "userid" ) - { - $opt_u = $val; - } - - else - { - print stderr "parse error: unknown option "$opt"\n"; - #> exit 2; - } - } -} - -if (@ARGV > 0){ - getopts("a:hp:S:qr:u:V") || fail_usage; - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unkown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - fail_usage "No '-u' flag specified." unless defined $opt_u; - -} else { - get_options_stdin(); - - fail "no IP address" unless defined $opt_a; - fail "no userid" unless defined $opt_u; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail "no password" unless defined $opt_p; -} - -$pid = open2(READ_H, WRITE_H, "$comm_program 2>&1"); -&do_write("connect $opt_a\n"); -$_ = &do_read; -unless (/^U U U/){ - chomp; - fail "communication program failed with '$_'."; -} -$_ = &do_read; -fail "couldn't connect to $opt_a." unless(/ok/); -send_wait or fail "couldn't start 3270 session on $opt_a."; -send_cmd "enter" or fail "couldn't reach logon prompt."; -look_for "Enter one of the following commands:" or fail "doesn't look like a login prompt\n"; -send_string "logon $opt_u $opt_p norun here" or fail "couldn't login"; -send_cmd "clear" or fail "couldn't send the clear command."; -send_string "#cp query userid"; -wait_for_response(uc($opt_u),"Enter one of the following commands:", "logon failed"); -fail "machine not in CP READ state" unless in_cp_read_state; -if (defined $opt_r){ - send_string "ipl $opt_r" or fail "couldn't send reboot command"; -} else { - send_string "stop" or fail "couldn't send stop command\n"; -} -fail "command failed" if look_for "Unknown CP command"; -if (defined $opt_r && !in_cp_read_state){ - send_string "#cp disc"; -} else { - &do_write("disconnect\n"); -} -&do_write("quit\n"); - -print "success: booted userid $opt_u\n" unless defined $opt_q; - -exit 0; diff --git a/fence/bin/Makefile b/fence/bin/Makefile deleted file mode 100644 index e611ad2..0000000 --- a/fence/bin/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. - -UNINSTALL= ${top_srcdir}/scripts/uninstall.pl - -SBINPROGS= \ - fence_ack_manual \ - fence_apc \ - fence_apc_snmp \ - fence_rsa \ - fence_rsb \ - fence_bladecenter \ - fence_baytech \ - fence_brocade \ - fence_drac \ - fence_drac5 \ - fence_egenera \ - fence_ilo \ - fence_manual \ - fence_mcdata \ - fence_node \ - fence_sanbox2 \ - fence_tool \ - fence_vixel \ - fence_wti \ - fence_rps10 \ - fence_bullpap \ - fence_ipmilan \ - fence_lpar \ - fence_xvm \ - fence_scsi \ - fence_scsi_test \ - fenced - -SHAREPROGS = \ - powernet369.mib \ - README_SNMP - -FENCEPYLIB = \ - fencing.py - -include ${top_srcdir}/make/defines.mk - -all: - cd ..; ${MAKE} all - -clean: - @echo -n Removing all copied files... - @for f in `ls . | grep -v -i "makefile|cvs"`; do rm -f $$f; done - @echo done. - -install: all - if [ ! -d ${sbindir} ]; then \ - install -d ${sbindir}; \ - fi - for v in ${SBINPROGS}; do \ - install -m755 $${v} ${sbindir}; \ - done - if [ ! -d ${sharedir} ]; then \ - install -d ${sharedir}; \ - fi - for v in ${SHAREPROGS}; do \ - install -m644 $${v} ${sharedir}; \ - done - if [ ! -d ${DESTDIR}/usr/lib/fence ]; then \ - install -d ${DESTDIR}/usr/lib/fence; \ - fi - for v in ${FENCEPYLIB}; do \ - install -m644 $${v} ${DESTDIR}/usr/lib/fence; \ - done - install -m755 telnet_ssl ${DESTDIR}/usr/lib/fence - -uninstall: - ${UNINSTALL} ${SBINPROGS} ${sbindir} - ${UNINSTALL} ${FENCEPYLIB} telnet_ssl ${DESTDIR}/usr/lib/fence diff --git a/fence/config/copyright.cf b/fence/config/copyright.cf deleted file mode 100644 index 8847c05..0000000 --- a/fence/config/copyright.cf +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) Red Hat, Inc. 2004 All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __COPYRIGHT_DOT_CF__ -#define __COPYRIGHT_DOT_CF__ - -#define REDHAT_COPYRIGHT ("Copyright (C) Red Hat, Inc. 2004 All rights reserved.") - -#endif /* __COPYRIGHT_DOT_CF__ */ - - - diff --git a/fence/configure b/fence/configure deleted file mode 100755 index dd4d532..0000000 --- a/fence/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/fence/fence_node/Makefile b/fence/fence_node/Makefile deleted file mode 100644 index e7dd301..0000000 --- a/fence/fence_node/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET = fence_node - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/make/uninstall.pl - -ifeq ($(DEBUG),y) -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DDEBUG -g -DFENCE_RELEASE_NAME="${RELEASE}" -else -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DFENCE_RELEASE_NAME="${RELEASE}" -endif - -INCLUDE = -I${top_srcdir}/include -I${incdir} -I${top_srcdir}/config - -LDFLAGS+= -L${libdir} -LOADLIBES+= -lccs - -FENCE_NODE_SRC = \ - agent.c \ - fence_node.c - -all: ${TARGET} - -fence_node: ${FENCE_NODE_SRC:.c=.o} - ${CC} ${CFLAGS} ${INCLUDE} ${FENCE_NODE_SRC:.c=.o} ${LDFLAGS} ${LOADLIBES} ${LDLIBS} -o $@ - -agent.c: - ln -s ${top_srcdir}/fenced/agent.c . - -copytobin: all - strip ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -rf *~ *.o ${TARGET} agent.c diff --git a/fence/fence_node/fence_node.c b/fence/fence_node/fence_node.c deleted file mode 100644 index f52706a..0000000 --- a/fence/fence_node/fence_node.c +++ /dev/null @@ -1,120 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <syslog.h> - -#include "copyright.cf" -#include "ccs.h" - -#define OPTION_STRING ("hOuV") - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt "\n", ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -static char *prog_name; -static int force; - -int dispatch_fence_agent(char *victim, int force); - -static void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options] node_name\n", prog_name); - printf("\n"); - printf("Options:\n"); - printf("\n"); - printf(" -h Print this help, then exit\n"); - printf(" -O Force connection to CCS\n"); - printf(" -V Print program version information, then exit\n"); - printf("\n"); -} - -int main(int argc, char *argv[]) -{ - int cont = 1, optchar, error, cd; - char *victim = NULL; - - prog_name = argv[0]; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case 'O': - force = 1; - break; - - case 'V': - printf("%s %s (built %s %s)\n", prog_name, - FENCE_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case EOF: - cont = 0; - break; - - default: - die("unknown option: %c", optchar); - break; - }; - } - - while (optind < argc) { - if (victim) - die("unknown option %s", argv[optind]); - victim = argv[optind]; - optind++; - } - - if (!victim) - die("no node name specified"); - - openlog("fence_node", LOG_PID, LOG_USER); - - error = dispatch_fence_agent(victim, force); - if (error) - goto fail; - - syslog(LOG_NOTICE, "Fence of "%s" was successful\n", victim); - exit(EXIT_SUCCESS); - - fail: - syslog(LOG_ERR, "Fence of "%s" was unsuccessful\n", victim); - exit(EXIT_FAILURE); -} - diff --git a/fence/fence_tool/Makefile b/fence/fence_tool/Makefile deleted file mode 100644 index 44ec095..0000000 --- a/fence/fence_tool/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET = fence_tool - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/make/uninstall.pl - -ifeq ($(DEBUG),y) -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DDEBUG -g -DFENCE_RELEASE_NAME="${RELEASE}" -else -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DFENCE_RELEASE_NAME="${RELEASE}" -endif - -INCLUDE = -I${top_srcdir}/include -I${incdir} -I${top_srcdir}/config - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -INCLUDE += -I${incdir}/cluster -endif - -LDFLAGS+= -L${libdir} -LOADLIBES+= -lccs - -FENCE_TOOL_SRC = \ - agent.c \ - fence_tool.c - -all: ${TARGET} - -fence_tool: ${FENCE_TOOL_SRC:.c=.o} - ${CC} ${CFLAGS} ${INCLUDE} ${FENCE_TOOL_SRC:.c=.o} ${LDFLAGS} ${LOADLIBES} ${LDLIBS} -o $@ - -agent.c: - ln -s ${top_srcdir}/fenced/agent.c . - -copytobin: all - strip ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -rf *~ *.o ${TARGET} agent.c diff --git a/fence/fence_tool/fence_tool.c b/fence/fence_tool/fence_tool.c deleted file mode 100644 index a14ad25..0000000 --- a/fence/fence_tool/fence_tool.c +++ /dev/null @@ -1,553 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <signal.h> -#include <string.h> -#include <stdint.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <fcntl.h> -#include <errno.h> -#include <mntent.h> -#include <libgen.h> - -#include "cnxman-socket.h" -#include "ccs.h" -#include "copyright.cf" - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#define OPTION_STRING ("VhScj:f:t:DwQ") -#define LOCKFILE_NAME "/var/run/fenced.pid" -#define FENCED_SOCK_PATH "fenced_socket" - -#define OP_JOIN 1 -#define OP_LEAVE 2 -#define OP_MONITOR 3 -#define OP_WAIT 4 - - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt "\n", ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -char *prog_name; -int debug; -int operation; -int child_wait; -int quorum_wait = TRUE; -int fenced_timeout = 0; -int signalled = 0; -int cl_sock; -char our_name[MAX_CLUSTER_MEMBER_NAME_LEN+1]; - -int dispatch_fence_agent(char *victim, int force); - - -static int check_mounted(void) -{ - FILE *fp; - struct mntent *me; - - fp = setmntent("/etc/mtab", "r"); - - for (;;) { - me = getmntent(fp); - if (!me) - break; - - if (!strcmp(me->mnt_type, "gfs")) - die("cannot leave, gfs mounted on %s", - me->mnt_fsname); - } - return 0; -} - -static void sigalarm_handler(int sig) -{ - signalled = 1; -} - -static int get_int_arg(char argopt, char *arg) -{ - char *tmp; - int val; - val = strtol(arg, &tmp, 10); - if (tmp == arg || tmp != arg + strlen(arg)) - die("argument to %c (%s) is not an integer", argopt, arg); - - if (val < 0) - die("argument to %c cannot be negative", argopt); - - return val; -} - - - -static void lockfile(void) -{ - int fd, error; - struct flock lock; - - fd = open(LOCKFILE_NAME, O_RDWR, 0); - if (fd < 0) - die("fenced not running - no %s", LOCKFILE_NAME); - - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - error = fcntl(fd, F_SETLK, &lock); - if (!error) - die("fenced is not running"); - - close(fd); -} - -static int setup_sock(void) -{ - cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cl_sock < 0) - die("cannot create cluster socket %d", cl_sock); - - return 0; -} - -static int check_ccs(void) -{ - int i = 0, cd; - - if (debug) - printf("%s: connect to ccs\n", prog_name); - - while ((cd = ccs_connect()) < 0) { - printf("%s: waiting for ccs connection %d\n", prog_name, cd); - sleep(1); - if (++i == 10) - die("cannot connect to ccs %d\n", cd); - } - - return cd; -} - -static int get_our_name(void) -{ - struct cl_cluster_node cl_node; - int rv; - - if (debug) - printf("%s: get our node name\n", prog_name); - - memset(&cl_node, 0, sizeof(struct cl_cluster_node)); - - for (;;) { - rv = ioctl(cl_sock, SIOCCLUSTER_GETNODE, &cl_node); - if (!rv) - break; - printf("%s: retrying cman getnode %d\n", prog_name, rv); - sleep(1); - } - - memcpy(our_name, cl_node.name, strlen(cl_node.name)); - return 0; -} - -/* - * We wait for the cluster to be quorate in this program because it's easy to - * kill this program if we want to quit waiting. If we just started fenced - * without waiting for quorum, fenced's join would then wait for quorum in SM - * but we can't kill/cancel it at that point -- we have to wait for it to - * complete. - * - * A second reason to wait for quorum is that the unfencing step involves - * cluster.conf lookups through ccs, but ccsd may wait for the cluster to be - * quorate before responding to the lookups. There wouldn't be a problem - * blocking there per se, but it's cleaner I think to just wait here first. - * - * In the case where we're leaving, we want to wait for quorum because if we go - * ahead and shut down fenced, the fence domain leave will block in SM where it - * will wait for quorum before the leave can be processed. We can't - * kill/cancel the leave at that point, but we can if we're waiting here. - * - * Waiting here doesn't guarantee we won't end up blocking in SM on the join or - * leave, but it avoids it in some common cases which can be helpful. (Quorum - * could easily be lost between the time we wait for it here and then begin the - * join/leave process.) - */ - -static int check_quorum(void) -{ - int rv, i = 0; - - if (debug) - printf("%s: wait for quorum %d\n", prog_name, quorum_wait); - - while (!signalled) { - rv = ioctl(cl_sock, SIOCCLUSTER_ISACTIVE, NULL); - if (!rv) - die("cluster is not active"); - - rv = ioctl(cl_sock, SIOCCLUSTER_ISQUORATE, NULL); - if (rv) - return TRUE; - else if (!quorum_wait) - return FALSE; - - sleep(1); - - if (!signalled && ++i > 9 && !(i % 10)) - printf("%s: waiting for cluster quorum\n", prog_name); - } - - errno = ETIMEDOUT; - return FALSE; -} - -/* - * This is a really lousy way of waiting, which is why I took so long to add - * it. I guess it's better than nothing for a lot of people. The state may - * not be "run" if we've joined but other nodes are joining/leaving. - */ - -static int do_wait(void) -{ - FILE *file; - char line[256]; - int error, i = 0, starting = 0; - - file = fopen("/proc/cluster/services", "r"); - if (!file) - return EXIT_FAILURE; - - while (!signalled) { - memset(line, 0, 256); - while (fgets(line, 256, file)) { - if (strstr(line, "Fence Domain")) { - if (strstr(line, "run")) { - error = EXIT_SUCCESS; - goto out; - } - starting = 1; - } - } - - if (++i > 9 && !(i % 10)) - printf("%s: waiting for fence domain run state\n", - prog_name); - if (i == 10 && !starting) { - printf("%s: fenced not starting\n", prog_name); - return EXIT_FAILURE; - } - sleep(1); - rewind(file); - } - errno = ETIMEDOUT; - error = EXIT_FAILURE; - - out: - fclose(file); - return error; -} - -static int do_join(int argc, char *argv[]) -{ - int cd; - - setup_sock(); - - if (fenced_timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(fenced_timeout); - } - - if (!check_quorum()) { - if (errno == ETIMEDOUT) - printf("%s: Timed out waiting for cluster " - "quorum to form.\n", prog_name); - return EXIT_FAILURE; - } - - get_our_name(); - close(cl_sock); - cd = check_ccs(); - ccs_disconnect(cd); - - /* Options for fenced can be given to this program which then passes - them on to fenced when it's started (now). We just manipulate the - args for this program a bit before passing them on to fenced. We - change the program name in argv[0] and remove the "join" which - getopt places as the last argv. - - Fenced shouldn't barf if it gets any args specific to this program */ - - if (debug) - printf("%s: start fenced\n", prog_name); - - if (!debug && child_wait) { - int status; - pid_t pid = fork(); - - /* parent waits for fenced to join */ - if (pid > 0) { - waitpid(pid, &status, 0); - if (WIFEXITED(status) && - !WEXITSTATUS(status)) { - if (do_wait() == EXIT_SUCCESS) - exit(EXIT_SUCCESS); - - if (errno == ETIMEDOUT) - printf("%s: Timed out waiting " - "for fenced to start.\n", - prog_name); - return EXIT_FAILURE; - } - - /* If we get here, the child died with a signal */ - if (WIFSIGNALED(status)) { - printf("%s: child pid %d died with " - "signal %d\n", prog_name, (int)pid, - WTERMSIG(status)); - } - - return EXIT_FAILURE; - } else if (pid < 0) { - fprintf(stderr, "%s: fork(): %s\n", - prog_name, strerror(errno)); - } - /* child execs fenced */ - } - - strcpy(argv[0], "fenced"); - argv[argc - 1] = NULL; - - execvp("fenced", argv); - die("starting fenced failed"); - - return EXIT_FAILURE; -} - -static int do_leave(void) -{ - FILE *f; - char buf[33] = ""; - int pid = 0, error; - - lockfile(); - - /* get the pid of fenced so we can kill it */ - - f = fopen(LOCKFILE_NAME, "r"); - if (!f) - die("fenced not running - no file %s", LOCKFILE_NAME); - fgets(buf, 33, f); - sscanf(buf, "%d", &pid); - fclose(f); - - check_mounted(); - setup_sock(); - - if (fenced_timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(fenced_timeout); - } - - if (!check_quorum()) { - if (errno == ETIMEDOUT) - printf("%s: Timed out waiting for cluster " - "quorum to form.\n", prog_name); - return EXIT_FAILURE; - } - - close(cl_sock); - - kill(pid, SIGTERM); - error = unlink(LOCKFILE_NAME); - if (error) - die("signal sent, but unable to unlink %s: %s", LOCKFILE_NAME, - strerror(error)); - return EXIT_SUCCESS; -} - -static int do_monitor(void) -{ - int sfd, error, rv; - struct sockaddr_un addr; - socklen_t addrlen; - char buf[256]; - - sfd = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (sfd < 0) - die("cannot create local socket"); - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_LOCAL; - strcpy(&addr.sun_path[1], FENCED_SOCK_PATH); - addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1; - - error = bind(sfd, (struct sockaddr *) &addr, addrlen); - if (error < 0) - die("cannot bind to local socket"); - - for (;;) { - memset(buf, 0, 256); - - rv = recvfrom(sfd, buf, 256, 0, (struct sockaddr *)&addr, - &addrlen); - - printf("%s", buf); - } - - return EXIT_SUCCESS; -} - -static void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s <join|leave|wait> [options]\n", prog_name); - printf("\n"); - printf("Actions:\n"); - printf(" join Join the default fence domain\n"); - printf(" leave Leave default fence domain\n"); - printf(" wait Wait for node to be member of default fence domain\n"); - printf("\n"); - printf("Options:\n"); - printf(" -w Wait for join to complete\n"); - printf(" -V Print program version information, then exit\n"); - printf(" -h Print this help, then exit\n"); - printf(" -t Maximum time in seconds to wait\n"); - printf(" -Q Fail if cluster is not quorate, don't wait\n"); - printf(" -D Enable debugging, don't fork (also passed to fenced)\n"); - printf("\n"); - printf("Fenced options:\n"); - printf(" these are passed on to fenced when it's started\n"); - printf(" -c All nodes are in a clean state to start\n"); - printf(" -j <secs> Post-join fencing delay\n"); - printf(" -f <secs> Post-fail fencing delay\n"); - printf("\n"); -} - -static void decode_arguments(int argc, char *argv[]) -{ - int cont = TRUE; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - - case 'V': - printf("fence_tool %s (built %s %s)\n", - FENCE_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case 'Q': - quorum_wait = FALSE; - break; - - case 'D': - debug = TRUE; - break; - - case 'w': - child_wait = TRUE; - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case EOF: - cont = FALSE; - break; - - case 't': - fenced_timeout = get_int_arg(optchar, optarg); - break; - - case 'c': - case 'j': - case 'f': - /* Do nothing, just pass these options on to fenced */ - break; - - default: - die("unknown option: %c\n", optchar); - break; - } - } - - while (optind < argc) { - if (strcmp(argv[optind], "join") == 0) { - operation = OP_JOIN; - } else if (strcmp(argv[optind], "leave") == 0) { - operation = OP_LEAVE; - } else if (strcmp(argv[optind], "monitor") == 0) { - operation = OP_MONITOR; - } else if (strcmp(argv[optind], "wait") == 0) { - operation = OP_WAIT; - } else - die("unknown option %s\n", argv[optind]); - optind++; - } - - if (!operation) - die("no operation specified\n"); -} - -int main(int argc, char *argv[]) -{ - prog_name = basename(argv[0]); - - decode_arguments(argc, argv); - - switch (operation) { - case OP_JOIN: - return do_join(argc, argv); - case OP_LEAVE: - return do_leave(); - case OP_MONITOR: - return do_monitor(); - case OP_WAIT: - return do_wait(); - } - - return EXIT_FAILURE; -} diff --git a/fence/fenced/Makefile b/fence/fenced/Makefile deleted file mode 100644 index f1f06ef..0000000 --- a/fence/fenced/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -TARGET = fenced - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/make/uninstall.pl - -ifeq ($(DEBUG),y) -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DDEBUG -g -DFENCE_RELEASE_NAME="${RELEASE}" -else -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -DFENCE_RELEASE_NAME="${RELEASE}" -endif - -INCLUDE = -I. -I.. -I${top_srcdir}/include -I${incdir} \ - -I${top_srcdir}/config - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -INCLUDE += -I${incdir}/cluster -endif - -LDFLAGS+= -L${libdir} -LOADLIBES+= -lccs - -FENCED_SRC = \ - main.c \ - recover.c \ - agent.c - -all: ${TARGET} - -fenced: ${FENCED_SRC:.c=.o} - ${CC} ${CFLAGS} ${INCLUDE} ${FENCED_SRC:.c=.o} ${LDFLAGS} ${LOADLIBES} ${LDLIBS} -o $@ -lpthread - -copytobin: all - strip ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -rf *~ *.o ${TARGET} diff --git a/fence/fenced/agent.c b/fence/fenced/agent.c deleted file mode 100644 index f439d14..0000000 --- a/fence/fenced/agent.c +++ /dev/null @@ -1,347 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> - -#include "ccs.h" - -#define MAX_METHODS 8 -#define MAX_DEVICES 8 -#define MAX_AGENT_ARGS_LEN 512 - -#define METHOD_NAME_PATH "/cluster/clusternodes/clusternode[@name="%s"]/fence/method[%d]/@name" -#define DEVICE_NAME_PATH "/cluster/clusternodes/clusternode[@name="%s"]/fence/method[@name="%s"]/device[%d]/@name" -#define NODE_FENCE_ARGS_PATH "/cluster/clusternodes/clusternode[@name="%s"]/fence/method[@name="%s"]/device[%d]/@*" -#define AGENT_NAME_PATH "/cluster/fencedevices/fencedevice[@name="%s"]/@agent" -#define FENCE_DEVICE_ARGS_PATH "/cluster/fencedevices/fencedevice[@name="%s"]/@*" - - - -static void display_agent_output(char *agent, int fd) -{ - char msg[512], buf[256]; - - memset(msg, 0, sizeof(msg)); - memset(buf, 0, sizeof(buf)); - - while (read(fd, buf, sizeof(buf)-1) > 0) { - snprintf(msg, 256, "agent "%s" reports: ", agent); - strcat(msg, buf); - - printf("%s\n", msg); - syslog(LOG_ERR, "%s", msg); - - memset(buf, 0, sizeof(buf)); - memset(msg, 0, sizeof(msg)); - } -} - -static int run_agent(char *agent, char *args) -{ - int pid, status, error, len = strlen(args); - int pr_fd, pw_fd; /* parent read/write file descriptors */ - int cr_fd, cw_fd; /* child read/write file descriptors */ - int fd1[2]; - int fd2[2]; - - cr_fd = cw_fd = pr_fd = pw_fd = -1; - - if (pipe(fd1)) - goto fail; - pr_fd = fd1[0]; - cw_fd = fd1[1]; - - if (pipe(fd2)) - goto fail; - cr_fd = fd2[0]; - pw_fd = fd2[1]; - - pid = fork(); - if (pid < 0) - goto fail; - - if (pid) { - /* parent */ - - fcntl(pr_fd, F_SETFL, fcntl(pr_fd, F_GETFL, 0) | O_NONBLOCK); - - error = write(pw_fd, args, len); - if (error != len) - goto fail; - - close(pw_fd); - waitpid(pid, &status, 0); - - if (!WIFEXITED(status) || WEXITSTATUS(status)) { - display_agent_output(agent, pr_fd); - goto fail; - } - } else { - /* child */ - - close(1); - dup(cw_fd); - close(2); - dup(cw_fd); - close(0); - dup(cr_fd); - /* keep cw_fd open so parent can report all errors. */ - close(pr_fd); - close(cr_fd); - close(pw_fd); - - execlp(agent, agent, NULL); - exit(EXIT_FAILURE); - } - - close(pr_fd); - close(cw_fd); - close(cr_fd); - close(pw_fd); - return 0; - - fail: - close(pr_fd); - close(cw_fd); - close(cr_fd); - close(pw_fd); - return -1; -} - -static int make_args(int cd, char *victim, char *method, int d, char *device, - char **args_out) { - char path[256], *args, *str; - int error; - - args = malloc(MAX_AGENT_ARGS_LEN); - if (!args) - return -ENOMEM; - memset(args, 0, MAX_AGENT_ARGS_LEN); - - /* node-specific args for victim */ - - memset(path, 0, 256); - sprintf(path, NODE_FENCE_ARGS_PATH, victim, method, d+1); - - for (;;) { - error = ccs_get_list(cd, path, &str); - if (error || !str) - break; - - if (!strncmp(str, "name=", 5)) { - free(str); - continue; - } - - strcat(args, str); - strcat(args, "\n"); - free(str); - } - - /* device-specific args */ - - memset(path, 0, 256); - sprintf(path, FENCE_DEVICE_ARGS_PATH, device); - - for (;;) { - error = ccs_get_list(cd, path, &str); - if (error || !str) - break; - - if (!strncmp(str, "name=", 5)) { - free(str); - continue; - } - - strcat(args, str); - strcat(args, "\n"); - free(str); - } - - if (error) { - free(args); - args = NULL; - } - - *args_out = args; - return error; -} - -/* return name of m'th method for nodes/<victim>/fence/ */ - -static int get_method(int cd, char *victim, int m, char **method) -{ - char path[256], *str = NULL; - int error; - - memset(path, 0, 256); - sprintf(path, METHOD_NAME_PATH, victim, m+1); - - error = ccs_get(cd, path, &str); - *method = str; - return error; -} - -/* return name of d'th device under nodes/<victim>/fence/<method>/ */ - -static int get_device(int cd, char *victim, char *method, int d, char **device) -{ - char path[256], *str = NULL; - int error; - - memset(path, 0, 256); - sprintf(path, DEVICE_NAME_PATH, victim, method, d+1); - - error = ccs_get(cd, path, &str); - *device = str; - return error; -} - -static int count_methods(int cd, char *victim) -{ - char path[256], *name; - int error, i; - - for (i = 0; i < MAX_METHODS; i++) { - memset(path, 0, 256); - sprintf(path, METHOD_NAME_PATH, victim, i+1); - - error = ccs_get(cd, path, &name); - if (error) - break; - free(name); - } - return i; -} - -static int count_devices(int cd, char *victim, char *method) -{ - char path[256], *name; - int error, i; - - for (i = 0; i < MAX_DEVICES; i++) { - memset(path, 0, 256); - sprintf(path, DEVICE_NAME_PATH, victim, method, i+1); - - error = ccs_get(cd, path, &name); - if (error) - break; - free(name); - } - return i; -} - -static int use_device(int cd, char *victim, char *method, int d, char *device) -{ - char path[256], *agent, *args = NULL; - int error; - - memset(path, 0, 256); - sprintf(path, AGENT_NAME_PATH, device); - - error = ccs_get(cd, path, &agent); - if (error) - goto out; - - error = make_args(cd, victim, method, d, device, &args); - if (error) - goto out_agent; - - error = run_agent(agent, args); - - free(args); - out_agent: - free(agent); - out: - return error; -} - -int dispatch_fence_agent(char *victim, int force) -{ - char *method = NULL, *device = NULL; - int num_methods, num_devices, m, d, error = -1, cd; - - if (force) - cd = ccs_force_connect(NULL, 0); - else { - while ((cd = ccs_connect()) < 0) - sleep(1); - } - - if (cd < 0) { - syslog(LOG_ERR, "cannot connect to ccs %d\n", cd); - return -1; - } - - num_methods = count_methods(cd, victim); - - for (m = 0; m < num_methods; m++) { - - error = get_method(cd, victim, m, &method); - - /* if the connection timed out while we were trying - * to fence, try to open the connection again - */ - if (error == -EBADR) { - syslog(LOG_INFO, "ccs connection timed out, " - "retrying\n"); - - while ((cd = ccs_connect()) < 0) - sleep(1); - - error = get_method(cd, victim, m, &method); - - if (error) - continue; - } else if (error) - continue; - - /* if num_devices is zero we should return an error */ - error = -1; - - num_devices = count_devices(cd, victim, method); - - for (d = 0; d < num_devices; d++) { - error = get_device(cd, victim, method, d, &device); - if (error) - break; - - error = use_device(cd, victim, method, d, device); - if (error) - break; - - free(device); - device = NULL; - } - - if (device) - free(device); - free(method); - - if (!error) - break; - } - - ccs_disconnect(cd); - - return error; -} - diff --git a/fence/fenced/fd.h b/fence/fenced/fd.h deleted file mode 100644 index f180045..0000000 --- a/fence/fenced/fd.h +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FD_DOT_H__ -#define __FD_DOT_H__ - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <stdint.h> -#include <syslog.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/un.h> - - -#include "cnxman-socket.h" -#include "list.h" - - -extern char * prog_name; -extern int fenced_debug; -extern int debug_sock; -extern char debug_buf[256]; -extern struct sockaddr_un debug_addr; -extern socklen_t debug_addrlen; - - -#define FENCED_SOCK_PATH "fenced_socket" -#define DEFAULT_OVERRIDE_PATH "/var/run/cluster/fenced_override" - -#define DEFAULT_POST_JOIN_DELAY 6 -#define DEFAULT_POST_FAIL_DELAY 0 -#define DEFAULT_CLEAN_START 0 - -/* should match service.h MAX_SERVICE_NAME_LEN */ -#define MAX_NAME_LEN 33 - -/* use this one before we fork into the background */ -#define die1(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt "\n", ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt "\n", ##args); \ - syslog(LOG_ERR, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -#define FENCE_ASSERT(x, todo) \ -do \ -{ \ - if (!(x)) \ - { \ - {todo} \ - die("assertion failed on line %d of file %s\n", __LINE__, __FILE__); \ - } \ -} \ -while (0) - -#define FENCE_RETRY(do_this, until_this) \ -for (;;) \ -{ \ - do { do_this; } while (0); \ - if (until_this) \ - break; \ - fprintf(stderr, "fenced: out of memory: %s, %u\n", __FILE__, __LINE__); \ - sleep(1); \ -} - -/* log_debug messages only appear when -D is used and then they go to stdout */ -/* #define log_debug(fmt, args...) printf("fenced: " fmt "\n", ##args) */ - -#define log_debug(fmt, args...) \ -do \ -{ \ - snprintf(debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \ - if (fenced_debug) printf("fenced: %s", debug_buf); \ - sendto(debug_sock, debug_buf, strlen(debug_buf), 0, \ - (struct sockaddr *)&debug_addr, debug_addrlen); \ -} \ -while (0) - - -struct fd; -struct fd_node; -struct commandline; - -typedef struct fd fd_t; -typedef struct fd_node fd_node_t; -typedef struct commandline commandline_t; - -struct commandline -{ - char name[MAX_NAME_LEN]; - int debug; - int post_join_delay; - int post_fail_delay; - char *override_path; - int8_t clean_start; - int8_t post_join_delay_opt; - int8_t post_fail_delay_opt; - int8_t clean_start_opt; - int8_t override_path_opt; -}; - -#define FDFL_RUN (0) -#define FDFL_START (1) -#define FDFL_FINISH (2) - -struct fd { - struct commandline *comline; - int cl_sock; - uint32_t our_nodeid; - uint32_t local_id; /* local unique fd ID */ - uint32_t global_id; /* global unique fd ID */ - - int last_stop; - int last_start; - int last_finish; - - int first_recovery; - int prev_count; - struct list_head prev; - struct list_head victims; - struct list_head leaving; - struct list_head complete; - - int namelen; - char name[1]; -}; - -struct fd_node { - struct list_head list; - uint32_t nodeid; - int namelen; - char name[1]; -}; - - -void add_complete_node(fd_t *fd, uint32_t nodeid, uint32_t len, char *name); -void do_recovery(fd_t *fd, struct cl_service_event *ev, - struct cl_cluster_node *cl_nodes); -void do_recovery_done(fd_t *fd); -int dispatch_fence_agent(char *victim, int force); - -#endif /* __FD_DOT_H__ */ diff --git a/fence/fenced/main.c b/fence/fenced/main.c deleted file mode 100644 index 51fd276..0000000 --- a/fence/fenced/main.c +++ /dev/null @@ -1,696 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fd.h" -#include "ccs.h" -#include "copyright.cf" - - -/* static pthread_t recv_thread; */ -static int quit; -static int leave_finished; -static int usr_interrupt; -char our_name[MAX_CLUSTER_MEMBER_NAME_LEN+1]; - - -#define OPTION_STRING ("cj:f:t:Dn:O:hVSwQ") -#define LOCKFILE_NAME "/var/run/fenced.pid" - - -static void print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options]\n", prog_name); - printf("\n"); - printf("Options:\n"); - printf("\n"); - printf(" -c All nodes are in a clean state to start\n"); - printf(" -j <secs> Post-join fencing delay (default %d)\n", - DEFAULT_POST_JOIN_DELAY); - printf(" -f <secs> Post-fail fencing delay (default %d)\n", - DEFAULT_POST_FAIL_DELAY); - printf(" -O <path> Override path (default %s)\n", - DEFAULT_OVERRIDE_PATH); - printf(" -D Enable debugging code and don't fork\n"); - printf(" -h Print this help, then exit\n"); - printf(" -n <name> Name of the fence domain, "default" if none\n"); - printf(" -V Print program version information, then exit\n"); - printf("\n"); - printf("Command line values override those in cluster.conf.\n"); - printf("For an unbounded delay use <secs> value of -1.\n"); - printf("\n"); -} - -static void lockfile(void) -{ - int fd, error; - struct flock lock; - char buf[33]; - - memset(buf, 0, 33); - - fd = open(LOCKFILE_NAME, O_CREAT|O_WRONLY, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (fd < 0) - die("cannot open/create lock file %s", LOCKFILE_NAME); - - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - error = fcntl(fd, F_SETLK, &lock); - if (error) - die("fenced is already running"); - - error = ftruncate(fd, 0); - if (error) - die("cannot clear lock file %s", LOCKFILE_NAME); - - sprintf(buf, "%d\n", getpid()); - - error = write(fd, buf, strlen(buf)); - if (error <= 0) - die("cannot write lock file %s", LOCKFILE_NAME); -} - - -/* SIGUSR1 will cause this program to look for a new service event from SM - using the GETEVENT ioctl. - - SIGTERM will cause this program to leave the service group cleanly; it will - do a LEAVE ioctl, get a stop event and then exit. - - SIGKILL will cause the program to exit without first leaving the service - group. In that case the kernel will clean up and leave the service group - (as a part of cl_release on the cluster socket). */ - - -static void sigusr1_handler(int sig) -{ - usr_interrupt = 1; -} - -static void sigterm_handler(int sig) -{ - usr_interrupt = 1; - quit = 1; -} - -#if 0 -/* This thread receives messages on the cluster socket and prints them. */ -static void *recv_thread_fn(void *arg) -{ - fd_t *fd = arg; - struct iovec iov[2]; - struct msghdr msg; - struct sockaddr_cl saddr; - char buf[256]; - int len; - int nodeid; - - for (;;) { - memset(buf, 0, 256); - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = &saddr; - msg.msg_flags = 0; - msg.msg_namelen = sizeof(saddr); - iov[0].iov_len = sizeof(buf); - iov[0].iov_base = buf; - - len = recvmsg(fd->cl_sock, &msg, MSG_OOB); - - if (len < 0 && errno == EAGAIN) - continue; - - if (!len || len < 0) - continue; - - memcpy(&nodeid, &saddr.scl_csid, sizeof(int)); - - if (buf[0] == CLUSTER_OOB_MSG_PORTCLOSED) - log_debug("message: oob port-closed from nodeid %d", - nodeid); - - else if (buf[0] == CLUSTER_OOB_MSG_SERVICEEVENT) - log_debug("message: oob service-event"); - - else if (!strcmp(buf, "hello")) - log_debug("message: "%s" from nodeid %d", buf, nodeid); - - else - log_debug("message: unknown len %d byte0 %x nodeid %d", - len, buf[0], nodeid); - } -} - -static void send_group_message(fd_t *fd) -{ - struct iovec iov[2]; - struct msghdr msg; - char buf[256]; - int len; - - strcpy(buf, "hello"); - - iov[0].iov_len = strlen(buf); - iov[0].iov_base = buf; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iovlen = 1; - msg.msg_iov = iov; - msg.msg_name = NULL; - msg.msg_flags = O_NONBLOCK; - msg.msg_namelen = 0; - - len = sendmsg(fd->cl_sock, &msg, 0); -} -#endif - -static void print_ev(struct cl_service_event *ev) -{ - switch (ev->type) { - case SERVICE_EVENT_STOP: - log_debug("stop:"); - break; - case SERVICE_EVENT_START: - log_debug("start:"); - break; - case SERVICE_EVENT_FINISH: - log_debug("finish:"); - break; - case SERVICE_EVENT_LEAVEDONE: - log_debug("leavedone:"); - break; - } - log_debug(" event_id = %u", ev->event_id); - log_debug(" last_stop = %u", ev->last_stop); - log_debug(" last_start = %u", ev->last_start); - log_debug(" last_finish = %u", ev->last_finish); - log_debug(" node_count = %u", ev->node_count); - - if (ev->type != SERVICE_EVENT_START) - return; - - switch (ev->start_type) { - case SERVICE_START_FAILED: - log_debug(" start_type = %s", "failed"); - break; - case SERVICE_START_JOIN: - log_debug(" start_type = %s", "join"); - break; - case SERVICE_START_LEAVE: - log_debug(" start_type = %s", "leave"); - break; - } -} - -static void print_members(int count, struct cl_cluster_node *nodes) -{ - int i; - - log_debug("members:"); - for (i = 0; i < count; i++) { - log_debug(" nodeid = %u "%s"", nodes->node_id, nodes->name); - nodes++; - } -} - -static void process_event(fd_t *fd, struct cl_service_event *ev) -{ - struct cl_cluster_nodelist nodelist; - struct cl_cluster_node *nodes; - int error = 0, n; - - print_ev(ev); - - if (ev->type == SERVICE_EVENT_START) { - fd->last_start = ev->event_id; - - /* space for two extra to be sure it's not too small */ - n = ev->node_count + 2; - - FENCE_RETRY(nodes = malloc(n * sizeof(struct cl_cluster_node)), - nodes); - memset(nodes, 0, n * sizeof(struct cl_cluster_node)); - - nodelist.max_members = n; - nodelist.nodes = nodes; - - error = ioctl(fd->cl_sock, SIOCCLUSTER_SERVICE_GETMEMBERS, - &nodelist); - if (error < 0) - die("process_event: service get members failed"); - - print_members(ev->node_count, nodes); - - do_recovery(fd, ev, nodes); - - error = ioctl(fd->cl_sock, SIOCCLUSTER_SERVICE_STARTDONE, - ev->event_id); - if (error < 0) - log_debug("process_event: start done error"); - - free(nodes); - } - - else if (ev->type == SERVICE_EVENT_LEAVEDONE) - leave_finished = 1; - - else if (ev->type == SERVICE_EVENT_STOP) - fd->last_stop = fd->last_start; - - else if (ev->type == SERVICE_EVENT_FINISH) { - fd->last_finish = ev->event_id; - do_recovery_done(fd); - } -} - -static void process_events(fd_t *fd) -{ - struct cl_service_event event; - sigset_t mask, oldmask; - int error; - - sigemptyset(&mask); - sigaddset(&mask, SIGUSR1); - sigaddset(&mask, SIGTERM); - - for (;;) { - memset(&event, 0, sizeof(struct cl_service_event)); - - error = ioctl(fd->cl_sock, SIOCCLUSTER_SERVICE_GETEVENT, &event); - if (error < 0) - die("process_events: service get event failed"); - - if (!error) { - /* Wait for a signal to arrive. */ - sigprocmask(SIG_BLOCK, &mask, &oldmask); - while (!usr_interrupt) - sigsuspend(&oldmask); - sigprocmask(SIG_UNBLOCK, &mask, NULL); - usr_interrupt = 0; - } else - process_event(fd, &event); - - if (quit) { - quit = 0; - leave_finished = 0; - - error = ioctl(fd->cl_sock, SIOCCLUSTER_SERVICE_LEAVE, 0); - if (error < 0) - die("process_events: service leave failed"); - } - - if (leave_finished) - break; - } -} - -static int fence_domain_add(fd_t *fd) -{ - int cl_sock, error; - - cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cl_sock < 0) - die("fence_domain_add: can't create cluster socket"); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_REGISTER, fd->name); - if (error < 0) - die("fence_domain_add: service register failed"); - - /* FIXME: SERVICE_LEVEL_FENCE is 0 but defined in service.h */ - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_SETLEVEL, 0); - if (error < 0) - die("fence_domain_add: service set level failed"); - - signal(SIGUSR1, sigusr1_handler); - signal(SIGTERM, sigterm_handler); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_SETSIGNAL, SIGUSR1); - if (error < 0) - die("fence_domain_add: service set signal failed"); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_JOIN, NULL); - if (error < 0) - die("fence_domain_add: service join failed"); - - fd->cl_sock = cl_sock; - - /* Main loop */ - process_events(fd); - - error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_UNREGISTER, NULL); - if (error < 0) - die("fence_domain_add: unregister failed"); - - return 0; -} - -static int check_ccs(fd_t *fd) -{ - char path[256]; - char *name = NULL, *str = NULL; - int error, cd, i = 0, count = 0; - - - while ((cd = ccs_connect()) < 0) { - sleep(1); - if (++i > 9 && !(i % 10)) - log_debug("connect to ccs error %d, " - "check ccsd or cluster status", cd); - } - - - /* Our own nodename must be in cluster.conf before we're allowed to - join the fence domain and then mount gfs; other nodes need this to - fence us. */ - - memset(path, 0, 256); - snprintf(path, 256, - "/cluster/clusternodes/clusternode[@name="%s"]/@name", - our_name); - - error = ccs_get(cd, path, &str); - if (error) - die1("local cman node name "%s" not found in cluster.conf", - our_name); - - - /* If an option was set on the command line, don't set it from ccs. */ - - if (fd->comline->clean_start_opt == FALSE) { - str = NULL; - memset(path, 0, 256); - sprintf(path, "/cluster/fence_daemon/@clean_start"); - - error = ccs_get(cd, path, &str); - if (!error) - fd->comline->clean_start = atoi(str); - else - fd->comline->clean_start = DEFAULT_CLEAN_START; - if (str) - free(str); - } - - if (fd->comline->post_join_delay_opt == FALSE) { - str = NULL; - memset(path, 0, 256); - sprintf(path, "/cluster/fence_daemon/@post_join_delay"); - - error = ccs_get(cd, path, &str); - if (!error) - fd->comline->post_join_delay = atoi(str); - else - fd->comline->post_join_delay = DEFAULT_POST_JOIN_DELAY; - if (str) - free(str); - } - - if (fd->comline->post_fail_delay_opt == FALSE) { - str = NULL; - memset(path, 0, 256); - sprintf(path, "/cluster/fence_daemon/@post_fail_delay"); - - error = ccs_get(cd, path, &str); - if (!error) - fd->comline->post_fail_delay = atoi(str); - else - fd->comline->post_fail_delay = DEFAULT_POST_FAIL_DELAY; - if (str) - free(str); - } - - if (fd->comline->override_path_opt == FALSE) { - str = NULL; - memset(path, 0, 256); - sprintf(path, "/cluster/fence_daemon/@override_path"); - - error = ccs_get(cd, path, &str); - if (!error) - /* XXX These are not explicitly freed on exit; if - we decide to make fenced handle SIGHUP at a later - time, we will need to free this. */ - fd->comline->override_path = strdup(str); - else - fd->comline->override_path = strdup(DEFAULT_OVERRIDE_PATH); - if (str) - free(str); - } - - log_debug("delay post_join %ds post_fail %ds", - fd->comline->post_join_delay, fd->comline->post_fail_delay); - - if (fd->comline->clean_start) { - log_debug("clean start, skipping initial nodes"); - goto out; - } - - for (i = 1; ; i++) { - name = NULL; - memset(path, 0, 256); - sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", i); - - error = ccs_get(cd, path, &name); - if (error || !name) - break; - - add_complete_node(fd, 0, strlen(name), name); - free(name); - count++; - } - - log_debug("added %d nodes from ccs", count); - out: - ccs_disconnect(cd); - return 0; -} - -static int check_cluster(fd_t *fd) -{ - struct cl_cluster_node cl_node; - int cl_sock, active, error; - - memset(&cl_node, 0, sizeof(struct cl_cluster_node)); - - cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (cl_sock < 0) - die1("can't create cman cluster socket"); - - active = ioctl(cl_sock, SIOCCLUSTER_ISACTIVE, 0); - if (!active) - die1("cman cluster manager is not running"); - - for (;;) { - error = ioctl(cl_sock, SIOCCLUSTER_GETNODE, &cl_node); - if (!error) - break; - log_debug("cman getnode failed %d", error); - sleep(1); - } - memcpy(our_name, cl_node.name, strlen(cl_node.name)); - - log_debug("our name from cman "%s"", our_name); - - close(cl_sock); - return 0; -} - -static fd_t *new_fd(commandline_t *comline) -{ - int namelen = strlen(comline->name); - fd_t *fd; - - if (namelen > MAX_NAME_LEN-1) - die1("cluster name too long, max %d", MAX_NAME_LEN-1); - - fd = malloc(sizeof(fd_t) + MAX_NAME_LEN); - if (!fd) - die1("no memory"); - - memset(fd, 0, sizeof(fd_t) + MAX_NAME_LEN); - memcpy(fd->name, comline->name, namelen); - fd->namelen = namelen; - - fd->comline = comline; - fd->first_recovery = FALSE; - fd->last_stop = 0; - fd->last_start = 0; - fd->last_finish = 0; - fd->prev_count = 0; - INIT_LIST_HEAD(&fd->prev); - INIT_LIST_HEAD(&fd->victims); - INIT_LIST_HEAD(&fd->leaving); - INIT_LIST_HEAD(&fd->complete); - - return fd; -} - -static void decode_arguments(int argc, char **argv, commandline_t *comline) -{ - int cont = TRUE; - int optchar; - - comline->override_path_opt = FALSE; - comline->override_path = NULL; - comline->post_join_delay_opt = FALSE; - comline->post_fail_delay_opt = FALSE; - comline->clean_start_opt = FALSE; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - - case 'c': - comline->clean_start = 1; - comline->clean_start_opt = TRUE; - break; - - case 'j': - comline->post_join_delay = atoi(optarg); - comline->post_join_delay_opt = TRUE; - break; - - case 'f': - comline->post_fail_delay = atoi(optarg); - comline->post_fail_delay_opt = TRUE; - break; - - case 'O': - comline->override_path = strdup(optarg); - comline->override_path_opt = TRUE; - break; - - case 'D': - comline->debug = TRUE; - fenced_debug = TRUE; - break; - - case 'n': - strncpy(comline->name, optarg, MAX_NAME_LEN); - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case 'V': - printf("fenced %s (built %s %s)\n", FENCE_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case 'S': - case 'w': - case 't': - case 'Q': - /* do nothing, this is a fence_tool option that - we ignore when fence_tool starts us */ - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case EOF: - cont = FALSE; - break; - - default: - die1("unknown option: %c", optchar); - break; - }; - } - - if (!strcmp(comline->name, "")) - strcpy(comline->name, "default"); -} - -void setup_debug(void) -{ - debug_sock = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (debug_sock < 0) - return; - - debug_addr.sun_family = AF_LOCAL; - strcpy(&debug_addr.sun_path[1], FENCED_SOCK_PATH); - debug_addrlen = sizeof(sa_family_t) + strlen(debug_addr.sun_path+1) + 1; -} - -int main(int argc, char **argv) -{ - commandline_t comline; - fd_t *fd; - int error; - - prog_name = argv[0]; - - setup_debug(); - - memset(&comline, 0, sizeof(commandline_t)); - - decode_arguments(argc, argv, &comline); - - fd = new_fd(&comline); - - error = check_cluster(fd); - if (error) - die1("check_cluster error %d", error); - - error = check_ccs(fd); - if (error) - die1("check_ccs error %d", error); - - if (!fenced_debug) { - pid_t pid = fork(); - if (pid < 0) { - perror("main: cannot fork"); - exit(EXIT_FAILURE); - } - if (pid) - exit(EXIT_SUCCESS); - setsid(); - chdir("/"); - umask(0); - close(0); - close(1); - close(2); - openlog("fenced", LOG_PID, LOG_DAEMON); - } - - lockfile(); - - fence_domain_add(fd); - - free(fd); - return 0; -} - -char *prog_name; -int fenced_debug; -int debug_sock; -char debug_buf[256]; -struct sockaddr_un debug_addr; -socklen_t debug_addrlen; - - diff --git a/fence/fenced/recover.c b/fence/fenced/recover.c deleted file mode 100644 index 65fbadf..0000000 --- a/fence/fenced/recover.c +++ /dev/null @@ -1,657 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fd.h" -#include <sys/time.h> -#include <sys/types.h> -#include <sys/select.h> - -/* Fencing recovery algorithm - - do_recovery (service event start) - - complete = list of nodes in previous completed fence domain - - cl_nodes = list of current domain members provided by start - - victims = list of nodes in complete that are not in cl_nodes - - prev = saved version of cl_nodes (in list format) - - fence_victims() fences nodes in victims list - - do_recovery_done (service event finish) - - complete = prev - - Notes: - - When fenced is started, the complete list is initialized to all - the nodes in cluster.conf. - - fence_victims actually only runs on one of the nodes in the domain - so that a victim isn't fenced by everyone. - - The node to run fence_victims is the node with lowest id that's in both - complete and prev lists. - - This node will never be a node that's just joining since by definition - the joining node wasn't in the last complete group. - - An exception to this is when there is just one node in the group - in which case it's chosen even if it wasn't in the last complete group. - - There's also a leaving list that parallels the victims list but are - not fenced. -*/ - -static fd_node_t *new_fd_node(fd_t *fd, uint32_t nodeid, int namelen, char *name) -{ - struct cl_cluster_node cl_node; - fd_node_t *node = NULL; - int error; - - memset(&cl_node, 0, sizeof(struct cl_cluster_node)); - - if (!namelen) { - cl_node.node_id = nodeid; - error = ioctl(fd->cl_sock, SIOCCLUSTER_GETNODE, &cl_node); - - FENCE_ASSERT(!error, printf("unknown nodeid %u\n", nodeid);); - - namelen = strlen(cl_node.name); - name = cl_node.name; - } - - FENCE_RETRY(node = malloc(sizeof(fd_node_t) + namelen), node); - memset(node, 0, sizeof(fd_node_t) + namelen); - - node->nodeid = nodeid; - node->namelen = namelen; - memcpy(node->name, name, namelen); - - return node; -} - -static int name_equal(fd_node_t *node1, struct cl_cluster_node *node2) -{ - char name1[64], name2[64]; - int i, len1, len2; - - if ((node1->namelen == strlen(node2->name) && - !strncmp(node1->name, node2->name, node1->namelen))) - return TRUE; - - memset(name1, 0, 64); - memset(name2, 0, 64); - - len1 = node1->namelen; - for (i = 0; i < 63 && i < len1; i++) { - if (node1->name[i] != '.') - name1[i] = node1->name[i]; - else - break; - } - - len2 = strlen(node2->name); - for (i = 0; i < 63 && i < len2; i++) { - if (node2->name[i] != '.') - name1[i] = node2->name[i]; - else - break; - } - - if (!strncmp(name1, name2, strlen(name1))) - return TRUE; - - return FALSE; -} - -static uint32_t next_complete_nodeid(fd_t *fd, uint32_t gt) -{ - fd_node_t *node; - uint32_t low = 0xFFFFFFFF; - - /* find lowest node id in fd_complete greater than gt */ - - list_for_each_entry(node, &fd->complete, list) { - if ((node->nodeid > gt) && (node->nodeid < low)) - low = node->nodeid; - } - return low; -} - -static uint32_t find_master_nodeid(fd_t *fd, char **master_name) -{ - fd_node_t *node; - uint32_t low = 0; - - /* Find the lowest nodeid common to fd->fd_prev (newest member list) - * and fd->fd_complete (last complete member list). */ - - for (;;) { - low = next_complete_nodeid(fd, low); - - if (low == 0xFFFFFFFF) - break; - - list_for_each_entry(node, &fd->prev, list) { - if (low != node->nodeid) - continue; - *master_name = node->name; - goto out; - } - } - - /* Special case: we're the first and only FD member */ - - if (fd->prev_count == 1) - low = fd->our_nodeid; - - /* We end up returning -1 when we're not the only node and we've just - joined. Because we've just joined we weren't in the last complete - domain group and won't be chosen as master. We defer to someone who - _was_ in the last complete group. All we know is it isn't us. */ - - *master_name = "prior member"; - - out: - return low; -} - -static int can_avert_fence(fd_t *fd, fd_node_t *victim) -{ - struct cl_cluster_node cl_node; - int error; - - memset(&cl_node, 0, sizeof(cl_node)); - - strcpy(cl_node.name, victim->name); - - error = ioctl(fd->cl_sock, SIOCCLUSTER_GETNODE, &cl_node); - if (error < 0) - return FALSE; - - log_debug("state of node %s is %d", victim->name, cl_node.state); - - if (cl_node.state == NODESTATE_MEMBER || - cl_node.state == NODESTATE_JOINING) - return TRUE; - - return FALSE; -} - -static void free_node_list(struct list_head *head) -{ - fd_node_t *node; - while (!list_empty(head)) { - node = list_entry(head->next, fd_node_t, list); - list_del(&node->list); - free(node); - } -} - -static inline void free_victims(fd_t *fd) -{ - free_node_list(&fd->victims); -} - -static inline void free_leaving(fd_t *fd) -{ - free_node_list(&fd->leaving); -} - -static inline void free_prev(fd_t *fd) -{ - free_node_list(&fd->prev); -} - -static inline void free_complete(fd_t *fd) -{ - free_node_list(&fd->complete); -} - -void add_complete_node(fd_t *fd, uint32_t nodeid, uint32_t len, char *name) -{ - fd_node_t *node; - node = new_fd_node(fd, nodeid, len, name); - list_add(&node->list, &fd->complete); -} - -static void new_prev_nodes(fd_t *fd, struct cl_service_event *ev, - struct cl_cluster_node *cl_nodes) -{ - struct cl_cluster_node *cl_node = cl_nodes; - fd_node_t *node; - int i; - - for (i = 0; i < ev->node_count; i++) { - node = new_fd_node(fd, cl_node->node_id, 0, NULL); - list_add(&node->list, &fd->prev); - cl_node++; - } - - fd->prev_count = ev->node_count; -} - -static int in_cl_nodes(struct cl_cluster_node *cl_nodes, fd_node_t *node, - int num_nodes) -{ - struct cl_cluster_node *cl_node = cl_nodes; - int i; - - for (i = 0; i < num_nodes; i++) { - if (name_equal(node, cl_node)) - return TRUE; - cl_node++; - } - return FALSE; -} - -static int get_members(fd_t *fd, struct cl_cluster_node **cl_nodes) -{ - struct cl_cluster_nodelist nodelist; - struct cl_cluster_node *nodes; - int n = 0; - - for (;;) { - n = ioctl(fd->cl_sock, SIOCCLUSTER_GETMEMBERS, 0); - - FENCE_ASSERT(n > 0, ); - - FENCE_RETRY(nodes = malloc(n * sizeof(struct cl_cluster_node)), - nodes); - memset(nodes, 0, n * sizeof(struct cl_cluster_node)); - - nodelist.max_members = n; - nodelist.nodes = nodes; - - n = ioctl(fd->cl_sock, SIOCCLUSTER_GETMEMBERS, &nodelist); - if (n < 0) { - free(nodes); - continue; - } - break; - } - - *cl_nodes = nodes; - return n; -} - -static void add_first_victims(fd_t *fd) -{ - fd_node_t *prev_node, *safe; - struct cl_cluster_node *cl_nodes, *cl_node; - int num_nodes, i; - - num_nodes = get_members(fd, &cl_nodes); - cl_node = cl_nodes; - - for (i = 0; i < num_nodes; i++) { - if (cl_node->us) { - fd->our_nodeid = cl_node->node_id; - log_debug("our nodeid %u", fd->our_nodeid); - break; - } - cl_node++; - } - FENCE_ASSERT(fd->our_nodeid, printf("num_nodes %d\n", num_nodes);); - - /* complete list initialised in init_nodes() to all nodes from ccs */ - if (list_empty(&fd->complete)) - log_debug("first complete list empty warning"); - - list_for_each_entry_safe(prev_node, safe, &fd->complete, list) { - if (!in_cl_nodes(cl_nodes, prev_node, num_nodes)) { - list_del(&prev_node->list); - list_add(&prev_node->list, &fd->victims); - log_debug("add first victim %s", prev_node->name); - } - } - - free(cl_nodes); -} - -static int id_in_cl_nodes(struct cl_cluster_node *cl_nodes, uint32_t nodeid, - int num_nodes) -{ - struct cl_cluster_node *cl_node = cl_nodes; - int i; - - for (i = 0; i < num_nodes; i++) { - if (nodeid == cl_node->node_id) - return TRUE; - cl_node++; - } - return FALSE; -} - -static int list_count(struct list_head *head) -{ - struct list_head *tmp; - int count = 0; - - list_for_each(tmp, head) - count++; - return count; -} - -/* This routine should probe other indicators to check if victims - can be reduced. Right now we just check if the victim has rejoined the - cluster. */ - -static int reduce_victims(fd_t *fd) -{ - fd_node_t *node, *safe; - struct cl_cluster_node *cl_nodes; - int num_nodes, num_victims; - - num_victims = list_count(&fd->victims); - - num_nodes = get_members(fd, &cl_nodes); - - list_for_each_entry_safe(node, safe, &fd->victims, list) { - if (in_cl_nodes(cl_nodes, node, num_nodes)) { - list_del(&node->list); - log_debug("reduce victim %s", node->name); - free(node); - num_victims--; - } - } - - free(cl_nodes); - return num_victims; -} - -static inline void close_override(int *fd, char *path) -{ - unlink(path); - if (fd && *fd >= 0) - close(*fd); - *fd = -1; -} - -static int open_override(char *path) -{ - int ret; - mode_t om; - - om = umask(077); - ret = mkfifo(path, (S_IRUSR | S_IWUSR)); - umask(om); - - if (ret < 0) - return -1; - return open(path, O_RDONLY | O_NONBLOCK); -} - -static int check_override(int ofd, char *nodename, int timeout) -{ - char buf[128]; - fd_set rfds; - struct timeval tv = {0, 0}; - int ret, x; - - if (ofd < 0 || !nodename || !strlen(nodename)) { - sleep(timeout); - return 0; - } - - FD_ZERO(&rfds); - FD_SET(ofd, &rfds); - tv.tv_usec = 0; - tv.tv_sec = timeout; - - ret = select(ofd + 1, &rfds, NULL, NULL, &tv); - if (ret < 0) { - syslog(LOG_ERR, "select: %s\n", strerror(errno)); - return -1; - } - - if (ret == 0) - return 0; - - memset(buf, 0, sizeof(buf)); - ret = read(ofd, buf, sizeof(buf) - 1); - if (ret < 0) { - syslog(LOG_ERR, "read: %s\n", strerror(errno)); - return -1; - } - - /* chop off control characters */ - for (x = 0; x < ret; x++) { - if (buf[x] < 0x20) { - buf[x] = 0; - break; - } - } - - if (!strcasecmp(nodename, buf)) { - /* Case insensitive, but not as nice as, say, name_equal - in the other file... */ - return 1; - } - - return 0; -} - - -/* If there are victims after a node has joined, it's a good indication that - they may be joining the cluster shortly. If we delay a bit they might - become members and we can avoid fencing them. This is only really an issue - when the fencing method reboots the victims. Otherwise, the nodes should - unfence themselves when they start up. */ - -static void delay_fencing(fd_t *fd, struct cl_service_event *ev) -{ - struct timeval first, last, start, now; - int victim_count, last_count = 0, delay = 0; - fd_node_t *node; - char *delay_type; - - if (ev->start_type == SERVICE_START_JOIN) { - delay = fd->comline->post_join_delay; - delay_type = "post_join_delay"; - } else { - delay = fd->comline->post_fail_delay; - delay_type = "post_fail_delay"; - } - - if (delay == 0) - goto out; - - gettimeofday(&first, NULL); - gettimeofday(&start, NULL); - - for (;;) { - sleep(1); - - victim_count = reduce_victims(fd); - - if (victim_count == 0) - break; - - if (victim_count < last_count) { - gettimeofday(&start, NULL); - if (delay > 0 && fd->comline->post_join_delay > delay) { - delay = fd->comline->post_join_delay; - delay_type = "post_join_delay (modified)"; - } - } - - last_count = victim_count; - - /* negative delay means wait forever */ - if (delay == -1) - continue; - - gettimeofday(&now, NULL); - if (now.tv_sec - start.tv_sec >= delay) - break; - } - - gettimeofday(&last, NULL); - - log_debug("delay of %ds leaves %d victims", - (int) (last.tv_sec - first.tv_sec), victim_count); - out: - list_for_each_entry(node, &fd->victims, list) { - syslog(LOG_INFO, "%s not a cluster member after %d sec %s", - node->name, delay, delay_type); - } -} - -static void fence_victims(fd_t *fd, struct cl_service_event *ev) -{ - fd_node_t *node; - char *master_name; - uint32_t master; - int error, override = -1; - - master = find_master_nodeid(fd, &master_name); - - if (master != fd->our_nodeid) { - log_debug("defer fencing to %u %s", master, master_name); - syslog(LOG_INFO, "fencing deferred to %s", master_name); - return; - } - - delay_fencing(fd, ev); - - while (!list_empty(&fd->victims)) { - node = list_entry(fd->victims.next, fd_node_t, list); - - if (can_avert_fence(fd, node)) { - log_debug("averting fence of node %s", node->name); - list_del(&node->list); - free(node); - continue; - } - - log_debug("fencing node %s", node->name); - syslog(LOG_INFO, "fencing node "%s"", node->name); - - error = dispatch_fence_agent(node->name, 0); - - syslog(LOG_INFO, "fence "%s" %s", node->name, - error ? "failed" : "success"); - - if (!error) { - list_del(&node->list); - free(node); - continue; - } - - if (!fd->comline->override_path) { - sleep(5); - continue; - } - - /* Check for manual intervention */ - override = open_override(fd->comline->override_path); - if (check_override(override, node->name, 5) > 0) { - syslog(LOG_WARNING, "fence "%s" overridden by " - "administrator intervention", node->name); - - list_del(&node->list); - free(node); - } - close_override(&override, fd->comline->override_path); - } -} - -static void add_victims(fd_t *fd, struct cl_service_event *ev, - struct cl_cluster_node *cl_nodes) -{ - fd_node_t *node, *safe; - int count = ev->node_count; - - /* nodes which haven't completed leaving when a failure restart happens - * are dead (and need fencing) or are still members */ - - if (ev->start_type == SERVICE_START_FAILED) { - list_for_each_entry_safe(node, safe, &fd->leaving, list) { - list_del(&node->list); - if (id_in_cl_nodes(cl_nodes, node->nodeid, count)) - list_add(&node->list, &fd->complete); - else { - list_add(&node->list, &fd->victims); - log_debug("add victim %u, was leaving", - node->nodeid); - } - } - } - - /* nodes in last completed SG but missing from fr_nodeids are added to - * victims list or leaving list, depending on the type of start. */ - - if (list_empty(&fd->complete)) - log_debug("complete list empty warning"); - - list_for_each_entry_safe(node, safe, &fd->complete, list) { - if (!id_in_cl_nodes(cl_nodes, node->nodeid, count)) { - list_del(&node->list); - - if (ev->start_type == SERVICE_START_FAILED) - list_add(&node->list, &fd->victims); - else - list_add(&node->list, &fd->leaving); - - log_debug("add node %u to list %u", node->nodeid, - ev->start_type); - } - } -} - -/* cl_nodes is the set of sg members from the last service start */ - -void do_recovery(fd_t *fd, struct cl_service_event *ev, - struct cl_cluster_node *cl_nodes) -{ - /* Reset things when the last stop aborted our first - * start, i.e. there was no finish; we got a - * start/stop/start immediately upon joining. */ - - if (!fd->last_finish && fd->last_stop) { - log_debug("revert aborted first start"); - fd->last_stop = 0; - fd->first_recovery = FALSE; - free_prev(fd); - free_victims(fd); - free_leaving(fd); - } - - log_debug("do_recovery stop %d start %d finish %d", - fd->last_stop, fd->last_start, fd->last_finish); - - if (!fd->first_recovery) { - fd->first_recovery = TRUE; - add_first_victims(fd); - } else - add_victims(fd, ev, cl_nodes); - - free_prev(fd); - new_prev_nodes(fd, ev, cl_nodes); - - if (!list_empty(&fd->victims)) - fence_victims(fd, ev); -} - -void do_recovery_done(fd_t *fd) -{ - fd_node_t *node, *safe; - - if (fd->last_finish == fd->last_start) { - free_leaving(fd); - free_victims(fd); - } - - /* Save a copy of this set of nodes which constitutes the latest - * complete SG. Any of these nodes missing in the next start will - * either be leaving or victims. For the next recovery, the lowest - * remaining nodeid in this group will be the master. */ - - free_complete(fd); - list_for_each_entry_safe(node, safe, &fd->prev, list) { - list_del(&node->list); - list_add(&node->list, &fd->complete); - } -} diff --git a/fence/include/list.h b/fence/include/list.h deleted file mode 100644 index 566b377..0000000 --- a/fence/include/list.h +++ /dev/null @@ -1,325 +0,0 @@ -/* Copied from include/linux/list.h */ - -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -/** - * container_of - cast a member of a structure out to the containing structure - * - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - - -/* - * These are non-NULL pointers that will result in page faults - * under normal circumstances, used to verify that nobody uses - * non-initialized list entries. - */ -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is - * empty _and_ checks that no other CPU might be - * in the process of still modifying either member - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - * - * @head: the list to test. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * __list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. - */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use as a start point in - * list_for_each_entry_continue - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - iterate over list of given type - * continuing after existing point - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - - -#endif diff --git a/fence/init.d/Makefile b/fence/init.d/Makefile deleted file mode 100644 index 7ef55ca..0000000 --- a/fence/init.d/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= fenced - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -copytobin: - -clean: - -install: - install -d ${DESTDIR}/etc/init.d - install ${TARGET} ${DESTDIR}/etc/init.d - -uninstall: - ${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d diff --git a/fence/init.d/fenced b/fence/init.d/fenced deleted file mode 100755 index 11e0148..0000000 --- a/fence/init.d/fenced +++ /dev/null @@ -1,139 +0,0 @@ -#!/bin/bash -# -# chkconfig: 345 23 77 -# description: Starts and stops fence domain -# -# -### BEGIN INIT INFO -# Provides: -### END INIT INFO - -# FENCED_START_TIMEOUT -- amount of time to wait for starting fenced -# before giving up. If FENCED_START_TIMEOUT is positive, then we will -# wait FENCED_START_TIMEOUT seconds before giving up and failing when -# fenced does not start. If FENCED_START_TIMEOUT is zero, then -# wait indefinately for fenced to start. -FENCED_START_TIMEOUT=120 - -# FENCED_STOP_TIMEOUT -- amount of time to wait for stopping fenced -# before giving up. If FENCED_STOP_TIMEOUT is positive, then we will -# wait FENCED_STOP_TIMEOUT seconds before giving up and failing when -# fenced does not stop. If FENCED_STOP_TIMEOUT is zero, then -# wait indefinately for fenced to stop. -FENCED_STOP_TIMEOUT=120 - -. /etc/init.d/functions -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - -LOCK_FILE="/var/lock/subsys/fenced" - - -start() -{ - echo -n "Starting fence domain:" - - # If gulm is in ccs, don't start fenced - if ! [ -r /etc/cluster/cluster.conf ] - then - failure "/etc/cluster/cluster.conf not readable." - echo - return 1 - elif grep -qE "<[[:space:]]*gulm([[:space:]]|[>]|$)" \ - /etc/cluster/cluster.conf - then - warning "Skipping because of <gulm> section detected in /etc/cluster/cluster.conf" - echo - exit 0 - fi - - if ! [ -e /proc/cluster/status ] - then - failure "cman has not been properly started." - echo - return 0 - fi - - rtrn=1 - - fence_tool -t $FENCED_START_TIMEOUT join -w > /dev/null 2>&1 - rtrn=$? - - if [ $rtrn -eq 0 ] - then - #> # make sure that the fence domain is up and running - #> until grep "^Fence Domain:" /proc/cluster/services | grep -q " run " - #> do - #> sleep 1; - #> done - - success "startup" - echo - else - failure "startup" - echo - fi - - # need the extra echo to properlly terminate the line - return $rtrn -} - -stop() -{ - echo -n "Stopping fence domain:" - - if pidof fenced &> /dev/null - then - fence_tool -t $FENCED_STOP_TIMEOUT leave > /dev/null 2>&1 - rtrn=$? - - if [ $rtrn -eq 0 ] - then - success "shutdown" - echo - else - failure "shutdown" - echo - fi - else - rtrn=0 - success "shutdown" - echo - fi - - # need the extra echo to properlly terminate the line - return $rtrn -} - -rtrn=1 - -# See how we were called. -case "$1" in - start) - start - rtrn=$? - [ $rtrn = 0 ] && touch $LOCK_FILE - ;; - - stop) - stop - rtrn=$? - [ $rtrn = 0 ] && rm -f $LOCK_FILE - ;; - - restart) - $0 stop - $0 start - rtrn=$? - ;; - - status) - status fenced - rtrn=$? - ;; - - *) - echo $"Usage: $0 {start|stop|restart|status}" - ;; -esac - -exit $rtrn diff --git a/fence/make/defines.mk.input b/fence/make/defines.mk.input deleted file mode 100644 index c372add..0000000 --- a/fence/make/defines.mk.input +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -sharedir ?= ${DESTDIR}/@SHAREDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/fence/make/release.mk.input b/fence/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/fence/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/fence/man/Makefile b/fence/man/Makefile deleted file mode 100644 index 1e09342..0000000 --- a/fence/man/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET8= \ - fence.8 \ - fence_ack_manual.8 \ - fence_apc.8 \ - fence_rsa.8 \ - fence_rsb.8 \ - fence_bladecenter.8 \ - fence_brocade.8 \ - fence_drac.8 \ - fence_egenera.8 \ - fence_eps.8 \ - fence_ilo.8 \ - fence_manual.8 \ - fence_mcdata.8 \ - fence_node.8 \ - fence_rib.8 \ - fence_sanbox2.8 \ - fence_scsi.8 \ - fence_tool.8 \ - fence_vixel.8 \ - fence_wti.8 \ - fence_xvm.8 \ - fence_bullpap.8 \ - fence_ipmilan.8 \ - fenced.8 - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -install: - install -d ${mandir}/man8 - install ${TARGET8} ${mandir}/man8 - -uninstall: - ${UNINSTALL} ${TARGET8} ${mandir}/man8 diff --git a/fence/man/fence.8 b/fence/man/fence.8 deleted file mode 100644 index c7d735e..0000000 --- a/fence/man/fence.8 +++ /dev/null @@ -1,73 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence 8 - -.SH NAME -I/O Fencing reference guide - -.SH SYNOPSIS -Overview of related manual pages -.SH DESCRIPTION -The I/O Fencing documentation has been split into a number of sections. Please -refer to the table below to determine which man page coincides with the -command/feature you are looking for. - -.TP 20 -fence -I/O Fencing overview (this man page) -.TP -fenced -I/O Fencing daemon -.TP -fence_tool -Manages fenced -.TP -fence_node -Calls fence agent, used by lock_gulmd - -.SS I/O Fencing agents - -.TP 20 -fence_apc -for APC MasterSwitch and APC 79xx models -.TP -fence_bladecenter -for IBM Bladecenters w/ telnet interface -.TP -fence_brocade -for Brocade fibre channel switches (PortDisable) -.TP -fence_egenera -for Egenera blades -.TP -fence_gnbd -for GNBD-based GFS clusters -.TP -fence_ilo -for HP ILO interfaces (formerly fence_rib) -.TP -fence_manual -for manual intervention -.TP -fence_mcdata -for McData fibre channel switches -.TP -fence_ack_manual -for manual intervention -.TP -fence_sanbox2 -for Qlogic SAN Box fibre channel switches -.TP -fence_vixel -for Vixel switches (PortDisable) -.TP -fence_wti -for WTI Network Power Switch - -.SH SEE ALSO -gnbd(8), gfs(8) diff --git a/fence/man/fence_ack_manual.8 b/fence/man/fence_ack_manual.8 deleted file mode 100644 index d0e492b..0000000 --- a/fence/man/fence_ack_manual.8 +++ /dev/null @@ -1,43 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_ack_manual 8 - -.SH NAME -fence_ack_manual - program run by an operator as a part of manual I/O Fencing - -.SH SYNOPSIS -.B -fence_ack_manual -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_ack_manual is run by an operator on the same node that fence_manual(8) -was run after the operator has reset a node which required fencing. A message -in the system log indicates to the operator that they must reset a machine and -then run fence_ack_manual. Running fence_ack_manual allows the cluster to -continue with recovery of the fenced machine. The victim may be disconnected -from storage rather than resetting it. - -.SH OPTIONS -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-O\fP -Run without prompting for user confirmation. -.TP -\fB-n\fP \fInodename\fP -Name of node that has been reset or disconnected from storage. -.TP -\fB-s\fP \fIIPaddress\fP -IP address of the machine which has been reset or disconnected from storage. (Deprecated; use -n instead.) -.TP -\fB-V\fP -Print out a version message, then exit. -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_apc.8 b/fence/man/fence_apc.8 deleted file mode 100644 index 8ac49f7..0000000 --- a/fence/man/fence_apc.8 +++ /dev/null @@ -1,105 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_apc 8 - -.SH NAME -fence_apc - I/O Fencing agent for APC MasterSwitch - -.SH SYNOPSIS -.B -fence_apc -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_apc is an I/O Fencing agent which can be used with the APC MasterSwitch -network power switch. It logs into a MasterSwitch via telnet and reboots -a specified outlet. Lengthy telnet connections to the MasterSwitch should -be avoided while a GFS cluster is running because the connection will -block any necessary fencing actions. - -fence_apc accepts options on the command line as well as from stdin. -Fenced sends parameters through stdin when it execs the agent. fence_apc -can be run by itself with command line options. This is useful for testing -and for turning outlets on or off from scripts. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fR -IP address or hostname of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fR -Login name. -.TP -\fB-n\fP \fI[<switch>:]outlet\fR -The outlet number to act upon. -.TP -\fB-o\fP \fIaction\fR -The action required. Reboot (default), Status, Off or On. -.TP -\fB-p\fP \fIpassword\fR -Password for login or for passphrase. -.TP -\fB-S\fP \fIscript\fR -Script to run to retrieve password. -.TP -\fB-x\fP -Use secure connection over ssh (using version 1, cipher blowfish). -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-T\fP -Test only. Answer NO to the confirmation prompt instead of YES. -.TP -\fB-v\fP -Verbose. Record telnet session in /tmp/apclog. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_apc. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. Reboot (default), Off or On. -.TP -\fIpasswd = < param >\fR -Password for login or for passphrase. -\fIpasswd_script = < param >\fR -Script to run to retrieve password. -\fIsecure = < param >\fR -Use secure connection over ssh. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The outlet number to act upon. -.TP -\fIswitch = < param >\fR -The switch to operate on. Defaults to "1" if not specified. -.TP -\fItest = < param >\fR -Test only. Answer NO to the confirmation prompt instead of YES. -.TP -\fIverbose = < param >\fR -Verbose. Record telnet session in /tmp/apclog. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_baytech.8 b/fence/man/fence_baytech.8 deleted file mode 100644 index 1cd77e1..0000000 --- a/fence/man/fence_baytech.8 +++ /dev/null @@ -1,89 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_baytech 8 - -.SH NAME -fence_baytech - I/O Fencing agent for Baytech RPC switches in combination with a Cyclades Terminal Server - -.SH SYNOPSIS -.B -fence_baytech -[\fIOPTION\fR]... - -.SH DESCRIPTION - -This fencing agent is written for the Baytech RPC27-20nc in combination with -a Cyclades terminal server. The Cyclades TS exports the RPC's serial port -via a Telnet interface. Other interfaces, such as SSH, are possible. -However, this script relys upon the assumption that Telnet is used. Future -features to this agent would allow the agent to work with a mulitude of -different communication protocols such as Telnet, SSH or Kermit. - -The other assumption that is made is that Outlet names do not end in space. -The name "Foo" and "Foo " are identical when the RPC prints them with -the status command. - -fence_baytech accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_baytech -can be run by itself with command line options which is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIhost\fP -IP address or hostname to connect to. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Username name for the switch. -.TP -\fB-n\fP \fIport\fP -The name of the outlet to act upon. -.TP -\fB-o\fP \fIaction\fP -The action required. disable (default) or enable. -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS - -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_baytech. -.TP -\fIhost = < hostname | ip >\fR -IP address or hostname to connect to. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIaction = < param >\fR -The action required. On, Off, Status or Reboot (default) -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIoutlet = < param >\fR -The name of the outlet to act upon. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_bladecenter.8 b/fence/man/fence_bladecenter.8 deleted file mode 100644 index c28f37e..0000000 --- a/fence/man/fence_bladecenter.8 +++ /dev/null @@ -1,102 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_bladecenter 8 - -.SH NAME -fence_bladecenter - I/O Fencing agent for IBM Bladecenter - -.SH SYNOPSIS -.B -fence_bladecenter -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_bladecenter is an I/O Fencing agent which can be used with IBM -Bladecenters with recent enough firmware that includes telnet support. It -logs into a Brocade chasis via telnet or ssh and uses the command line -interface to power on and off blades. fence_bladecenter accepts options on -the command line or from stdin. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the Bladecenter. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Login name for the Bladecenter. -.TP -\fB-n\fP \fIblade\fP -The blade to operate on. -.TP -\fB-o\fP \fIaction\fP -The action required. Valid actions are on, off, reboot (default) and status. -.TP -\fB-p\fP \fIpassword\fP -Password for login or for passphrase. -.TP -\fB-S\fP \fIscript\fR -Script to run to retrieve password. -.TP -\fB-k\fP \fIidentity\fR -Identity file (private key) for ssh connection. -.TP -\fB-x\fP -Use secure connection over ssh. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. -.TP -\fB-v\fP \fIdebuglog\fP -Log the telnet session to \fIdebuglog\fP for debugging purposes. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_bladecenter. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. disable (default) or enable. -.TP -\fIpasswd = < param >\fR -Password for login or for passphrase. -.TP -\fIpasswd_script = < param >\fR -Script to run to retrieve password. -.TP -\fIidentity_file = < param > \fR -Identity file (private key) for ssh. -.TP -\fIsecure = < param >\fR -Use secure connection over ssh. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIblade = < param >\fR -The blade to operate on. -.TP -\fIdebuglog = < param>\fR -Optional parameter to send debug transcript of the telnet session to a log file - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_brocade.8 b/fence/man/fence_brocade.8 deleted file mode 100644 index f5e9b99..0000000 --- a/fence/man/fence_brocade.8 +++ /dev/null @@ -1,89 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_brocade 8 - -.SH NAME -fence_brocade - I/O Fencing agent for Brocade FC switches - -.SH SYNOPSIS -.B -fence_brocade -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_brocade is an I/O Fencing agent which can be used with Brocade FC -switches. It logs into a Brocade switch via telnet and disables a specified -port. Disabling the port which a machine is connected to effectively fences -that machine. Lengthy telnet connections to the switch should be avoided -while a GFS cluster is running because the connection will block any necessary -fencing actions. - -fence_brocade accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_brocade -can be run by itself with command line options which is useful for testing. - -After a fence operation has taken place the fenced machine can no longer connect -to the Brocade FC switch. When the fenced machine is ready to be brought back -into the GFS cluster (after reboot) the port on the Brocade FC switch needs to -be enabled. This can be done by running fence_brocade and specifying the -enable action. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Login name for the switch. -.TP -\fB-n\fP \fIport\fP -The port number to disable on the switch. -.TP -\fB-o\fP \fIaction\fP -The action required. disable (default) or enable. -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_brocade. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. disable (default) or enable. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The port number to disable on the switch. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_bullpap.8 b/fence/man/fence_bullpap.8 deleted file mode 100644 index 38c920d..0000000 --- a/fence/man/fence_bullpap.8 +++ /dev/null @@ -1,78 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_bullpap 8 - -.SH NAME -fence_bullpap - I/O Fencing agent for Bull FAME architecture controlled by a -PAP management console. - -.SH SYNOPSIS -.B -fence_bullpap -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_bullpap is an I/O Fencing agent which can be used with Bull's NovaScale -machines controlled by PAP management consoles. This agent calls Bull's -support software provided by the NSMasterHW RPM available from Bull. - -fence_bullpap accepts options on the command line as well as from stdin. -fenced sends the options through stdin when it execs the agent. fence_bullpap -can be run by itself with command line options which is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address or hostname of the PAP management console. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Login with administrative privileges. -.TP -\fB-d\fP \fIdomain\fP -This is the domain name of the Bull machine to power-cycle. -.TP -\fB-o\fP \fIoption\fP -Action to perform (on, off, reboot, status). -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-q\fP -Quiet operation. Only print out error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the PAP management console. -.TP -\fIlogin= < param >\fR -Login with administrative privileges. -.TP -\fIdomain = < param >\fR -This is the domain name of the Bull machine to power-cycle. -.TP -\fIoption = < param >\fR -Action to perform (on, off, reboot, status). -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_cpint.8 b/fence/man/fence_cpint.8 deleted file mode 100644 index e3c47f8..0000000 --- a/fence/man/fence_cpint.8 +++ /dev/null @@ -1,59 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_cpint 8 - -.SH NAME -fence_cpint - I/O Fencing agent for GFS on s390 and zSeries VM clusters - -.SH SYNOPSIS -.B -fence_cpint -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_cpint is an I/O Fencing agent used on a virtual machine running GFS in a -s390 or zSeries VM cluster. -It uses the cpint package to send a CP LOGOFF command to the specified virtual -machine. -For fence_cpint to execute correctly, you must have the cpint module installed, -and hcp in your PATH. -\fBNOTE:\fP for fence_cpint to send a command to another virtual machine, the -machine executing it must either be a privilege class C user or it must be -the secondary user of the virtual machine to be fenced. This means that unless -all of you gulm server nodes are privilege class C, fence_cpint can only be -used with SLM. - -fence_cpint accepts options on the command line as well as from stdin. -fence_node sends the options through stdin when it execs the agent. -fence_cpint can be run by itself with command line options which is useful for -testing. - -.SH OPTIONS -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-u\fP \fIuserid\fP -userid of the virtual machine to fence (required). -.TP -\fB-q\fP -quiet mode, no output. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_cpint. -.TP -\fIuserid = < parm >\fP -userid of the virtual machine to fence (required). - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_drac.8 b/fence/man/fence_drac.8 deleted file mode 100644 index ff3707b..0000000 --- a/fence/man/fence_drac.8 +++ /dev/null @@ -1,103 +0,0 @@ -." Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_drac 8 - -.SH NAME -fence_drac - fencing agent for Dell Remote Access Card - -.SH SYNOPSIS -.B -fence_drac -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_drac is an I/O Fencing agent which can be used with the Dell Remote -Access Card (DRAC). This card provides remote access to controling -power to a server. It logs into the DRAC through the telnet interface of -the card. By default, the telnet interface is not enabled. To enable the -interface, you will need to use the racadm command in the racser-devel rpm -available from Dell. To enable telnet on the DRAC: - -[root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1 - -[root]# racadm racreset - -fence_drac accepts options on the command line as well as from stdin. -Fenced sends parameters through stdin when it execs the agent. fence_drac -can be run by itself with command line options. This is useful for testing -and for turning outlets on or off from scripts. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fR -IP address or hostname of the switch. -.TP -\fB-c\fP \fIcmd_prompt\fR -Force fence_drac to use cmd_prompt as the command prompt -.TP -\fB-d\fP \fIdracversion\fR -Force fence_drac to treat the device as though it was for the specified drac version -.TP -\fB-D\fP \fIdumpfile\fR -Debug file of the telnet interaction -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fR -Login name. -.TP -\fB-m\fP \fImodulename\fR -The module name of the blade when using DRAC/MC firmware. -.TP -\fB-o\fP \fIaction\fR -The action required. reboot (default), off, on or status. -.TP -\fB-p\fP \fIpassword\fR -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIaction = < param >\fR -The action required. reboot (default), off, on or status. -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_apc. -.TP -\fIcmd_prompt = < param >\fr -Force fence_drac to use cmd_prompt as the command prompt -.TP -\fIdrac_version = < param >\fr -Force fence_drac to treat the device as though it was for the specified drac version. -.TP -\fIdebug = < dumpfile >\fR -Debug file of the telnet interaction -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fImodulename = < param >\fr -The module name of the blade when using DRAC/MC firmware. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_egenera.8 b/fence/man/fence_egenera.8 deleted file mode 100644 index 46f5a06..0000000 --- a/fence/man/fence_egenera.8 +++ /dev/null @@ -1,77 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_egenera 8 - -.SH NAME -fence_egenera - I/O Fencing agent for the Egenera BladeFrame - -.SH SYNOPSIS -.B -fence_egenera -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_egenera is an I/O Fencing agent which can be used with the Egenera -BladeFrame. It logs into a control blade (cserver) via ssh and operates -on a processing blade (pserver) identified by the pserver name and the -logical process area network (LPAN) that it is in. fence_egenera requires -that ssh keys have been setup so that the fence_egenera does not require -a password to authenticate. Refer to ssh(8) for more information on setting -up ssh keys. - -fence_egenera accepts options on the command line as well as from stdin. -Fenced sends parameters through stdin when it execs the agent. fence_egenera -can also be run by itself with command line options. - -.SH OPTIONS -.TP -\fB-c\fP \fIcserver\fR -The cserver to ssh to. cserver can be in the form user@hostname to -specify a different user to login as. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlpan\fR -the lpan to operate on -.TP -\fB-o\fP \fIaction\fR -The action required. reboot (default), off, on or status. -.TP -\fB-p\fP \fIpserver\fR -the pserver to operate on -.TP -\fB-q\fP -quite mode. supress output. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIaction = < param >\fR -The action required. reboot (default), off, on or status. -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_apc. -.TP -\fIcserver = < param >\fR -The cserver to ssh to. cserver can be in the form user@hostname to -specify a different user to login as. -.TP -\fIlpan = < param >\fR -The lpan to operate on -.TP -\fIpserver = < param >\fR -The pserver to operate on -.TP -\fIesh = < param >\fR -The path to the esh command on the cserver (default is /opt/panmgr/bin/esh) - -.SH SEE ALSO -fence(8), fence_node(8), ssh(8) diff --git a/fence/man/fence_eps.8 b/fence/man/fence_eps.8 deleted file mode 100644 index 3685837..0000000 --- a/fence/man/fence_eps.8 +++ /dev/null @@ -1,106 +0,0 @@ -.TH fence_eps 8 - -.SH NAME -fence_eps - I/O Fencing agent for ePowerSwitch 8M+ power switch - -.SH SYNOPSIS -.B -fence_eps -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_eps is an I/O Fencing agent which can be used with the ePowerSwitch 8M+ power -switch to fence connected machines. Fence agent works (in 2008/10/21) ONLY on 8M+ -device, because this is only one, which has support for hidden page feature. - -Agent basically works by connecting to hidden page and pass appropriate arguments -to GET request. This means, that hidden page feature must be enabled and properly -configured. - -fence_eps accepts options on the command line as well as from stdin. -Fenced sends parameters through stdin when it execs the agent. fence_eps -can be run by itself with command line options. This is useful for testin -and for turning outlets on or off from scripts. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fR -IP address or hostname of ePowerSwitch 8M+ device. If device is configured -to listen on nonstandard port (other than 80), it's possible to use :port syntax -(ex. psip:8080). -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fR -Login name. -.TP -\fB-o\fP \fIaction\fR -The action required. This can be reboot (default), status, off or on. -.TP -\fB-p\fP \fIpassword\fR -Password for login. -.TP -\fB-S\fP \fIscript\fR -Script to run to retrieve password. -.TP -\fB-n\fP \fIname\fR -Physical plug number. Entered without P and with preceding zero (where is needed). -.TP -\fB-c\fP \fIname\fR -Name of hidden page. Default is (hidden.htm) -.TP -\fB-T\fP -Test only. Answer NO to the confirmation prompt instead of YES. -.TP -\fB-q\fP -Quiet mode. -.TP -\fB-v\fP -Verbose. Record session to stdout, or debug file if specified (see -D). -.TP -\fB-D\fP -Specifies file, where will be written debug messages from session. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_eps. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of ePowerSwitch 8M+ device. If device is configured -to listen on nonstandard port (other than 80), it's possible to use :port syntax -(ex. psip:8080). -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. This can be reboot (default), status, off or on. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Script to run to retrieve password. -.TP -\fIport = < param >\fR -Physical plug number. Entered without P and with preceding zero (where is needed) -.TP -\fIhidden_page = < param >\fR -Name of hidden page. Default is (hidden.htm) -.TP -\fItest = < param >\fR -Test only. Answer NO to the confirmation prompt instead of YES. -.TP -\fIverbose = < param >\fR -Verbose. Record session to stdout, or debug file if specified (see debug). -.TP -\fIdebug = < param >\fR -Specifies file, where will be written debug messages from session. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_ibmblade.8 b/fence/man/fence_ibmblade.8 deleted file mode 100644 index a3245be..0000000 --- a/fence/man/fence_ibmblade.8 +++ /dev/null @@ -1,68 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_ibmblade 8 - -.SH NAME -fence_ibmblade - I/O Fencing agent for IBM BladeCenter - -.SH SYNOPSIS -.B -fence_ibmblade -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_ibmblade is an I/O Fencing agent which can be used with IBM BladeCenter -chassis. It issues SNMP Set request to BladeCenter chassins, rebooting, powering -up or down the specified Blade Server. - -fence_ibmblade accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_ibmblade -can be run by itself with command line options which is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the BladeCenter chassis. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-c\fP \fIcommunity\fP -SNMP community string to use. -.TP -\fB-n\fP \fIport\fP -The Blade port number to disable. -.TP -\fB-o\fP \fIaction\fP -The action required. Reboot (default), On or off. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_ibmblade. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIcommunity = < param >\fR -SNMP community. -.TP -\fIoption = < param >\fR -The action required. reboot (default), on or off. -.TP -\fIport = < param >\fR -The Blade port number to disable. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_ilo.8 b/fence/man/fence_ilo.8 deleted file mode 100644 index 63937f3..0000000 --- a/fence/man/fence_ilo.8 +++ /dev/null @@ -1,101 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_ilo 8 - -.SH NAME -fence_ilo - I/O Fencing agent for HP Integrated Lights Out card - -.SH SYNOPSIS -.B -fence_ilo -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_ilo is an I/O Fencing agent used for HP servers with the Integrated Light -Out (iLO) PCI card. The agent opens an SSL connection to the iLO card. Once the -SSL connection is established, the agent is able to communicate with the iLO -card through an XML stream. - -fence_ilo depends on the pyOpenSSL available in your distribution or -downloadable from http://pyopenssl.sourceforge.net - -NOTE: fence_ilo deprecates fence_rib. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress[:port]\fR -IP address or hostname of the iLO card. If the SSL server of the card is -not running on the default SSL port, 443, then [:port] will also need to be -specified. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fR -Login name. -.TP -\fB-o\fP \fIaction\fR -The action required. reboot (default), off, on or status. -.TP -\fB-p\fP \fIpassword\fR -Password for login or for passphrase. -.TP -\fB-S\fP \fIscript\fR -Script to run to retrieve password. -\fB-z\fP -Use secure connection over SSL (default). -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-r\fP \fIprotocol\fR -RIBCL protocol to use. Default is to autodetect. -.TP -\fB-v\fP -Verbose. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIaction = < param >\fR -The action required. reboot (default), off, on or status. -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_ilo. -.TP -\fIhostname = < hostname | ip >\fR -IP address or hostname of the iLO card. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIpasswd = < param >\fR -Password for login or for passphrase. -.TP -\fIpasswd_script = < param >\fR -Script to run to retrieve password. -.TP -\fIssl = < param >\fR -Use secure connection over SSL. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIribcl = < param >\fR -RIBCL protocol to use. Default is to autodetect. -.TP -\fIverbose = < param >\fR -Verbose mode. - -.SH SEE ALSO -fence(8), fence_node(8), fence_rib(8) diff --git a/fence/man/fence_ipmilan.8 b/fence/man/fence_ipmilan.8 deleted file mode 100644 index 5bcdf8c..0000000 --- a/fence/man/fence_ipmilan.8 +++ /dev/null @@ -1,101 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_ipmilan 8 - -.SH NAME -fence_ipmilan - I/O Fencing agent for machines controlled by IPMI over -LAN. - -.SH SYNOPSIS -.B -fence_ipmilan -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_ipmilan is an I/O Fencing agent which can be used with -machines controlled by IPMI. This agent calls support software -using ipmitool (http://ipmitool.sf.net/). - -fence_ipmilan accepts options on the command line as well as from stdin. -fenced sends the options through stdin when it execs the agent. fence_ipmilan -can be run by itself with command line options which is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address or hostname of the IPMI controller. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Login (if required) with administrative privileges. -.TP -\fB-o\fP \fIoption\fP -Action to perform (on, off, reboot). -.TP -\fB-p\fP \fIpassword\fP -Password (if required) for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-A\fP \fIAuthentication Type\fP -Can be set to none, password, md2, or md5. -.TP -\fB-M\fP \fImethod\fP -Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management -card will power off with default method so there will be no chance to power machine -on by IPMI. -.TP -\fB-t\fP \fItimeout\fP -Timeout in seconds for IPMI operation. Default is 10, but in some cases it -must be set to higher value (anything above 30 is not recommended and may -cause strange problems). -.TP -\fB-q\fP -Quiet operation. Only print out error messages. -.TP -\fB-V\fP -Print out a version message, then exit. -.TP -\fB-v\fP -Verbose mode. - -.SH STDIN PARAMETERS -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the IPMI controller. -.TP -\fIlogin= < param >\fR -Login (if required) with administrative privileges. -.TP -\fIoption = < param >\fR -Action to perform (on, off, reboot). -.TP -\fIpasswd = < param >\fR -Password (if required) for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIauth = < param >\fR -Authentication type (none, password, md2, md5). -.TP -\fItimeout = < param >\fR -Timeout in seconds for IPMI operation. Default is 10, but in some cases it -must be set to higher value (anything above 30 is not recommended and may -cause strange problems). -.TP -\fImethod = < param >\fR -Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management -card will power off with default method so there will be no chance to power machine -on by IPMI. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_manual.8 b/fence/man/fence_manual.8 deleted file mode 100644 index b227b01..0000000 --- a/fence/man/fence_manual.8 +++ /dev/null @@ -1,56 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_manual 8 - -.SH NAME -fence_manual - program run by fenced as a part of manual I/O Fencing - -.SH SYNOPSIS -.B -fence_manual -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_manual is run by fenced. It creates a fifo and waits for -its counter-part fence_ack_manual(8) to acknowledge that a failed node -has been reset. fence_ack_manual(8) should only be run after the operator -has reset the faulty node. While waiting for the manual acknowledgement, -fence_manual also watches for the faulty node to rejoin the cluster; -if it does, it's taken as an acknowledgement and completes. - -Note: fence_manual is provided for use during testing and evaluation -only. Sites should not use fence_manual as the primary fencing method -on a production cluster. - -.SH OPTIONS -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-q\fP -quiet mode, no output. -.TP -\fB-n\fP \fInodename\fP -The node name (usually hostname) of the machine that needs to be reset or disconnected from shared storage. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_manual. -.TP -\fInodename = < param >\fR -The node name (usually hostname) of the machine that needs to be reset or disconnected from storage. -.TP -\fIipaddr = < param >\fR -IP address or hostname of the machine that needs to be reset or disconnected from storage. (Deprecated; use nodename instead.) - -.SH SEE ALSO -fence(8), fence_node(8), fence_ack_manual(8) diff --git a/fence/man/fence_mcdata.8 b/fence/man/fence_mcdata.8 deleted file mode 100644 index 00b7b65..0000000 --- a/fence/man/fence_mcdata.8 +++ /dev/null @@ -1,89 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_mcdata 8 - -.SH NAME -fence_mcdata - I/O Fencing agent for McData FC switches - -.SH SYNOPSIS -.B -fence_mcdata -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_mcdata is an I/O Fencing agent which can be used with McData FC -switches. It logs into a McData switch via telnet and disables a specified -port. Disabling the port which a machine is connected to effectively fences -that machine. Lengthy telnet connections to the switch should be avoided -while a GFS cluster is running because the connection will block any necessary -fencing actions. - -fence_mcdata accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_mcdata -can be run by itself with command line options which is useful for testing. - -After a fence operation has taken place the fenced machine can no longer connect -to the McData FC switch. When the fenced machine is ready to be brought back -into the GFS cluster (after reboot) the port on the McData FC switch needs to -be enabled. This can be done by running fence_mcdata and specifying the -enable action. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Username name for the switch. -.TP -\fB-n\fP \fIport\fP -The port number to disable on the switch. -.TP -\fB-o\fP \fIaction\fP -The action required. disable (default) or enable. -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_mcdata. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. disable (default) or enable. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The port number to disable on the switch. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_node.8 b/fence/man/fence_node.8 deleted file mode 100644 index c1a2b34..0000000 --- a/fence/man/fence_node.8 +++ /dev/null @@ -1,43 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_node 8 - -.SH NAME -fence_node - A program which performs I/O fencing on a single node. - -.SH SYNOPSIS -.B -fence_node -[\fIOPTION\fR]... - -.SH DESCRIPTION -\fBfence_node\fP is a program which accumulates all the necessary information -for I/O fencing a particular node and then performs the fencing action by -issuing a call to the proper fencing agent. \fBfence_node\fP gets the -necessary information from the Cluster Configuration System (CCS). CCS must -be running and properly configured for \fBfence_node\fP to work properly. - -.SH OPTIONS -.TP -\fB-h\fP -Help. Print out the usage syntax. -.TP -\fB-O\fP -Force a connection to CCS. This overrides the usual -requirement that the cluster be quorate to get information from ccs. -.TP -\fB-V\fP -Print version information. - -.SH EXAMPLES -.TP -To fence a node called ``bellerophon'': -prompt> fence_node bellerophon - -.SH SEE ALSO -fence(8), ccs(7) diff --git a/fence/man/fence_rackswitch.8 b/fence/man/fence_rackswitch.8 deleted file mode 100644 index 1956172..0000000 --- a/fence/man/fence_rackswitch.8 +++ /dev/null @@ -1,75 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_rackswitch 8 - -.SH NAME -fence_rackswitch - I/O Fencing agent for RackSaver RackSwitch - -.SH SYNOPSIS -.B -fence_rackswitch -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_rackswitch is an I/O Fencing agent which can be used with the RackSaver -RackSwitch. It logs into the RackSwitch and boots a specified plug. -Using the http interface to the RackSwitch should be avoided while a GFS cluster is -running because the connection may interfere with the operation of this agent. - -fence_rackswitch accepts options on the command line as well as from stdin. -fenced sends the options through stdin when it execs the agent. fence_rackswitch -can be run by itself with command line options which is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-n\fP \fIplug\fP -The plug number to power cycle. -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-l\fP \fIusername\fP -Username for login. -.TP -\fB-q\fP -Quiet operation. Only print out error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_rackswitch. -.TP -\fIipaddr = < ip >\fR -IP address of the switch. -.TP -\fIusername = < param >\fR -Username for login. -.TP -\fIpassword = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The port (outlet) number to act upon. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_rib.8 b/fence/man/fence_rib.8 deleted file mode 100644 index f540ff9..0000000 --- a/fence/man/fence_rib.8 +++ /dev/null @@ -1,17 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_rib 8 - -.SH NAME -fence_rib - I/O Fencing agent for Compaq Remote Insight Lights Out card - -.SH DESCRIPTION -fence_rib is deprecated. fence_ilo should be used instead - -.SH SEE ALSO -fence_ilo(8) diff --git a/fence/man/fence_rsa.8 b/fence/man/fence_rsa.8 deleted file mode 100644 index 1b0127a..0000000 --- a/fence/man/fence_rsa.8 +++ /dev/null @@ -1,76 +0,0 @@ -." Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_rsa 8 - -.SH NAME -fence_rsa - I/O Fencing agent for IBM RSA II - -.SH SYNOPSIS -.B -fence_rsa -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_rsa is an I/O Fencing agent which can be used with the IBM RSA II -management interface. It logs into an RSA II device via telnet and reboots -the associated machine. Lengthy telnet connections to the RSA II device -should be avoided while a GFS cluster is running because the connection -will block any necessary fencing actions. - -fence_rsa accepts options on the command line as well as from stdin. -Fenced sends parameters through stdin when it execs the agent. fence_rsa -can be run by itself with command line options. This is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fR -IP address or hostname of the RSA II device. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fR -Login name. -.TP -\fB-o\fP \fIaction\fR -The action required. Reboot (default), Off, On, or Status. -.TP -\fB-p\fP \fIpassword\fR -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-v\fP -Verbose. Print informational messages to standard out. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_rsa. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the device. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. Reboot (default), Off, On or Status. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_rsb.8 b/fence/man/fence_rsb.8 deleted file mode 100644 index 985c6a6..0000000 --- a/fence/man/fence_rsb.8 +++ /dev/null @@ -1,81 +0,0 @@ -." Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_rsb 8 - -.SH NAME -fence_rsb - I/O Fencing agent for Fujitsu-Siemens RSB - -.SH SYNOPSIS -.B -fence_rsb -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_rsb is an I/O Fencing agent which can be used with the Fujitsu-Siemens -RSB management interface. It logs into an RSB device via telnet and reboots -the associated machine. Lengthy telnet connections to the RSB device -should be avoided while a GFS cluster is running because the connection -will block any necessary fencing actions. - -fence_rsb accepts options on the command line as well as from stdin. -Fenced sends parameters through stdin when it execs the agent. fence_rsb -can be run by itself with command line options. This is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fR -IP address or hostname of the RSB device. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fR -Login name. -.TP -\fB-n\fP \fItelnet_port\fR -The port number on which the telnet service listens. -.TP -\fB-o\fP \fIaction\fR -The action required. Reboot (default), Off, On, or Status. -.TP -\fB-p\fP \fIpassword\fR -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-v\fP -Verbose. Print informational messages to standard out. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_rsb. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the device. -.TP -\fItelnet_port = < port number >\fR -The port number on which the telnet service listens. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. Reboot (default), Off, On or Status. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_sanbox2.8 b/fence/man/fence_sanbox2.8 deleted file mode 100644 index 8d3aa00..0000000 --- a/fence/man/fence_sanbox2.8 +++ /dev/null @@ -1,89 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_sanbox2 8 - -.SH NAME -fence_sanbox2 - I/O Fencing agent for QLogic SANBox2 FC switches - -.SH SYNOPSIS -.B -fence_sanbox2 -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_sanbox2 is an I/O Fencing agent which can be used with QLogic SANBox2 FC -switches. It logs into a SANBox2 switch via telnet and disables a specified -port. Disabling the port which a machine is connected to effectively fences -that machine. Lengthy telnet connections to the switch should be avoided -while a GFS cluster is running because the connection will block any necessary -fencing actions. - -fence_sanbox2 accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_sanbox2 -can be run by itself with command line options which is useful for testing. - -After a fence operation has taken place the fenced machine can no longer connect -to the switch. When the fenced machine is ready to be brought back -into the GFS cluster (after reboot) the port on the FC switch needs to -be enabled. This can be done by running fence_sanbox2 and specifying the -enable action. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-l\fP \fIlogin\fP -Login name for the switch. -.TP -\fB-n\fP \fIport\fP -The port number to disable on the switch. -.TP -\fB-o\fP \fIaction\fP -The action required. disable (default) or enable. -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_sanbox2. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIlogin = < param >\fR -Login name. -.TP -\fIoption = < param >\fR -The action required. disable (default) or enable. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The port number to disable on the switch. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_scsi.8 b/fence/man/fence_scsi.8 deleted file mode 100644 index 62d75ba..0000000 --- a/fence/man/fence_scsi.8 +++ /dev/null @@ -1,109 +0,0 @@ -." Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_scsi 8 - -.SH NAME -fence_scsi - I/O fencing agent for SCSI persistent reservations - -.SH SYNOPSIS -.B -fence_scsi -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_scsi is an I/O fencing agent which can be used with the SCSI -devices that support persistent reservations (SPC-2 or greater). - -SCSI persistent reservations work by having each node in the cluster -register with the SCSI device. Registration is done using a unique key -(based on the node's IP address). Each node that will perform I/O -operations to the shared storage must register with the device. This -is done at system startup with the scsi_reserve init script. This -script will discover all clustered volumes as well as the underlying -SCSI device(s). Device discovery is done via the lvs command (see -lvs(8)) and is subject to any filtering rules defined in the lvm.conf -file. - -After generating the node's unique key, the script will register the -node with the SCSI device(s) that were discovered. Once the node is -registered, the script will attempt to create a reservation. Unlike -registrations, of which there are multiple registrants (one for each -node in the cluster), there is only one reservation holder. If a -reservation does not already exist for a device, the script will -create a reservation using the node's unique key. - -It is important to distinguish between registrations and -reservations. As mentioned above, each node that will perform I/O -operations to the SCSI device must register. As a result, there will -be multiple registrations for a given SCSI device. In contrast, there -can only be one reservation per SCSI device. It is not important which -node holds the reservation. The reservation simply tells the device -how the registrants are allowed to access the device. For our -purposes, the reservation type is "write exclusive, registrants only". -With this reservation type, only registered nodes will be able to -write to the device. - -When the cluster must fence a node, it simply revokes a node's -registration, or "unregisters" the node. This operation also uses the -node's unique key. By deriving the unique key based on the errant -node's IP address, the cluster can "unregister" the key. As a -result, the errant node will no longer be able to write to the SCSI -device. - -Note that the node that holds the reservation for a device must also -be registered with that device. When the situation arises where the -node that is being fenced is also the reservation holder, the -reservation must be moved. This is handled by using the -"preempt-and-abort command" which will transfer the reservation from -the node that is being fenced to the node that is performing the -fencing. This operation will maintain the reservation while -"unregistering" the node being fenced. - -At system shutdown, the scsi_reserve script will attempt to -"unregister" the node from all devices. The exception is when the -node happens to be the reservation holder. In this case, the script -does nothing, due to the fact that there may be other nodes using the -device and the reservation must remain intact. - -fence_scsi accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_scsi -can be run by itself with command line options. This is useful for testing -and for turning outlets on or off from scripts. - -.SH OPTIONS -.TP -\fB-n\fP \fInode\fR -Name of the node to be fenced. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-s\fP \fIself\fR -Name of the node that will perform the fencing operation. -.TP -\fB-v\fP -Verbose output. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_scsi. -.TP -\fInodename = < hostname | ip >\fR -Name of the node to be fenced. -.TP -\fIself = < nodename >\fR -Name of the node that will perform the fencing operation. -.TP -\fIverbose = < param >\fR -Verbose output. - -.SH SEE ALSO -fence(8), fence_node(8), sg_persist(8), lvs(8), lvm.conf(5) diff --git a/fence/man/fence_tool.8 b/fence/man/fence_tool.8 deleted file mode 100644 index 41ebc13..0000000 --- a/fence/man/fence_tool.8 +++ /dev/null @@ -1,64 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_tool 8 - -.SH NAME -fence_tool - A program to join and leave the fence domain - -.SH SYNOPSIS -.B -fence_tool -<\fBjoin | leave | wait\fP> -[\fIOPTION\fR]... - -.SH DESCRIPTION -\fBfence_tool\fP is a program used to join or leave the default fence -domain. Specifically, it starts the fence daemon (fenced) to join the -domain and kills fenced to leave the domain. Fenced can be started -and stopped directly without using this program, but fence_tool takes -some added steps that are often helpful. - -Before joining or leaving the fence domain, fence_tool waits for the -cluster be in a quorate state. The user can cancel fence_tool while it's -waiting for quorum. It's generally nicer to block waiting for quorum here -than to have the fence daemon itself waiting to join or leave the domain -while the cluster is inquorate. - -Since \fBfence_tool join\fP is the usual way of starting fenced, the -fenced options -j, -f, and -c can also be passed to fence_tool which -passes them on to fenced. - -A node must not leave the fence domain (fenced must not be terminated) -while CLVM or GFS are in use. - -.SH OPTIONS -.TP -\fB-w\fP -Wait until the join is completed. "fence_tool join -w" is -equivalent to "fence_tool join; fence_tool wait" -.TP -\fB-h\fP -Help. Print out the usage syntax. -.TP -\fB-V\fP -Print version information. -.TP -\fB-D\fP -Enable debugging output and don't fork (also passed to fenced) -.TP -\fB-j\fP \fIsecs\fP -Post-join fencing delay (passed to fenced) -.TP -\fB-f\fP \fIsecs\fP -Post-fail fencing delay (passed to fenced) -.TP -\fB-c\fP -All nodes are in a clean state to start (passed to fenced) - -.SH SEE ALSO -fenced(8), fence(8), fence_node(8) diff --git a/fence/man/fence_vixel.8 b/fence/man/fence_vixel.8 deleted file mode 100644 index c105dde..0000000 --- a/fence/man/fence_vixel.8 +++ /dev/null @@ -1,77 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_vixel 8 - -.SH NAME -fence_vixel - I/O Fencing agent for Vixel FC switches - -.SH SYNOPSIS -.B -fence_vixel -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_vixel is an I/O Fencing agent which can be used with Vixel FC switches. -It logs into a Vixel switch via telnet and removes the specified port from the -zone. Removing the zone access from the port disables the port from being able -to access the storage. - -fence_vixel accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_vixel -can be run by itself with command line options which is useful for testing. - -After a fence operation has taken place the fenced machine can no longer -connect to the Vixel FC switch. When the fenced machine is ready to be brought -back into the GFS cluster (after reboot) the port on the Vixel FC switch needs -to be enabled. In order to do this, log into the Vixel FC switch. Then go to: - -config->zones->config <port> <comma-separated-list-of-ports-in-the-zone> - -Then apply - -Consult the Vixel manual for details - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-n\fP \fIport\fP -The port number to remove zoning from on the switch. -.TP -\fB-p\fP \fIpassword\fP -Password for login. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_vixel. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIpasswd = < param >\fR -Password for login. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The port number to remove zoning from on the switch. - -.SH BSEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_wti.8 b/fence/man/fence_wti.8 deleted file mode 100644 index 9487472..0000000 --- a/fence/man/fence_wti.8 +++ /dev/null @@ -1,90 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_wti 8 - -.SH NAME -fence_wti - I/O Fencing agent for WTI Network Power Switch - -.SH SYNOPSIS -.B -fence_wti -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_wti is an I/O Fencing agent which can be used with the WTI Network -Power Switch (NPS). It logs into an NPS via telnet or ssh and boots a specified plug. -Lengthy telnet connections to the NPS should be avoided while a GFS cluster is -running because the connection will block any necessary fencing actions. - -fence_wti accepts options on the command line as well as from stdin. -fenced sends the options through stdin when it execs the agent. fence_wti -can be run by itself with command line options which is useful for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address of the switch. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-n\fP \fIplug\fP -The plug number to power cycle. -.TP -\fB-p\fP \fIpassword\fP -Password for login or for passphrase. -.TP -\fB-S\fP \fIscript\fR -Script to run to retrieve password. -.TP -\fB-x\fP -Use secure connection over ssh. -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password for login. -.TP -\fB-T\fP -Test only. Do not power cycle. Reports state of the plug. -.TP -\fB-q\fP -Quiet operation. Only print out error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_wti. -.TP -\fIipaddr = < hostname | ip >\fR -IP address or hostname of the switch. -.TP -\fIpasswd = < param >\fR -Password for login or for passphrase. -.TP -\fIpasswd_script = < param >\fR -Script to run to retrieve password. -.TP -\fIidentity_file = < param > \fR -Identity file (private key) for ssh. -.TP -\fIsecure = < param >\fR -Use secure connection over ssh. -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password for login. -.TP -\fIport = < param >\fR -The outlet number to act upon. -.TP -\fItest = < param >\fR -Test only. Answer NO to the confirmation prompt instead of YES. - -.SH SEE ALSO -fence(8), fence_node(8) diff --git a/fence/man/fence_xcat.8 b/fence/man/fence_xcat.8 deleted file mode 100644 index 3aaa620..0000000 --- a/fence/man/fence_xcat.8 +++ /dev/null @@ -1,64 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. - -.TH fence_xcat 8 - -.SH NAME -fence_xcat - I/O Fencing agent for xcat environments - -.SH SYNOPSIS -.B -fence_xcat -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_xcat is a wrapper to the rpower(1) command that is distributed -with the xCAT project available at http://www.xcat.org. Use of -fence_xcat requires that xcat has already been properlly configfured -for your environment. Refer to xCAT(1) for more information on -configuring xCAT. - -fence_xcat accepts options on the command line as well as from stdin. -fenced sends parameters through stdin when it execs the agent. fence_xcat -can be run by itself with command line options which is useful for testing. - -NOTE: It is recommended that fence_bladecenter(8) is used instead of fence_xcat if -the bladecenter firmware supports telnet. This interface is much cleaner and -easier to setup. - -.SH OPTIONS -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-n\fP \fInodename\fP -The nodename as defined in nodelist.tab of the xCAT setup. -.TP -\fB-o\fP \fIaction\fP -The action required. on, off, reset (default) or stat. -.TP -\fB-r\fP \fIrpower\fP -The path to the rpower binary. -.TP -\fB-q\fP -Quiet mode: print only error messages. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fR -This option is used by fence_node(8) and is ignored by fence_xcat. -.TP -\fInodename = < param >\fR -The nodename as defined in nodelist.tab of the xCAT setup. -.TP -\fIaction = < param >\fR -The action required. on, off, reset (default) or stat. -.TP -\fIrpower = < param >\fR -The path to the rpower binary. - -.SH SEE ALSO -fence(8), fence_node(8), fence_bladecenter(8), nodelist.tab(8), rpower(1), xCAT(1) diff --git a/fence/man/fence_xvm.8 b/fence/man/fence_xvm.8 deleted file mode 100644 index a58b266..0000000 --- a/fence/man/fence_xvm.8 +++ /dev/null @@ -1,142 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_xvm 8 - -.SH NAME -fence_xvm - I/O Fencing agent for Xen virtual machines. - -.SH SYNOPSIS -.B -fence_xvm -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_xvm is an I/O Fencing agent which can be used with Xen virtual machines -which are part of a cluster. There is a requirement that the parent -domain-0s are also a part of a CMAN/OpenAIS based cluster, such as -linux-cluster. - -fence_xvm accepts options on the command line as well as from standard input. -If no command line options are present, fence_xvm will automatically use -standard input. fenced sends the options through stdin when it execs the -agent. fence_xvm can be run by itself with command line options which is -useful for testing. - -.SH OPTIONS -.TP -\fB-d\fP -Enable debugging output. The more times you specify this parameter, -the more debugging output you will receive. -.TP -\fB-i\fP \fIfamily\fP -IP family to use (auto, ipv4, or ipv6; default = auto) -.TP -\fB-a\fP \fIaddress\fP -Multicast address to use (default=225.0.0.12 for ipv4, ff02::3:1 for ipv6) -.TP -\fB-p\fP \fIport\fP -Port to use for all communications; must match fence_xvmd (default=1229) -.TP -\fB-r\fP \fIretrans\fP -Multicast retransmission time (in 1/10 seconds; default=20). This -is used to tune the amount of retransmission which is done on busy networks -where multicast traffic is unreliable. -.TP -\fB-C\fP \fIauth\fP -Authentication type (none, sha1, sha256, sha512; default=sha256). This -controls the authentication mechanism used to authenticate clients. The -three SHA hashes use a key which must be shared between both the Xen virtual -machines and the host domain-0 cluster. The three SHA authentication -mechanisms use a simple bidirectional challenge-response based on pseudo- -random number generation and a shared private key. -.TP -\fB-c\fP \fIhash\fP -Packet hash type (none, sha1, sha256, sha512; default=sha256). This -controls the hashing mechanism used to authenticate fencing requests. The -three SHA hashes use a key which must be shared between both the Xen virtual -machines and the host domain-0 cluster. -.TP -\fB-k\fP \fIkey_file\fP -Use the specified key file for packet hashing / SHA authentication. -When both the hash type and the authentication type are set to "none", -this parameter is ignored. -.TP -\fB-H\fP \fIdomain\fP -This specifies unique domain name of the Xen guest which needs to be fenced. -.TP -\fB-u\fP -Fence by UUID instead of Xen Domain name. If specified, the above -H -parameter should be the statically-defined 36-character UUID of the Xen -domain rather than its human-readable name. -.TP -\fB-o\fP \fIoperation\fP -Fencing operation to perform (null, off, reboot; default=off). This specifies -the fencing operation to perform. The null operation does not actually do -anything, but allows you to check to see if communication with fence_xvmd -is working correctly (note: the result of the null operation is *always* -failure!). -.TP -\fB-t\fP \fItimeout\fP -This specifies the amount of time, in seconds, to wait before a response to -the multicast request before giving up (default=30). -.TP -\fB-?\fP -Print out a help message describing available options, then exit. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIdebug = 1\fR -Same as the -d option. Specify numbers >1 for more debugging information. -.TP -\fIfamily = < param >\fR -Same as the -i option. -.TP -\fImulticast_address = < param >\fR -Same as the -a option. -.TP -\fIport = < param >\fR -Same as the -p option. -.TP -\fIretrans = < param >\fR -Same as the -r option. -.TP -\fIauth = < param >\fR -Same as the -C option. -.TP -\fIhash = < param >\fR -Same as the -c option. -.TP -\fIkey_file = < param >\fR -Same as the -k option. -.TP -\fIretrans = < param >\fR -Same as the -r option. -.TP -\fIdomain = < param >\fR -Same as the -H option. -.TP -\fIuse_uuid = 1\fR -Same as the -u option. -.TP -\fIoption = < param >\fR -Same as the -o option. -.TP -\fItimeout = < param >\fR -Same as the -t option. -.TP -\fIdomain = < param >\fR -Same as the -H option. - -.SH SEE ALSO -fence(8), fence_node(8), fence_xvmd(8) diff --git a/fence/man/fence_zvm.8 b/fence/man/fence_zvm.8 deleted file mode 100644 index 6558987..0000000 --- a/fence/man/fence_zvm.8 +++ /dev/null @@ -1,69 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fence_zvm 8 - -.SH NAME -fence_zvm - I/O Fencing agent for GFS on s390 and zSeries VM clusters - -.SH SYNOPSIS -.B -fence_zvm -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_zvm is an I/O Fencing agent used on a GFS virtual machine in a s390 or zSeries VM cluster. -It uses the s3270 program to log the specified virtual machine out of VM. -For fence_zvm to execute correctly, you must have s3270 in your PATH. - -fence_zvm accepts options on the command line as well as from stdin. -fence_node sends the options through stdin when it execs the agent. -fence_zvm can be run by itself with command line options which is useful -for testing. - -.SH OPTIONS -.TP -\fB-a\fP \fIIPaddress\fP -IP address or hostname of the Physical machine (required). -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-u\fP \fIuserid\fP -userid of the virtual machine to fence (required). -.TP -\fB-p\fP \fIpassword\fP -password of the virtual machine to fence (required). -.TP -\fB-S\fP \fIpath\fR -Full path to an executable to generate the password of the virtual machine to fence. -.TP -\fB-q\fP -quiet mode, no output. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fP -This option is used by fence_node(8) and is ignored by fence_zvm. -.TP -\fIipaddr = < hostname | ip >\fP -IP address or hostname of the Physical machine (required). -.TP -\fIpasswd = < param >\fP -password of the virtual machine to fence (required). -.TP -\fIpasswd_script = < param >\fR -Full path to an executable to generate the password of the virtual machine to fence. -.TP -\fIuserid = < param >\fP -userid of the virtual machine to fence (required). - -.SH SEE ALSO -fence(8), fenced(8), fence_node(8) diff --git a/fence/man/fenced.8 b/fence/man/fenced.8 deleted file mode 100644 index c4804d7..0000000 --- a/fence/man/fenced.8 +++ /dev/null @@ -1,141 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH fenced 8 - -.SH NAME -fenced - the I/O Fencing daemon - -.SH SYNOPSIS -.B -fenced -[\fIOPTION\fR]... - -.SH DESCRIPTION -The fencing daemon, \fBfenced\fP, should be run on every node that will -use CLVM or GFS. It should be started after the node has joined the CMAN -cluster (fenced is only used with CMAN; it is not used with GULM/SLM/RLM.) -A node that is not running \fBfenced\fP is not permitted to mount GFS file -systems. - -All fencing daemons running in the cluster form a group called the "fence -domain". Any member of the fence domain that fails is fenced by a -remaining domain member. The actual fencing does not occur unless the -cluster has quorum so if a node failure causes the loss of quorum, the -failed node will not be fenced until quorum has been regained. If a -failed domain member (due to be fenced) rejoins the cluster prior to the -actual fencing operation is carried out, the fencing operation is -bypassed. - -The fencing daemon depends on CMAN for cluster membership information and -it depends on CCS to provide cluster.conf information. The fencing daemon -calls fencing agents according to cluster.conf information. - -.SS Node failure - -When a domain member fails, the actual fencing must be completed before -GFS recovery can begin. This means any delay in carrying out the fencing -operation will also delay the completion of GFS file system operations; -most file system operations will hang during this period. - -When a domain member fails, the actual fencing operation can be delayed by -a configurable number of seconds (post_fail_delay or -f). Within this -time the failed node can rejoin the cluster to avoid being fenced. This -delay is 0 by default to minimize the time that applications using GFS are -stalled by recovery. A delay of -1 causes the fence daemon to wait -indefinitely for the failed node to rejoin the cluster. In this case the -node is not fenced and all recovery must wait until the failed node -rejoins the cluster. - -.SS Domain startup - -When the domain is first created in the cluster (by the first node to join -it) and subsequently enabled (by the cluster gaining quorum) any nodes -listed in cluster.conf that are not presently members of the CMAN cluster -are fenced. The status of these nodes is unknown and to be on the side of -safety they are assumed to be in need of fencing. This startup fencing -can be disabled; but it's only truely safe to do so if an operator is -present to verify that no cluster nodes are in need of fencing. -(Dangerous nodes that need to be fenced are those that had gfs mounted, -did not cleanly unmount, and are now either hung or unable to communicate -with other nodes over the network.) - -The first way to avoid fencing nodes unnecessarily on startup is to ensure -that all nodes have joined the cluster before any of the nodes start the -fence daemon. This method is difficult to automate. - -A second way to avoid fencing nodes unnecessarily on startup is using the -post_join_delay parameter (or -j option). This is the number of seconds -the fence daemon will delay before actually fencing any victims after -nodes join the domain. This delay will give any nodes that have been -tagged for fencing the chance to join the cluster and avoid being fenced. -A delay of -1 here will cause the daemon to wait indefinitely for all -nodes to join the cluster and no nodes will actually be fenced on startup. - -To disable fencing at domain-creation time entirely, the -c option can be -used to declare that all nodes are in a clean or safe state to start. The -clean_start cluster.conf option can also be set to do this, but -automatically disabling startup fencing in cluster.conf can risk file -system corruption. - -Avoiding unnecessary fencing at startup is primarily a concern when nodes -are fenced by power cycling. If nodes are fenced by disabling their SAN -access, then unnecessarily fencing a node is usually less disruptive. - -.SH CONFIGURATION FILE -Fencing daemon behavior can be controlled by setting options in the -cluster.conf file under the section <fence_daemon> </fence_daemon>. See -above for complete descriptions of these values. The delay values are in -seconds; -1 secs means an unlimitted delay. The values shown are the -defaults. - -Post-join delay is the number of seconds the daemon will wait before -fencing any victims after a node joins the domain. - - <fence_daemon post_join_delay="3"> - </fence_daemon> - -Post-fail delay is the number of seconds the daemon will wait before -fencing any victims after a domain member fails. - - <fence_daemon post_fail_delay="0"> - </fence_daemon> - -Clean-start is used to prevent any startup fencing the daemon might do. -It indicates that the daemon should assume all nodes are in a clean state -to start. - - <fence_daemon clean_start="0"> - </fence_daemon> - -.SH OPTIONS -Command line options override corresonding values in cluster.conf. -.TP -\fB-j\fP \fIsecs\fP -Post-join fencing delay -.TP -\fB-f\fP \fIsecs\fP -Post-fail fencing delay -.TP -\fB-c\fP -All nodes are in a clean state to start. -.TP -\fB-D\fP -Enable debugging code and don't fork into the background. -.TP -\fB-n\fP \fIname\fP -Name of the fence domain, "default" if none. -.TP -\fB-V\fP -Print the version information and exit. -.TP -\fB-h\fP -Print out a help message describing available options, then exit. - -.SH SEE ALSO -gfs(8), fence(8) - diff --git a/fence/scripts/define2var b/fence/scripts/define2var deleted file mode 100755 index 6f0ef5b..0000000 --- a/fence/scripts/define2var +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## -## This script will pull out #define's and convert them into variables that -## can be used for shell or perl scripts. -## -## It takes 2 or 3 parameters. The first parameter is the filename to search -## in. The second paramter is the desired output format. Supported types -## ar sh and perl. An optional third parameter may be given. If specified, -## only that partiucular #define will be extracted, otherwise, all #defines -## are extracted. This script is not capable of handling condiitional rules. -## - -$usage = "usage: define2var <filename> <perl|sh> [define]"; - -if (@ARGV != 2 && @ARGV != 3) -{ - die "$usage\n"; -} - -my ($filename, $type, $define ) = @ARGV; -my $pfx,$sfx; - -if ($type eq "sh") -{ - ($pfx,$sfx) = ("",""); i -} -elsif ($type eq "perl" ) -{ - ($pfx,$sfx) = ("$",";"); -} -else -{ - die "Unknown type: $type\n"; -} - -open FILE, "< $filename" or die "error opening $filename: $!\n"; - -while (<FILE>) -{ - chomp; - if ($_ =~ /^#define\s+(\S+)\s+(.*)/) - { - if(! $define ) - { - print "$pfx$1=$2$sfx\n"; - } - elsif ($define eq $1 ) - { - print "$pfx$1=$2$sfx\n"; - exit 0; - } - } -} - -die ""$define" not found\n" if ($define); - -exit 0; diff --git a/fence/scripts/uninstall.pl b/fence/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/fence/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/gfs-kernel/Makefile b/gfs-kernel/Makefile deleted file mode 100644 index a1b0df5..0000000 --- a/gfs-kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: - cd src && ${MAKE} all - -clean: - cd src && ${MAKE} clean - -install: - cd src && ${MAKE} install - -uninstall: - cd src && ${MAKE} uninstall - -distclean: clean - rm -f make/defines.mk \ No newline at end of file diff --git a/gfs-kernel/configure b/gfs-kernel/configure deleted file mode 100755 index 430d161..0000000 --- a/gfs-kernel/configure +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$kernel_src) { - $kernel_src="/usr/src/linux-2.6"; -} -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -open VER, "<$kernel_src/include/linux/version.h" or die "Can't open $kernel_src/include/linux/version.h"; -while(<VER>){ - chomp; - if( $_ =~ /^#define\s*UTS_RELEASE\s*"(.*)"$/ ){ - $kernel_version = $1; - $module_dir = "${prefix}/lib/modules/$1/kernel"; - } -} - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@KERNEL_VERSION@/$kernel_version/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@MODULE_DIR@/$module_dir/; - $_ =~ s/@SBINDIR@/$sbindir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/gfs-kernel/make/defines.mk.input b/gfs-kernel/make/defines.mk.input deleted file mode 100644 index 0c2ea7a..0000000 --- a/gfs-kernel/make/defines.mk.input +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -module_dir ?= ${DESTDIR}/@MODULE_DIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ -KERNEL_VERSION = @KERNEL_VERSION@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/gfs-kernel/make/release.mk.input b/gfs-kernel/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/gfs-kernel/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/gfs-kernel/patches/2.6.9/00001.patch b/gfs-kernel/patches/2.6.9/00001.patch deleted file mode 100644 index ce49b45..0000000 --- a/gfs-kernel/patches/2.6.9/00001.patch +++ /dev/null @@ -1,65 +0,0 @@ -# Add lock harness to the build system. -diff -urN -p linux-2.6.9/fs/Kconfig linux/fs/Kconfig ---- linux-2.6.9/fs/Kconfig 2004-12-10 16:16:48.000000000 -0600 -+++ linux/fs/Kconfig 2004-12-17 20:03:05.384600848 -0600 -@@ -1768,6 +1768,14 @@ config AFS_FS - config RXRPC - tristate - -+config LOCK_HARNESS -+ tristate "GFS Lock Harness" -+ help -+ The module that connects GFS to the modules that provide -+ locking for GFS. -+ -+ If you want to use GFS (a cluster filesystem) say Y here. -+ - endmenu - - menu "Partition Types" -diff -urN -p linux-2.6.9/fs/Makefile linux/fs/Makefile ---- linux-2.6.9/fs/Makefile 2004-12-10 16:16:48.000000000 -0600 -+++ linux/fs/Makefile 2004-12-17 20:03:05.385600615 -0600 -@@ -93,3 +93,4 @@ obj-$(CONFIG_AFS_FS) += afs/ - obj-$(CONFIG_BEFS_FS) += befs/ - obj-$(CONFIG_HOSTFS) += hostfs/ - obj-$(CONFIG_HPPFS) += hppfs/ -+obj-$(CONFIG_LOCK_HARNESS) += gfs_locking/ -diff -urN -p linux-2.6.9/fs/gfs_locking/Makefile linux/fs/gfs_locking/Makefile ---- linux-2.6.9/fs/gfs_locking/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux/fs/gfs_locking/Makefile 2004-12-17 20:03:05.385600615 -0600 -@@ -0,0 +1,14 @@ -+############################################################################### -+############################################################################### -+## -+## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -+## -+## This copyrighted material is made available to anyone wishing to use, -+## modify, copy, or redistribute it subject to the terms and conditions -+## of the GNU General Public License v.2. -+## -+############################################################################### -+############################################################################### -+ -+obj-$(CONFIG_LOCK_HARNESS) += lock_harness/ -+ -diff -urN -p linux-2.6.9/fs/gfs_locking/lock_harness/Makefile linux/fs/gfs_locking/lock_harness/Makefile ---- linux-2.6.9/fs/gfs_locking/lock_harness/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux/fs/gfs_locking/lock_harness/Makefile 2004-12-17 20:03:05.385600615 -0600 -@@ -0,0 +1,16 @@ -+############################################################################### -+############################################################################### -+## -+## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -+## -+## This copyrighted material is made available to anyone wishing to use, -+## modify, copy, or redistribute it subject to the terms and conditions -+## of the GNU General Public License v.2. -+## -+############################################################################### -+############################################################################### -+ -+obj-$(CONFIG_LOCK_HARNESS) += lock_harness.o -+ -+lock_harness-y := main.o -+ diff --git a/gfs-kernel/patches/2.6.9/00002.patch b/gfs-kernel/patches/2.6.9/00002.patch deleted file mode 100644 index fd88cb8..0000000 --- a/gfs-kernel/patches/2.6.9/00002.patch +++ /dev/null @@ -1,106 +0,0 @@ -# Add GFS to the build system. -diff -urN -p linux-2.6.9/fs/Kconfig linux/fs/Kconfig ---- linux-2.6.9/fs/Kconfig 2004-12-17 20:03:54.724107982 -0600 -+++ linux/fs/Kconfig 2004-12-17 20:03:54.752101460 -0600 -@@ -283,13 +283,13 @@ config JFS_STATISTICS - to be made available to the user in the /proc/fs/jfs/ directory. - - config FS_POSIX_ACL --# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs) -+# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/GFS) - # - # NOTE: you can implement Posix ACLs without these helpers (XFS does). - # Never use this symbol for ifdefs. - # - bool -- depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL || REISERFS_FS_POSIX_ACL || NFSD_V4 -+ depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL || REISERFS_FS_POSIX_ACL || NFSD_V4 || GFS_FS - default y - - config XFS_FS -@@ -1776,6 +1776,20 @@ config LOCK_HARNESS - - If you want to use GFS (a cluster filesystem) say Y here. - -+config GFS_FS -+ tristate "GFS file system support" -+ depends on LOCK_HARNESS -+ help -+ A cluster filesystem. -+ -+ Allows a cluster of computers to simultaneously use a block device -+ that is shared between them (with FC, iSCSI, NBD, etc...). GFS reads -+ and writes to the block device like a local filesystem, but also uses -+ a lock module to allow the computers coordinate their I/O so -+ filesystem consistency is maintained. One of the nifty features of -+ GFS is perfect consistency -- changes made to the filesystem on one -+ machine show up immediately on all other machines in the cluster. -+ - endmenu - - menu "Partition Types" -diff -urN -p linux-2.6.9/fs/Makefile linux/fs/Makefile ---- linux-2.6.9/fs/Makefile 2004-12-17 20:03:54.725107749 -0600 -+++ linux/fs/Makefile 2004-12-17 20:03:54.752101460 -0600 -@@ -94,3 +94,4 @@ obj-$(CONFIG_BEFS_FS) += befs/ - obj-$(CONFIG_HOSTFS) += hostfs/ - obj-$(CONFIG_HPPFS) += hppfs/ - obj-$(CONFIG_LOCK_HARNESS) += gfs_locking/ -+obj-$(CONFIG_GFS_FS) += gfs/ -diff -urN -p linux-2.6.9/fs/gfs/Makefile linux/fs/gfs/Makefile ---- linux-2.6.9/fs/gfs/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux/fs/gfs/Makefile 2004-12-17 20:03:54.752101460 -0600 -@@ -0,0 +1,53 @@ -+############################################################################### -+############################################################################### -+## -+## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -+## -+## This copyrighted material is made available to anyone wishing to use, -+## modify, copy, or redistribute it subject to the terms and conditions -+## of the GNU General Public License v.2. -+## -+############################################################################### -+############################################################################### -+ -+obj-$(CONFIG_GFS_FS) += gfs.o -+ -+gfs-y := acl.o \ -+ bits.o \ -+ bmap.o \ -+ daemon.o \ -+ diaper.o \ -+ dio.o \ -+ dir.o \ -+ eaops.o \ -+ eattr.o \ -+ file.o \ -+ glock.o \ -+ glops.o \ -+ inode.o \ -+ ioctl.o \ -+ lm.o \ -+ log.o \ -+ lops.o \ -+ lvb.o \ -+ main.o \ -+ mount.o \ -+ ondisk.o \ -+ ops_address.o \ -+ ops_dentry.o \ -+ ops_export.o \ -+ ops_file.o \ -+ ops_fstype.o \ -+ ops_inode.o \ -+ ops_super.o \ -+ ops_vm.o \ -+ page.o \ -+ proc.o \ -+ quota.o \ -+ recovery.o \ -+ rgrp.o \ -+ super.o \ -+ trans.o \ -+ unlinked.o \ -+ util.o -+ diff --git a/gfs-kernel/patches/2.6.9/00003.patch b/gfs-kernel/patches/2.6.9/00003.patch deleted file mode 100644 index a320d35..0000000 --- a/gfs-kernel/patches/2.6.9/00003.patch +++ /dev/null @@ -1,46 +0,0 @@ -# Add lock_nolock to the build system. -diff -urN -p linux-2.6.9/fs/Kconfig linux/fs/Kconfig ---- linux-2.6.9/fs/Kconfig 2004-12-17 20:03:58.371258623 -0600 -+++ linux/fs/Kconfig 2004-12-17 20:03:58.382256062 -0600 -@@ -1790,6 +1790,12 @@ config GFS_FS - GFS is perfect consistency -- changes made to the filesystem on one - machine show up immediately on all other machines in the cluster. - -+config LOCK_NOLOCK -+ tristate "Lock Nolock" -+ depends on LOCK_HARNESS -+ help -+ A "fake" lock module that allows GFS to run as a local filesystem. -+ - endmenu - - menu "Partition Types" -diff -urN -p linux-2.6.9/fs/gfs_locking/Makefile linux/fs/gfs_locking/Makefile ---- linux-2.6.9/fs/gfs_locking/Makefile 2004-12-17 20:03:54.725107749 -0600 -+++ linux/fs/gfs_locking/Makefile 2004-12-17 20:03:58.382256062 -0600 -@@ -11,4 +11,5 @@ - ############################################################################### - - obj-$(CONFIG_LOCK_HARNESS) += lock_harness/ -+obj-$(CONFIG_LOCK_NOLOCK) += lock_nolock/ - -diff -urN -p linux-2.6.9/fs/gfs_locking/lock_nolock/Makefile linux/fs/gfs_locking/lock_nolock/Makefile ---- linux-2.6.9/fs/gfs_locking/lock_nolock/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux/fs/gfs_locking/lock_nolock/Makefile 2004-12-17 20:03:58.382256062 -0600 -@@ -0,0 +1,16 @@ -+############################################################################### -+############################################################################### -+## -+## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -+## -+## This copyrighted material is made available to anyone wishing to use, -+## modify, copy, or redistribute it subject to the terms and conditions -+## of the GNU General Public License v.2. -+## -+############################################################################### -+############################################################################### -+ -+obj-$(CONFIG_LOCK_NOLOCK) += lock_nolock.o -+ -+lock_nolock-y := main.o -+ diff --git a/gfs-kernel/patches/2.6.9/00004.patch b/gfs-kernel/patches/2.6.9/00004.patch deleted file mode 100644 index bff1c4f..0000000 --- a/gfs-kernel/patches/2.6.9/00004.patch +++ /dev/null @@ -1,46 +0,0 @@ -# Add lock_dlm to the build system. -diff -urN -p linux-2.6.9/fs/Kconfig linux/fs/Kconfig ---- linux-2.6.9/fs/Kconfig 2004-12-17 20:04:02.110388381 -0600 -+++ linux/fs/Kconfig 2004-12-17 20:04:02.120386055 -0600 -@@ -1796,6 +1796,12 @@ config LOCK_NOLOCK - help - A "fake" lock module that allows GFS to run as a local filesystem. - -+config LOCK_DLM -+ tristate "Lock DLM" -+ depends on LOCK_HARNESS -+ help -+ A lock module that allows GFS to use a Distributed Lock Manager. -+ - endmenu - - menu "Partition Types" -diff -urN -p linux-2.6.9/fs/gfs_locking/Makefile linux/fs/gfs_locking/Makefile ---- linux-2.6.9/fs/gfs_locking/Makefile 2004-12-17 20:04:02.110388381 -0600 -+++ linux/fs/gfs_locking/Makefile 2004-12-17 20:04:02.121385822 -0600 -@@ -12,4 +12,5 @@ - - obj-$(CONFIG_LOCK_HARNESS) += lock_harness/ - obj-$(CONFIG_LOCK_NOLOCK) += lock_nolock/ -+obj-$(CONFIG_LOCK_DLM) += lock_dlm/ - -diff -urN -p linux-2.6.9/fs/gfs_locking/lock_dlm/Makefile linux/fs/gfs_locking/lock_dlm/Makefile ---- linux-2.6.9/fs/gfs_locking/lock_dlm/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux/fs/gfs_locking/lock_dlm/Makefile 2004-12-17 20:04:02.121385822 -0600 -@@ -0,0 +1,16 @@ -+############################################################################### -+############################################################################### -+## -+## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -+## -+## This copyrighted material is made available to anyone wishing to use, -+## modify, copy, or redistribute it subject to the terms and conditions -+## of the GNU General Public License v.2. -+## -+############################################################################### -+############################################################################### -+ -+obj-$(CONFIG_LOCK_DLM) += lock_dlm.o -+ -+lock_dlm-y := main.o group.o lock.o mount.o thread.o plock.o -+ diff --git a/gfs-kernel/patches/2.6.9/00005.patch b/gfs-kernel/patches/2.6.9/00005.patch deleted file mode 100644 index b33ce51..0000000 --- a/gfs-kernel/patches/2.6.9/00005.patch +++ /dev/null @@ -1,61 +0,0 @@ -# Add lock_gulm to the build system. -diff -urN -p linux-2.6.9/fs/Kconfig linux/fs/Kconfig ---- linux-2.6.9/fs/Kconfig 2004-12-17 20:04:05.713550299 -0600 -+++ linux/fs/Kconfig 2004-12-17 20:04:05.724547742 -0600 -@@ -1802,6 +1802,12 @@ config LOCK_DLM - help - A lock module that allows GFS to use a Distributed Lock Manager. - -+config LOCK_GULM -+ tristate "Lock GULM" -+ depends on LOCK_HARNESS -+ help -+ A lock module that allows GFS to use a Failover Lock Manager. -+ - endmenu - - menu "Partition Types" -diff -urN -p linux-2.6.9/fs/gfs_locking/Makefile linux/fs/gfs_locking/Makefile ---- linux-2.6.9/fs/gfs_locking/Makefile 2004-12-17 20:04:05.714550067 -0600 -+++ linux/fs/gfs_locking/Makefile 2004-12-17 20:04:05.724547742 -0600 -@@ -13,4 +13,5 @@ - obj-$(CONFIG_LOCK_HARNESS) += lock_harness/ - obj-$(CONFIG_LOCK_NOLOCK) += lock_nolock/ - obj-$(CONFIG_LOCK_DLM) += lock_dlm/ -+obj-$(CONFIG_LOCK_GULM) += lock_gulm/ - -diff -urN -p linux-2.6.9/fs/gfs_locking/lock_gulm/Makefile linux/fs/gfs_locking/lock_gulm/Makefile ---- linux-2.6.9/fs/gfs_locking/lock_gulm/Makefile 1969-12-31 18:00:00.000000000 -0600 -+++ linux/fs/gfs_locking/lock_gulm/Makefile 2004-12-17 20:04:05.724547742 -0600 -@@ -0,0 +1,31 @@ -+############################################################################### -+############################################################################### -+## -+## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -+## -+## This copyrighted material is made available to anyone wishing to use, -+## modify, copy, or redistribute it subject to the terms and conditions -+## of the GNU General Public License v.2. -+## -+############################################################################### -+############################################################################### -+ -+obj-$(CONFIG_LOCK_GULM) += lock_gulm.o -+ -+lock_gulm-y := gulm_core.o \ -+ gulm_firstlock.o \ -+ gulm_fs.o \ -+ gulm_jid.o \ -+ gulm_lock_queue.o \ -+ gulm_lt.o \ -+ gulm_main.o \ -+ gulm_plock.o \ -+ handler.o \ -+ lg_core.o \ -+ lg_lock.o \ -+ lg_main.o \ -+ utils_tostr.o \ -+ xdr_base.o \ -+ xdr_io.o \ -+ xdr_socket.o -+ diff --git a/gfs-kernel/scripts/uninstall.pl b/gfs-kernel/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/gfs-kernel/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/gfs-kernel/src/Makefile b/gfs-kernel/src/Makefile deleted file mode 100644 index 49f7f46..0000000 --- a/gfs-kernel/src/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd harness && ${MAKE} all - cd nolock && ${MAKE} all - cd dlm && ${MAKE} all - cd gulm && ${MAKE} all - cd gfs && ${MAKE} all - -install: - cd harness && ${MAKE} install - cd nolock && ${MAKE} install - cd dlm && ${MAKE} install - cd gulm && ${MAKE} install - cd gfs && ${MAKE} install - -uninstall: - cd harness && ${MAKE} uninstall - cd nolock && ${MAKE} uninstall - cd dlm && ${MAKE} uninstall - cd gulm && ${MAKE} uninstall - cd gfs && ${MAKE} uninstall - -clean: - rm -rf *.patch linux-patched - cd harness && ${MAKE} clean - cd nolock && ${MAKE} clean - cd dlm && ${MAKE} clean - cd gulm && ${MAKE} clean - cd gfs && ${MAKE} clean - -patches: - cd gfs && ${MAKE} patches - cd harness && ${MAKE} patches - cd nolock && ${MAKE} patches - cd dlm && ${MAKE} patches - cd gulm && ${MAKE} patches - - diff --git a/gfs-kernel/src/dlm/Makefile b/gfs-kernel/src/dlm/Makefile deleted file mode 100644 index 1c24769..0000000 --- a/gfs-kernel/src/dlm/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = ../.. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/src/linux-orig -linux_patched = ${top_srcdir}/src/linux-patched - -PWD := $(shell pwd) - -TARGET = lock_dlm.patch -SYMVERFILE := ${PWD}/../harness/lock_harness.symvers - - -obj-m := lock_dlm.o -lock_dlm-objs := group.o \ - lock.o \ - main.o \ - mount.o \ - plock.o \ - thread.o - -EXTRA_CFLAGS += -I$(obj) - -all: - if [ ! -e linux ]; then ln -s . linux; fi - if [ ! -e cluster ]; then ln -s . cluster; fi - if [ ! -e lm_interface.h ]; then ln -s ${top_srcdir}/src/harness/lm_interface.h .; fi - if [ ! -e dlm.h ]; then cp ${incdir}/cluster/dlm.h .; fi - if [ ! -e cnxman.h ]; then cp ${incdir}/cluster/cnxman.h .; fi - if [ ! -e cnxman-socket.h ]; then cp ${incdir}/cluster/cnxman-socket.h .; fi - if [ ! -e service.h ]; then cp ${incdir}/cluster/service.h .; fi - ${MAKE} -C ${KERNEL_SRC} M=${PWD} symverfile=${SYMVERFILE} modules USING_KBUILD=yes - ${KERNEL_SRC}/scripts/mod/modpost -m -i ${SYMVERFILE} ../dlm/lock_dlm.o -o lock_dlm.symvers - -install: all - install -d ${module_dir}/fs/gfs_locking/lock_dlm - install lock_dlm.ko ${module_dir}/fs/gfs_locking/lock_dlm - -uninstall: - ${UNINSTALL} lock_dlm.ko ${module_dir}/fs/gfs_locking/lock_dlm - -clean: - rm -rf linux cluster lm_interface.h dlm.h cnxman.h \ - cnxman-socket.h service.h .tmp_versions *.o \ - .*.o.cmd lock_dlm.ko .*.ko.cmd lock_dlm.mod.c *~ - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir}/src ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/fs/gfs_locking/lock_dlm - cp *.[ch] ${linux_patched}/fs/gfs_locking/lock_dlm diff --git a/gfs-kernel/src/dlm/group.c b/gfs-kernel/src/dlm/group.c deleted file mode 100644 index bac7ff3..0000000 --- a/gfs-kernel/src/dlm/group.c +++ /dev/null @@ -1,882 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "lock_dlm.h" - - -struct kcl_service_ops mg_ops; - -/* - * Get the node struct for a given nodeid. - */ - -static dlm_node_t *find_node_by_nodeid(dlm_t *dlm, uint32_t nodeid) -{ - dlm_node_t *node; - - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (node->nodeid == nodeid) - return node; - } - return NULL; -} - -/* - * Get the node struct for a given journalid. - */ - -static dlm_node_t *find_node_by_jid(dlm_t *dlm, uint32_t jid) -{ - dlm_node_t *node; - - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (node->jid == jid) - return node; - } - return NULL; -} - -/* - * If the given ID is clear, get it, setting to the given VALUE. The ID is a - * journalid, the VALUE is our nodeid. When successful, the held ID-lock is - * returned (in shared mode). As long as this ID-lock is held, the journalid - * is owned. - */ - -static int id_test_and_set(dlm_t *dlm, uint32_t id, uint32_t val, - dlm_lock_t **lp_set) -{ - dlm_lock_t *lp = NULL; - struct lm_lockname name; - lm_lock_t *lock; - char *lvb; - uint32_t exist_val, beval; - int error; - - name.ln_type = LM_TYPE_JID; - name.ln_number = id; - - error = lm_dlm_get_lock(dlm, &name, &lock); - if (error) - goto fail; - - lp = (dlm_lock_t *) lock; - - error = dlm_add_lvb(lp); - if (error) - goto fail_put; - - lvb = lp->lvb; - set_bit(LFL_INLOCK, &lp->flags); - set_bit(LFL_NOBAST, &lp->flags); - - retry: - - error = lm_dlm_lock_sync(lock, LM_ST_UNLOCKED, LM_ST_SHARED, - LM_FLAG_TRY | LM_FLAG_NOEXP); - if (error == -EAGAIN) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - goto retry; - } - if (error) - goto fail_lvb; - - memcpy(&beval, lvb, sizeof(beval)); - exist_val = be32_to_cpu(beval); - - if (!exist_val) { - /* - * This id is unused. Attempt to claim it by getting EX mode - * and writing our nodeid into the lvb. - */ - error = lm_dlm_lock_sync(lock, LM_ST_SHARED, LM_ST_EXCLUSIVE, - LM_FLAG_TRY | LM_FLAG_NOEXP); - if (error == -EAGAIN) { - lm_dlm_unlock_sync(lock, LM_ST_SHARED); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - goto retry; - } - if (error) - goto fail_unlock; - - beval = cpu_to_be32(val); - memcpy(lvb, &beval, sizeof(beval)); - - error = lm_dlm_lock_sync(lock, LM_ST_EXCLUSIVE, LM_ST_SHARED, - LM_FLAG_NOEXP); - DLM_ASSERT(!error,); - - *lp_set = lp; - error = 0; - } else { - /* - * This id is already used. It has a non-zero nodeid in the lvb - */ - lm_dlm_unlock_sync(lock, LM_ST_SHARED); - dlm_del_lvb(lp); - lm_dlm_put_lock(lock); - error = exist_val; - } - - return error; - - fail_unlock: - lm_dlm_unlock_sync(lock, LM_ST_SHARED); - - fail_lvb: - dlm_del_lvb(lp); - - fail_put: - lm_dlm_put_lock(lock); - - fail: - return error; -} - -/* - * Release a held ID-lock clearing its VALUE. We have to acquire the lock in - * EX again so we can write out a zeroed lvb. - */ - -static void id_clear(dlm_t *dlm, dlm_lock_t *lp) -{ - lm_lock_t *lock = (lm_lock_t *) lp; - int error; - - /* - * This flag means that DLM_LKF_CONVDEADLK should not be used. - */ - set_bit(LFL_FORCE_PROMOTE, &lp->flags); - - retry: - - error = lm_dlm_lock_sync(lock, LM_ST_SHARED, LM_ST_EXCLUSIVE, - LM_FLAG_TRY | LM_FLAG_NOEXP); - if (error == -EAGAIN) { - schedule(); - goto retry; - } - if (error) - goto end; - - memset(lp->lvb, 0, DLM_LVB_LEN); - lm_dlm_unlock_sync(lock, LM_ST_EXCLUSIVE); - - end: - dlm_del_lvb(lp); - lm_dlm_put_lock(lock); -} - -/* - * Get the VALUE for a given ID. The ID is a journalid, the VALUE is a nodeid. - */ - -static int id_value(dlm_t *dlm, uint32_t id, uint32_t *val) -{ - dlm_lock_t *lp = NULL; - struct lm_lockname name; - lm_lock_t *lock; - char *lvb; - uint32_t beval; - int error; - - name.ln_type = LM_TYPE_JID; - name.ln_number = id; - - error = lm_dlm_get_lock(dlm, &name, &lock); - if (error) - goto out; - - lp = (dlm_lock_t *) lock; - - error = dlm_add_lvb(lp); - if (error) - goto out_put; - - lvb = lp->lvb; - set_bit(LFL_INLOCK, &lp->flags); - set_bit(LFL_NOBAST, &lp->flags); - - retry: - - error = lm_dlm_lock_sync(lock, LM_ST_UNLOCKED, LM_ST_SHARED, - LM_FLAG_TRY | LM_FLAG_NOEXP); - if (error == -EAGAIN) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - goto retry; - } - if (error) - goto out_lvb; - - memcpy(&beval, lvb, sizeof(beval)); - *val = be32_to_cpu(beval); - - lm_dlm_unlock_sync(lock, LM_ST_SHARED); - - error = 0; - - out_lvb: - dlm_del_lvb(lp); - - out_put: - lm_dlm_put_lock(lock); - - out: - return error; -} - -/* - * Find an ID with a given VALUE. The ID is a journalid, the VALUE is a - * nodeid. - */ - -static int id_find(dlm_t *dlm, uint32_t value, uint32_t *id_out) -{ - uint32_t val, id; - int error = 0, found = FALSE; - - for (id = 0; id < dlm->max_nodes; id++) { - error = id_value(dlm, id, &val); - if (error) - break; - - if (val == value) { - *id_out = id; - error = 0; - found = TRUE; - break; - } - } - - if (!error && !found) - error = -ENOENT; - - return error; -} - -/* - * Get a journalid to use. The journalid must be owned exclusively as long as - * this fs is mounted. Other nodes must be able to discover our nodeid as the - * owner of the journalid. The journalid we claim should have the lowest value - * of all unused journalids. - */ - -static int claim_jid(dlm_t *dlm) -{ - dlm_node_t *node; - uint32_t id; - int error = 0; - - DLM_ASSERT(dlm->our_nodeid,); - - /* - * Search an arbitrary number (8) past max nodes so we're sure to find - * one so we can let the GFS handle the "too big jid" error and fail - * the mount. - */ - - for (id = 0; id < dlm->max_nodes + 8; id++) { - error = id_test_and_set(dlm, id, dlm->our_nodeid, &dlm->jid_lp); - if (error < 0) - break; - if (error > 0) - continue; - - dlm->jid = id; - node = find_node_by_nodeid(dlm, dlm->our_nodeid); - node->jid = id; - set_bit(NFL_HAVE_JID, &node->flags); - break; - } - - /* - * If we have a problem getting a jid, pick a bogus one which should - * cause GFS to complain and fail to mount. - */ - - if (error) { - printk("lock_dlm: %s: no journal id available (%d)\n", - dlm->fsname, error); - dlm->jid = dlm->max_nodes + dlm->our_nodeid; - } - - log_debug("claim_jid %u", dlm->jid); - return 0; -} - -/* - * Release our journalid, allowing it to be used by a node subsequently - * mounting the fs. When withdrawing, we've already left the lockspace. - */ - -static void release_jid(dlm_t *dlm) -{ - if (test_bit(DFL_WITHDRAW, &dlm->flags)) { - dlm_del_lvb(dlm->jid_lp); - delete_lp(dlm->jid_lp); - } else - id_clear(dlm, dlm->jid_lp); - dlm->jid_lp = NULL; -} - -/* - * For all nodes in the mountgroup, find the journalid being used by each. - */ - -static int discover_jids(dlm_t *dlm) -{ - dlm_node_t *node; - uint32_t id; - int error, notfound = 0; - - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (test_bit(NFL_HAVE_JID, &node->flags)) - continue; - - error = id_find(dlm, node->nodeid, &id); - if (error) { - log_debug("jid for node %d not found", node->nodeid); - notfound++; - continue; - } - - node->jid = id; - set_bit(NFL_HAVE_JID, &node->flags); - } - - return notfound; -} - -/* - * Discover the nodeid that we've been assigned by the cluster manager. - */ - -static int get_our_nodeid(dlm_t *dlm) -{ - LIST_HEAD(cur_memb); - struct kcl_cluster_node *cur_node; - - kcl_get_members(&cur_memb); - - list_for_each_entry(cur_node, &cur_memb, list) { - if (cur_node->us) { - dlm->our_nodeid = cur_node->node_id; - break; - } - } - - while (!list_empty(&cur_memb)) { - cur_node = list_entry(cur_memb.next, struct kcl_cluster_node, - list); - list_del(&cur_node->list); - kfree(cur_node); - } - - return 0; -} - -static void release_mg_nodes(dlm_t *dlm) -{ - dlm_node_t *node, *safe; - - list_for_each_entry_safe(node, safe, &dlm->mg_nodes, list) { - list_del(&node->list); - lm_dlm_release_withdraw(dlm, node); - kfree(node); - } -} - -/* - * Run in dlm_async thread - */ - -void process_start(dlm_t *dlm, dlm_start_t *ds) -{ - dlm_node_t *node; - uint32_t nodeid; - int last_stop, last_start, last_finish; - int error, i, new = FALSE, found; - - down(&dlm->unmount_lock); - - /* - * when the initial sequence of callbacks is start/stop/start the - * second start has the same event id (the first doesn't count) - */ - - spin_lock(&dlm->async_lock); - last_stop = dlm->mg_last_stop; - last_start = dlm->mg_last_start; - last_finish = dlm->mg_last_finish; - - if (!last_finish && last_stop) { - log_debug("pr_start reset stop %d start %d finish %d", - last_stop, last_start, last_finish); - dlm->mg_last_stop = 0; - last_stop = 0; - } - spin_unlock(&dlm->async_lock); - - log_debug("pr_start last_stop %d last_start %d last_finish %d", - last_stop, last_start, last_finish); - log_debug("pr_start count %d type %d event %d flags %lx", - ds->count, ds->type, ds->event_id, dlm->flags); - - /* - * gfs won't do journal recoveries once it's sent us an unmount or - * withdraw - */ - - if (test_bit(DFL_UMOUNT, &dlm->flags) || - test_bit(DFL_WITHDRAW, &dlm->flags)) { - log_debug("pr_start %d skip for umount/wd", ds->event_id); - kcl_start_done(dlm->mg_local_id, ds->event_id); - goto out; - } - - /* - * a couple special things to take care of on the first start (mount) - */ - - if (!test_and_set_bit(DFL_GOT_NODEID, &dlm->flags)) - get_our_nodeid(dlm); - - if (test_bit(DFL_MOUNT, &dlm->flags) && (ds->count == 1)) - set_bit(DFL_FIRST_MOUNT, &dlm->flags); - - down(&dlm->mg_nodes_lock); - - /* - * while mounting, cancelled starts are discarded - * (normally, (uninterrupted starts) mg_nodes is empty at this point) - */ - - if (test_bit(DFL_MOUNT, &dlm->flags)) - release_mg_nodes(dlm); - - /* - * find nodes which are gone - */ - - list_for_each_entry(node, &dlm->mg_nodes, list) { - found = FALSE; - for (i = 0; i < ds->count; i++) { - if (node->nodeid != ds->nodeids[i]) - continue; - found = TRUE; - break; - } - - /* node is still a member */ - if (found) - continue; - - set_bit(NFL_NOT_MEMBER, &node->flags); - - /* failed and withdrawing nodes need journal recovery */ - if (ds->type != SERVICE_NODE_FAILED && - !test_bit(NFL_WITHDRAW, &node->flags)) - continue; - - /* callbacks sent only for nodes in last completed MG */ - if (!test_bit(NFL_LAST_FINISH, &node->flags)) - continue; - - /* only send a single callback per node */ - if (test_and_set_bit(NFL_SENT_CB, &node->flags)) - continue; - - dlm->fscb(dlm->fsdata, LM_CB_NEED_RECOVERY, &node->jid); - set_bit(DFL_NEED_STARTDONE, &dlm->flags); - log_debug("pr_start cb jid %u id %u", node->jid, node->nodeid); - } - - /* - * add new nodes - */ - - for (i = 0; i < ds->count; i++) { - nodeid = ds->nodeids[i]; - - node = find_node_by_nodeid(dlm, nodeid); - if (node) - continue; - - DLM_RETRY(node = kmalloc(sizeof(dlm_node_t), GFP_KERNEL), node); - memset(node, 0, sizeof(dlm_node_t)); - - node->nodeid = nodeid; - list_add(&node->list, &dlm->mg_nodes); - new = TRUE; - } - - up(&dlm->mg_nodes_lock); - - /* - * get a jid for ourself when started for first time - */ - - if (!test_and_set_bit(DFL_HAVE_JID, &dlm->flags)) - claim_jid(dlm); - else if (new) { - /* give new nodes a little time to claim a jid */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ); - } - - /* - * find jid's of new nodes - */ - - for (;;) { - /* we don't need to do these jid lookups if this start has been - followed by a stop event (and thus cancelled) */ - - spin_lock(&dlm->async_lock); - last_stop = dlm->mg_last_stop; - last_start = dlm->mg_last_start; - spin_unlock(&dlm->async_lock); - - if (last_stop >= ds->event_id) { - log_debug("pr_start %d abort discover", ds->event_id); - break; - } - - error = discover_jids(dlm); - if (error) { - /* Not all jids were found. Wait for a time to let all - new nodes claim_jid, then try to scan for jids - again. */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ); - continue; - } - break; - } - - /* - * Hold withdraw locks for all nodes in PR. We're notified by a bast - * if one of them withdraws. We promote ours to EX to withdraw - * ourself. - */ - - lm_dlm_hold_withdraw(dlm); - - /* - * tell SM we're done if there are no GFS recoveries to wait for - */ - - if (last_start > last_stop) { - error = 0; - down(&dlm->mg_nodes_lock); - - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (!test_bit(NFL_SENT_CB, &node->flags)) - continue; - error = 1; - break; - } - up(&dlm->mg_nodes_lock); - - /* We were the first mounter and haven't gotten omm yet - so we can't let this second node complete its mount. - We set WAIT_OMM so that the eventual call to omm will - do the kcl_start_done(). */ - - if (test_bit(DFL_FIRST_MOUNT, &dlm->flags) && - !test_bit(DFL_OTHERSMAYMOUNT, &dlm->flags) && - !test_bit(DFL_MOUNT, &dlm->flags)) { - log_debug("pr_start delay done before omm %lx", - dlm->flags); - set_bit(DFL_WAIT_OTHERSMAYMOUNT, &dlm->flags); - error = 1; - } - - log_debug("pr_start %d done %d", ds->event_id, !error); - - if (!error) - kcl_start_done(dlm->mg_local_id, ds->event_id); - } else - log_debug("pr_start %d stopped %d", ds->event_id, last_stop); - - out: - clear_bit(DFL_RECOVER, &dlm->flags); - kfree(ds->nodeids); - kfree(ds); - up(&dlm->unmount_lock); -} - -void process_finish(dlm_t *dlm) -{ - struct list_head *tmp, *tmpsafe; - dlm_node_t *node; - dlm_lock_t *lp; - int leave_blocked = FALSE; - - log_debug("pr_finish flags %lx", dlm->flags); - - down(&dlm->mg_nodes_lock); - list_for_each_safe(tmp, tmpsafe, &dlm->mg_nodes) { - node = list_entry(tmp, dlm_node_t, list); - - if (test_bit(NFL_NOT_MEMBER, &node->flags)) { - list_del(&node->list); - lm_dlm_release_withdraw(dlm, node); - kfree(node); - } else { - set_bit(NFL_LAST_FINISH, &node->flags); - - /* If there are still withdrawing nodes that haven't - left the MG (had their journals recovered), we need - to keep lock requests blocked */ - - if (test_bit(NFL_WITHDRAW, &node->flags)) { - log_debug("pr_finish leave blocked for %d", - node->nodeid); - leave_blocked = TRUE; - } - } - } - up(&dlm->mg_nodes_lock); - - if (leave_blocked) - goto out; - - spin_lock(&dlm->async_lock); - clear_bit(DFL_BLOCK_LOCKS, &dlm->flags); - - list_for_each_safe(tmp, tmpsafe, &dlm->delayed) { - lp = list_entry(tmp, dlm_lock_t, dlist); - - if (lp->type != QUEUE_LOCKS_BLOCKED) - continue; - - lp->type = 0; - list_del(&lp->dlist); - list_add_tail(&lp->slist, &dlm->submit); - - clear_bit(LFL_DLIST, &lp->flags); - set_bit(LFL_SLIST, &lp->flags); - } - spin_unlock(&dlm->async_lock); - - out: - clear_bit(DFL_MOUNT, &dlm->flags); - wake_up(&dlm->wait); -} - -/* - * Run in user process - */ - -int init_mountgroup(dlm_t *dlm) -{ - int error; - int id; - - error = kcl_register_service(dlm->fsname, dlm->fnlen, SERVICE_LEVEL_GFS, - &mg_ops, TRUE, (void *) dlm, &id); - if (error) - goto out; - - dlm->mg_local_id = id; - - /* MOUNT and BLOCK_LOCKS are cleared when the join is finished */ - set_bit(DFL_BLOCK_LOCKS, &dlm->flags); - set_bit(DFL_MOUNT, &dlm->flags); - - error = kcl_join_service(id); - if (error) - goto out_unreg; - - if (test_bit(DFL_START_ERROR, &dlm->flags)) - goto out_leave; - - return 0; - - out_leave: - kcl_leave_service(dlm->mg_local_id); - - out_unreg: - kcl_unregister_service(id); - - out: - printk("lock_dlm: service error %d\n", error); - return error; -} - -void release_mountgroup(dlm_t *dlm) -{ - int last_start, last_stop; - - down(&dlm->unmount_lock); - - /* this flag causes a kcl_start_done() to be sent right away for - any start callbacks we get from SM */ - - log_debug("release_mountgroup flags %lx", dlm->flags); - set_bit(DFL_UMOUNT, &dlm->flags); - - /* gfs has done a unmount and will not call jid_recovery_done() - any longer so make necessary kcl_start_done() calls so - kcl_leave_service() will complete */ - - spin_lock(&dlm->async_lock); - last_start = dlm->mg_last_start; - last_stop = dlm->mg_last_stop; - spin_unlock(&dlm->async_lock); - - if ((last_start > last_stop) && - test_and_clear_bit(DFL_NEED_STARTDONE, &dlm->flags)) { - log_debug("umount doing start_done %d", last_start); - kcl_start_done(dlm->mg_local_id, last_start); - } - - up(&dlm->unmount_lock); - - kcl_leave_service(dlm->mg_local_id); - kcl_unregister_service(dlm->mg_local_id); - - release_jid(dlm); - down(&dlm->mg_nodes_lock); - release_mg_nodes(dlm); - up(&dlm->mg_nodes_lock); -} - -/* - * Run in GFS thread - */ - -void jid_recovery_done(dlm_t *dlm, unsigned int jid, unsigned int message) -{ - dlm_node_t *node; - int last_start, last_stop; - int remain = 0; - - log_debug("recovery_done jid %u msg %u %lx", jid, message, dlm->flags); - - node = find_node_by_jid(dlm, jid); - if (!node) - goto out; - - log_debug("recovery_done nodeid %u flg %lx", node->nodeid, node->flags); - - if (!test_bit(NFL_SENT_CB, &node->flags)) - goto out; - - if (!test_bit(NFL_NOT_MEMBER, &node->flags)) - goto out; - - set_bit(NFL_RECOVERY_DONE, &node->flags); - - /* - * when recovery is done for all nodes, we're done with the start - */ - - down(&dlm->mg_nodes_lock); - - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (test_bit(NFL_SENT_CB, &node->flags) && - !test_bit(NFL_RECOVERY_DONE, &node->flags)) - remain++; - } - up(&dlm->mg_nodes_lock); - - if (!remain) { - /* don't send a start_done if there's since been a stop which - * cancels this start */ - - spin_lock(&dlm->async_lock); - last_start = dlm->mg_last_start; - last_stop = dlm->mg_last_stop; - spin_unlock(&dlm->async_lock); - - if (last_start > last_stop) { - log_debug("recovery_done start_done %d", last_start); - kcl_start_done(dlm->mg_local_id, last_start); - clear_bit(DFL_NEED_STARTDONE, &dlm->flags); - } - } - - out: - return; -} - -/* - * Run in CMAN SM thread - */ - -static void queue_start(dlm_t *dlm, uint32_t *nodeids, int count, - int event_id, int type) -{ - dlm_start_t *ds; - - DLM_RETRY(ds = kmalloc(sizeof(dlm_start_t), GFP_KERNEL), ds); - - memset(ds, 0, sizeof(dlm_start_t)); - - ds->nodeids = nodeids; - ds->count = count; - ds->event_id = event_id; - ds->type = type; - - spin_lock(&dlm->async_lock); - dlm->mg_last_start = event_id; - list_add_tail(&ds->list, &dlm->starts); - spin_unlock(&dlm->async_lock); - - wake_up(&dlm->wait); -} - -static int mg_stop(void *data) -{ - dlm_t *dlm = (dlm_t *) data; - - spin_lock(&dlm->async_lock); - set_bit(DFL_BLOCK_LOCKS, &dlm->flags); - dlm->mg_last_stop = dlm->mg_last_start; - spin_unlock(&dlm->async_lock); - - return 0; -} - -static int mg_start(void *data, uint32_t *nodeids, int count, int event_id, - int type) -{ - dlm_t *dlm = (dlm_t *) data; - - queue_start(dlm, nodeids, count, event_id, type); - - return 0; -} - -static void mg_finish(void *data, int event_id) -{ - dlm_t *dlm = (dlm_t *) data; - - spin_lock(&dlm->async_lock); - dlm->mg_last_finish = event_id; - set_bit(DFL_MG_FINISH, &dlm->flags); - spin_unlock(&dlm->async_lock); - - wake_up(&dlm->wait); -} - -struct kcl_service_ops mg_ops = { - .stop = mg_stop, - .start = mg_start, - .finish = mg_finish -}; diff --git a/gfs-kernel/src/dlm/lock.c b/gfs-kernel/src/dlm/lock.c deleted file mode 100644 index 2528314..0000000 --- a/gfs-kernel/src/dlm/lock.c +++ /dev/null @@ -1,766 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "lock_dlm.h" - -static char junk_lvb[DLM_LVB_SIZE]; - - -/* - * Run in DLM thread - */ - -static void queue_complete(dlm_lock_t *lp) -{ - dlm_t *dlm = lp->dlm; - - if (!test_bit(LFL_WAIT_COMPLETE, &lp->flags)) { - log_all("extra completion %x,%"PRIx64" %d,%d id %x flags %lx", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->cur, lp->req, lp->lksb.sb_lkid, lp->flags); - return; - } - - clear_bit(LFL_WAIT_COMPLETE, &lp->flags); - - /* - log_debug("qc %x,%"PRIx64" %d,%d id %x sts %d %x", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->cur, lp->req, lp->lksb.sb_lkid, lp->lksb.sb_status, - lp->lksb.sb_flags); - */ - - spin_lock(&dlm->async_lock); - list_add_tail(&lp->clist, &dlm->complete); - set_bit(LFL_CLIST, &lp->flags); - spin_unlock(&dlm->async_lock); - wake_up(&dlm->wait); -} - -static void queue_blocking(dlm_lock_t *lp, int mode) -{ - dlm_t *dlm = lp->dlm; - - /* We often get basts for EX while we're promoting from SH to EX */ - /* - if (test_bit(LFL_WAIT_COMPLETE, &lp->flags)) { - log_debug("bast during wait %x,%"PRIx64" %d-%d %x bmode %d", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->cur, lp->req, lp->lkf, mode); - } - */ - - if (!mode) { - printk("lock_dlm: bast mode zero %x,%"PRIx64"\n", - lp->lockname.ln_type, lp->lockname.ln_number); - return; - } - - spin_lock(&dlm->async_lock); - - if (!lp->bast_mode) { - list_add_tail(&lp->blist, &dlm->blocking); - set_bit(LFL_BLIST, &lp->flags); - lp->bast_mode = mode; - } else if (lp->bast_mode < mode) - lp->bast_mode = mode; - - spin_unlock(&dlm->async_lock); - wake_up(&dlm->wait); -} - -static __inline__ void lock_ast(void *astarg) -{ - queue_complete((dlm_lock_t *) astarg); -} - -static __inline__ void lock_bast(void *astarg, int mode) -{ - queue_blocking((dlm_lock_t *) astarg, mode); -} - -/* - * Run in GFS or user thread - */ - -/** - * queue_delayed - add request to queue to be submitted later - * @lp: DLM lock - * @type: the reason the lock is blocked - * - * Queue of locks which need submitting sometime later. Locks here - * due to BLOCKED_LOCKS are moved to request queue when recovery is - * done. Locks here due to an ERROR are moved to request queue after - * some delay. This could also be called from dlm_async thread. - */ - -void queue_delayed(dlm_lock_t *lp, int type) -{ - dlm_t *dlm = lp->dlm; - - lp->type = type; - - spin_lock(&dlm->async_lock); - list_add_tail(&lp->dlist, &dlm->delayed); - set_bit(LFL_DLIST, &lp->flags); - spin_unlock(&dlm->async_lock); -} - -/** - * make_mode - convert to DLM_LOCK_ - * @lmstate: GFS lock state - * - * Returns: DLM lock mode - */ - -static int16_t make_mode(int16_t lmstate) -{ - switch (lmstate) { - case LM_ST_UNLOCKED: - return DLM_LOCK_NL; - case LM_ST_EXCLUSIVE: - return DLM_LOCK_EX; - case LM_ST_DEFERRED: - return DLM_LOCK_CW; - case LM_ST_SHARED: - return DLM_LOCK_PR; - default: - DLM_ASSERT(0, printk("unknown LM state %d\n", lmstate);); - } -} - -/** - * make_lmstate - convert to LM_ST_ - * @dlmmode: DLM lock mode - * - * Returns: GFS lock state - */ - -int16_t make_lmstate(int16_t dlmmode) -{ - switch (dlmmode) { - case DLM_LOCK_IV: - case DLM_LOCK_NL: - return LM_ST_UNLOCKED; - case DLM_LOCK_EX: - return LM_ST_EXCLUSIVE; - case DLM_LOCK_CW: - return LM_ST_DEFERRED; - case DLM_LOCK_PR: - return LM_ST_SHARED; - default: - DLM_ASSERT(0, printk("unknown DLM mode %d\n", dlmmode);); - } -} - -/** - * check_cur_state - verify agreement with GFS on the current lock state - * @lp: the DLM lock - * @cur_state: the current lock state from GFS - * - * NB: DLM_LOCK_NL and DLM_LOCK_IV are both considered - * LM_ST_UNLOCKED by GFS. - * - */ - -static void check_cur_state(dlm_lock_t *lp, unsigned int cur_state) -{ - int16_t cur = make_mode(cur_state); - if (lp->cur != DLM_LOCK_IV) - DLM_ASSERT(lp->cur == cur, printk("%d, %d\n", lp->cur, cur);); -} - -/** - * make_flags - put together necessary DLM flags - * @lp: DLM lock - * @gfs_flags: GFS flags - * @cur: current DLM lock mode - * @req: requested DLM lock mode - * - * Returns: DLM flags - */ - -static unsigned int make_flags(dlm_lock_t *lp, unsigned int gfs_flags, - int16_t cur, int16_t req) -{ - unsigned int lkf = 0; - - if (gfs_flags & LM_FLAG_TRY) - lkf |= DLM_LKF_NOQUEUE; - - if (gfs_flags & LM_FLAG_TRY_1CB) { - lkf |= DLM_LKF_NOQUEUE; - lkf |= DLM_LKF_NOQUEUEBAST; - } - - if (gfs_flags & LM_FLAG_PRIORITY) { - lkf |= DLM_LKF_NOORDER; - lkf |= DLM_LKF_HEADQUE; - } - - if (gfs_flags & LM_FLAG_ANY) { - if (req == DLM_LOCK_PR) - lkf |= DLM_LKF_ALTCW; - else if (req == DLM_LOCK_CW) - lkf |= DLM_LKF_ALTPR; - } - - if (lp->lksb.sb_lkid != 0) { - lkf |= DLM_LKF_CONVERT; - - /* Conversion deadlock avoidance by DLM */ - - if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) && - !(lkf & DLM_LKF_NOQUEUE) && - cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req) - lkf |= DLM_LKF_CONVDEADLK; - } - - if (lp->lvb) - lkf |= DLM_LKF_VALBLK; - - return lkf; -} - -/** - * make_strname - convert GFS lock numbers to string - * @lockname: the lock type/number - * @str: the lock string/length - * - */ - -static __inline__ void make_strname(struct lm_lockname *lockname, - strname_t *str) -{ - sprintf(str->name, "%8x%16"PRIx64, lockname->ln_type, - lockname->ln_number); - str->namelen = LOCK_DLM_STRNAME_BYTES; -} - -int create_lp(dlm_t *dlm, struct lm_lockname *name, dlm_lock_t **lpp) -{ - dlm_lock_t *lp; - - lp = kmalloc(sizeof(dlm_lock_t), GFP_KERNEL); - if (!lp) - return -ENOMEM; - - memset(lp, 0, sizeof(dlm_lock_t)); - lp->lockname = *name; - lp->dlm = dlm; - lp->cur = DLM_LOCK_IV; - lp->lvb = NULL; - lp->hold_null = NULL; - init_completion(&lp->uast_wait); - - *lpp = lp; - return 0; -} - -void delete_lp(dlm_lock_t *lp) -{ - dlm_t *dlm = lp->dlm; - - spin_lock(&dlm->async_lock); - if (test_bit(LFL_CLIST, &lp->flags)) { - printk("lock_dlm: dlm_put_lock lp on clist num=%x,%"PRIx64"\n", - lp->lockname.ln_type, lp->lockname.ln_number); - list_del(&lp->clist); - } - if (test_bit(LFL_BLIST, &lp->flags)) { - /* - printk("lock_dlm: dlm_put_lock lp on blist num=%x,%"PRIx64"\n", - lp->lockname.ln_type, lp->lockname.ln_number); - */ - list_del(&lp->blist); - } - if (test_bit(LFL_DLIST, &lp->flags)) { - printk("lock_dlm: dlm_put_lock lp on dlist num=%x,%"PRIx64"\n", - lp->lockname.ln_type, lp->lockname.ln_number); - list_del(&lp->dlist); - } - if (test_bit(LFL_SLIST, &lp->flags)) { - printk("lock_dlm: dlm_put_lock lp on slist num=%x,%"PRIx64"\n", - lp->lockname.ln_type, lp->lockname.ln_number); - list_del(&lp->slist); - } - spin_unlock(&dlm->async_lock); - - kfree(lp); -} - -/** - * dlm_get_lock - get a lm_lock_t given a descripton of the lock - * @lockspace: the lockspace the lock lives in - * @name: the name of the lock - * @lockp: return the lm_lock_t here - * - * Returns: 0 on success, -EXXX on failure - */ - -int lm_dlm_get_lock(lm_lockspace_t *lockspace, struct lm_lockname *name, - lm_lock_t **lockp) -{ - dlm_lock_t *lp; - int error; - - error = create_lp((dlm_t *) lockspace, name, &lp); - - *lockp = (lm_lock_t *) lp; - return error; -} - -/** - * dlm_put_lock - get rid of a lock structure - * @lock: the lock to throw away - * - */ - -void lm_dlm_put_lock(lm_lock_t *lock) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - DLM_ASSERT(!lp->lvb,); - delete_lp(lp); -} - -void do_dlm_unlock(dlm_lock_t *lp) -{ - unsigned int lkf = 0; - int error, plock = 0; - - if (lp->lockname.ln_type == LM_TYPE_PLOCK) - plock = 1; - - set_bit(LFL_DLM_UNLOCK, &lp->flags); - set_bit(LFL_WAIT_COMPLETE, &lp->flags); - - if (lp->lvb) - lkf = DLM_LKF_VALBLK; - - /* - log_debug("un %x,%"PRIx64" %x %d %x", lp->lockname.ln_type, - lp->lockname.ln_number, lp->lksb.sb_lkid, lp->cur, lkf); - */ - - error = dlm_unlock(lp->dlm->gdlm_lsp, lp->lksb.sb_lkid, lkf, NULL, lp); - - if (plock) { - if (error == -EINPROGRESS || error == -EBUSY) { - log_all("do_dlm_unlock %x,%"PRIx64" flags %lx error %d", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->flags, error); - return; - } - } - - DLM_ASSERT(!error, - printk("%s: error=%d num=%x,%"PRIx64" lkf=%x flags=%lx\n", - lp->dlm->fsname, error, lp->lockname.ln_type, - lp->lockname.ln_number, lp->lkf, lp->flags);); -} - -void do_dlm_unlock_sync(dlm_lock_t *lp) -{ - set_bit(LFL_UNLOCK_SYNC, &lp->flags); - init_completion(&lp->uast_wait); - do_dlm_unlock(lp); - wait_for_completion(&lp->uast_wait); -} - -void do_dlm_lock(dlm_lock_t *lp, struct dlm_range *range) -{ - dlm_t *dlm = lp->dlm; - strname_t str; - int error, bast = 1; - - /* - * Don't block any locks (NOEXP or not) from first mounter until it - * calls others_may_mount(). This solves an end case where a second - * mounter results in BLOCK_LOCKS while the first mounter is still - * doing the mount. - */ - - if (test_bit(DFL_FIRST_MOUNT, &dlm->flags) && - !test_bit(DFL_OTHERSMAYMOUNT, &dlm->flags)) - set_bit(LFL_NOBLOCK, &lp->flags); - - /* - * When recovery is in progress, delay lock requests for submission - * once recovery is done. Requests for recovery (NOEXP) and unlocks - * can pass. - */ - - if (test_bit(DFL_BLOCK_LOCKS, &dlm->flags) && - !test_bit(LFL_NOBLOCK, &lp->flags) && lp->req != DLM_LOCK_NL) { - queue_delayed(lp, QUEUE_LOCKS_BLOCKED); - return; - } - - /* - * Submit the actual lock request. - */ - - if (lp->posix || test_bit(LFL_NOBAST, &lp->flags)) - bast = 0; - - make_strname(&lp->lockname, &str); - - set_bit(LFL_WAIT_COMPLETE, &lp->flags); - - /* - log_debug("lk %x,%"PRIx64" id %x %d,%d %x", lp->lockname.ln_type, - lp->lockname.ln_number, lp->lksb.sb_lkid, - lp->cur, lp->req, lp->lkf); - */ - - error = dlm_lock(dlm->gdlm_lsp, lp->req, &lp->lksb, lp->lkf, str.name, - str.namelen, 0, lock_ast, (void *) lp, - bast ? lock_bast : NULL, range); - - if ((error == -EAGAIN) && (lp->lkf & DLM_LKF_NOQUEUE)) { - lp->lksb.sb_status = -EAGAIN; - queue_complete(lp); - error = 0; - } - - DLM_ASSERT(!error, - printk("%s: num=%x,%"PRIx64" err=%d cur=%d req=%d lkf=%x\n", - dlm->fsname, lp->lockname.ln_type, - lp->lockname.ln_number, error, lp->cur, lp->req, - lp->lkf);); -} - -int do_dlm_lock_sync(dlm_lock_t *lp, struct dlm_range *range) -{ - init_completion(&lp->uast_wait); - do_dlm_lock(lp, range); - wait_for_completion(&lp->uast_wait); - - return lp->lksb.sb_status; -} - -/** - * lm_dlm_lock - acquire a lock - * @lock: the lock to manipulate - * @cur_state: the current state - * @req_state: the requested state - * @flags: modifier flags - * - * Returns: A bitmap of LM_OUT_* on success, -EXXX on failure - */ - -unsigned int lm_dlm_lock(lm_lock_t *lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - - clear_bit(LFL_DLM_CANCEL, &lp->flags); - if (flags & LM_FLAG_NOEXP) - set_bit(LFL_NOBLOCK, &lp->flags); - - check_cur_state(lp, cur_state); - lp->req = make_mode(req_state); - lp->lkf = make_flags(lp, flags, lp->cur, lp->req); - - do_dlm_lock(lp, NULL); - return LM_OUT_ASYNC; -} - -int lm_dlm_lock_sync(lm_lock_t *lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - - init_completion(&lp->uast_wait); - lm_dlm_lock(lock, cur_state, req_state, flags); - wait_for_completion(&lp->uast_wait); - - return lp->lksb.sb_status; -} - -/** - * lm_dlm_unlock - unlock a lock - * @lock: the lock to manipulate - * @cur_state: the current state - * - * Returns: 0 on success, -EXXX on failure - */ - -unsigned int lm_dlm_unlock(lm_lock_t *lock, unsigned int cur_state) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - - clear_bit(LFL_DLM_CANCEL, &lp->flags); - if (lp->cur == DLM_LOCK_IV) - return 0; - do_dlm_unlock(lp); - return LM_OUT_ASYNC; -} - -void lm_dlm_unlock_sync(lm_lock_t *lock, unsigned int cur_state) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - - init_completion(&lp->uast_wait); - lm_dlm_unlock(lock, cur_state); - wait_for_completion(&lp->uast_wait); -} - -/** - * dlm_cancel - cancel a request that is blocked due to DFL_BLOCK_LOCKS - * @lock: the lock to cancel request for - * - */ - -void lm_dlm_cancel(lm_lock_t *lock) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - int error, dlist = FALSE; - - if (test_bit(LFL_DLM_CANCEL, &lp->flags)) - return; - - log_all("lm_dlm_cancel %x,%"PRIx64" flags %lx", - lp->lockname.ln_type, lp->lockname.ln_number, lp->flags); - - spin_lock(&lp->dlm->async_lock); - if (test_and_clear_bit(LFL_DLIST, &lp->flags)) { - list_del(&lp->dlist); - lp->type = 0; - dlist = TRUE; - } - spin_unlock(&lp->dlm->async_lock); - - if (dlist) { - set_bit(LFL_CANCEL, &lp->flags); - set_bit(LFL_WAIT_COMPLETE, &lp->flags); - queue_complete(lp); - return; - } - - if (!test_bit(LFL_WAIT_COMPLETE, &lp->flags) || - test_bit(LFL_DLM_UNLOCK, &lp->flags)) { - log_all("lm_dlm_cancel skip %x,%"PRIx64" flags %lx", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->flags); - return; - } - - /* the lock is blocked in the dlm */ - - set_bit(LFL_DLM_CANCEL, &lp->flags); - set_bit(LFL_WAIT_COMPLETE, &lp->flags); - - error = dlm_unlock(lp->dlm->gdlm_lsp, lp->lksb.sb_lkid, DLM_LKF_CANCEL, - NULL, lp); - - log_all("lm_dlm_cancel rv %d %x,%"PRIx64" flags %lx", error, - lp->lockname.ln_type, lp->lockname.ln_number, lp->flags); - - if (error == -EBUSY) - clear_bit(LFL_DLM_CANCEL, &lp->flags); -} - -int dlm_add_lvb(dlm_lock_t *lp) -{ - char *lvb; - - lvb = kmalloc(DLM_LVB_SIZE, GFP_KERNEL); - if (!lvb) - return -ENOMEM; - - memset(lvb, 0, DLM_LVB_SIZE); - - lp->lksb.sb_lvbptr = lvb; - lp->lvb = lvb; - return 0; -} - -void dlm_del_lvb(dlm_lock_t *lp) -{ - kfree(lp->lvb); - lp->lvb = NULL; - lp->lksb.sb_lvbptr = NULL; -} - -/** - * hold_null_lock - add a NL lock to the resource - * @lp: represents the resource - * - * This can do a synchronous dlm request (requiring a lock_dlm thread to - * get the completion) because gfs won't call hold_lvb() during a - * callback (from the context of a lock_dlm thread). - * - * Returns: 0 on success, -EXXX on failure - */ - -static int hold_null_lock(dlm_lock_t *lp) -{ - dlm_lock_t *lpn = NULL; - int error; - - if (lp->hold_null) { - printk("lock_dlm: lvb already held\n"); - return 0; - } - - error = create_lp(lp->dlm, &lp->lockname, &lpn); - if (error) - goto out; - - lpn->lksb.sb_lvbptr = junk_lvb; - lpn->lvb = junk_lvb; - - lpn->req = DLM_LOCK_NL; - lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; - set_bit(LFL_NOBAST, &lpn->flags); - set_bit(LFL_INLOCK, &lpn->flags); - - error = do_dlm_lock_sync(lpn, NULL); - if (error) { - delete_lp(lpn); - lpn = NULL; - } - - out: - lp->hold_null = lpn; - return error; -} - -/** - * unhold_null_lock - remove the NL lock from the resource - * @lp: represents the resource - * - * This cannot do a synchronous dlm request (requiring a lock_dlm thread to - * get the completion) because gfs may call unhold_lvb() during a - * callback (from the context of a lock_dlm thread) which could cause a - * deadlock since the other lock_dlm thread could be engaged in recovery. - * - * Returns: 0 on success, -EXXX on failure - */ - -static void unhold_null_lock(dlm_lock_t *lp) -{ - dlm_lock_t *lpn = lp->hold_null; - - lpn->lksb.sb_lvbptr = NULL; - lpn->lvb = NULL; - set_bit(LFL_UNLOCK_DELETE, &lpn->flags); - do_dlm_unlock(lpn); - lp->hold_null = NULL; -} - -/** - * dlm_hold_lvb - hold on to a lock value block - * @lock: the lock the LVB is associated with - * @lvbp: return the lvb memory here - * - * Returns: 0 on success, -EXXX on failure - */ - -int lm_dlm_hold_lvb(lm_lock_t *lock, char **lvbp) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - int error; - - error = dlm_add_lvb(lp); - if (error) - return error; - - *lvbp = lp->lvb; - - /* Acquire a NL lock because gfs requires the value block to remain - intact on the resource while the lvb is "held" even if it's holding - no locks on the resource. */ - - error = hold_null_lock(lp); - if (error) - dlm_del_lvb(lp); - - return error; -} - -/** - * dlm_unhold_lvb - release a LVB - * @lock: the lock the LVB is associated with - * @lvb: the lock value block - * - */ - -void lm_dlm_unhold_lvb(lm_lock_t *lock, char *lvb) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - - unhold_null_lock(lp); - dlm_del_lvb(lp); -} - -/** - * dlm_sync_lvb - sync out the value of a lvb - * @lock: the lock the LVB is associated with - * @lvb: the lock value block - * - */ - -void lm_dlm_sync_lvb(lm_lock_t *lock, char *lvb) -{ - dlm_lock_t *lp = (dlm_lock_t *) lock; - - if (lp->cur != DLM_LOCK_EX) - return; - - init_completion(&lp->uast_wait); - set_bit(LFL_SYNC_LVB, &lp->flags); - - lp->req = DLM_LOCK_EX; - lp->lkf = make_flags(lp, 0, lp->cur, lp->req); - - do_dlm_lock(lp, NULL); - wait_for_completion(&lp->uast_wait); -} - -/** - * dlm_recovery_done - reset the expired locks for a given jid - * @lockspace: the lockspace - * @jid: the jid - * - */ - -void lm_dlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid, - unsigned int message) -{ - jid_recovery_done((dlm_t *) lockspace, jid, message); -} - -/* - * Run in dlm_async - */ - -/** - * process_submit - make DLM lock requests from dlm_async thread - * @lp: DLM Lock - * - */ - -void process_submit(dlm_lock_t *lp) -{ - struct dlm_range range, *r = NULL; - - if (lp->posix) { - range.ra_start = lp->posix->start; - range.ra_end = lp->posix->end; - r = ⦥ - } - - do_dlm_lock(lp, r); -} diff --git a/gfs-kernel/src/dlm/lock_dlm.h b/gfs-kernel/src/dlm/lock_dlm.h deleted file mode 100644 index 15f7386..0000000 --- a/gfs-kernel/src/dlm/lock_dlm.h +++ /dev/null @@ -1,388 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef LOCK_DLM_DOT_H -#define LOCK_DLM_DOT_H - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/list.h> -#include <linux/socket.h> -#include <linux/kthread.h> -#include <net/sock.h> -#include <linux/lm_interface.h> -#include <cluster/cnxman.h> -#include <cluster/service.h> -#include <cluster/dlm.h> - -/* We take a shortcut and use lm_lockname structs for internal locks. This - means we must be careful to keep these types different from those used in - lm_interface.h. */ - -#define LM_TYPE_JID (0x10) -#define LM_TYPE_PLOCK_UPDATE (0x11) - -#define DLM_LVB_SIZE (DLM_LVB_LEN) - -/* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number). - We sprintf these numbers into a 24 byte string of hex values to make them - human-readable (to make debugging simpler.) */ - -#define LOCK_DLM_STRNAME_BYTES (24) - -#define LOCK_DLM_MAX_NODES (128) -#define LOCK_DLM_MAX_PLOCK (1024) - -#define DROP_LOCKS_COUNT (200000) -#define DROP_LOCKS_PERIOD (60) -#define SHRINK_CACHE_COUNT (100) -#define SHRINK_CACHE_MAX (1000) -#define SHRINK_CACHE_TIME (30) - -struct dlm; -struct dlm_lock; -struct dlm_node; -struct dlm_start; -struct strname; - -typedef struct dlm dlm_t; -typedef struct dlm_lock dlm_lock_t; -typedef struct dlm_node dlm_node_t; -typedef struct dlm_start dlm_start_t; -typedef struct strname strname_t; - -#define DFL_FIRST_MOUNT 0 -#define DFL_GOT_NODEID 1 -#define DFL_MG_FINISH 2 -#define DFL_HAVE_JID 3 -#define DFL_BLOCK_LOCKS 4 -#define DFL_START_ERROR 5 -#define DFL_MOUNT 6 -#define DFL_UMOUNT 7 -#define DFL_NEED_STARTDONE 8 -#define DFL_RECOVER 9 -#define DFL_WITHDRAW 10 -#define DFL_OTHERSMAYMOUNT 11 -#define DFL_WAIT_OTHERSMAYMOUNT 12 - -struct dlm { - uint32_t jid; - uint32_t our_nodeid; - unsigned long flags; - - int cnlen; - char * clustername; - int fnlen; - char * fsname; - int max_nodes; - - dlm_lockspace_t * gdlm_lsp; - - lm_callback_t fscb; - lm_fsdata_t * fsdata; - dlm_lock_t * jid_lp; - - spinlock_t async_lock; - struct list_head complete; - struct list_head blocking; - struct list_head delayed; - struct list_head submit; - struct list_head starts; - - wait_queue_head_t wait; - struct task_struct * thread1; - struct task_struct * thread2; - atomic_t lock_count; - unsigned long drop_time; - unsigned long shrink_time; - - int drop_locks_count; - int drop_locks_period; - - int mg_local_id; - int mg_last_start; - int mg_last_stop; - int mg_last_finish; - struct list_head mg_nodes; - struct semaphore mg_nodes_lock; - struct semaphore unmount_lock; - - struct list_head resources; - struct semaphore res_lock; - struct list_head null_cache; - spinlock_t null_cache_spin; - uint32_t null_count; -}; - -struct dlm_resource { - dlm_t * dlm; - struct list_head list; /* list of resources */ - struct lm_lockname name; /* the resource name */ - struct semaphore sema; - struct list_head locks; /* one lock for each range */ - int count; - dlm_lock_t * update; - struct list_head async_locks; - spinlock_t async_spin; - wait_queue_head_t waiters; -}; - -struct posix_lock { - struct list_head list; /* resource locks list */ - struct list_head async_list; /* resource async_locks list */ - struct dlm_resource * resource; - dlm_lock_t * lp; - unsigned long owner; - unsigned int pid; - uint64_t start; - uint64_t end; - int count; - int ex; - int busy; -}; - -#define LFL_NOBLOCK 0 -#define LFL_NOCACHE 1 -#define LFL_DLM_UNLOCK 2 -#define LFL_TRYFAILED 3 -#define LFL_SYNC_LVB 4 -#define LFL_FORCE_PROMOTE 5 -#define LFL_REREQUEST 6 -#define LFL_WAIT_COMPLETE 7 -#define LFL_CLIST 8 -#define LFL_BLIST 9 -#define LFL_DLIST 10 -#define LFL_SLIST 11 -#define LFL_INLOCK 12 -#define LFL_CANCEL 13 -#define LFL_UNLOCK_SYNC 14 -#define LFL_NOBAST 15 -#define LFL_HEADQUE 16 -#define LFL_UNLOCK_DELETE 17 -#define LFL_DLM_CANCEL 18 - -struct dlm_lock { - dlm_t * dlm; - struct lm_lockname lockname; - char * lvb; - struct dlm_lksb lksb; - - int16_t cur; - int16_t req; - int16_t prev_req; - unsigned int lkf; - unsigned int type; - unsigned long flags; - - int bast_mode; /* protected by async_lock */ - struct completion uast_wait; - - struct list_head clist; /* complete */ - struct list_head blist; /* blocking */ - struct list_head dlist; /* delayed */ - struct list_head slist; /* submit */ - - struct dlm_lock * hold_null; /* NL lock for hold_lvb */ - struct posix_lock * posix; - struct list_head null_list; /* NL lock cache for plocks */ -}; - -#define NFL_SENT_CB 0 -#define NFL_NOT_MEMBER 1 -#define NFL_RECOVERY_DONE 2 -#define NFL_LAST_FINISH 3 -#define NFL_HAVE_JID 4 -#define NFL_WITHDRAW 5 - -struct dlm_node { - uint32_t nodeid; - uint32_t jid; - unsigned long flags; - dlm_lock_t * withdraw_lp; - struct list_head list; -}; - -#define QUEUE_LOCKS_BLOCKED 1 -#define QUEUE_ERROR_UNLOCK 2 -#define QUEUE_ERROR_LOCK 3 -#define QUEUE_ERROR_RETRY 4 - -struct strname { - unsigned char name[LOCK_DLM_STRNAME_BYTES]; - unsigned short namelen; -}; - -struct dlm_start { - uint32_t * nodeids; - int count; - int type; - int event_id; - struct list_head list; -}; - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#if (BITS_PER_LONG == 64) -#define PRIu64 "lu" -#define PRId64 "ld" -#define PRIo64 "lo" -#define PRIx64 "lx" -#define PRIX64 "lX" -#define SCNu64 "lu" -#define SCNd64 "ld" -#define SCNo64 "lo" -#define SCNx64 "lx" -#define SCNX64 "lX" -#else -#define PRIu64 "Lu" -#define PRId64 "Ld" -#define PRIo64 "Lo" -#define PRIx64 "Lx" -#define PRIX64 "LX" -#define SCNu64 "Lu" -#define SCNd64 "Ld" -#define SCNo64 "Lo" -#define SCNx64 "Lx" -#define SCNX64 "LX" -#endif - -extern struct lm_lockops lock_dlm_ops; - -/* group.c */ - -int init_mountgroup(dlm_t *dlm); -void release_mountgroup(dlm_t *dlm); -void process_start(dlm_t *dlm, dlm_start_t *ds); -void process_finish(dlm_t *dlm); -void jid_recovery_done(dlm_t *dlm, unsigned int jid, unsigned int message); - -/* mount.c */ - -void lm_dlm_hold_withdraw(dlm_t *dlm); -void lm_dlm_release_withdraw(dlm_t *dlm, dlm_node_t *node); - -/* thread.c */ - -int init_async_thread(dlm_t *dlm); -void release_async_thread(dlm_t *dlm); - -/* lock.c */ - -int16_t make_lmstate(int16_t dlmmode); -void queue_delayed(dlm_lock_t *lp, int type); -void process_submit(dlm_lock_t *lp); -int create_lp(dlm_t *dlm, struct lm_lockname *name, dlm_lock_t **lpp); -void delete_lp(dlm_lock_t *lp); -int dlm_add_lvb(dlm_lock_t *lp); -void dlm_del_lvb(dlm_lock_t *lp); - -int lm_dlm_get_lock(lm_lockspace_t *lockspace, struct lm_lockname *name, - lm_lock_t **lockp); -void lm_dlm_put_lock(lm_lock_t *lock); - -void do_dlm_lock(dlm_lock_t *lp, struct dlm_range *range); -int do_dlm_lock_sync(dlm_lock_t *lp, struct dlm_range *range); -void do_dlm_unlock(dlm_lock_t *lp); -void do_dlm_unlock_sync(dlm_lock_t *lp); - -unsigned int lm_dlm_lock(lm_lock_t *lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags); -int lm_dlm_lock_sync(lm_lock_t *lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags); -unsigned int lm_dlm_unlock(lm_lock_t *lock, unsigned int cur_state); -void lm_dlm_unlock_sync(lm_lock_t *lock, unsigned int cur_state); - -void lm_dlm_cancel(lm_lock_t *lock); -int lm_dlm_hold_lvb(lm_lock_t *lock, char **lvbp); -void lm_dlm_unhold_lvb(lm_lock_t *lock, char *lvb); -void lm_dlm_sync_lvb(lm_lock_t *lock, char *lvb); -void lm_dlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid, - unsigned int message); - -/* plock.c */ - -int lm_dlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl); -int lm_dlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl); -int lm_dlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl); -void clear_null_cache(dlm_t *dlm); -void shrink_null_cache(dlm_t *dlm); - -/* main.c */ - -void lock_dlm_debug_log(const char *fmt, ...); -void lock_dlm_debug_dump(void); - - -#define LOCK_DLM_DEBUG - -#ifdef LOCK_DLM_DEBUG -#define log_debug(fmt, args...) lock_dlm_debug_log(fmt, ##args) -#else -#define log_debug(fmt, args...) -#endif - -#define log_all(fmt, args...) \ - do { \ - printk("lock_dlm: " fmt "\n", ##args); \ - lock_dlm_debug_log(fmt, ##args); \ - } while (0) - -#define log_error log_all - - -static inline int check_timeout(unsigned long stamp, unsigned int seconds) -{ - return time_after(jiffies, stamp + seconds * HZ); -} - -#define DLM_ASSERT(x, do) \ -{ \ - if (!(x)) \ - { \ - dlm_debug_dump(); \ - lock_dlm_debug_dump(); \ - printk("\nlock_dlm: Assertion failed on line %d of file %s\n" \ - "lock_dlm: assertion: "%s"\n" \ - "lock_dlm: time = %lu\n", \ - __LINE__, __FILE__, #x, jiffies); \ - {do} \ - printk("\n"); \ - BUG(); \ - panic("lock_dlm: Record message above and reboot.\n"); \ - } \ -} - -#define DLM_RETRY(do_this, until_this) \ -for (;;) \ -{ \ - do { do_this; } while (0); \ - if (until_this) \ - break; \ - printk("lock_dlm: out of memory: %s, %u\n", __FILE__, __LINE__); \ - schedule();\ -} - -#endif diff --git a/gfs-kernel/src/dlm/main.c b/gfs-kernel/src/dlm/main.c deleted file mode 100644 index c317830..0000000 --- a/gfs-kernel/src/dlm/main.c +++ /dev/null @@ -1,359 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "lock_dlm.h" -#include <linux/init.h> -#include <linux/proc_fs.h> - -#if defined(LOCK_DLM_DEBUG) -#define LOCK_DLM_DEBUG_SIZE (4096) -#define MAX_DEBUG_MSG_LEN (80) -#else -#define LOCK_DLM_DEBUG_SIZE (0) -#define MAX_DEBUG_MSG_LEN (0) -#endif -#define MAX_PROC_STRING (16) - -int lock_dlm_max_nodes; -int lock_dlm_drop_count; -int lock_dlm_drop_period; -int lock_dlm_max_plock_get; - -static char * debug_buf; -static unsigned int debug_size; -static unsigned int debug_point; -static int debug_wrap; -static spinlock_t debug_lock; -static struct proc_dir_entry * proc_dir = NULL; -static char proc_str[MAX_PROC_STRING + 1]; - - -void lock_dlm_debug_log(const char *fmt, ...) -{ - va_list va; - int i, n, size, len; - char buf[MAX_DEBUG_MSG_LEN+1]; - - spin_lock(&debug_lock); - - if (!debug_buf) - goto out; - - size = MAX_DEBUG_MSG_LEN; - memset(buf, 0, size+1); - - n = 0; - /* n = snprintf(buf, size, "%s ", dlm->fsname); */ - n = snprintf(buf, size, "%u ", current->pid); - size -= n; - - va_start(va, fmt); - vsnprintf(buf+n, size, fmt, va); - va_end(va); - - len = strlen(buf); - if (len > MAX_DEBUG_MSG_LEN-1) - len = MAX_DEBUG_MSG_LEN-1; - buf[len] = '\n'; - buf[len+1] = '\0'; - - for (i = 0; i < strlen(buf); i++) { - debug_buf[debug_point++] = buf[i]; - - if (debug_point == debug_size) { - debug_point = 0; - debug_wrap = 1; - } - } - out: - spin_unlock(&debug_lock); -} - -static void debug_setup(int size) -{ - char *b = NULL; - - if (size > PAGE_SIZE) - size = PAGE_SIZE; - if (size) - b = kmalloc(size, GFP_KERNEL); - - spin_lock(&debug_lock); - if (debug_buf) - kfree(debug_buf); - if (!size || !b) - goto out; - debug_size = size; - debug_point = 0; - debug_wrap = 0; - debug_buf = b; - memset(debug_buf, 0, debug_size); - out: - spin_unlock(&debug_lock); -} - -static void debug_init(void) -{ - debug_buf = NULL; - debug_size = 0; - debug_point = 0; - debug_wrap = 0; - spin_lock_init(&debug_lock); - debug_setup(LOCK_DLM_DEBUG_SIZE); -} - -void lock_dlm_debug_dump(void) -{ - int i; - - spin_lock(&debug_lock); - - if (debug_wrap) { - for (i = debug_point; i < debug_size; i++) - printk("%c", debug_buf[i]); - } - for (i = 0; i < debug_point; i++) - printk("%c", debug_buf[i]); - - spin_unlock(&debug_lock); -} - -EXPORT_SYMBOL(lock_dlm_debug_dump); - -#ifdef CONFIG_PROC_FS -static int lock_dlm_debug_info(char *b, char **start, off_t offset, int length) -{ - int i, n = 0; - - spin_lock(&debug_lock); - - if (debug_wrap) { - for (i = debug_point; i < debug_size; i++) - n += sprintf(b + n, "%c", debug_buf[i]); - } - for (i = 0; i < debug_point; i++) - n += sprintf(b + n, "%c", debug_buf[i]); - - spin_unlock(&debug_lock); - - return n; -} - -static int max_nodes_info(char *b, char **start, off_t offset, int length) -{ - return sprintf(b, "%d\n", lock_dlm_max_nodes); -} - -static int max_plock_info(char *b, char **start, off_t offset, int length) -{ - return sprintf(b, "%d\n", lock_dlm_max_plock_get); -} - -static int drop_count_info(char *b, char **start, off_t offset, int length) -{ - return sprintf(b, "%d\n", lock_dlm_drop_count); -} - -static int drop_period_info(char *b, char **start, off_t offset, int length) -{ - return sprintf(b, "%d\n", lock_dlm_drop_period); -} - -static int copy_string(const char *buffer, unsigned long count) -{ - int len; - - if (count > MAX_PROC_STRING) - len = MAX_PROC_STRING; - else - len = count; - - if (copy_from_user(proc_str, buffer, len)) - return -EFAULT; - proc_str[len] = '\0'; - return len; -} - -static int max_nodes_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int rv = copy_string(buffer, count); - if (rv < 0) - return rv; - lock_dlm_max_nodes = (int) simple_strtol(proc_str, NULL, 0); - return rv; -} - -static int max_plock_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int rv = copy_string(buffer, count); - if (rv < 0) - return rv; - lock_dlm_max_plock_get = (int) simple_strtol(proc_str, NULL, 0); - return rv; -} - -static int drop_count_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int rv = copy_string(buffer, count); - if (rv < 0) - return rv; - lock_dlm_drop_count = (int) simple_strtol(proc_str, NULL, 0); - return rv; -} - -static int drop_period_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int rv = copy_string(buffer, count); - if (rv < 0) - return rv; - lock_dlm_drop_period = (int) simple_strtol(proc_str, NULL, 0); - return rv; -} - -static void create_proc_entries(void) -{ - struct proc_dir_entry *p, *debug, *drop_count, *drop_period, - *max_nodes, *plock_get; - - debug = drop_count = drop_period = max_nodes = NULL; - - proc_dir = proc_mkdir("cluster/lock_dlm", 0); - if (!proc_dir) - return; - proc_dir->owner = THIS_MODULE; - - p = create_proc_entry("max_nodes", 0666, proc_dir); - if (!p) - goto out; - p->owner = THIS_MODULE; - p->get_info = max_nodes_info; - p->write_proc = max_nodes_write; - max_nodes = p; - - p = create_proc_entry("max_plock_get", 0666, proc_dir); - if (!p) - goto out; - p->owner = THIS_MODULE; - p->get_info = max_plock_info; - p->write_proc = max_plock_write; - plock_get = p; - - p = create_proc_entry("debug", 0444, proc_dir); - if (!p) - goto out; - p->get_info = lock_dlm_debug_info; - p->owner = THIS_MODULE; - debug = p; - - p = create_proc_entry("drop_count", 0666, proc_dir); - if (!p) - goto out; - p->owner = THIS_MODULE; - p->get_info = drop_count_info; - p->write_proc = drop_count_write; - drop_count = p; - - p = create_proc_entry("drop_period", 0666, proc_dir); - if (!p) - goto out; - p->owner = THIS_MODULE; - p->get_info = drop_period_info; - p->write_proc = drop_period_write; - drop_period = p; - - return; - - out: - if (drop_period) - remove_proc_entry("drop_period", proc_dir); - if (drop_count) - remove_proc_entry("drop_count", proc_dir); - if (debug) - remove_proc_entry("debug", proc_dir); - if (plock_get) - remove_proc_entry("max_plock_get", proc_dir); - if (max_nodes) - remove_proc_entry("max_nodes", proc_dir); - - remove_proc_entry("cluster/lock_dlm", NULL); - proc_dir = NULL; -} - -static void remove_proc_entries(void) -{ - if (proc_dir) { - remove_proc_entry("max_nodes", proc_dir); - remove_proc_entry("max_plock_get", proc_dir); - remove_proc_entry("debug", proc_dir); - remove_proc_entry("drop_period", proc_dir); - remove_proc_entry("drop_count", proc_dir); - remove_proc_entry("cluster/lock_dlm", NULL); - proc_dir = NULL; - } -} -#endif - -/** - * init_dlm - Initialize the dlm module - * - * Returns: 0 on success, -EXXX on failure - */ - -int __init init_lock_dlm(void) -{ - int error; - - error = lm_register_proto(&lock_dlm_ops); - if (error) { - printk("lock_dlm: can't register protocol: (%d)\n", error); - return error; - } - - lock_dlm_max_nodes = LOCK_DLM_MAX_NODES; - lock_dlm_drop_count = DROP_LOCKS_COUNT; - lock_dlm_drop_period = DROP_LOCKS_PERIOD; - lock_dlm_max_plock_get = LOCK_DLM_MAX_PLOCK; - -#ifdef CONFIG_PROC_FS - create_proc_entries(); -#endif - debug_init(); - - printk("Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__); - return 0; -} - -/** - * exit_dlm - cleanup the dlm module - * - */ - -void __exit exit_lock_dlm(void) -{ - lm_unregister_proto(&lock_dlm_ops); -#ifdef CONFIG_PROC_FS - remove_proc_entries(); -#endif - debug_setup(0); -} - -module_init(init_lock_dlm); -module_exit(exit_lock_dlm); - -MODULE_DESCRIPTION("GFS DLM Locking Module"); -MODULE_AUTHOR("Red Hat, Inc."); -MODULE_LICENSE("GPL"); diff --git a/gfs-kernel/src/dlm/mount.c b/gfs-kernel/src/dlm/mount.c deleted file mode 100644 index d031368..0000000 --- a/gfs-kernel/src/dlm/mount.c +++ /dev/null @@ -1,589 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/socket.h> -#include <net/sock.h> -#include <linux/delay.h> - -#include "lock_dlm.h" -#include <cluster/cnxman.h> -#include <cluster/service.h> - -extern int lock_dlm_max_nodes; -extern int lock_dlm_drop_count; -extern int lock_dlm_drop_period; - - -static int init_cman(dlm_t *dlm) -{ - int error = -1; - char *name = NULL; - - if (!dlm->clustername) - goto fail; - - error = kcl_addref_cluster(); - if (error) { - printk("lock_dlm: cannot get cman reference %d\n", error); - goto fail; - } - - error = kcl_cluster_name(&name); - if (error) { - printk("lock_dlm: cannot get cman cluster name %d\n", error); - goto fail_ref; - } - - if (strcmp(name, dlm->clustername)) { - error = -1; - printk("lock_dlm: cman cluster name "%s" does not match " - "file system cluster name "%s"\n", - name, dlm->clustername); - goto fail_ref; - } - - kfree(name); - return 0; - - fail_ref: - kcl_releaseref_cluster(); - fail: - if (name) - kfree(name); - return error; -} - -static int release_cman(dlm_t *dlm) -{ - return kcl_releaseref_cluster(); -} - -static int init_cluster(dlm_t *dlm, char *table_name) -{ - char *buf, *c, *clname, *fsname; - int len, error = -1; - - /* - * Parse superblock lock table <clustername>:<fsname> - */ - - len = strlen(table_name) + 1; - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - goto out; - memset(buf, 0, len); - memcpy(buf, table_name, strlen(table_name)); - - c = strstr(buf, ":"); - if (!c) - goto out_buf; - - *c = '\0'; - clname = buf; - fsname = ++c; - - dlm->max_nodes = lock_dlm_max_nodes; - - len = strlen(clname) + 1; - c = kmalloc(len, GFP_KERNEL); - if (!c) - goto out_buf; - memset(c, 0, len); - memcpy(c, clname, len-1); - dlm->cnlen = len-1; - dlm->clustername = c; - - len = strlen(fsname) + 1; - c = kmalloc(len, GFP_KERNEL); - if (!c) - goto out_cn; - memset(c, 0, len); - memcpy(c, fsname, len-1); - dlm->fnlen = len-1; - dlm->fsname = c; - - error = init_cman(dlm); - if (error) - goto out_fn; - - kfree(buf); - return 0; - - out_fn: - kfree(dlm->fsname); - out_cn: - kfree(dlm->clustername); - out_buf: - kfree(buf); - out: - printk("lock_dlm: init_cluster error %d\n", error); - return error; -} - -static int release_cluster(dlm_t *dlm) -{ - release_cman(dlm); - kfree(dlm->clustername); - kfree(dlm->fsname); - return 0; -} - -static int init_fence(dlm_t *dlm) -{ - LIST_HEAD(head); - struct kcl_service *s, *safe; - int error, found = FALSE; - - error = kcl_get_services(&head, SERVICE_LEVEL_FENCE); - if (error < 0) - goto out; - - list_for_each_entry_safe(s, safe, &head, list) { - list_del(&s->list); - if (!found && !strcmp(s->name, "default")) - found = TRUE; - kfree(s); - } - - if (found) - return 0; - - error = -1; - out: - printk("lock_dlm: fence domain not found; check fenced\n"); - return error; -} - -static int release_fence(dlm_t *dlm) -{ - return 0; -} - -static int init_gdlm(dlm_t *dlm) -{ - int error; - - error = dlm_new_lockspace(dlm->fsname, dlm->fnlen, &dlm->gdlm_lsp, - DLM_LSF_NOTIMERS); - if (error) - printk("lock_dlm: new lockspace error %d\n", error); - - return error; -} - -static int release_gdlm(dlm_t *dlm) -{ - dlm_release_lockspace(dlm->gdlm_lsp, 2); - return 0; -} - -static dlm_t *init_dlm(lm_callback_t cb, lm_fsdata_t *fsdata) -{ - dlm_t *dlm; - - dlm = kmalloc(sizeof(dlm_t), GFP_KERNEL); - if (!dlm) - return NULL; - - memset(dlm, 0, sizeof(dlm_t)); - - dlm->drop_locks_count = lock_dlm_drop_count; - dlm->drop_locks_period = lock_dlm_drop_period; - - dlm->fscb = cb; - dlm->fsdata = fsdata; - - spin_lock_init(&dlm->async_lock); - - INIT_LIST_HEAD(&dlm->complete); - INIT_LIST_HEAD(&dlm->blocking); - INIT_LIST_HEAD(&dlm->delayed); - INIT_LIST_HEAD(&dlm->submit); - INIT_LIST_HEAD(&dlm->starts); - INIT_LIST_HEAD(&dlm->resources); - INIT_LIST_HEAD(&dlm->null_cache); - - init_waitqueue_head(&dlm->wait); - dlm->thread1 = NULL; - dlm->thread2 = NULL; - atomic_set(&dlm->lock_count, 0); - dlm->drop_time = jiffies; - dlm->shrink_time = jiffies; - - INIT_LIST_HEAD(&dlm->mg_nodes); - init_MUTEX(&dlm->mg_nodes_lock); - init_MUTEX(&dlm->unmount_lock); - init_MUTEX(&dlm->res_lock); - - dlm->null_count = 0; - spin_lock_init(&dlm->null_cache_spin); - - return dlm; -} - -/** - * dlm_mount - mount a dlm lockspace - * @table_name: the name of the space to mount - * @host_data: host specific data - * @cb: the callback - * @lockstruct: the structure of crap to fill in - * - * Returns: 0 on success, -EXXX on failure - */ - -static int lm_dlm_mount(char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t *fsdata, - unsigned int min_lvb_size, - struct lm_lockstruct *lockstruct) -{ - dlm_t *dlm; - int error = -ENOMEM; - - if (min_lvb_size > DLM_LVB_SIZE) - goto out; - - dlm = init_dlm(cb, fsdata); - if (!dlm) - goto out; - - error = init_cluster(dlm, table_name); - if (error) - goto out_free; - - error = init_fence(dlm); - if (error) - goto out_cluster; - - error = init_gdlm(dlm); - if (error) - goto out_fence; - - error = init_async_thread(dlm); - if (error) - goto out_gdlm; - - error = init_mountgroup(dlm); - if (error) - goto out_thread; - - lockstruct->ls_jid = dlm->jid; - lockstruct->ls_first = test_bit(DFL_FIRST_MOUNT, &dlm->flags); - lockstruct->ls_lockspace = dlm; - lockstruct->ls_ops = &lock_dlm_ops; - lockstruct->ls_flags = 0; - lockstruct->ls_lvb_size = DLM_LVB_SIZE; - return 0; - - out_thread: - release_async_thread(dlm); - out_gdlm: - release_gdlm(dlm); - out_fence: - release_fence(dlm); - out_cluster: - release_cluster(dlm); - out_free: - kfree(dlm); - out: - return error; -} - -/** - * dlm_others_may_mount - * @lockspace: the lockspace to unmount - * - */ - -static void lm_dlm_others_may_mount(lm_lockspace_t *lockspace) -{ - dlm_t *dlm = (dlm_t *) lockspace; - int last_start; - - log_debug("others_may_mount %lx", dlm->flags); - - if (!test_bit(DFL_FIRST_MOUNT, &dlm->flags)) { - log_all("others_may_mount not first mounter %lx", dlm->flags); - return; - } - - down(&dlm->unmount_lock); - - spin_lock(&dlm->async_lock); - last_start = dlm->mg_last_start; - spin_unlock(&dlm->async_lock); - - set_bit(DFL_OTHERSMAYMOUNT, &dlm->flags); - - /* There's been a start to add a second node while we've been - doing first-mount recovery. We skipped the kcl_start_done() when - processing the start to keep the second node from mounting until we - allow others. Now we can ack the start and allow the second node be - complete its mount. */ - - if (test_bit(DFL_WAIT_OTHERSMAYMOUNT, &dlm->flags)) { - log_debug("others_may_mount start_done %d %lx", - last_start, dlm->flags); - kcl_start_done(dlm->mg_local_id, last_start); - } - up(&dlm->unmount_lock); -} - -/** - * dlm_unmount - unmount a lock space - * @lockspace: the lockspace to unmount - * - */ - -static void lm_dlm_unmount(lm_lockspace_t *lockspace) -{ - dlm_t *dlm = (dlm_t *) lockspace; - - log_debug("unmount flags %lx", dlm->flags); - if (test_bit(DFL_WITHDRAW, &dlm->flags)) - goto out; - release_mountgroup(dlm); - release_async_thread(dlm); - release_gdlm(dlm); - release_fence(dlm); - release_cluster(dlm); - clear_null_cache(dlm); - out: - kfree(dlm); -} - -static void wd_ast(void *arg) -{ - dlm_lock_t *lp = (dlm_lock_t *) arg; - complete(&lp->uast_wait); -} - -static void wd_bast(void *arg, int mode) -{ - dlm_lock_t *lp = (dlm_lock_t *) arg; - dlm_t *dlm = lp->dlm; - dlm_node_t *node; - int error; - - if (lp->cur == DLM_LOCK_NL) { - log_all("withdraw bast cur NL arg %d", mode); - return; - } - - if (lp->cur != DLM_LOCK_PR) { - log_all("withdraw bast cur %d arg %d", lp->cur, mode); - return; - } - - if (mode != DLM_LOCK_EX) { - log_all("withdraw bast cur %d arg %d", lp->cur, mode); - return; - } - - set_bit(DFL_BLOCK_LOCKS, &dlm->flags); - - down(&dlm->mg_nodes_lock); - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (node->withdraw_lp == lp) { - log_debug("wd_bast node %d withdraw", node->nodeid); - set_bit(NFL_WITHDRAW, &node->flags); - break; - } - } - up(&dlm->mg_nodes_lock); - - set_bit(LFL_UNLOCK_DELETE, &lp->flags); - - error = dlm_unlock(dlm->gdlm_lsp, lp->lksb.sb_lkid, 0, NULL, lp); - - DLM_ASSERT(!error, printk("error %d\n", error);); - - node->withdraw_lp = NULL; -} - -void lm_dlm_hold_withdraw(dlm_t *dlm) -{ - char name[16]; - dlm_node_t *node; - dlm_lock_t *lp; - int error; - - down(&dlm->mg_nodes_lock); - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (test_bit(NFL_WITHDRAW, &node->flags)) - continue; - - lp = node->withdraw_lp; - - /* if we have the lp it should always be in PR */ - if (lp) { - if (lp->cur != DLM_LOCK_PR) - log_all("hold_withdraw cur %d", lp->cur); - continue; - } - - lp = kmalloc(sizeof(dlm_lock_t), GFP_KERNEL); - if (!lp) - continue; - memset(lp, 0, sizeof(dlm_lock_t)); - init_completion(&lp->uast_wait); - lp->dlm = dlm; - node->withdraw_lp = lp; - - memset(name, 0, sizeof(name)); - snprintf(name, sizeof(name), "withdraw %u", node->nodeid); - - error = dlm_lock(dlm->gdlm_lsp, DLM_LOCK_PR, &lp->lksb, - DLM_LKF_NOQUEUE, name, sizeof(name), 0, - wd_ast, (void *) lp, wd_bast, NULL); - - DLM_ASSERT(!error, printk("error %d\n", error);); - - wait_for_completion(&lp->uast_wait); - - DLM_ASSERT(lp->lksb.sb_status == 0, - printk("status %d\n", lp->lksb.sb_status);); - - lp->cur = DLM_LOCK_PR; - } - up(&dlm->mg_nodes_lock); -} - -static void do_withdraw(dlm_t *dlm) -{ - char name[16]; - dlm_node_t *node; - dlm_lock_t *lp; - int error; - - down(&dlm->mg_nodes_lock); - list_for_each_entry(node, &dlm->mg_nodes, list) { - if (node->nodeid == dlm->our_nodeid) - break; - } - up(&dlm->mg_nodes_lock); - - if (!node) { - log_all("node not found for %d", dlm->our_nodeid); - return; - } - - lp = node->withdraw_lp; - if (!lp) { - log_all("no withdraw lock for self"); - return; - } - - if (lp->cur != DLM_LOCK_PR) { - log_all("our withdraw lock in mode %d", lp->cur); - return; - } - - log_debug("do_withdraw"); - memset(name, 0, sizeof(name)); - snprintf(name, sizeof(name), "withdraw %u", dlm->our_nodeid); - - error = dlm_lock(dlm->gdlm_lsp, DLM_LOCK_EX, &lp->lksb, - DLM_LKF_CONVERT, name, sizeof(name), 0, wd_ast, - (void *) lp, wd_bast, NULL); - - DLM_ASSERT(!error, printk("error %d\n", error);); - - wait_for_completion(&lp->uast_wait); - - DLM_ASSERT(lp->lksb.sb_status == 0, - printk("status %d\n", lp->lksb.sb_status);); - - lp->cur = DLM_LOCK_EX; -} - -/* Release the withdraw lock for this node. If the node was removed because it - withdrew, then we already released the lock (in wd_bast). If the node has - failed or unmounted, then we still hold its withdraw lock and need to unlock - it. If _we're_ withdrawing, then we've already left the lockspace so we - don't unlock, just free. */ - -void lm_dlm_release_withdraw(dlm_t *dlm, dlm_node_t *node) -{ - dlm_lock_t *lp; - int error; - - lp = node->withdraw_lp; - if (!lp) - return; - - if (test_bit(DFL_WITHDRAW, &dlm->flags)) { - kfree(lp); - goto out; - } - - /* the lp is freed by the async thread when it gets the comp ast */ - set_bit(LFL_UNLOCK_DELETE, &lp->flags); - - error = dlm_unlock(dlm->gdlm_lsp, lp->lksb.sb_lkid, 0, NULL, lp); - - DLM_ASSERT(!error, printk("error %d\n", error);); - - out: - node->withdraw_lp = NULL; -} - -/** - * dlm_withdraw - withdraw from a lock space - * @lockspace: the lockspace to withdraw from - * - * Holding the withdraw lock in EX means all gfs locks are blocked on other - * nodes and we can safely leave the lockspace. - * - */ - -static void lm_dlm_withdraw(lm_lockspace_t *lockspace) -{ - dlm_t *dlm = (dlm_t *) lockspace; - - log_debug("withdraw flags %lx", dlm->flags); - set_bit(DFL_WITHDRAW, &dlm->flags); - - /* process_start uses the dlm so leaving the ls while it's running - can hang it; this waits for it to complete. */ - down(&dlm->unmount_lock); - up(&dlm->unmount_lock); - - do_withdraw(dlm); - release_gdlm(dlm); - release_mountgroup(dlm); - release_cluster(dlm); - - /* FIXME: free all outstanding memory */ - log_all("withdraw abandoned memory"); -} - -struct lm_lockops lock_dlm_ops = { - lm_proto_name:"lock_dlm", - lm_mount:lm_dlm_mount, - lm_others_may_mount:lm_dlm_others_may_mount, - lm_unmount:lm_dlm_unmount, - lm_withdraw:lm_dlm_withdraw, - lm_get_lock:lm_dlm_get_lock, - lm_put_lock:lm_dlm_put_lock, - lm_lock:lm_dlm_lock, - lm_unlock:lm_dlm_unlock, - lm_plock:lm_dlm_plock, - lm_punlock:lm_dlm_punlock, - lm_plock_get:lm_dlm_plock_get, - lm_cancel:lm_dlm_cancel, - lm_hold_lvb:lm_dlm_hold_lvb, - lm_unhold_lvb:lm_dlm_unhold_lvb, - lm_sync_lvb:lm_dlm_sync_lvb, - lm_recovery_done:lm_dlm_recovery_done, - lm_owner:THIS_MODULE, -}; diff --git a/gfs-kernel/src/dlm/plock.c b/gfs-kernel/src/dlm/plock.c deleted file mode 100644 index 41dbf27..0000000 --- a/gfs-kernel/src/dlm/plock.c +++ /dev/null @@ -1,1269 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "lock_dlm.h" -#include <linux/fcntl.h> - -#define MIN(a,b) ((a) <= (b)) ? (a) : (b) -#define MAX(a,b) ((a) >= (b)) ? (a) : (b) - -#define CREATE 1 -#define NO_CREATE 0 - -#define WAIT 1 -#define NO_WAIT 0 -#define X_WAIT -1 - -#define EX 1 -#define NO_EX 0 -#define SH NO_EX - -#define HEAD 1 - -extern int lock_dlm_max_plock_get; - -static int local_conflict(dlm_t *dlm, struct dlm_resource *r, - struct lm_lockname *name, unsigned long owner, - uint64_t start, uint64_t end, int ex); - -static int global_conflict(dlm_t *dlm, struct lm_lockname *name, - unsigned long owner, uint64_t start, uint64_t end, - int ex); - -/* remove lru lp from end of list, null_cache_spin must be held */ - -static dlm_lock_t *lru_null(dlm_t *dlm) -{ - dlm_lock_t *lp; - - lp = list_entry(dlm->null_cache.next, dlm_lock_t, null_list); - list_del(&lp->null_list); - dlm->null_count--; - - return lp; -} - -/* It's important that the lock_dlm thread not block doing any synchronous - dlm operations because a recovery event (which makes sync requests) can - happen during this. If both lock_dlm threads do sync requests they deadlock - since one is required to process asts. We also break out early if there's a - recovery so it doesn't have to wait. */ - -void shrink_null_cache(dlm_t *dlm) -{ - dlm_lock_t *lp; - - while (1) { - spin_lock(&dlm->null_cache_spin); - if (dlm->null_count <= SHRINK_CACHE_COUNT || - test_bit(DFL_RECOVER, &dlm->flags)) { - spin_unlock(&dlm->null_cache_spin); - break; - } - - lp = lru_null(dlm); - spin_unlock(&dlm->null_cache_spin); - - set_bit(LFL_UNLOCK_DELETE, &lp->flags); - do_dlm_unlock(lp); - schedule(); - } -} - -void clear_null_cache(dlm_t *dlm) -{ - dlm_lock_t *lp, *safe; - - spin_lock(&dlm->null_cache_spin); - list_for_each_entry_safe(lp, safe, &dlm->null_cache, null_list) { - list_del(&lp->null_list); - dlm->null_count--; - delete_lp(lp); - } - spin_unlock(&dlm->null_cache_spin); -} - -static void keep_null_lock(dlm_t *dlm, dlm_lock_t *lp) -{ - dlm_lock_t *lp2 = NULL; - - spin_lock(&dlm->null_cache_spin); - /* add to front of list wrt list_add_tail/list_for_each */ - list_add_tail(&lp->null_list, &dlm->null_cache); - dlm->null_count++; - - /* help to shrink cache if too many null locks are piling up */ - if (dlm->null_count > SHRINK_CACHE_MAX) - lp2 = lru_null(dlm); - spin_unlock(&dlm->null_cache_spin); - - if (lp2) { - set_bit(LFL_UNLOCK_DELETE, &lp2->flags); - do_dlm_unlock(lp2); - } -} - -static dlm_lock_t *find_null_lock(dlm_t *dlm, struct lm_lockname *name) -{ - dlm_lock_t *lp; - int found = FALSE; - - spin_lock(&dlm->null_cache_spin); - list_for_each_entry(lp, &dlm->null_cache, null_list) { - if (lm_name_equal(&lp->lockname, name)) { - list_del(&lp->null_list); - dlm->null_count--; - found = TRUE; - break; - } - } - spin_unlock(&dlm->null_cache_spin); - - if (!found) - lp = NULL; - return lp; -} - -static int lock_resource(struct dlm_resource *r) -{ - dlm_lock_t *lp; - struct lm_lockname name; - int error; - - name.ln_type = LM_TYPE_PLOCK_UPDATE; - name.ln_number = r->name.ln_number; - - lp = find_null_lock(r->dlm, &name); - if (!lp) { - error = create_lp(r->dlm, &name, &lp); - if (error) - return error; - set_bit(LFL_NOBAST, &lp->flags); - set_bit(LFL_INLOCK, &lp->flags); - } else - lp->lkf = DLM_LKF_CONVERT; - - lp->req = DLM_LOCK_EX; - error = do_dlm_lock_sync(lp, NULL); - if (error) { - delete_lp(lp); - lp = NULL; - } - - r->update = lp; - return error; -} - -static void unlock_resource(struct dlm_resource *r) -{ - dlm_lock_t *lp = r->update; - - set_bit(LFL_NOBAST, &lp->flags); - set_bit(LFL_INLOCK, &lp->flags); - lp->req = DLM_LOCK_NL; - lp->lkf = DLM_LKF_CONVERT; - do_dlm_lock_sync(lp, NULL); - keep_null_lock(r->dlm, lp); - r->update = NULL; -} - -static struct dlm_resource *search_resource(dlm_t *dlm, struct lm_lockname *name) -{ - struct dlm_resource *r; - - list_for_each_entry(r, &dlm->resources, list) { - if (lm_name_equal(&r->name, name)) - return r; - } - return NULL; -} - -static int get_resource(dlm_t *dlm, struct lm_lockname *name, int create, - struct dlm_resource **res) -{ - struct dlm_resource *r, *r2; - int error = -ENOMEM; - - down(&dlm->res_lock); - r = search_resource(dlm, name); - if (r) - r->count++; - up(&dlm->res_lock); - - if (r) - goto out; - - if (create == NO_CREATE) { - error = -ENOENT; - goto fail; - } - - r = kmalloc(sizeof(struct dlm_resource), GFP_KERNEL); - if (!r) - goto fail; - - memset(r, 0, sizeof(struct dlm_resource)); - r->dlm = dlm; - r->name = *name; - r->count = 1; - INIT_LIST_HEAD(&r->locks); - INIT_LIST_HEAD(&r->async_locks); - init_MUTEX(&r->sema); - spin_lock_init(&r->async_spin); - init_waitqueue_head(&r->waiters); - - down(&dlm->res_lock); - r2 = search_resource(dlm, name); - if (r2) { - r2->count++; - up(&dlm->res_lock); - kfree(r); - r = r2; - goto out; - } - - list_add_tail(&r->list, &dlm->resources); - up(&dlm->res_lock); - - out: - *res = r; - return 0; - fail: - return error; -} - -static void put_resource(struct dlm_resource *r) -{ - dlm_t *dlm = r->dlm; - - down(&dlm->res_lock); - r->count--; - if (r->count == 0) { - DLM_ASSERT(list_empty(&r->locks), ); - DLM_ASSERT(list_empty(&r->async_locks), ); - list_del(&r->list); - kfree(r); - } - up(&dlm->res_lock); -} - -static inline void hold_resource(struct dlm_resource *r) -{ - down(&r->dlm->res_lock); - r->count++; - up(&r->dlm->res_lock); -} - -static inline int ranges_overlap(uint64_t start1, uint64_t end1, - uint64_t start2, uint64_t end2) -{ - if (end1 < start2 || start1 > end2) - return FALSE; - return TRUE; -} - -/** - * overlap_type - returns a value based on the type of overlap - * @s1 - start of new lock range - * @e1 - end of new lock range - * @s2 - start of existing lock range - * @e2 - end of existing lock range - * - */ - -static int overlap_type(uint64_t s1, uint64_t e1, uint64_t s2, uint64_t e2) -{ - int ret; - - /* - * ---r1--- - * ---r2--- - */ - - if (s1 == s2 && e1 == e2) - ret = 0; - - /* - * --r1-- - * ---r2--- - */ - - else if (s1 == s2 && e1 < e2) - ret = 1; - - /* - * --r1-- - * ---r2--- - */ - - else if (s1 > s2 && e1 == e2) - ret = 1; - - /* - * --r1-- - * ---r2--- - */ - - else if (s1 > s2 && e1 < e2) - ret = 2; - - /* - * ---r1--- or ---r1--- or ---r1--- - * --r2-- --r2-- --r2-- - */ - - else if (s1 <= s2 && e1 >= e2) - ret = 3; - - /* - * ---r1--- - * ---r2--- - */ - - else if (s1 > s2 && e1 > e2) - ret = 4; - - /* - * ---r1--- - * ---r2--- - */ - - else if (s1 < s2 && e1 < e2) - ret = 4; - - else - ret = -1; - - return ret; -} - -/* shrink the range start2:end2 by the partially overlapping start:end */ - -static int shrink_range2(uint64_t *start2, uint64_t *end2, - uint64_t start, uint64_t end) -{ - int error = 0; - - if (*start2 < start) - *end2 = start - 1; - else if (*end2 > end) - *start2 = end + 1; - else - error = -1; - return error; -} - -static int shrink_range(struct posix_lock *po, uint64_t start, uint64_t end) -{ - return shrink_range2(&po->start, &po->end, start, end); -} - -static void put_lock(dlm_lock_t *lp) -{ - struct posix_lock *po = lp->posix; - - po->count--; - if (po->count == 0) { - kfree(po); - delete_lp(lp); - } -} - -static int create_lock(struct dlm_resource *r, unsigned long owner, - unsigned int pid, int ex, uint64_t start, - uint64_t end, dlm_lock_t **lpp) -{ - dlm_lock_t *lp; - struct posix_lock *po; - int error; - - error = create_lp(r->dlm, &r->name, &lp); - if (error) - return error; - - po = kmalloc(sizeof(struct posix_lock), GFP_KERNEL); - if (!po) { - kfree(lp); - return -ENOMEM; - } - memset(po, 0, sizeof(struct posix_lock)); - - lp->posix = po; - po->lp = lp; - po->resource = r; - po->count = 1; - po->start = start; - po->end = end; - po->owner = owner; - po->pid = pid; - po->ex = ex; - list_add_tail(&po->list, &r->locks); - - *lpp = lp; - return 0; -} - -static unsigned int make_flags_posix(dlm_lock_t *lp, int wait) -{ - unsigned int lkf = DLM_LKF_NOORDER; - - if (test_and_clear_bit(LFL_HEADQUE, &lp->flags)) - lkf |= DLM_LKF_HEADQUE; - - if (wait == NO_WAIT || wait == X_WAIT) - lkf |= DLM_LKF_NOQUEUE; - - if (lp->lksb.sb_lkid != 0) - lkf |= DLM_LKF_CONVERT; - - return lkf; -} - -static void do_range_lock(dlm_lock_t *lp) -{ - struct dlm_range range = { lp->posix->start, lp->posix->end }; - do_dlm_lock(lp, &range); -} - -static void request_lock(dlm_lock_t *lp, int wait) -{ - set_bit(LFL_INLOCK, &lp->flags); - lp->req = lp->posix->ex ? DLM_LOCK_EX : DLM_LOCK_PR; - lp->lkf = make_flags_posix(lp, wait); - - log_debug("req %x,%"PRIx64" %s %"PRIx64"-%"PRIx64" lkf %x wait %u", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->posix->ex ? "ex" : "sh", lp->posix->start, - lp->posix->end, lp->lkf, wait); - - do_range_lock(lp); -} - -static void add_async(struct posix_lock *po, struct dlm_resource *r) -{ - spin_lock(&r->async_spin); - list_add_tail(&po->async_list, &r->async_locks); - spin_unlock(&r->async_spin); -} - -static void del_async(struct posix_lock *po, struct dlm_resource *r) -{ - spin_lock(&r->async_spin); - list_del(&po->async_list); - spin_unlock(&r->async_spin); -} - -static int wait_async(dlm_lock_t *lp) -{ - wait_for_completion(&lp->uast_wait); - del_async(lp->posix, lp->posix->resource); - return lp->lksb.sb_status; -} - -static void wait_async_list(struct dlm_resource *r, unsigned long owner) -{ - struct posix_lock *po; - int error, found; - - restart: - found = FALSE; - spin_lock(&r->async_spin); - list_for_each_entry(po, &r->async_locks, async_list) { - if (po->owner != owner) - continue; - found = TRUE; - break; - } - spin_unlock(&r->async_spin); - - if (found) { - DLM_ASSERT(po->lp, ); - po->busy = 1; - error = wait_async(po->lp); - DLM_ASSERT(!error, ); - po->busy = 0; - goto restart; - } -} - -static void update_lock(dlm_lock_t *lp, int wait) -{ - request_lock(lp, wait); - add_async(lp->posix, lp->posix->resource); - - if (wait == NO_WAIT || wait == X_WAIT) { - int error = wait_async(lp); - DLM_ASSERT(!error, printk("error=%d\n", error);); - } -} - -static void add_lock(struct dlm_resource *r, unsigned long owner, - unsigned int pid, int wait, int ex, uint64_t start, - uint64_t end, int head) -{ - dlm_lock_t *lp; - int error; - - error = create_lock(r, owner, pid, ex, start, end, &lp); - DLM_ASSERT(!error, ); - if (head == HEAD) - set_bit(LFL_HEADQUE, &lp->flags); - - hold_resource(r); - update_lock(lp, wait); -} - -static int remove_lock(dlm_lock_t *lp) -{ - struct dlm_resource *r = lp->posix->resource; - - log_debug("remove %x,%"PRIx64"", r->name.ln_type, r->name.ln_number); - - do_dlm_unlock_sync(lp); - put_lock(lp); - put_resource(r); - return 0; -} - -/* RN within RE (and starts or ends on RE boundary) - 1. add new lock for non-overlap area of RE, orig mode - 2. convert RE to RN range and mode */ - -static int lock_case1(struct posix_lock *po, struct dlm_resource *r, - unsigned long owner, unsigned int pid, int wait, - int ex, uint64_t start, uint64_t end) -{ - uint64_t start2, end2; - - /* non-overlapping area start2:end2 */ - start2 = po->start; - end2 = po->end; - shrink_range2(&start2, &end2, start, end); - - po->start = start; - po->end = end; - po->ex = ex; - - if (ex) { - add_lock(r, owner, pid, X_WAIT, SH, start2, end2, HEAD); - update_lock(po->lp, wait); - } else { - add_lock(r, owner, pid, WAIT, EX, start2, end2, HEAD); - update_lock(po->lp, X_WAIT); - } - return 0; -} - -/* RN within RE (RE overlaps RN on both sides) - 1. add new lock for front fragment, orig mode - 2. add new lock for back fragment, orig mode - 3. convert RE to RN range and mode */ - -static int lock_case2(struct posix_lock *po, struct dlm_resource *r, - unsigned long owner, unsigned int pid, int wait, - int ex, uint64_t start, uint64_t end) -{ - if (ex) { - add_lock(r, owner, pid, X_WAIT, SH, po->start, start-1, HEAD); - add_lock(r, owner, pid, X_WAIT, SH, end+1, po->end, HEAD); - - po->start = start; - po->end = end; - po->ex = ex; - - update_lock(po->lp, wait); - } else { - add_lock(r, owner, pid, WAIT, EX, po->start, start-1, HEAD); - add_lock(r, owner, pid, WAIT, EX, end+1, po->end, HEAD); - - po->start = start; - po->end = end; - po->ex = ex; - - update_lock(po->lp, X_WAIT); - } - return 0; -} - -/* returns ranges from exist list in order of their start values */ - -static int next_exist(struct list_head *exist, uint64_t *start, uint64_t *end) -{ - struct posix_lock *po; - int first = TRUE, first_call = FALSE; - - if (!*start && !*end) - first_call = TRUE; - - list_for_each_entry(po, exist, list) { - if (!first_call && (po->start <= *start)) - continue; - - if (first) { - *start = po->start; - *end = po->end; - first = FALSE; - } else if (po->start < *start) { - *start = po->start; - *end = po->end; - } - } - - return (first ? -1 : 0); -} - -/* adds locks in gaps between existing locks from start to end */ - -static int fill_gaps(struct list_head *exist, struct dlm_resource *r, - unsigned long owner, unsigned int pid, int wait, int ex, uint64_t start, - uint64_t end) -{ - uint64_t exist_start = 0, exist_end = 0; - - /* cover gaps in front of each existing lock */ - for (;;) { - if (next_exist(exist, &exist_start, &exist_end)) - break; - if (start < exist_start) - add_lock(r, owner, pid, wait, ex, start, exist_start-1, 0); - start = exist_end + 1; - } - - /* cover gap after last existing lock */ - if (exist_end < end) - add_lock(r, owner, pid, wait, ex, exist_end+1, end, 0); - - return 0; -} - -/* RE within RN (possibly more than one RE lock, all within RN) */ - -static int lock_case3(struct list_head *exist, struct dlm_resource *r, - unsigned long owner, unsigned int pid, int wait, - int ex, uint64_t start, uint64_t end) -{ - struct posix_lock *po, *safe; - - fill_gaps(exist, r, owner, pid, wait, ex, start, end); - - if (!ex) - wait = X_WAIT; - - /* update existing locks to new mode and put back in locks list */ - list_for_each_entry_safe(po, safe, exist, list) { - list_move_tail(&po->list, &r->locks); - if (po->ex == ex) - continue; - po->ex = ex; - update_lock(po->lp, wait); - } - - return 0; -} - -/* RE within RN (possibly more than one RE lock, one RE partially overlaps RN) - 1. add new locks with new mode for RN gaps not covered by RE's - 2. convert RE locks' mode to new mode - other steps deal with the partial-overlap fragment and depend on whether - the request is sh->ex or ex->sh */ - -static int lock_case4(struct posix_lock *opo, struct list_head *exist, - struct dlm_resource *r, unsigned long owner, - unsigned int pid, int wait, int ex, uint64_t start, - uint64_t end) -{ - struct posix_lock *po, *safe; - uint64_t over_start = 0, over_end = 0; - uint64_t frag_start = 0, frag_end = 0; - - /* fragment (non-overlap) range of opo */ - if (opo->start < start) { - frag_start = opo->start; - frag_end = start - 1; - } else { - frag_start = end + 1; - frag_end = opo->end; - } - - /* overlap range of opo */ - if (opo->start < start) { - over_start = start; - over_end = opo->end; - } else { - over_start = opo->start; - opo->end = end; - } - - /* cut off the non-overlap portion of opo so fill_gaps will work */ - opo->start = over_start; - opo->end = over_end; - - fill_gaps(exist, r, owner, pid, wait, ex, start, end); - - /* update existing locks to new mode and put back in locks list */ - list_for_each_entry_safe(po, safe, exist, list) { - list_move_tail(&po->list, &r->locks); - if (po == opo) - continue; - if (po->ex == ex) - continue; - po->ex = ex; - update_lock(po->lp, wait); - } - - /* deal with the RE that partially overlaps the requested range */ - - if (ex == opo->ex) - return 0; - - if (ex) { - /* 1. add a shared lock in the non-overlap range - 2. convert RE to overlap range and requested mode */ - - add_lock(r, owner, pid, X_WAIT, SH, frag_start, frag_end, HEAD); - - opo->start = over_start; - opo->end = over_end; - opo->ex = ex; - - update_lock(opo->lp, wait); - } else { - /* 1. request a shared lock in the overlap range - 2. convert RE to non-overlap range - 3. wait for shared lock to complete */ - - add_lock(r, owner, pid, WAIT, SH, over_start, over_end, HEAD); - - opo->start = frag_start; - opo->end = frag_end; - - update_lock(opo->lp, X_WAIT); - } - - return 0; -} - -/* go through r->locks to find what needs to be done to extend, - shrink, shift, split, etc existing locks (this often involves adding new - locks in addition to modifying existing locks. */ - -static int plock_internal(struct dlm_resource *r, unsigned long owner, - unsigned int pid, int wait, int ex, uint64_t start, - uint64_t end) -{ - LIST_HEAD(exist); - struct posix_lock *po, *safe, *case4_po = NULL; - int error = 0; - - list_for_each_entry_safe(po, safe, &r->locks, list) { - if (po->owner != owner) - continue; - if (!ranges_overlap(po->start, po->end, start, end)) - continue; - - /* existing range (RE) overlaps new range (RN) */ - - switch(overlap_type(start, end, po->start, po->end)) { - - case 0: - if (po->ex == ex) - goto out; - - /* ranges the same - just update the existing lock */ - po->ex = ex; - update_lock(po->lp, wait); - goto out; - - case 1: - if (po->ex == ex) - goto out; - - error = lock_case1(po, r, owner, pid, wait, ex, start, end); - goto out; - - case 2: - if (po->ex == ex) - goto out; - - error = lock_case2(po, r, owner, pid, wait, ex, start, end); - goto out; - - case 3: - list_move_tail(&po->list, &exist); - break; - - case 4: - DLM_ASSERT(!case4_po, ); - case4_po = po; - list_move_tail(&po->list, &exist); - break; - - default: - error = -1; - goto out; - } - } - - if (case4_po) - error = lock_case4(case4_po, &exist, r, owner, pid, wait, ex, - start, end); - else if (!list_empty(&exist)) - error = lock_case3(&exist, r, owner, pid, wait, ex, start, end); - else - add_lock(r, owner, pid, wait, ex, start, end, 0); - - out: - return error; -} - -static int punlock_internal(struct dlm_resource *r, unsigned long owner, - unsigned int pid, uint64_t start, uint64_t end) -{ - struct posix_lock *po, *safe; - int error = 0; - - list_for_each_entry_safe(po, safe, &r->locks, list) { - if (po->owner != owner) - continue; - if (po->busy) - continue; - if (!ranges_overlap(po->start, po->end, start, end)) - continue; - - /* existing range (RE) overlaps new range (RN) */ - - switch(overlap_type(start, end, po->start, po->end)) { - - case 0: - /* ranges the same - just remove the existing lock */ - - list_del(&po->list); - remove_lock(po->lp); - goto out; - - case 1: - /* RN within RE and starts or ends on RE boundary - - * shrink and update RE */ - - shrink_range(po, start, end); - update_lock(po->lp, X_WAIT); - goto out; - - case 2: - /* RN within RE - shrink and update RE to be front - * fragment, and add a new lock for back fragment */ - - add_lock(r, owner, pid, po->ex ? WAIT : X_WAIT, po->ex, - end+1, po->end, HEAD); - - po->end = start - 1; - update_lock(po->lp, X_WAIT); - goto out; - - case 3: - /* RE within RN - remove RE, then continue checking - * because RN could cover other locks */ - - list_del(&po->list); - remove_lock(po->lp); - continue; - - case 4: - /* front of RE in RN, or end of RE in RN - shrink and - * update RE, then continue because RN could cover - * other locks */ - - shrink_range(po, start, end); - update_lock(po->lp, X_WAIT); - continue; - - default: - error = -1; - goto out; - } - } - - out: - return error; -} - -static int wait_local(struct dlm_resource *r, unsigned long owner, - uint64_t start, uint64_t end, int ex) -{ - DECLARE_WAITQUEUE(wait, current); - int error = 0; - - add_wait_queue(&r->waiters, &wait); - - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - - if (!local_conflict(r->dlm, r, &r->name, owner, start, end, ex)) - break; - - if (signal_pending(current)) { - up(&r->sema); - error = -EINTR; - break; - } - - up(&r->sema); - schedule(); - down(&r->sema); - } - - remove_wait_queue(&r->waiters, &wait); - set_current_state(TASK_RUNNING); - return error; -} - -int lm_dlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl) -{ - dlm_t *dlm = (dlm_t *) lockspace; - unsigned long owner = (unsigned long) fl->fl_owner; - unsigned int pid = fl->fl_pid; - int wait = IS_SETLKW(cmd); - int ex = (fl->fl_type == F_WRLCK); - uint64_t start = fl->fl_start, end = fl->fl_end; - struct dlm_resource *r; - int error; - - log_debug("en plock %x,%"PRIx64"", name->ln_type, name->ln_number); - - error = get_resource(dlm, name, CREATE, &r); - if (error) - goto out; - - error = down_interruptible(&r->sema); - if (error) - goto out_put; - - /* We wait here until we aren't blocked by any other local locks. - Then we can request the lock from the dlm, request the vfs lock - (without it blocking) and release r->sema before waiting on the dlm - request. [We can't release the semaphore between the dlm and vfs - requests, but we must release it before waiting for the ast.] */ - - error = local_conflict(dlm, r, name, owner, start, end, ex); - if (error) { - if (!wait) { - error = -EAGAIN; - goto out_up; - } - error = wait_local(r, owner, start, end, ex); - if (error) - goto out_put; - /* wait_local returns with r->sema held if no error */ - } - - error = lock_resource(r); - if (error) - goto out_up; - - if (!wait && global_conflict(dlm, name, owner, start, end, ex)) { - error = -EAGAIN; - unlock_resource(r); - goto out_up; - } - - /* If NO_WAIT all requests should return immediately. - If WAIT all requests go on r->async_locks which we wait on in - wait_async_locks(). This means DLM should not return -EAGAIN and we - should never block waiting for a plock to be released until we call - wait_async_list(). */ - - error = plock_internal(r, owner, pid, wait, ex, start, end); - unlock_resource(r); - - if (!error) { - /* this won't block due to wait_local above and not yet - having released r->sema */ - if (posix_lock_file_wait(file, fl) < 0) - log_error("lm_dlm_plock: vfs lock error %x,%"PRIx64"", - name->ln_type, name->ln_number); - } - - out_up: - up(&r->sema); - wait_async_list(r, owner); - wake_up_all(&r->waiters); - out_put: - put_resource(r); - out: - log_debug("ex plock %d", error); - return error; -} - -int lm_dlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - dlm_t *dlm = (dlm_t *) lockspace; - unsigned long owner = (unsigned long) fl->fl_owner; - unsigned int pid = fl->fl_pid; - uint64_t start = fl->fl_start, end = fl->fl_end; - struct dlm_resource *r; - int error; - - log_debug("en punlock %x,%"PRIx64"", name->ln_type, name->ln_number); - - error = get_resource(dlm, name, NO_CREATE, &r); - if (error) { - if (error == -ENOENT) - error = 0; - goto out; - } - - down(&r->sema); - - if (posix_lock_file_wait(file, fl) < 0) - log_error("lm_dlm_punlock: vfs unlock error %x,%"PRIx64"", - name->ln_type, name->ln_number); - - error = lock_resource(r); - if (error) - goto out_up; - - error = punlock_internal(r, owner, pid, start, end); - unlock_resource(r); - - out_up: - up(&r->sema); - wait_async_list(r, owner); - wake_up_all(&r->waiters); - put_resource(r); - out: - log_debug("ex punlock %d", error); - return error; -} - -static void query_ast(void *astargs) -{ - dlm_lock_t *lp = (dlm_lock_t *) astargs;; - complete(&lp->uast_wait); -} - -static int get_global_conflict(dlm_t *dlm, struct lm_lockname *name, - unsigned long owner, uint64_t *start, - uint64_t *end, int *ex, unsigned long *rowner, - unsigned int *rpid) -{ - dlm_lock_t *lp; - struct dlm_queryinfo qinfo; - struct dlm_lockinfo *lki; - int query = 0, s = 0, error; - - /* acquire a null lock on which to base the query */ - - lp = find_null_lock(dlm, name); - if (!lp) { - error = create_lp(dlm, name, &lp); - if (error) - goto ret; - - lp->req = DLM_LOCK_NL; - lp->lkf = DLM_LKF_EXPEDITE; - set_bit(LFL_INLOCK, &lp->flags); - do_dlm_lock_sync(lp, NULL); - } - - /* do query, repeating if insufficient space */ - - query = DLM_LOCK_THIS | DLM_QUERY_QUEUE_GRANTED | - DLM_QUERY_LOCKS_HIGHER; - - do { - s += 16; - lki = kzalloc(s * sizeof(struct dlm_lockinfo), GFP_KERNEL); - if (!lki) { - error = -ENOMEM; - goto out; - } - memset(&qinfo, 0, sizeof(qinfo)); - qinfo.gqi_locksize = s; - qinfo.gqi_lockinfo = lki; - - init_completion(&lp->uast_wait); - error = dlm_query(dlm->gdlm_lsp, &lp->lksb, query, &qinfo, - query_ast, (void *) lp); - if (error) { - kfree(lki); - goto out; - } - wait_for_completion(&lp->uast_wait); - error = lp->lksb.sb_status; - - if (!error) - break; - kfree(lki); - if (error != -E2BIG) - goto out; - } while (error == -E2BIG && s < lock_dlm_max_plock_get); - - /* check query results for blocking locks */ - - if (error) { - error = -EAGAIN; - goto out; - } - - for (s = 0; s < qinfo.gqi_lockcount; s++) { - - lki = &qinfo.gqi_lockinfo[s]; - - if (!ranges_overlap(*start, *end, lki->lki_grrange.ra_start, - lki->lki_grrange.ra_end)) - continue; - - if (lki->lki_node == dlm->our_nodeid) - continue; - - if (lki->lki_grmode == DLM_LOCK_EX || *ex) { - *start = lki->lki_grrange.ra_start; - *end = lki->lki_grrange.ra_end; - *ex = (lki->lki_grmode == DLM_LOCK_EX) ? 1 : 0; - *rowner = lki->lki_node; - *rpid = lki->lki_node; /* nodeid for pid as well */ - error = -EAGAIN; - break; - } - } - - kfree(qinfo.gqi_lockinfo); - - log_debug("global conflict %d %"PRIx64"-%"PRIx64" ex %d own %lu, pid %du", - error, *start, *end, *ex, *rowner, *rpid); - out: - keep_null_lock(dlm, lp); - ret: - return error; -} - -static int get_local_conflict(dlm_t *dlm, struct dlm_resource *r, - struct lm_lockname *name, unsigned long owner, - uint64_t *start, uint64_t *end, int *ex, - unsigned long *rowner, unsigned int *rpid) -{ - struct posix_lock *po; - int found = FALSE; - - list_for_each_entry(po, &r->locks, list) { - if (po->owner == owner) { - if (!po->busy) - continue; - log_debug("po busy %llx %llu %u", - (unsigned long long)name->ln_number, - (unsigned long long)owner, po->pid); - found = TRUE; - break; - } - if (!ranges_overlap(po->start, po->end, *start, *end)) - continue; - - if (*ex || po->ex) { - *start = po->start; - *end = po->end; - *ex = po->ex; - *rowner = po->owner; - *rpid = po->pid; - found = TRUE; - break; - } - } - return found; -} - -static int do_plock_get(dlm_t *dlm, struct lm_lockname *name, - unsigned long owner, uint64_t *start, uint64_t *end, - int *ex, unsigned long *rowner, unsigned int *rpid) -{ - struct dlm_resource *r; - int error, found; - - error = get_resource(dlm, name, NO_CREATE, &r); - if (!error) { - error = down_interruptible(&r->sema); - if (error) { - put_resource(r); - goto out; - } - - found = get_local_conflict(dlm, r, name, owner, start, end, ex, - rowner, rpid); - up(&r->sema); - put_resource(r); - if (found) { - error = 1; - goto out; - } - } - - error = get_global_conflict(dlm, name, owner, start, end, ex, rowner, rpid); - if (error == -EAGAIN) { - log_debug("pl get global conflict %"PRIx64"-%"PRIx64" %d %lu %du", - *start, *end, *ex, *rowner, *rpid); - error = 1; - } - out: - return error; -} - -static int local_conflict(dlm_t *dlm, struct dlm_resource *r, - struct lm_lockname *name, unsigned long owner, - uint64_t start, uint64_t end, int ex) -{ - uint64_t get_start = start, get_end = end; - unsigned long get_owner = 0; - unsigned int get_pid = 0; - int get_ex = ex; - - return get_local_conflict(dlm, r, name, owner, &get_start, &get_end, - &get_ex, &get_owner, &get_pid); -} - -static int global_conflict(dlm_t *dlm, struct lm_lockname *name, - unsigned long owner, uint64_t start, uint64_t end, - int ex) -{ - uint64_t get_start = start, get_end = end; - unsigned long get_owner = 0; - unsigned int get_pid = 0; - int get_ex = ex; - - return get_global_conflict(dlm, name, owner, &get_start, &get_end, - &get_ex, &get_owner, &get_pid); -} - -int lm_dlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - dlm_t *dlm = (dlm_t *) lockspace; - unsigned long owner; - unsigned int pid; - int ex, error; - - ex = (fl->fl_type == F_WRLCK) ? 1 : 0; - - error = do_plock_get(dlm, name, fl->fl_owner, &fl->fl_start, - &fl->fl_end, &ex, &owner, &pid); - if (error < 0) - return error; - if (error == 0) - fl->fl_type = F_UNLCK; - else { - fl->fl_type = (ex) ? F_WRLCK : F_RDLCK; - fl->fl_pid = pid; - } - - return 0; -} diff --git a/gfs-kernel/src/dlm/thread.c b/gfs-kernel/src/dlm/thread.c deleted file mode 100644 index 14282fc..0000000 --- a/gfs-kernel/src/dlm/thread.c +++ /dev/null @@ -1,448 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "lock_dlm.h" - -extern int lock_dlm_drop_count; - -/* - * Run in dlm_async thread - */ - -/** - * queue_submit - add lock request to queue for dlm_async thread - * @lp: DLM lock - * - * A lock placed on this queue is re-submitted to DLM as soon as - * dlm_async thread gets to it. - */ - -static void queue_submit(dlm_lock_t *lp) -{ - dlm_t *dlm = lp->dlm; - - spin_lock(&dlm->async_lock); - list_add_tail(&lp->slist, &dlm->submit); - set_bit(LFL_SLIST, &lp->flags); - spin_unlock(&dlm->async_lock); - wake_up(&dlm->wait); -} - -/** - * process_blocking - processing of blocking callback - * @lp: DLM lock - * - */ - -static void process_blocking(dlm_lock_t *lp, int bast_mode) -{ - dlm_t *dlm = lp->dlm; - unsigned int cb; - - switch (make_lmstate(bast_mode)) { - case LM_ST_EXCLUSIVE: - cb = LM_CB_NEED_E; - break; - case LM_ST_DEFERRED: - cb = LM_CB_NEED_D; - break; - case LM_ST_SHARED: - cb = LM_CB_NEED_S; - break; - default: - DLM_ASSERT(0, printk("unknown bast mode %u\n", lp->bast_mode);); - } - - dlm->fscb(dlm->fsdata, cb, &lp->lockname); -} - -/** - * process_complete - processing of completion callback for a lock request - * @lp: DLM lock - * - */ - -static void process_complete(dlm_lock_t *lp) -{ - dlm_t *dlm = lp->dlm; - struct lm_async_cb acb; - int16_t prev_mode = lp->cur; - - memset(&acb, 0, sizeof(acb)); - - if (lp->lksb.sb_status == -DLM_ECANCEL) { - log_all("complete dlm cancel %x,%"PRIx64" flags %lx", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->flags); - - lp->req = lp->cur; - acb.lc_ret |= LM_OUT_CANCELED; - if (lp->cur == DLM_LOCK_IV) - lp->lksb.sb_lkid = 0; - goto out; - } - - if (test_and_clear_bit(LFL_DLM_UNLOCK, &lp->flags)) { - if (lp->lksb.sb_status != -DLM_EUNLOCK) { - log_all("unlock sb_status %d %x,%"PRIx64" flags %lx", - lp->lksb.sb_status, lp->lockname.ln_type, - lp->lockname.ln_number, lp->flags); - return; - } - - lp->cur = DLM_LOCK_IV; - lp->req = DLM_LOCK_IV; - lp->lksb.sb_lkid = 0; - atomic_dec(&dlm->lock_count); - - if (test_and_clear_bit(LFL_UNLOCK_SYNC, &lp->flags)) { - complete(&lp->uast_wait); - return; - } - if (test_and_clear_bit(LFL_UNLOCK_DELETE, &lp->flags)) { - delete_lp(lp); - return; - } - goto out; - } - - if (lp->lksb.sb_flags & DLM_SBF_VALNOTVALID) { - if (lp->lksb.sb_lvbptr) - memset(lp->lksb.sb_lvbptr, 0, DLM_LVB_LEN); - else - log_all("no lvb for VALNOTVALID lkid %x", - lp->lksb.sb_lkid); - } - - if (lp->lksb.sb_flags & DLM_SBF_ALTMODE) { - if (lp->req == DLM_LOCK_PR) - lp->req = DLM_LOCK_CW; - else if (lp->req == DLM_LOCK_CW) - lp->req = DLM_LOCK_PR; - } - - /* - * A canceled lock request. The lock was just taken off the delayed - * list and was never even submitted to dlm. - */ - - if (test_and_clear_bit(LFL_CANCEL, &lp->flags)) { - log_all("complete internal cancel %x,%"PRIx64"", - lp->lockname.ln_type, lp->lockname.ln_number); - lp->req = lp->cur; - acb.lc_ret |= LM_OUT_CANCELED; - goto out; - } - - /* - * An error occured. - */ - - if (lp->lksb.sb_status) { - /* a "normal" error */ - if ((lp->lksb.sb_status == -EAGAIN) && - (lp->lkf & DLM_LKF_NOQUEUE)) { - lp->req = lp->cur; - if (lp->cur == DLM_LOCK_IV) - lp->lksb.sb_lkid = 0; - goto out; - } - - /* this could only happen with cancels I think */ - log_all("ast sb_status %d %x,%"PRIx64" flags %lx", - lp->lksb.sb_status, lp->lockname.ln_type, - lp->lockname.ln_number, lp->flags); - return; - } - - /* - * This is an AST for an EX->EX conversion for sync_lvb from GFS. - */ - - if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { - complete(&lp->uast_wait); - return; - } - - /* - * A lock has been demoted to NL because it initially completed during - * BLOCK_LOCKS. Now it must be requested in the originally requested - * mode. - */ - - if (test_and_clear_bit(LFL_REREQUEST, &lp->flags)) { - - DLM_ASSERT(lp->req == DLM_LOCK_NL,); - DLM_ASSERT(lp->prev_req > DLM_LOCK_NL,); - - lp->cur = DLM_LOCK_NL; - lp->req = lp->prev_req; - lp->prev_req = DLM_LOCK_IV; - lp->lkf &= ~DLM_LKF_CONVDEADLK; - - set_bit(LFL_NOCACHE, &lp->flags); - - if (test_bit(DFL_BLOCK_LOCKS, &dlm->flags) && - !test_bit(LFL_NOBLOCK, &lp->flags)) - queue_delayed(lp, QUEUE_LOCKS_BLOCKED); - else - queue_submit(lp); - return; - } - - /* - * A request is granted during dlm recovery. It may be granted - * because the locks of a failed node were cleared. In that case, - * there may be inconsistent data beneath this lock and we must wait - * for recovery to complete to use it. When gfs recovery is done this - * granted lock will be converted to NL and then reacquired in this - * granted state. - */ - - if (test_bit(DFL_BLOCK_LOCKS, &dlm->flags) && - !test_bit(LFL_NOBLOCK, &lp->flags) && - lp->req != DLM_LOCK_NL) { - - lp->cur = lp->req; - lp->prev_req = lp->req; - lp->req = DLM_LOCK_NL; - lp->lkf |= DLM_LKF_CONVERT; - lp->lkf &= ~DLM_LKF_CONVDEADLK; - - log_debug("rereq %x,%"PRIx64" id %x %d,%d", - lp->lockname.ln_type, lp->lockname.ln_number, - lp->lksb.sb_lkid, lp->cur, lp->req); - - set_bit(LFL_REREQUEST, &lp->flags); - queue_submit(lp); - return; - } - - /* - * DLM demoted the lock to NL before it was granted so GFS must be - * told it cannot cache data for this lock. - */ - - if (lp->lksb.sb_flags & DLM_SBF_DEMOTED) - set_bit(LFL_NOCACHE, &lp->flags); - - out: - - /* - * This is an internal lock_dlm lock (for jid's or plock's) - */ - - if (test_bit(LFL_INLOCK, &lp->flags)) { - clear_bit(LFL_NOBLOCK, &lp->flags); - lp->cur = lp->req; - complete(&lp->uast_wait); - return; - } - - /* - * Normal completion of a lock request. Tell GFS it now has the lock. - */ - - clear_bit(LFL_NOBLOCK, &lp->flags); - lp->cur = lp->req; - - acb.lc_name = lp->lockname; - acb.lc_ret |= make_lmstate(lp->cur); - - if (!test_and_clear_bit(LFL_NOCACHE, &lp->flags) && - (lp->cur > DLM_LOCK_NL) && (prev_mode > DLM_LOCK_NL)) - acb.lc_ret |= LM_OUT_CACHEABLE; - - if (prev_mode == DLM_LOCK_IV && lp->cur > DLM_LOCK_IV) - atomic_inc(&dlm->lock_count); - - dlm->fscb(dlm->fsdata, LM_CB_ASYNC, &acb); -} - -/** - * no_work - determine if there's work for the dlm_async thread - * @dlm: - * - * Returns: 1 if no work, 0 otherwise - */ - -static __inline__ int no_work(dlm_t *dlm) -{ - int ret; - - spin_lock(&dlm->async_lock); - - ret = list_empty(&dlm->complete) && - list_empty(&dlm->blocking) && - list_empty(&dlm->submit) && - list_empty(&dlm->starts) && !test_bit(DFL_MG_FINISH, &dlm->flags); - - spin_unlock(&dlm->async_lock); - - return ret; -} - -static __inline__ int check_drop(dlm_t *dlm) -{ - if (!dlm->drop_locks_count) - return FALSE; - - if (check_timeout(dlm->drop_time, dlm->drop_locks_period)) { - dlm->drop_time = jiffies; - dlm->drop_locks_count = lock_dlm_drop_count; - if (!dlm->drop_locks_count) - return FALSE; - if (atomic_read(&dlm->lock_count) >= dlm->drop_locks_count) - return TRUE; - } - return FALSE; -} - -static __inline__ int check_shrink(dlm_t *dlm) -{ - if (check_timeout(dlm->shrink_time, SHRINK_CACHE_TIME)){ - dlm->shrink_time = jiffies; - return TRUE; - } - return FALSE; -} - -/** - * dlm_async - thread for a variety of asynchronous processing - * @data: - * - * Returns: 0 on success, -EXXX on failure - */ - -static int dlm_async(void *data) -{ - dlm_t *dlm = (dlm_t *) data; - dlm_lock_t *lp = NULL; - dlm_start_t *ds = NULL; - uint8_t complete, blocking, submit, start, finish, drop, shrink; - - while (!kthread_should_stop()) { - wait_event_interruptible(dlm->wait, - !no_work(dlm) || kthread_should_stop()); - - complete = blocking = submit = start = finish = 0; - drop = shrink = 0; - - spin_lock(&dlm->async_lock); - - if (!list_empty(&dlm->complete)) { - lp = list_entry(dlm->complete.next, dlm_lock_t, clist); - list_del(&lp->clist); - clear_bit(LFL_CLIST, &lp->flags); - complete = 1; - } else if (!list_empty(&dlm->blocking)) { - lp = list_entry(dlm->blocking.next, dlm_lock_t, blist); - list_del(&lp->blist); - clear_bit(LFL_BLIST, &lp->flags); - blocking = lp->bast_mode; - lp->bast_mode = 0; - } else if (!list_empty(&dlm->submit)) { - lp = list_entry(dlm->submit.next, dlm_lock_t, slist); - list_del(&lp->slist); - clear_bit(LFL_SLIST, &lp->flags); - submit = 1; - } else if (!test_bit(DFL_RECOVER, &dlm->flags) && - !list_empty(&dlm->starts)) { - ds = list_entry(dlm->starts.next, dlm_start_t, list); - list_del(&ds->list); - set_bit(DFL_RECOVER, &dlm->flags); - start = 1; - } else if (test_and_clear_bit(DFL_MG_FINISH, &dlm->flags)) { - finish = 1; - } - - /* Don't get busy doing this stuff during recovery. */ - if (!test_bit(DFL_RECOVER, &dlm->flags)) { - drop = check_drop(dlm); - shrink = check_shrink(dlm); - } - spin_unlock(&dlm->async_lock); - - /* once withdrawn don't call into gfs for anything */ - if (test_bit(DFL_WITHDRAW, &dlm->flags)) - complete = blocking = drop = shrink = 0; - - if (complete) - process_complete(lp); - - else if (blocking) - process_blocking(lp, blocking); - - else if (submit) - process_submit(lp); - - else if (start) - process_start(dlm, ds); - - else if (finish) - process_finish(dlm); - - if (drop) - dlm->fscb(dlm->fsdata, LM_CB_DROPLOCKS, NULL); - if (shrink) - shrink_null_cache(dlm); - - schedule(); - } - - return 0; -} - -/** - * init_async_thread - * @dlm: - * - * Returns: 0 on success, -EXXX on failure - */ - -int init_async_thread(dlm_t *dlm) -{ - struct task_struct *p; - int error; - - p = kthread_run(dlm_async, dlm, "lock_dlm1"); - error = IS_ERR(p); - if (error) { - log_all("can't start lock_dlm1 daemon %d", error); - return error; - } - dlm->thread1 = p; - - p = kthread_run(dlm_async, dlm, "lock_dlm2"); - error = IS_ERR(p); - if (error) { - log_all("can't start lock_dlm2 daemon %d", error); - kthread_stop(dlm->thread1); - return error; - } - dlm->thread2 = p; - - return 0; -} - -/** - * release_async_thread - * @dlm: - * - */ - -void release_async_thread(dlm_t *dlm) -{ - kthread_stop(dlm->thread1); - kthread_stop(dlm->thread2); -} diff --git a/gfs-kernel/src/gfs/Makefile b/gfs-kernel/src/gfs/Makefile deleted file mode 100644 index 468cbe6..0000000 --- a/gfs-kernel/src/gfs/Makefile +++ /dev/null @@ -1,109 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = ../.. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/src/linux-orig -linux_patched = ${top_srcdir}/src/linux-patched - -PWD := $(shell pwd) - -TARGET = gfs.patch -SYMVERFILE := ${PWD}/../gulm/lock_gulm.symvers - - -obj-m := gfs.o -gfs-objs := acl.o \ - bits.o \ - bmap.o \ - daemon.o \ - diaper.o \ - dio.o \ - dir.o \ - eaops.o \ - eattr.o \ - file.o \ - glock.o \ - glops.o \ - inode.o \ - ioctl.o \ - lm.o \ - log.o \ - lops.o \ - lvb.o \ - main.o \ - mount.o \ - ondisk.o \ - ops_address.o \ - ops_dentry.o \ - ops_export.o \ - ops_file.o \ - ops_fstype.o \ - ops_inode.o \ - ops_super.o \ - ops_vm.o \ - page.o \ - proc.o \ - quota.o \ - recovery.o \ - rgrp.o \ - super.o \ - trans.o \ - unlinked.o \ - util.o - -EXTRA_CFLAGS += -I$(obj) -I/usr/include - -all: - rm -f linux lm_interface.h - ln -s . linux - ln -s ${top_srcdir}/src/harness/lm_interface.h . - ${MAKE} -C ${KERNEL_SRC} M=${PWD} symverfile=${SYMVERFILE} modules USING_KBUILD=yes - -install: all - install -d ${module_dir}/fs/gfs - install gfs.ko ${module_dir}/fs/gfs - install -d ${incdir}/linux - install gfs_ondisk.h gfs_ioctl.h ${incdir}/linux - -uninstall: - ${UNINSTALL} gfs.ko ${module_dir}/fs/gfs - ${UNINSTALL} gfs_ondisk.h gfs_ioctl.h ${incdir}/linux - -clean: - rm -rf linux *.o .*.o.cmd .gfs.ko.cmd lm_interface.h \ - gfs.ko gfs.mod.c .tmp_versions *~ - - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir}/src ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/fs/gfs - cp *.[ch] ${linux_patched}/fs/gfs - mv ${linux_patched}/fs/gfs/gfs_*.h ${linux_patched}/include/linux - diff --git a/gfs-kernel/src/gfs/acl.c b/gfs-kernel/src/gfs/acl.c deleted file mode 100644 index 3376d97..0000000 --- a/gfs-kernel/src/gfs/acl.c +++ /dev/null @@ -1,383 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/posix_acl.h> -#include <linux/posix_acl_xattr.h> -#include <linux/xattr_acl.h> - -#include "gfs.h" -#include "acl.h" -#include "eattr.h" -#include "inode.h" - -/** - * gfs_acl_validate_set - - * @ip: - * @access: - * @er: - * @mode: - * @remove: - * - * Returns: errno - */ - -int -gfs_acl_validate_set(struct gfs_inode *ip, int access, - struct gfs_ea_request *er, - int *remove, mode_t *mode) -{ - struct posix_acl *acl; - int error; - - error = gfs_acl_validate_remove(ip, access); - if (error) - return error; - - if (!er->er_data) - return -EINVAL; - - acl = posix_acl_from_xattr(er->er_data, er->er_data_len); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (!acl) { - *remove = TRUE; - return 0; - } - - error = posix_acl_valid(acl); - if (error) - goto out; - - if (access) { - error = posix_acl_equiv_mode(acl, mode); - if (!error) - *remove = TRUE; - else - error = 0; - } - - out: - posix_acl_release(acl); - - return error; -} - -/** - * gfs_acl_validate_remove - - * @ip: - * @access: - * - * Returns: errno - */ - -int -gfs_acl_validate_remove(struct gfs_inode *ip, int access) -{ - if (!ip->i_sbd->sd_args.ar_posix_acls) - return -EOPNOTSUPP; - if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER)) - return -EPERM; - if (ip->i_di.di_type == GFS_FILE_LNK) - return -EOPNOTSUPP; - if (!access && ip->i_di.di_type != GFS_FILE_DIR) - return -EACCES; - - return 0; -} - -/** - * gfs_acl_get - - * @ip: - * @access: - * @acl: - * - * Returns: errno - */ - -int -gfs_acl_get(struct gfs_inode *ip, int access, struct posix_acl **acl) -{ - struct gfs_ea_request er; - struct gfs_ea_location el; - int error; - - if (!ip->i_di.di_eattr) - return 0; - - memset(&er, 0, sizeof(struct gfs_ea_request)); - if (access) { - er.er_name = GFS_POSIX_ACL_ACCESS; - er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; - } else { - er.er_name = GFS_POSIX_ACL_DEFAULT; - er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; - } - er.er_type = GFS_EATYPE_SYS; - - error = gfs_ea_find(ip, &er, &el); - if (error) - return error; - if (!el.el_ea) - return 0; - if (!GFS_EA_DATA_LEN(el.el_ea)) - goto out; - - er.er_data = kmalloc(GFS_EA_DATA_LEN(el.el_ea), GFP_KERNEL); - error = -ENOMEM; - if (!er.er_data) - goto out; - - error = gfs_ea_get_copy(ip, &el, er.er_data); - if (error) - goto out_kfree; - - *acl = posix_acl_from_xattr(er.er_data, GFS_EA_DATA_LEN(el.el_ea)); - if (IS_ERR(*acl)) - error = PTR_ERR(*acl); - - out_kfree: - kfree(er.er_data); - - out: - brelse(el.el_bh); - - return error; -} - -/** - * gfs_acl_new_prep - - * @dip: - * @type: - * @mode: - * @a_acl: - * @d_acl: - * @blocks: - * @data: - * - * Returns: errno - */ - -int -gfs_acl_new_prep(struct gfs_inode *dip, - unsigned int type, mode_t *mode, - void **a_data, void **d_data, - unsigned int *size, - unsigned int *blocks) -{ - struct posix_acl *acl = NULL; - int set_a = FALSE, set_d = FALSE; - int error; - - if (!dip->i_sbd->sd_args.ar_posix_acls) - return 0; - if (type == GFS_FILE_LNK) - return 0; - - error = gfs_acl_get(dip, FALSE, &acl); - if (error) - return error; - if (!acl) { - (*mode) &= ~current->fs->umask; - return 0; - } - - { - struct posix_acl *clone = posix_acl_clone(acl, GFP_KERNEL); - error = -ENOMEM; - if (!clone) - goto out; - posix_acl_release(acl); - acl = clone; - } - - error = posix_acl_create_masq(acl, mode); - if (error < 0) - goto out; - if (error > 0) { - set_a = TRUE; - error = 0; - } - if (type == GFS_FILE_DIR) - set_d = TRUE; - - if (set_a || set_d) { - struct gfs_ea_request er; - void *d; - unsigned int s = posix_acl_xattr_size(acl->a_count); - unsigned int b; - - memset(&er, 0, sizeof(struct gfs_ea_request)); - er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; - er.er_data_len = s; - error = gfs_ea_check_size(dip->i_sbd, &er); - if (error) - goto out; - - b = DIV_RU(er.er_data_len, dip->i_sbd->sd_jbsize); - if (set_a && set_d) - b *= 2; - b++; - - d = kmalloc(s, GFP_KERNEL); - error = -ENOMEM; - if (!d) - goto out; - posix_acl_to_xattr(acl, d, s); - - if (set_a) - *a_data = d; - if (set_d) - *d_data = d; - *size = s; - *blocks = b; - - error = 0; - } - - out: - posix_acl_release(acl); - - return error; -} - -/** - * gfs_acl_new_init - - * @dip: - * @ip: - * @a_data: - * @d_data: - * @size: - * - * Returns: errno - */ - -int gfs_acl_new_init(struct gfs_inode *dip, struct gfs_inode *ip, - void *a_data, void *d_data, unsigned int size) -{ - void *data = (a_data) ? a_data : d_data; - unsigned int x; - int error = 0; - - ip->i_alloc = dip->i_alloc; /* Cheesy, but it works. */ - - for (x = 0; x < 2; x++) { - struct gfs_ea_request er; - - memset(&er, 0, sizeof(struct gfs_ea_request)); - if (x) { - if (!a_data) - continue; - er.er_name = GFS_POSIX_ACL_ACCESS; - er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; - } else { - if (!d_data) - continue; - er.er_name = GFS_POSIX_ACL_DEFAULT; - er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; - } - er.er_data = data; - er.er_data_len = size; - er.er_type = GFS_EATYPE_SYS; - - error = gfs_ea_acl_init(ip, &er); - if (error) - break; - } - - ip->i_alloc = NULL; - - kfree(data); - - return error; -} - -/** - * gfs_acl_chmod - - * @ip: - * @attr: - * - * Returns: errno - */ - -int -gfs_acl_chmod(struct gfs_inode *ip, struct iattr *attr) -{ - struct gfs_ea_request er; - struct gfs_ea_location el; - struct posix_acl *acl; - int error; - - if (!ip->i_di.di_eattr) - goto simple; - - memset(&er, 0, sizeof(struct gfs_ea_request)); - er.er_name = GFS_POSIX_ACL_ACCESS; - er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; - er.er_type = GFS_EATYPE_SYS; - - error = gfs_ea_find(ip, &er, &el); - if (error) - return error; - if (!el.el_ea) - goto simple; - if (!GFS_EA_DATA_LEN(el.el_ea)) - goto simple; - - er.er_data = kmalloc(GFS_EA_DATA_LEN(el.el_ea), GFP_KERNEL); - error = -ENOMEM; - if (!er.er_data) - goto out; - - error = gfs_ea_get_copy(ip, &el, er.er_data); - if (error) - goto out_kfree; - - acl = posix_acl_from_xattr(er.er_data, GFS_EA_DATA_LEN(el.el_ea)); - if (IS_ERR(acl)) { - error = PTR_ERR(acl); - goto out_kfree; - } else if (!acl) { - kfree(er.er_data); - brelse(el.el_bh); - goto simple; - } - - error = posix_acl_chmod_masq(acl, attr->ia_mode); - if (error) - goto out_acl; - - posix_acl_to_xattr(acl, er.er_data, GFS_EA_DATA_LEN(el.el_ea)); - - error = gfs_ea_acl_chmod(ip, &el, attr, er.er_data); - - out_acl: - posix_acl_release(acl); - - out_kfree: - kfree(er.er_data); - - out: - brelse(el.el_bh); - - return error; - - simple: - return gfs_setattr_simple(ip, attr); -} diff --git a/gfs-kernel/src/gfs/acl.h b/gfs-kernel/src/gfs/acl.h deleted file mode 100644 index 612fc7c..0000000 --- a/gfs-kernel/src/gfs/acl.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __ACL_DOT_H__ -#define __ACL_DOT_H__ - -#define GFS_POSIX_ACL_ACCESS "posix_acl_access" -#define GFS_POSIX_ACL_ACCESS_LEN (16) -#define GFS_POSIX_ACL_DEFAULT "posix_acl_default" -#define GFS_POSIX_ACL_DEFAULT_LEN (17) - -#define GFS_ACL_IS_ACCESS(name, len) \ - ((len) == GFS_POSIX_ACL_ACCESS_LEN && \ - !memcmp(GFS_POSIX_ACL_ACCESS, (name), (len))) - -#define GFS_ACL_IS_DEFAULT(name, len) \ - ((len) == GFS_POSIX_ACL_DEFAULT_LEN && \ - !memcmp(GFS_POSIX_ACL_DEFAULT, (name), (len))) - -struct gfs_ea_request; - -int gfs_acl_validate_set(struct gfs_inode *ip, int access, - struct gfs_ea_request *er, - int *remove, mode_t *mode); -int gfs_acl_validate_remove(struct gfs_inode *ip, int access); -int gfs_acl_get(struct gfs_inode *ip, int access, struct posix_acl **acl); -int gfs_acl_new_prep(struct gfs_inode *dip, - unsigned int type, mode_t *mode, - void **a_data, void **d_data, - unsigned int *size, - unsigned int *blocks); -int gfs_acl_new_init(struct gfs_inode *dip, struct gfs_inode *ip, - void *a_data, void *d_data, unsigned int size); -int gfs_acl_chmod(struct gfs_inode *ip, struct iattr *attr); - -#endif /* __ACL_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/bits.c b/gfs-kernel/src/gfs/bits.c deleted file mode 100644 index a82d821..0000000 --- a/gfs-kernel/src/gfs/bits.c +++ /dev/null @@ -1,189 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * These routines are used by the resource group routines (rgrp.c) - * to keep track of block allocation. Each block is represented by two - * bits. One bit indicates whether or not the block is used. (1=used, - * 0=free) The other bit indicates whether or not the block contains a - * dinode or not. (1=dinode, 0=data block) So, each byte represents - * GFS_NBBY (i.e. 4) blocks. - */ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "bits.h" - -static const char valid_change[16] = { - /* current */ - /* n */ 0, 1, 1, 1, - /* e */ 1, 0, 0, 0, - /* w */ 1, 0, 0, 1, - 0, 0, 1, 0 -}; - -/** - * gfs_setbit - Set a bit in the bitmaps - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @block: the block to set - * @new_state: the new state of the block - * - */ - -void -gfs_setbit(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - uint32_t block, unsigned char new_state) -{ - unsigned char *byte, *end, cur_state; - unsigned int bit; - - byte = buffer + (block / GFS_NBBY); - bit = (block % GFS_NBBY) * GFS_BIT_SIZE; - end = buffer + buflen; - - gfs_assert(rgd->rd_sbd, byte < end,); - - cur_state = (*byte >> bit) & GFS_BIT_MASK; - - if (valid_change[new_state * 4 + cur_state]) { - *byte ^= cur_state << bit; - *byte |= new_state << bit; - } else - gfs_consist_rgrpd(rgd); -} - -/** - * gfs_testbit - test a bit in the bitmaps - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @block: the block to read - * - */ - -unsigned char -gfs_testbit(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, uint32_t block) -{ - unsigned char *byte, *end, cur_state; - unsigned int bit; - - byte = buffer + (block / GFS_NBBY); - bit = (block % GFS_NBBY) * GFS_BIT_SIZE; - end = buffer + buflen; - - gfs_assert(rgd->rd_sbd, byte < end,); - - cur_state = (*byte >> bit) & GFS_BIT_MASK; - - return cur_state; -} - -/** - * gfs_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing - * a block in a given allocation state. - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @goal: start search at this block's bit-pair (within @buffer) - * @old_state: GFS_BLKST_XXX the state of the block we're looking for; - * bit 0 = alloc(1)/free(0), bit 1 = meta(1)/data(0) - * - * Scope of @goal and returned block number is only within this bitmap buffer, - * not entire rgrp or filesystem. - * @buffer will be offset from the actual beginning of a bitmap block buffer, - * skipping any header structures. - * - * Return: the block number (bitmap buffer scope) that was found - */ - -uint32_t -gfs_bitfit(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - uint32_t goal, unsigned char old_state) -{ - unsigned char *byte, *end, alloc; - uint32_t blk = goal; - unsigned int bit; - - byte = buffer + (goal / GFS_NBBY); - bit = (goal % GFS_NBBY) * GFS_BIT_SIZE; - end = buffer + buflen; - alloc = (old_state & 1) ? 0 : 0x55; - - while (byte < end) { - if ((*byte & 0x55) == alloc) { - blk += (8 - bit) >> 1; - - bit = 0; - byte++; - - continue; - } - - if (((*byte >> bit) & GFS_BIT_MASK) == old_state) - return blk; - - bit += GFS_BIT_SIZE; - if (bit >= 8) { - bit = 0; - byte++; - } - - blk++; - } - - return BFITNOENT; -} - -/** - * gfs_bitcount - count the number of bits in a certain state - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @state: the state of the block we're looking for - * - * Returns: The number of bits - */ - -uint32_t -gfs_bitcount(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - unsigned char state) -{ - unsigned char *byte = buffer; - unsigned char *end = buffer + buflen; - unsigned char state1 = state << 2; - unsigned char state2 = state << 4; - unsigned char state3 = state << 6; - uint32_t count = 0; - - for (; byte < end; byte++) { - if (((*byte) & 0x03) == state) - count++; - if (((*byte) & 0x0C) == state1) - count++; - if (((*byte) & 0x30) == state2) - count++; - if (((*byte) & 0xC0) == state3) - count++; - } - - return count; -} diff --git a/gfs-kernel/src/gfs/bits.h b/gfs-kernel/src/gfs/bits.h deleted file mode 100644 index a1e63a0..0000000 --- a/gfs-kernel/src/gfs/bits.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __BITS_DOT_H__ -#define __BITS_DOT_H__ - -#define BFITNOENT (0xFFFFFFFF) - -void gfs_setbit(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - uint32_t block, unsigned char new_state); -unsigned char gfs_testbit(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - uint32_t block); -uint32_t gfs_bitfit(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - uint32_t goal, unsigned char old_state); -uint32_t gfs_bitcount(struct gfs_rgrpd *rgd, - unsigned char *buffer, unsigned int buflen, - unsigned char state); - -#endif /* __BITS_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/bmap.c b/gfs-kernel/src/gfs/bmap.c deleted file mode 100644 index f614b49..0000000 --- a/gfs-kernel/src/gfs/bmap.c +++ /dev/null @@ -1,1406 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "bmap.h" -#include "dio.h" -#include "glock.h" -#include "inode.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" - -struct metapath { - unsigned int mp_list[GFS_MAX_META_HEIGHT]; -}; - -typedef int (*block_call_t) (struct gfs_inode *ip, struct buffer_head *dibh, - struct buffer_head *bh, uint64_t *top, - uint64_t *bottom, unsigned int height, - void *data); - -struct strip_mine { - int sm_first; - unsigned int sm_height; -}; - -/** - * gfs_unstuffer_sync - unstuff a dinode synchronously - * @ip: the inode - * @dibh: the dinode buffer - * @block: the block number that was allocated - * @private: not used - * - * Returns: errno - */ - -int -gfs_unstuffer_sync(struct gfs_inode *ip, struct buffer_head *dibh, - uint64_t block, void *private) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh; - int error; - - error = gfs_get_data_buffer(ip, block, TRUE, &bh); - if (error) - return error; - - gfs_buffer_copy_tail(bh, 0, dibh, sizeof(struct gfs_dinode)); - - error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); - - brelse(bh); - - return error; -} - -/** - * gfs_unstuffer_async - unstuff a dinode asynchronously - * @ip: the inode - * @dibh: the dinode buffer - * @block: the block number that was allocated - * @private: not used - * - * Returns: errno - */ - -int -gfs_unstuffer_async(struct gfs_inode *ip, struct buffer_head *dibh, - uint64_t block, void *private) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh; - int error; - - error = gfs_get_data_buffer(ip, block, TRUE, &bh); - if (error) - return error; - - gfs_buffer_copy_tail(bh, 0, dibh, sizeof(struct gfs_dinode)); - - error = gfs_dwrite(sdp, bh, DIO_DIRTY); - - brelse(bh); - - return error; -} - -/** - * gfs_unstuff_dinode - Unstuff a dinode when the data has grown too big - * @ip: The GFS inode to unstuff - * @unstuffer: the routine that handles unstuffing a non-zero length file - * @private: private data for the unstuffer - * - * This routine unstuffs a dinode and returns it to a "normal" state such - * that the height can be grown in the traditional way. - * - * Returns: errno - */ - -int -gfs_unstuff_dinode(struct gfs_inode *ip, gfs_unstuffer_t unstuffer, - void *private) -{ - struct buffer_head *bh, *dibh; - uint64_t block = 0; - int journaled = gfs_is_jdata(ip); - int error; - - down_write(&ip->i_rw_mutex); - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto out; - - if (ip->i_di.di_size) { - /* Get a free block, fill it with the stuffed data, - and write it out to disk */ - - if (journaled) { - error = gfs_metaalloc(ip, &block); - if (error) - goto out_brelse; - - error = gfs_get_data_buffer(ip, block, TRUE, &bh); - if (error) - goto out_brelse; - - gfs_buffer_copy_tail(bh, sizeof(struct gfs_meta_header), - dibh, sizeof(struct gfs_dinode)); - - brelse(bh); - } else { - gfs_blkalloc(ip, &block); - - error = unstuffer(ip, dibh, block, private); - if (error) - goto out_brelse; - } - } - - /* Set up the pointer to the new block */ - - gfs_trans_add_bh(ip->i_gl, dibh); - - gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); - - if (ip->i_di.di_size) { - *(uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)) = cpu_to_gfs64(block); - ip->i_di.di_blocks++; - } - - ip->i_di.di_height = 1; - - gfs_dinode_out(&ip->i_di, dibh->b_data); - - out_brelse: - brelse(dibh); - - out: - up_write(&ip->i_rw_mutex); - - return error; -} - -/** - * calc_tree_height - Calculate the height of a metadata tree - * @ip: The GFS inode - * @size: The proposed size of the file - * - * Work out how tall a metadata tree needs to be in order to accommodate a - * file of a particular size. If size is less than the current size of - * the inode, then the current size of the inode is used instead of the - * supplied one. - * - * Returns: the height the tree should be - */ - -static unsigned int -calc_tree_height(struct gfs_inode *ip, uint64_t size) -{ - struct gfs_sbd *sdp = ip->i_sbd; - uint64_t *arr; - unsigned int max, height; - - if (ip->i_di.di_size > size) - size = ip->i_di.di_size; - - if (gfs_is_jdata(ip)) { - arr = sdp->sd_jheightsize; - max = sdp->sd_max_jheight; - } else { - arr = sdp->sd_heightsize; - max = sdp->sd_max_height; - } - - for (height = 0; height < max; height++) - if (arr[height] >= size) - break; - - return height; -} - -/** - * build_height - Build a metadata tree of the requested height - * @ip: The GFS inode - * @height: The height to build to - * - * This routine makes sure that the metadata tree is tall enough to hold - * "size" bytes of data. - * - * Returns: errno - */ - -static int -build_height(struct gfs_inode *ip, int height) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh, *dibh; - uint64_t block, *bp; - unsigned int x; - int new_block; - int error; - - while (ip->i_di.di_height < height) { - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - return error; - - new_block = FALSE; - bp = (uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)); - for (x = 0; x < sdp->sd_diptrs; x++, bp++) - if (*bp) { - new_block = TRUE; - break; - } - - if (new_block) { - /* Get a new block, fill it with the old direct pointers, - and write it out */ - - error = gfs_metaalloc(ip, &block); - if (error) - goto fail; - - error = gfs_dread(ip->i_gl, block, - DIO_NEW | DIO_START | DIO_WAIT, &bh); - if (error) - goto fail; - - gfs_trans_add_bh(ip->i_gl, bh); - gfs_metatype_set(bh, - GFS_METATYPE_IN, - GFS_FORMAT_IN); - memset(bh->b_data + sizeof(struct gfs_meta_header), - 0, - sizeof(struct gfs_indirect) - - sizeof(struct gfs_meta_header)); - gfs_buffer_copy_tail(bh, sizeof(struct gfs_indirect), - dibh, sizeof(struct gfs_dinode)); - - brelse(bh); - } - - /* Set up the new direct pointer and write it out to disk */ - - gfs_trans_add_bh(ip->i_gl, dibh); - - gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); - - if (new_block) { - *(uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)) = cpu_to_gfs64(block); - ip->i_di.di_blocks++; - } - - ip->i_di.di_height++; - - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - return 0; - - fail: - brelse(dibh); - - return error; -} - -/** - * find_metapath - Find path through the metadata tree - * @ip: The inode pointer - * @mp: The metapath to return the result in - * @block: The disk block to look up - * - * This routine returns a struct metapath structure that defines a path through - * the metadata of inode "ip" to get to block "block". - * - * Example: - * Given: "ip" is a height 3 file, "offset" is 101342453, and this is a - * filesystem with a blocksize of 4096. - * - * find_metapath() would return a struct metapath structure set to: - * mp_offset = 101342453, mp_height = 3, mp_list[0] = 0, mp_list[1] = 48, - * and mp_list[2] = 165. - * - * That means that in order to get to the block containing the byte at - * offset 101342453, we would load the indirect block pointed to by pointer - * 0 in the dinode. We would then load the indirect block pointed to by - * pointer 48 in that indirect block. We would then load the data block - * pointed to by pointer 165 in that indirect block. - * - * ---------------------------------------- - * | Dinode | | - * | | 4| - * | |0 1 2 3 4 5 9| - * | | 6| - * ---------------------------------------- - * | - * | - * V - * ---------------------------------------- - * | Indirect Block | - * | 5| - * | 4 4 4 4 4 5 5 1| - * |0 5 6 7 8 9 0 1 2| - * ---------------------------------------- - * | - * | - * V - * ---------------------------------------- - * | Indirect Block | - * | 1 1 1 1 1 5| - * | 6 6 6 6 6 1| - * |0 3 4 5 6 7 2| - * ---------------------------------------- - * | - * | - * V - * ---------------------------------------- - * | Data block containing offset | - * | 101342453 | - * | | - * | | - * ---------------------------------------- - * - */ - -static struct metapath * -find_metapath(struct gfs_inode *ip, uint64_t block) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct metapath *mp; - uint64_t b = block; - unsigned int i; - - mp = gmalloc(sizeof(struct metapath)); - memset(mp, 0, sizeof(struct metapath)); - - for (i = ip->i_di.di_height; i--;) - mp->mp_list[i] = do_div(b, sdp->sd_inptrs); - - return mp; -} - -/** - * metapointer - Return pointer to start of metadata in a buffer - * @bh: The buffer - * @height: The metadata height (0 = dinode) - * @mp: The metapath - * - * Return a pointer to the block number of the next height of the metadata - * tree given a buffer containing the pointer to the current height of the - * metadata tree. - */ - -static __inline__ uint64_t * -metapointer(struct buffer_head *bh, unsigned int height, struct metapath *mp) -{ - unsigned int head_size = (height > 0) ? - sizeof(struct gfs_indirect) : sizeof(struct gfs_dinode); - - return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height]; -} - -/** - * get_metablock - Get the next metadata block in metadata tree - * @ip: The GFS inode - * @bh: Buffer containing the pointers to metadata blocks - * @height: The height of the tree (0 = dinode) - * @mp: The metapath - * @create: Non-zero if we may create a new meatdata block - * @new: Used to indicate if we did create a new metadata block - * @block: the returned disk block number - * - * Given a metatree, complete to a particular height, checks to see if the next - * height of the tree exists. If not the next height of the tree is created. - * The block number of the next height of the metadata tree is returned. - * - * Returns: errno - */ - -static int -get_metablock(struct gfs_inode *ip, - struct buffer_head *bh, unsigned int height, struct metapath *mp, - int create, int *new, uint64_t *block) -{ - uint64_t *ptr = metapointer(bh, height, mp); - int error; - - if (*ptr) { - *block = gfs64_to_cpu(*ptr); - return 0; - } - - *block = 0; - - if (!create) - return 0; - - error = gfs_metaalloc(ip, block); - if (error) - return error; - - gfs_trans_add_bh(ip->i_gl, bh); - - *ptr = cpu_to_gfs64(*block); - ip->i_di.di_blocks++; - - *new = 1; - - return 0; -} - -/** - * get_datablock - Get datablock number from metadata block - * @ip: The GFS inode - * @bh: The buffer containing pointers to datablocks - * @mp: The metapath - * @create: Non-zero if we may create a new data block - * @new: Used to indicate if we created a new data block - * @block: the returned disk block number - * - * Given a fully built metadata tree, checks to see if a particular data - * block exists. It is created if it does not exist and the block number - * on disk is returned. - * - * Returns: errno - */ - -static int -get_datablock(struct gfs_inode *ip, - struct buffer_head *bh, struct metapath *mp, - int create, int *new, uint64_t *block) -{ - uint64_t *ptr = metapointer(bh, ip->i_di.di_height - 1, mp); - - if (*ptr) { - *block = gfs64_to_cpu(*ptr); - return 0; - } - - *block = 0; - - if (!create) - return 0; - - if (gfs_is_jdata(ip)) { - int error; - error = gfs_metaalloc(ip, block); - if (error) - return error; - } else - gfs_blkalloc(ip, block); - - gfs_trans_add_bh(ip->i_gl, bh); - - *ptr = cpu_to_gfs64(*block); - ip->i_di.di_blocks++; - - *new = 1; - - return 0; -} - -/** - * gfs_block_map - Map a block from an inode to a disk block - * @ip: The GFS inode - * @lblock: The logical block number - * @new: Value/Result argument (1 = may create/did create new blocks) - * @dblock: the disk block number of the start of an extent - * @extlen: the size of the extent - * - * Find the block number on the current device which corresponds to an - * inode's block. If the block had to be created, "new" will be set. - * - * Returns: errno - */ - -int -gfs_block_map(struct gfs_inode *ip, - uint64_t lblock, int *new, - uint64_t *dblock, uint32_t *extlen) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh; - struct metapath *mp; - int create = *new; - unsigned int bsize; - unsigned int height; - unsigned int end_of_metadata; - unsigned int x; - int error = 0; - - *new = 0; - *dblock = 0; - if (extlen) - *extlen = 0; - - if (create) - down_write(&ip->i_rw_mutex); - else - down_read(&ip->i_rw_mutex); - - if (gfs_assert_warn(sdp, !gfs_is_stuffed(ip))) - goto out; - - bsize = (gfs_is_jdata(ip)) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; - - height = calc_tree_height(ip, (lblock + 1) * bsize); - if (ip->i_di.di_height < height) { - if (!create) - goto out; - - error = build_height(ip, height); - if (error) - goto out; - } - - mp = find_metapath(ip, lblock); - end_of_metadata = ip->i_di.di_height - 1; - - error = gfs_get_inode_buffer(ip, &bh); - if (error) - goto out_kfree; - - for (x = 0; x < end_of_metadata; x++) { - error = get_metablock(ip, bh, x, mp, create, new, dblock); - brelse(bh); - if (error || !*dblock) - goto out_kfree; - - error = gfs_get_meta_buffer(ip, x + 1, *dblock, *new, &bh); - if (error) - goto out_kfree; - } - - error = get_datablock(ip, bh, mp, create, new, dblock); - if (error) { - brelse(bh); - goto out_kfree; - } - - if (extlen && *dblock) { - *extlen = 1; - - if (!*new) { - uint64_t tmp_dblock; - int tmp_new; - unsigned int nptrs; - - nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs; - - while (++mp->mp_list[end_of_metadata] < nptrs) { - get_datablock(ip, bh, mp, - FALSE, &tmp_new, - &tmp_dblock); - - if (*dblock + *extlen != tmp_dblock) - break; - - (*extlen)++; - } - } - } - - brelse(bh); - - if (*new) { - error = gfs_get_inode_buffer(ip, &bh); - if (!error) { - gfs_trans_add_bh(ip->i_gl, bh); - gfs_dinode_out(&ip->i_di, bh->b_data); - brelse(bh); - } - } - - out_kfree: - kfree(mp); - - out: - if (create) - up_write(&ip->i_rw_mutex); - else - up_read(&ip->i_rw_mutex); - - return error; -} - -/** - * do_grow - Make a file look bigger than it is - * @ip: the inode - * @size: the size to set the file to - * - * Called with an exclusive lock on @ip. - * - * Returns: errno - */ - -static int -do_grow(struct gfs_inode *ip, uint64_t size) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al; - struct buffer_head *dibh; - unsigned int h; - int journaled = gfs_is_jdata(ip); - int error; - - al = gfs_alloc_get(ip); - - error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out; - - error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); - if (error) - goto out_gunlock_q; - - if (journaled) - al->al_requested_meta = sdp->sd_max_height + 1; - else { - al->al_requested_meta = sdp->sd_max_height; - al->al_requested_data = 1; - } - - error = gfs_inplace_reserve(ip); - if (error) - goto out_gunlock_q; - - /* Trans may require: - Full extention of the metadata tree, block allocation, - a dinode modification, and a quota change */ - - error = gfs_trans_begin(sdp, - sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + - 1 + !!journaled, - 1); - if (error) - goto out_ipres; - - if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { - if (gfs_is_stuffed(ip)) { - error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); - if (error) - goto out_end_trans; - } - - h = calc_tree_height(ip, size); - if (ip->i_di.di_height < h) { - down_write(&ip->i_rw_mutex); - error = build_height(ip, h); - up_write(&ip->i_rw_mutex); - if (error) - goto out_end_trans; - } - } - - ip->i_di.di_size = size; - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto out_end_trans; - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - out_end_trans: - gfs_trans_end(sdp); - - out_ipres: - gfs_inplace_release(ip); - - out_gunlock_q: - gfs_quota_unlock_m(ip); - - out: - gfs_alloc_put(ip); - - return error; -} - -/** - * recursive_scan - recursively scan through the end of a file - * @ip: the inode - * @dibh: the dinode buffer - * @mp: the path through the metadata to the point to start - * @height: the height the recursion is at - * @block: the indirect block to look at - * @first: TRUE if this is the first block - * @bc: the call to make for each piece of metadata - * @data: data opaque to this function to pass to @bc - * - * When this is first called @height and @block should be zero and - * @first should be TRUE. - * - * Returns: errno - */ - -static int -recursive_scan(struct gfs_inode *ip, struct buffer_head *dibh, - struct metapath *mp, unsigned int height, uint64_t block, - int first, block_call_t bc, void *data) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh = NULL; - uint64_t *top, *bottom; - uint64_t bn; - int error; - - if (!height) { - error = gfs_get_inode_buffer(ip, &bh); - if (error) - goto fail; - dibh = bh; - - top = (uint64_t *)(bh->b_data + sizeof(struct gfs_dinode)) + - mp->mp_list[0]; - bottom = (uint64_t *)(bh->b_data + sizeof(struct gfs_dinode)) + - sdp->sd_diptrs; - } else { - error = gfs_get_meta_buffer(ip, height, block, FALSE, &bh); - if (error) - goto fail; - - top = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)) + - ((first) ? mp->mp_list[height] : 0); - bottom = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)) + - sdp->sd_inptrs; - } - - error = bc(ip, dibh, bh, top, bottom, height, data); - if (error) - goto fail; - - if (height < ip->i_di.di_height - 1) - for (; top < bottom; top++, first = FALSE) { - if (!*top) - continue; - - bn = gfs64_to_cpu(*top); - - error = recursive_scan(ip, dibh, mp, - height + 1, bn, first, - bc, data); - if (error) - goto fail; - } - - brelse(bh); - - return 0; - - fail: - if (bh) - brelse(bh); - - return error; -} - -/** - * do_strip - Look for a layer a particular layer of the file and strip it off - * @ip: the inode - * @dibh: the dinode buffer - * @bh: A buffer of pointers - * @top: The first pointer in the buffer - * @bottom: One more than the last pointer - * @height: the height this buffer is at - * @data: a pointer to a struct strip_mine - * - * Returns: errno - */ - -static int -do_strip(struct gfs_inode *ip, struct buffer_head *dibh, - struct buffer_head *bh, uint64_t *top, uint64_t *bottom, - unsigned int height, void *data) -{ - struct strip_mine *sm = (struct strip_mine *)data; - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrp_list rlist; - uint64_t bn, bstart; - uint32_t blen; - uint64_t *p; - unsigned int rg_blocks = 0; - int metadata; - int x; - int error; - - if (!*top) - sm->sm_first = FALSE; - - if (height != sm->sm_height) - return 0; - - if (sm->sm_first) { - top++; - sm->sm_first = FALSE; - } - - metadata = (height != ip->i_di.di_height - 1) || gfs_is_jdata(ip); - - error = gfs_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); - if (error) - return error; - - memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); - bstart = 0; - blen = 0; - - for (p = top; p < bottom; p++) { - if (!*p) - continue; - - bn = gfs64_to_cpu(*p); - - if (bstart + blen == bn) - blen++; - else { - if (bstart) - gfs_rlist_add(sdp, &rlist, bstart); - - bstart = bn; - blen = 1; - } - } - - if (bstart) - gfs_rlist_add(sdp, &rlist, bstart); - else - goto out; /* Nothing to do */ - - gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); - - for (x = 0; x < rlist.rl_rgrps; x++) { - struct gfs_rgrpd *rgd; - rgd = gl2rgd(rlist.rl_ghs[x].gh_gl); - rg_blocks += rgd->rd_ri.ri_length; - } - - error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); - if (error) - goto out_rlist; - - /* Trans may require: - All the bitmaps that were reserved. - One block for the dinode. - One block for the indirect block being cleared. - One block for a quota change. */ - - error = gfs_trans_begin(sdp, rg_blocks + 2, 1); - if (error) - goto out_rg_gunlock; - - down_write(&ip->i_rw_mutex); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_trans_add_bh(ip->i_gl, bh); - - bstart = 0; - blen = 0; - - for (p = top; p < bottom; p++) { - if (!*p) - continue; - - bn = gfs64_to_cpu(*p); - - if (bstart + blen == bn) - blen++; - else { - if (bstart) { - if (metadata) - gfs_metafree(ip, bstart, blen); - else - gfs_blkfree(ip, bstart, blen); - } - - bstart = bn; - blen = 1; - } - - *p = 0; - if (!ip->i_di.di_blocks) - gfs_consist_inode(ip); - ip->i_di.di_blocks--; - } - if (bstart) { - if (metadata) - gfs_metafree(ip, bstart, blen); - else - gfs_blkfree(ip, bstart, blen); - } - - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - gfs_dinode_out(&ip->i_di, dibh->b_data); - - up_write(&ip->i_rw_mutex); - - gfs_trans_end(sdp); - - out_rg_gunlock: - gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); - - out_rlist: - gfs_rlist_free(&rlist); - - out: - gfs_glock_dq_uninit(&ip->i_alloc->al_ri_gh); - - return error; -} - -/** - * gfs_truncator_default - truncate a partial data block - * @ip: the inode - * @size: the size the file should be - * - * Returns: errno - */ - -int -gfs_truncator_default(struct gfs_inode *ip, uint64_t size) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh; - uint64_t bn; - int not_new = 0; - int error; - - error = gfs_block_map(ip, size >> sdp->sd_sb.sb_bsize_shift, ¬_new, - &bn, NULL); - if (error) - return error; - if (!bn) - return 0; - - error = gfs_get_data_buffer(ip, bn, FALSE, &bh); - if (error) - return error; - - gfs_buffer_clear_tail(bh, size & (sdp->sd_sb.sb_bsize - 1)); - - error = gfs_dwrite(sdp, bh, DIO_DIRTY); - - brelse(bh); - - return error; -} - -/** - * truncator_journaled - truncate a partial data block - * @ip: the inode - * @size: the size the file should be - * - * Returns: errno - */ - -static int -truncator_journaled(struct gfs_inode *ip, uint64_t size) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh; - uint64_t lbn, dbn; - uint32_t off; - int not_new = 0; - int error; - - lbn = size; - off = do_div(lbn, sdp->sd_jbsize); - - error = gfs_block_map(ip, lbn, ¬_new, &dbn, NULL); - if (error) - return error; - if (!dbn) - return 0; - - error = gfs_trans_begin(sdp, 1, 0); - if (error) - return error; - - error = gfs_get_data_buffer(ip, dbn, FALSE, &bh); - if (!error) { - gfs_trans_add_bh(ip->i_gl, bh); - gfs_buffer_clear_tail(bh, - sizeof(struct gfs_meta_header) + - off); - brelse(bh); - } - - gfs_trans_end(sdp); - - return error; -} - -/** - * gfs_shrink - make a file smaller - * @ip: the inode - * @size: the size to make the file - * @truncator: function to truncate the last partial block - * - * Called with an exclusive lock on @ip. - * - * Returns: errno - */ - -int -gfs_shrink(struct gfs_inode *ip, uint64_t size, gfs_truncator_t truncator) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_holder ri_gh; - struct gfs_rgrpd *rgd; - struct buffer_head *dibh; - uint64_t block; - unsigned int height; - int journaled = gfs_is_jdata(ip); - int error; - - if (!size) - block = 0; - else if (journaled) { - block = size - 1; - do_div(block, sdp->sd_jbsize); - } - else - block = (size - 1) >> sdp->sd_sb.sb_bsize_shift; - - /* Get rid of all the data/metadata blocks */ - - height = ip->i_di.di_height; - if (height) { - struct metapath *mp = find_metapath(ip, block); - gfs_alloc_get(ip); - - error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) { - gfs_alloc_put(ip); - kfree(mp); - return error; - } - - while (height--) { - struct strip_mine sm; - - sm.sm_first = (size) ? TRUE : FALSE; - sm.sm_height = height; - - error = recursive_scan(ip, NULL, mp, 0, 0, TRUE, - do_strip, &sm); - if (error) { - gfs_quota_unhold_m(ip); - gfs_alloc_put(ip); - kfree(mp); - return error; - } - } - - gfs_quota_unhold_m(ip); - gfs_alloc_put(ip); - kfree(mp); - } - - /* If we truncated in the middle of a block, zero out the leftovers. */ - - if (gfs_is_stuffed(ip)) { - /* Do nothing */ - } else if (journaled) { - if (do_mod(size, sdp->sd_jbsize)) { - error = truncator_journaled(ip, size); - if (error) - return error; - } - } else if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1)) { - error = truncator(ip, size); - if (error) - return error; - } - - /* Set the new size (and possibly the height) */ - - if (!size) { - error = gfs_rindex_hold(sdp, &ri_gh); - if (error) - return error; - } - - error = gfs_trans_begin(sdp, 1, 0); - if (error) - goto out; - - down_write(&ip->i_rw_mutex); - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto out_end_trans; - - if (!size) { - ip->i_di.di_height = 0; - - rgd = gfs_blk2rgrpd(sdp, ip->i_num.no_addr); - if (!rgd) { - gfs_consist_inode(ip); - error = -EIO; - goto out_end_trans; - } - - ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; - ip->i_di.di_goal_dblk = - ip->i_di.di_goal_mblk = - ip->i_num.no_addr - rgd->rd_ri.ri_data1; - } - - ip->i_di.di_size = size; - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(ip->i_gl, dibh); - - if (!ip->i_di.di_height && - size < sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) - gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode) + size); - - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - out_end_trans: - up_write(&ip->i_rw_mutex); - - gfs_trans_end(sdp); - - out: - if (!size) - gfs_glock_dq_uninit(&ri_gh); - - return error; -} - -/** - * do_same - truncate to same size (update time stamps) - * @ip: - * - * Returns: errno - */ - -static int -do_same(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *dibh; - int error; - - error = gfs_trans_begin(sdp, 1, 0); - if (error) - return error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto out; - - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - - brelse(dibh); - - out: - gfs_trans_end(sdp); - - return error; -} - -/** - * gfs_truncatei - make a file a give size - * @ip: the inode - * @size: the size to make the file - * @truncator: function to truncate the last partial block - * - * The file size can grow, shrink, or stay the same size. - * - * Returns: errno - */ - -int -gfs_truncatei(struct gfs_inode *ip, uint64_t size, - gfs_truncator_t truncator) -{ - if (gfs_assert_warn(ip->i_sbd, ip->i_di.di_type == GFS_FILE_REG)) - return -EINVAL; - - if (size == ip->i_di.di_size) - return do_same(ip); - else if (size > ip->i_di.di_size) - return do_grow(ip, size); - else - return gfs_shrink(ip, size, truncator); -} - -/** - * gfs_write_calc_reserv - calculate the number of blocks needed to write to a file - * @ip: the file - * @len: the number of bytes to be written to the file - * @data_blocks: returns the number of data blocks required - * @ind_blocks: returns the number of indirect blocks required - * - */ - -void -gfs_write_calc_reserv(struct gfs_inode *ip, unsigned int len, - unsigned int *data_blocks, unsigned int *ind_blocks) -{ - struct gfs_sbd *sdp = ip->i_sbd; - unsigned int tmp; - - if (gfs_is_jdata(ip)) { - *data_blocks = DIV_RU(len, sdp->sd_jbsize) + 2; - *ind_blocks = 3 * (sdp->sd_max_jheight - 1); - } else { - *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3; - *ind_blocks = 3 * (sdp->sd_max_height - 1); - } - - for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) { - tmp = DIV_RU(tmp, sdp->sd_inptrs); - *ind_blocks += tmp; - } -} - -/** - * gfs_write_alloc_required - figure out if a write is going to require an allocation - * @ip: the file being written to - * @offset: the offset to write to - * @len: the number of bytes being written - * @alloc_required: the int is set to TRUE if an alloc is required, FALSE otherwise - * - * Returns: errno - */ - -int -gfs_write_alloc_required(struct gfs_inode *ip, - uint64_t offset, unsigned int len, - int *alloc_required) -{ - struct gfs_sbd *sdp = ip->i_sbd; - uint64_t lblock, lblock_stop, dblock; - uint32_t extlen; - int not_new = FALSE; - int error = 0; - - *alloc_required = FALSE; - - if (!len) - return 0; - - if (gfs_is_stuffed(ip)) { - if (offset + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) - *alloc_required = TRUE; - return 0; - } - - if (gfs_is_jdata(ip)) { - unsigned int bsize = sdp->sd_jbsize; - lblock = offset; - do_div(lblock, bsize); - lblock_stop = offset + len + bsize - 1; - do_div(lblock_stop, bsize); - } else { - unsigned int shift = sdp->sd_sb.sb_bsize_shift; - lblock = offset >> shift; - lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; - } - - for (; lblock < lblock_stop; lblock += extlen) { - error = gfs_block_map(ip, lblock, ¬_new, &dblock, &extlen); - if (error) - return error; - - if (!dblock) { - *alloc_required = TRUE; - return 0; - } - } - - return 0; -} - -/** - * do_gfm - Copy out the dinode/indirect blocks of a file - * @ip: the file - * @dibh: the dinode buffer - * @bh: the indirect buffer we're looking at - * @top: the first pointer in the block - * @bottom: one more than the last pointer in the block - * @height: the height the block is at - * @data: a pointer to a struct gfs_user_buffer structure - * - * If this is a journaled file, copy out the data too. - * - * Returns: errno - */ - -static int -do_gfm(struct gfs_inode *ip, struct buffer_head *dibh, - struct buffer_head *bh, uint64_t *top, uint64_t *bottom, - unsigned int height, void *data) -{ - struct gfs_user_buffer *ub = (struct gfs_user_buffer *)data; - int error; - - error = gfs_add_bh_to_ub(ub, bh); - if (error) - return error; - - if (ip->i_di.di_type != GFS_FILE_DIR || - height + 1 != ip->i_di.di_height) - return 0; - - for (; top < bottom; top++) - if (*top) { - struct buffer_head *data_bh; - - error = gfs_dread(ip->i_gl, gfs64_to_cpu(*top), - DIO_START | DIO_WAIT, - &data_bh); - if (error) - return error; - - error = gfs_add_bh_to_ub(ub, data_bh); - - brelse(data_bh); - - if (error) - return error; - } - - return 0; -} - -/** - * gfs_get_file_meta - return all the metadata for a file - * @ip: the file - * @ub: the structure representing the meta - * - * Returns: errno - */ - -int -gfs_get_file_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub) -{ - int error; - - if (gfs_is_stuffed(ip)) { - struct buffer_head *dibh; - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - error = gfs_add_bh_to_ub(ub, dibh); - brelse(dibh); - } - } else { - struct metapath *mp = find_metapath(ip, 0); - error = recursive_scan(ip, NULL, mp, 0, 0, TRUE, do_gfm, ub); - kfree(mp); - } - - return error; -} diff --git a/gfs-kernel/src/gfs/bmap.h b/gfs-kernel/src/gfs/bmap.h deleted file mode 100644 index c7b7385..0000000 --- a/gfs-kernel/src/gfs/bmap.h +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __BMAP_DOT_H__ -#define __BMAP_DOT_H__ - -typedef int (*gfs_unstuffer_t) (struct gfs_inode * ip, - struct buffer_head * dibh, uint64_t block, - void *private); - -int gfs_unstuffer_sync(struct gfs_inode *ip, struct buffer_head *dibh, - uint64_t block, void *private); -int gfs_unstuffer_async(struct gfs_inode *ip, struct buffer_head *dibh, - uint64_t block, void *private); - -int gfs_unstuff_dinode(struct gfs_inode *ip, gfs_unstuffer_t unstuffer, - void *private); - -int gfs_block_map(struct gfs_inode *ip, - uint64_t lblock, int *new, - uint64_t *dblock, uint32_t *extlen); - -typedef int (*gfs_truncator_t) (struct gfs_inode * ip, uint64_t size); - -int gfs_truncator_default(struct gfs_inode *ip, uint64_t size); - -int gfs_shrink(struct gfs_inode *ip, uint64_t size, gfs_truncator_t truncator); -int gfs_truncatei(struct gfs_inode *ip, uint64_t size, - gfs_truncator_t truncator); - -void gfs_write_calc_reserv(struct gfs_inode *ip, unsigned int len, - unsigned int *data_blocks, unsigned int *ind_blocks); -int gfs_write_alloc_required(struct gfs_inode *ip, uint64_t offset, - unsigned int len, int *alloc_required); - -int gfs_get_file_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); - -#endif /* __BMAP_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/daemon.c b/gfs-kernel/src/gfs/daemon.c deleted file mode 100644 index c9830ac..0000000 --- a/gfs-kernel/src/gfs/daemon.c +++ /dev/null @@ -1,286 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "daemon.h" -#include "glock.h" -#include "log.h" -#include "quota.h" -#include "recovery.h" -#include "super.h" -#include "unlinked.h" - -/** - * gfs_scand - Look for cached glocks and inodes to toss from memory - * @sdp: Pointer to GFS superblock - * - * One of these daemons runs, finding candidates to add to sd_reclaim_list. - * See gfs_glockd() - */ - -int -gfs_scand(void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)data; - - daemonize("gfs_scand"); - sdp->sd_scand_process = current; - set_bit(SDF_SCAND_RUN, &sdp->sd_flags); - complete(&sdp->sd_thread_completion); - - for (;;) { - gfs_scand_internal(sdp); - - if (!test_bit(SDF_SCAND_RUN, &sdp->sd_flags)) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(gfs_tune_get(sdp, gt_scand_secs) * HZ); - } - - down(&sdp->sd_thread_lock); - up(&sdp->sd_thread_lock); - - complete(&sdp->sd_thread_completion); - - return 0; -} - -/** - * gfs_glockd - Reclaim unused glock structures - * @sdp: Pointer to GFS superblock - * - * One or more of these daemons run, reclaiming glocks on sd_reclaim_list. - * sd_glockd_num says how many daemons are running now. - * Number of daemons can be set by user, with num_glockd mount option. - * See gfs_scand() - */ - -int -gfs_glockd(void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)data; - - daemonize("gfs_glockd"); - set_bit(SDF_GLOCKD_RUN, &sdp->sd_flags); - complete(&sdp->sd_thread_completion); - - for (;;) { - while (atomic_read(&sdp->sd_reclaim_count)) - gfs_reclaim_glock(sdp); - - if (!test_bit(SDF_GLOCKD_RUN, &sdp->sd_flags)) - break; - - { - DECLARE_WAITQUEUE(__wait_chan, current); - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&sdp->sd_reclaim_wchan, &__wait_chan); - if (!atomic_read(&sdp->sd_reclaim_count) - && test_bit(SDF_GLOCKD_RUN, &sdp->sd_flags)) - schedule(); - remove_wait_queue(&sdp->sd_reclaim_wchan, &__wait_chan); - set_current_state(TASK_RUNNING); - } - } - - complete(&sdp->sd_thread_completion); - - return 0; -} - -/** - * gfs_recoverd - Recover dead machine's journals - * @sdp: Pointer to GFS superblock - * - */ - -int -gfs_recoverd(void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)data; - - daemonize("gfs_recoverd"); - sdp->sd_recoverd_process = current; - set_bit(SDF_RECOVERD_RUN, &sdp->sd_flags); - complete(&sdp->sd_thread_completion); - - for (;;) { - gfs_check_journals(sdp); - - if (!test_bit(SDF_RECOVERD_RUN, &sdp->sd_flags)) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(gfs_tune_get(sdp, gt_recoverd_secs) * HZ); - } - - down(&sdp->sd_thread_lock); - up(&sdp->sd_thread_lock); - - complete(&sdp->sd_thread_completion); - - return 0; -} - -/** - * gfs_logd - Update log tail as Active Items get flushed to in-place blocks - * @sdp: Pointer to GFS superblock - * - * Also, periodically check to make sure that we're using the most recent - * journal index. - */ - -int -gfs_logd(void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)data; - struct gfs_holder ji_gh; - - daemonize("gfs_logd"); - sdp->sd_logd_process = current; - set_bit(SDF_LOGD_RUN, &sdp->sd_flags); - complete(&sdp->sd_thread_completion); - - for (;;) { - /* Advance the log tail */ - gfs_ail_empty(sdp); - - /* Check for latest journal index */ - if (time_after_eq(jiffies, - sdp->sd_jindex_refresh_time + - gfs_tune_get(sdp, gt_jindex_refresh_secs) * HZ)) { - if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags) && - !gfs_jindex_hold(sdp, &ji_gh)) - gfs_glock_dq_uninit(&ji_gh); - sdp->sd_jindex_refresh_time = jiffies; - } - - if (!test_bit(SDF_LOGD_RUN, &sdp->sd_flags)) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(gfs_tune_get(sdp, gt_logd_secs) * HZ); - } - - down(&sdp->sd_thread_lock); - up(&sdp->sd_thread_lock); - - complete(&sdp->sd_thread_completion); - - return 0; -} - -/** - * gfs_quotad - Write cached quota changes into the quota file - * @sdp: Pointer to GFS superblock - * - */ - -int -gfs_quotad(void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)data; - int error; - - daemonize("gfs_quotad"); - sdp->sd_quotad_process = current; - set_bit(SDF_QUOTAD_RUN, &sdp->sd_flags); - complete(&sdp->sd_thread_completion); - - for (;;) { - /* Update statfs file */ - if (gfs_tune_get(sdp, gt_statfs_fast) && - time_after_eq(jiffies, - sdp->sd_statfs_sync_time + - gfs_tune_get(sdp, gt_statfs_fast) * HZ)) { - error = gfs_statfs_sync(sdp); - if (error && - error != -EROFS && - !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - printk("GFS: fsid=%s: statfs: error = %d\n", - sdp->sd_fsname, error); - sdp->sd_statfs_sync_time = jiffies; - } - /* Update quota file */ - if (time_after_eq(jiffies, - sdp->sd_quota_sync_time + - gfs_tune_get(sdp, gt_quota_quantum) * HZ)) { - error = gfs_quota_sync(sdp); - if (error && - error != -EROFS && - !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - printk("GFS: fsid=%s: quotad: error = %d\n", - sdp->sd_fsname, error); - sdp->sd_quota_sync_time = jiffies; - } - - /* Clean up */ - gfs_quota_scan(sdp); - - if (!test_bit(SDF_QUOTAD_RUN, &sdp->sd_flags)) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(gfs_tune_get(sdp, gt_quotad_secs) * HZ); - } - - down(&sdp->sd_thread_lock); - up(&sdp->sd_thread_lock); - - complete(&sdp->sd_thread_completion); - - return 0; -} - -/** - * gfs_inoded - Deallocate unlinked inodes - * @sdp: Pointer to GFS superblock - * - */ - -int -gfs_inoded(void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)data; - - daemonize("gfs_inoded"); - sdp->sd_inoded_process = current; - set_bit(SDF_INODED_RUN, &sdp->sd_flags); - complete(&sdp->sd_thread_completion); - - for (;;) { - gfs_unlinked_dealloc(sdp); - - if (!test_bit(SDF_INODED_RUN, &sdp->sd_flags)) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(gfs_tune_get(sdp, gt_inoded_secs) * HZ); - } - - down(&sdp->sd_thread_lock); - up(&sdp->sd_thread_lock); - - complete(&sdp->sd_thread_completion); - - return 0; -} diff --git a/gfs-kernel/src/gfs/daemon.h b/gfs-kernel/src/gfs/daemon.h deleted file mode 100644 index 680eb41..0000000 --- a/gfs-kernel/src/gfs/daemon.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DAEMON_DOT_H__ -#define __DAEMON_DOT_H__ - -int gfs_scand(void *data); -int gfs_glockd(void *data); -int gfs_recoverd(void *data); -int gfs_logd(void *data); -int gfs_quotad(void *data); -int gfs_inoded(void *data); - -#endif /* __DAEMON_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/diaper.c b/gfs-kernel/src/gfs/diaper.c deleted file mode 100644 index e08aeae..0000000 --- a/gfs-kernel/src/gfs/diaper.c +++ /dev/null @@ -1,631 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/module.h> -#include <linux/blkdev.h> -#include <linux/idr.h> -#include <linux/mempool.h> - -#include "gfs.h" -#include "diaper.h" -#include "ops_fstype.h" - -struct diaper_holder { - struct list_head dh_list; - unsigned int dh_count; - - struct gendisk *dh_gendisk; - - struct block_device *dh_real; - struct block_device *dh_diaper; - - struct gfs_sbd *dh_sbd; - mempool_t *dh_mempool; - struct super_block *dh_dummy_sb; -}; - -struct bio_wrapper { - struct bio *bw_orig; - struct diaper_holder *bw_dh; -}; - -static int diaper_major = 0; -static LIST_HEAD(diaper_list); -static spinlock_t diaper_lock; -static DEFINE_IDR(diaper_idr); -kmem_cache_t *diaper_slab; - -/** - * diaper_open - - * @inode: - * @file: - * - * Don't allow these devices to be opened from userspace - * or from other kernel routines. They should only be opened - * from this file. - * - * Returns: -ENOSYS - */ - -static int -diaper_open(struct inode *inode, struct file *file) -{ - return -ENOSYS; -} - -static struct block_device_operations diaper_fops = { - .owner = THIS_MODULE, - .open = diaper_open, -}; - -/** - * diaper_end_io - Called at the end of a block I/O - * @bio: - * @bytes_done: - * @error: - * - * Returns: an integer thats usually discarded - */ - -static int -diaper_end_io(struct bio *bio, unsigned int bytes_done, int error) -{ - struct bio_wrapper *bw = (struct bio_wrapper *)bio->bi_private; - struct diaper_holder *dh = bw->bw_dh; - struct gfs_sbd *sdp = dh->dh_sbd; - - bio_endio(bw->bw_orig, bytes_done, error); - if (bio->bi_size) - return 1; - - atomic_dec(&sdp->sd_bio_outstanding); - bio_put(bio); - mempool_free(bw, dh->dh_mempool); - - return 0; -} - -/** - * diaper_make_request - - * @q: - * @bio: - * - * Returns: 0 - */ - -static int -diaper_make_request(request_queue_t *q, struct bio *bio) -{ - struct diaper_holder *dh = (struct diaper_holder *)q->queuedata; - struct gfs_sbd *sdp = dh->dh_sbd; - struct bio_wrapper *bw; - struct bio *bi; - - atomic_inc(&sdp->sd_bio_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { - atomic_dec(&sdp->sd_bio_outstanding); - bio_endio(bio, bio->bi_size, 0); - return 0; - } - if (bio_rw(bio) == WRITE) - atomic_add(bio->bi_size >> 9, &sdp->sd_bio_writes); - else - atomic_add(bio->bi_size >> 9, &sdp->sd_bio_reads); - - bw = mempool_alloc(dh->dh_mempool, GFP_NOIO); - bw->bw_orig = bio; - bw->bw_dh = dh; - - bi = bio_clone(bio, GFP_NOIO); - bi->bi_bdev = dh->dh_real; - bi->bi_end_io = diaper_end_io; - bi->bi_private = bw; - - generic_make_request(bi); - - return 0; -} - -/** - * minor_get - - * - * Returns: a unused minor number - */ - -static int -minor_get(void) -{ - int minor; - int error; - - for (;;) { - if (!idr_pre_get(&diaper_idr, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(&diaper_lock); - error = idr_get_new(&diaper_idr, NULL, &minor); - spin_unlock(&diaper_lock); - - if (!error) - break; - if (error != -EAGAIN) - return error; - } - - return minor; -} - -/** - * minor_put - Free a used minor number - * @minor: - * - */ - -static void -minor_put(int minor) -{ - spin_lock(&diaper_lock); - idr_remove(&diaper_idr, minor); - spin_unlock(&diaper_lock); -} - -/** - * gfs_dummy_write_super_lockfs - pass a freeze from the real device to the diaper - * @sb: the real device's dummy sb - * - */ - -static void -gfs_dummy_write_super_lockfs(struct super_block *sb) -{ - struct diaper_holder *dh = (struct diaper_holder *)sb->s_fs_info; - freeze_bdev(dh->dh_diaper); -} - -/** - * gfs_dummy_unlockfs - pass a thaw from the real device to the diaper - * @sb: the real device's dummy sb - * - */ - -static void -gfs_dummy_unlockfs(struct super_block *sb) -{ - struct diaper_holder *dh = (struct diaper_holder *)sb->s_fs_info; - thaw_bdev(dh->dh_diaper, dh->dh_sbd->sd_vfs); -} - -struct super_operations gfs_dummy_sops = { - .write_super_lockfs = gfs_dummy_write_super_lockfs, - .unlockfs = gfs_dummy_unlockfs, -}; - -/** - * gfs_dummy_sb - create a dummy superblock for the real device - * @dh: - * - * Returns: errno - */ - -static int -get_dummy_sb(struct diaper_holder *dh) -{ - struct block_device *real = dh->dh_real; - struct super_block *sb; - struct inode *inode; - int error; - - down(&real->bd_mount_sem); - sb = sget(&gfs_fs_type, gfs_test_bdev_super, gfs_set_bdev_super, real); - up(&real->bd_mount_sem); - if (IS_ERR(sb)) - return PTR_ERR(sb); - - error = -ENOMEM; - inode = new_inode(sb); - if (!inode) - goto fail; - - make_bad_inode(inode); - - sb->s_root = d_alloc_root(inode); - if (!sb->s_root) - goto fail_iput; - - sb->s_op = &gfs_dummy_sops; - sb->s_fs_info = dh; - - up_write(&sb->s_umount); - module_put(gfs_fs_type.owner); - - dh->dh_dummy_sb = sb; - - return 0; - - fail_iput: - iput(inode); - - fail: - up_write(&sb->s_umount); - deactivate_super(sb); - return error; -} - -static int -diaper_congested(void *congested_data, int bdi_bits) -{ - struct diaper_holder *dh = (struct diaper_holder *)congested_data; - request_queue_t *q = bdev_get_queue(dh->dh_real); - return bdi_congested(&q->backing_dev_info, bdi_bits); -} - -static void -diaper_unplug(request_queue_t *q) -{ - struct diaper_holder *dh = (struct diaper_holder *)q->queuedata; - request_queue_t *rq = bdev_get_queue(dh->dh_real); - - if (rq->unplug_fn) - rq->unplug_fn(rq); -} - -static int -diaper_flush(request_queue_t *q, struct gendisk *disk, - sector_t *error_sector) -{ - struct diaper_holder *dh = (struct diaper_holder *)q->queuedata; - request_queue_t *rq = bdev_get_queue(dh->dh_real); - int error = -EOPNOTSUPP; - - if (rq->issue_flush_fn) - error = rq->issue_flush_fn(rq, dh->dh_real->bd_disk, NULL); - - return error; -} - -/** - * diaper_get - Do the work of creating a diaper device - * @real: - * @flags: - * - * Returns: the diaper device or ERR_PTR() - */ - -static struct diaper_holder * -diaper_get(struct block_device *real, int flags) -{ - struct diaper_holder *dh; - struct gendisk *gd; - struct block_device *diaper; - unsigned int minor; - int error = -ENOMEM; - - minor = minor_get(); - if (minor < 0) - return ERR_PTR(error); - - dh = kmalloc(sizeof(struct diaper_holder), GFP_KERNEL); - if (!dh) - goto fail; - memset(dh, 0, sizeof(struct diaper_holder)); - - gd = alloc_disk(1); - if (!gd) - goto fail_kfree; - - gd->queue = blk_alloc_queue(GFP_KERNEL); - if (!gd->queue) - goto fail_gd; - - gd->queue->queuedata = dh; - gd->queue->backing_dev_info.congested_fn = diaper_congested; - gd->queue->backing_dev_info.congested_data = dh; - gd->queue->unplug_fn = diaper_unplug; - gd->queue->issue_flush_fn = diaper_flush; - blk_queue_make_request(gd->queue, diaper_make_request); - blk_queue_stack_limits(gd->queue, bdev_get_queue(real)); - if (bdev_get_queue(real)->merge_bvec_fn && - gd->queue->max_sectors > (PAGE_SIZE >> 9)) - blk_queue_max_sectors(gd->queue, PAGE_SIZE >> 9); - blk_queue_hardsect_size(gd->queue, bdev_hardsect_size(real)); - - gd->major = diaper_major; - gd->first_minor = minor; - { - char buf[BDEVNAME_SIZE]; - bdevname(real, buf); - snprintf(gd->disk_name, sizeof(gd->disk_name), "diapered_%s", buf); - } - gd->fops = &diaper_fops; - gd->private_data = dh; - gd->capacity--; - - add_disk(gd); - - diaper = bdget_disk(gd, 0); - if (!diaper) - goto fail_remove; - - down(&diaper->bd_sem); - if (!diaper->bd_openers) { - diaper->bd_disk = gd; - diaper->bd_contains = diaper; - bd_set_size(diaper, 0x7FFFFFFFFFFFFFFFULL); - diaper->bd_inode->i_data.backing_dev_info = &gd->queue->backing_dev_info; - } else - printk("GFS: diaper: reopening\n"); - - diaper->bd_openers++; - up(&diaper->bd_sem); - - dh->dh_mempool = mempool_create(512, - mempool_alloc_slab, mempool_free_slab, - diaper_slab); - if (!dh->dh_mempool) - goto fail_bdput; - - dh->dh_count = 1; - dh->dh_gendisk = gd; - dh->dh_real = real; - dh->dh_diaper = diaper; - - error = get_dummy_sb(dh); - if (error) - goto fail_mempool; - - return dh; - - fail_mempool: - mempool_destroy(dh->dh_mempool); - - fail_bdput: - down(&diaper->bd_sem); - if (!--diaper->bd_openers) { - invalidate_bdev(diaper, 1); - diaper->bd_contains = NULL; - diaper->bd_disk = NULL; - } else - printk("GFS: diaper: not closed\n"); - up(&diaper->bd_sem); - bdput(diaper); - - fail_remove: - del_gendisk(gd); - blk_put_queue(gd->queue); - - fail_gd: - put_disk(gd); - - fail_kfree: - kfree(dh); - - fail: - minor_put(minor); - return ERR_PTR(error); -} - -/** - * diaper_put - Do the work of destroying a diaper device - * @dh: - * - */ - -static void -diaper_put(struct diaper_holder *dh) -{ - struct block_device *diaper = dh->dh_diaper; - struct gendisk *gd = dh->dh_gendisk; - int minor = dh->dh_gendisk->first_minor; - - generic_shutdown_super(dh->dh_dummy_sb); - - mempool_destroy(dh->dh_mempool); - - down(&diaper->bd_sem); - if (!--diaper->bd_openers) { - invalidate_bdev(diaper, 1); - diaper->bd_contains = NULL; - diaper->bd_disk = NULL; - } else - printk("GFS: diaper: not closed\n"); - up(&diaper->bd_sem); - - bdput(diaper); - del_gendisk(gd); - blk_put_queue(gd->queue); - put_disk(gd); - kfree(dh); - minor_put(minor); -} - -/** - * gfs_diaper_get - Get a hold of an existing diaper or create a new one - * @real: - * @flags: - * - * Returns: the diaper device or ERR_PTR() - */ - -struct block_device * -gfs_diaper_get(struct block_device *real, int flags) -{ - struct list_head *tmp; - struct diaper_holder *dh, *dh_new = NULL; - - for (;;) { - spin_lock(&diaper_lock); - for (tmp = diaper_list.next; - tmp != &diaper_list; - tmp = tmp->next) { - dh = list_entry(tmp, struct diaper_holder, dh_list); - if (dh->dh_real == real) { - dh->dh_count++; - break; - } - } - if (tmp == &diaper_list) - dh = NULL; - if (!dh && dh_new) { - dh = dh_new; - list_add(&dh->dh_list, &diaper_list); - dh_new = NULL; - } - spin_unlock(&diaper_lock); - - if (dh) { - if (dh_new) - diaper_put(dh_new); - return dh->dh_diaper; - } - - dh_new = diaper_get(real, flags); - if (IS_ERR(dh_new)) - return (struct block_device *)dh_new; - } -} - -/** - * gfs_diaper_put - Drop a reference on a diaper - * @diaper: - * - */ - -void -gfs_diaper_put(struct block_device *diaper) -{ - struct list_head *tmp; - struct diaper_holder *dh; - - spin_lock(&diaper_lock); - for (tmp = diaper_list.next; - tmp != &diaper_list; - tmp = tmp->next) { - dh = list_entry(tmp, struct diaper_holder, dh_list); - if (dh->dh_diaper == diaper) { - if (!--dh->dh_count) { - list_del(&dh->dh_list); - spin_unlock(&diaper_lock); - diaper_put(dh); - } else - spin_unlock(&diaper_lock); - return; - } - } - spin_unlock(&diaper_lock); - - printk("GFS: diaper: unknown undiaper\n"); -} - -/** - * gfs_diaper_register_sbd - - * @diaper: - * @sdp: - * - */ - -void -gfs_diaper_register_sbd(struct block_device *diaper, struct gfs_sbd *sdp) -{ - struct list_head *tmp; - struct diaper_holder *dh; - - spin_lock(&diaper_lock); - for (tmp = diaper_list.next; - tmp != &diaper_list; - tmp = tmp->next) { - dh = list_entry(tmp, struct diaper_holder, dh_list); - if (dh->dh_diaper == diaper) { - dh->dh_sbd = sdp; - spin_unlock(&diaper_lock); - return; - } - } - spin_unlock(&diaper_lock); - - printk("GFS: diaper: unknown register\n"); -} - -/** - * gfs_diaper_2real - - * @diaper: - * - * Returns: the real device cooresponding to the diaper - */ - -struct block_device * -gfs_diaper_2real(struct block_device *diaper) -{ - struct list_head *tmp; - struct diaper_holder *dh; - - spin_lock(&diaper_lock); - for (tmp = diaper_list.next; - tmp != &diaper_list; - tmp = tmp->next) { - dh = list_entry(tmp, struct diaper_holder, dh_list); - if (dh->dh_diaper == diaper) { - spin_unlock(&diaper_lock); - return dh->dh_real; - } - } - spin_unlock(&diaper_lock); - - printk("GFS: diaper: unknown 2real\n"); - return NULL; -} - -/** - * gfs_diaper_init - - * - * Returns: errno - */ - -int -gfs_diaper_init(void) -{ - spin_lock_init(&diaper_lock); - - diaper_slab = kmem_cache_create("gfs_bio_wrapper", sizeof(struct bio_wrapper), - 0, 0, - NULL, NULL); - if (!diaper_slab) - return -ENOMEM; - - diaper_major = register_blkdev(0, "gfs_diaper"); - if (diaper_major < 0) { - kmem_cache_destroy(diaper_slab); - return diaper_major; - } - - return 0; -} - -/** - * gfs_diaper_uninit - - * - */ - -void -gfs_diaper_uninit(void) -{ - kmem_cache_destroy(diaper_slab); - unregister_blkdev(diaper_major, "gfs_diaper"); -} - diff --git a/gfs-kernel/src/gfs/diaper.h b/gfs-kernel/src/gfs/diaper.h deleted file mode 100644 index d401834..0000000 --- a/gfs-kernel/src/gfs/diaper.h +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DIAPER_DOT_H__ -#define __DIAPER_DOT_H__ - -struct block_device *gfs_diaper_get(struct block_device *real, int flags); -void gfs_diaper_put(struct block_device *diaper); - -void gfs_diaper_register_sbd(struct block_device *diaper, struct gfs_sbd *sdp); -struct block_device *gfs_diaper_2real(struct block_device *diaper); - -int gfs_diaper_init(void); -void gfs_diaper_uninit(void); - -#endif /* __DIAPER_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/dio.c b/gfs-kernel/src/gfs/dio.c deleted file mode 100644 index ddf9df2..0000000 --- a/gfs-kernel/src/gfs/dio.c +++ /dev/null @@ -1,1244 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/writeback.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "log.h" -#include "lops.h" -#include "rgrp.h" -#include "trans.h" - -/** - * aspace_get_block - - * @inode: - * @lblock: - * @bh_result: - * @create: - * - * Returns: errno - */ - -static int -aspace_get_block(struct inode *inode, sector_t lblock, - struct buffer_head *bh_result, int create) -{ - gfs_assert_warn(vfs2sdp(inode->i_sb), FALSE); - return -ENOSYS; -} - -/** - * gfs_aspace_writepage - write an aspace page - * @page: the page - * @wbc: - * - * Returns: errno - */ - -static int -gfs_aspace_writepage(struct page *page, struct writeback_control *wbc) -{ - return block_write_full_page(page, aspace_get_block, wbc); -} - -/** - * stuck_releasepage - We're stuck in gfs_releasepage(). Print stuff out. - * @bh: the buffer we're stuck on - * - */ - -static void -stuck_releasepage(struct buffer_head *bh) -{ - struct gfs_sbd *sdp = vfs2sdp(bh->b_page->mapping->host->i_sb); - struct gfs_bufdata *bd = bh2bd(bh); - - printk("GFS: fsid=%s: stuck in gfs_releasepage()...\n", sdp->sd_fsname); - printk("GFS: fsid=%s: blkno = %"PRIu64", bh->b_count = %d\n", - sdp->sd_fsname, - (uint64_t)bh->b_blocknr, - atomic_read(&bh->b_count)); - printk("GFS: fsid=%s: bh2bd(bh) = %s\n", - sdp->sd_fsname, - (bd) ? "!NULL" : "NULL"); - - if (bd) { - struct gfs_glock *gl = bd->bd_gl; - - printk("GFS: fsid=%s: gl = (%u, %"PRIu64")\n", - sdp->sd_fsname, - gl->gl_name.ln_type, - gl->gl_name.ln_number); - - printk("GFS: fsid=%s: bd_new_le.le_trans = %s\n", - sdp->sd_fsname, - (bd->bd_new_le.le_trans) ? "!NULL" : "NULL"); - printk("GFS: fsid=%s: bd_incore_le.le_trans = %s\n", - sdp->sd_fsname, - (bd->bd_incore_le.le_trans) ? "!NULL" : "NULL"); - printk("GFS: fsid=%s: bd_frozen = %s\n", - sdp->sd_fsname, - (bd->bd_frozen) ? "!NULL" : "NULL"); - printk("GFS: fsid=%s: bd_pinned = %u\n", - sdp->sd_fsname, bd->bd_pinned); - printk("GFS: fsid=%s: bd_ail_tr_list = %s\n", - sdp->sd_fsname, - (list_empty(&bd->bd_ail_tr_list)) ? "Empty" : "!Empty"); - - if (gl->gl_ops == &gfs_inode_glops) { - struct gfs_inode *ip = gl2ip(gl); - - if (ip) { - unsigned int x; - - printk("GFS: fsid=%s: ip = %"PRIu64"/%"PRIu64"\n", - sdp->sd_fsname, - ip->i_num.no_formal_ino, - ip->i_num.no_addr); - printk("GFS: fsid=%s: ip->i_count = %d, ip->i_vnode = %s\n", - sdp->sd_fsname, - atomic_read(&ip->i_count), - (ip->i_vnode) ? "!NULL" : "NULL"); - for (x = 0; x < GFS_MAX_META_HEIGHT; x++) - printk("GFS: fsid=%s: ip->i_cache[%u] = %s\n", - sdp->sd_fsname, x, - (ip->i_cache[x]) ? "!NULL" : "NULL"); - } - } - } -} - -/** - * gfs_aspace_releasepage - free the metadata associated with a page - * @page: the page that's being released - * @gfp_mask: passed from Linux VFS, ignored by us - * - * Call try_to_free_buffers() if the buffers in this page can be - * released. - * - * Returns: 0 - */ - -static int -gfs_aspace_releasepage(struct page *page, int gfp_mask) -{ - struct inode *aspace = page->mapping->host; - struct gfs_sbd *sdp = vfs2sdp(aspace->i_sb); - struct buffer_head *bh, *head; - struct gfs_bufdata *bd; - unsigned long t; - - if (!page_has_buffers(page)) - goto out; - - head = bh = page_buffers(page); - do { - t = jiffies; - - while (atomic_read(&bh->b_count)) { - if (atomic_read(&aspace->i_writecount)) { - if (time_after_eq(jiffies,t + - gfs_tune_get(sdp, - gt_stall_secs) * HZ)) { - stuck_releasepage(bh); - t = jiffies; - } - - yield(); - continue; - } - - return 0; - } - - bd = bh2bd(bh); - if (bd) { - gfs_assert_warn(sdp, bd->bd_bh == bh); - gfs_assert_warn(sdp, !bd->bd_new_le.le_trans); - gfs_assert_warn(sdp, !bd->bd_incore_le.le_trans); - gfs_assert_warn(sdp, !bd->bd_frozen); - gfs_assert_warn(sdp, !bd->bd_pinned); - gfs_assert_warn(sdp, list_empty(&bd->bd_ail_tr_list)); - kmem_cache_free(gfs_bufdata_cachep, bd); - atomic_dec(&sdp->sd_bufdata_count); - bh2bd(bh) = NULL; - } - - bh = bh->b_this_page; - } - while (bh != head); - - out: - return try_to_free_buffers(page); -} - -static struct address_space_operations aspace_aops = { - .writepage = gfs_aspace_writepage, - .releasepage = gfs_aspace_releasepage, -}; - -/** - * gfs_aspace_get - Create and initialize a struct inode structure - * @sdp: the filesystem the aspace is in - * - * Right now a struct inode is just a struct inode. Maybe Linux - * will supply a more lightweight address space construct (that works) - * in the future. - * - * Make sure pages/buffers in this aspace aren't in high memory. - * - * Returns: the aspace - */ - -struct inode * -gfs_aspace_get(struct gfs_sbd *sdp) -{ - struct inode *aspace; - - aspace = new_inode(sdp->sd_vfs); - if (aspace) { - mapping_set_gfp_mask(aspace->i_mapping, GFP_KERNEL); - aspace->i_mapping->a_ops = &aspace_aops; - aspace->i_size = ~0ULL; - vn2ip(aspace) = NULL; - insert_inode_hash(aspace); - } - - return aspace; -} - -/** - * gfs_aspace_put - get rid of an aspace - * @aspace: - * - */ - -void -gfs_aspace_put(struct inode *aspace) -{ - remove_inode_hash(aspace); - iput(aspace); -} - -/** - * gfs_ail_start_trans - Start I/O on a part of the AIL - * @sdp: the filesystem - * @tr: the part of the AIL - * - */ - -void -gfs_ail_start_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *head, *tmp, *prev; - struct gfs_bufdata *bd; - struct buffer_head *bh; - int retry; - - do { - retry = FALSE; - - spin_lock(&sdp->sd_ail_lock); - - for (head = &tr->tr_ail_bufs, tmp = head->prev, prev = tmp->prev; - tmp != head; - tmp = prev, prev = tmp->prev) { - bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); - bh = bd->bd_bh; - - if (gfs_trylock_buffer(bh)) - continue; - - if (bd->bd_pinned || gfs_bd_ail_tryremove(sdp, bd)) { - gfs_unlock_buffer(bh); - continue; - } - - if (buffer_dirty(bh)) { - list_move(&bd->bd_ail_tr_list, head); - - spin_unlock(&sdp->sd_ail_lock); - wait_on_buffer(bh); - ll_rw_block(WRITE, 1, &bh); - spin_lock(&sdp->sd_ail_lock); - - gfs_unlock_buffer(bh); - retry = TRUE; - break; - } - - gfs_unlock_buffer(bh); - } - - spin_unlock(&sdp->sd_ail_lock); - } while (retry); -} - -/** - * gfs_ail_empty_trans - Check whether or not a trans in the AIL has been synced - * @sdp: the filesystem - * @tr: the transaction - * - */ - -int -gfs_ail_empty_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *head, *tmp, *prev; - struct gfs_bufdata *bd; - struct buffer_head *bh; - int ret; - - spin_lock(&sdp->sd_ail_lock); - - for (head = &tr->tr_ail_bufs, tmp = head->prev, prev = tmp->prev; - tmp != head; - tmp = prev, prev = tmp->prev) { - bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); - bh = bd->bd_bh; - - if (gfs_trylock_buffer(bh) == 0) { - gfs_bd_ail_tryremove(sdp, bd); - gfs_unlock_buffer(bh); - } - } - - ret = list_empty(head); - - spin_unlock(&sdp->sd_ail_lock); - - return ret; -} - -/** - * getbuf - Get a buffer with a given address space - * @sdp: the filesystem - * @aspace: the address space - * @blkno: the block number (filesystem scope) - * @create: TRUE if the buffer should be created - * - * Returns: the buffer - */ - -static struct buffer_head * -getbuf(struct gfs_sbd *sdp, struct inode *aspace, uint64_t blkno, int create) -{ - struct page *page; - struct buffer_head *bh; - unsigned int shift; - unsigned long index; - unsigned int bufnum; - - shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift; - index = blkno >> shift; /* convert block to page */ - bufnum = blkno - (index << shift); /* block buf index within page */ - - if (create) { - RETRY_MALLOC(page = grab_cache_page(aspace->i_mapping, index), page); - } else { - page = find_lock_page(aspace->i_mapping, index); - if (!page) - return NULL; - } - - if (!page_has_buffers(page)) - create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0); - - /* Locate header for our buffer within our page */ - for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page) - /* Do nothing */; - get_bh(bh); - - if (!buffer_mapped(bh)) - map_bh(bh, sdp->sd_vfs, blkno); - else if (gfs_assert_warn(sdp, bh->b_bdev == sdp->sd_vfs->s_bdev && - bh->b_blocknr == blkno)) - map_bh(bh, sdp->sd_vfs, blkno); - - unlock_page(page); - page_cache_release(page); - - return bh; -} - -/** - * gfs_dgetblk - Get a block - * @gl: The glock associated with this block - * @blkno: The block number - * - * Returns: The buffer - */ - -struct buffer_head * -gfs_dgetblk(struct gfs_glock *gl, uint64_t blkno) -{ - return getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); -} - -/** - * gfs_dread - Read a block from disk - * @gl: The glock covering the block - * @blkno: The block number - * @flags: flags to gfs_dreread() - * @bhp: the place where the buffer is returned (NULL on failure) - * - * Returns: errno - */ - -int -gfs_dread(struct gfs_glock *gl, uint64_t blkno, - int flags, struct buffer_head **bhp) -{ - int error; - - *bhp = gfs_dgetblk(gl, blkno); - error = gfs_dreread(gl->gl_sbd, *bhp, flags); - if (error) - brelse(*bhp); - - return error; -} - -/** - * gfs_prep_new_buffer - Mark a new buffer we just gfs_dgetblk()ed uptodate - * @bh: the buffer - * - */ - -void -gfs_prep_new_buffer(struct buffer_head *bh) -{ - wait_on_buffer(bh); - clear_buffer_dirty(bh); - set_buffer_uptodate(bh); -} - -/** - * gfs_dreread - Reread a block from disk - * @sdp: the filesystem - * @bh: The block to read - * @flags: Flags that control the read - * - * Returns: errno - */ - -int -gfs_dreread(struct gfs_sbd *sdp, struct buffer_head *bh, int flags) -{ - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - return -EIO; - - /* Fill in meta-header if we have a cached copy, else read from disk */ - if (flags & DIO_NEW) { - if (gfs_mhc_fish(sdp, bh)) - return 0; - clear_buffer_uptodate(bh); - } - - if (flags & DIO_FORCE) - clear_buffer_uptodate(bh); - - if ((flags & DIO_START) && !buffer_uptodate(bh)) - ll_rw_block(READ, 1, &bh); - - if (flags & DIO_WAIT) { - wait_on_buffer(bh); - - if (!buffer_uptodate(bh)) { - gfs_io_error_bh(sdp, bh); - return -EIO; - } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - return -EIO; - } - - return 0; -} - -/** - * gfs_dwrite - Write a buffer to disk (and/or wait for write to complete) - * @sdp: the filesystem - * @bh: The buffer to write - * @flags: DIO_XXX The type of write/wait operation to do - * - * Returns: errno - */ - -int -gfs_dwrite(struct gfs_sbd *sdp, struct buffer_head *bh, int flags) -{ - if (gfs_assert_warn(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags))) - return -EIO; - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - return -EIO; - - if (flags & DIO_CLEAN) { - lock_buffer(bh); - clear_buffer_dirty(bh); - unlock_buffer(bh); - } - - if (flags & DIO_DIRTY) { - if (gfs_assert_warn(sdp, buffer_uptodate(bh))) - return -EIO; - mark_buffer_dirty(bh); - } - - if ((flags & DIO_START) && buffer_dirty(bh)) { - wait_on_buffer(bh); - ll_rw_block(WRITE, 1, &bh); - } - - if (flags & DIO_WAIT) { - wait_on_buffer(bh); - - if (!buffer_uptodate(bh) || buffer_dirty(bh)) { - gfs_io_error_bh(sdp, bh); - return -EIO; - } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - return -EIO; - } - - return 0; -} - -/** - * gfs_attach_bufdata - attach a struct gfs_bufdata structure to a buffer - * @bh: The buffer to be attached to - * @gl: the glock the buffer belongs to - * - */ - -void -gfs_attach_bufdata(struct buffer_head *bh, struct gfs_glock *gl) -{ - struct gfs_bufdata *bd; - - lock_page(bh->b_page); - - /* If there's one attached already, we're done */ - if (bh2bd(bh)) { - unlock_page(bh->b_page); - return; - } - - RETRY_MALLOC(bd = kmem_cache_alloc(gfs_bufdata_cachep, GFP_KERNEL), bd); - atomic_inc(&gl->gl_sbd->sd_bufdata_count); - - memset(bd, 0, sizeof(struct gfs_bufdata)); - - bd->bd_bh = bh; - bd->bd_gl = gl; - - INIT_LE(&bd->bd_new_le, &gfs_buf_lops); - INIT_LE(&bd->bd_incore_le, &gfs_buf_lops); - - init_MUTEX(&bd->bd_lock); - - INIT_LIST_HEAD(&bd->bd_ail_tr_list); - - bh2bd(bh) = bd; - - unlock_page(bh->b_page); -} - -/** - * gfs_is_pinned - Figure out if a buffer is pinned or not - * @sdp: the filesystem the buffer belongs to - * @bh: The buffer to be pinned - * - * Returns: TRUE if the buffer is pinned, FALSE otherwise - */ - -int -gfs_is_pinned(struct gfs_sbd *sdp, struct buffer_head *bh) -{ - struct gfs_bufdata *bd = bh2bd(bh); - int ret = FALSE; - - if (bd) { - gfs_lock_buffer(bh); - if (bd->bd_pinned) - ret = TRUE; - gfs_unlock_buffer(bh); - } - - return ret; -} - -/** - * gfs_dpin - Pin a metadata buffer in memory - * @sdp: the filesystem the buffer belongs to - * @bh: The buffer to be pinned - * - * "Pinning" means keeping buffer from being written to its in-place location. - * A buffer should be pinned from the time it is added to a new transaction, - * until after it has been written to the log. - * If an earlier change to this buffer is still pinned, waiting to be written - * to on-disk log, we need to keep a "frozen" copy of the old data while this - * transaction is modifying the real data. We keep the frozen copy until - * this transaction's incore_commit(), i.e. until the transaction has - * finished modifying the real data, at which point we can use the real - * buffer for logging, even if the frozen copy didn't get written to the log. - * - */ - -void -gfs_dpin(struct gfs_sbd *sdp, struct buffer_head *bh) -{ - struct gfs_bufdata *bd = bh2bd(bh); - char *data; - - gfs_assert_withdraw(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags)); - - gfs_lock_buffer(bh); - - gfs_assert_warn(sdp, !bd->bd_frozen); - - if (!bd->bd_pinned++) { - wait_on_buffer(bh); - - /* If this buffer is in the AIL and it has already been written - to in-place disk block, remove it from the AIL. */ - - spin_lock(&sdp->sd_ail_lock); - gfs_bd_ail_tryremove(sdp, bd); - spin_unlock(&sdp->sd_ail_lock); - - clear_buffer_dirty(bh); - wait_on_buffer(bh); - - if (!buffer_uptodate(bh)) - gfs_io_error_bh(sdp, bh); - } else { - gfs_unlock_buffer(bh); - - gfs_assert_withdraw(sdp, buffer_uptodate(bh)); - - data = gmalloc(sdp->sd_sb.sb_bsize); - - gfs_lock_buffer(bh); - - /* Create frozen copy, if needed. */ - if (bd->bd_pinned > 1) { - memcpy(data, bh->b_data, sdp->sd_sb.sb_bsize); - bd->bd_frozen = data; - } else - kfree(data); - } - - gfs_unlock_buffer(bh); - - get_bh(bh); -} - -/** - * gfs_dunpin - Unpin a buffer - * @sdp: the filesystem the buffer belongs to - * @bh: The buffer to unpin - * @tr: The transaction in the AIL that contains this buffer - * If NULL, don't attach buffer to any AIL list - * (i.e. when dropping a pin reference when merging a new transaction - * with an already existing incore transaction) - * - * Called for (meta) buffers, after they've been logged to on-disk journal. - * Make a (meta) buffer writeable to in-place location on-disk, if recursive - * pin count is 1 (i.e. no other, later transaction is modifying this buffer). - * Add buffer to AIL lists of 1) the latest transaction that's modified and - * logged (on-disk) the buffer, and of 2) the glock that protects the buffer. - * A single buffer might have been modified by more than one transaction - * since the buffer's previous write to disk (in-place location). We keep - * the buffer on only one transaction's AIL list, i.e. that of the latest - * transaction that's completed logging this buffer (no need to write it to - * in-place block multiple times for multiple transactions, only once with - * the most up-to-date data). - * A single buffer will be protected by one and only one glock. If buffer is - * already on a (previous) transaction's AIL, we know that we're already - * on buffer's glock's AIL. - * - */ - -void -gfs_dunpin(struct gfs_sbd *sdp, struct buffer_head *bh, struct gfs_trans *tr) -{ - struct gfs_bufdata *bd = bh2bd(bh); - - gfs_assert_withdraw(sdp, buffer_uptodate(bh)); - - gfs_lock_buffer(bh); - - if (gfs_assert_warn(sdp, bd->bd_pinned)) { - gfs_unlock_buffer(bh); - return; - } - - /* No other (later) transaction is modifying buffer; ready to write */ - if (bd->bd_pinned == 1) - mark_buffer_dirty(bh); - - bd->bd_pinned--; - - gfs_unlock_buffer(bh); - - if (tr) { - spin_lock(&sdp->sd_ail_lock); - - if (list_empty(&bd->bd_ail_tr_list)) { - /* Buffer not attached to any earlier transaction. Add - it to glock's AIL, and this trans' AIL (below). */ - list_add(&bd->bd_ail_gl_list, &bd->bd_gl->gl_ail_bufs); - } else { - /* Was part of earlier transaction. - Move from that trans' AIL to this newer one's AIL. - Buf is already on glock's AIL. */ - list_del_init(&bd->bd_ail_tr_list); - brelse(bh); - } - list_add(&bd->bd_ail_tr_list, &tr->tr_ail_bufs); - - spin_unlock(&sdp->sd_ail_lock); - } else - brelse(bh); -} - -/** - * logbh_end_io - Called by OS at the end of a logbh ("fake" bh) write to log - * @bh: the buffer - * @uptodate: whether or not the write succeeded - * - */ - -static void -logbh_end_io(struct buffer_head *bh, int uptodate) -{ - if (uptodate) - set_buffer_uptodate(bh); - else - clear_buffer_uptodate(bh); - unlock_buffer(bh); -} - -/** - * gfs_logbh_init - Initialize a fake buffer head - * @sdp: the filesystem - * @bh: the buffer to initialize - * @blkno: the block address of the buffer - * @data: the data to be written - * - */ - -void -gfs_logbh_init(struct gfs_sbd *sdp, struct buffer_head *bh, - uint64_t blkno, char *data) -{ - memset(bh, 0, sizeof(struct buffer_head)); - bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock); - atomic_set(&bh->b_count, 1); - set_bh_page(bh, virt_to_page(data), ((unsigned long)data) & (PAGE_SIZE - 1)); - bh->b_blocknr = blkno; - bh->b_size = sdp->sd_sb.sb_bsize; - bh->b_bdev = sdp->sd_vfs->s_bdev; - init_buffer(bh, logbh_end_io, NULL); - INIT_LIST_HEAD(&bh->b_assoc_buffers); -} - -/** - * gfs_logbh_uninit - Clean up a fake buffer head - * @sdp: the filesystem - * @bh: the buffer to clean - * - */ - -void -gfs_logbh_uninit(struct gfs_sbd *sdp, struct buffer_head *bh) -{ - gfs_assert_warn(sdp, test_bit(SDF_SHUTDOWN, &sdp->sd_flags) || - !buffer_busy(bh)); - gfs_assert_warn(sdp, atomic_read(&bh->b_count) == 1); -} - -/** - * gfs_logbh_start - Start writing a fake buffer head - * @sdp: the filesystem - * @bh: the buffer to write - * - * This starts a block write to our journal. - */ - -void -gfs_logbh_start(struct gfs_sbd *sdp, struct buffer_head *bh) -{ - submit_bh(WRITE, bh); -} - -/** - * gfs_logbh_wait - Wait for the write of a fake buffer head to complete - * @sdp: the filesystem - * @bh: the buffer to write - * - * This waits for a block write to our journal to complete. - * - * Returns: errno - */ - -int -gfs_logbh_wait(struct gfs_sbd *sdp, struct buffer_head *bh) -{ - wait_on_buffer(bh); - - if (!buffer_uptodate(bh) || buffer_dirty(bh)) { - gfs_io_error_bh(sdp, bh); - return -EIO; - } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - return -EIO; - - return 0; -} - -/** - * gfs_replay_buf - write a log buffer to its inplace location - * @gl: the journal's glock - * @bh: the buffer - * - * Returns: errno - */ - -int -gfs_replay_buf(struct gfs_glock *gl, struct buffer_head *bh) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_bufdata *bd; - - bd = bh2bd(bh); - if (!bd) { - gfs_attach_bufdata(bh, gl); - bd = bh2bd(bh); - } - - mark_buffer_dirty(bh); - - if (list_empty(&bd->bd_ail_tr_list)) { - get_bh(bh); - list_add(&bd->bd_ail_tr_list, &sdp->sd_recovery_bufs); - } - - return 0; -} - -/** - * gfs_replay_check - Check up on journal replay - * @sdp: the filesystem - * - */ - -void -gfs_replay_check(struct gfs_sbd *sdp) -{ - struct buffer_head *bh; - struct gfs_bufdata *bd; - - while (!list_empty(&sdp->sd_recovery_bufs)) { - bd = list_entry(sdp->sd_recovery_bufs.prev, - struct gfs_bufdata, bd_ail_tr_list); - bh = bd->bd_bh; - - if (buffer_busy(bh)) { - list_move(&bd->bd_ail_tr_list, - &sdp->sd_recovery_bufs); - break; - } else { - list_del_init(&bd->bd_ail_tr_list); - if (!buffer_uptodate(bh)) - gfs_io_error_bh(sdp, bh); - brelse(bh); - } - } -} - -/** - * gfs_replay_wait - Wait for all replayed buffers to hit the disk - * @sdp: the filesystem - * - */ - -void -gfs_replay_wait(struct gfs_sbd *sdp) -{ - struct list_head *head, *tmp, *prev; - struct buffer_head *bh; - struct gfs_bufdata *bd; - - for (head = &sdp->sd_recovery_bufs, tmp = head->prev, prev = tmp->prev; - tmp != head; - tmp = prev, prev = tmp->prev) { - bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); - bh = bd->bd_bh; - - if (!buffer_busy(bh)) { - list_del_init(&bd->bd_ail_tr_list); - if (!buffer_uptodate(bh)) - gfs_io_error_bh(sdp, bh); - brelse(bh); - continue; - } - - if (buffer_dirty(bh)) { - wait_on_buffer(bh); - ll_rw_block(WRITE, 1, &bh); - } - } - - while (!list_empty(head)) { - bd = list_entry(head->prev, struct gfs_bufdata, bd_ail_tr_list); - bh = bd->bd_bh; - - wait_on_buffer(bh); - - gfs_assert_withdraw(sdp, !buffer_busy(bh)); - - list_del_init(&bd->bd_ail_tr_list); - if (!buffer_uptodate(bh)) - gfs_io_error_bh(sdp, bh); - brelse(bh); - } -} - -/** - * gfs_wipe_buffers - make inode's buffers so they aren't dirty/AILed anymore - * @ip: the inode who owns the buffers - * @rgd: the resource group - * @bstart: the first buffer in the run - * @blen: the number of buffers in the run - * - * Called when de-allocating a contiguous run of meta blocks within an rgrp. - * Make sure all buffers for de-alloc'd blocks are removed from the AIL, if - * they can be. Dirty or pinned blocks are left alone. Add relevant - * meta-headers to meta-header cache, so we don't need to read disk - * if we re-allocate blocks. - */ - -void -gfs_wipe_buffers(struct gfs_inode *ip, struct gfs_rgrpd *rgd, - uint64_t bstart, uint32_t blen) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct inode *aspace = ip->i_gl->gl_aspace; - struct buffer_head *bh; - struct gfs_bufdata *bd; - int busy; - int add = FALSE; - - while (blen) { - bh = getbuf(sdp, aspace, bstart, NO_CREATE); - if (bh) { - - bd = bh2bd(bh); - - if (buffer_uptodate(bh)) { - if (bd) { - gfs_lock_buffer(bh); - gfs_mhc_add(rgd, &bh, 1); - busy = bd->bd_pinned || buffer_busy(bh); - gfs_unlock_buffer(bh); - - if (busy) - add = TRUE; - else { - spin_lock(&sdp->sd_ail_lock); - gfs_bd_ail_tryremove(sdp, bd); - spin_unlock(&sdp->sd_ail_lock); - } - } else { - gfs_assert_withdraw(sdp, !buffer_dirty(bh)); - wait_on_buffer(bh); - gfs_assert_withdraw(sdp, !buffer_busy(bh)); - gfs_mhc_add(rgd, &bh, 1); - } - } else { - gfs_assert_withdraw(sdp, !bd || !bd->bd_pinned); - gfs_assert_withdraw(sdp, !buffer_dirty(bh)); - wait_on_buffer(bh); - gfs_assert_withdraw(sdp, !buffer_busy(bh)); - } - - brelse(bh); - } - - bstart++; - blen--; - } - - if (add) - gfs_depend_add(rgd, ip->i_num.no_formal_ino); -} - -/** - * gfs_sync_meta - sync all the buffers in a filesystem - * @sdp: the filesystem - * - * Flush metadata blocks to on-disk journal, then - * Flush metadata blocks (now in AIL) to on-disk in-place locations - * Periodically keep checking until done (AIL empty) - */ - -void -gfs_sync_meta(struct gfs_sbd *sdp) -{ - gfs_log_flush(sdp); - for (;;) { - gfs_ail_start(sdp, DIO_ALL); - if (gfs_ail_empty(sdp)) - break; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 10); - } -} - -/** - * gfs_flush_meta_cache - get rid of any references on buffers for this inode - * @ip: The GFS inode - * - * This releases buffers that are in the most-recently-used array of - * blocks used for indirect block addressing for this inode. - * Don't confuse this with the meta-HEADER cache (mhc)! - */ - -void -gfs_flush_meta_cache(struct gfs_inode *ip) -{ - struct buffer_head **bh_slot; - unsigned int x; - - spin_lock(&ip->i_spin); - - for (x = 0; x < GFS_MAX_META_HEIGHT; x++) { - bh_slot = &ip->i_cache[x]; - if (*bh_slot) { - brelse(*bh_slot); - *bh_slot = NULL; - } - } - - spin_unlock(&ip->i_spin); -} - -/** - * gfs_get_meta_buffer - Get a metadata buffer - * @ip: The GFS inode - * @height: The level of this buf in the metadata (indir addr) tree (if any) - * @num: The block number (device relative) of the buffer - * @new: Non-zero if we may create a new buffer - * @bhp: the buffer is returned here - * - * Returns: errno - */ - -int -gfs_get_meta_buffer(struct gfs_inode *ip, int height, uint64_t num, int new, - struct buffer_head **bhp) -{ - struct buffer_head *bh, **bh_slot = &ip->i_cache[height]; - int flags = ((new) ? DIO_NEW : 0) | DIO_START | DIO_WAIT; - int error; - - /* Try to use the gfs_inode's MRU metadata tree cache */ - spin_lock(&ip->i_spin); - bh = *bh_slot; - if (bh) { - if (bh->b_blocknr == num) - get_bh(bh); - else - bh = NULL; - } - spin_unlock(&ip->i_spin); - - if (bh) { - error = gfs_dreread(ip->i_sbd, bh, flags); - if (error) { - brelse(bh); - return error; - } - } else { - error = gfs_dread(ip->i_gl, num, flags, &bh); - if (error) - return error; - - spin_lock(&ip->i_spin); - if (*bh_slot != bh) { - if (*bh_slot) - brelse(*bh_slot); - *bh_slot = bh; - get_bh(bh); - } - spin_unlock(&ip->i_spin); - } - - if (new) { - if (gfs_assert_warn(ip->i_sbd, height)) { - brelse(bh); - return -EIO; - } - gfs_trans_add_bh(ip->i_gl, bh); - gfs_metatype_set(bh, GFS_METATYPE_IN, GFS_FORMAT_IN); - gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); - } else if (gfs_metatype_check(ip->i_sbd, bh, - (height) ? GFS_METATYPE_IN : GFS_METATYPE_DI)) { - brelse(bh); - return -EIO; - } - - *bhp = bh; - - return 0; -} - -/** - * gfs_get_data_buffer - Get a data buffer - * @ip: The GFS inode - * @num: The block number (device relative) of the data block - * @new: Non-zero if this is a new allocation - * @bhp: the buffer is returned here - * - * Returns: errno - */ - -int -gfs_get_data_buffer(struct gfs_inode *ip, uint64_t block, int new, - struct buffer_head **bhp) -{ - struct buffer_head *bh; - int error = 0; - - if (block == ip->i_num.no_addr) { - if (gfs_assert_warn(ip->i_sbd, !new)) - return -EIO; - error = gfs_dread(ip->i_gl, block, DIO_START | DIO_WAIT, &bh); - if (error) - return error; - if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_DI)) { - brelse(bh); - return -EIO; - } - } else if (gfs_is_jdata(ip)) { - if (new) { - error = gfs_dread(ip->i_gl, block, - DIO_NEW | DIO_START | DIO_WAIT, &bh); - if (error) - return error; - gfs_trans_add_bh(ip->i_gl, bh); - gfs_metatype_set(bh, GFS_METATYPE_JD, GFS_FORMAT_JD); - gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); - } else { - error = gfs_dread(ip->i_gl, block, - DIO_START | DIO_WAIT, &bh); - if (error) - return error; - if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_JD)) { - brelse(bh); - return -EIO; - } - } - } else { - if (new) { - bh = gfs_dgetblk(ip->i_gl, block); - gfs_prep_new_buffer(bh); - } else { - error = gfs_dread(ip->i_gl, block, - DIO_START | DIO_WAIT, &bh); - if (error) - return error; - } - } - - *bhp = bh; - - return 0; -} - -/** - * gfs_start_ra - start readahead on an extent of a file - * @gl: the glock the blocks belong to - * @dblock: the starting disk block - * @extlen: the number of blocks in the extent - * - * returns: number of blocks for which it submitted read requests. - */ - -int -gfs_start_ra(struct gfs_glock *gl, uint64_t dblock, uint32_t extlen) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct inode *aspace = gl->gl_aspace; - struct buffer_head *first_bh, *bh; - uint32_t max_ra = gfs_tune_get(sdp, gt_max_readahead) >> sdp->sd_sb.sb_bsize_shift; - int error, submitted = 0; - - if (!extlen) - return 0; - if (!max_ra) - return 0; - if (extlen > max_ra) - extlen = max_ra; - - first_bh = getbuf(sdp, aspace, dblock, CREATE); - - if (buffer_uptodate(first_bh)) - goto out; - if (!buffer_locked(first_bh)) { - error = gfs_dreread(sdp, first_bh, DIO_START); - submitted++; - if (error) - goto out; - } - - dblock++; - extlen--; - - while (extlen) { - bh = getbuf(sdp, aspace, dblock, CREATE); - - if (!buffer_uptodate(bh) && !buffer_locked(bh)) { - error = gfs_dreread(sdp, bh, DIO_START); - submitted++; - brelse(bh); - if (error) - goto out; - } else - brelse(bh); - - dblock++; - extlen--; - - if (buffer_uptodate(first_bh)) - break; - } - - out: - brelse(first_bh); - return submitted; -} diff --git a/gfs-kernel/src/gfs/dio.h b/gfs-kernel/src/gfs/dio.h deleted file mode 100644 index d5d0beb..0000000 --- a/gfs-kernel/src/gfs/dio.h +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DIO_DOT_H__ -#define __DIO_DOT_H__ - -#define buffer_busy(bh) ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock))) - -void gfs_ail_start_trans(struct gfs_sbd *sdp, struct gfs_trans *tr); -int gfs_ail_empty_trans(struct gfs_sbd *sdp, struct gfs_trans *tr); - -/* Asynchronous I/O Routines */ - -struct buffer_head *gfs_dgetblk(struct gfs_glock *gl, uint64_t blkno); -int gfs_dread(struct gfs_glock *gl, uint64_t blkno, - int flags, struct buffer_head **bhp); - -void gfs_prep_new_buffer(struct buffer_head *bh); -int gfs_dreread(struct gfs_sbd *sdp, struct buffer_head *bh, int flags); -int gfs_dwrite(struct gfs_sbd *sdp, struct buffer_head *bh, int flags); - -void gfs_attach_bufdata(struct buffer_head *bh, struct gfs_glock *gl); -int gfs_is_pinned(struct gfs_sbd *sdp, struct buffer_head *bh); -void gfs_dpin(struct gfs_sbd *sdp, struct buffer_head *bh); -void gfs_dunpin(struct gfs_sbd *sdp, struct buffer_head *bh, - struct gfs_trans *tr); - -static __inline__ -void gfs_lock_buffer(struct buffer_head *bh) -{ - struct gfs_bufdata *bd = bh2bd(bh); - down(&bd->bd_lock); -} -static __inline__ -int gfs_trylock_buffer(struct buffer_head *bh) -{ - struct gfs_bufdata *bd = bh2bd(bh); - return down_trylock(&bd->bd_lock); -} -static __inline__ -void gfs_unlock_buffer(struct buffer_head *bh) -{ - struct gfs_bufdata *bd = bh2bd(bh); - up(&bd->bd_lock); -} - -void gfs_logbh_init(struct gfs_sbd *sdp, struct buffer_head *bh, uint64_t blkno, - char *data); -void gfs_logbh_uninit(struct gfs_sbd *sdp, struct buffer_head *bh); -void gfs_logbh_start(struct gfs_sbd *sdp, struct buffer_head *bh); -int gfs_logbh_wait(struct gfs_sbd *sdp, struct buffer_head *bh); - -int gfs_replay_buf(struct gfs_glock *gl, struct buffer_head *bh); -void gfs_replay_check(struct gfs_sbd *sdp); -void gfs_replay_wait(struct gfs_sbd *sdp); - -void gfs_wipe_buffers(struct gfs_inode *ip, struct gfs_rgrpd *rgd, - uint64_t bstart, uint32_t blen); - -void gfs_sync_meta(struct gfs_sbd *sdp); - -/* Buffer Caching routines */ - -int gfs_get_meta_buffer(struct gfs_inode *ip, int height, uint64_t num, int new, - struct buffer_head **bhp); -int gfs_get_data_buffer(struct gfs_inode *ip, uint64_t block, int new, - struct buffer_head **bhp); -int gfs_start_ra(struct gfs_glock *gl, uint64_t dblock, uint32_t extlen); - -static __inline__ int -gfs_get_inode_buffer(struct gfs_inode *ip, struct buffer_head **bhp) -{ - return gfs_get_meta_buffer(ip, 0, ip->i_num.no_addr, FALSE, bhp); -} - -struct inode *gfs_aspace_get(struct gfs_sbd *sdp); -void gfs_aspace_put(struct inode *aspace); - -void gfs_inval_buf(struct gfs_glock *gl); - -void gfs_flush_meta_cache(struct gfs_inode *ip); - -/* Buffer Content Functions */ - -/** - * gfs_buffer_clear - Zeros out a buffer - * @ip: The GFS inode - * @bh: The buffer to zero - * - */ - -static __inline__ void -gfs_buffer_clear(struct buffer_head *bh) -{ - memset(bh->b_data, 0, bh->b_size); -} - -/** - * gfs_buffer_clear_tail - Clear buffer beyond the dinode - * @bh: The buffer containing the on-disk inode - * @head: the size of the head of the buffer - * - * Clears the remaining part of an on-disk inode that is not a dinode. - * i.e. The data part of a stuffed inode, or the top level of metadata - * of a non-stuffed inode. - */ - -static __inline__ void -gfs_buffer_clear_tail(struct buffer_head *bh, int head) -{ - memset(bh->b_data + head, 0, bh->b_size - head); -} - -/** - * gfs_buffer_clear_ends - Zero out any bits of a buffer which are not being written - * @bh: The buffer - * @offset: Offset in buffer where write starts - * @amount: Amount of data being written - * @journaled: TRUE if this is a journaled buffer - * - */ - -static __inline__ void -gfs_buffer_clear_ends(struct buffer_head *bh, int offset, int amount, - int journaled) -{ - int z_off1 = (journaled) ? sizeof(struct gfs_meta_header) : 0; - int z_len1 = offset - z_off1; - int z_off2 = offset + amount; - int z_len2 = (bh)->b_size - z_off2; - - if (z_len1) - memset(bh->b_data + z_off1, 0, z_len1); - - if (z_len2) - memset(bh->b_data + z_off2, 0, z_len2); -} - -/** - * gfs_buffer_copy_tail - copies the tail of one buffer to another - * @to_bh: the buffer to copy to - * @to_head: the size of the head of to_bh - * @from_bh: the buffer to copy from - * @from_head: the size of the head of from_bh - * - * from_head is guaranteed to bigger than to_head - */ - -static __inline__ void -gfs_buffer_copy_tail(struct buffer_head *to_bh, int to_head, - struct buffer_head *from_bh, int from_head) -{ - memcpy(to_bh->b_data + to_head, - from_bh->b_data + from_head, - from_bh->b_size - from_head); - memset(to_bh->b_data + to_bh->b_size + to_head - from_head, - 0, - from_head - to_head); -} - -/* - * gfs_bd_ail_tryremove - try to remove a bd from the ail - * returns: 1 if it removed one, else 0 - */ -static __inline__ int -gfs_bd_ail_tryremove(struct gfs_sbd *sdp, struct gfs_bufdata *bd) -{ - struct buffer_head *bh; - - bh = bd->bd_bh; - if (!bd->bd_pinned && !list_empty(&bd->bd_ail_tr_list) && - !buffer_busy(bh)) { - if (!buffer_uptodate(bh)) - gfs_io_error_bh(sdp, bh); - - list_del_init(&bd->bd_ail_tr_list); - list_del(&bd->bd_ail_gl_list); - - brelse(bh); - return 1; - } - return 0; -} - -#endif /* __DIO_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/dir.c b/gfs-kernel/src/gfs/dir.c deleted file mode 100644 index b53da73..0000000 --- a/gfs-kernel/src/gfs/dir.c +++ /dev/null @@ -1,2420 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* -* Implements Extendible Hashing as described in: -* "Extendible Hashing" by Fagin, et al in -* __ACM Trans. on Database Systems__, Sept 1979. -* -* -* Here's the layout of dirents which is essentially the same as that of ext2 -* within a single block. The field de_name_len is the number of bytes -* actually required for the name (no null terminator). The field de_rec_len -* is the number of bytes allocated to the dirent. The offset of the next -* dirent in the block is (dirent + dirent->de_rec_len). When a dirent is -* deleted, the preceding dirent inherits its allocated space, ie -* prev->de_rec_len += deleted->de_rec_len. Since the next dirent is obtained -* by adding de_rec_len to the current dirent, this essentially causes the -* deleted dirent to get jumped over when iterating through all the dirents. -* -* When deleting the first dirent in a block, there is no previous dirent so -* the field de_ino is set to zero to designate it as deleted. When allocating -* a dirent, gfs_dirent_alloc iterates through the dirents in a block. If the -* first dirent has (de_ino == 0) and de_rec_len is large enough, this first -* dirent is allocated. Otherwise it must go through all the 'used' dirents -* searching for one in which the amount of total space minus the amount of -* used space will provide enough space for the new dirent. -* -* There are two types of blocks in which dirents reside. In a stuffed dinode, -* the dirents begin at offset sizeof(struct gfs_dinode) from the beginning of -* the block. In leaves, they begin at offset sizeof (struct gfs_leaf) from the -* beginning of the leaf block. The dirents reside in leaves when -* -* dip->i_di.di_flags & GFS_DIF_EXHASH is true -* -* Otherwise, the dirents are "linear", within a single stuffed dinode block. -* -* When the dirents are in leaves, the actual contents of the directory file are -* used as an array of 64-bit block pointers pointing to the leaf blocks. The -* dirents are NOT in the directory file itself. There can be more than one block -* pointer in the array that points to the same leaf. In fact, when a directory -* is first converted from linear to exhash, all of the pointers point to the -* same leaf. -* -* When a leaf is completely full, the size of the hash table can be -* doubled unless it is already at the maximum size which is hard coded into -* GFS_DIR_MAX_DEPTH. After that, leaves are chained together in a linked list, -* but never before the maximum hash table size has been reached. -*/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/vmalloc.h> - -#include "gfs.h" -#include "dio.h" -#include "dir.h" -#include "file.h" -#include "glock.h" -#include "inode.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" - -#define IS_LEAF (1) /* Hashed (leaf) directory */ -#define IS_DINODE (2) /* Linear (stuffed dinode block) directory */ - -#if 1 -#define gfs_dir_hash2offset(h) (((uint64_t)(h)) >> 1) -#define gfs_dir_offset2hash(p) ((uint32_t)(((uint64_t)(p)) << 1)) -#else -#define gfs_dir_hash2offset(h) (((uint64_t)(h))) -#define gfs_dir_offset2hash(p) ((uint32_t)(((uint64_t)(p)))) -#endif - -typedef int (*leaf_call_t) (struct gfs_inode *dip, - uint32_t index, uint32_t len, uint64_t leaf_no, - void *data); - -/** - * int gfs_filecmp - Compare two filenames - * @file1: The first filename - * @file2: The second filename - * @len_of_file2: The length of the second file - * - * This routine compares two filenames and returns TRUE if they are equal. - * - * Returns: TRUE (!=0) if the files are the same, otherwise FALSE (0). - */ - -int -gfs_filecmp(struct qstr *file1, char *file2, int len_of_file2) -{ - if (file1->len != len_of_file2) - return FALSE; - if (memcmp(file1->name, file2, file1->len)) - return FALSE; - return TRUE; -} - -/** - * dirent_first - Return the first dirent - * @dip: the directory - * @bh: The buffer - * @dent: Pointer to list of dirents - * - * return first dirent whether bh points to leaf or stuffed dinode - * - * Returns: IS_LEAF, IS_DINODE, or -errno - */ - -static int -dirent_first(struct gfs_inode *dip, struct buffer_head *bh, - struct gfs_dirent **dent) -{ - struct gfs_meta_header *h = (struct gfs_meta_header *)bh->b_data; - - if (gfs32_to_cpu(h->mh_type) == GFS_METATYPE_LF) { - if (gfs_meta_check(dip->i_sbd, bh)) - return -EIO; - *dent = (struct gfs_dirent *)(bh->b_data + sizeof(struct gfs_leaf)); - return IS_LEAF; - } else { - if (gfs_metatype_check(dip->i_sbd, bh, GFS_METATYPE_DI)) - return -EIO; - *dent = (struct gfs_dirent *)(bh->b_data + sizeof(struct gfs_dinode)); - return IS_DINODE; - } -} - -/** - * dirent_next - Next dirent - * @dip: the directory - * @bh: The buffer - * @dent: Pointer to list of dirents - * - * Returns: 0 on success, error code otherwise - */ - -static int -dirent_next(struct gfs_inode *dip, struct buffer_head *bh, - struct gfs_dirent **dent) -{ - struct gfs_dirent *tmp, *cur; - char *bh_end; - uint32_t cur_rec_len; - - cur = *dent; - bh_end = bh->b_data + bh->b_size; - cur_rec_len = gfs16_to_cpu(cur->de_rec_len); - - if ((char *)cur + cur_rec_len >= bh_end) { - if ((char *)cur + cur_rec_len > bh_end) { - gfs_consist_inode(dip); - return -EIO; - } - return -ENOENT; - } - - tmp = (struct gfs_dirent *)((char *)cur + cur_rec_len); - - if ((char *)tmp + gfs16_to_cpu(tmp->de_rec_len) > bh_end) { - gfs_consist_inode(dip); - return -EIO; - } - /* Only the first dent could ever have de_ino == 0 */ - if (!tmp->de_inum.no_formal_ino) { - gfs_consist_inode(dip); - return -EIO; - } - - *dent = tmp; - - return 0; -} - -/** - * dirent_del - Delete a dirent - * @dip: The GFS inode - * @bh: The buffer - * @prev: The previous dirent - * @cur: The current dirent - * - */ - -static void -dirent_del(struct gfs_inode *dip, struct buffer_head *bh, - struct gfs_dirent *prev, struct gfs_dirent *cur) -{ - uint32_t cur_rec_len, prev_rec_len; - - if (!cur->de_inum.no_formal_ino) { - gfs_consist_inode(dip); - return; - } - - gfs_trans_add_bh(dip->i_gl, bh); - - /* If there is no prev entry, this is the first entry in the block. - The de_rec_len is already as big as it needs to be. Just zero - out the inode number and return. */ - - if (!prev) { - cur->de_inum.no_formal_ino = 0; /* No endianess worries */ - return; - } - - /* Combine this dentry with the previous one. */ - - prev_rec_len = gfs16_to_cpu(prev->de_rec_len); - cur_rec_len = gfs16_to_cpu(cur->de_rec_len); - - if ((char *)prev + prev_rec_len != (char *)cur) - gfs_consist_inode(dip); - if ((char *)cur + cur_rec_len > bh->b_data + bh->b_size) - gfs_consist_inode(dip); - - prev_rec_len += cur_rec_len; - prev->de_rec_len = cpu_to_gfs16(prev_rec_len); -} - -/** - * gfs_dirent_alloc - Allocate a directory entry - * @dip: The GFS inode - * @bh: The buffer - * @name_len: The length of the name - * @dent_out: Pointer to list of dirents - * - * Returns: 0 on success, error code otherwise - */ - -int -gfs_dirent_alloc(struct gfs_inode *dip, struct buffer_head *bh, int name_len, - struct gfs_dirent **dent_out) -{ - struct gfs_dirent *dent, *new; - unsigned int rec_len = GFS_DIRENT_SIZE(name_len); - unsigned int entries = 0, offset = 0; - int type; - - type = dirent_first(dip, bh, &dent); - if (type < 0) - return type; - - if (type == IS_LEAF) { - struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; - entries = gfs16_to_cpu(leaf->lf_entries); - offset = sizeof(struct gfs_leaf); - } else { - struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; - entries = gfs32_to_cpu(dinode->di_entries); - offset = sizeof(struct gfs_dinode); - } - - if (!entries) { - if (dent->de_inum.no_formal_ino) { - gfs_consist_inode(dip); - return -EIO; - } - - gfs_trans_add_bh(dip->i_gl, bh); - - dent->de_rec_len = bh->b_size - offset; - dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); - dent->de_name_len = cpu_to_gfs16(name_len); - - *dent_out = dent; - return 0; - } - - do { - uint32_t cur_rec_len, cur_name_len; - - cur_rec_len = gfs16_to_cpu(dent->de_rec_len); - cur_name_len = gfs16_to_cpu(dent->de_name_len); - - if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || - (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)) { - gfs_trans_add_bh(dip->i_gl, bh); - - if (dent->de_inum.no_formal_ino) { - new = (struct gfs_dirent *)((char *)dent + - GFS_DIRENT_SIZE(cur_name_len)); - memset(new, 0, sizeof(struct gfs_dirent)); - - new->de_rec_len = cpu_to_gfs16(cur_rec_len - - GFS_DIRENT_SIZE(cur_name_len)); - new->de_name_len = cpu_to_gfs16(name_len); - - dent->de_rec_len = cur_rec_len - gfs16_to_cpu(new->de_rec_len); - dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); - - *dent_out = new; - return 0; - } - - dent->de_name_len = cpu_to_gfs16(name_len); - - *dent_out = dent; - return 0; - } - } while (dirent_next(dip, bh, &dent) == 0); - - return -ENOSPC; -} - -/** - * dirent_fits - See if we can fit a entry in this buffer - * @dip: The GFS inode - * @bh: The buffer - * @name_len: The length of the name - * - * Returns: TRUE if it can fit, FALSE otherwise - */ - -static int -dirent_fits(struct gfs_inode *dip, struct buffer_head *bh, int name_len) -{ - struct gfs_dirent *dent; - unsigned int rec_len = GFS_DIRENT_SIZE(name_len); - unsigned int entries = 0; - int type; - - type = dirent_first(dip, bh, &dent); - if (type < 0) - return type; - - if (type == IS_LEAF) { - struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; - entries = gfs16_to_cpu(leaf->lf_entries); - } else { - struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; - entries = gfs32_to_cpu(dinode->di_entries); - } - - if (!entries) - return TRUE; - - do { - uint32_t cur_rec_len, cur_name_len; - - cur_rec_len = gfs16_to_cpu(dent->de_rec_len); - cur_name_len = gfs16_to_cpu(dent->de_name_len); - - if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || - (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)) - return TRUE; - } while (dirent_next(dip, bh, &dent) == 0); - - return FALSE; -} - -/** - * leaf_search - * @bh: - * @filename: - * @dent_out: - * @dent_prev: - * - * Returns: - */ - -static int -leaf_search(struct gfs_inode *dip, - struct buffer_head *bh, struct qstr *filename, - struct gfs_dirent **dent_out, struct gfs_dirent **dent_prev) -{ - uint32_t hash; - struct gfs_dirent *dent, *prev = NULL; - unsigned int entries = 0; - int type; - - type = dirent_first(dip, bh, &dent); - if (type < 0) - return type; - - if (type == IS_LEAF) { - struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; - entries = gfs16_to_cpu(leaf->lf_entries); - } else if (type == IS_DINODE) { - struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; - entries = gfs32_to_cpu(dinode->di_entries); - } - - hash = gfs_dir_hash(filename->name, filename->len); - - do { - if (!dent->de_inum.no_formal_ino) { - prev = dent; - continue; - } - - if (gfs32_to_cpu(dent->de_hash) == hash && - gfs_filecmp(filename, (char *)(dent + 1), - gfs16_to_cpu(dent->de_name_len))) { - *dent_out = dent; - if (dent_prev) - *dent_prev = prev; - - return 0; - } - - prev = dent; - } while (dirent_next(dip, bh, &dent) == 0); - - return -ENOENT; -} - -/** - * get_leaf - Get leaf - * @dip: - * @leaf_no: - * @bh_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int -get_leaf(struct gfs_inode *dip, uint64_t leaf_no, struct buffer_head **bhp) -{ - int error; - - error = gfs_dread(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp); - if (!error && gfs_metatype_check(dip->i_sbd, *bhp, GFS_METATYPE_LF)) - error = -EIO; - - return error; -} - -/** - * get_leaf_nr - Get a leaf number associated with the index - * @dip: The GFS inode - * @index: - * @leaf_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int -get_leaf_nr(struct gfs_inode *dip, uint32_t index, uint64_t *leaf_out) -{ - uint64_t leaf_no; - int error; - - error = gfs_internal_read(dip, (char *)&leaf_no, - index * sizeof(uint64_t), - sizeof(uint64_t)); - if (error != sizeof(uint64_t)) - return (error < 0) ? error : -EIO; - - *leaf_out = gfs64_to_cpu(leaf_no); - - return 0; -} - -/** - * get_first_leaf - Get first leaf - * @dip: The GFS inode - * @index: - * @bh_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int -get_first_leaf(struct gfs_inode *dip, uint32_t index, - struct buffer_head **bh_out) -{ - uint64_t leaf_no; - int error; - - error = get_leaf_nr(dip, index, &leaf_no); - if (!error) - error = get_leaf(dip, leaf_no, bh_out); - - return error; -} - -/** - * get_next_leaf - Get next leaf - * @dip: The GFS inode - * @bh_in: The buffer - * @bh_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int -get_next_leaf(struct gfs_inode *dip, struct buffer_head *bh_in, - struct buffer_head **bh_out) -{ - struct gfs_leaf *leaf; - int error; - - leaf = (struct gfs_leaf *)bh_in->b_data; - - if (!leaf->lf_next) - error = -ENOENT; - else - error = get_leaf(dip, gfs64_to_cpu(leaf->lf_next), bh_out); - - return error; -} - -/** - * linked_leaf_search - Linked leaf search - * @dip: The GFS inode - * @filename: The filename to search for - * @dent_out: - * @dent_prev: - * @bh_out: - * - * Returns: 0 on sucess, error code otherwise - */ - -static int -linked_leaf_search(struct gfs_inode *dip, struct qstr *filename, - struct gfs_dirent **dent_out, struct gfs_dirent **dent_prev, - struct buffer_head **bh_out) -{ - struct buffer_head *bh = NULL, *bh_next; - uint32_t hsize, index; - uint32_t hash; - int error; - - hsize = 1 << dip->i_di.di_depth; - if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { - gfs_consist_inode(dip); - return -EIO; - } - - /* Figure out the address of the leaf node. */ - - hash = gfs_dir_hash(filename->name, filename->len); - index = hash >> (32 - dip->i_di.di_depth); - - error = get_first_leaf(dip, index, &bh_next); - if (error) - return error; - - /* Find the entry */ - - do { - if (bh) - brelse(bh); - - bh = bh_next; - - error = leaf_search(dip, bh, filename, dent_out, dent_prev); - switch (error) { - case 0: - *bh_out = bh; - return 0; - - case -ENOENT: - break; - - default: - brelse(bh); - return error; - } - - error = get_next_leaf(dip, bh, &bh_next); - } - while (!error); - - brelse(bh); - - return error; -} - -/** - * dir_make_exhash - Convert a stuffed directory into an ExHash directory - * @dip: The GFS inode - * - * Returns: 0 on success, error code otherwise - */ - -static int -dir_make_exhash(struct gfs_inode *dip) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_dirent *dent; - struct buffer_head *bh, *dibh; - struct gfs_leaf *leaf; - int y; - uint32_t x; - uint64_t *lp, bn; - int error; - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - /* Allocate a new block for the first leaf node */ - - error = gfs_metaalloc(dip, &bn); - if (error) - goto fail; - - /* Turn over a new leaf */ - - error = gfs_dread(dip->i_gl, bn, DIO_NEW | DIO_START | DIO_WAIT, &bh); - if (error) - goto fail; - - gfs_trans_add_bh(dip->i_gl, bh); - gfs_metatype_set(bh, GFS_METATYPE_LF, GFS_FORMAT_LF); - gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); - - /* Fill in the leaf structure */ - - leaf = (struct gfs_leaf *)bh->b_data; - - gfs_assert(sdp, dip->i_di.di_entries < (1 << 16),); - - leaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); - leaf->lf_entries = cpu_to_gfs16(dip->i_di.di_entries); - - /* Copy dirents */ - - gfs_buffer_copy_tail(bh, sizeof(struct gfs_leaf), dibh, - sizeof(struct gfs_dinode)); - - /* Find last entry */ - - x = 0; - dirent_first(dip, bh, &dent); - - do { - if (!dent->de_inum.no_formal_ino) - continue; - if (++x == dip->i_di.di_entries) - break; - } - while (dirent_next(dip, bh, &dent) == 0); - - /* Adjust the last dirent's record length - (Remember that dent still points to the last entry.) */ - - dent->de_rec_len = gfs16_to_cpu(dent->de_rec_len) + - sizeof(struct gfs_dinode) - - sizeof(struct gfs_leaf); - dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); - - brelse(bh); - - /* We're done with the new leaf block, now setup the new - hash table. */ - - gfs_trans_add_bh(dip->i_gl, dibh); - gfs_buffer_clear_tail(dibh, sizeof (struct gfs_dinode)); - - lp = (uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)); - - for (x = sdp->sd_hash_ptrs; x--; lp++) - *lp = cpu_to_gfs64(bn); - - dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; - dip->i_di.di_blocks++; - dip->i_di.di_flags |= GFS_DIF_EXHASH; - dip->i_di.di_payload_format = 0; - - for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; - dip->i_di.di_depth = y; - - gfs_dinode_out(&dip->i_di, dibh->b_data); - - brelse(dibh); - - return 0; - - fail: - brelse(dibh); - return error; -} - -/** - * dir_split_leaf - Split a leaf block into two - * @dip: The GFS inode - * @index: - * @leaf_no: - * - * Returns: 0 on success, error code on failure - */ - -static int -dir_split_leaf(struct gfs_inode *dip, uint32_t index, uint64_t leaf_no) -{ - struct buffer_head *nbh, *obh, *dibh; - struct gfs_leaf *nleaf, *oleaf; - struct gfs_dirent *dent, *prev = NULL, *next = NULL, *new; - uint32_t start, len, half_len, divider; - uint64_t bn, *lp; - uint32_t name_len; - int x, moved = FALSE; - int error, lp_vfree=0; - - /* Allocate the new leaf block */ - - error = gfs_metaalloc(dip, &bn); - if (error) - return error; - - /* Get the new leaf block */ - - error = gfs_dread(dip->i_gl, bn, - DIO_NEW | DIO_START | DIO_WAIT, &nbh); - if (error) - return error; - - gfs_trans_add_bh(dip->i_gl, nbh); - gfs_metatype_set(nbh, GFS_METATYPE_LF, GFS_FORMAT_LF); - gfs_buffer_clear_tail(nbh, sizeof (struct gfs_meta_header)); - - nleaf = (struct gfs_leaf *)nbh->b_data; - - nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); - - /* Get the old leaf block */ - - error = get_leaf(dip, leaf_no, &obh); - if (error) - goto fail; - - gfs_trans_add_bh(dip->i_gl, obh); - - oleaf = (struct gfs_leaf *)obh->b_data; - - /* Compute the start and len of leaf pointers in the hash table. */ - - len = 1 << (dip->i_di.di_depth - gfs16_to_cpu(oleaf->lf_depth)); - half_len = len >> 1; - if (!half_len) { - gfs_consist_inode(dip); - error = -EIO; - goto fail_brelse; - } - - start = (index & ~(len - 1)); - - /* Change the pointers. - Don't bother distinguishing stuffed from non-stuffed. - This code is complicated enough already. */ - - lp = kmalloc(half_len * sizeof (uint64_t), GFP_KERNEL); - if (unlikely(!lp)) { - lp = vmalloc(half_len * sizeof (uint64_t)); - if (!lp) { - printk("GFS: dir_split_leaf vmalloc fail - half_len=%d\n", half_len); - error = -ENOMEM; - goto fail_brelse; - } else - lp_vfree = 1; - } - - error = gfs_internal_read(dip, (char *)lp, start * sizeof(uint64_t), - half_len * sizeof(uint64_t)); - if (error != half_len * sizeof(uint64_t)) { - if (error >= 0) - error = -EIO; - goto fail_lpfree; - } - - /* Change the pointers */ - - for (x = 0; x < half_len; x++) - lp[x] = cpu_to_gfs64(bn); - - error = gfs_internal_write(dip, (char *)lp, start * sizeof(uint64_t), - half_len * sizeof(uint64_t)); - if (error != half_len * sizeof(uint64_t)) { - if (error >= 0) - error = -EIO; - goto fail_lpfree; - } - - if (unlikely(lp_vfree)) - vfree(lp); - else - kfree(lp); - - /* Compute the divider */ - - divider = (start + half_len) << (32 - dip->i_di.di_depth); - - /* Copy the entries */ - - dirent_first(dip, obh, &dent); - - do { - next = dent; - if (dirent_next(dip, obh, &next)) - next = NULL; - - if (dent->de_inum.no_formal_ino && - gfs32_to_cpu(dent->de_hash) < divider) { - name_len = gfs16_to_cpu(dent->de_name_len); - - error = gfs_dirent_alloc(dip, nbh, name_len, &new); - if (error) - goto fail_brelse; - - new->de_inum = dent->de_inum; /* No endianness worries */ - new->de_hash = dent->de_hash; /* No endianness worries */ - new->de_type = dent->de_type; /* No endianness worries */ - memcpy((char *)(new + 1), (char *)(dent + 1), - name_len); - - nleaf->lf_entries = gfs16_to_cpu(nleaf->lf_entries) + 1; - nleaf->lf_entries = cpu_to_gfs16(nleaf->lf_entries); - - dirent_del(dip, obh, prev, dent); - - if (!oleaf->lf_entries) - gfs_consist_inode(dip); - oleaf->lf_entries = gfs16_to_cpu(oleaf->lf_entries) - 1; - oleaf->lf_entries = cpu_to_gfs16(oleaf->lf_entries); - - if (!prev) - prev = dent; - - moved = TRUE; - } else - prev = dent; - - dent = next; - } - while (dent); - - /* If none of the entries got moved into the new leaf, - artificially fill in the first entry. */ - - if (!moved) { - error = gfs_dirent_alloc(dip, nbh, 0, &new); - if (error) - goto fail_brelse; - new->de_inum.no_formal_ino = 0; - } - - oleaf->lf_depth = gfs16_to_cpu(oleaf->lf_depth) + 1; - oleaf->lf_depth = cpu_to_gfs16(oleaf->lf_depth); - nleaf->lf_depth = oleaf->lf_depth; - - error = gfs_get_inode_buffer(dip, &dibh); - if (!gfs_assert_withdraw(dip->i_sbd, !error)) { - gfs_trans_add_bh(dip->i_gl, dibh); - dip->i_di.di_blocks++; - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - } - - brelse(obh); - brelse(nbh); - - return error; - - fail_lpfree: - if (unlikely(lp_vfree)) - vfree(lp); - else - kfree(lp); - - fail_brelse: - brelse(obh); - - fail: - brelse(nbh); - return error; -} - -/** - * dir_double_exhash - Double size of ExHash table - * @dip: The GFS dinode - * - * Returns: 0 on success, error code on failure - */ - -static int -dir_double_exhash(struct gfs_inode *dip) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct buffer_head *dibh; - uint32_t hsize; - uint64_t *buf; - uint64_t *from, *to; - uint64_t block; - int x; - int error = 0; - - hsize = 1 << dip->i_di.di_depth; - if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { - gfs_consist_inode(dip); - return -EIO; - } - - /* Allocate both the "from" and "to" buffers in one big chunk */ - - buf = gmalloc(3 * sdp->sd_hash_bsize); - - for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { - error = gfs_internal_read(dip, (char *)buf, - block * sdp->sd_hash_bsize, - sdp->sd_hash_bsize); - if (error != sdp->sd_hash_bsize) { - if (error >= 0) - error = -EIO; - goto fail; - } - - from = buf; - to = (uint64_t *)((char *)buf + sdp->sd_hash_bsize); - - for (x = sdp->sd_hash_ptrs; x--; from++) { - *to++ = *from; /* No endianess worries */ - *to++ = *from; - } - - error = gfs_internal_write(dip, (char *)buf + sdp->sd_hash_bsize, - block * sdp->sd_sb.sb_bsize, - sdp->sd_sb.sb_bsize); - if (error != sdp->sd_sb.sb_bsize) { - if (error >= 0) - error = -EIO; - goto fail; - } - } - - kfree(buf); - - error = gfs_get_inode_buffer(dip, &dibh); - if (!gfs_assert_withdraw(sdp, !error)) { - gfs_trans_add_bh(dip->i_gl, dibh); - dip->i_di.di_depth++; - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - } - - return error; - - fail: - kfree(buf); - - return error; -} - -/** - * compare_dents - compare directory entries by hash value - * @a: first dent - * @b: second dent - * - * When comparing the hash entries of @a to @b: - * gt: returns 1 - * lt: returns -1 - * eq: returns 0 - */ - -static int -compare_dents(const void *a, const void *b) -{ - struct gfs_dirent *dent_a, *dent_b; - uint32_t hash_a, hash_b; - int ret = 0; - - dent_a = *(struct gfs_dirent **)a; - hash_a = dent_a->de_hash; - hash_a = gfs32_to_cpu(hash_a); - - dent_b = *(struct gfs_dirent **)b; - hash_b = dent_b->de_hash; - hash_b = gfs32_to_cpu(hash_b); - - if (hash_a > hash_b) - ret = 1; - else if (hash_a < hash_b) - ret = -1; - else { - unsigned int len_a = gfs16_to_cpu(dent_a->de_name_len); - unsigned int len_b = gfs16_to_cpu(dent_b->de_name_len); - - if (len_a > len_b) - ret = 1; - else if (len_a < len_b) - ret = -1; - else - ret = memcmp((char *)(dent_a + 1), - (char *)(dent_b + 1), - len_a); - } - - return ret; -} - -/** - * do_filldir_main - read out directory entries - * @dip: The GFS inode - * @offset: The offset in the file to read from - * @opaque: opaque data to pass to filldir - * @filldir: The function to pass entries to - * @darr: an array of struct gfs_dirent pointers to read - * @entries: the number of entries in darr - * @copied: pointer to int that's non-zero if a entry has been copied out - * - * Jump through some hoops to make sure that if there are hash collsions, - * they are read out at the beginning of a buffer. We want to minimize - * the possibility that they will fall into different readdir buffers or - * that someone will want to seek to that location. - * - * Returns: errno, >0 on exception from filldir - */ - -static int -do_filldir_main(struct gfs_inode *dip, uint64_t *offset, - void *opaque, gfs_filldir_t filldir, - struct gfs_dirent **darr, uint32_t entries, int *copied) -{ - struct gfs_dirent *dent, *dent_next; - struct gfs_inum inum; - uint64_t off, off_next; - unsigned int x, y; - int run = FALSE; - int error = 0; - - gfs_sort(darr, entries, sizeof(struct gfs_dirent *), compare_dents); - - dent_next = darr[0]; - off_next = gfs32_to_cpu(dent_next->de_hash); - off_next = gfs_dir_hash2offset(off_next); - - for (x = 0, y = 1; x < entries; x++, y++) { - dent = dent_next; - off = off_next; - - if (y < entries) { - dent_next = darr[y]; - off_next = gfs32_to_cpu(dent_next->de_hash); - off_next = gfs_dir_hash2offset(off_next); - - if (off < *offset) - continue; - *offset = off; - - if (off_next == off) { - if (*copied && !run) - return 1; - run = TRUE; - } else - run = FALSE; - } else { - if (off < *offset) - continue; - *offset = off; - } - - gfs_inum_in(&inum, (char *)&dent->de_inum); - - error = filldir(opaque, (char *)(dent + 1), - gfs16_to_cpu(dent->de_name_len), - off, &inum, - gfs16_to_cpu(dent->de_type)); - if (error) - return 1; - - *copied = TRUE; - } - - /* Increment the *offset by one, so the next time we come into the do_filldir fxn, - we get the next entry instead of the last one in the current leaf */ - - (*offset)++; - - return 0; -} - -/** - * do_filldir_single - Read directory entries out of a single block - * @dip: The GFS inode - * @offset: The offset in the file to read from - * @opaque: opaque data to pass to filldir - * @filldir: The function to pass entries to - * @bh: the block - * @entries: the number of entries in the block - * @copied: pointer to int that's non-zero if a entry has been copied out - * - * Returns: errno, >0 on exception from filldir - */ - -static int -do_filldir_single(struct gfs_inode *dip, uint64_t *offset, - void *opaque, gfs_filldir_t filldir, - struct buffer_head *bh, uint32_t entries, int *copied) -{ - struct gfs_dirent **darr; - struct gfs_dirent *de; - unsigned int e = 0; - int error, do_vfree=0; - - if (!entries) - return 0; - - darr = kmalloc(entries * sizeof(struct gfs_dirent *), GFP_KERNEL); - if (unlikely(!darr)) { - darr = vmalloc(entries * sizeof (struct gfs_dirent *)); - if (!darr) { - printk("GFS: do_filldir_single vmalloc fails, entries=%d\n", entries); - return -ENOMEM; - } - else - do_vfree = 1; - } - - dirent_first(dip, bh, &de); - do { - if (!de->de_inum.no_formal_ino) - continue; - if (e >= entries) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - darr[e++] = de; - } - while (dirent_next(dip, bh, &de) == 0); - - if (e != entries) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - - error = do_filldir_main(dip, offset, opaque, filldir, darr, - entries, copied); - - out: - if (unlikely(do_vfree)) - vfree(darr); - else - kfree(darr); - - return error; -} - -/** - * do_filldir_multi - Read directory entries out of a linked leaf list - * @dip: The GFS inode - * @offset: The offset in the file to read from - * @opaque: opaque data to pass to filldir - * @filldir: The function to pass entries to - * @bh: the first leaf in the list - * @copied: pointer to int that's non-zero if a entry has been copied out - * - * Returns: errno, >0 on exception from filldir - */ - -static int -do_filldir_multi(struct gfs_inode *dip, uint64_t *offset, - void *opaque, gfs_filldir_t filldir, - struct buffer_head *bh, int *copied) -{ - struct buffer_head **larr = NULL; - struct gfs_dirent **darr; - struct gfs_leaf *leaf; - struct buffer_head *tmp_bh; - struct gfs_dirent *de; - unsigned int entries, e = 0; - unsigned int leaves = 0, l = 0; - unsigned int x; - uint64_t ln; - int error = 0, leaves_vfree=0, entries_vfree=0; - - /* Count leaves and entries */ - - leaf = (struct gfs_leaf *)bh->b_data; - entries = gfs16_to_cpu(leaf->lf_entries); - ln = leaf->lf_next; - - while (ln) { - ln = gfs64_to_cpu(ln); - - error = get_leaf(dip, ln, &tmp_bh); - if (error) - return error; - - leaf = (struct gfs_leaf *)tmp_bh->b_data; - if (leaf->lf_entries) { - entries += gfs16_to_cpu(leaf->lf_entries); - leaves++; - } - ln = leaf->lf_next; - - brelse(tmp_bh); - } - - /* Bail out if there's nothing to do */ - - if (!entries) - return 0; - - /* Alloc arrays */ - - if (leaves) { - larr = kmalloc(leaves * sizeof(struct buffer_head *), GFP_KERNEL); - if (unlikely(!larr)) { - larr = vmalloc(leaves * sizeof (struct buffer_head *)); - if (!larr) { - printk("GFS: do_filldir_multi vmalloc fails leaves=%d\n", leaves); - return -ENOMEM; - } else - leaves_vfree = 1; - } - } - - darr = kmalloc(entries * sizeof(struct gfs_dirent *), GFP_KERNEL); - if (unlikely(!darr)) { - darr = vmalloc(entries * sizeof (struct gfs_dirent *)); - if (!darr) { - printk("GFS: do_filldir_multi vmalloc fails entries=%d\n", entries); - if (larr) { - if (leaves_vfree) - vfree(larr); - else - kfree(larr); - } - return -ENOMEM; - } else - entries_vfree = 1; - } - if (!darr) { - if (larr) - kfree(larr); - return -ENOMEM; - } - - /* Fill in arrays */ - - leaf = (struct gfs_leaf *)bh->b_data; - if (leaf->lf_entries) { - dirent_first(dip, bh, &de); - do { - if (!de->de_inum.no_formal_ino) - continue; - if (e >= entries) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - darr[e++] = de; - } - while (dirent_next(dip, bh, &de) == 0); - } - ln = leaf->lf_next; - - while (ln) { - ln = gfs64_to_cpu(ln); - - error = get_leaf(dip, ln, &tmp_bh); - if (error) - goto out; - - leaf = (struct gfs_leaf *)tmp_bh->b_data; - if (leaf->lf_entries) { - dirent_first(dip, tmp_bh, &de); - do { - if (!de->de_inum.no_formal_ino) - continue; - if (e >= entries) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - darr[e++] = de; - } - while (dirent_next(dip, tmp_bh, &de) == 0); - - larr[l++] = tmp_bh; - - ln = leaf->lf_next; - } else { - ln = leaf->lf_next; - brelse(tmp_bh); - } - } - - if (gfs_assert_withdraw(dip->i_sbd, l == leaves)) { - error = -EIO; - goto out; - } - if (e != entries) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - - /* Do work */ - - error = do_filldir_main(dip, offset, opaque, filldir, darr, - entries, copied); - - /* Clean up */ - - out: - if (unlikely(entries_vfree)) - vfree(darr); - else - kfree(darr); - - for (x = 0; x < l; x++) - brelse(larr[x]); - - if (leaves) { - if (unlikely(leaves_vfree)) - vfree(larr); - else - kfree(larr); - } - - return error; -} - -/** - * dir_e_search - Search exhash (leaf) dir for inode matching name - * @dip: The GFS inode - * @filename: Filename string - * @inode: If non-NULL, function fills with formal inode # and block address - * @type: If non-NULL, function fills with GFS_FILE_... dinode type - * - * Returns: - */ - -static int -dir_e_search(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int *type) -{ - struct buffer_head *bh; - struct gfs_dirent *dent; - int error; - - error = linked_leaf_search(dip, filename, &dent, NULL, &bh); - if (error) - return error; - - if (inum) - gfs_inum_in(inum, (char *)&dent->de_inum); - if (type) - *type = gfs16_to_cpu(dent->de_type); - - brelse(bh); - - return 0; -} - -/** - * dir_e_add - - * @dip: The GFS inode - * @filename: - * @inode: - * @type: - * - */ - -static int -dir_e_add(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int type) -{ - struct buffer_head *bh, *nbh, *dibh; - struct gfs_leaf *leaf, *nleaf; - struct gfs_dirent *dent; - uint32_t hsize, index; - uint32_t hash; - uint64_t leaf_no, bn; - int error; - - restart: - hsize = 1 << dip->i_di.di_depth; - if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { - gfs_consist_inode(dip); - return -EIO; - } - - /* Figure out the address of the leaf node. */ - - hash = gfs_dir_hash(filename->name, filename->len); - index = hash >> (32 - dip->i_di.di_depth); - - error = get_leaf_nr(dip, index, &leaf_no); - if (error) - return error; - - /* Add entry to the leaf */ - - for (;;) { - error = get_leaf(dip, leaf_no, &bh); - if (error) - return error; - - leaf = (struct gfs_leaf *)bh->b_data; - - if (gfs_dirent_alloc(dip, bh, filename->len, &dent)) { - - if (gfs16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) { - /* Can we split the leaf? */ - - brelse(bh); - - error = dir_split_leaf(dip, index, leaf_no); - if (error) - return error; - - goto restart; - - } else if (dip->i_di.di_depth < GFS_DIR_MAX_DEPTH) { - /* Can we double the hash table? */ - - brelse(bh); - - error = dir_double_exhash(dip); - if (error) - return error; - - goto restart; - - } else if (leaf->lf_next) { - /* Can we try the next leaf in the list? */ - leaf_no = gfs64_to_cpu(leaf->lf_next); - brelse(bh); - continue; - - } else { - /* Create a new leaf and add it to the list. */ - - error = gfs_metaalloc(dip, &bn); - if (error) { - brelse(bh); - return error; - } - - error = gfs_dread(dip->i_gl, bn, - DIO_NEW | DIO_START | DIO_WAIT, - &nbh); - if (error) { - brelse(bh); - return error; - } - - gfs_trans_add_bh(dip->i_gl, nbh); - gfs_metatype_set(nbh, - GFS_METATYPE_LF, - GFS_FORMAT_LF); - gfs_buffer_clear_tail(nbh, - sizeof(struct gfs_meta_header)); - - gfs_trans_add_bh(dip->i_gl, bh); - leaf->lf_next = cpu_to_gfs64(bn); - - nleaf = (struct gfs_leaf *)nbh->b_data; - nleaf->lf_depth = leaf->lf_depth; - nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); - - error = gfs_dirent_alloc(dip, nbh, filename->len, &dent); - if (error) - return error; - - dip->i_di.di_blocks++; - - brelse(bh); - - bh = nbh; - leaf = nleaf; - } - } - - /* If the gfs_dirent_alloc() succeeded, it pinned the "bh". */ - - gfs_inum_out(inum, (char *)&dent->de_inum); - dent->de_hash = cpu_to_gfs32(hash); - dent->de_type = cpu_to_gfs16(type); - memcpy((char *)(dent + 1), filename->name, filename->len); - - leaf->lf_entries = gfs16_to_cpu(leaf->lf_entries) + 1; - leaf->lf_entries = cpu_to_gfs16(leaf->lf_entries); - - brelse(bh); - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - dip->i_di.di_entries++; - dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(dip->i_gl, dibh); - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - - return 0; - } - - return -ENOENT; -} - -/** - * dir_e_del - - * @dip: The GFS inode - * @filename: - * - * Returns: - */ - -static int -dir_e_del(struct gfs_inode *dip, struct qstr *filename) -{ - struct buffer_head *bh, *dibh; - struct gfs_dirent *dent, *prev; - struct gfs_leaf *leaf; - unsigned int entries; - int error; - - error = linked_leaf_search(dip, filename, &dent, &prev, &bh); - if (error == -ENOENT) { - gfs_consist_inode(dip); - return -EIO; - } - if (error) - return error; - - dirent_del(dip, bh, prev, dent); /* Pins bh */ - - leaf = (struct gfs_leaf *)bh->b_data; - entries = gfs16_to_cpu(leaf->lf_entries); - if (!entries) - gfs_consist_inode(dip); - entries--; - leaf->lf_entries = cpu_to_gfs16(entries); - - brelse(bh); - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - if (!dip->i_di.di_entries) - gfs_consist_inode(dip); - dip->i_di.di_entries--; - dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(dip->i_gl, dibh); - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - - return 0; -} - -/** - * dir_e_read - Reads the entries from a directory into a filldir buffer - * @dip: dinode pointer - * @offset: the hash of the last entry read shifted to the right once - * @opaque: buffer for the filldir function to fill - * @filldir: points to the filldir function to use - * - * Returns: errno - */ - -static int -dir_e_read(struct gfs_inode *dip, uint64_t *offset, void *opaque, - gfs_filldir_t filldir) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct buffer_head *bh; - struct gfs_leaf leaf; - uint32_t hsize, len; - uint32_t ht_offset, lp_offset, ht_offset_cur = -1; - uint32_t hash, index; - uint64_t *lp; - int copied = FALSE; - int error = 0; - - hsize = 1 << dip->i_di.di_depth; - if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { - gfs_consist_inode(dip); - return -EIO; - } - - hash = gfs_dir_offset2hash(*offset); - index = hash >> (32 - dip->i_di.di_depth); - - lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); - if (!lp) - return -ENOMEM; - - while (index < hsize) { - lp_offset = index & (sdp->sd_hash_ptrs - 1); - ht_offset = index - lp_offset; - - if (ht_offset_cur != ht_offset) { - error = gfs_internal_read(dip, (char *)lp, - ht_offset * sizeof(uint64_t), - sdp->sd_hash_bsize); - if (error != sdp->sd_hash_bsize) { - if (error >= 0) - error = -EIO; - goto out; - } - ht_offset_cur = ht_offset; - } - - error = get_leaf(dip, gfs64_to_cpu(lp[lp_offset]), &bh); - if (error) - goto out; - - gfs_leaf_in(&leaf, bh->b_data); - - if (leaf.lf_next) - error = do_filldir_multi(dip, offset, - opaque, filldir, - bh, &copied); - else - error = do_filldir_single(dip, offset, - opaque, filldir, - bh, leaf.lf_entries, - &copied); - - brelse(bh); - - if (error) { - if (error > 0) - error = 0; - goto out; - } - - len = 1 << (dip->i_di.di_depth - leaf.lf_depth); - index = (index & ~(len - 1)) + len; - } - - out: - kfree(lp); - - return error; -} - -/** - * dir_e_mvino - - * @dip: The GFS inode - * @filename: - * @new_inode: - * - * Returns: - */ - -static int -dir_e_mvino(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int new_type) -{ - struct buffer_head *bh, *dibh; - struct gfs_dirent *dent; - int error; - - error = linked_leaf_search(dip, filename, &dent, NULL, &bh); - if (error == -ENOENT) { - gfs_consist_inode(dip); - return -EIO; - } - if (error) - return error; - - gfs_trans_add_bh(dip->i_gl, bh); - - gfs_inum_out(inum, (char *)&dent->de_inum); - dent->de_type = cpu_to_gfs16(new_type); - - brelse(bh); - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(dip->i_gl, dibh); - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - - return 0; -} - -/** - * dir_l_search - Search linear (stuffed dinode) dir for inode matching name - * @dip: The GFS inode - * @filename: Filename string - * @inode: If non-NULL, function fills with formal inode # and block address - * @type: If non-NULL, function fills with GFS_FILE_... dinode type - * - * Returns: - */ - -static int -dir_l_search(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int *type) -{ - struct buffer_head *dibh; - struct gfs_dirent *dent; - int error; - - if (!gfs_is_stuffed(dip)) { - gfs_consist_inode(dip); - return -EIO; - } - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - error = leaf_search(dip, dibh, filename, &dent, NULL); - if (!error) { - if (inum) - gfs_inum_in(inum, (char *)&dent->de_inum); - if (type) - *type = gfs16_to_cpu(dent->de_type); - } - - brelse(dibh); - - return error; -} - -/** - * dir_l_add - - * @dip: The GFS inode - * @filename: - * @inode: - * @type: - * - * Returns: - */ - -static int -dir_l_add(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int type) -{ - struct buffer_head *dibh; - struct gfs_dirent *dent; - int error; - - if (!gfs_is_stuffed(dip)) { - gfs_consist_inode(dip); - return -EIO; - } - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - gfs_trans_add_bh(dip->i_gl, dibh); - if (gfs_dirent_alloc(dip, dibh, filename->len, &dent)) { - brelse(dibh); - - error = dir_make_exhash(dip); - if (!error) - error = dir_e_add(dip, filename, inum, type); - - return error; - } - - /* gfs_dirent_alloc() pins */ - - gfs_inum_out(inum, (char *)&dent->de_inum); - dent->de_hash = gfs_dir_hash(filename->name, filename->len); - dent->de_hash = cpu_to_gfs32(dent->de_hash); - dent->de_type = cpu_to_gfs16(type); - memcpy((char *)(dent + 1), filename->name, filename->len); - - dip->i_di.di_entries++; - dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); - - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - - return 0; -} - -/** - * dir_l_del - - * @dip: The GFS inode - * @filename: - * - * Returns: - */ - -static int -dir_l_del(struct gfs_inode *dip, struct qstr *filename) -{ - struct buffer_head *dibh; - struct gfs_dirent *dent, *prev; - int error; - - if (!gfs_is_stuffed(dip)) { - gfs_consist_inode(dip); - return -EIO; - } - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - error = leaf_search(dip, dibh, filename, &dent, &prev); - if (error == -ENOENT) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - if (error) - goto out; - - dirent_del(dip, dibh, prev, dent); - - /* dirent_del() pins */ - - if (!dip->i_di.di_entries) - gfs_consist_inode(dip); - dip->i_di.di_entries--; - - dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); - - gfs_dinode_out(&dip->i_di, dibh->b_data); - - out: - brelse(dibh); - - return error; -} - -/** - * dir_l_read - - * @dip: - * @offset: - * @opaque: - * @filldir: - * - * Returns: - */ - -static int -dir_l_read(struct gfs_inode *dip, uint64_t *offset, void *opaque, - gfs_filldir_t filldir) -{ - struct buffer_head *dibh; - int copied = FALSE; - int error; - - if (!gfs_is_stuffed(dip)) { - gfs_consist_inode(dip); - return -EIO; - } - - if (!dip->i_di.di_entries) - return 0; - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - error = do_filldir_single(dip, offset, - opaque, filldir, - dibh, dip->i_di.di_entries, - &copied); - if (error > 0) - error = 0; - - brelse(dibh); - - return error; -} - -/** - * dir_l_mvino - - * @dip: - * @filename: - * @new_inode: - * - * Returns: - */ - -static int -dir_l_mvino(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int new_type) -{ - struct buffer_head *dibh; - struct gfs_dirent *dent; - int error; - - if (!gfs_is_stuffed(dip)) { - gfs_consist_inode(dip); - return -EIO; - } - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - return error; - - error = leaf_search(dip, dibh, filename, &dent, NULL); - if (error == -ENOENT) { - gfs_consist_inode(dip); - error = -EIO; - goto out; - } - if (error) - goto out; - - gfs_trans_add_bh(dip->i_gl, dibh); - - gfs_inum_out(inum, (char *)&dent->de_inum); - dent->de_type = cpu_to_gfs16(new_type); - - dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); - - gfs_dinode_out(&dip->i_di, dibh->b_data); - - out: - brelse(dibh); - - return error; -} - -/** - * gfs_dir_search - Search a directory - * @dip: The GFS inode - * @filename: - * @inode: - * - * This routine searches a directory for a file or another directory. - * Assumes a glock is held on dip. - * - * Returns: errno - */ - -int -gfs_dir_search(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int *type) -{ - int error; - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_search(dip, filename, inum, type); - else - error = dir_l_search(dip, filename, inum, type); - - return error; -} - -/** - * gfs_dir_add - Add new filename into directory - * @dip: The GFS inode - * @filename: The new name - * @inode: The inode number of the entry - * @type: The type of the entry - * - * Returns: 0 on success, error code on failure - */ - -int -gfs_dir_add(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int type) -{ - int error; - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_add(dip, filename, inum, type); - else - error = dir_l_add(dip, filename, inum, type); - - return error; -} - -/** - * gfs_dir_del - Delete a directory entry - * @dip: The GFS inode - * @filename: The filename - * - * Returns: 0 on success, error code on failure - */ - -int -gfs_dir_del(struct gfs_inode *dip, struct qstr *filename) -{ - int error; - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_del(dip, filename); - else - error = dir_l_del(dip, filename); - - return error; -} - -/** - * gfs_dir_read - Translate a GFS filename - * @dip: The GFS inode - * @offset: - * @opaque: - * @filldir: - * - * Returns: 0 on success, error code otherwise - */ - -int -gfs_dir_read(struct gfs_inode *dip, uint64_t * offset, void *opaque, - gfs_filldir_t filldir) -{ - int error; - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_read(dip, offset, opaque, filldir); - else - error = dir_l_read(dip, offset, opaque, filldir); - - return error; -} - -/** - * gfs_dir_mvino - Change inode number of directory entry - * @dip: The GFS inode - * @filename: - * @new_inode: - * - * This routine changes the inode number of a directory entry. It's used - * by rename to change ".." when a directory is moved. - * Assumes a glock is held on dvp. - * - * Returns: errno - */ - -int -gfs_dir_mvino(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int new_type) -{ - int error; - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_mvino(dip, filename, inum, new_type); - else - error = dir_l_mvino(dip, filename, inum, new_type); - - return error; -} - -/** - * foreach_leaf - call a function for each leaf in a directory - * @dip: the directory - * @lc: the function to call for each each - * @data: private data to pass to it - * - * Returns: errno - */ - -static int -foreach_leaf(struct gfs_inode *dip, leaf_call_t lc, void *data) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct buffer_head *bh; - struct gfs_leaf leaf; - uint32_t hsize, len; - uint32_t ht_offset, lp_offset, ht_offset_cur = -1; - uint32_t index = 0; - uint64_t *lp; - uint64_t leaf_no; - int error = 0; - - hsize = 1 << dip->i_di.di_depth; - if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { - gfs_consist_inode(dip); - return -EIO; - } - - lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); - if (!lp) - return -ENOMEM; - - while (index < hsize) { - lp_offset = index & (sdp->sd_hash_ptrs - 1); - ht_offset = index - lp_offset; - - if (ht_offset_cur != ht_offset) { - error = gfs_internal_read(dip, (char *)lp, - ht_offset * sizeof(uint64_t), - sdp->sd_hash_bsize); - if (error != sdp->sd_hash_bsize) { - if (error >= 0) - error = -EIO; - goto out; - } - ht_offset_cur = ht_offset; - } - - leaf_no = gfs64_to_cpu(lp[lp_offset]); - if (leaf_no) { - error = get_leaf(dip, leaf_no, &bh); - if (error) - goto out; - gfs_leaf_in(&leaf, bh->b_data); - brelse(bh); - - len = 1 << (dip->i_di.di_depth - leaf.lf_depth); - - error = lc(dip, index, len, leaf_no, data); - if (error) - goto out; - - index = (index & ~(len - 1)) + len; - } else - index++; - } - - if (index != hsize) { - gfs_consist_inode(dip); - error = -EIO; - } - - out: - kfree(lp); - - return error; -} - -/** - * leaf_free - Deallocate a directory leaf - * @dip: the directory - * @index: the hash table offset in the directory - * @len: the number of pointers to this leaf - * @leaf_no: the leaf number - * @data: not used - * - * Returns: errno - */ - -static int -leaf_free(struct gfs_inode *dip, - uint32_t index, uint32_t len, - uint64_t leaf_no, void *data) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_leaf tmp_leaf; - struct gfs_rgrp_list rlist; - struct buffer_head *bh, *dibh; - uint64_t blk; - unsigned int rg_blocks = 0; - char *ht=0; - unsigned int x, size = len * sizeof(uint64_t); - int error; - - memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); - - gfs_alloc_get(dip); - - error = gfs_quota_hold_m(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out; - - error = gfs_rindex_hold(sdp, &dip->i_alloc->al_ri_gh); - if (error) - goto out_qs; - - /* Count the number of leaves */ - - for (blk = leaf_no; blk; blk = tmp_leaf.lf_next) { - error = get_leaf(dip, blk, &bh); - if (error) - goto out_rlist; - gfs_leaf_in(&tmp_leaf, (bh)->b_data); - brelse(bh); - - gfs_rlist_add(sdp, &rlist, blk); - } - - gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); - - for (x = 0; x < rlist.rl_rgrps; x++) { - struct gfs_rgrpd *rgd; - rgd = gl2rgd(rlist.rl_ghs[x].gh_gl); - rg_blocks += rgd->rd_ri.ri_length; - } - - error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); - if (error) - goto out_rlist; - - /* Trans may require: - All the bitmaps that were reserved. - One block for the dinode. - All the hash blocks that will be changed. - One block for a quota change. */ - - error = gfs_trans_begin(sdp, - rg_blocks + 1 + (DIV_RU(size, sdp->sd_jbsize) + 1), - 1); - if (error) - goto out_rg_gunlock; - - for (blk = leaf_no; blk; blk = tmp_leaf.lf_next) { - error = get_leaf(dip, blk, &bh); - if (error) - goto out_end_trans; - gfs_leaf_in(&tmp_leaf, bh->b_data); - brelse(bh); - - gfs_metafree(dip, blk, 1); - - if (!dip->i_di.di_blocks) - gfs_consist_inode(dip); - dip->i_di.di_blocks--; - } - - error = gfs_writei(dip, ht, index * sizeof (uint64_t), size, - gfs_zero_blocks, NULL); - - if (error != size) { - if (error >= 0) - error = -EIO; - goto out_end_trans; - } - - error = gfs_get_inode_buffer(dip, &dibh); - if (error) - goto out_end_trans; - - gfs_trans_add_bh(dip->i_gl, dibh); - gfs_dinode_out(&dip->i_di, dibh->b_data); - brelse(dibh); - - out_end_trans: - gfs_trans_end(sdp); - - out_rg_gunlock: - gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); - - out_rlist: - gfs_rlist_free(&rlist); - gfs_glock_dq_uninit(&dip->i_alloc->al_ri_gh); - - out_qs: - gfs_quota_unhold_m(dip); - - out: - gfs_alloc_put(dip); - - return error; -} - -/** - * gfs_dir_exhash_free - free all the leaf blocks in a directory - * @dip: the directory - * - * Dealloc all on-disk directory leaves to FREEMETA state - * Change on-disk inode type to "regular file" - * - * Returns: errno - */ - -int -gfs_dir_exhash_free(struct gfs_inode *dip) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct buffer_head *bh; - int error; - - /* Dealloc on-disk leaves to FREEMETA state */ - error = foreach_leaf(dip, leaf_free, NULL); - if (error) - return error; - - /* Make this a regular file in case we crash. - (We don't want to free these blocks a second time.) */ - - error = gfs_trans_begin(sdp, 1, 0); - if (error) - return error; - - error = gfs_get_inode_buffer(dip, &bh); - if (!error) { - gfs_trans_add_bh(dip->i_gl, bh); - ((struct gfs_dinode *)bh->b_data)->di_type = cpu_to_gfs16(GFS_FILE_REG); - brelse(bh); - } - - gfs_trans_end(sdp); - - return error; -} - -/** - * gfs_diradd_alloc_required - figure out if an entry addition is going to require an allocation - * @ip: the file being written to - * @filname: the filename that's going to be added - * @alloc_required: the int is set to TRUE if an alloc is required, FALSE otherwise - * - * Returns: errno - */ - -int -gfs_diradd_alloc_required(struct gfs_inode *dip, struct qstr *filename, - int *alloc_required) -{ - struct buffer_head *bh = NULL, *bh_next; - uint32_t hsize, hash, index; - int error = 0; - - *alloc_required = FALSE; - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) { - hsize = 1 << dip->i_di.di_depth; - if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { - gfs_consist_inode(dip); - return -EIO; - } - - hash = gfs_dir_hash(filename->name, filename->len); - index = hash >> (32 - dip->i_di.di_depth); - - error = get_first_leaf(dip, index, &bh_next); - if (error) - return error; - - do { - if (bh) - brelse(bh); - - bh = bh_next; - - if (dirent_fits(dip, bh, filename->len)) - break; - - error = get_next_leaf(dip, bh, &bh_next); - if (error == -ENOENT) { - *alloc_required = TRUE; - error = 0; - break; - } - } - while (!error); - - brelse(bh); - } else { - error = gfs_get_inode_buffer(dip, &bh); - if (error) - return error; - - if (!dirent_fits(dip, bh, filename->len)) - *alloc_required = TRUE; - - brelse(bh); - } - - return error; -} - -/** - * do_gdm - copy out one leaf (or list of leaves) - * @dip: the directory - * @index: the hash table offset in the directory - * @len: the number of pointers to this leaf - * @leaf_no: the leaf number - * @data: a pointer to a struct gfs_user_buffer structure - * - * Returns: errno - */ - -static int -do_gdm(struct gfs_inode *dip, - uint32_t index, uint32_t len, uint64_t leaf_no, - void *data) -{ - struct gfs_user_buffer *ub = (struct gfs_user_buffer *)data; - struct gfs_leaf leaf; - struct buffer_head *bh; - uint64_t blk; - int error = 0; - - for (blk = leaf_no; blk; blk = leaf.lf_next) { - error = get_leaf(dip, blk, &bh); - if (error) - break; - - gfs_leaf_in(&leaf, bh->b_data); - - error = gfs_add_bh_to_ub(ub, bh); - - brelse(bh); - - if (error) - break; - } - - return error; -} - -/** - * gfs_get_dir_meta - return all the leaf blocks of a directory - * @dip: the directory - * @ub: the structure representing the meta - * - * Returns: errno - */ - -int -gfs_get_dir_meta(struct gfs_inode *dip, struct gfs_user_buffer *ub) -{ - return foreach_leaf(dip, do_gdm, ub); -} diff --git a/gfs-kernel/src/gfs/dir.h b/gfs-kernel/src/gfs/dir.h deleted file mode 100644 index d7f02ab..0000000 --- a/gfs-kernel/src/gfs/dir.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __DIR_DOT_H__ -#define __DIR_DOT_H__ - -/** - * gfs_filldir_t - Report a directory entry to the caller of gfs_dir_read() - * @opaque: opaque data used by the function - * @name: the name of the directory entry - * @length: the length of the name - * @offset: the entry's offset in the directory - * @inum: the inode number the entry points to - * @type: the type of inode the entry points to - * - * Returns: 0 on success, 1 if buffer full - */ - -typedef int (*gfs_filldir_t) (void *opaque, - const char *name, unsigned int length, - uint64_t offset, - struct gfs_inum *inum, unsigned int type); - -int gfs_filecmp(struct qstr *file1, char *file2, int len_of_file2); -int gfs_dirent_alloc(struct gfs_inode *dip, struct buffer_head *bh, - int name_len, struct gfs_dirent **dent_out); - -int gfs_dir_search(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int *type); -int gfs_dir_add(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *inum, unsigned int type); -int gfs_dir_del(struct gfs_inode *dip, struct qstr *filename); -int gfs_dir_read(struct gfs_inode *dip, uint64_t * offset, void *opaque, - gfs_filldir_t filldir); -int gfs_dir_mvino(struct gfs_inode *dip, struct qstr *filename, - struct gfs_inum *new_inum, unsigned int new_type); - -int gfs_dir_exhash_free(struct gfs_inode *dip); - -int gfs_diradd_alloc_required(struct gfs_inode *dip, struct qstr *filename, - int *alloc_required); - -int gfs_get_dir_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); - -#endif /* __DIR_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/eaops.c b/gfs-kernel/src/gfs/eaops.c deleted file mode 100644 index 8446974..0000000 --- a/gfs-kernel/src/gfs/eaops.c +++ /dev/null @@ -1,314 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> -#include <linux/xattr.h> -#include <linux/xattr_acl.h> - -#include "gfs.h" -#include "acl.h" -#include "eaops.h" -#include "eattr.h" - -/** - * gfs_ea_name2type - get the type of the ea, and trucate the type from the name - * @namep: ea name, possibly with type appended - * - * Returns: GFS_EATYPE_XXX - */ - -unsigned int -gfs_ea_name2type(const char *name, char **truncated_name) -{ - unsigned int type; - - if (strncmp(name, "system.", 7) == 0) { - type = GFS_EATYPE_SYS; - if (truncated_name) - *truncated_name = strchr(name, '.') + 1; - } else if (strncmp(name, "user.", 5) == 0) { - type = GFS_EATYPE_USR; - if (truncated_name) - *truncated_name = strchr(name, '.') + 1; - } else if (strncmp(name, "security.", 9) == 0) { - type = GFS_EATYPE_SECURITY; - if (truncated_name) - *truncated_name = strchr(name, '.') + 1; - } else { - type = GFS_EATYPE_UNUSED; - if (truncated_name) - *truncated_name = NULL; - } - - return type; -} - -/** - * user_eo_get - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -user_eo_get(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - { - struct inode *inode = ip->i_vnode; - int error = permission(inode, MAY_READ, NULL); - if (error) - return error; - } - - return gfs_ea_get_i(ip, er); -} - -/** - * user_eo_set - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -user_eo_set(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - { - struct inode *inode = ip->i_vnode; - if (S_ISREG(inode->i_mode) || - (S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) { - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - } else - return -EPERM; - } - - return gfs_ea_set_i(ip, er); -} - -/** - * user_eo_remove - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -user_eo_remove(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - { - struct inode *inode = ip->i_vnode; - if (S_ISREG(inode->i_mode) || - (S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) { - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - } else - return -EPERM; - } - - return gfs_ea_remove_i(ip, er); -} - -/** - * system_eo_get - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -system_eo_get(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - if (!GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len) && - !GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len) && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (ip->i_sbd->sd_args.ar_posix_acls == FALSE && - (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len) || - GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len))) - return -EOPNOTSUPP; - - return gfs_ea_get_i(ip, er); -} - -/** - * system_eo_set - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -system_eo_set(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - int remove = FALSE; - int error; - - if (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { - er->er_mode = ip->i_vnode->i_mode; - error = gfs_acl_validate_set(ip, TRUE, er, - &remove, &er->er_mode); - if (error) - return error; - error = gfs_ea_set_i(ip, er); - if (error) - return error; - if (remove) - gfs_ea_remove_i(ip, er); - return 0; - - } else if (GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) { - int error = gfs_acl_validate_set(ip, FALSE, er, - &remove, NULL); - if (error) - return error; - if (!remove) - error = gfs_ea_set_i(ip, er); - else { - error = gfs_ea_remove_i(ip, er); - if (error == -ENODATA) - error = 0; - } - return error; - } - - return -EPERM; -} - -/** - * system_eo_remove - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -system_eo_remove(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - if (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { - int error = gfs_acl_validate_remove(ip, TRUE); - if (error) - return error; - - } else if (GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) { - int error = gfs_acl_validate_remove(ip, FALSE); - if (error) - return error; - - } else - return -EPERM; - - return gfs_ea_remove_i(ip, er); -} - -/** - * security_eo_get - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -security_eo_get(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct inode *inode = ip->i_vnode; - int error = permission(inode, MAY_READ, NULL); - if (error) - return error; - - return gfs_ea_get_i(ip, er); -} - -/** - * security_eo_set - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -security_eo_set(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct inode *inode = ip->i_vnode; - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - - return gfs_ea_set_i(ip, er); -} - -/** - * security_eo_remove - - * @ip: - * @er: - * - * Returns: errno - */ - -static int -security_eo_remove(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct inode *inode = ip->i_vnode; - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - - return gfs_ea_remove_i(ip, er); -} - -struct gfs_eattr_operations gfs_user_eaops = { - .eo_get = user_eo_get, - .eo_set = user_eo_set, - .eo_remove = user_eo_remove, - .eo_name = "user", -}; - -struct gfs_eattr_operations gfs_system_eaops = { - .eo_get = system_eo_get, - .eo_set = system_eo_set, - .eo_remove = system_eo_remove, - .eo_name = "system", -}; - -struct gfs_eattr_operations gfs_security_eaops = { - .eo_get = security_eo_get, - .eo_set = security_eo_set, - .eo_remove = security_eo_remove, - .eo_name = "security", -}; - -struct gfs_eattr_operations *gfs_ea_ops[] = { - NULL, - &gfs_user_eaops, - &gfs_system_eaops, - &gfs_security_eaops, -}; - diff --git a/gfs-kernel/src/gfs/eaops.h b/gfs-kernel/src/gfs/eaops.h deleted file mode 100644 index 12f471c..0000000 --- a/gfs-kernel/src/gfs/eaops.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __EAOPS_DOT_H__ -#define __EAOPS_DOT_H__ - -struct gfs_ea_request; - -struct gfs_eattr_operations { - int (*eo_get) (struct gfs_inode *ip, struct gfs_ea_request *er); - int (*eo_set) (struct gfs_inode *ip, struct gfs_ea_request *er); - int (*eo_remove) (struct gfs_inode *ip, struct gfs_ea_request *er); - char *eo_name; -}; - -unsigned int gfs_ea_name2type(const char *name, char **truncated_name); - -extern struct gfs_eattr_operations gfs_user_eaops; -extern struct gfs_eattr_operations gfs_system_eaops; -extern struct gfs_eattr_operations gfs_security_eaops; - -extern struct gfs_eattr_operations *gfs_ea_ops[]; - -#endif /* __EAOPS_DOT_H__ */ - diff --git a/gfs-kernel/src/gfs/eattr.c b/gfs-kernel/src/gfs/eattr.c deleted file mode 100644 index 03c5f89..0000000 --- a/gfs-kernel/src/gfs/eattr.c +++ /dev/null @@ -1,2020 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> -#include <linux/xattr.h> -#include <linux/xattr_acl.h> - -#include "gfs.h" -#include "acl.h" -#include "dio.h" -#include "eaops.h" -#include "eattr.h" -#include "glock.h" -#include "inode.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" - -/** - * ea_calc_size - returns the acutal number of bytes the request will take up - * (not counting any unstuffed data blocks) - * @sdp: - * @er: - * @size: - * - * Returns: TRUE if the EA should be stuffed - */ - -static int -ea_calc_size(struct gfs_sbd *sdp, - struct gfs_ea_request *er, - unsigned int *size) -{ - *size = GFS_EAREQ_SIZE_STUFFED(er); - if (*size <= sdp->sd_jbsize) - return TRUE; - - *size = GFS_EAREQ_SIZE_UNSTUFFED(sdp, er); - return FALSE; -} - -/** - * gfs_ea_check_size - - * @ip: - * @er: - * - * Returns: errno - */ - -int -gfs_ea_check_size(struct gfs_sbd *sdp, struct gfs_ea_request *er) -{ - unsigned int size; - - if (er->er_data_len > GFS_EA_MAX_DATA_LEN) - return -ERANGE; - - ea_calc_size(sdp, er, &size); - if (size > sdp->sd_jbsize) - return -ERANGE; /* This can only happen with 512 byte blocks */ - - return 0; -} - -typedef int (*ea_call_t) (struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct gfs_ea_header *prev, - void *private); - -/** - * ea_foreach_i - - * @ip: - * @bh: - * @eabc: - * @data: - * - * Returns: errno - */ - -static int -ea_foreach_i(struct gfs_inode *ip, - struct buffer_head *bh, - ea_call_t ea_call, void *data) -{ - struct gfs_ea_header *ea, *prev = NULL; - int error = 0; - - if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) - return -EIO; - - for (ea = GFS_EA_BH2FIRST(bh);; prev = ea, ea = GFS_EA2NEXT(ea)) { - if (!GFS_EA_REC_LEN(ea)) - goto fail; - if (!(bh->b_data <= (char *)ea && - (char *)GFS_EA2NEXT(ea) <= - bh->b_data + bh->b_size)) - goto fail; - if (!GFS_EATYPE_VALID(ea->ea_type)) - goto fail; - - error = ea_call(ip, bh, ea, prev, data); - if (error) - return error; - - if (GFS_EA_IS_LAST(ea)) { - if ((char *)GFS_EA2NEXT(ea) != - bh->b_data + bh->b_size) - goto fail; - break; - } - } - - return error; - - fail: - gfs_consist_inode(ip); - return -EIO; -} - -/** - * ea_foreach - - * @ip: - * @ea_call: - * @data: - * - * Returns: errno - */ - -static int -ea_foreach(struct gfs_inode *ip, - ea_call_t ea_call, - void *data) -{ - struct buffer_head *bh; - int error; - - error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, - DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - if (!(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT)) - error = ea_foreach_i(ip, bh, ea_call, data); - else { - struct buffer_head *eabh; - uint64_t *eablk, *end; - - if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_IN)) { - error = -EIO; - goto out; - } - - eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)); - end = eablk + ip->i_sbd->sd_inptrs; - - for (; eablk < end; eablk++) { - uint64_t bn; - - if (!*eablk) - break; - bn = gfs64_to_cpu(*eablk); - - error = gfs_dread(ip->i_gl, bn, - DIO_START | DIO_WAIT, &eabh); - if (error) - break; - error = ea_foreach_i(ip, eabh, ea_call, data); - brelse(eabh); - if (error) - break; - } - } - - out: - brelse(bh); - - return error; -} - -struct ea_find { - struct gfs_ea_request *ef_er; - struct gfs_ea_location *ef_el; -}; - -/** - * ea_find_i - - * @ip: - * @bh: - * @ea: - * @prev: - * @private: - * - * Returns: -errno on error, 1 if search is over, - * 0 if search should continue - */ - -static int -ea_find_i(struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct gfs_ea_header *prev, - void *private) -{ - struct ea_find *ef = (struct ea_find *)private; - struct gfs_ea_request *er = ef->ef_er; - - if (ea->ea_type == GFS_EATYPE_UNUSED) - return 0; - - if (ea->ea_type == er->er_type) { - if (ea->ea_name_len == er->er_name_len && - !memcmp(GFS_EA2NAME(ea), er->er_name, ea->ea_name_len)) { - struct gfs_ea_location *el = ef->ef_el; - get_bh(bh); - el->el_bh = bh; - el->el_ea = ea; - el->el_prev = prev; - return 1; - } - } - -#if 0 - else if ((ip->i_di.di_flags & GFS_DIF_EA_PACKED) && - er->er_type == GFS_EATYPE_SYS) - return 1; -#endif - - return 0; -} - -/** - * gfs_ea_find - find a matching eattr - * @ip: - * @er: - * @el: - * - * Returns: errno - */ - -int -gfs_ea_find(struct gfs_inode *ip, - struct gfs_ea_request *er, - struct gfs_ea_location *el) -{ - struct ea_find ef; - int error; - - ef.ef_er = er; - ef.ef_el = el; - - memset(el, 0, sizeof(struct gfs_ea_location)); - - error = ea_foreach(ip, ea_find_i, &ef); - if (error > 0) - return 0; - - return error; -} - -/** - * ea_dealloc_unstuffed - - * @ip: - * @bh: - * @ea: - * @prev: - * @private: - * - * Take advantage of the fact that all unstuffed blocks are - * allocated from the same RG. But watch, this may not always - * be true. - * - * Returns: errno - */ - -static int -ea_dealloc_unstuffed(struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct gfs_ea_header *prev, - void *private) -{ - int *leave = (int *)private; - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrpd *rgd; - struct gfs_holder rg_gh; - struct buffer_head *dibh; - uint64_t *dataptrs, bn = 0; - uint64_t bstart = 0; - unsigned int blen = 0; - unsigned int x; - int error; - - if (GFS_EA_IS_STUFFED(ea)) - return 0; - - dataptrs = GFS_EA2DATAPTRS(ea); - for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) - if (*dataptrs) { - bn = gfs64_to_cpu(*dataptrs); - break; - } - if (!bn) - return 0; - - rgd = gfs_blk2rgrpd(sdp, bn); - if (!rgd) { - gfs_consist_inode(ip); - return -EIO; - } - - error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh); - if (error) - return error; - - error = gfs_trans_begin(sdp, 2 + rgd->rd_ri.ri_length, 1); - if (error) - goto out_gunlock; - - gfs_trans_add_bh(ip->i_gl, bh); - - dataptrs = GFS_EA2DATAPTRS(ea); - for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) { - if (!*dataptrs) - break; - bn = gfs64_to_cpu(*dataptrs); - - if (bstart + blen == bn) - blen++; - else { - if (bstart) - gfs_metafree(ip, bstart, blen); - bstart = bn; - blen = 1; - } - - *dataptrs = 0; - if (!ip->i_di.di_blocks) - gfs_consist_inode(ip); - ip->i_di.di_blocks--; - } - if (bstart) - gfs_metafree(ip, bstart, blen); - - if (prev && !leave) { - uint32_t len; - - len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); - prev->ea_rec_len = cpu_to_gfs32(len); - - if (GFS_EA_IS_LAST(ea)) - prev->ea_flags |= GFS_EAFLAG_LAST; - } else { - ea->ea_type = GFS_EATYPE_UNUSED; - ea->ea_num_ptrs = 0; - } - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - ip->i_di.di_ctime = get_seconds(); - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - gfs_trans_end(sdp); - - out_gunlock: - gfs_glock_dq_uninit(&rg_gh); - - return error; -} - -/** - * ea_remove_unstuffed - - * @ip: - * @bh: - * @ea: - * @prev: - * @leave: - * - * Returns: errno - */ - -static int -ea_remove_unstuffed(struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct gfs_ea_header *prev, - int leave) -{ - struct gfs_alloc *al; - int error; - - al = gfs_alloc_get(ip); - - error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out_alloc; - - error = gfs_rindex_hold(ip->i_sbd, &al->al_ri_gh); - if (error) - goto out_quota; - - error = ea_dealloc_unstuffed(ip, - bh, ea, prev, - (leave) ? &error : NULL); - - gfs_glock_dq_uninit(&al->al_ri_gh); - - out_quota: - gfs_quota_unhold_m(ip); - - out_alloc: - gfs_alloc_put(ip); - - return error; -} - -/**************************************************************************************************/ - -/** - * gfs_ea_repack_i - - * @ip: - * - * Returns: errno - */ - -int -gfs_ea_repack_i(struct gfs_inode *ip) -{ - return -ENOSYS; -} - -/** - * gfs_ea_repack - - * @ip: - * - * Returns: errno - */ - -int gfs_ea_repack(struct gfs_inode *ip) -{ - struct gfs_holder gh; - int error; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - if (error) - return error; - - /* Some sort of permissions checking would be nice */ - - error = gfs_ea_repack_i(ip); - - gfs_glock_dq_uninit(&gh); - - return error; -} - -struct ea_list { - struct gfs_ea_request *ei_er; - unsigned int ei_size; -}; - -/** - * ea_list_i - - * @ip: - * @bh: - * @ea: - * @prev: - * @private: - * - * Returns: errno - */ - -static int -ea_list_i(struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct gfs_ea_header *prev, - void *private) -{ - struct ea_list *ei = (struct ea_list *)private; - struct gfs_ea_request *er = ei->ei_er; - unsigned int ea_size = gfs_ea_strlen(ea); - - if (ea->ea_type == GFS_EATYPE_UNUSED) - return 0; - - if (er->er_data_len) { - char *prefix; - unsigned int l; - char c = 0; - - if (ei->ei_size + ea_size > er->er_data_len) - return -ERANGE; - - switch (ea->ea_type) { - case GFS_EATYPE_USR: - prefix = "user."; - l = 5; - break; - case GFS_EATYPE_SYS: - prefix = "system."; - l = 7; - break; - case GFS_EATYPE_SECURITY: - prefix = "security."; - l = 9; - break; - default: - prefix = NULL; - l = 0; - break; - } - - if (prefix == NULL || l == 0) - return -EIO; - - memcpy(er->er_data + ei->ei_size, - prefix, l); - memcpy(er->er_data + ei->ei_size + l, - GFS_EA2NAME(ea), - ea->ea_name_len); - memcpy(er->er_data + ei->ei_size + - ea_size - 1, - &c, 1); - } - - ei->ei_size += ea_size; - - return 0; -} - -/** - * gfs_ea_list - - * @ip: - * @er: - * - * Returns: actual size of data on success, -errno on error - */ - -int -gfs_ea_list(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_holder i_gh; - int error; - - if (!er->er_data || !er->er_data_len) { - er->er_data = NULL; - er->er_data_len = 0; - } - - error = gfs_glock_nq_init(ip->i_gl, - LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); - if (error) - return error; - - if (ip->i_di.di_eattr) { - struct ea_list ei = { .ei_er = er, .ei_size = 0 }; - - error = ea_foreach(ip, ea_list_i, &ei); - if (!error) - error = ei.ei_size; - } - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * ea_get_unstuffed - actually copies the unstuffed data into the - * request buffer - * @ip: - * @ea: - * @data: - * - * Returns: errno - */ - -static int -ea_get_unstuffed(struct gfs_inode *ip, struct gfs_ea_header *ea, - char *data) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head **bh; - unsigned int amount = GFS_EA_DATA_LEN(ea); - unsigned int nptrs = DIV_RU(amount, sdp->sd_jbsize); - uint64_t *dataptrs = GFS_EA2DATAPTRS(ea); - unsigned int x; - int error = 0; - - bh = kmalloc(nptrs * sizeof(struct buffer_head *), GFP_KERNEL); - if (!bh) - return -ENOMEM; - - for (x = 0; x < nptrs; x++) { - error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs), - DIO_START, bh + x); - if (error) { - while (x--) - brelse(bh[x]); - goto out; - } - dataptrs++; - } - - for (x = 0; x < nptrs; x++) { - error = gfs_dreread(sdp, bh[x], DIO_WAIT); - if (error) { - for (; x < nptrs; x++) - brelse(bh[x]); - goto out; - } - if (gfs_metatype_check2(sdp, bh[x], - GFS_METATYPE_ED, GFS_METATYPE_EA)) { - for (; x < nptrs; x++) - brelse(bh[x]); - error = -EIO; - goto out; - } - - memcpy(data, - bh[x]->b_data + sizeof(struct gfs_meta_header), - (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); - - amount -= sdp->sd_jbsize; - data += sdp->sd_jbsize; - - brelse(bh[x]); - } - - out: - kfree(bh); - - return error; -} - -/** - * gfs_ea_get_copy - - * @ip: - * @el: - * @data: - * - * Returns: errno - */ - -int -gfs_ea_get_copy(struct gfs_inode *ip, - struct gfs_ea_location *el, - char *data) -{ - if (GFS_EA_IS_STUFFED(el->el_ea)) { - memcpy(data, - GFS_EA2DATA(el->el_ea), - GFS_EA_DATA_LEN(el->el_ea)); - return 0; - } else - return ea_get_unstuffed(ip, el->el_ea, - data); -} - -/** - * gfs_ea_get_i - - * @ip: - * @er: - * - * Returns: actual size of data on success, -errno on error - */ - -int -gfs_ea_get_i(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_ea_location el; - int error; - - if (!ip->i_di.di_eattr) - return -ENODATA; - - error = gfs_ea_find(ip, er, &el); - if (error) - return error; - if (!el.el_ea) - return -ENODATA; - - if (er->er_data_len) { - if (GFS_EA_DATA_LEN(el.el_ea) > er->er_data_len) - error = -ERANGE; - else - error = gfs_ea_get_copy(ip, &el, er->er_data); - } - if (!error) - error = GFS_EA_DATA_LEN(el.el_ea); - - brelse(el.el_bh); - - return error; -} - -/** - * gfs_ea_get - - * @ip: - * @er: - * - * Returns: actual size of data on success, -errno on error - */ - -int -gfs_ea_get(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_holder i_gh; - int error; - - if (!er->er_name_len || - er->er_name_len > GFS_EA_MAX_NAME_LEN) - return -EINVAL; - if (!er->er_data || !er->er_data_len) { - er->er_data = NULL; - er->er_data_len = 0; - } - - error = gfs_glock_nq_init(ip->i_gl, - LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); - if (error) - return error; - - error = gfs_ea_ops[er->er_type]->eo_get(ip, er); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * ea_alloc_blk - allocates a new block for extended attributes. - * @ip: A pointer to the inode that's getting extended attributes - * @bhp: - * - * Returns: errno - */ - -static int -ea_alloc_blk(struct gfs_inode *ip, - struct buffer_head **bhp) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_ea_header *ea; - uint64_t block; - int error; - - error = gfs_metaalloc(ip, &block); - if (error) - return error; - - error = gfs_dread(ip->i_gl, block, - DIO_NEW | DIO_START | DIO_WAIT, bhp); - if (error) - return error; - - gfs_trans_add_bh(ip->i_gl, *bhp); - gfs_metatype_set(*bhp, GFS_METATYPE_EA, GFS_FORMAT_EA); - - ea = GFS_EA_BH2FIRST(*bhp); - ea->ea_rec_len = cpu_to_gfs32(sdp->sd_jbsize); - ea->ea_type = GFS_EATYPE_UNUSED; - ea->ea_flags = GFS_EAFLAG_LAST; - ea->ea_num_ptrs = 0; - - ip->i_di.di_blocks++; - - return 0; -} - -/** - * ea_write - writes the request info to an ea, creating new blocks if - * necessary - * @ip: inode that is being modified - * @ea: the location of the new ea in a block - * @er: the write request - * - * Note: does not update ea_rec_len or the GFS_EAFLAG_LAST bin of ea_flags - * - * returns : errno - */ - -static int -ea_write(struct gfs_inode *ip, - struct gfs_ea_header *ea, - struct gfs_ea_request *er) -{ - struct gfs_sbd *sdp = ip->i_sbd; - - ea->ea_data_len = cpu_to_gfs32(er->er_data_len); - ea->ea_name_len = er->er_name_len; - ea->ea_type = er->er_type; - ea->ea_pad = 0; - - memcpy(GFS_EA2NAME(ea), er->er_name, er->er_name_len); - - if (GFS_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) { - ea->ea_num_ptrs = 0; - memcpy(GFS_EA2DATA(ea), er->er_data, er->er_data_len); - } else { - uint64_t *dataptr = GFS_EA2DATAPTRS(ea); - const char *data = er->er_data; - unsigned int data_len = er->er_data_len; - unsigned int copy; - unsigned int x; - - ea->ea_num_ptrs = DIV_RU(er->er_data_len, sdp->sd_jbsize); - for (x = 0; x < ea->ea_num_ptrs; x++) { - struct buffer_head *bh; - uint64_t block; - int error; - - error = gfs_metaalloc(ip, &block); - if (error) - return error; - - error = gfs_dread(ip->i_gl, block, - DIO_NEW | DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - gfs_trans_add_bh(ip->i_gl, bh); - gfs_metatype_set(bh, GFS_METATYPE_ED, GFS_FORMAT_ED); - ip->i_di.di_blocks++; - - copy = (data_len > sdp->sd_jbsize) ? sdp->sd_jbsize : data_len; - memcpy(bh->b_data + sizeof(struct gfs_meta_header), - data, - copy); - - *dataptr++ = cpu_to_gfs64((uint64_t)bh->b_blocknr); - data += copy; - data_len -= copy; - - brelse(bh); - } - - gfs_assert_withdraw(sdp, !data_len); - } - - return 0; -} - -typedef int (*ea_skeleton_call_t) (struct gfs_inode *ip, - struct gfs_ea_request *er, - void *private); -/** - * ea_alloc_skeleton - - * @ip: - * @er: - * @blks: - * @skeleton_call: - * @private: - * - * Returns: errno - */ - -static int -ea_alloc_skeleton(struct gfs_inode *ip, struct gfs_ea_request *er, - unsigned int blks, - ea_skeleton_call_t skeleton_call, void *private) -{ - struct gfs_alloc *al; - struct buffer_head *dibh; - int error; - - al = gfs_alloc_get(ip); - - error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out; - - error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); - if (error) - goto out_gunlock_q; - - al->al_requested_meta = blks; - - error = gfs_inplace_reserve(ip); - if (error) - goto out_gunlock_q; - - /* Trans may require: - A modified dinode, multiple EA metadata blocks, and all blocks for a RG - bitmap */ - - error = gfs_trans_begin(ip->i_sbd, - 1 + blks + al->al_rgd->rd_ri.ri_length, 1); - if (error) - goto out_ipres; - - error = skeleton_call(ip, er, private); - if (error) - goto out_end_trans; - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - if (er->er_mode) { - ip->i_vnode->i_mode = er->er_mode; - gfs_inode_attr_out(ip); - } - ip->i_di.di_ctime = get_seconds(); - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - out_end_trans: - gfs_trans_end(ip->i_sbd); - - out_ipres: - gfs_inplace_release(ip); - - out_gunlock_q: - gfs_quota_unlock_m(ip); - - out: - gfs_alloc_put(ip); - - return error; -} - -/** - * ea_init_i - initializes a new eattr block - * @ip: - * @er: - * @private: - * - * Returns: errno - */ - -static int -ea_init_i(struct gfs_inode *ip, - struct gfs_ea_request *er, - void *private) -{ - struct buffer_head *bh; - int error; - - error = ea_alloc_blk(ip, &bh); - if (error) - return error; - - ip->i_di.di_eattr = bh->b_blocknr; - error = ea_write(ip, GFS_EA_BH2FIRST(bh), er); - - brelse(bh); - - return error; -} - -/** - * ea_init - initializes a new eattr block - * @ip: - * @er: - * - * Returns: errno - */ - -static int -ea_init(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - unsigned int jbsize = ip->i_sbd->sd_jbsize; - unsigned int blks = 1; - - if (GFS_EAREQ_SIZE_STUFFED(er) > jbsize) - blks += DIV_RU(er->er_data_len, jbsize); - - return ea_alloc_skeleton(ip, er, - blks, - ea_init_i, NULL); -} - -/** - * ea_split_ea - - * @ea: - * - * Returns: the new ea - */ - -static struct gfs_ea_header * -ea_split_ea(struct gfs_ea_header *ea) -{ - uint32_t ea_size = GFS_EA_SIZE(ea); - struct gfs_ea_header *new = (struct gfs_ea_header *)((char *)ea + ea_size); - uint32_t new_size = GFS_EA_REC_LEN(ea) - ea_size; - int last = ea->ea_flags & GFS_EAFLAG_LAST; - - ea->ea_rec_len = cpu_to_gfs32(ea_size); - ea->ea_flags ^= last; - - new->ea_rec_len = cpu_to_gfs32(new_size); - new->ea_flags = last; - - return new; -} - -/** - * ea_set_remove_stuffed - - * @ip: - * @ea: - * - */ - -static void -ea_set_remove_stuffed(struct gfs_inode *ip, struct gfs_ea_location *el) -{ - struct gfs_ea_header *ea = el->el_ea; - struct gfs_ea_header *prev = el->el_prev; - uint32_t len; - - gfs_trans_add_bh(ip->i_gl, el->el_bh); - - if (!prev || !GFS_EA_IS_STUFFED(ea)) { - ea->ea_type = GFS_EATYPE_UNUSED; - return; - } else if (GFS_EA2NEXT(prev) != ea) { - prev = GFS_EA2NEXT(prev); - gfs_assert_withdraw(ip->i_sbd, GFS_EA2NEXT(prev) == ea); - } - - len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); - prev->ea_rec_len = cpu_to_gfs32(len); - - if (GFS_EA_IS_LAST(ea)) - prev->ea_flags |= GFS_EAFLAG_LAST; -} - -struct ea_set { - int ea_split; - - struct gfs_ea_request *es_er; - struct gfs_ea_location *es_el; - - struct buffer_head *es_bh; - struct gfs_ea_header *es_ea; -}; - -/** - * ea_set_simple_noalloc - - * @ip: - * @ea: - * @es: - * - * Returns: errno - */ - -static int -ea_set_simple_noalloc(struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct ea_set *es) -{ - struct gfs_ea_request *er = es->es_er; - int error; - - error = gfs_trans_begin(ip->i_sbd, 3, 0); - if (error) - return error; - - gfs_trans_add_bh(ip->i_gl, bh); - - if (es->ea_split) - ea = ea_split_ea(ea); - - ea_write(ip, ea, er); - - if (es->es_el) - ea_set_remove_stuffed(ip, es->es_el); - - { - struct buffer_head *dibh; - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - if (er->er_mode) { - ip->i_vnode->i_mode = er->er_mode; - gfs_inode_attr_out(ip); - } - ip->i_di.di_ctime = get_seconds(); - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - } - - gfs_trans_end(ip->i_sbd); - - return error; -} - -/** - * ea_set_simple_alloc - - * @ip: - * @er: - * @private: - * - * Returns: errno - */ - -static int -ea_set_simple_alloc(struct gfs_inode *ip, - struct gfs_ea_request *er, - void *private) -{ - struct ea_set *es = (struct ea_set *)private; - struct gfs_ea_header *ea = es->es_ea; - int error; - - gfs_trans_add_bh(ip->i_gl, es->es_bh); - - if (es->ea_split) - ea = ea_split_ea(ea); - - error = ea_write(ip, ea, er); - if (error) - return error; - - if (es->es_el) - ea_set_remove_stuffed(ip, es->es_el); - - return 0; -} - -/** - * ea_set_simple - - * @ip: - * @el: - * - * Returns: errno - */ - -static int -ea_set_simple(struct gfs_inode *ip, - struct buffer_head *bh, - struct gfs_ea_header *ea, - struct gfs_ea_header *prev, - void *private) -{ - struct ea_set *es = (struct ea_set *)private; - unsigned int size; - int stuffed; - int error; - - stuffed = ea_calc_size(ip->i_sbd, es->es_er, &size); - - if (ea->ea_type == GFS_EATYPE_UNUSED) { - if (GFS_EA_REC_LEN(ea) < size) - return 0; - if (!GFS_EA_IS_STUFFED(ea)) { - error = ea_remove_unstuffed(ip, bh, ea, prev, TRUE); - if (error) - return error; - } - es->ea_split = FALSE; - } else if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) - es->ea_split = TRUE; - else - return 0; - - if (stuffed) { - error = ea_set_simple_noalloc(ip, bh, ea, es); - if (error) - return error; - } else { - unsigned int blks; - - es->es_bh = bh; - es->es_ea = ea; - blks = 2 + DIV_RU(es->es_er->er_data_len, - ip->i_sbd->sd_jbsize); - - error = ea_alloc_skeleton(ip, es->es_er, - blks, - ea_set_simple_alloc, es); - if (error) - return error; - } - - return 1; -} - -/** - * ea_set_block - - * @ip: - * @er: - * @private: - * - * Returns: errno - */ - -static int -ea_set_block(struct gfs_inode *ip, - struct gfs_ea_request *er, - void *private) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *indbh, *newbh; - uint64_t *eablk; - int error; - - if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { - uint64_t *end; - - error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, - DIO_START | DIO_WAIT, &indbh); - if (error) - return error; - - if (gfs_metatype_check(sdp, indbh, GFS_METATYPE_IN)) { - error = -EIO; - goto out; - } - - eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); - end = eablk + sdp->sd_inptrs; - - for (; eablk < end; eablk++) - if (!*eablk) - break; - - if (eablk == end) { - error = -ENOSPC; - goto out; - } - - gfs_trans_add_bh(ip->i_gl, indbh); - } else { - uint64_t blk; - - error = gfs_metaalloc(ip, &blk); - if (error) - return error; - - error = gfs_dread(ip->i_gl, blk, - DIO_NEW | DIO_START | DIO_WAIT, &indbh); - if (error) - return error; - - gfs_trans_add_bh(ip->i_gl, indbh); - gfs_metatype_set(indbh, GFS_METATYPE_IN, GFS_FORMAT_IN); - gfs_buffer_clear_tail(indbh, sizeof(struct gfs_meta_header)); - - eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); - *eablk = cpu_to_gfs64(ip->i_di.di_eattr); - ip->i_di.di_eattr = blk; - ip->i_di.di_flags |= GFS_DIF_EA_INDIRECT; - ip->i_di.di_blocks++; - - eablk++; - } - - error = ea_alloc_blk(ip, &newbh); - if (error) - goto out; - - *eablk = cpu_to_gfs64((uint64_t)newbh->b_blocknr); - error = ea_write(ip, GFS_EA_BH2FIRST(newbh), er); - brelse(newbh); - if (error) - goto out; - - if (private) - ea_set_remove_stuffed(ip, (struct gfs_ea_location *)private); - - out: - brelse(indbh); - - return error; -} - -/** - * ea_set_i - - * @ip: - * @el: - * - * Returns: errno - */ - -static int -ea_set_i(struct gfs_inode *ip, - struct gfs_ea_request *er, - struct gfs_ea_location *el) -{ - { - struct ea_set es; - int error; - - memset(&es, 0, sizeof(struct ea_set)); - es.es_er = er; - es.es_el = el; - - error = ea_foreach(ip, ea_set_simple, &es); - if (error > 0) - return 0; - if (error) - return error; - } - { - unsigned int blks = 2; - if (!(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT)) - blks++; - if (GFS_EAREQ_SIZE_STUFFED(er) > ip->i_sbd->sd_jbsize) - blks += DIV_RU(er->er_data_len, - ip->i_sbd->sd_jbsize); - - return ea_alloc_skeleton(ip, er, blks, ea_set_block, el); - } -} - -/** - * ea_set_remove_unstuffed - - * @ip: - * @el: - * - * Returns: errno - */ - -static int -ea_set_remove_unstuffed(struct gfs_inode *ip, struct gfs_ea_location *el) -{ - if (el->el_prev && GFS_EA2NEXT(el->el_prev) != el->el_ea) { - el->el_prev = GFS_EA2NEXT(el->el_prev); - gfs_assert_withdraw(ip->i_sbd, - GFS_EA2NEXT(el->el_prev) == el->el_ea); - } - - return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, FALSE); -} - -/** - * gfs_ea_set_i - - * @ip: - * @er: - * - * Returns: errno - */ - -int -gfs_ea_set_i(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_ea_location el; - int error; - - if (!ip->i_di.di_eattr) { - if (er->er_flags & XATTR_REPLACE) - return -ENODATA; - return ea_init(ip, er); - } - - error = gfs_ea_find(ip, er, &el); - if (error) - return error; - - if (el.el_ea) { - if (IS_APPEND(ip->i_vnode)) { - brelse(el.el_bh); - return -EPERM; - } - - error = -EEXIST; - if (!(er->er_flags & XATTR_CREATE)) { - int unstuffed = !GFS_EA_IS_STUFFED(el.el_ea); - error = ea_set_i(ip, er, &el); - if (!error && unstuffed) - ea_set_remove_unstuffed(ip, &el); - } - - brelse(el.el_bh); - } else { - error = -ENODATA; - if (!(er->er_flags & XATTR_REPLACE)) - error = ea_set_i(ip, er, NULL); - } - - return error; -} - -/** - * gfs_ea_set - - * @ip: - * @er: - * - * Returns: errno - */ - -int -gfs_ea_set(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_holder i_gh; - int error; - - if (!er->er_name_len || - er->er_name_len > GFS_EA_MAX_NAME_LEN) - return -EINVAL; - if (!er->er_data || !er->er_data_len) { - er->er_data = NULL; - er->er_data_len = 0; - } - error = gfs_ea_check_size(ip->i_sbd, er); - if (error) - return error; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - return error; - - if (IS_IMMUTABLE(ip->i_vnode)) - error = -EPERM; - else - error = gfs_ea_ops[er->er_type]->eo_set(ip, er); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * ea_remove_stuffed - - * @ip: - * @el: - * @mode: - * - * Returns: errno - */ - -static int -ea_remove_stuffed(struct gfs_inode *ip, - struct gfs_ea_location *el) -{ - struct gfs_ea_header *ea = el->el_ea; - struct gfs_ea_header *prev = el->el_prev; - int error; - - error = gfs_trans_begin(ip->i_sbd, 2, 0); - if (error) - return error; - - gfs_trans_add_bh(ip->i_gl, el->el_bh); - - if (prev) { - uint32_t len; - - len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); - prev->ea_rec_len = cpu_to_gfs32(len); - - if (GFS_EA_IS_LAST(ea)) - prev->ea_flags |= GFS_EAFLAG_LAST; - } else - ea->ea_type = GFS_EATYPE_UNUSED; - - { - struct buffer_head *dibh; - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - ip->i_di.di_ctime = get_seconds(); - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - } - - gfs_trans_end(ip->i_sbd); - - return error; -} - -/** - * gfs_ea_remove_i - - * @ip: - * @er: - * - * Returns: errno - */ - -int -gfs_ea_remove_i(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_ea_location el; - int error; - - if (!ip->i_di.di_eattr) - return -ENODATA; - - error = gfs_ea_find(ip, er, &el); - if (error) - return error; - if (!el.el_ea) - return -ENODATA; - - if (GFS_EA_IS_STUFFED(el.el_ea)) - error = ea_remove_stuffed(ip, &el); - else - error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, FALSE); - - brelse(el.el_bh); - - return error; -} - -/** - * gfs_ea_remove - sets (or creates or replaces) an extended attribute - * @ip: pointer to the inode of the target file - * @er: request information - * - * Returns: errno - */ - -int -gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct gfs_holder i_gh; - int error; - - if (!er->er_name_len || - er->er_name_len > GFS_EA_MAX_NAME_LEN) - return -EINVAL; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - return error; - - if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode)) - error = -EPERM; - else - error = gfs_ea_ops[er->er_type]->eo_remove(ip, er); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_ea_acl_init - - * @ip: - * @er: - * - * Returns: errno - */ - -int gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er) -{ - struct buffer_head *bh; - struct gfs_ea_header *ea; - unsigned int size; - struct buffer_head *dibh; - int error; - - if (!ip->i_di.di_eattr) - return ea_init_i(ip, er, NULL); - - ea_calc_size(ip->i_sbd, er, &size); - - error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, - DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) { - brelse(bh); - return -EIO; - } - - ea = GFS_EA_BH2FIRST(bh); - if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) { - ea = ea_split_ea(ea); - ea_write(ip, ea, er); - brelse(bh); - return 0; - } - - brelse(bh); - - error = ea_set_block(ip, er, NULL); - gfs_assert_withdraw(ip->i_sbd, error != -ENOSPC); - if (error) - return error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - return error; - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - return error; -} - -/** - * ea_acl_chmod_unstuffed - - * @ip: - * @ea: - * @data: - * - * Returns: errno - */ - -static int ea_acl_chmod_unstuffed(struct gfs_inode *ip, - struct gfs_ea_header *ea, char *data, - int *trans) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head **bh; - unsigned int amount = GFS_EA_DATA_LEN(ea); - unsigned int nptrs = DIV_RU(amount, sdp->sd_jbsize); - uint64_t *dataptrs = GFS_EA2DATAPTRS(ea); - unsigned int x; - int error = 0; - - bh = kmalloc(nptrs * sizeof(struct buffer_head *), GFP_KERNEL); - if (!bh) - return -ENOMEM; - - if (current_transaction == NULL) { - error = gfs_trans_begin(sdp, 1 + nptrs, 0); - if (error) - goto out; - *trans = 1; - } - - for (x = 0; x < nptrs; x++) { - error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs), - DIO_START, bh + x); - if (error) { - while (x--) - brelse(bh[x]); - goto fail; - } - dataptrs++; - } - - for (x = 0; x < nptrs; x++) { - error = gfs_dreread(sdp, bh[x], DIO_WAIT); - if (error) { - for (; x < nptrs; x++) - brelse(bh[x]); - goto fail; - } - if (gfs_metatype_check2(sdp, bh[x], - GFS_METATYPE_ED, GFS_METATYPE_EA)) { - for (; x < nptrs; x++) - brelse(bh[x]); - error = -EIO; - goto fail; - } - - gfs_trans_add_bh(ip->i_gl, bh[x]); - - memcpy(bh[x]->b_data + sizeof(struct gfs_meta_header), - data, - (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); - - amount -= sdp->sd_jbsize; - data += sdp->sd_jbsize; - - brelse(bh[x]); - } - -out: - kfree(bh); - return error; - -fail: - gfs_trans_end(sdp); - *trans = 0; - kfree(bh); - return error; -} - -/** - * gfs_ea_acl_chmod - - * @ip: - * @el: - * @attr: - * @data: - * - * Returns: errno - */ - -int gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el, - struct iattr *attr, char *data) -{ - struct buffer_head *dibh; - int error = 0; - int trans = 0; - - if (GFS_EA_IS_STUFFED(el->el_ea)) { - if (current_transaction == NULL) { - error = gfs_trans_begin(ip->i_sbd, 2, 0); - if (error) - return error; - trans = 1; - } - - gfs_trans_add_bh(ip->i_gl, el->el_bh); - memcpy(GFS_EA2DATA(el->el_ea), data, - GFS_EA_DATA_LEN(el->el_ea)); - } else { - error = ea_acl_chmod_unstuffed(ip, el->el_ea, data, &trans); - } - - if (error) - return error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - error = inode_setattr(ip->i_vnode, attr); - gfs_assert_warn(ip->i_sbd, !error); - gfs_inode_attr_out(ip); - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - if (trans) - gfs_trans_end(ip->i_sbd); - - return error; -} - -/** - * ea_dealloc_indirect - - * @ip: - * - * Returns: errno - */ - -static int -ea_dealloc_indirect(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrp_list rlist; - struct buffer_head *indbh, *dibh; - uint64_t *eablk, *end; - unsigned int rg_blocks = 0; - uint64_t bstart = 0; - unsigned int blen = 0; - unsigned int x; - int error; - - memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); - - error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, - DIO_START | DIO_WAIT, &indbh); - if (error) - return error; - - if (gfs_metatype_check(sdp, indbh, GFS_METATYPE_IN)) { - error = -EIO; - goto out; - } - - eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); - end = eablk + sdp->sd_inptrs; - - for (; eablk < end; eablk++) { - uint64_t bn; - - if (!*eablk) - break; - bn = gfs64_to_cpu(*eablk); - - if (bstart + blen == bn) - blen++; - else { - if (bstart) - gfs_rlist_add(sdp, &rlist, bstart); - bstart = bn; - blen = 1; - } - } - if (bstart) - gfs_rlist_add(sdp, &rlist, bstart); - else - goto out; - - gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); - - for (x = 0; x < rlist.rl_rgrps; x++) { - struct gfs_rgrpd *rgd; - rgd = gl2rgd(rlist.rl_ghs[x].gh_gl); - rg_blocks += rgd->rd_ri.ri_length; - } - - error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); - if (error) - goto out_rlist_free; - - error = gfs_trans_begin(sdp, 2 + rg_blocks, 1); - if (error) - goto out_gunlock; - - gfs_trans_add_bh(ip->i_gl, indbh); - - eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); - bstart = 0; - blen = 0; - - for (; eablk < end; eablk++) { - uint64_t bn; - - if (!*eablk) - break; - bn = gfs64_to_cpu(*eablk); - - if (bstart + blen == bn) - blen++; - else { - if (bstart) - gfs_metafree(ip, bstart, blen); - bstart = bn; - blen = 1; - } - - *eablk = 0; - if (!ip->i_di.di_blocks) - gfs_consist_inode(ip); - ip->i_di.di_blocks--; - } - if (bstart) - gfs_metafree(ip, bstart, blen); - - ip->i_di.di_flags &= ~GFS_DIF_EA_INDIRECT; - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - gfs_trans_end(sdp); - - out_gunlock: - gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); - - out_rlist_free: - gfs_rlist_free(&rlist); - - out: - brelse(indbh); - - return error; -} - -/** - * ea_dealloc_block - - * @ip: - * - * Returns: errno - */ - -static int -ea_dealloc_block(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - struct gfs_rgrpd *rgd; - struct buffer_head *dibh; - int error; - - rgd = gfs_blk2rgrpd(sdp, ip->i_di.di_eattr); - if (!rgd) { - gfs_consist_inode(ip); - return -EIO; - } - - error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &al->al_rgd_gh); - if (error) - return error; - - error = gfs_trans_begin(sdp, 1 + rgd->rd_ri.ri_length, 1); - if (error) - goto out_gunlock; - - gfs_metafree(ip, ip->i_di.di_eattr, 1); - - ip->i_di.di_eattr = 0; - if (!ip->i_di.di_blocks) - gfs_consist_inode(ip); - ip->i_di.di_blocks--; - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - gfs_trans_end(sdp); - - out_gunlock: - gfs_glock_dq_uninit(&al->al_rgd_gh); - - return error; -} - -/** - * gfs_ea_dealloc - deallocate the extended attribute fork - * @ip: the inode - * - * Returns: errno - */ - -int -gfs_ea_dealloc(struct gfs_inode *ip) -{ - struct gfs_alloc *al; - int error; - - al = gfs_alloc_get(ip); - - error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out_alloc; - - error = gfs_rindex_hold(ip->i_sbd, &al->al_ri_gh); - if (error) - goto out_quota; - - error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); - if (error) - goto out_rindex; - - if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { - error = ea_dealloc_indirect(ip); - if (error) - goto out_rindex; - } - - error = ea_dealloc_block(ip); - - out_rindex: - gfs_glock_dq_uninit(&al->al_ri_gh); - - out_quota: - gfs_quota_unhold_m(ip); - - out_alloc: - gfs_alloc_put(ip); - - return error; -} - -/** - * gfs_get_eattr_meta - return all the eattr blocks of a file - * @dip: the directory - * @ub: the structure representing the user buffer to copy to - * - * Returns: errno - */ - -int -gfs_get_eattr_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub) -{ - struct buffer_head *bh; - int error; - - error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, - DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - gfs_add_bh_to_ub(ub, bh); - - if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { - struct buffer_head *eabh; - uint64_t *eablk, *end; - - if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_IN)) { - error = -EIO; - goto out; - } - - eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)); - end = eablk + ip->i_sbd->sd_inptrs; - - for (; eablk < end; eablk++) { - uint64_t bn; - - if (!*eablk) - break; - bn = gfs64_to_cpu(*eablk); - - error = gfs_dread(ip->i_gl, bn, - DIO_START | DIO_WAIT, &eabh); - if (error) - break; - gfs_add_bh_to_ub(ub, eabh); - brelse(eabh); - if (error) - break; - } - } - - out: - brelse(bh); - - return error; -} diff --git a/gfs-kernel/src/gfs/eattr.h b/gfs-kernel/src/gfs/eattr.h deleted file mode 100644 index 9a558db..0000000 --- a/gfs-kernel/src/gfs/eattr.h +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __EATTR_DOT_H__ -#define __EATTR_DOT_H__ - -#define GFS_EA_REC_LEN(ea) gfs32_to_cpu((ea)->ea_rec_len) -#define GFS_EA_DATA_LEN(ea) gfs32_to_cpu((ea)->ea_data_len) - -#define GFS_EA_SIZE(ea) \ -MAKE_MULT8(sizeof(struct gfs_ea_header) + \ - (ea)->ea_name_len + \ - ((GFS_EA_IS_STUFFED(ea)) ? \ - GFS_EA_DATA_LEN(ea) : \ - (sizeof(uint64_t) * (ea)->ea_num_ptrs))) - -#define GFS_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) -#define GFS_EA_IS_LAST(ea) ((ea)->ea_flags & GFS_EAFLAG_LAST) - -#define GFS_EAREQ_SIZE_STUFFED(er) \ -MAKE_MULT8(sizeof(struct gfs_ea_header) + \ - (er)->er_name_len + (er)->er_data_len) -#define GFS_EAREQ_SIZE_UNSTUFFED(sdp, er) \ -MAKE_MULT8(sizeof(struct gfs_ea_header) + \ - (er)->er_name_len + \ - sizeof(uint64_t) * DIV_RU((er)->er_data_len, (sdp)->sd_jbsize)) - -#define GFS_EA2NAME(ea) ((char *)((struct gfs_ea_header *)(ea) + 1)) -#define GFS_EA2DATA(ea) (GFS_EA2NAME(ea) + (ea)->ea_name_len) -#define GFS_EA2DATAPTRS(ea) \ -((uint64_t *)(GFS_EA2NAME(ea) + MAKE_MULT8((ea)->ea_name_len))) -#define GFS_EA2NEXT(ea) \ -((struct gfs_ea_header *)((char *)(ea) + GFS_EA_REC_LEN(ea))) -#define GFS_EA_BH2FIRST(bh) \ -((struct gfs_ea_header *)((bh)->b_data + \ - sizeof(struct gfs_meta_header))) - -struct gfs_ea_request { - char *er_name; - char *er_data; - unsigned int er_name_len; - unsigned int er_data_len; - unsigned int er_type; /* GFS_EATYPE_... */ - int er_flags; - mode_t er_mode; -}; - -struct gfs_ea_location { - struct buffer_head *el_bh; - struct gfs_ea_header *el_ea; - struct gfs_ea_header *el_prev; -}; - -static inline unsigned int -gfs_ea_strlen(struct gfs_ea_header *ea) -{ - switch (ea->ea_type) { - case GFS_EATYPE_USR: - return (5 + (ea->ea_name_len + 1)); - case GFS_EATYPE_SYS: - return (7 + (ea->ea_name_len + 1)); - case GFS_EATYPE_SECURITY: - return (9 + (ea->ea_name_len + 1)); - default: - return (0); - } -} - -int gfs_ea_repack(struct gfs_inode *ip); - -int gfs_ea_get_i(struct gfs_inode *ip, struct gfs_ea_request *er); -int gfs_ea_set_i(struct gfs_inode *ip, struct gfs_ea_request *er); -int gfs_ea_remove_i(struct gfs_inode *ip, struct gfs_ea_request *er); - -int gfs_ea_list(struct gfs_inode *ip, struct gfs_ea_request *er); -int gfs_ea_get(struct gfs_inode *ip, struct gfs_ea_request *er); -int gfs_ea_set(struct gfs_inode *ip, struct gfs_ea_request *er); -int gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er); - -int gfs_ea_dealloc(struct gfs_inode *ip); - -int gfs_get_eattr_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); - -/* Exported to acl.c */ - -int gfs_ea_check_size(struct gfs_sbd *sdp, struct gfs_ea_request *er); -int gfs_ea_find(struct gfs_inode *ip, - struct gfs_ea_request *er, - struct gfs_ea_location *el); -int gfs_ea_get_copy(struct gfs_inode *ip, - struct gfs_ea_location *el, - char *data); -int gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er); -int gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el, - struct iattr *attr, char *data); - -#endif /* __EATTR_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/file.c b/gfs-kernel/src/gfs/file.c deleted file mode 100644 index 925a814..0000000 --- a/gfs-kernel/src/gfs/file.c +++ /dev/null @@ -1,458 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> - -#include "gfs.h" -#include "bmap.h" -#include "dio.h" -#include "file.h" -#include "inode.h" -#include "trans.h" - -/** - * gfs_copy2mem - Trivial copy function for gfs_readi() - * @bh: The buffer to copy from, or NULL meaning zero the buffer - * @buf: The buffer to copy/zero - * @offset: The offset in the buffer to copy from - * @size: The amount of data to copy/zero - * - * Returns: errno - */ - -int -gfs_copy2mem(struct buffer_head *bh, void **buf, unsigned int offset, - unsigned int size) -{ - char **p = (char **)buf; - - if (bh) - memcpy(*p, bh->b_data + offset, size); - else - memset(*p, 0, size); - - *p += size; - - return 0; -} - -/** - * gfs_copy2user - Copy data to user space - * @bh: The buffer - * @buf: The destination of the data - * @offset: The offset into the buffer - * @size: The amount of data to copy - * - * Returns: errno - */ - -int -gfs_copy2user(struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size) -{ - char **p = (char **)buf; - int error; - - if (bh) - error = copy_to_user(*p, bh->b_data + offset, size); - else - error = clear_user(*p, size); - - if (error) - error = -EFAULT; - else - *p += size; - - return error; -} - -/** - * gfs_readi - Read a file - * @ip: The GFS Inode - * @buf: The buffer to place result into - * @offset: File offset to begin reading from - * @size: Amount of data to transfer - * @copy_fn: Function to actually perform the copy - * - * The @copy_fn only copies a maximum of a single block at once so - * we are safe calling it with int arguments. It is done so that - * we don't needlessly put 64bit arguments on the stack and it - * also makes the code in the @copy_fn nicer too. - * - * Returns: The amount of data actually copied or the error - */ - -int -gfs_readi(struct gfs_inode *ip, void *buf, - uint64_t offset, unsigned int size, - read_copy_fn_t copy_fn) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *bh; - uint64_t lblock, dblock; - unsigned int o; - uint32_t extlen = 0; - unsigned int amount; - int not_new = 0; - int journaled = gfs_is_jdata(ip); - int copied = 0; - int error = 0; - - if (offset >= ip->i_di.di_size) - return 0; - - if ((offset + size) > ip->i_di.di_size) - size = ip->i_di.di_size - offset; - - if (!size) - return 0; - - if (journaled) { - lblock = offset; - o = do_div(lblock, sdp->sd_jbsize); - } else { - lblock = offset >> sdp->sd_sb.sb_bsize_shift; - o = offset & (sdp->sd_sb.sb_bsize - 1); - } - - if (gfs_is_stuffed(ip)) - o += sizeof(struct gfs_dinode); - else if (journaled) - o += sizeof(struct gfs_meta_header); - - while (copied < size) { - amount = size - copied; - if (amount > sdp->sd_sb.sb_bsize - o) - amount = sdp->sd_sb.sb_bsize - o; - - if (!extlen) { - if (!gfs_is_stuffed(ip)) { - error = gfs_block_map(ip, lblock, ¬_new, - &dblock, &extlen); - if (error) - goto fail; - } else if (!lblock) { - dblock = ip->i_num.no_addr; - extlen = 1; - } else - dblock = 0; - } - - if (extlen > 1) - gfs_start_ra(ip->i_gl, dblock, extlen); - - if (dblock) { - error = gfs_get_data_buffer(ip, dblock, not_new, &bh); - if (error) - goto fail; - - dblock++; - extlen--; - } else - bh = NULL; - - error = copy_fn(bh, &buf, o, amount); - if (bh) - brelse(bh); - if (error) - goto fail; - - copied += amount; - lblock++; - - o = (journaled) ? sizeof(struct gfs_meta_header) : 0; - } - - return copied; - - fail: - return (copied) ? copied : error; -} - -/** - * gfs_copy_from_mem - Trivial copy function for gfs_writei() - * @ip: The file to write to - * @bh: The buffer to copy to or clear - * @buf: The buffer to copy from - * @offset: The offset in the buffer to write to - * @size: The amount of data to write - * @new: Flag indicating that remaining space in the buffer should be zeroed - * - * Returns: errno - */ - -int -gfs_copy_from_mem(struct gfs_inode *ip, struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size, int new) -{ - char **p = (char **)buf; - int error = 0; - - /* The dinode block always gets journaled */ - if (bh->b_blocknr == ip->i_num.no_addr) { - if (gfs_assert_warn(ip->i_sbd, !new)) - return -EIO; - gfs_trans_add_bh(ip->i_gl, bh); - memcpy(bh->b_data + offset, *p, size); - - /* Data blocks for journaled files get written added to the journal */ - } else if (gfs_is_jdata(ip)) { - gfs_trans_add_bh(ip->i_gl, bh); - memcpy(bh->b_data + offset, *p, size); - if (new) - gfs_buffer_clear_ends(bh, offset, size, TRUE); - - /* Non-journaled data blocks get written to in-place disk blocks */ - } else { - memcpy(bh->b_data + offset, *p, size); - if (new) - gfs_buffer_clear_ends(bh, offset, size, FALSE); - error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); - } - - if (!error) - *p += size; - - return error; -} - -/** - * gfs_copy_from_user - Copy bytes from user space for gfs_writei() - * @ip: The file to write to - * @bh: The buffer to copy to or clear - * @buf: The buffer to copy from - * @offset: The offset in the buffer to write to - * @size: The amount of data to write - * @new: Flag indicating that remaining space in the buffer should be zeroed - * - * Returns: errno - */ - -int -gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size, int new) -{ - char **p = (char **)buf; - int error = 0; - - /* the dinode block always gets journaled */ - if (bh->b_blocknr == ip->i_num.no_addr) { - if (gfs_assert_warn(ip->i_sbd, !new)) - return -EIO; - gfs_trans_add_bh(ip->i_gl, bh); - if (copy_from_user(bh->b_data + offset, *p, size)) - error = -EFAULT; - - /* Data blocks for journaled files get written added to the journal */ - } else if (gfs_is_jdata(ip)) { - gfs_trans_add_bh(ip->i_gl, bh); - if (copy_from_user(bh->b_data + offset, *p, size)) - error = -EFAULT; - if (new) { - gfs_buffer_clear_ends(bh, offset, size, TRUE); - if (error) - memset(bh->b_data + offset, 0, size); - } - - /* non-journaled data blocks get written to in-place disk blocks */ - } else { - if (copy_from_user(bh->b_data + offset, *p, size)) - error = -EFAULT; - if (error) { - if (new) - gfs_buffer_clear(bh); - gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); - } else { - if (new) - gfs_buffer_clear_ends(bh, offset, size, FALSE); - error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); - } - } - - if (!error) - *p += size; - - return error; -} - -/** - * gfs_writei - Write bytes to a file - * @ip: The GFS inode - * @buf: The buffer containing information to be written - * @offset: The file offset to start writing at - * @size: The amount of data to write - * @copy_fn: Function to do the actual copying - * - * Returns: The number of bytes correctly written or error code - */ - -int -gfs_writei(struct gfs_inode *ip, void *buf, - uint64_t offset, unsigned int size, - write_copy_fn_t copy_fn, - struct kiocb *iocb) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct buffer_head *dibh, *bh; - uint64_t lblock, dblock; - unsigned int o; - uint32_t extlen = 0, blocks_ra = 0; - unsigned int amount; - int new; - int journaled = gfs_is_jdata(ip); - const uint64_t start = offset; - int copied = 0; - int error = 0; - - if (!size) - return 0; - - if (gfs_is_stuffed(ip) && - ((start + size) > (sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)))) { - error = gfs_unstuff_dinode(ip, gfs_unstuffer_async, NULL); - if (error) - return error; - } - - if (journaled) { - lblock = offset; - o = do_div(lblock, sdp->sd_jbsize); - } else { - lblock = offset >> sdp->sd_sb.sb_bsize_shift; - o = offset & (sdp->sd_sb.sb_bsize - 1); - } - - if (gfs_is_stuffed(ip)) - o += sizeof(struct gfs_dinode); - else if (journaled) - o += sizeof(struct gfs_meta_header); - - while (copied < size) { - amount = size - copied; - if (amount > sdp->sd_sb.sb_bsize - o) - amount = sdp->sd_sb.sb_bsize - o; - - if (!extlen) { - if (!gfs_is_stuffed(ip)) { - new = TRUE; - error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); - if (error) - goto fail; - blocks_ra = 0; - } else { - new = FALSE; - dblock = ip->i_num.no_addr; - extlen = 1; - } - } - - if (journaled && extlen > 1) { - if (!blocks_ra) - blocks_ra = gfs_start_ra(ip->i_gl, dblock, - extlen); - if (blocks_ra) - blocks_ra--; - } - - error = gfs_get_data_buffer(ip, dblock, - (amount == sdp->sd_sb.sb_bsize) ? TRUE : new, - &bh); - if (error) - goto fail; - - if (journaled) - gfs_trans_add_bh(ip->i_gl, bh); - error = copy_fn(ip, bh, &buf, o, amount, new); - brelse(bh); - if (error) - goto fail; - - copied += amount; - lblock++; - dblock++; - extlen--; - - o = (journaled) ? sizeof(struct gfs_meta_header) : 0; - } - - out: - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - return error; - - if (ip->i_di.di_size < start + copied) - ip->i_di.di_size = start + copied; - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - return copied; - - fail: - if (copied) - goto out; - return error; -} - -/* - * gfs_zero_blocks - zero out disk blocks via gfs_writei() - * @ip: The file to write to - * @bh: The buffer to clear - * @buf: The pseudo buffer (not used but added to keep interface unchanged) - * @offset: The offset in the buffer to write to - * @size: The size to zero out - * @new: Flag indicating that remaining space in the buffer should be zeroed - * - * Returns: 0 on success, -EXXX on failure - */ - -int -gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size, int new) -{ - int error = 0; - - /* The dinode block always gets journaled */ - if (bh->b_blocknr == ip->i_num.no_addr) { - if (gfs_assert_warn(ip->i_sbd, !new)) - return -EIO; - gfs_trans_add_bh(ip->i_gl, bh); - memset((bh)->b_data + offset, 0, size); - - /* Data blocks for journaled files get written added to the journal */ - } else if (gfs_is_jdata(ip)) { - gfs_trans_add_bh(ip->i_gl, bh); - memset((bh)->b_data + offset, 0, size); - if (new) - gfs_buffer_clear_ends(bh, offset, size, TRUE); - - /* Non-journaled data blocks get written to in-place disk blocks */ - } else { - memset((bh)->b_data + offset, 0, size); - if (new) - gfs_buffer_clear_ends(bh, offset, size, FALSE); - error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); - } - - return error; -} - diff --git a/gfs-kernel/src/gfs/file.h b/gfs-kernel/src/gfs/file.h deleted file mode 100644 index f2b13a7..0000000 --- a/gfs-kernel/src/gfs/file.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FILE_DOT_H__ -#define __FILE_DOT_H__ - -typedef int (*read_copy_fn_t) (struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size); -typedef int (*write_copy_fn_t) (struct gfs_inode *ip, struct buffer_head *bh, - void **buf, unsigned int offset, - unsigned int size, int new); - -int gfs_copy2mem(struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size); -int gfs_copy2user(struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size); -int gfs_readi(struct gfs_inode *ip, void *buf, uint64_t offset, - unsigned int size, read_copy_fn_t copy_fn); - -int gfs_copy_from_mem(struct gfs_inode *ip, struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size, int new); -int gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size, int new); -int gfs_writei(struct gfs_inode *ip, void *buf, uint64_t offset, - unsigned int size, write_copy_fn_t copy_fn, - struct kiocb *iocb); - -int gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf, - unsigned int offset, unsigned int size, int new); - -static __inline__ int -gfs_internal_read(struct gfs_inode *ip, char *buf, uint64_t offset, - unsigned int size) -{ - return gfs_readi(ip, buf, offset, size, gfs_copy2mem); -} - -static __inline__ int -gfs_internal_write(struct gfs_inode *ip, char *buf, uint64_t offset, - unsigned int size) -{ - return gfs_writei(ip, buf, offset, size, gfs_copy_from_mem, NULL); -} - -#endif /* __FILE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/fixed_div64.h b/gfs-kernel/src/gfs/fixed_div64.h deleted file mode 100644 index b121074..0000000 --- a/gfs-kernel/src/gfs/fixed_div64.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - * - * Additional munging: - * Copyright (C) 2004 Red Hat, Inc. All rights reserved. - */ - -#ifndef __FIXED_DIV64_DOT_H__ -#define __FIXED_DIV64_DOT_H__ - -#include <asm/div64.h> - -#if defined __i386__ -/* For ia32 we need to pull some tricks to get past various versions - * of the compiler which do not like us using do_div in the middle - * of large functions. - */ -static inline __u32 fixed_div64_do_div(void *a, __u32 b, int n) -{ - __u32 mod; - - switch (n) { - case 4: - mod = *(__u32 *)a % b; - *(__u32 *)a = *(__u32 *)a / b; - return mod; - case 8: - { - unsigned long __upper, __low, __high, __mod; - __u64 c = *(__u64 *)a; - __upper = __high = c >> 32; - __low = c; - if (__high) { - __upper = __high % (b); - __high = __high / (b); - } - asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); - asm("":"=A" (c):"a" (__low),"d" (__high)); - *(__u64 *)a = c; - return __mod; - } - } - - /* NOTREACHED */ - return 0; -} - -/* Side effect free 64 bit mod operation */ -static inline __u32 fixed_div64_do_mod(void *a, __u32 b, int n) -{ - switch (n) { - case 4: - return *(__u32 *)a % b; - case 8: - { - unsigned long __upper, __low, __high, __mod; - __u64 c = *(__u64 *)a; - __upper = __high = c >> 32; - __low = c; - if (__high) { - __upper = __high % (b); - __high = __high / (b); - } - asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); - asm("":"=A" (c):"a" (__low),"d" (__high)); - return __mod; - } - } - - /* NOTREACHED */ - return 0; -} -#else -static inline __u32 fixed_div64_do_div(void *a, __u32 b, int n) -{ - __u32 mod; - - switch (n) { - case 4: - mod = *(__u32 *)a % b; - *(__u32 *)a = *(__u32 *)a / b; - return mod; - case 8: - mod = do_div(*(__u64 *)a, b); - return mod; - } - - /* NOTREACHED */ - return 0; -} - -/* Side effect free 64 bit mod operation */ -static inline __u32 fixed_div64_do_mod(void *a, __u32 b, int n) -{ - switch (n) { - case 4: - return *(__u32 *)a % b; - case 8: - { - __u64 c = *(__u64 *)a; - return do_div(c, b); - } - } - - /* NOTREACHED */ - return 0; -} -#endif - -#undef do_div -#define do_div(a, b) fixed_div64_do_div(&(a), (b), sizeof(a)) -#define do_mod(a, b) fixed_div64_do_mod(&(a), (b), sizeof(a)) - -#endif /* __FIXED_DIV64_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/format.h b/gfs-kernel/src/gfs/format.h deleted file mode 100644 index f5cabed..0000000 --- a/gfs-kernel/src/gfs/format.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FORMAT_DOT_H__ -#define __FORMAT_DOT_H__ - -static const uint32_t gfs_old_fs_formats[] = { - 1308, - 1307, - 1306, - 1305, - 0 -}; - -static const uint32_t gfs_old_multihost_formats[] = { - 1400, - 0 -}; - -#endif /* __FORMAT_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/gfs.h b/gfs-kernel/src/gfs/gfs.h deleted file mode 100644 index 82b7ec2..0000000 --- a/gfs-kernel/src/gfs/gfs.h +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFS_DOT_H__ -#define __GFS_DOT_H__ - -#define GFS_RELEASE_NAME "<CVS>" - -#include <linux/lm_interface.h> -#include <linux/gfs_ondisk.h> - -#include "fixed_div64.h" -#include "lvb.h" -#include <linux/backing-dev.h> -#include "incore.h" -#include "util.h" - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#define NO_CREATE (0) -#define CREATE (1) - -#if (BITS_PER_LONG == 64) -#define PRIu64 "lu" -#define PRId64 "ld" -#define PRIo64 "lo" -#define PRIx64 "lx" -#define PRIX64 "lX" -#define SCNu64 "lu" -#define SCNd64 "ld" -#define SCNo64 "lo" -#define SCNx64 "lx" -#define SCNX64 "lX" -#else -#define PRIu64 "Lu" -#define PRId64 "Ld" -#define PRIo64 "Lo" -#define PRIx64 "Lx" -#define PRIX64 "LX" -#define SCNu64 "Lu" -#define SCNd64 "Ld" -#define SCNo64 "Lo" -#define SCNx64 "Lx" -#define SCNX64 "LX" -#endif - -/* Divide num by den. Round up if there is a remainder. */ -#define DIV_RU(num, den) (((num) + (den) - 1) / (den)) -#define MAKE_MULT8(x) (((x) + 7) & ~7) - -#define GFS_FAST_NAME_SIZE (8) - -#define vfs2sdp(sb) ((struct gfs_sbd *)(sb)->s_fs_info) -#define vn2ip(inode) ((struct gfs_inode *)(inode)->u.generic_ip) -#define vf2fp(file) ((struct gfs_file *)(file)->private_data) -#define bh2bd(bh) ((struct gfs_bufdata *)(bh)->b_private) - -/* A process can build only one transaction at a time */ -#define current_transaction ((struct gfs_trans *)(current->journal_info)) - -#define gl2ip(gl) ((struct gfs_inode *)(gl)->gl_object) -#define gl2rgd(gl) ((struct gfs_rgrpd *)(gl)->gl_object) -#define gl2gl(gl) ((struct gfs_glock *)(gl)->gl_object) - -#define gfs_printf(fmt, args...) \ -do { \ - if (buf) { \ - int gspf_left = size - *count, gspf_out; \ - if (gspf_left <= 0) \ - goto out; \ - gspf_out = snprintf(buf + *count, gspf_left, fmt, ##args); \ - if (gspf_out < gspf_left) \ - *count += gspf_out; \ - else \ - goto out; \ - } else \ - printk(fmt, ##args); \ -} while (0) - -#endif /* __GFS_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/gfs_ioctl.h b/gfs-kernel/src/gfs/gfs_ioctl.h deleted file mode 100644 index d706599..0000000 --- a/gfs-kernel/src/gfs/gfs_ioctl.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFS_IOCTL_DOT_H__ -#define __GFS_IOCTL_DOT_H__ - -#define _GFSC_(x) (('G' << 8) | (x)) - -/* Ioctls implemented */ - -#define GFS_IOCTL_IDENTIFY _GFSC_(35) -#define GFS_IOCTL_SUPER _GFSC_(45) - -struct gfs_ioctl { - unsigned int gi_argc; - char **gi_argv; - - char __user *gi_data; - unsigned int gi_size; - uint64_t gi_offset; -}; - -#endif /* ___GFS_IOCTL_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/gfs_ondisk.h b/gfs-kernel/src/gfs/gfs_ondisk.h deleted file mode 100644 index 186d0e8..0000000 --- a/gfs-kernel/src/gfs/gfs_ondisk.h +++ /dev/null @@ -1,1915 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * On-disk structures. - * - * THE BIG PICTURE of on-disk layout: - * - * GFS filesystem code views the entire filesystem, including journals, as - * one contiguous group of blocks on one (perhaps virtual) storage device. - * The filesystem space is shared, not distributed; each node in the cluster - * must see the entire filesystem space. - * - * If the filesystem is spread across multiple physical storage devices, - * volume management (device mapping) must be used to present the fileystem - * space to GFS as one (virtual) device, with contiguous blocks. - * - * The superblock contains basic information about the filesytem, and appears - * at a location 64 KBytes into the filesystem. The first 64 KBytes of the - * filesystem are empty, providing a safety buffer against wayward volume - * management software (that sometimes write data into the first few bytes of - * a device) or administrators. - * - * After the superblock, the rest of the filesystem is divided into multiple - * Resource Groups and several journals. - * - * The Resource Groups (RGs or rgrps) contain the allocatable blocks that are - * used for storing files, directories, etc., and all of the associated - * metadata. Each RG has its own set of block allocation statistics (within - * the RG header), a number of blocks containing the block allocation bitmap, - * and a large number of allocatable blocks for file data and metadata. - * Multiple RGs allow multiple nodes to simultaneously allocate blocks from the - * filesystem (using different RGs), enhancing parallel access. RG size and - * number of RGs are determined by gfs_mkfs when creating the filesystem. - * An administrator can specify RG size (see man gfs_mkfs). - * - * The journals contain temporary copies of metadata blocks, along with - * other data, that allow GFS to recover the filesystem to a consistent state - * (at least as far as metadata is concerned) if a node fails in the midst - * of performing a write transaction. There must be one journal for each node - * in the cluster. Since access to the entire filesystem space is shared, - * if a node crashes, another node will be able to read the crashed node's - * journal, and perform recovery. - * - * Currently, gfs_mkfs places the journals right in the middle of a freshly - * created filesystem space, between 2 large groups of RGs. From a filesystem - * layout perspective, this placement is not a requirement; the journals - * could be placed anywhere within the filesystem space. - * - * New Resource Groups and Journals may be added to the filesystem after the - * filesystem has been created, if the filesystem's (virtual) device is made - * larger. See man gfs_grow and gfs_jadd. - * - * A few special hidden inodes are contained in a GFS filesystem. They do - * not appear in any directories; instead, the superblock points to them - * using block numbers for their location. The special inodes are: - * - * Root inode: Root directory of the filesystem - * Resource Group Index: A file containing block numbers and sizes of all RGs - * Journal Index: A file containing block numbers and sizes of all journals - * Quota: A file containing all quota information for the filesystem - * License: A file containing license information - * - * Note that there is NOTHING RELATED TO INTER-NODE LOCK MANAGEMENT ON-DISK. - * Locking is handled completely off-disk, typically via LAN. - * - * NOTE: - * If you add 8 byte fields to these structures, they must be 8 byte - * aligned. 4 byte field must be 4 byte aligned, etc... - * - * All structures must be a multiple of 8 bytes long. - * - * GRIPES: - * We should have forgetten about supporting 512B FS block sizes - * and made the di_reserved field in the struct gfs_dinode structure - * much bigger. - * - * de_rec_len in struct gfs_dirent should really have been a 32-bit value - * as it now limits us to a 64k FS block size (with the current code - * in dir.c). - */ - -#ifndef __GFS_ONDISK_DOT_H__ -#define __GFS_ONDISK_DOT_H__ - -#define GFS_MAGIC (0x01161970) /* for all on-disk headers */ -#define GFS_BASIC_BLOCK (512) /* "basic block" = "sector" = 512B */ -#define GFS_BASIC_BLOCK_SHIFT (9) - -/* Controls how much data can be logged in-core before dumping log to disk */ - -#define GFS_DUMPS_PER_LOG (4) /* 1/4 of on-disk journal size*/ - -/* Lock numbers of the LM_TYPE_NONDISK type. These protect certain - * cluster-wide operations (rather than on-disk entities). - * Currently, the LIVE lock is not used for any real purpose. */ - -#define GFS_MOUNT_LOCK (0) /* only one node can Mount at a time */ -#define GFS_LIVE_LOCK (1) /* shared by all mounted nodes */ -#define GFS_TRANS_LOCK (2) /* Transaction, protects jrnl recovery */ -#define GFS_RENAME_LOCK (3) /* only one node can Rename at a time */ - -/* On-disk format (version) numbers for various metadata types, - * used in gfs_meta_header */ - -#define GFS_FORMAT_SB (100) /* Super-Block */ -#define GFS_FORMAT_RG (200) /* Resource Group Header */ -#define GFS_FORMAT_RB (300) /* Resource Group Block Alloc BitBlock */ -#define GFS_FORMAT_DI (400) /* "Disk" inode (dinode) */ -#define GFS_FORMAT_IN (500) /* Indirect dinode block list */ -#define GFS_FORMAT_LF (600) /* Leaf dinode block list */ -#define GFS_FORMAT_JD (700) /* Journal Data */ -#define GFS_FORMAT_LH (800) /* Log Header */ -#define GFS_FORMAT_LD (900) /* Log Descriptor */ -/* These don't have actual struct gfs_meta_header structures to go with them */ -#define GFS_FORMAT_JI (1000) /* Journal Index */ -#define GFS_FORMAT_RI (1100) /* Resource Group Index */ -#define GFS_FORMAT_DE (1200) /* Directory Entry */ -#define GFS_FORMAT_QU (1500) /* Quota */ -#define GFS_FORMAT_EA (1600) /* Extended Attribute */ -#define GFS_FORMAT_ED (1700) /* Extended Attribute data */ -/* These version #s are embedded in the superblock */ -#define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */ -#define GFS_FORMAT_MULTI (1401) /* Multi-Host */ - -/* - * An on-disk inode number - * Initially, the on-disk block address of the inode block is assigned as the - * formal (permanent) ID as well. Block address can change (to move inode - * on-disk), but formal ID must stay unchanged once assigned. - */ - -#define gfs_inum_equal(ino1, ino2) \ -(((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \ - ((ino1)->no_addr == (ino2)->no_addr)) - -struct gfs_inum { - uint64_t no_formal_ino; /* inode identifier */ - uint64_t no_addr; /* block # of dinode block */ -}; - -/* - * Generic metadata head structure - * - * Every inplace buffer logged in the journal must start - * with a struct gfs_meta_header. - * - * In addition to telling what kind of metadata is in the block, - * the metaheader contains the important generation and incarnation - * numbers. - * - * The generation number is used during journal recovery to determine - * whether an in-place block on-disk is older than an on-disk journaled copy - * of the block. If so, GFS overwrites the in-place block with the journaled - * version of the block. - * - * A meta block's generation number must increment monotonically across the - * cluster, each time new contents are committed to the block. This means - * that whenever GFS allocates a pre-existing metadata block, GFS must read - * that block from disk (in case another node has incremented it). It also - * means that GFS must sync the block (with incremented generation number) - * to disk (both log and in-place blocks), not only after changing contents - * of the block, but also after de-allocating the block (GFS can't just throw - * away incore metadata for a file that it's just erased). - * - * The incarnation number is used only for on-disk (d)inodes. GFS increments - * it each time it de-allocates a dinode block (i.e. each time the dinode - * loses its identity with a particular file, directory, etc.). When the - * dinode is later allocated (i.e. to be identified with a new file, etc.), - * GFS copies the incarnation number into the VFS inode's i_generation member. - * If GFS is used as the backing store for an NFS server, GFS uses this - * i_generation number as part of the NFS filehandle, which differentiates - * it from the previous identity of the dinode, and helps protect against - * filesystem corruption that could happen with the use of outdated, - * invalid, or malicious filehandles. See ops_export.c. - * - * GFS caches de-allocated meta-headers, to minimize disk reads. - * See struct gfs_meta_header_cache. - */ - -#define GFS_METATYPE_NONE (0) -#define GFS_METATYPE_SB (1) /* Super-Block */ -#define GFS_METATYPE_RG (2) /* Resource Group Header */ -#define GFS_METATYPE_RB (3) /* Resource Group Block Alloc BitBlock */ -#define GFS_METATYPE_DI (4) /* "Disk" inode (dinode) */ -#define GFS_METATYPE_IN (5) /* Indirect dinode block list */ -#define GFS_METATYPE_LF (6) /* Leaf dinode block list */ -#define GFS_METATYPE_JD (7) /* Journal Data */ -#define GFS_METATYPE_LH (8) /* Log Header (gfs_log_header) */ -#define GFS_METATYPE_LD (9) /* Log Descriptor (gfs_log_descriptor) */ -#define GFS_METATYPE_EA (10) /* Extended Attribute */ -#define GFS_METATYPE_ED (11) /* Extended Attribute data */ - -#define GFS_META_CLUMP (64) /* # blocks to convert fm data to meta */ - -struct gfs_meta_header { - uint32_t mh_magic; /* GFS_MAGIC sanity check magic number */ - uint32_t mh_type; /* GFS_METATYPE_XX type of metadata block */ - uint64_t mh_generation; /* increment before writing to journal */ - uint32_t mh_format; /* GFS_FORMAT_XX (version # for this type) */ - uint32_t mh_incarn; /* increment when marking dinode "unused" */ -}; - -/* - * super-block structure - * - * One of these is at beginning of filesystem. - * It's probably good if SIZEOF_SB <= GFS_BASIC_BLOCK (512 bytes) - */ - -/* Address of SuperBlock in GFS basic blocks. 1st 64K of filesystem is empty - for safety against getting clobbered by wayward volume managers, etc. - 64k was chosen because it's the largest GFS-supported fs block size. */ -#define GFS_SB_ADDR (128) - -/* The lock number for the superblock (must be zero) */ -#define GFS_SB_LOCK (0) -#define GFS_CRAP_LOCK (1) - -/* Requirement: GFS_LOCKNAME_LEN % 8 == 0 - Includes: the fencing zero at the end */ -#define GFS_LOCKNAME_LEN (64) - -struct gfs_sb { - /* Order is important; need to be able to read old superblocks - in order to support on-disk version upgrades */ - struct gfs_meta_header sb_header; - - uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ - uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ - uint32_t sb_flags; /* ?? */ - - uint32_t sb_bsize; /* fundamental FS block size in bytes */ - uint32_t sb_bsize_shift; /* log2(sb_bsize) */ - uint32_t sb_seg_size; /* Journal segment size in FS blocks */ - - /* These special inodes do not appear in any on-disk directory. */ - struct gfs_inum sb_jindex_di; /* journal index inode */ - struct gfs_inum sb_rindex_di; /* resource group index inode */ - struct gfs_inum sb_root_di; /* root directory inode */ - - /* Default inter-node locking protocol (lock module) and namespace */ - char sb_lockproto[GFS_LOCKNAME_LEN]; /* lock protocol name */ - char sb_locktable[GFS_LOCKNAME_LEN]; /* unique name for this FS */ - - /* More special inodes */ - struct gfs_inum sb_quota_di; /* quota inode */ - struct gfs_inum sb_license_di; /* license inode */ - - char sb_reserved[96]; -}; - -/* - * journal index structure - * - * One for each journal used by the filesystem. - * These descriptors are packed contiguously within the jindex inode (file). - */ - -struct gfs_jindex { - uint64_t ji_addr; /* starting block of the journal */ - uint32_t ji_nsegment; /* number (quantity) of segments in journal */ - uint32_t ji_pad; - - char ji_reserved[64]; -}; - -/* - * resource index structure - * - * One of these for each resource group in the filesystem. - * These descriptors are packed contiguously within the rindex inode (file). - * Also see struct gfs_rgrp. - */ - -struct gfs_rindex { - uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ - uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ - uint32_t ri_pad; - - uint64_t ri_data1; /* block # of first data/meta block in rgrp */ - uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ - - uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ - - char ri_reserved[64]; -}; - -/* - * resource group header structure - * - * One of these at beginning of the first block of an rgrp, - * followed by block alloc bitmap data in remainder of first block. - * Each resource group contains: - * Header block, including block allocation statistics (struct gfs_rgrp) - * and first part of block alloc bitmap. - * Bitmap block(s), continuing block alloc bitmap started in header block. - * Data/meta blocks, allocatable blocks containing file data and metadata. - * - * In older versions, now-unused (but previously allocated) dinodes were - * saved for re-use in an on-disk linked list (chain). This is no longer - * done, but support still exists for reclaiming dinodes from this list, - * to support upgrades from older on-disk formats. - */ - -/* Each data block within rgrp is represented by 2 bits in the alloc bitmap */ -#define GFS_NBBY (4) /* # blocks represented by 1 bitmap byte */ -#define GFS_BIT_SIZE (2) -#define GFS_BIT_MASK (0x00000003) - -/* - * 4 possible block allocation states: - * bit 0 = alloc(1)/free(0) - * bit 1 = metadata(1)/data(0) - */ -#define GFS_BLKST_FREE (0) -#define GFS_BLKST_USED (1) -#define GFS_BLKST_FREEMETA (2) -#define GFS_BLKST_USEDMETA (3) - -struct gfs_rgrp { - struct gfs_meta_header rg_header; - - uint32_t rg_flags; /* ?? */ - - uint32_t rg_free; /* Number (qty) of free data blocks */ - - /* Dinodes are USEDMETA, but are handled separately from other METAs */ - uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ - uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ - struct gfs_inum rg_freedi_list; /* 1st block in chain of free dinodes */ - - /* These META statistics do not include dinodes (used or free) */ - uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ - uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ - - char rg_reserved[64]; -}; - -/* - * quota structure - */ - -struct gfs_quota { - uint64_t qu_limit; - uint64_t qu_warn; - int64_t qu_value; - - char qu_reserved[64]; -}; - -/* - * dinode (disk inode) structure - * The ondisk representation of inodes - * One for each file, directory, etc. - * GFS does not put more than one inode in a single block. - * The inode may be "stuffed", carrying file data along with metadata, - * if the file data is small enough. - * Otherwise, the inode block contains pointers to other blocks that contain - * either file data or other pointers to other blocks (indirect addressing - * via a metadata tree). - */ - -#define GFS_MAX_META_HEIGHT (10) -#define GFS_DIR_MAX_DEPTH (17) - -/* Dinode types */ -#define GFS_FILE_NON (0) -#define GFS_FILE_REG (1) /* regular file */ -#define GFS_FILE_DIR (2) /* directory */ -#define GFS_FILE_LNK (5) /* link */ -#define GFS_FILE_BLK (7) /* block device node */ -#define GFS_FILE_CHR (8) /* character device node */ -#define GFS_FILE_FIFO (101) /* fifo/pipe */ -#define GFS_FILE_SOCK (102) /* socket */ - -/* Dinode flags */ -#define GFS_DIF_JDATA (0x00000001) /* jrnl all data for this file */ -#define GFS_DIF_EXHASH (0x00000002) /* hashed directory (leaves) */ -#define GFS_DIF_UNUSED (0x00000004) /* unused dinode */ -#define GFS_DIF_EA_INDIRECT (0x00000008) /* extended attribute, indirect*/ -#define GFS_DIF_DIRECTIO (0x00000010) -#define GFS_DIF_IMMUTABLE (0x00000020) /* Can't change file */ -#define GFS_DIF_APPENDONLY (0x00000040) /* Can only add to end of file */ -#define GFS_DIF_NOATIME (0x00000080) /* Don't update access time - (currently unused/ignored) */ -#define GFS_DIF_SYNC (0x00000100) /* Flush to disk, don't cache - (currently unused/ignored) */ -#define GFS_DIF_INHERIT_DIRECTIO (0x40000000) /* new files get DIRECTIO flag */ -#define GFS_DIF_INHERIT_JDATA (0x80000000) /* new files get JDATA flag */ - -struct gfs_dinode { - struct gfs_meta_header di_header; - - struct gfs_inum di_num; /* formal inode # and block address */ - - uint32_t di_mode; /* mode of file */ - uint32_t di_uid; /* owner's user id */ - uint32_t di_gid; /* owner's group id */ - uint32_t di_nlink; /* number (qty) of links to this file */ - uint64_t di_size; /* number (qty) of bytes in file */ - uint64_t di_blocks; /* number (qty) of blocks in file */ - int64_t di_atime; /* time last accessed */ - int64_t di_mtime; /* time last modified */ - int64_t di_ctime; /* time last changed */ - - /* Non-zero only for character or block device nodes */ - uint32_t di_major; /* device major number */ - uint32_t di_minor; /* device minor number */ - - /* Block allocation strategy */ - uint64_t di_rgrp; /* dinode rgrp block number */ - uint64_t di_goal_rgrp; /* rgrp to alloc from next */ - uint32_t di_goal_dblk; /* data block goal */ - uint32_t di_goal_mblk; /* metadata block goal */ - - uint32_t di_flags; /* GFS_DIF_... */ - - /* struct gfs_rindex, struct gfs_jindex, or struct gfs_dirent */ - uint32_t di_payload_format; /* GFS_FORMAT_... */ - uint16_t di_type; /* GFS_FILE_... type of file */ - uint16_t di_height; /* height of metadata (0 == stuffed) */ - uint32_t di_incarn; /* incarnation (unused, see gfs_meta_header) */ - uint16_t di_pad; - - /* These only apply to directories */ - uint16_t di_depth; /* Number of bits in the table */ - uint32_t di_entries; /* The # (qty) of entries in the directory */ - - /* This formed an on-disk chain of unused dinodes */ - struct gfs_inum di_next_unused; /* used in old versions only */ - - uint64_t di_eattr; /* extended attribute block number */ - - char di_reserved[56]; -}; - -/* - * indirect block header - * - * A component of a dinode's indirect addressing metadata tree. - * These are pointed to by pointers in dinodes or other indirect blocks. - */ - -struct gfs_indirect { - struct gfs_meta_header in_header; - - char in_reserved[64]; -}; - -/* - * directory structure - many of these per directory file - * - * See comments at beginning of dir.c - */ - -#define GFS_FNAMESIZE (255) -#define GFS_DIRENT_SIZE(name_len) ((sizeof(struct gfs_dirent) + (name_len) + 7) & ~7) - -struct gfs_dirent { - struct gfs_inum de_inum; /* formal inode number and block address */ - uint32_t de_hash; /* hash of the filename */ - uint16_t de_rec_len; /* the length of the dirent */ - uint16_t de_name_len; /* the length of the name */ - uint16_t de_type; /* GFS_FILE_... type of dinode this points to */ - - char de_reserved[14]; -}; - -/* - * Header of leaf directory nodes - * - * See comments at beginning of dir.c - */ - -struct gfs_leaf { - struct gfs_meta_header lf_header; - - uint16_t lf_depth; /* Depth of leaf */ - uint16_t lf_entries; /* Number of dirents in leaf */ - uint32_t lf_dirent_format; /* GFS_FORMAT_DE (version #) */ - uint64_t lf_next; /* Next leaf, if overflow */ - - char lf_reserved[64]; -}; - -/* - * Log header structure - * - * Two of these are in the first block of a transaction log: - * 1) at beginning of block - * 2) at end of first 512-byte sector within block - */ - -#define GFS_LOG_HEAD_UNMOUNT (0x00000001) /* log is clean, can unmount fs */ - -struct gfs_log_header { - struct gfs_meta_header lh_header; - - uint32_t lh_flags; /* GFS_LOG_HEAD_... */ - uint32_t lh_pad; - - uint64_t lh_first; /* Block number of first header in this trans */ - uint64_t lh_sequence; /* Sequence number of this transaction */ - - uint64_t lh_tail; /* Block number of log tail */ - uint64_t lh_last_dump; /* Block number of last dump */ - - char lh_reserved[64]; -}; - -/* - * Log type descriptor - * - * One of these for each chunk in a transaction - */ - -#define GFS_LOG_DESC_METADATA (300) /* metadata */ -/* ld_data1 is the number (quantity) of metadata blocks in the descriptor. - ld_data2 is unused. - */ - -#define GFS_LOG_DESC_IUL (400) /* unlinked inode */ -/* ld_data1 is TRUE if this is a dump. - ld_data2 is unused. - FixMe!!! ld_data1 should be the number (quantity) of entries. - ld_data2 should be "TRUE if this is a dump". - */ - -#define GFS_LOG_DESC_IDA (401) /* de-allocated inode */ -/* ld_data1 is unused. - ld_data2 is unused. - FixMe!!! ld_data1 should be the number (quantity) of entries. - */ - -#define GFS_LOG_DESC_Q (402) /* quota */ -/* ld_data1 is the number of quota changes in the descriptor. - ld_data2 is TRUE if this is a dump. - */ - -#define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */ -/* ld_data1 is unused. - ld_data2 is unused. - */ - -struct gfs_log_descriptor { - struct gfs_meta_header ld_header; - - uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ - uint32_t ld_length; /* Number of buffers in this chunk */ - uint32_t ld_data1; /* descriptor-specific field */ - uint32_t ld_data2; /* descriptor-specific field */ - - char ld_reserved[64]; -}; - -/* - * Metadata block tags - * - * One for each logged block. Tells where block really belongs on-disk. - * These descriptor tags are packed contiguously after a gfs_log_descriptor. - */ - -struct gfs_block_tag { - uint64_t bt_blkno; /* inplace block number */ - uint32_t bt_flags; /* ?? */ - uint32_t bt_pad; -}; - -/* - * Quota Journal Tag - */ - -#define GFS_QTF_USER (0x00000001) - -struct gfs_quota_tag { - int64_t qt_change; - uint32_t qt_flags; /* GFS_QTF_... */ - uint32_t qt_id; -}; - -/* - * Extended attribute header format - */ - -#define GFS_EA_MAX_NAME_LEN (255) -#define GFS_EA_MAX_DATA_LEN (65536) - -#define GFS_EATYPE_UNUSED (0) -#define GFS_EATYPE_USR (1) /* user attribute */ -#define GFS_EATYPE_SYS (2) /* system attribute */ -#define GFS_EATYPE_SECURITY (3) /* security attribute */ - -#define GFS_EATYPE_LAST (3) -#define GFS_EATYPE_VALID(x) ((x) <= GFS_EATYPE_LAST) - -#define GFS_EAFLAG_LAST (0x01) /* last ea in block */ - -struct gfs_ea_header { - uint32_t ea_rec_len; /* total record length: hdr + name + data */ - uint32_t ea_data_len; /* data length, in bytes */ - uint8_t ea_name_len; /* no NULL pointer after the string */ - uint8_t ea_type; /* GFS_EATYPE_... */ - uint8_t ea_flags; /* GFS_EAFLAG_... */ - uint8_t ea_num_ptrs; /* # fs blocks needed for EA */ - uint32_t ea_pad; -}; - -/* - * Statfs change - * Describes an change to the pool of free and allocated - * blocks. - */ - -struct gfs_statfs_change { - uint64_t sc_total; - uint64_t sc_free; - uint64_t sc_dinodes; -}; - -struct gfs_statfs_change_host { - int64_t sc_total; - int64_t sc_free; - int64_t sc_dinodes; -}; - -/* Endian functions */ - -#define GFS_ENDIAN_BIG - -#ifdef GFS_ENDIAN_BIG - -#define gfs16_to_cpu be16_to_cpu -#define gfs32_to_cpu be32_to_cpu -#define gfs64_to_cpu be64_to_cpu - -#define cpu_to_gfs16 cpu_to_be16 -#define cpu_to_gfs32 cpu_to_be32 -#define cpu_to_gfs64 cpu_to_be64 - -#else /* GFS_ENDIAN_BIG */ - -#define gfs16_to_cpu le16_to_cpu -#define gfs32_to_cpu le32_to_cpu -#define gfs64_to_cpu le64_to_cpu - -#define cpu_to_gfs16 cpu_to_le16 -#define cpu_to_gfs32 cpu_to_le32 -#define cpu_to_gfs64 cpu_to_le64 - -#endif /* GFS_ENDIAN_BIG */ - -/* Translation functions */ - -void gfs_inum_in(struct gfs_inum *no, char *buf); -void gfs_inum_out(struct gfs_inum *no, char *buf); -void gfs_meta_header_in(struct gfs_meta_header *mh, char *buf); -void gfs_meta_header_out(struct gfs_meta_header *mh, char *buf); -void gfs_sb_in(struct gfs_sb *sb, char *buf); -void gfs_sb_out(struct gfs_sb *sb, char *buf); -void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); -void gfs_jindex_out(struct gfs_jindex *jindex, char *buf); -void gfs_rindex_in(struct gfs_rindex *rindex, char *buf); -void gfs_rindex_out(struct gfs_rindex *rindex, char *buf); -void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf); -void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf); -void gfs_quota_in(struct gfs_quota *quota, char *buf); -void gfs_quota_out(struct gfs_quota *quota, char *buf); -void gfs_dinode_in(struct gfs_dinode *dinode, char *buf); -void gfs_dinode_out(struct gfs_dinode *dinode, char *buf); -void gfs_indirect_in(struct gfs_indirect *indirect, char *buf); -void gfs_indirect_out(struct gfs_indirect *indirect, char *buf); -void gfs_dirent_in(struct gfs_dirent *dirent, char *buf); -void gfs_dirent_out(struct gfs_dirent *dirent, char *buf); -void gfs_leaf_in(struct gfs_leaf *leaf, char *buf); -void gfs_leaf_out(struct gfs_leaf *leaf, char *buf); -void gfs_log_header_in(struct gfs_log_header *head, char *buf); -void gfs_log_header_out(struct gfs_log_header *head, char *buf); -void gfs_desc_in(struct gfs_log_descriptor *desc, char *buf); -void gfs_desc_out(struct gfs_log_descriptor *desc, char *buf); -void gfs_block_tag_in(struct gfs_block_tag *btag, char *buf); -void gfs_block_tag_out(struct gfs_block_tag *btag, char *buf); -void gfs_quota_tag_in(struct gfs_quota_tag *qtag, char *buf); -void gfs_quota_tag_out(struct gfs_quota_tag *qtag, char *buf); -void gfs_ea_header_in(struct gfs_ea_header *qtag, char *buf); -void gfs_ea_header_out(struct gfs_ea_header *qtag, char *buf); - -/* Printing functions */ - -void gfs_inum_print(struct gfs_inum *no); -void gfs_meta_header_print(struct gfs_meta_header *mh); -void gfs_sb_print(struct gfs_sb *sb); -void gfs_jindex_print(struct gfs_jindex *jindex); -void gfs_rindex_print(struct gfs_rindex *rindex); -void gfs_rgrp_print(struct gfs_rgrp *rgrp); -void gfs_quota_print(struct gfs_quota *quota); -void gfs_dinode_print(struct gfs_dinode *dinode); -void gfs_indirect_print(struct gfs_indirect *indirect); -void gfs_dirent_print(struct gfs_dirent *dirent, char *name); -void gfs_leaf_print(struct gfs_leaf *leaf); -void gfs_log_header_print(struct gfs_log_header *head); -void gfs_desc_print(struct gfs_log_descriptor *desc); -void gfs_block_tag_print(struct gfs_block_tag *tag); -void gfs_quota_tag_print(struct gfs_quota_tag *tag); -void gfs_ea_header_print(struct gfs_ea_header *ea, char *name); - -/* The hash function for ExHash directories */ - -uint32_t gfs_dir_hash(const char *data, int len); - -#endif /* __GFS_ONDISK_DOT_H__ */ - - - -#ifdef WANT_GFS_CONVERSION_FUNCTIONS - -#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} -#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} -#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} -#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} -#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} -#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} -#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} -#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} - -#define pa(struct, member, count) print_array(#member, struct->member, count); - -/** - * print_array - Print out an array of bytes - * @title: what to print before the array - * @buf: the array - * @count: the number of bytes - * - */ - -static void -print_array(char *title, char *buf, int count) -{ - int x; - - printk(" %s =\n", title); - for (x = 0; x < count; x++) { - printk("%.2X ", (unsigned char)buf[x]); - if (x % 16 == 15) - printk("\n"); - } - if (x % 16) - printk("\n"); -} - -/** - * gfs_inum_in - Read in an inode number - * @no: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_inum_in(struct gfs_inum *no, char *buf) -{ - struct gfs_inum *str = (struct gfs_inum *)buf; - - CPIN_64(no, str, no_formal_ino); - CPIN_64(no, str, no_addr); -} - -/** - * gfs_inum_out - Write out an inode number - * @no: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_inum_out(struct gfs_inum *no, char *buf) -{ - struct gfs_inum *str = (struct gfs_inum *)buf; - - CPOUT_64(no, str, no_formal_ino); - CPOUT_64(no, str, no_addr); -} - -/** - * gfs_inum_print - Print out a inode number - * @no: the cpu-order buffer - * - */ - -void -gfs_inum_print(struct gfs_inum *no) -{ - pv(no, no_formal_ino, "%"PRIu64); - pv(no, no_addr, "%"PRIu64); -} - -/** - * gfs_meta_header_in - Read in a metadata header - * @mh: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_meta_header_in(struct gfs_meta_header *mh, char *buf) -{ - struct gfs_meta_header *str = (struct gfs_meta_header *)buf; - - CPIN_32(mh, str, mh_magic); - CPIN_32(mh, str, mh_type); - CPIN_64(mh, str, mh_generation); - CPIN_32(mh, str, mh_format); - CPIN_32(mh, str, mh_incarn); -} - -/** - * gfs_meta_header_in - Write out a metadata header - * @mh: the cpu-order structure - * @buf: the disk-order buffer - * - * Don't ever change the generation number in this routine. - * It's done manually in increment_generation(). - */ - -void -gfs_meta_header_out(struct gfs_meta_header *mh, char *buf) -{ - struct gfs_meta_header *str = (struct gfs_meta_header *)buf; - - CPOUT_32(mh, str, mh_magic); - CPOUT_32(mh, str, mh_type); -#if 0 - /* Don't do this! - Mh_generation should only be change manually. */ - CPOUT_64(mh, str, mh_generation); -#endif - CPOUT_32(mh, str, mh_format); - CPOUT_32(mh, str, mh_incarn); -} - -/** - * gfs_meta_header_print - Print out a metadata header - * @mh: the cpu-order buffer - * - */ - -void -gfs_meta_header_print(struct gfs_meta_header *mh) -{ - pv(mh, mh_magic, "0x%.8X"); - pv(mh, mh_type, "%u"); - pv(mh, mh_generation, "%"PRIu64); - pv(mh, mh_format, "%u"); - pv(mh, mh_incarn, "%u"); -} - -/** - * gfs_sb_in - Read in a superblock - * @sb: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_sb_in(struct gfs_sb *sb, char *buf) -{ - struct gfs_sb *str = (struct gfs_sb *)buf; - - gfs_meta_header_in(&sb->sb_header, buf); - - CPIN_32(sb, str, sb_fs_format); - CPIN_32(sb, str, sb_multihost_format); - CPIN_32(sb, str, sb_flags); - - CPIN_32(sb, str, sb_bsize); - CPIN_32(sb, str, sb_bsize_shift); - CPIN_32(sb, str, sb_seg_size); - - gfs_inum_in(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); - gfs_inum_in(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); - gfs_inum_in(&sb->sb_root_di, (char *)&str->sb_root_di); - - CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); - CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); - - gfs_inum_in(&sb->sb_quota_di, (char *)&str->sb_quota_di); - gfs_inum_in(&sb->sb_license_di, (char *)&str->sb_license_di); - - CPIN_08(sb, str, sb_reserved, 96); -} - -/** - * gfs_sb_out - Write out a superblock - * @sb: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_sb_out(struct gfs_sb *sb, char *buf) -{ - struct gfs_sb *str = (struct gfs_sb *)buf; - - gfs_meta_header_out(&sb->sb_header, buf); - - CPOUT_32(sb, str, sb_fs_format); - CPOUT_32(sb, str, sb_multihost_format); - CPOUT_32(sb, str, sb_flags); - - CPOUT_32(sb, str, sb_bsize); - CPOUT_32(sb, str, sb_bsize_shift); - CPOUT_32(sb, str, sb_seg_size); - - gfs_inum_out(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); - gfs_inum_out(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); - gfs_inum_out(&sb->sb_root_di, (char *)&str->sb_root_di); - - CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); - CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); - - gfs_inum_out(&sb->sb_quota_di, (char *)&str->sb_quota_di); - gfs_inum_out(&sb->sb_license_di, (char *)&str->sb_license_di); - - CPOUT_08(sb, str, sb_reserved, 96); -} - -/** - * gfs_sb_print - Print out a superblock - * @sb: the cpu-order buffer - * - */ - -void -gfs_sb_print(struct gfs_sb *sb) -{ - gfs_meta_header_print(&sb->sb_header); - - pv(sb, sb_fs_format, "%u"); - pv(sb, sb_multihost_format, "%u"); - pv(sb, sb_flags, "%u"); - - pv(sb, sb_bsize, "%u"); - pv(sb, sb_bsize_shift, "%u"); - pv(sb, sb_seg_size, "%u"); - - gfs_inum_print(&sb->sb_jindex_di); - gfs_inum_print(&sb->sb_rindex_di); - gfs_inum_print(&sb->sb_root_di); - - pv(sb, sb_lockproto, "%s"); - pv(sb, sb_locktable, "%s"); - - gfs_inum_print(&sb->sb_quota_di); - gfs_inum_print(&sb->sb_license_di); - - pa(sb, sb_reserved, 96); -} - -/** - * gfs_jindex_in - Read in a journal index structure - * @jindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_jindex_in(struct gfs_jindex *jindex, char *buf) -{ - struct gfs_jindex *str = (struct gfs_jindex *)buf; - - CPIN_64(jindex, str, ji_addr); - CPIN_32(jindex, str, ji_nsegment); - CPIN_32(jindex, str, ji_pad); - - CPIN_08(jindex, str, ji_reserved, 64); -} - -/** - * gfs_jindex_out - Write out a journal index structure - * @jindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_jindex_out(struct gfs_jindex *jindex, char *buf) -{ - struct gfs_jindex *str = (struct gfs_jindex *)buf; - - CPOUT_64(jindex, str, ji_addr); - CPOUT_32(jindex, str, ji_nsegment); - CPOUT_32(jindex, str, ji_pad); - - CPOUT_08(jindex, str, ji_reserved, 64); -} - -/** - * gfs_jindex_print - Print out a journal index structure - * @ji: the cpu-order buffer - * - */ - -void -gfs_jindex_print(struct gfs_jindex *ji) -{ - pv(ji, ji_addr, "%"PRIu64); - pv(ji, ji_nsegment, "%u"); - pv(ji, ji_pad, "%u"); - - pa(ji, ji_reserved, 64); -} - -/** - * gfs_rindex_in - Read in a resource index structure - * @rindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rindex_in(struct gfs_rindex *rindex, char *buf) -{ - struct gfs_rindex *str = (struct gfs_rindex *)buf; - - CPIN_64(rindex, str, ri_addr); - CPIN_32(rindex, str, ri_length); - CPIN_32(rindex, str, ri_pad); - - CPIN_64(rindex, str, ri_data1); - CPIN_32(rindex, str, ri_data); - - CPIN_32(rindex, str, ri_bitbytes); - - CPIN_08(rindex, str, ri_reserved, 64); -} - -/** - * gfs_rindex_out - Write out a resource index structure - * @rindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rindex_out(struct gfs_rindex *rindex, char *buf) -{ - struct gfs_rindex *str = (struct gfs_rindex *)buf; - - CPOUT_64(rindex, str, ri_addr); - CPOUT_32(rindex, str, ri_length); - CPOUT_32(rindex, str, ri_pad); - - CPOUT_64(rindex, str, ri_data1); - CPOUT_32(rindex, str, ri_data); - - CPOUT_32(rindex, str, ri_bitbytes); - - CPOUT_08(rindex, str, ri_reserved, 64); -} - -/** - * gfs_rindex_print - Print out a resource index structure - * @ri: the cpu-order buffer - * - */ - -void -gfs_rindex_print(struct gfs_rindex *ri) -{ - pv(ri, ri_addr, "%"PRIu64); - pv(ri, ri_length, "%u"); - pv(ri, ri_pad, "%u"); - - pv(ri, ri_data1, "%"PRIu64); - pv(ri, ri_data, "%u"); - - pv(ri, ri_bitbytes, "%u"); - - pa(ri, ri_reserved, 64); -} - -/** - * gfs_rgrp_in - Read in a resource group header - * @rgrp: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf) -{ - struct gfs_rgrp *str = (struct gfs_rgrp *)buf; - - gfs_meta_header_in(&rgrp->rg_header, buf); - - CPIN_32(rgrp, str, rg_flags); - - CPIN_32(rgrp, str, rg_free); - - CPIN_32(rgrp, str, rg_useddi); - CPIN_32(rgrp, str, rg_freedi); - gfs_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); - - CPIN_32(rgrp, str, rg_usedmeta); - CPIN_32(rgrp, str, rg_freemeta); - - CPIN_08(rgrp, str, rg_reserved, 64); -} - -/** - * gfs_rgrp_out - Write out a resource group header - * @rgrp: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf) -{ - struct gfs_rgrp *str = (struct gfs_rgrp *)buf; - - gfs_meta_header_out(&rgrp->rg_header, buf); - - CPOUT_32(rgrp, str, rg_flags); - - CPOUT_32(rgrp, str, rg_free); - - CPOUT_32(rgrp, str, rg_useddi); - CPOUT_32(rgrp, str, rg_freedi); - gfs_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); - - CPOUT_32(rgrp, str, rg_usedmeta); - CPOUT_32(rgrp, str, rg_freemeta); - - CPOUT_08(rgrp, str, rg_reserved, 64); -} - -/** - * gfs_rgrp_print - Print out a resource group header - * @rg: the cpu-order buffer - * - */ - -void -gfs_rgrp_print(struct gfs_rgrp *rg) -{ - gfs_meta_header_print(&rg->rg_header); - - pv(rg, rg_flags, "%u"); - - pv(rg, rg_free, "%u"); - - pv(rg, rg_useddi, "%u"); - pv(rg, rg_freedi, "%u"); - gfs_inum_print(&rg->rg_freedi_list); - - pv(rg, rg_usedmeta, "%u"); - pv(rg, rg_freemeta, "%u"); - - pa(rg, rg_reserved, 64); -} - -/** - * gfs_quota_in - Read in a quota structures - * @quota: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_in(struct gfs_quota *quota, char *buf) -{ - struct gfs_quota *str = (struct gfs_quota *)buf; - - CPIN_64(quota, str, qu_limit); - CPIN_64(quota, str, qu_warn); - CPIN_64(quota, str, qu_value); - - CPIN_08(quota, str, qu_reserved, 64); -} - -/** - * gfs_quota_out - Write out a quota structure - * @quota: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_out(struct gfs_quota *quota, char *buf) -{ - struct gfs_quota *str = (struct gfs_quota *)buf; - - CPOUT_64(quota, str, qu_limit); - CPOUT_64(quota, str, qu_warn); - CPOUT_64(quota, str, qu_value); - - CPOUT_08(quota, str, qu_reserved, 64); -} - -/** - * gfs_quota_print - Print out a quota structure - * @quota: the cpu-order buffer - * - */ - -void -gfs_quota_print(struct gfs_quota *quota) -{ - pv(quota, qu_limit, "%"PRIu64); - pv(quota, qu_warn, "%"PRIu64); - pv(quota, qu_value, "%"PRId64); - - pa(quota, qu_reserved, 64); -} - -/** - * gfs_dinode_in - Read in a dinode - * @dinode: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dinode_in(struct gfs_dinode *dinode, char *buf) -{ - struct gfs_dinode *str = (struct gfs_dinode *)buf; - - gfs_meta_header_in(&dinode->di_header, buf); - - gfs_inum_in(&dinode->di_num, (char *)&str->di_num); - - CPIN_32(dinode, str, di_mode); - CPIN_32(dinode, str, di_uid); - CPIN_32(dinode, str, di_gid); - CPIN_32(dinode, str, di_nlink); - CPIN_64(dinode, str, di_size); - CPIN_64(dinode, str, di_blocks); - CPIN_64(dinode, str, di_atime); - CPIN_64(dinode, str, di_mtime); - CPIN_64(dinode, str, di_ctime); - CPIN_32(dinode, str, di_major); - CPIN_32(dinode, str, di_minor); - - CPIN_64(dinode, str, di_rgrp); - CPIN_64(dinode, str, di_goal_rgrp); - CPIN_32(dinode, str, di_goal_dblk); - CPIN_32(dinode, str, di_goal_mblk); - CPIN_32(dinode, str, di_flags); - CPIN_32(dinode, str, di_payload_format); - CPIN_16(dinode, str, di_type); - CPIN_16(dinode, str, di_height); - CPIN_32(dinode, str, di_incarn); - CPIN_16(dinode, str, di_pad); - - CPIN_16(dinode, str, di_depth); - CPIN_32(dinode, str, di_entries); - - gfs_inum_in(&dinode->di_next_unused, (char *)&str->di_next_unused); - - CPIN_64(dinode, str, di_eattr); - - CPIN_08(dinode, str, di_reserved, 56); -} - -/** - * gfs_dinode_out - Write out a dinode - * @dinode: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dinode_out(struct gfs_dinode *dinode, char *buf) -{ - struct gfs_dinode *str = (struct gfs_dinode *)buf; - - gfs_meta_header_out(&dinode->di_header, buf); - - gfs_inum_out(&dinode->di_num, (char *)&str->di_num); - - CPOUT_32(dinode, str, di_mode); - CPOUT_32(dinode, str, di_uid); - CPOUT_32(dinode, str, di_gid); - CPOUT_32(dinode, str, di_nlink); - CPOUT_64(dinode, str, di_size); - CPOUT_64(dinode, str, di_blocks); - CPOUT_64(dinode, str, di_atime); - CPOUT_64(dinode, str, di_mtime); - CPOUT_64(dinode, str, di_ctime); - CPOUT_32(dinode, str, di_major); - CPOUT_32(dinode, str, di_minor); - - CPOUT_64(dinode, str, di_rgrp); - CPOUT_64(dinode, str, di_goal_rgrp); - CPOUT_32(dinode, str, di_goal_dblk); - CPOUT_32(dinode, str, di_goal_mblk); - CPOUT_32(dinode, str, di_flags); - CPOUT_32(dinode, str, di_payload_format); - CPOUT_16(dinode, str, di_type); - CPOUT_16(dinode, str, di_height); - CPOUT_32(dinode, str, di_incarn); - CPOUT_16(dinode, str, di_pad); - - CPOUT_16(dinode, str, di_depth); - CPOUT_32(dinode, str, di_entries); - - gfs_inum_out(&dinode->di_next_unused, (char *)&str->di_next_unused); - - CPOUT_64(dinode, str, di_eattr); - - CPOUT_08(dinode, str, di_reserved, 56); -} - -/** - * gfs_dinode_print - Print out a dinode - * @di: the cpu-order buffer - * - */ - -void -gfs_dinode_print(struct gfs_dinode *di) -{ - gfs_meta_header_print(&di->di_header); - - gfs_inum_print(&di->di_num); - - pv(di, di_mode, "0%o"); - pv(di, di_uid, "%u"); - pv(di, di_gid, "%u"); - pv(di, di_nlink, "%u"); - pv(di, di_size, "%"PRIu64); - pv(di, di_blocks, "%"PRIu64); - pv(di, di_atime, "%"PRId64); - pv(di, di_mtime, "%"PRId64); - pv(di, di_ctime, "%"PRId64); - pv(di, di_major, "%u"); - pv(di, di_minor, "%u"); - - pv(di, di_rgrp, "%"PRIu64); - pv(di, di_goal_rgrp, "%"PRIu64); - pv(di, di_goal_dblk, "%u"); - pv(di, di_goal_mblk, "%u"); - pv(di, di_flags, "0x%.8X"); - pv(di, di_payload_format, "%u"); - pv(di, di_type, "%u"); - pv(di, di_height, "%u"); - pv(di, di_incarn, "%u"); - pv(di, di_pad, "%u"); - - pv(di, di_depth, "%u"); - pv(di, di_entries, "%u"); - - gfs_inum_print(&di->di_next_unused); - - pv(di, di_eattr, "%"PRIu64); - - pa(di, di_reserved, 56); -} - -/** - * gfs_indirect_in - copy in the header of an indirect block - * @indirect: the in memory copy - * @buf: the buffer copy - * - */ - -void -gfs_indirect_in(struct gfs_indirect *indirect, char *buf) -{ - struct gfs_indirect *str = (struct gfs_indirect *)buf; - - gfs_meta_header_in(&indirect->in_header, buf); - - CPIN_08(indirect, str, in_reserved, 64); -} - -/** - * gfs_indirect_out - copy out the header of an indirect block - * @indirect: the in memory copy - * @buf: the buffer copy - * - */ - -void -gfs_indirect_out(struct gfs_indirect *indirect, char *buf) -{ - struct gfs_indirect *str = (struct gfs_indirect *)buf; - - gfs_meta_header_out(&indirect->in_header, buf); - - CPOUT_08(indirect, str, in_reserved, 64); -} - -/** - * gfs_indirect_print - Print out a indirect block header - * @indirect: the cpu-order buffer - * - */ - -void -gfs_indirect_print(struct gfs_indirect *indirect) -{ - gfs_meta_header_print(&indirect->in_header); - - pa(indirect, in_reserved, 64); -} - -/** - * gfs_dirent_in - Read in a directory entry - * @dirent: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dirent_in(struct gfs_dirent *dirent, char *buf) -{ - struct gfs_dirent *str = (struct gfs_dirent *)buf; - - gfs_inum_in(&dirent->de_inum, (char *)&str->de_inum); - CPIN_32(dirent, str, de_hash); - CPIN_16(dirent, str, de_rec_len); - CPIN_16(dirent, str, de_name_len); - CPIN_16(dirent, str, de_type); - - CPIN_08(dirent, str, de_reserved, 14); -} - -/** - * gfs_dirent_out - Write out a directory entry - * @dirent: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dirent_out(struct gfs_dirent *dirent, char *buf) -{ - struct gfs_dirent *str = (struct gfs_dirent *)buf; - - gfs_inum_out(&dirent->de_inum, (char *)&str->de_inum); - CPOUT_32(dirent, str, de_hash); - CPOUT_16(dirent, str, de_rec_len); - CPOUT_16(dirent, str, de_name_len); - CPOUT_16(dirent, str, de_type); - - CPOUT_08(dirent, str, de_reserved, 14); -} - -/** - * gfs_dirent_print - Print out a directory entry - * @de: the cpu-order buffer - * @name: the filename - * - */ - -void -gfs_dirent_print(struct gfs_dirent *de, char *name) -{ - char buf[GFS_FNAMESIZE + 1]; - - gfs_inum_print(&de->de_inum); - pv(de, de_hash, "0x%.8X"); - pv(de, de_rec_len, "%u"); - pv(de, de_name_len, "%u"); - pv(de, de_type, "%u"); - - pa(de, de_reserved, 14); - - memset(buf, 0, GFS_FNAMESIZE + 1); - memcpy(buf, name, de->de_name_len); - printk(" name = %s\n", buf); -} - -/** - * gfs_leaf_in - Read in a directory leaf header - * @leaf: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_leaf_in(struct gfs_leaf *leaf, char *buf) -{ - struct gfs_leaf *str = (struct gfs_leaf *)buf; - - gfs_meta_header_in(&leaf->lf_header, buf); - - CPIN_16(leaf, str, lf_depth); - CPIN_16(leaf, str, lf_entries); - CPIN_32(leaf, str, lf_dirent_format); - CPIN_64(leaf, str, lf_next); - - CPIN_08(leaf, str, lf_reserved, 64); -} - -/** - * gfs_leaf_out - Write out a directory leaf header - * @leaf: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_leaf_out(struct gfs_leaf *leaf, char *buf) -{ - struct gfs_leaf *str = (struct gfs_leaf *)buf; - - gfs_meta_header_out(&leaf->lf_header, buf); - - CPOUT_16(leaf, str, lf_depth); - CPOUT_16(leaf, str, lf_entries); - CPOUT_32(leaf, str, lf_dirent_format); - CPOUT_64(leaf, str, lf_next); - - CPOUT_08(leaf, str, lf_reserved, 64); -} - -/** - * gfs_leaf_print - Print out a directory leaf header - * @lf: the cpu-order buffer - * - */ - -void -gfs_leaf_print(struct gfs_leaf *lf) -{ - gfs_meta_header_print(&lf->lf_header); - - pv(lf, lf_depth, "%u"); - pv(lf, lf_entries, "%u"); - pv(lf, lf_dirent_format, "%u"); - pv(lf, lf_next, "%"PRIu64); - - pa(lf, lf_reserved, 64); -} - -/** - * gfs_log_header_in - Read in a log header - * @head: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_log_header_in(struct gfs_log_header *head, char *buf) -{ - struct gfs_log_header *str = (struct gfs_log_header *)buf; - - gfs_meta_header_in(&head->lh_header, buf); - - CPIN_32(head, str, lh_flags); - CPIN_32(head, str, lh_pad); - - CPIN_64(head, str, lh_first); - CPIN_64(head, str, lh_sequence); - - CPIN_64(head, str, lh_tail); - CPIN_64(head, str, lh_last_dump); - - CPIN_08(head, str, lh_reserved, 64); -} - -/** - * gfs_log_header_out - Write out a log header - * @head: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_log_header_out(struct gfs_log_header *head, char *buf) -{ - struct gfs_log_header *str = (struct gfs_log_header *)buf; - - gfs_meta_header_out(&head->lh_header, buf); - - CPOUT_32(head, str, lh_flags); - CPOUT_32(head, str, lh_pad); - - CPOUT_64(head, str, lh_first); - CPOUT_64(head, str, lh_sequence); - - CPOUT_64(head, str, lh_tail); - CPOUT_64(head, str, lh_last_dump); - - CPOUT_08(head, str, lh_reserved, 64); -} - -/** - * gfs_log_header_print - Print out a log header - * @head: the cpu-order buffer - * - */ - -void -gfs_log_header_print(struct gfs_log_header *lh) -{ - gfs_meta_header_print(&lh->lh_header); - - pv(lh, lh_flags, "0x%.8X"); - pv(lh, lh_pad, "%u"); - - pv(lh, lh_first, "%"PRIu64); - pv(lh, lh_sequence, "%"PRIu64); - - pv(lh, lh_tail, "%"PRIu64); - pv(lh, lh_last_dump, "%"PRIu64); - - pa(lh, lh_reserved, 64); -} - -/** - * gfs_desc_in - Read in a log descriptor - * @desc: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_desc_in(struct gfs_log_descriptor *desc, char *buf) -{ - struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; - - gfs_meta_header_in(&desc->ld_header, buf); - - CPIN_32(desc, str, ld_type); - CPIN_32(desc, str, ld_length); - CPIN_32(desc, str, ld_data1); - CPIN_32(desc, str, ld_data2); - - CPIN_08(desc, str, ld_reserved, 64); -} - -/** - * gfs_desc_out - Write out a log descriptor - * @desc: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_desc_out(struct gfs_log_descriptor *desc, char *buf) -{ - struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; - - gfs_meta_header_out(&desc->ld_header, buf); - - CPOUT_32(desc, str, ld_type); - CPOUT_32(desc, str, ld_length); - CPOUT_32(desc, str, ld_data1); - CPOUT_32(desc, str, ld_data2); - - CPOUT_08(desc, str, ld_reserved, 64); -} - -/** - * gfs_desc_print - Print out a log descriptor - * @ld: the cpu-order buffer - * - */ - -void -gfs_desc_print(struct gfs_log_descriptor *ld) -{ - gfs_meta_header_print(&ld->ld_header); - - pv(ld, ld_type, "%u"); - pv(ld, ld_length, "%u"); - pv(ld, ld_data1, "%u"); - pv(ld, ld_data2, "%u"); - - pa(ld, ld_reserved, 64); -} - -/** - * gfs_block_tag_in - Read in a block tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_block_tag_in(struct gfs_block_tag *tag, char *buf) -{ - struct gfs_block_tag *str = (struct gfs_block_tag *)buf; - - CPIN_64(tag, str, bt_blkno); - CPIN_32(tag, str, bt_flags); - CPIN_32(tag, str, bt_pad); -} - -/** - * gfs_block_tag_out - Write out a block tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_block_tag_out(struct gfs_block_tag *tag, char *buf) -{ - struct gfs_block_tag *str = (struct gfs_block_tag *)buf; - - CPOUT_64(tag, str, bt_blkno); - CPOUT_32(tag, str, bt_flags); - CPOUT_32(tag, str, bt_pad); -} - -/** - * gfs_block_tag_print - Print out a block tag - * @tag: the cpu-order buffer - * - */ - -void -gfs_block_tag_print(struct gfs_block_tag *tag) -{ - pv(tag, bt_blkno, "%"PRIu64); - pv(tag, bt_flags, "%u"); - pv(tag, bt_pad, "%u"); -} - -/** - * gfs_quota_tag_in - Read in a quota tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf) -{ - struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; - - CPIN_64(tag, str, qt_change); - CPIN_32(tag, str, qt_flags); - CPIN_32(tag, str, qt_id); -} - -/** - * gfs_quota_tag_out - Write out a quota tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf) -{ - struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; - - CPOUT_64(tag, str, qt_change); - CPOUT_32(tag, str, qt_flags); - CPOUT_32(tag, str, qt_id); -} - -/** - * gfs_quota_tag_print - Print out a quota tag - * @tag: the cpu-order buffer - * - */ - -void -gfs_quota_tag_print(struct gfs_quota_tag *tag) -{ - pv(tag, qt_change, "%"PRId64); - pv(tag, qt_flags, "0x%.8X"); - pv(tag, qt_id, "%u"); -} - -/** - * gfs_ea_header_in - Read in a Extended Attribute header - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_ea_header_in(struct gfs_ea_header *ea, char *buf) -{ - struct gfs_ea_header *str = (struct gfs_ea_header *)buf; - - CPIN_32(ea, str, ea_rec_len); - CPIN_32(ea, str, ea_data_len); - ea->ea_name_len = str->ea_name_len; - ea->ea_type = str->ea_type; - ea->ea_flags = str->ea_flags; - ea->ea_num_ptrs = str->ea_num_ptrs; - CPIN_32(ea, str, ea_pad); -} - -/** - * gfs_ea_header_out - Write out a Extended Attribute header - * @ea: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_ea_header_out(struct gfs_ea_header *ea, char *buf) -{ - struct gfs_ea_header *str = (struct gfs_ea_header *)buf; - - CPOUT_32(ea, str, ea_rec_len); - CPOUT_32(ea, str, ea_data_len); - str->ea_name_len = ea->ea_name_len; - str->ea_type = ea->ea_type; - str->ea_flags = ea->ea_flags; - str->ea_num_ptrs = ea->ea_num_ptrs; - CPOUT_32(ea, str, ea_pad); -} - -/** - * gfs_ea_header_printt - Print out a Extended Attribute header - * @ea: the cpu-order buffer - * - */ - -void -gfs_ea_header_print(struct gfs_ea_header *ea, char *name) -{ - char buf[GFS_EA_MAX_NAME_LEN + 1]; - - pv(ea, ea_rec_len, "%u"); - pv(ea, ea_data_len, "%u"); - pv(ea, ea_name_len, "%u"); - pv(ea, ea_type, "%u"); - pv(ea, ea_flags, "%u"); - pv(ea, ea_num_ptrs, "%u"); - pv(ea, ea_pad, "%u"); - - memset(buf, 0, GFS_EA_MAX_NAME_LEN + 1); - memcpy(buf, name, ea->ea_name_len); - printk(" name = %s\n", buf); -} - -static const uint32_t crc_32_tab[] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -/** - * gfs_dir_hash - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * Take some data and convert it to a 32-bit hash. - * - * The hash function is a 32-bit CRC of the data. The algorithm uses - * the crc_32_tab table above. - * - * This may not be the fastest hash function, but it does a fair bit better - * at providing uniform results than the others I've looked at. That's - * really important for efficient directories. - * - * Returns: the hash - */ - -uint32_t -gfs_dir_hash(const char *data, int len) -{ - uint32_t hash = 0xFFFFFFFF; - - for (; len--; data++) - hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); - - hash = ~hash; - - return hash; -} - -#endif /* WANT_GFS_CONVERSION_FUNCTIONS */ - diff --git a/gfs-kernel/src/gfs/glock.c b/gfs-kernel/src/gfs/glock.c deleted file mode 100644 index 11c5edc..0000000 --- a/gfs-kernel/src/gfs/glock.c +++ /dev/null @@ -1,3002 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "lm.h" -#include "lops.h" -#include "quota.h" -#include "recovery.h" - -/* Must be kept in sync with the beginning of struct gfs_glock */ -struct glock_plug { - struct list_head gl_list; - unsigned long gl_flags; -}; - -struct greedy { - struct gfs_holder gr_gh; - struct work_struct gr_work; -}; - -typedef void (*glock_examiner) (struct gfs_glock * gl, unsigned int *p_cnt); - -/** - * relaxed_state_ok - is a requested lock compatible with the current lock mode? - * @actual: the current state of the lock - * @requested: the lock state that was requested by the caller - * @flags: the modifier flags passed in by the caller - * - * Returns: TRUE if the locks are compatible, FALSE otherwise - * - * It's often possible that a holder B may request the lock in SHARED mode, - * while another holder A (on this same node) has the lock in EXCLUSIVE mode - * (node must hold the glock in EXCLUSIVE mode for this situation, of course). - * This is okay to grant, in some cases, since both holders would have access - * to the in-core up-to-date cached data that the EX holder would write to disk. - * This is the default behavior. - * - * The EXACT flag disallows this behavior, though. A SHARED request would - * compatible only with a SHARED lock with this flag. - * - * The ANY flag provides broader permission to grant the lock to a holder, - * whatever the requested state is, as long as the lock is locked in any mode. - */ - -static __inline__ int -relaxed_state_ok(unsigned int actual, unsigned requested, int flags) -{ - if (actual == requested) - return TRUE; - - if (flags & GL_EXACT) - return FALSE; - - if (actual == LM_ST_EXCLUSIVE && requested == LM_ST_SHARED) - return TRUE; - - if (actual != LM_ST_UNLOCKED && (flags & LM_FLAG_ANY)) - return TRUE; - - return FALSE; -} - -/** - * gl_hash() - Turn glock number into hash bucket number - * @lock: The glock number - * - * Returns: The number of the corresponding hash bucket - */ - -static unsigned int -gl_hash(struct lm_lockname *name) -{ - unsigned int h; - - h = gfs_hash(&name->ln_number, sizeof(uint64_t)); - h = gfs_hash_more(&name->ln_type, sizeof(unsigned int), h); - h &= GFS_GL_HASH_MASK; - - return h; -} - -/** - * glock_hold() - increment reference count on glock - * @gl: The glock to hold - * - */ - -static __inline__ void -glock_hold(struct gfs_glock *gl) -{ - gfs_assert(gl->gl_sbd, atomic_read(&gl->gl_count) > 0,); - atomic_inc(&gl->gl_count); -} - -/** - * glock_put() - Decrement reference count on glock - * @gl: The glock to put - * - */ - -static __inline__ void -glock_put(struct gfs_glock *gl) -{ - if (atomic_read(&gl->gl_count) == 1) - gfs_glock_schedule_for_reclaim(gl); - gfs_assert(gl->gl_sbd, atomic_read(&gl->gl_count) > 0,); - atomic_dec(&gl->gl_count); -} - -/** - * queue_empty - check to see if a glock's queue is empty - * @gl: the glock - * @head: the head of the queue to check - * - * Returns: TRUE if the queue is empty - */ - -static __inline__ int -queue_empty(struct gfs_glock *gl, struct list_head *head) -{ - int empty; - spin_lock(&gl->gl_spin); - empty = list_empty(head); - spin_unlock(&gl->gl_spin); - return empty; -} - -/** - * search_bucket() - Find struct gfs_glock by lock number - * @bucket: the bucket to search - * @name: The lock name - * - * Returns: NULL, or the struct gfs_glock with the requested number - */ - -static struct gfs_glock * -search_bucket(struct gfs_gl_hash_bucket *bucket, struct lm_lockname *name) -{ - struct list_head *tmp, *head; - struct gfs_glock *gl; - - for (head = &bucket->hb_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gl = list_entry(tmp, struct gfs_glock, gl_list); - - if (test_bit(GLF_PLUG, &gl->gl_flags)) - continue; - if (!lm_name_equal(&gl->gl_name, name)) - continue; - - atomic_inc(&gl->gl_count); - - return gl; - } - - return NULL; -} - -/** - * gfs_glock_find() - Find glock by lock number - * @sdp: The GFS superblock - * @name: The lock name - * - * Figure out what bucket the lock is in, acquire the read lock on - * it and call search_bucket(). - * - * Returns: NULL, or the struct gfs_glock with the requested number - */ - -struct gfs_glock * -gfs_glock_find(struct gfs_sbd *sdp, struct lm_lockname *name) -{ - struct gfs_gl_hash_bucket *bucket = &sdp->sd_gl_hash[gl_hash(name)]; - struct gfs_glock *gl; - - read_lock(&bucket->hb_lock); - gl = search_bucket(bucket, name); - read_unlock(&bucket->hb_lock); - - return gl; -} - -/** - * glock_free() - Perform a few checks and then release struct gfs_glock - * @gl: The glock to release - * - * Also calls lock module to release its internal structure for this glock. - * - */ - -static void -glock_free(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct inode *aspace = gl->gl_aspace; - - gfs_assert_warn(sdp, list_empty(&gl->gl_list)); - gfs_assert_warn(sdp, atomic_read(&gl->gl_count) == 1); - gfs_assert_warn(sdp, list_empty(&gl->gl_holders)); - gfs_assert_warn(sdp, list_empty(&gl->gl_waiters1)); - gfs_assert_warn(sdp, list_empty(&gl->gl_waiters2)); - gfs_assert_warn(sdp, list_empty(&gl->gl_waiters3)); - gfs_assert_warn(sdp, gl->gl_state == LM_ST_UNLOCKED); - gfs_assert_warn(sdp, !gl->gl_object); - gfs_assert_warn(sdp, !gl->gl_lvb); - gfs_assert_warn(sdp, list_empty(&gl->gl_reclaim)); - - gfs_lm_put_lock(sdp, gl->gl_lock); - - if (aspace) - gfs_aspace_put(aspace); - - kmem_cache_free(gfs_glock_cachep, gl); - - atomic_dec(&sdp->sd_glock_count); -} - -/** - * gfs_glock_get() - Get a glock, or create one if one doesn't exist - * @sdp: The GFS superblock - * @number: the lock number - * @glops: The glock_operations to use - * @create: If FALSE, don't create the glock if it doesn't exist - * @glp: the glock is returned here - * - * This does not lock a glock, just finds/creates structures for one. - * - * Returns: errno - */ - -int -gfs_glock_get(struct gfs_sbd *sdp, - uint64_t number, struct gfs_glock_operations *glops, - int create, struct gfs_glock **glp) -{ - struct lm_lockname name; - struct gfs_glock *gl, *tmp; - struct gfs_gl_hash_bucket *bucket; - int error; - - /* Look for pre-existing glock in hash table */ - name.ln_number = number; - name.ln_type = glops->go_type; - bucket = &sdp->sd_gl_hash[gl_hash(&name)]; - - read_lock(&bucket->hb_lock); - gl = search_bucket(bucket, &name); - read_unlock(&bucket->hb_lock); - - if (gl || !create) { - *glp = gl; - return 0; - } - - /* None found; create a new one */ - gl = kmem_cache_alloc(gfs_glock_cachep, GFP_KERNEL); - if (!gl) - return -ENOMEM; - - memset(gl, 0, sizeof(struct gfs_glock)); - - INIT_LIST_HEAD(&gl->gl_list); - gl->gl_name = name; - atomic_set(&gl->gl_count, 1); - - spin_lock_init(&gl->gl_spin); - - gl->gl_state = LM_ST_UNLOCKED; - INIT_LIST_HEAD(&gl->gl_holders); - INIT_LIST_HEAD(&gl->gl_waiters1); - INIT_LIST_HEAD(&gl->gl_waiters2); - INIT_LIST_HEAD(&gl->gl_waiters3); - - gl->gl_ops = glops; - - INIT_LE(&gl->gl_new_le, &gfs_glock_lops); - INIT_LE(&gl->gl_incore_le, &gfs_glock_lops); - - gl->gl_bucket = bucket; - INIT_LIST_HEAD(&gl->gl_reclaim); - - gl->gl_sbd = sdp; - - INIT_LIST_HEAD(&gl->gl_ail_bufs); - - /* If this glock protects actual on-disk data or metadata blocks, - create a VFS inode to manage the pages/buffers holding them. */ - if (glops == &gfs_inode_glops || - glops == &gfs_rgrp_glops || - glops == &gfs_meta_glops) { - gl->gl_aspace = gfs_aspace_get(sdp); - if (!gl->gl_aspace) { - error = -ENOMEM; - goto fail; - } - } - - /* Ask lock module to find/create its structure for this lock - (but this doesn't lock the inter-node lock yet) */ - error = gfs_lm_get_lock(sdp, &name, &gl->gl_lock); - if (error) - goto fail_aspace; - - atomic_inc(&sdp->sd_glock_count); - - /* Double-check, in case another process created the glock, and has - put it in the hash table while we were preparing this one */ - write_lock(&bucket->hb_lock); - tmp = search_bucket(bucket, &name); - if (tmp) { - /* Somebody beat us to it; forget the one we prepared */ - write_unlock(&bucket->hb_lock); - glock_free(gl); - gl = tmp; - } else { - /* Add our glock to hash table */ - list_add_tail(&gl->gl_list, &bucket->hb_list); - write_unlock(&bucket->hb_lock); - } - - *glp = gl; - - return 0; - - fail_aspace: - if (gl->gl_aspace) - gfs_aspace_put(gl->gl_aspace); - - fail: - kmem_cache_free(gfs_glock_cachep, gl); - - return error; -} - -/** - * gfs_glock_hold() - As glock_hold(), but suitable for exporting - * @gl: The glock to hold - * - */ - -void -gfs_glock_hold(struct gfs_glock *gl) -{ - glock_hold(gl); -} - -/** - * gfs_glock_put() - As glock_put(), but suitable for exporting - * @gl: The glock to put - * - */ - -void -gfs_glock_put(struct gfs_glock *gl) -{ - glock_put(gl); -} - -/** - * gfs_holder_init - initialize a struct gfs_holder in the default way - * @gl: the glock - * @state: the state we're requesting - * @flags: the modifier flags - * @gh: the holder structure - * - */ - -void -gfs_holder_init(struct gfs_glock *gl, unsigned int state, int flags, - struct gfs_holder *gh) -{ - memset(gh, 0, sizeof(struct gfs_holder)); - - INIT_LIST_HEAD(&gh->gh_list); - gh->gh_gl = gl; - gh->gh_owner = current; - gh->gh_state = state; - gh->gh_flags = flags; - - if (gh->gh_state == LM_ST_EXCLUSIVE) - gh->gh_flags |= GL_LOCAL_EXCL; - - init_completion(&gh->gh_wait); - - glock_hold(gl); -} - -/** - * gfs_holder_reinit - reinitialize a struct gfs_holder so we can requeue it - * @state: the state we're requesting - * @flags: the modifier flags - * @gh: the holder structure - * - * Preserve holder's associated glock and owning process. - * Reset all holder state flags (we're starting a new request from scratch), - * except for HIF_ALLOCED. - * Don't do glock_hold() again (it was done in gfs_holder_init()). - * Don't mess with the glock. - * - * Rules: - * Holder must have been gfs_holder_init()d already - * Holder must *not* be in glock's holder list or wait queues now - */ - -void -gfs_holder_reinit(unsigned int state, int flags, struct gfs_holder *gh) -{ - int alloced; - - gfs_assert_warn(gh->gh_gl->gl_sbd, - list_empty(&gh->gh_list)); - - gh->gh_state = state; - gh->gh_flags = flags; - - if (gh->gh_state == LM_ST_EXCLUSIVE) - gh->gh_flags |= GL_LOCAL_EXCL; - - alloced = test_bit(HIF_ALLOCED, &gh->gh_iflags); - memset(&gh->gh_iflags, 0, sizeof(unsigned long)); - if (alloced) - set_bit(HIF_ALLOCED, &gh->gh_iflags); -} - -/** - * gfs_holder_uninit - uninitialize a holder structure (drop reference on glock) - * @gh: the holder structure - * - */ - -void -gfs_holder_uninit(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - - gfs_assert_warn(gl->gl_sbd, list_empty(&gh->gh_list)); - gh->gh_gl = NULL; - - glock_put(gl); -} - -/** - * gfs_holder_get - get a struct gfs_holder structure - * @gl: the glock - * @state: the state we're requesting - * @flags: the modifier flags - * - * Figure out how big an impact this function has. Either: - * 1) Replace it with a cache of structures hanging off the struct gfs_sbd - * 2) Leave it like it is - * - * Returns: the holder structure, NULL on ENOMEM - */ - -struct gfs_holder * -gfs_holder_get(struct gfs_glock *gl, unsigned int state, int flags) -{ - struct gfs_holder *gh; - - gh = kmalloc(sizeof(struct gfs_holder), GFP_KERNEL); - if (!gh) - return NULL; - - gfs_holder_init(gl, state, flags, gh); - set_bit(HIF_ALLOCED, &gh->gh_iflags); - - return gh; -} - -/** - * gfs_holder_put - get rid of a struct gfs_holder structure - * @gh: the holder structure - * - */ - -void -gfs_holder_put(struct gfs_holder *gh) -{ - if (gfs_assert_warn(gh->gh_gl->gl_sbd, - test_bit(HIF_ALLOCED, &gh->gh_iflags))) - return; - gfs_holder_uninit(gh); - kfree(gh); -} - -/** - * handle_recurse - put other holder structures (marked recursive) into the holders list - * @gh: the holder structure - * - */ - -static void -handle_recurse(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct list_head *tmp, *head, *next; - struct gfs_holder *tmp_gh; - int found = FALSE; - - if (gfs_assert_warn(sdp, gh->gh_owner)) - return; - - for (head = &gl->gl_waiters3, tmp = head->next, next = tmp->next; - tmp != head; - tmp = next, next = tmp->next) { - tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); - if (tmp_gh->gh_owner != gh->gh_owner) - continue; - - gfs_assert_warn(sdp, test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); - - list_move_tail(&tmp_gh->gh_list, &gl->gl_holders); - tmp_gh->gh_error = 0; - set_bit(HIF_HOLDER, &tmp_gh->gh_iflags); - - complete(&tmp_gh->gh_wait); - - found = TRUE; - } - - gfs_assert_warn(sdp, found); -} - -/** - * do_unrecurse - a recursive holder was just dropped of the waiters3 list - * @gh: the holder - * - * If there is only one other recursive holder, clear its HIF_RECURSE bit - * (it's no longer a recursive request). - * If there is more than one, leave them alone (they're recursive!). - * - */ - -static void -do_unrecurse(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct list_head *tmp, *head; - struct gfs_holder *tmp_gh, *last_gh = NULL; - int found = FALSE; - - if (gfs_assert_warn(sdp, gh->gh_owner)) - return; - - for (head = &gl->gl_waiters3, tmp = head->next; - tmp != head; - tmp = tmp->next) { - tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); - if (tmp_gh->gh_owner != gh->gh_owner) - continue; - - gfs_assert_warn(sdp, test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); - - /* found more than one */ - if (found) - return; - - found = TRUE; - last_gh = tmp_gh; - } - - /* found just one */ - if (!gfs_assert_warn(sdp, found)) - clear_bit(HIF_RECURSE, &last_gh->gh_iflags); -} - -/** - * rq_mutex - process a mutex request in the queue - * @gh: the glock holder - * - * Returns: TRUE if the queue is blocked (always, since there can be only one - * holder of the mutex). - * - * See lock_on_glock() - */ - -static int -rq_mutex(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - - list_del_init(&gh->gh_list); - /* gh->gh_error never examined. */ - set_bit(GLF_LOCK, &gl->gl_flags); - complete(&gh->gh_wait); - - return TRUE; -} - -/** - * rq_promote - process a promote request in the queue - * @gh: the glock holder - * - * Acquire a new inter-node lock, or change a lock state to more restrictive. - * - * Returns: TRUE if the queue is blocked - */ - -static int -rq_promote(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - int recurse; - - if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { - if (list_empty(&gl->gl_holders)) { - gl->gl_req_gh = gh; - set_bit(GLF_LOCK, &gl->gl_flags); - spin_unlock(&gl->gl_spin); - - /* If we notice a lot of glocks in reclaim list, free - up memory for 2 of them before locking a new one */ - if (atomic_read(&sdp->sd_reclaim_count) > - gfs_tune_get(sdp, gt_reclaim_limit) && - !(gh->gh_flags & LM_FLAG_PRIORITY)) { - gfs_reclaim_glock(sdp); - gfs_reclaim_glock(sdp); - } - - glops->go_xmote_th(gl, gh->gh_state, - gh->gh_flags); - - spin_lock(&gl->gl_spin); - } - return TRUE; - } - - if (list_empty(&gl->gl_holders)) { - set_bit(HIF_FIRST, &gh->gh_iflags); - set_bit(GLF_LOCK, &gl->gl_flags); - recurse = FALSE; - } else { - struct gfs_holder *next_gh; - if (gh->gh_flags & GL_LOCAL_EXCL) - return TRUE; - next_gh = list_entry(gl->gl_holders.next, struct gfs_holder, gh_list); - if (next_gh->gh_flags & GL_LOCAL_EXCL) - return TRUE; - recurse = test_bit(HIF_RECURSE, &gh->gh_iflags); - } - - list_move_tail(&gh->gh_list, &gl->gl_holders); - gh->gh_error = 0; - set_bit(HIF_HOLDER, &gh->gh_iflags); - - if (recurse) - handle_recurse(gh); - - complete(&gh->gh_wait); - - return FALSE; -} - -/** - * rq_demote - process a demote request in the queue - * @gh: the glock holder - * - * Returns: TRUE if the queue is blocked - * - * Unlock an inter-node lock, or change a lock state to less restrictive. - * If the glock is already the same as the holder's requested state, or is - * UNLOCKED, no lock module request is required. - * Otherwise, we need to ask lock module to unlock or change locked state - * of the glock. - * If requested state is UNLOCKED, or current glock state is SHARED or - * DEFERRED (neither of which have a less restrictive state other than - * UNLOCK), we call go_drop_th() to unlock the lock. - * Otherwise (i.e. requested is SHARED or DEFERRED, and current is EXCLUSIVE), - * we can continue to hold the lock, and just ask for a new state; - * we call go_xmote_th() to change state. - * - * Must be called with glock's gl->gl_spin locked. - */ - -static int -rq_demote(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_glock_operations *glops = gl->gl_ops; - - if (!list_empty(&gl->gl_holders)) - return TRUE; - - if (gl->gl_state == gh->gh_state || gl->gl_state == LM_ST_UNLOCKED) { - list_del_init(&gh->gh_list); - gh->gh_error = 0; - spin_unlock(&gl->gl_spin); - if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) - gfs_holder_put(gh); - else - complete(&gh->gh_wait); - spin_lock(&gl->gl_spin); - } else { - gl->gl_req_gh = gh; - set_bit(GLF_LOCK, &gl->gl_flags); - spin_unlock(&gl->gl_spin); - - if (gh->gh_state == LM_ST_UNLOCKED || - gl->gl_state != LM_ST_EXCLUSIVE) - /* Unlock */ - glops->go_drop_th(gl); - else - /* Change state while holding lock */ - glops->go_xmote_th(gl, gh->gh_state, gh->gh_flags); - - spin_lock(&gl->gl_spin); - } - - return FALSE; -} - -/** - * rq_greedy - process a queued request to drop greedy status - * @gh: the glock holder - * - * Returns: TRUE if the queue is blocked - */ - -static int -rq_greedy(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - - list_del_init(&gh->gh_list); - /* gh->gh_error never examined. */ - clear_bit(GLF_GREEDY, &gl->gl_flags); - spin_unlock(&gl->gl_spin); - - gfs_holder_uninit(gh); - kfree(container_of(gh, struct greedy, gr_gh)); - - spin_lock(&gl->gl_spin); - - return FALSE; -} - -/** - * run_queue - process holder structures on the glock's wait queues - * @gl: the glock - * - * Rules: - * Caller must hold gl->gl_spin. - */ - -static void -run_queue(struct gfs_glock *gl) -{ - struct gfs_holder *gh; - int blocked = TRUE; - - for (;;) { - /* Another process is manipulating the glock structure; - we can't do anything now */ - if (test_bit(GLF_LOCK, &gl->gl_flags)) - break; - - /* Waiting to manipulate the glock structure */ - if (!list_empty(&gl->gl_waiters1)) { - gh = list_entry(gl->gl_waiters1.next, - struct gfs_holder, gh_list); - - if (test_bit(HIF_MUTEX, &gh->gh_iflags)) - blocked = rq_mutex(gh); - else - gfs_assert_warn(gl->gl_sbd, FALSE); - - /* Waiting to demote the lock, or drop greedy status */ - } else if (!list_empty(&gl->gl_waiters2) && - !test_bit(GLF_SKIP_WAITERS2, &gl->gl_flags)) { - gh = list_entry(gl->gl_waiters2.next, - struct gfs_holder, gh_list); - - if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) - blocked = rq_demote(gh); - else if (test_bit(HIF_GREEDY, &gh->gh_iflags)) - blocked = rq_greedy(gh); - else - gfs_assert_warn(gl->gl_sbd, FALSE); - - /* Waiting to promote the lock */ - } else if (!list_empty(&gl->gl_waiters3)) { - gh = list_entry(gl->gl_waiters3.next, - struct gfs_holder, gh_list); - - if (test_bit(HIF_PROMOTE, &gh->gh_iflags)) - blocked = rq_promote(gh); - else - gfs_assert_warn(gl->gl_sbd, FALSE); - - } else - break; - - if (blocked) - break; - } -} - -/** - * lock_on_glock - acquire a local lock on a glock (structure) - * @gl: the glock - * - * Gives caller exclusive access to manipulate a glock structure. - * Has nothing to do with inter-node lock state or GL_LOCAL_EXCL! - * - * If structure already locked, places temporary holder structure on glock's - * wait-for-exclusive-access queue, and blocks until exclusive access granted. - */ - -static void -lock_on_glock(struct gfs_glock *gl) -{ - struct gfs_holder gh; - - gfs_holder_init(gl, 0, 0, &gh); - set_bit(HIF_MUTEX, &gh.gh_iflags); - - spin_lock(&gl->gl_spin); - if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) - list_add_tail(&gh.gh_list, &gl->gl_waiters1); - else - complete(&gh.gh_wait); - spin_unlock(&gl->gl_spin); - - wait_for_completion(&gh.gh_wait); - gfs_holder_uninit(&gh); -} - -/** - * trylock_on_glock - try to acquire a local lock on a glock (structure) - * @gl: the glock - * - * Returns: TRUE if the glock is acquired - * - * Tries to give caller exclusive access to manipulate a glock structure. - * Has nothing to do with inter-node lock state or LOCAL_EXCL! - * - * If structure already locked, does not block to wait; returns FALSE. - */ - -static int -trylock_on_glock(struct gfs_glock *gl) -{ - int acquired = TRUE; - - spin_lock(&gl->gl_spin); - if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) - acquired = FALSE; - spin_unlock(&gl->gl_spin); - - return acquired; -} - -/** - * unlock_on_glock - release a local lock on a glock (structure) - * @gl: the glock - * - * Caller is done manipulating glock structure. - * Service any others waiting for exclusive access. - */ - -static void -unlock_on_glock(struct gfs_glock *gl) -{ - spin_lock(&gl->gl_spin); - clear_bit(GLF_LOCK, &gl->gl_flags); - run_queue(gl); - spin_unlock(&gl->gl_spin); -} - -/** - * handle_callback - add a demote request to a lock's queue - * @gl: the glock - * @state: the state the caller wants us to change to - * - * Called when we learn that another node needs a lock held by this node, - * or when this node simply wants to drop a lock as soon as it's done with - * it (NOCACHE flag), or dump a glock out of glock cache (reclaim it). - * - * We are told the @state that will satisfy the needs of the caller, so - * we can ask for a demote to that state. - * - * If another demote request is already on the queue for a different state, just - * set its request to UNLOCK (and don't bother queueing a request for us). - * This consolidates LM requests and moves the lock to the least restrictive - * state, so it will be compatible with whatever reason we were called. - * No need to be too smart here. Demotes between the shared and deferred - * states will often fail, so don't even try. - * - * Otherwise, queue a demote request to the requested state. - */ - -static void -handle_callback(struct gfs_glock *gl, unsigned int state) -{ - struct list_head *tmp, *head; - struct gfs_holder *gh, *new_gh = NULL; - - if (gfs_assert_warn(gl->gl_sbd, state != LM_ST_EXCLUSIVE)) - return; - - restart: - spin_lock(&gl->gl_spin); - - /* If another queued demote request is for a different state, - set its request to UNLOCKED */ - for (head = &gl->gl_waiters2, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gh = list_entry(tmp, struct gfs_holder, gh_list); - if (test_bit(HIF_DEMOTE, &gh->gh_iflags) && - gl->gl_req_gh != gh) { - if (gh->gh_state != state) - gh->gh_state = LM_ST_UNLOCKED; - goto out; - } - } - - /* pass 2; add new holder to glock's demote request queue */ - if (new_gh) { - list_add_tail(&new_gh->gh_list, &gl->gl_waiters2); - new_gh = NULL; - - /* pass 1; set up a new holder struct for a demote request, then - check again to see if another process added a demote request - while we were preparing this one. */ - } else { - spin_unlock(&gl->gl_spin); - - RETRY_MALLOC(new_gh = gfs_holder_get(gl, state, LM_FLAG_TRY), - new_gh); - set_bit(HIF_DEMOTE, &new_gh->gh_iflags); - set_bit(HIF_DEALLOC, &new_gh->gh_iflags); - new_gh->gh_owner = NULL; - - goto restart; - } - - out: - spin_unlock(&gl->gl_spin); - - if (new_gh) - gfs_holder_put(new_gh); -} - -/** - * state_change - record that the glock is now in a different state - * @gl: the glock - * @new_state the new state - * - */ - -static void -state_change(struct gfs_glock *gl, unsigned int new_state) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - int held1, held2; - - held1 = (gl->gl_state != LM_ST_UNLOCKED); - held2 = (new_state != LM_ST_UNLOCKED); - - if (held1 != held2) { - if (held2) { - atomic_inc(&sdp->sd_glock_held_count); - glock_hold(gl); - } else { - atomic_dec(&sdp->sd_glock_held_count); - glock_put(gl); - } - } - - gl->gl_state = new_state; -} - -/** - * xmote_bh - Called after the lock module is done acquiring a lock - * @gl: The glock in question - * @ret: the int returned from the lock module - * - */ - -static void -xmote_bh(struct gfs_glock *gl, unsigned int ret) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - struct gfs_holder *gh = gl->gl_req_gh; - int prev_state = gl->gl_state; - int op_done = TRUE; - - gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); - gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); - gfs_assert_warn(sdp, !(ret & LM_OUT_ASYNC)); - - state_change(gl, ret & LM_OUT_ST_MASK); - - if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { - if (glops->go_inval) - glops->go_inval(gl, DIO_METADATA | DIO_DATA); - } else if (gl->gl_state == LM_ST_DEFERRED) { - /* We might not want to do this here. - Look at moving to the inode glops. */ - if (glops->go_inval) - glops->go_inval(gl, DIO_DATA); - } - - /* Deal with each possible exit condition */ - - if (!gh) - gl->gl_stamp = jiffies; - - else if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - gh->gh_error = -EIO; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); - spin_unlock(&gl->gl_spin); - - } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) { - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - if (gl->gl_state == gh->gh_state || - gl->gl_state == LM_ST_UNLOCKED) - gh->gh_error = 0; - else { - if (gfs_assert_warn(sdp, gh->gh_flags & - (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) == -1) - printk("GFS: fsid=%s: ret = 0x%.8X\n", - sdp->sd_fsname, ret); - gh->gh_error = GLR_TRYFAILED; - } - spin_unlock(&gl->gl_spin); - - if (ret & LM_OUT_CANCELED) - handle_callback(gl, LM_ST_UNLOCKED); /* Lame */ - - } else if (ret & LM_OUT_CANCELED) { - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - gh->gh_error = GLR_CANCELED; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); - spin_unlock(&gl->gl_spin); - - } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { - spin_lock(&gl->gl_spin); - list_move_tail(&gh->gh_list, &gl->gl_holders); - gh->gh_error = 0; - set_bit(HIF_HOLDER, &gh->gh_iflags); - spin_unlock(&gl->gl_spin); - - set_bit(HIF_FIRST, &gh->gh_iflags); - - op_done = FALSE; - - } else if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - gh->gh_error = GLR_TRYFAILED; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); - spin_unlock(&gl->gl_spin); - - } else { - if (gfs_assert_withdraw(sdp, FALSE) == -1) - printk("GFS: fsid=%s: ret = 0x%.8X\n", - sdp->sd_fsname, ret); - } - - if (glops->go_xmote_bh) - glops->go_xmote_bh(gl); - - if (op_done) { - spin_lock(&gl->gl_spin); - gl->gl_req_gh = NULL; - gl->gl_req_bh = NULL; - clear_bit(GLF_LOCK, &gl->gl_flags); - run_queue(gl); - spin_unlock(&gl->gl_spin); - } - - glock_put(gl); - - if (gh) { - if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) - gfs_holder_put(gh); - else - complete(&gh->gh_wait); - } -} - -/** - * gfs_glock_xmote_th - Call into the lock module to acquire or change a glock - * @gl: The glock in question - * @state: the requested state - * @flags: modifier flags to the lock call - * - * Used to acquire a new glock, or to change an already-acquired glock to - * more/less restrictive state (other than LM_ST_UNLOCKED). - * - * *Not* used to unlock a glock; use gfs_glock_drop_th() for that. - */ - -void -gfs_glock_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB | - LM_FLAG_NOEXP | LM_FLAG_ANY | - LM_FLAG_PRIORITY); - unsigned int lck_ret; - - gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); - gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); - gfs_assert_warn(sdp, state != LM_ST_UNLOCKED); - gfs_assert_warn(sdp, state != gl->gl_state); - - /* Current state EX, may need to sync log/data/metadata to disk */ - if (gl->gl_state == LM_ST_EXCLUSIVE) { - if (glops->go_sync) - glops->go_sync(gl, DIO_METADATA | DIO_DATA); - } - - glock_hold(gl); - gl->gl_req_bh = xmote_bh; - - atomic_inc(&sdp->sd_lm_lock_calls); - - lck_ret = gfs_lm_lock(sdp, gl->gl_lock, - gl->gl_state, state, - lck_flags); - - if (lck_ret & LM_OUT_ASYNC) - gfs_assert_warn(sdp, lck_ret == LM_OUT_ASYNC); - else - xmote_bh(gl, lck_ret); -} - -/** - * drop_bh - Called after a lock module unlock completes - * @gl: the glock - * @ret: the return status - * - * Doesn't wake up the process waiting on the struct gfs_holder (if any) - * Doesn't drop the reference on the glock the top half took out - * - */ - -static void -drop_bh(struct gfs_glock *gl, unsigned int ret) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - struct gfs_holder *gh = gl->gl_req_gh; - - clear_bit(GLF_PREFETCH, &gl->gl_flags); - - gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); - gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); - gfs_assert_warn(sdp, !ret); - - state_change(gl, LM_ST_UNLOCKED); - - if (glops->go_inval) - glops->go_inval(gl, DIO_METADATA | DIO_DATA); - - if (gh) { - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - gh->gh_error = 0; - spin_unlock(&gl->gl_spin); - } - - if (glops->go_drop_bh) - glops->go_drop_bh(gl); - - spin_lock(&gl->gl_spin); - gl->gl_req_gh = NULL; - gl->gl_req_bh = NULL; - clear_bit(GLF_LOCK, &gl->gl_flags); - run_queue(gl); - spin_unlock(&gl->gl_spin); - - glock_put(gl); - - if (gh) { - if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) - gfs_holder_put(gh); - else - complete(&gh->gh_wait); - } -} - -/** - * gfs_glock_drop_th - call into the lock module to unlock a lock - * @gl: the glock - * - */ - -void -gfs_glock_drop_th(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - unsigned int ret; - - gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); - gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); - gfs_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); - - /* Leaving state EX, may need to sync log/data/metadata to disk */ - if (gl->gl_state == LM_ST_EXCLUSIVE) { - if (glops->go_sync) - glops->go_sync(gl, DIO_METADATA | DIO_DATA); - } - - glock_hold(gl); - gl->gl_req_bh = drop_bh; - - atomic_inc(&sdp->sd_lm_unlock_calls); - - ret = gfs_lm_unlock(sdp, gl->gl_lock, gl->gl_state); - - if (!ret) - drop_bh(gl, ret); - else - gfs_assert_warn(sdp, ret == LM_OUT_ASYNC); -} - -/** - * do_cancels - cancel requests for locks stuck waiting on an expire flag - * @gh: the LM_FLAG_PRIORITY holder waiting to acquire the lock - * - * Don't cancel GL_NOCANCEL requests. - */ - -static void -do_cancels(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - - spin_lock(&gl->gl_spin); - - while (gl->gl_req_gh != gh && - !test_bit(HIF_HOLDER, &gh->gh_iflags) && - !list_empty(&gh->gh_list)) { - if (gl->gl_req_bh && - !(gl->gl_req_gh && - (gl->gl_req_gh->gh_flags & GL_NOCANCEL))) { - spin_unlock(&gl->gl_spin); - gfs_lm_cancel(gl->gl_sbd, gl->gl_lock); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 10); - spin_lock(&gl->gl_spin); - } else { - spin_unlock(&gl->gl_spin); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 10); - spin_lock(&gl->gl_spin); - } - } - - spin_unlock(&gl->gl_spin); -} - -/** - * glock_wait_internal - wait on a glock acquisition - * @gh: the glock holder - * - * Returns: 0 on success - */ - -static int -glock_wait_internal(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - int error = 0; - - if (test_bit(HIF_ABORTED, &gh->gh_iflags)) - return -EIO; - - if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { - spin_lock(&gl->gl_spin); - if (gl->gl_req_gh != gh && - !test_bit(HIF_HOLDER, &gh->gh_iflags) && - !list_empty(&gh->gh_list)) { - list_del_init(&gh->gh_list); - gh->gh_error = GLR_TRYFAILED; - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); - run_queue(gl); - spin_unlock(&gl->gl_spin); - return GLR_TRYFAILED; - } - spin_unlock(&gl->gl_spin); - } - - if ((gh->gh_flags & LM_FLAG_PRIORITY) && - !(gh->gh_flags & GL_NOCANCEL_OTHER)) - do_cancels(gh); - - wait_for_completion(&gh->gh_wait); - - if (gh->gh_error) - return gh->gh_error; - - gfs_assert_withdraw(sdp, test_bit(HIF_HOLDER, &gh->gh_iflags)); - gfs_assert_withdraw(sdp, relaxed_state_ok(gl->gl_state, - gh->gh_state, - gh->gh_flags)); - - if (test_bit(HIF_FIRST, &gh->gh_iflags)) { - gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); - - if (glops->go_lock) { - error = glops->go_lock(gl, gh->gh_flags); - if (error) { - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - gh->gh_error = error; - if (test_and_clear_bit(HIF_RECURSE, &gh->gh_iflags)) - do_unrecurse(gh); - spin_unlock(&gl->gl_spin); - } - } - - spin_lock(&gl->gl_spin); - gl->gl_req_gh = NULL; - gl->gl_req_bh = NULL; - clear_bit(GLF_LOCK, &gl->gl_flags); - if (test_bit(HIF_RECURSE, &gh->gh_iflags)) - handle_recurse(gh); - run_queue(gl); - spin_unlock(&gl->gl_spin); - } - - return error; -} - -/** - * add_to_queue - Add a holder to the wait-for-promotion queue or holder list - * (according to recursion) - * @gh: the holder structure to add - * - * If the hold requestor's process already has a granted lock (on holder list), - * and this new request is compatible, go ahead and grant it, adding this - * new holder to the glock's holder list. - * - * If the hold requestor's process has earlier requested a lock, and is still - * waiting for it to be granted, and this new request is compatible with - * the earlier one, they can be handled at the same time when the request - * is finally granted. Mark both (all) with RECURSE flags, and add new - * holder to wait-for-promotion queue. - * - * If there is no previous holder from this process (on holder list or wait- - * for-promotion queue), simply add new holder to wait-for-promotion queue. - */ - -static void -add_to_queue(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct list_head *tmp, *head; - struct gfs_holder *tmp_gh; - - if (gh->gh_owner) { - /* Search through glock's holders list to see if this process - already holds a granted lock. */ - for (head = &gl->gl_holders, tmp = head->next; - tmp != head; - tmp = tmp->next) { - tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); - if (tmp_gh->gh_owner == gh->gh_owner) { - /* Make sure pre-existing holder is compatible - with this new one. */ - if (gfs_assert_warn(sdp, (gh->gh_flags & LM_FLAG_ANY) || - !(tmp_gh->gh_flags & LM_FLAG_ANY)) || - gfs_assert_warn(sdp, (tmp_gh->gh_flags & GL_LOCAL_EXCL) || - !(gh->gh_flags & GL_LOCAL_EXCL)) || - gfs_assert_warn(sdp, relaxed_state_ok(gl->gl_state, - gh->gh_state, - gh->gh_flags))) - goto fail; - - /* We're good! Grant the hold. */ - list_add_tail(&gh->gh_list, &gl->gl_holders); - set_bit(HIF_HOLDER, &gh->gh_iflags); - - gh->gh_error = 0; - complete(&gh->gh_wait); - - return; - } - } - - /* If not, Search through glock's wait-for-promotion list to - see if this process already is waiting for a grant. */ - for (head = &gl->gl_waiters3, tmp = head->next; - tmp != head; - tmp = tmp->next) { - tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); - if (tmp_gh->gh_owner == gh->gh_owner) { - /* Yes, make sure it is compatible with new */ - if (gfs_assert_warn(sdp, test_bit(HIF_PROMOTE, - &tmp_gh->gh_iflags)) || - gfs_assert_warn(sdp, (gh->gh_flags & LM_FLAG_ANY) || - !(tmp_gh->gh_flags & LM_FLAG_ANY)) || - gfs_assert_warn(sdp, (tmp_gh->gh_flags & GL_LOCAL_EXCL) || - !(gh->gh_flags & GL_LOCAL_EXCL)) || - gfs_assert_warn(sdp, relaxed_state_ok(tmp_gh->gh_state, - gh->gh_state, - gh->gh_flags))) - goto fail; - - /* OK, make sure they're marked, so - * when one gets granted, the other will too. */ - set_bit(HIF_RECURSE, &gh->gh_iflags); - set_bit(HIF_RECURSE, &tmp_gh->gh_iflags); - - list_add_tail(&gh->gh_list, &gl->gl_waiters3); - - return; - } - } - } - - /* Else, no recursion ... - If high priority request, add to head of promote queue, else tail */ - if (gh->gh_flags & LM_FLAG_PRIORITY) - list_add(&gh->gh_list, &gl->gl_waiters3); - else - list_add_tail(&gh->gh_list, &gl->gl_waiters3); - - return; - - fail: - set_bit(HIF_ABORTED, &gh->gh_iflags); -} - -/** - * gfs_glock_nq - enqueue a struct gfs_holder onto a glock (acquire a glock) - * @gh: the holder structure - * - * if (gh->gh_flags & GL_ASYNC), this never returns an error - * - * Returns: 0, GLR_TRYFAILED, or errno on failure - * - * Rules: - * @gh must not be already attached to a glock. - * Don't ask for UNLOCKED state (use gfs_glock_dq() for that). - * LM_FLAG_ANY (liberal) and GL_EXACT (restrictive) are mutually exclusive. - */ - -int -gfs_glock_nq(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - int error = 0; - - atomic_inc(&sdp->sd_glock_nq_calls); - - restart: - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) || - gfs_assert_warn(sdp, list_empty(&gh->gh_list)) || - gfs_assert_warn(sdp, gh->gh_state != LM_ST_UNLOCKED) || - gfs_assert_warn(sdp, (gh->gh_flags & (LM_FLAG_ANY | GL_EXACT)) != - (LM_FLAG_ANY | GL_EXACT))) { - set_bit(HIF_ABORTED, &gh->gh_iflags); - return -EIO; - } - - set_bit(HIF_PROMOTE, &gh->gh_iflags); - - spin_lock(&gl->gl_spin); - add_to_queue(gh); - run_queue(gl); - spin_unlock(&gl->gl_spin); - - if (!(gh->gh_flags & GL_ASYNC)) { - error = glock_wait_internal(gh); - if (error == GLR_CANCELED) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - goto restart; - } - } - - clear_bit(GLF_PREFETCH, &gl->gl_flags); - - return error; -} - -/** - * gfs_glock_poll - poll to see if an async request has been completed - * @gh: the holder - * - * Returns: TRUE if the request is ready to be gfs_glock_wait()ed on - */ - -int -gfs_glock_poll(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - int ready = FALSE; - - gfs_assert_warn(gl->gl_sbd, gh->gh_flags & GL_ASYNC); - - spin_lock(&gl->gl_spin); - - if (test_bit(HIF_HOLDER, &gh->gh_iflags)) - ready = TRUE; - else if (list_empty(&gh->gh_list)) { - if (gh->gh_error == GLR_CANCELED) { - spin_unlock(&gl->gl_spin); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - if (gfs_glock_nq(gh)) - return TRUE; - return FALSE; - } else - ready = TRUE; - } - - spin_unlock(&gl->gl_spin); - - return ready; -} - -/** - * gfs_glock_wait - wait for a lock acquisition that ended in a GLR_ASYNC - * @gh: the holder structure - * - * Returns: 0, GLR_TRYFAILED, or errno on failure - */ - -int -gfs_glock_wait(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - int error; - - gfs_assert_warn(gl->gl_sbd, gh->gh_flags & GL_ASYNC); - - error = glock_wait_internal(gh); - if (error == GLR_CANCELED) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - gh->gh_flags &= ~GL_ASYNC; - error = gfs_glock_nq(gh); - } - - return error; -} - -/** - * gfs_glock_dq - dequeue a struct gfs_holder from a glock (release a glock) - * @gh: the glock holder - * - * This releases a local process' hold on a glock, and services other waiters. - * If this is the last holder on this node, calls glock operation go_unlock(), - * and go_sync() if requested by glock's GL_SYNC flag. - * If glock's GL_NOCACHE flag is set, requests demotion to unlock the inter- - * node lock now, rather than caching the glock for later use. - * Otherwise, this function does *not* release the glock at inter-node scope. - * The glock will stay in glock cache until: - * -- This node uses it again (extending residence in glock cache), or - * -- Another node asks (via callback) for the lock, or - * -- The glock sits unused in glock cache for a while, and the cleanup - * daemons (gfs_scand and gfs_glockd) reclaim it. - */ - -void -gfs_glock_dq(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - - atomic_inc(&gl->gl_sbd->sd_glock_dq_calls); - - gfs_assert_withdraw(sdp, !queue_empty(gl, &gh->gh_list)); - gfs_assert_withdraw(sdp, test_bit(HIF_HOLDER, &gh->gh_iflags)); - - if (gh->gh_flags & GL_SYNC) - set_bit(GLF_SYNC, &gl->gl_flags); - - /* Don't cache glock; request demote to unlock at inter-node scope */ - if (gh->gh_flags & GL_NOCACHE && gl->gl_holders.next == &gh->gh_list && - gl->gl_holders.prev == &gh->gh_list) - /* There's a race here. If there are two holders, and both - * are dq'ed at almost the same time, you can't guarantee that - * you will call handle_callback. Fixing this will require - * some refactoring */ - handle_callback(gl, LM_ST_UNLOCKED); - - lock_on_glock(gl); - - spin_lock(&gl->gl_spin); - list_del_init(&gh->gh_list); - - /* If last holder, do appropriate glock operations, set cache timer */ - if (list_empty(&gl->gl_holders)) { - spin_unlock(&gl->gl_spin); - - if (glops->go_unlock) - glops->go_unlock(gl, gh->gh_flags); - - /* Do "early" sync, if requested by holder */ - if (test_bit(GLF_SYNC, &gl->gl_flags)) { - if (glops->go_sync) - glops->go_sync(gl, - DIO_METADATA | - DIO_DATA | - DIO_INVISIBLE); - } - - gl->gl_stamp = jiffies; - - spin_lock(&gl->gl_spin); - } - - clear_bit(GLF_LOCK, &gl->gl_flags); - run_queue(gl); - spin_unlock(&gl->gl_spin); -} - -/** - * gfs_glock_prefetch - Try to prefetch a glock - * @gl: the glock - * @state: the state to prefetch in - * @flags: flags passed to go_xmote_th() - * - * Bypass request queues of glock (i.e. no holder involved), and directly call - * go_xmote_th() to ask lock module for lock, to put in glock cache for - * later use. - * - * Will not prefetch the lock (no need to) if a process on this node is already - * interested in the lock, or if it's sitting in glock cache in a compatible - * state. - * - * Rules: - * Don't ask for UNLOCKED state (use gfs_glock_dq() for that). - * LM_FLAG_ANY (liberal) and GL_EXACT (restrictive) are mutually exclusive. - */ - -void -gfs_glock_prefetch(struct gfs_glock *gl, unsigned int state, int flags) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - - if (gfs_assert_warn(sdp, state != LM_ST_UNLOCKED) || - gfs_assert_warn(sdp, (flags & (LM_FLAG_ANY | GL_EXACT)) != - (LM_FLAG_ANY | GL_EXACT))) - return; - - spin_lock(&gl->gl_spin); - - /* Should we prefetch? */ - if (test_bit(GLF_LOCK, &gl->gl_flags) || - !list_empty(&gl->gl_holders) || - !list_empty(&gl->gl_waiters1) || - !list_empty(&gl->gl_waiters2) || - !list_empty(&gl->gl_waiters3) || - relaxed_state_ok(gl->gl_state, state, flags)) { - spin_unlock(&gl->gl_spin); - return; - } - - /* Let bottom half know we're prefetching, ask lock module for lock */ - set_bit(GLF_PREFETCH, &gl->gl_flags); - - if (gfs_assert_warn(sdp, !gl->gl_req_gh)) - gl->gl_req_gh = NULL; - set_bit(GLF_LOCK, &gl->gl_flags); - spin_unlock(&gl->gl_spin); - - glops->go_xmote_th(gl, state, flags); - - atomic_inc(&gl->gl_sbd->sd_glock_prefetch_calls); -} - -/** - * gfs_glock_force_drop - Force a glock to be uncached - * @gl: the glock - * - */ - -void -gfs_glock_force_drop(struct gfs_glock *gl) -{ - struct gfs_holder gh; - - gfs_holder_init(gl, LM_ST_UNLOCKED, 0, &gh); - set_bit(HIF_DEMOTE, &gh.gh_iflags); - gh.gh_owner = NULL; - - spin_lock(&gl->gl_spin); - list_add_tail(&gh.gh_list, &gl->gl_waiters2); - run_queue(gl); - spin_unlock(&gl->gl_spin); - - wait_for_completion(&gh.gh_wait); - gfs_holder_uninit(&gh); -} - -/** - * greedy_work - - * @data: - * - */ - -static void -greedy_work(void *data) -{ - struct greedy *gr = (struct greedy *)data; - struct gfs_holder *gh = &gr->gr_gh; - struct gfs_glock *gl = gh->gh_gl; - struct gfs_glock_operations *glops = gl->gl_ops; - - clear_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); - - if (glops->go_greedy) - glops->go_greedy(gl); - - spin_lock(&gl->gl_spin); - - if (list_empty(&gl->gl_waiters2)) { - clear_bit(GLF_GREEDY, &gl->gl_flags); - spin_unlock(&gl->gl_spin); - gfs_holder_uninit(gh); - kfree(gr); - } else { - glock_hold(gl); - list_add_tail(&gh->gh_list, &gl->gl_waiters2); - run_queue(gl); - spin_unlock(&gl->gl_spin); - glock_put(gl); - } -} - -/** - * gfs_glock_be_greedy - - * @gl: - * @time: - * - * Returns: 0 if go_greedy will be called, 1 otherwise - */ - -int -gfs_glock_be_greedy(struct gfs_glock *gl, unsigned int time) -{ - struct greedy *gr; - struct gfs_holder *gh; - - if (!time || - gl->gl_sbd->sd_args.ar_localcaching || - test_and_set_bit(GLF_GREEDY, &gl->gl_flags)) - return 1; - - gr = kmalloc(sizeof(struct greedy), GFP_KERNEL); - if (!gr) { - clear_bit(GLF_GREEDY, &gl->gl_flags); - return 1; - } - gh = &gr->gr_gh; - - gfs_holder_init(gl, 0, 0, gh); - set_bit(HIF_GREEDY, &gh->gh_iflags); - gh->gh_owner = NULL; - INIT_WORK(&gr->gr_work, greedy_work, gr); - - set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); - schedule_delayed_work(&gr->gr_work, time); - - return 0; -} - -/** - * gfs_glock_nq_init - intialize a holder and enqueue it on a glock - * @gl: the glock - * @state: the state we're requesting - * @flags: the modifier flags - * @gh: the holder structure - * - * Returns: 0, GLR_*, or errno - */ - -int -gfs_glock_nq_init(struct gfs_glock *gl, unsigned int state, int flags, - struct gfs_holder *gh) -{ - int error; - - gfs_holder_init(gl, state, flags, gh); - - error = gfs_glock_nq(gh); - if (error) - gfs_holder_uninit(gh); - - return error; -} - -/** - * gfs_glock_dq_uninit - dequeue a holder from a glock and initialize it - * @gh: the holder structure - * - */ - -void -gfs_glock_dq_uninit(struct gfs_holder *gh) -{ - gfs_glock_dq(gh); - gfs_holder_uninit(gh); -} - -/** - * gfs_glock_nq_num - acquire a glock based on lock number - * @sdp: the filesystem - * @number: the lock number - * @glops: the glock operations for the type of glock - * @state: the state to acquire the glock in - * @flags: modifier flags for the aquisition - * @gh: the struct gfs_holder - * - * Returns: errno - */ - -int -gfs_glock_nq_num(struct gfs_sbd *sdp, - uint64_t number, struct gfs_glock_operations *glops, - unsigned int state, int flags, struct gfs_holder *gh) -{ - struct gfs_glock *gl; - int error; - - error = gfs_glock_get(sdp, number, glops, CREATE, &gl); - if (!error) { - error = gfs_glock_nq_init(gl, state, flags, gh); - glock_put(gl); - } - - return error; -} - -/** - * glock_compare - Compare two struct gfs_glock structures for sorting - * @arg_a: the first structure - * @arg_b: the second structure - * - */ - -static int -glock_compare(const void *arg_a, const void *arg_b) -{ - struct gfs_holder *gh_a = *(struct gfs_holder **)arg_a; - struct gfs_holder *gh_b = *(struct gfs_holder **)arg_b; - struct lm_lockname *a = &gh_a->gh_gl->gl_name; - struct lm_lockname *b = &gh_b->gh_gl->gl_name; - int ret = 0; - - if (a->ln_number > b->ln_number) - ret = 1; - else if (a->ln_number < b->ln_number) - ret = -1; - else { - if (gh_a->gh_state == LM_ST_SHARED && - gh_b->gh_state == LM_ST_EXCLUSIVE) - ret = 1; - else if (!(gh_a->gh_flags & GL_LOCAL_EXCL) && - (gh_b->gh_flags & GL_LOCAL_EXCL)) - ret = 1; - } - - return ret; -} - -/** - * nq_m_sync - synchonously acquire more than one glock in deadlock free order - * @num_gh: the number of structures - * @ghs: an array of struct gfs_holder structures - * - * Returns: 0 on success (all glocks acquired), errno on failure (no glocks acquired) - */ - -static int -nq_m_sync(unsigned int num_gh, struct gfs_holder *ghs, struct gfs_holder **p) -{ - unsigned int x; - int error = 0; - - for (x = 0; x < num_gh; x++) - p[x] = &ghs[x]; - - gfs_sort(p, num_gh, sizeof(struct gfs_holder *), glock_compare); - - for (x = 0; x < num_gh; x++) { - p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); - - error = gfs_glock_nq(p[x]); - if (error) { - while (x--) - gfs_glock_dq(p[x]); - break; - } - } - - return error; -} - -/** - * gfs_glock_nq_m - acquire multiple glocks - * @num_gh: the number of structures - * @ghs: an array of struct gfs_holder structures - * - * Figure out how big an impact this function has. Either: - * 1) Replace this code with code that calls gfs_glock_prefetch() - * 2) Forget async stuff and just call nq_m_sync() - * 3) Leave it like it is - * - * Returns: 0 on success (all glocks acquired), errno on failure (no glocks acquired) - */ - -int -gfs_glock_nq_m(unsigned int num_gh, struct gfs_holder *ghs) -{ - int *e; - unsigned int x; - int borked = FALSE, serious = 0; - int error = 0; - - if (!num_gh) - return 0; - - /* For just one gh, do request synchronously */ - if (num_gh == 1) { - ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); - return gfs_glock_nq(ghs); - } - - /* using sizeof(struct gfs_holder *) instead of sizeof(int), because - * we're also using this memory for nq_m_sync and ints should never be - * larger than pointers.... I hope - */ - e = kmalloc(num_gh * sizeof(struct gfs_holder *), GFP_KERNEL); - if (!e) - return -ENOMEM; - - /* Send off asynchronous requests */ - for (x = 0; x < num_gh; x++) { - ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; - error = gfs_glock_nq(&ghs[x]); - if (error) { - borked = TRUE; - serious = error; - num_gh = x; - break; - } - } - - /* Wait for all to complete */ - for (x = 0; x < num_gh; x++) { - error = e[x] = glock_wait_internal(&ghs[x]); - if (error) { - borked = TRUE; - if (error != GLR_TRYFAILED && error != GLR_CANCELED) - serious = error; - } - } - - /* If all good, done! */ - if (!borked) { - kfree(e); - return 0; - } - - for (x = 0; x < num_gh; x++) - if (!e[x]) - gfs_glock_dq(&ghs[x]); - - if (serious) - error = serious; - else { - for (x = 0; x < num_gh; x++) - gfs_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, - &ghs[x]); - error = nq_m_sync(num_gh, ghs, (struct gfs_holder **)e); - } - - kfree(e); - return error; -} - -/** - * gfs_glock_dq_m - release multiple glocks - * @num_gh: the number of structures - * @ghs: an array of struct gfs_holder structures - * - */ - -void -gfs_glock_dq_m(unsigned int num_gh, struct gfs_holder *ghs) -{ - unsigned int x; - - for (x = 0; x < num_gh; x++) - gfs_glock_dq(&ghs[x]); -} - -/** - * gfs_glock_prefetch_num - prefetch a glock based on lock number - * @sdp: the filesystem - * @number: the lock number - * @glops: the glock operations for the type of glock - * @state: the state to acquire the glock in - * @flags: modifier flags for the aquisition - * - * Returns: errno - */ - -void -gfs_glock_prefetch_num(struct gfs_sbd *sdp, - uint64_t number, struct gfs_glock_operations *glops, - unsigned int state, int flags) -{ - struct gfs_glock *gl; - int error; - - if (atomic_read(&sdp->sd_reclaim_count) < gfs_tune_get(sdp, gt_reclaim_limit)) { - error = gfs_glock_get(sdp, number, glops, CREATE, &gl); - if (!error) { - gfs_glock_prefetch(gl, state, flags); - glock_put(gl); - } - } -} - -/** - * gfs_lvb_hold - attach a LVB from a glock - * @gl: The glock in question - * - */ - -int -gfs_lvb_hold(struct gfs_glock *gl) -{ - int error; - - lock_on_glock(gl); - - if (!atomic_read(&gl->gl_lvb_count)) { - gfs_assert_warn(gl->gl_sbd, !gl->gl_lvb); - error = gfs_lm_hold_lvb(gl->gl_sbd, gl->gl_lock, &gl->gl_lvb); - if (error) { - unlock_on_glock(gl); - return error; - } - glock_hold(gl); - } - atomic_inc(&gl->gl_lvb_count); - - unlock_on_glock(gl); - - return 0; -} - -/** - * gfs_lvb_unhold - detach a LVB from a glock - * @gl: The glock in question - * - */ - -void -gfs_lvb_unhold(struct gfs_glock *gl) -{ - glock_hold(gl); - - lock_on_glock(gl); - - if (!gfs_assert_warn(gl->gl_sbd, atomic_read(&gl->gl_lvb_count) > 0) && - atomic_dec_and_test(&gl->gl_lvb_count)) { - gfs_assert_warn(gl->gl_sbd, gl->gl_lvb); - gfs_lm_unhold_lvb(gl->gl_sbd, gl->gl_lock, gl->gl_lvb); - gl->gl_lvb = NULL; - glock_put(gl); - } - - unlock_on_glock(gl); - - glock_put(gl); -} - -/** - * gfs_lvb_sync - sync a LVB - * @gl: The glock in question - * - */ - -void -gfs_lvb_sync(struct gfs_glock *gl) -{ - if (gfs_assert_warn(gl->gl_sbd, atomic_read(&gl->gl_lvb_count))) - return; - - lock_on_glock(gl); - - if (!gfs_assert_warn(gl->gl_sbd, gfs_glock_is_held_excl(gl))) - gfs_lm_sync_lvb(gl->gl_sbd, gl->gl_lock, gl->gl_lvb); - - unlock_on_glock(gl); -} - -/** - * blocking_cb - - * @sdp: - * @name: - * @state: - * - */ - -void -blocking_cb(struct gfs_sbd *sdp, struct lm_lockname *name, unsigned int state) -{ - struct gfs_glock *gl; - - gl = gfs_glock_find(sdp, name); - if (!gl) - return; - - if (gl->gl_ops->go_callback) - gl->gl_ops->go_callback(gl, state); - handle_callback(gl, state); - - spin_lock(&gl->gl_spin); - run_queue(gl); - spin_unlock(&gl->gl_spin); - - glock_put(gl); -} - -/** - * gfs_glock_cb - Callback used by locking module - * @fsdata: Pointer to the superblock - * @type: Type of callback - * @data: Type dependent data pointer - * - * Called by the locking module when it wants to tell us something. - * Either we need to drop a lock, one of our ASYNC requests completed, or - * another client expired (crashed/died) and we need to recover its journal. - * If another node needs a lock held by this node, we queue a request to demote - * our lock to a state compatible with that needed by the other node. - * For example, if the other node needs EXCLUSIVE, we request UNLOCKED. - * SHARED and DEFERRED modes can be shared with other nodes, so we request - * accordingly. - * Once all incompatible holders on this node are done with the lock, the - * queued request will cause run_queue() to call the lock module to demote - * our lock to a compatible state, allowing the other node to grab the lock. - */ - -void -gfs_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data) -{ - struct gfs_sbd *sdp = (struct gfs_sbd *)fsdata; - - atomic_inc(&sdp->sd_lm_callbacks); - - switch (type) { - case LM_CB_NEED_E: - blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_UNLOCKED); - return; - - case LM_CB_NEED_D: - blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_DEFERRED); - return; - - case LM_CB_NEED_S: - blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_SHARED); - return; - - case LM_CB_ASYNC: { - struct lm_async_cb *async = (struct lm_async_cb *)data; - struct gfs_glock *gl; - - gl = gfs_glock_find(sdp, &async->lc_name); - if (gfs_assert_warn(sdp, gl)) - return; - if (!gfs_assert_warn(sdp, gl->gl_req_bh)) - gl->gl_req_bh(gl, async->lc_ret); - glock_put(gl); - - return; - } - - case LM_CB_NEED_RECOVERY: - gfs_add_dirty_j(sdp, *(unsigned int *)data); - if (test_bit(SDF_RECOVERD_RUN, &sdp->sd_flags)) - wake_up_process(sdp->sd_recoverd_process); - return; - - case LM_CB_DROPLOCKS: - gfs_gl_hash_clear(sdp, FALSE); - gfs_quota_scan(sdp); - return; - - default: - gfs_assert_warn(sdp, FALSE); - return; - } -} - -/** - * gfs_try_toss_inode - try to remove a particular GFS inode struct from cache - * sdp: the filesystem - * inum: the inode number - * - * Look for the glock protecting the inode of interest. - * If no process is manipulating or holding the glock, see if the glock - * has a gfs_inode attached. - * If gfs_inode has no references, unhold its iopen glock, release any - * indirect addressing buffers, and destroy the gfs_inode. - */ - -void -gfs_try_toss_inode(struct gfs_sbd *sdp, struct gfs_inum *inum) -{ - struct gfs_glock *gl; - struct gfs_inode *ip; - int error; - - error = gfs_glock_get(sdp, - inum->no_formal_ino, &gfs_inode_glops, - NO_CREATE, &gl); - if (error || !gl) - return; - - if (!trylock_on_glock(gl)) - goto out; - - if (!queue_empty(gl, &gl->gl_holders)) - goto out_unlock; - - ip = gl2ip(gl); - if (!ip) - goto out_unlock; - - if (atomic_read(&ip->i_count)) - goto out_unlock; - - gfs_inode_destroy(ip); - - out_unlock: - unlock_on_glock(gl); - - out: - glock_put(gl); -} - -/** - * gfs_iopen_go_callback - Try to kick the inode/vnode associated with an iopen glock from memory - * @io_gl: the iopen glock - * @state: the state into which the glock should be put - * - */ - -void -gfs_iopen_go_callback(struct gfs_glock *io_gl, unsigned int state) -{ - struct gfs_glock *i_gl; - struct gfs_inode *ip; - - if (state != LM_ST_UNLOCKED) - return; - - spin_lock(&io_gl->gl_spin); - i_gl = gl2gl(io_gl); - if (i_gl) { - glock_hold(i_gl); - spin_unlock(&io_gl->gl_spin); - } else { - spin_unlock(&io_gl->gl_spin); - return; - } - - if (trylock_on_glock(i_gl)) { - if (queue_empty(i_gl, &i_gl->gl_holders)) { - ip = gl2ip(i_gl); - if (ip) { - gfs_try_toss_vnode(ip); - unlock_on_glock(i_gl); - gfs_glock_schedule_for_reclaim(i_gl); - goto out; - } - } - unlock_on_glock(i_gl); - } - - out: - glock_put(i_gl); -} - -/** - * demote_ok - Check to see if it's ok to unlock a glock (to remove it - * from glock cache) - * @gl: the glock - * - * Called when trying to reclaim glocks, once it's determined that the glock - * has no holders on this node. - * - * Returns: TRUE if it's ok - * - * It's not okay if: - * -- glock is STICKY - * -- PREFETCHed glock has not been given enough chance to be used - * -- glock-type-specific test says "no" - */ - -static int -demote_ok(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock_operations *glops = gl->gl_ops; - int demote = TRUE; - - if (test_bit(GLF_STICKY, &gl->gl_flags)) - demote = FALSE; - else if (test_bit(GLF_PREFETCH, &gl->gl_flags)) - demote = time_after_eq(jiffies, - gl->gl_stamp + - gfs_tune_get(sdp, gt_prefetch_secs) * HZ); - else if (glops->go_demote_ok) - demote = glops->go_demote_ok(gl); - - return demote; -} - -/** - * gfs_glock_schedule_for_reclaim - Add a glock to the reclaim list - * @gl: the glock - * - */ - -void -gfs_glock_schedule_for_reclaim(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - - spin_lock(&sdp->sd_reclaim_lock); - if (list_empty(&gl->gl_reclaim)) { - glock_hold(gl); - list_add(&gl->gl_reclaim, &sdp->sd_reclaim_list); - atomic_inc(&sdp->sd_reclaim_count); - } - spin_unlock(&sdp->sd_reclaim_lock); - - wake_up(&sdp->sd_reclaim_wchan); -} - -/** - * gfs_reclaim_glock - process the next glock on the filesystem's reclaim list - * @sdp: the filesystem - * - * Called from gfs_glockd() glock reclaim daemon, or when promoting a - * (different) glock and we notice that there are a lot of glocks in the - * reclaim list. - * - * Remove glock from filesystem's reclaim list, update reclaim statistics. - * If no holders (might have gotten added since glock was placed on reclaim - * list): - * -- Destroy any now-unused inode protected by glock - * (and release hold on iopen glock). - * -- Ask for demote to UNLOCKED to enable removal of glock from glock cache. - * - * If no further interest in glock struct, remove it from glock cache, and - * free it from memory. (During normal operation, this is the only place - * that this is done). - * - * Glock-type-specific considerations for permission to demote are handled - * in demote_ok(). This includes how long to retain a glock in cache after it - * is no longer held by any process. - */ - -void -gfs_reclaim_glock(struct gfs_sbd *sdp) -{ - struct gfs_glock *gl; - struct gfs_gl_hash_bucket *bucket; - - spin_lock(&sdp->sd_reclaim_lock); - - /* Nothing to reclaim? Done! */ - if (list_empty(&sdp->sd_reclaim_list)) { - spin_unlock(&sdp->sd_reclaim_lock); - return; - } - - /* Remove next victim from reclaim list */ - gl = list_entry(sdp->sd_reclaim_list.next, - struct gfs_glock, gl_reclaim); - list_del_init(&gl->gl_reclaim); - - spin_unlock(&sdp->sd_reclaim_lock); - - atomic_dec(&sdp->sd_reclaim_count); - atomic_inc(&sdp->sd_reclaimed); - - if (trylock_on_glock(gl)) { - if (queue_empty(gl, &gl->gl_holders)) { - /* Inode glock-type-specific; free unused gfs inode, - and release hold on iopen glock */ - if (gl->gl_ops == &gfs_inode_glops) { - struct gfs_inode *ip = gl2ip(gl); - if (ip && !atomic_read(&ip->i_count)) - gfs_inode_destroy(ip); - } - /* Generic (including inodes); try to unlock glock */ - if (gl->gl_state != LM_ST_UNLOCKED && - demote_ok(gl)) - handle_callback(gl, LM_ST_UNLOCKED); - } - unlock_on_glock(gl); - } - - bucket = gl->gl_bucket; - - /* If glock struct's only remaining reference is from being put on - the reclaim list, remove glock from hash table (sd_gl_hash), - and free the glock's memory */ - write_lock(&bucket->hb_lock); - if (atomic_read(&gl->gl_count) == 1) { - list_del_init(&gl->gl_list); - write_unlock(&bucket->hb_lock); - glock_free(gl); - } else { - write_unlock(&bucket->hb_lock); - glock_put(gl); /* see gfs_glock_schedule_for_reclaim() */ - } -} - -/** - * examine_bucket - Call a function for glock in a hash bucket - * @examiner: the function - * @sdp: the filesystem - * @bucket: the bucket - * - * Returns: TRUE if the bucket has entries - */ - -static int -examine_bucket(glock_examiner examiner, - struct gfs_sbd *sdp, struct gfs_gl_hash_bucket *bucket, - unsigned int *purge_nr) -{ - struct glock_plug plug; - struct list_head *tmp; - struct gfs_glock *gl; - int entries; - - /* Add "plug" to end of bucket list, work back up list from there */ - memset(&plug.gl_flags, 0, sizeof(unsigned long)); - set_bit(GLF_PLUG, &plug.gl_flags); - - write_lock(&bucket->hb_lock); - list_add(&plug.gl_list, &bucket->hb_list); - write_unlock(&bucket->hb_lock); - - /* Look at each bucket entry */ - for (;;) { - write_lock(&bucket->hb_lock); - - /* Work back up list from plug */ - for (;;) { - tmp = plug.gl_list.next; - - /* Top of list; we're done */ - if (tmp == &bucket->hb_list) { - list_del(&plug.gl_list); - entries = !list_empty(&bucket->hb_list); - write_unlock(&bucket->hb_lock); - return entries; - } - gl = list_entry(tmp, struct gfs_glock, gl_list); - - /* Move plug up list */ - list_move(&plug.gl_list, &gl->gl_list); - - if (test_bit(GLF_PLUG, &gl->gl_flags)) - continue; - - /* glock_hold; examiner must glock_put() */ - atomic_inc(&gl->gl_count); - - break; - } - - write_unlock(&bucket->hb_lock); - - examiner(gl, purge_nr); - } -} - -static void -try_purge_iopen(struct gfs_glock *gl, unsigned int *p_count) -{ - struct gfs_glock *i_gl; - - if (*p_count == 0) - return; - - /* find the associated inode glock */ - i_gl = gl2gl(gl); - if (!i_gl) - return; - - /* - * If the associated inode glock has been in unlocked - * state, try to purge it. - */ - if (trylock_on_glock(i_gl)) { - if (i_gl->gl_state == LM_ST_UNLOCKED) { - *p_count = *p_count - 1; - unlock_on_glock(i_gl); - atomic_inc(&gl->gl_count); - gfs_iopen_go_callback(gl, LM_ST_UNLOCKED); - handle_callback(gl, LM_ST_UNLOCKED); - spin_lock(&gl->gl_spin); - run_queue(gl); - spin_unlock(&gl->gl_spin); - glock_put(gl); - } else - unlock_on_glock(i_gl); - } - - return; -} - -/** - * scan_glock - look at a glock and see if we can reclaim it - * @gl: the glock to look at - * - * Called via examine_bucket() when trying to release glocks from glock cache, - * during normal operation (i.e. not unmount time). - * - * Place glock on filesystem's reclaim list if, on this node: - * -- No process is manipulating glock struct, and - * -- No current holders, and either: - * -- GFS incore inode, protected by glock, is no longer in use, or - * -- Glock-type-specific demote_ok glops gives permission - */ - -static void -scan_glock(struct gfs_glock *gl, unsigned int *p_count) -{ - if (trylock_on_glock(gl)) { - if (queue_empty(gl, &gl->gl_holders)) { - /* Inode glock-type-specific; reclaim glock if gfs inode - no longer in use. */ - if (gl->gl_ops == &gfs_inode_glops) { - struct gfs_inode *ip = gl2ip(gl); - if (ip && !atomic_read(&ip->i_count)) { - unlock_on_glock(gl); - gfs_glock_schedule_for_reclaim(gl); - goto out; - } - } - /* Generic (including inodes not scheduled above) */ - if (gl->gl_state != LM_ST_UNLOCKED && - demote_ok(gl)) { - unlock_on_glock(gl); - gfs_glock_schedule_for_reclaim(gl); - goto out; - } - } - /* iopen always has holder(s) */ - if (gl->gl_name.ln_type == LM_TYPE_IOPEN) { - unlock_on_glock(gl); - try_purge_iopen(gl, p_count); - goto out; - } - unlock_on_glock(gl); - } - out: - glock_put(gl); /* see examine_bucket() */ -} - -/** - * gfs_scand_internal - Look for glocks and inodes to toss from memory - * @sdp: the filesystem - * - * Invokes scan_glock() for each glock in each cache bucket. - * - * Steps of reclaiming a glock: - * -- scan_glock() places eligible glocks on filesystem's reclaim list. - * -- gfs_reclaim_glock() processes list members, attaches demotion requests - * to wait queues of glocks still locked at inter-node scope. - * -- Demote to UNLOCKED state (if not already unlocked). - * -- gfs_reclaim_lock() cleans up glock structure. - */ - -void -gfs_scand_internal(struct gfs_sbd *sdp) -{ - unsigned int x, purge_nr; - - if (!sdp->sd_tune.gt_glock_purge) - purge_nr = 0; - else - purge_nr = atomic_read(&sdp->sd_glock_count) * - sdp->sd_tune.gt_glock_purge / 100; - - for (x = 0; x < GFS_GL_HASH_SIZE; x++) { - examine_bucket(scan_glock, sdp, &sdp->sd_gl_hash[x], &purge_nr); - cond_resched(); - } -} - -/** - * clear_glock - look at a glock and see if we can free it from glock cache - * @gl: the glock to look at - * - * Called via examine_bucket() when unmounting the filesystem, or - * when inter-node lock manager requests DROPLOCKS because it is running - * out of capacity. - * - * Similar to gfs_reclaim_glock(), except does *not*: - * -- Consult demote_ok() for permission - * -- Increment sdp->sd_reclaimed statistic - * - */ - -static void -clear_glock(struct gfs_glock *gl, unsigned int *unused) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_gl_hash_bucket *bucket = gl->gl_bucket; - - /* If this isn't shutdown, keep the transaction glock around. */ - if (sdp->sd_glockd_num && gl == sdp->sd_trans_gl) { - glock_put(gl); /* see examine_bucket() */ - return; - } - spin_lock(&sdp->sd_reclaim_lock); - if (!list_empty(&gl->gl_reclaim)) { - list_del_init(&gl->gl_reclaim); - atomic_dec(&sdp->sd_reclaim_count); - glock_put(gl); /* see gfs_glock_schedule_for_reclaim() */ - } - spin_unlock(&sdp->sd_reclaim_lock); - - if (trylock_on_glock(gl)) { - if (queue_empty(gl, &gl->gl_holders)) { - /* Inode glock-type-specific; free unused gfs inode, - and release hold on iopen glock */ - if (gl->gl_ops == &gfs_inode_glops) { - struct gfs_inode *ip = gl2ip(gl); - if (ip && !atomic_read(&ip->i_count)) - gfs_inode_destroy(ip); - } - /* Generic (including inodes); unlock glock */ - if (gl->gl_state != LM_ST_UNLOCKED) - handle_callback(gl, LM_ST_UNLOCKED); - } - - unlock_on_glock(gl); - } - - /* If glock struct's only remaining reference is from examine_bucket(), - remove glock from hash table (sd_gl_hash), and free glock's memory */ - write_lock(&bucket->hb_lock); - if (atomic_read(&gl->gl_count) == 1) { - list_del_init(&gl->gl_list); - write_unlock(&bucket->hb_lock); - glock_free(gl); - } else { - write_unlock(&bucket->hb_lock); - glock_put(gl); /* see examine_bucket() */ - } -} - -/** - * gfs_gl_hash_clear - Empty out the glock hash table - * @sdp: the filesystem - * @wait: wait until it's all gone - * - * Called when unmounting the filesystem, or when inter-node lock manager - * requests DROPLOCKS because it is running out of capacity. - */ - -void -gfs_gl_hash_clear(struct gfs_sbd *sdp, int wait) -{ - unsigned long t; - unsigned int x; - int cont; - - t = jiffies; - - for (;;) { - cont = FALSE; - - for (x = 0; x < GFS_GL_HASH_SIZE; x++) - if (examine_bucket(clear_glock, sdp, - &sdp->sd_gl_hash[x], 0)) - cont = TRUE; - - if (!wait || !cont) - break; - - if (time_after_eq(jiffies, t + gfs_tune_get(sdp, gt_stall_secs) * HZ)) { - printk("GFS: fsid=%s: Unmount seems to be stalled. Dumping lock state...\n", - sdp->sd_fsname); - gfs_dump_lockstate(sdp, NULL); - t = jiffies; - } - - invalidate_inodes(sdp->sd_vfs); - yield(); - } -} - -/* - * Diagnostic routines to help debug distributed deadlock - */ - -/** - * dump_holder - print information about a glock holder - * @str: a string naming the type of holder - * @gh: the glock holder - * @buf: the buffer - * @size: the size of the buffer - * @count: where we are in the buffer - * - * Returns: 0 on success, -ENOBUFS when we run out of space - */ - -static int -dump_holder(char *str, struct gfs_holder *gh, - char *buf, unsigned int size, unsigned int *count) -{ - unsigned int x; - int error = -ENOBUFS; - - gfs_printf(" %s\n", str); - gfs_printf(" owner = %ld\n", - (gh->gh_owner) ? (long)gh->gh_owner->pid : -1); - gfs_printf(" gh_state = %u\n", gh->gh_state); - gfs_printf(" gh_flags ="); - for (x = 0; x < 32; x++) - if (gh->gh_flags & (1 << x)) - gfs_printf(" %u", x); - gfs_printf(" \n"); - gfs_printf(" error = %d\n", gh->gh_error); - gfs_printf(" gh_iflags ="); - for (x = 0; x < 32; x++) - if (test_bit(x, &gh->gh_iflags)) - gfs_printf(" %u", x); - gfs_printf(" \n"); - - error = 0; - - out: - return error; -} - -/** - * dump_inode - print information about an inode - * @ip: the inode - * @buf: the buffer - * @size: the size of the buffer - * @count: where we are in the buffer - * - * Returns: 0 on success, -ENOBUFS when we run out of space - */ - -static int -dump_inode(struct gfs_inode *ip, - char *buf, unsigned int size, unsigned int *count) -{ - unsigned int x; - int error = -ENOBUFS; - - gfs_printf(" Inode:\n"); - gfs_printf(" num = %" PRIu64 "/%" PRIu64 "\n", - ip->i_num.no_formal_ino, ip->i_num.no_addr); - gfs_printf(" type = %u\n", ip->i_di.di_type); - gfs_printf(" i_count = %d\n", atomic_read(&ip->i_count)); - gfs_printf(" i_flags ="); - for (x = 0; x < 32; x++) - if (test_bit(x, &ip->i_flags)) - gfs_printf(" %u", x); - gfs_printf(" \n"); - gfs_printf(" vnode = %s\n", (ip->i_vnode) ? "yes" : "no"); - - error = 0; - - out: - return error; -} - -/** - * dump_glock - print information about a glock - * @gl: the glock - * @buf: the buffer - * @size: the size of the buffer - * @count: where we are in the buffer - * - * Returns: 0 on success, -ENOBUFS when we run out of space - */ - -static int -dump_glock(struct gfs_glock *gl, - char *buf, unsigned int size, unsigned int *count) -{ - struct list_head *head, *tmp; - struct gfs_holder *gh; - unsigned int x; - int error = -ENOBUFS; - - spin_lock(&gl->gl_spin); - - gfs_printf("Glock (%u, %" PRIu64 ")\n", - gl->gl_name.ln_type, - gl->gl_name.ln_number); - gfs_printf(" gl_flags ="); - for (x = 0; x < 32; x++) - if (test_bit(x, &gl->gl_flags)) - gfs_printf(" %u", x); - gfs_printf(" \n"); - gfs_printf(" gl_count = %d\n", atomic_read(&gl->gl_count)); - gfs_printf(" gl_state = %u\n", gl->gl_state); - gfs_printf(" req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); - gfs_printf(" req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); - gfs_printf(" lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); - gfs_printf(" object = %s\n", (gl->gl_object) ? "yes" : "no"); - gfs_printf(" new_le = %s\n", (gl->gl_new_le.le_trans) ? "yes" : "no"); - gfs_printf(" incore_le = %s\n", (gl->gl_incore_le.le_trans) ? "yes" : "no"); - gfs_printf(" reclaim = %s\n", - (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); - if (gl->gl_aspace) - gfs_printf(" aspace = %lu\n", - gl->gl_aspace->i_mapping->nrpages); - else - gfs_printf(" aspace = no\n"); - gfs_printf(" ail_bufs = %s\n", - (list_empty(&gl->gl_ail_bufs)) ? "no" : "yes"); - if (gl->gl_req_gh) { - error = dump_holder("Request", gl->gl_req_gh, buf, size, count); - if (error) - goto out; - } - for (head = &gl->gl_holders, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gh = list_entry(tmp, struct gfs_holder, gh_list); - error = dump_holder("Holder", gh, buf, size, count); - if (error) - goto out; - } - for (head = &gl->gl_waiters1, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gh = list_entry(tmp, struct gfs_holder, gh_list); - error = dump_holder("Waiter1", gh, buf, size, count); - if (error) - goto out; - } - for (head = &gl->gl_waiters2, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gh = list_entry(tmp, struct gfs_holder, gh_list); - error = dump_holder("Waiter2", gh, buf, size, count); - if (error) - goto out; - } - for (head = &gl->gl_waiters3, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gh = list_entry(tmp, struct gfs_holder, gh_list); - error = dump_holder("Waiter3", gh, buf, size, count); - if (error) - goto out; - } - if (gl->gl_ops == &gfs_inode_glops && gl2ip(gl)) { - if (!test_bit(GLF_LOCK, &gl->gl_flags) && - list_empty(&gl->gl_holders)) { - error = dump_inode(gl2ip(gl), buf, size, count); - if (error) - goto out; - } else { - error = -ENOBUFS; - gfs_printf(" Inode: busy\n"); - } - } - - error = 0; - - out: - spin_unlock(&gl->gl_spin); - - return error; -} - -/** - * gfs_dump_lockstate - print out the current lockstate - * @sdp: the filesystem - * @ub: the buffer to copy the information into - * - * If @ub is NULL, dump the lockstate to the console. - * - */ - -int -gfs_dump_lockstate(struct gfs_sbd *sdp, struct gfs_user_buffer *ub) -{ - struct gfs_gl_hash_bucket *bucket; - struct list_head *tmp, *head; - struct gfs_glock *gl; - char *buf = NULL; - unsigned int size = gfs_tune_get(sdp, gt_lockdump_size); - unsigned int x, count; - int error = 0; - - if (ub) { - buf = kmalloc(size, GFP_KERNEL); - if (!buf) - return -ENOMEM; - } - - for (x = 0; x < GFS_GL_HASH_SIZE; x++) { - bucket = &sdp->sd_gl_hash[x]; - count = 0; - - read_lock(&bucket->hb_lock); - - for (head = &bucket->hb_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gl = list_entry(tmp, struct gfs_glock, gl_list); - - if (test_bit(GLF_PLUG, &gl->gl_flags)) - continue; - - error = dump_glock(gl, buf, size, &count); - if (error) - break; - } - - read_unlock(&bucket->hb_lock); - - if (error) - break; - - if (ub) { - if (ub->ub_count + count > ub->ub_size) { - error = -ENOMEM; - break; - } - if (copy_to_user(ub->ub_data + ub->ub_count, buf, count)) { - error = -EFAULT; - break; - } - ub->ub_count += count; - } - } - - if (ub) - kfree(buf); - - return error; -} diff --git a/gfs-kernel/src/gfs/glock.h b/gfs-kernel/src/gfs/glock.h deleted file mode 100644 index 4fa4d3f..0000000 --- a/gfs-kernel/src/gfs/glock.h +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFS_GLOCK_DOT_H__ -#define __GFS_GLOCK_DOT_H__ - -/* Flags for lock requests; used in gfs_holder gh_flag field. */ -/* These are defined in lm_interface.h, commented out here. -#define LM_FLAG_TRY (0x00000001) -#define LM_FLAG_TRY_1CB (0x00000002) -#define LM_FLAG_NOEXP (0x00000004) -#define LM_FLAG_ANY (0x00000008) -#define LM_FLAG_PRIORITY (0x00000010) - These are defined here. */ -#define GL_LOCAL_EXCL (0x00000020) /* Only one holder may be granted the - * lock on this node, even if SHARED */ -#define GL_ASYNC (0x00000040) /* Don't block waiting for lock ... - * must poll to wait for grant */ -#define GL_EXACT (0x00000080) /* Requested state must == current state - * for lock to be granted */ -#define GL_SKIP (0x00000100) /* Don't read from disk after grant */ -#define GL_ATIME (0x00000200) /* Update inode's ATIME after grant */ -#define GL_NOCACHE (0x00000400) /* Release glock when done, don't cache */ -#define GL_SYNC (0x00000800) /* Sync to disk when no more holders */ -#define GL_NOCANCEL (0x00001000) /* Don't ever cancel this request */ -#define GL_NOCANCEL_OTHER (0x00002000) /* Don't cancel other locks for this */ - -#define GLR_TRYFAILED (13) -#define GLR_CANCELED (14) - -static __inline__ int -gfs_glock_is_locked_by_me(struct gfs_glock *gl) -{ - struct list_head *tmp, *head; - struct gfs_holder *gh; - int locked = FALSE; - - /* Look in glock's list of holders for one with current task as owner */ - spin_lock(&gl->gl_spin); - for (head = &gl->gl_holders, tmp = head->next; - tmp != head; - tmp = tmp->next) { - gh = list_entry(tmp, struct gfs_holder, gh_list); - if (gh->gh_owner == current) { - locked = TRUE; - break; - } - } - spin_unlock(&gl->gl_spin); - - return locked; -} -static __inline__ int -gfs_glock_is_held_excl(struct gfs_glock *gl) -{ - return (gl->gl_state == LM_ST_EXCLUSIVE); -} -static __inline__ int -gfs_glock_is_held_dfrd(struct gfs_glock *gl) -{ - return (gl->gl_state == LM_ST_DEFERRED); -} -static __inline__ int -gfs_glock_is_held_shrd(struct gfs_glock *gl) -{ - return (gl->gl_state == LM_ST_SHARED); -} - -static __inline__ int -gfs_glock_is_blocking(struct gfs_glock *gl) -{ - int ret; - spin_lock(&gl->gl_spin); - ret = !list_empty(&gl->gl_waiters2) || !list_empty(&gl->gl_waiters3); - spin_unlock(&gl->gl_spin); - return ret; -} - -struct gfs_glock *gfs_glock_find(struct gfs_sbd *sdp, - struct lm_lockname *name); -int gfs_glock_get(struct gfs_sbd *sdp, - uint64_t number, struct gfs_glock_operations *glops, - int create, struct gfs_glock **glp); -void gfs_glock_hold(struct gfs_glock *gl); -void gfs_glock_put(struct gfs_glock *gl); - -void gfs_holder_init(struct gfs_glock *gl, unsigned int state, int flags, - struct gfs_holder *gh); -void gfs_holder_reinit(unsigned int state, int flags, struct gfs_holder *gh); -void gfs_holder_uninit(struct gfs_holder *gh); -struct gfs_holder *gfs_holder_get(struct gfs_glock *gl, unsigned int state, - int flags); -void gfs_holder_put(struct gfs_holder *gh); - -void gfs_glock_xmote_th(struct gfs_glock *gl, unsigned int state, int flags); -void gfs_glock_drop_th(struct gfs_glock *gl); - -int gfs_glock_nq(struct gfs_holder *gh); -int gfs_glock_poll(struct gfs_holder *gh); -int gfs_glock_wait(struct gfs_holder *gh); -void gfs_glock_dq(struct gfs_holder *gh); - -void gfs_glock_prefetch(struct gfs_glock *gl, unsigned int state, int flags); -void gfs_glock_force_drop(struct gfs_glock *gl); - -int gfs_glock_be_greedy(struct gfs_glock *gl, unsigned int time); - -int gfs_glock_nq_init(struct gfs_glock *gl, unsigned int state, int flags, - struct gfs_holder *gh); -void gfs_glock_dq_uninit(struct gfs_holder *gh); -int gfs_glock_nq_num(struct gfs_sbd *sdp, - uint64_t number, struct gfs_glock_operations *glops, - unsigned int state, int flags, struct gfs_holder *gh); - -int gfs_glock_nq_m(unsigned int num_gh, struct gfs_holder *ghs); -void gfs_glock_dq_m(unsigned int num_gh, struct gfs_holder *ghs); - -void gfs_glock_prefetch_num(struct gfs_sbd *sdp, - uint64_t number, struct gfs_glock_operations *glops, - unsigned int state, int flags); - -/* Lock Value Block functions */ - -int gfs_lvb_hold(struct gfs_glock *gl); -void gfs_lvb_unhold(struct gfs_glock *gl); -void gfs_lvb_sync(struct gfs_glock *gl); - -void gfs_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data); - -void gfs_try_toss_inode(struct gfs_sbd *sdp, struct gfs_inum *inum); -void gfs_iopen_go_callback(struct gfs_glock *gl, unsigned int state); - -void gfs_glock_schedule_for_reclaim(struct gfs_glock *gl); -void gfs_reclaim_glock(struct gfs_sbd *sdp); - -void gfs_scand_internal(struct gfs_sbd *sdp); -void gfs_gl_hash_clear(struct gfs_sbd *sdp, int wait); - -int gfs_dump_lockstate(struct gfs_sbd *sdp, struct gfs_user_buffer *ub); - -#endif /* __GFS_GLOCK_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/glops.c b/gfs-kernel/src/gfs/glops.c deleted file mode 100644 index 6b7218a..0000000 --- a/gfs-kernel/src/gfs/glops.c +++ /dev/null @@ -1,671 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "log.h" -#include "page.h" -#include "recovery.h" -#include "rgrp.h" - -/** - * meta_go_sync - sync out the metadata for this glock - * @gl: the glock - * @flags: DIO_* - * - * Used for meta and rgrp glocks. - * - * Called when demoting (gfs_glock_xmote_th()) or unlocking - * (gfs_glock_drop_th() an EX glock at inter-node scope. We must flush - * to disk all dirty buffers/pages relating to this glock, and must not - * not return to caller to demote/unlock the glock until I/O is complete. - * - * This is *not* called from gfs_glock_dq(), because GL_SYNC flag is not - * currently used for anything but inode glocks. - */ - -static void -meta_go_sync(struct gfs_glock *gl, int flags) -{ - if (!(flags & DIO_METADATA)) - return; - - if (test_bit(GLF_DIRTY, &gl->gl_flags)) - gfs_log_flush_glock(gl, flags); - - /* We've synced everything, clear SYNC request and DIRTY flags */ - clear_bit(GLF_DIRTY, &gl->gl_flags); - clear_bit(GLF_SYNC, &gl->gl_flags); -} - -/** - * meta_go_inval - invalidate the metadata for this glock - * @gl: the glock - * @flags: - * - */ - -static void -meta_go_inval(struct gfs_glock *gl, int flags) -{ - if (!(flags & DIO_METADATA)) - return; - - gfs_inval_buf(gl); - gl->gl_vn++; -} - -/** - * meta_go_demote_ok - Check to see if it's ok to unlock a meta glock - * @gl: the glock - * - * Returns: TRUE if we have no cached data; ok to demote meta glock - * - * Called when trying to dump (reclaim) a glock from the glock cache, after - * determining that there is currently no holder on this node for this glock, - * and before placing LM_ST_UNLOCKED request on glock's wait-for-demote queue. - * Note that callbacks from other nodes that need a lock do *not* - * seek permission from this function before requesting a demote. - * Nor do glocks obtained with the following flags (see demote_ok()): - * -- GL_NOCACHE: gets unlocked (and not cached) immediately after use - * -- GLF_STICKY: equivalent to always getting "FALSE" from this function - * -- GLF_PREFETCH: uses its own timeout - * - * For glocks that protect on-disk data (meta, inode, and rgrp glocks), disk - * accesses are slow, while lock manipulation is usually fast. Releasing - * a lock means that we: - * -- Must sync memory-cached write data to disk immediately, before another - * node can be granted the lock (at which point that node must read the - * data from disk). - * -- Must invalidate memory-cached data that we had read from or written - * to disk. Another node can change it if we don't have a lock, so it's - * now useless to us. - * - * Then, if we re-acquire the lock again in the future, we: - * -- Must (re-)read (perhaps unchanged) data from disk into memory. - * - * All of these are painful, so it pays to retain a glock in our glock cache - * as long as we have cached data (even though we have no active holders - * for this lock on this node currently), unless/until another node needs - * to change it. This allows Linux block I/O to sync write data to disk in - * a "lazy" way, rather than forcing an immediate sync (and resultant WAIT), - * and retains current data in memory as long as possible. - * - * This also helps GFS respond to memory pressure. There is no mechanism for - * the Linux virtual memory manager to directly call into GFS to ask it to - * drop locks. So, we take a hint from what the VM does to the page cache. - * When that cache is trimmed (and we see no more pages relating to this - * glock), we trim the glock cache as well, by releasing this lock. - */ - -static int -meta_go_demote_ok(struct gfs_glock *gl) -{ - return (gl->gl_aspace->i_mapping->nrpages) ? FALSE : TRUE; -} - -/** - * inode_go_xmote_th - promote/demote (but don't unlock) an inode glock - * @gl: the glock - * @state: the requested state - * @flags: the flags passed into gfs_glock() - * - * Acquire a new glock, or change an already-acquired glock to - * more/less restrictive state (other than LM_ST_UNLOCKED). - */ - -static void -inode_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) -{ - if (gl->gl_state != LM_ST_UNLOCKED) - gfs_inval_pte(gl); - gfs_glock_xmote_th(gl, state, flags); -} - -/** - * inode_go_xmote_bh - After promoting/demoting (but not unlocking) - * an inode glock - * @gl: the glock - * - * FIXME: This will be really broken when (no_formal_ino != no_addr) - * and gl_name.ln_number no longer refers to the dinode block #. - * - * If we've just acquired the inter-node lock for an inode, - * read the dinode block from disk (but don't wait for I/O completion). - * Exceptions (don't read if): - * Glock state is UNLOCKED. - * Glock's requesting holder's GL_SKIP flag is set. - */ - -static void -inode_go_xmote_bh(struct gfs_glock *gl) -{ - struct gfs_holder *gh = gl->gl_req_gh; - struct buffer_head *bh; - int error; - - if (gl->gl_state != LM_ST_UNLOCKED && - (!gh || !(gh->gh_flags & GL_SKIP))) { - error = gfs_dread(gl, gl->gl_name.ln_number, DIO_START, &bh); - if (!error) - brelse(bh); - } -} - -/** - * inode_go_drop_th - unlock an inode glock - * @gl: the glock - * - * Invoked from rq_demote(). - * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) - * is being purged from our node's glock cache; we're dropping lock. - */ - -static void -inode_go_drop_th(struct gfs_glock *gl) -{ - gfs_inval_pte(gl); - gfs_glock_drop_th(gl); -} - -/** - * inode_go_sync - Sync the dirty data and/or metadata for an inode glock - * @gl: the glock protecting the inode - * @flags: DIO_METADATA -- sync inode's metadata - * DIO_DATA -- sync inode's data - * DIO_INVISIBLE -- don't clear glock's DIRTY flag when done - * - * If DIO_INVISIBLE: - * 1) Called from gfs_glock_dq(), when releasing the last holder for an EX - * glock (but glock is still in our glock cache in EX state, and might - * stay there for a few minutes). Holder had GL_SYNC flag set, asking - * for early sync (i.e. now, instead of later when we release the EX at - * inter-node scope). GL_SYNC is currently used only for inodes in - * special cases, so inode is the only type of glock for which - * DIO_INVISIBLE would apply. - * 2) Called from depend_sync_one() to sync deallocated inode metadata - * before it can be reallocated by another process or machine. Since - * this call can happen at any time during the lifetime of the - * glock, don't clear the sync bit (more data might be dirtied - * momentarily). - * Else (later): - * Called when demoting (gfs_glock_xmote_th()) or unlocking - * (gfs_glock_drop_th() an EX glock at inter-node scope. We must flush - * to disk all dirty buffers/pages relating to this glock, and must not - * return to caller to demote/unlock the glock until I/O is complete. - * - * Syncs go in following order: - * Start data page writes - * Sync metadata to log (wait to complete I/O) - * Sync metadata to in-place location (wait to complete I/O) - * Wait for data page I/O to complete - * - */ - -static void -inode_go_sync(struct gfs_glock *gl, int flags) -{ - int meta = (flags & DIO_METADATA); - int data = (flags & DIO_DATA); - - if (test_bit(GLF_DIRTY, &gl->gl_flags)) { - if (meta && data) { - gfs_sync_page(gl, flags | DIO_START); - gfs_log_flush_glock(gl, flags); - gfs_sync_page(gl, flags | DIO_WAIT | DIO_CHECK); - } else if (meta) { - gfs_log_flush_glock(gl, flags); - } else if (data) - gfs_sync_page(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); - } - - /* If we've synced everything, clear the SYNC request. - If we're doing the final (not early) sync, clear DIRTY */ - if (meta && data) { - if (!(flags & DIO_INVISIBLE)) - clear_bit(GLF_DIRTY, &gl->gl_flags); - clear_bit(GLF_SYNC, &gl->gl_flags); - } -} - -/** - * inode_go_inval - prepare a inode glock to be released - * @gl: the glock - * @flags: - * - */ - -static void -inode_go_inval(struct gfs_glock *gl, int flags) -{ - int meta = (flags & DIO_METADATA); - int data = (flags & DIO_DATA); - - if (meta) { - gfs_inval_buf(gl); - gl->gl_vn++; - } - if (data) - gfs_inval_page(gl); -} - -/** - * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock - * @gl: the glock - * - * See comments for meta_go_demote_ok(). - * - * While other glock types (meta, rgrp) that protect disk data can be retained - * indefinitely, GFS imposes a timeout (overridden when using no_lock lock - * module) for inode glocks, even if there is still data in page cache for - * this inode. - * - * Returns: TRUE if it's ok - */ - -static int -inode_go_demote_ok(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - int demote = FALSE; - - if (!gl2ip(gl) && !gl->gl_aspace->i_mapping->nrpages) - demote = TRUE; - else if (!sdp->sd_args.ar_localcaching && - time_after_eq(jiffies, gl->gl_stamp + gfs_tune_get(sdp, gt_demote_secs) * HZ)) - demote = TRUE; - - return demote; -} - -/** - * inode_go_lock - operation done after an inode lock is locked by - * a first holder on this node - * @gl: the glock - * @flags: the flags passed into gfs_glock() - * - * Returns: errno - */ - -static int -inode_go_lock(struct gfs_glock *gl, int flags) -{ - struct gfs_inode *ip = gl2ip(gl); - int error = 0; - - if (ip && ip->i_vn != gl->gl_vn) { - error = gfs_copyin_dinode(ip); - if (!error) - gfs_inode_attr_in(ip); - } - - return error; -} - -/** - * inode_go_unlock - operation done when an inode lock is unlocked by - * a last holder on this node - * @gl: the glock - * @flags: the flags passed into gfs_gunlock() - * - */ - -static void -inode_go_unlock(struct gfs_glock *gl, int flags) -{ - struct gfs_inode *ip = gl2ip(gl); - - if (ip && test_bit(GLF_DIRTY, &gl->gl_flags)) - gfs_inode_attr_in(ip); - - if (ip) - gfs_flush_meta_cache(ip); -} - -/** - * inode_greedy - - * @gl: the glock - * - */ - -static void -inode_greedy(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_inode *ip = gl2ip(gl); - unsigned int quantum = gfs_tune_get(sdp, gt_greedy_quantum); - unsigned int max = gfs_tune_get(sdp, gt_greedy_max); - unsigned int new_time; - - spin_lock(&ip->i_spin); - - if (time_after(ip->i_last_pfault + quantum, jiffies)) { - new_time = ip->i_greedy + quantum; - if (new_time > max) - new_time = max; - } else { - new_time = ip->i_greedy - quantum; - if (!new_time || new_time > max) - new_time = 1; - } - - ip->i_greedy = new_time; - - spin_unlock(&ip->i_spin); - - gfs_inode_put(ip); -} - -/** - * rgrp_go_xmote_th - promote/demote (but don't unlock) a resource group glock - * @gl: the glock - * @state: the requested state - * @flags: the flags passed into gfs_glock() - * - * Acquire a new glock, or change an already-acquired glock to - * more/less restrictive state (other than LM_ST_UNLOCKED). - * - * We're going to lock the lock in SHARED or EXCLUSIVE state, or - * demote it from EXCLUSIVE to SHARED (because another node needs it SHARED). - * When locking, gfs_mhc_zap() and gfs_depend_sync() are basically no-ops; - * meta-header cache and dependency lists should be empty. - * - */ - -static void -rgrp_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) -{ - struct gfs_rgrpd *rgd = gl2rgd(gl); - - gfs_mhc_zap(rgd); - gfs_depend_sync(rgd); - gfs_glock_xmote_th(gl, state, flags); -} - -/** - * rgrp_go_drop_th - unlock a resource group glock - * @gl: the glock - * - * Invoked from rq_demote(). - * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) - * is being purged from our node's glock cache; we're dropping lock. - */ - -static void -rgrp_go_drop_th(struct gfs_glock *gl) -{ - struct gfs_rgrpd *rgd = gl2rgd(gl); - - gfs_mhc_zap(rgd); - gfs_depend_sync(rgd); - gfs_glock_drop_th(gl); -} - -/** - * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock - * @gl: the glock - * - * See comments for meta_go_demote_ok(). - * - * In addition to Linux page cache, we also check GFS meta-header-cache. - * - * Returns: TRUE if it's ok - */ - -static int -rgrp_go_demote_ok(struct gfs_glock *gl) -{ - struct gfs_rgrpd *rgd = gl2rgd(gl); - int demote = TRUE; - - if (gl->gl_aspace->i_mapping->nrpages) - demote = FALSE; - else if (rgd && !list_empty(&rgd->rd_mhc)) /* Don't bother with lock here */ - demote = FALSE; - - return demote; -} - -/** - * rgrp_go_lock - operation done after an rgrp lock is locked by - * a first holder on this node. - * @gl: the glock - * @flags: the flags passed into gfs_glock() - * - * Returns: errno - * - * Read rgrp's header and block allocation bitmaps from disk. - */ - -static int -rgrp_go_lock(struct gfs_glock *gl, int flags) -{ - if (flags & GL_SKIP) - return 0; - return gfs_rgrp_read(gl2rgd(gl)); -} - -/** - * rgrp_go_unlock - operation done when an rgrp lock is unlocked by - * a last holder on this node. - * @gl: the glock - * @flags: the flags passed into gfs_gunlock() - * - * Release rgrp's bitmap buffers (read in when lock was first obtained). - * Make sure rgrp's glock's Lock Value Block has up-to-date block usage stats, - * so other nodes can see them. - */ - -static void -rgrp_go_unlock(struct gfs_glock *gl, int flags) -{ - struct gfs_rgrpd *rgd = gl2rgd(gl); - if (flags & GL_SKIP) - return; - gfs_rgrp_relse(rgd); - if (test_bit(GLF_DIRTY, &gl->gl_flags)) - gfs_rgrp_lvb_fill(rgd); -} - -/** - * trans_go_xmote_th - promote/demote (but don't unlock) the transaction glock - * @gl: the glock - * @state: the requested state - * @flags: the flags passed into gfs_glock() - * - * Acquire a new glock, or change an already-acquired glock to - * more/less restrictive state (other than LM_ST_UNLOCKED). - */ - -static void -trans_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - - if (gl->gl_state != LM_ST_UNLOCKED && - test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { - gfs_sync_meta(sdp); - gfs_log_shutdown(sdp); - } - - gfs_glock_xmote_th(gl, state, flags); -} - -/** - * trans_go_xmote_bh - After promoting/demoting (but not unlocking) - * the transaction glock - * @gl: the glock - * - */ - -static void -trans_go_xmote_bh(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_glock *j_gl = sdp->sd_journal_gh.gh_gl; - struct gfs_log_header head; - int error; - - if (gl->gl_state != LM_ST_UNLOCKED && - test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { - j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); - - error = gfs_find_jhead(sdp, &sdp->sd_jdesc, j_gl, &head); - if (error) - gfs_consist(sdp); - if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) - gfs_consist(sdp); - - /* Initialize some head of the log stuff */ - sdp->sd_sequence = head.lh_sequence; - sdp->sd_log_head = head.lh_first + 1; - } -} - -/** - * trans_go_drop_th - unlock the transaction glock - * @gl: the glock - * - * Invoked from rq_demote(). - * Another node needs the lock in EXCLUSIVE mode to quiesce the filesystem - * (for journal replay, etc.). - * - * We want to sync the device even with localcaching. Remember - * that localcaching journal replay only marks buffers dirty. - */ - -static void -trans_go_drop_th(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - - if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { - gfs_sync_meta(sdp); - gfs_log_shutdown(sdp); - } - - gfs_glock_drop_th(gl); -} - -/** - * nondisk_go_demote_ok - Check to see if it's ok to unlock a non-disk glock - * @gl: the glock - * - * See comments for meta_go_demote_ok(). - * - * We never give up a non-disk glock (unless another node needs it). - * Non-disk type used for GFS_MOUNT_LOCK, GFS_LIVE_LOCK, GFS_RENAME_LOCK. - * GFS_MOUNT_LOCK is always requested GL_NOCACHE, however, so it never uses - * this function. - * - * Returns: TRUE if it's ok - */ - -static int -nondisk_go_demote_ok(struct gfs_glock *gl) -{ - return FALSE; -} - -/** - * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock - * @gl: the glock - * - * See comments for meta_go_demote_ok(). - * - * Returns: TRUE if it's ok - */ - -static int -quota_go_demote_ok(struct gfs_glock *gl) -{ - return !atomic_read(&gl->gl_lvb_count); -} - -struct gfs_glock_operations gfs_meta_glops = { - .go_xmote_th = gfs_glock_xmote_th, - .go_drop_th = gfs_glock_drop_th, - .go_sync = meta_go_sync, - .go_inval = meta_go_inval, - .go_demote_ok = meta_go_demote_ok, - .go_type = LM_TYPE_META -}; - -struct gfs_glock_operations gfs_inode_glops = { - .go_xmote_th = inode_go_xmote_th, - .go_xmote_bh = inode_go_xmote_bh, - .go_drop_th = inode_go_drop_th, - .go_sync = inode_go_sync, - .go_inval = inode_go_inval, - .go_demote_ok = inode_go_demote_ok, - .go_lock = inode_go_lock, - .go_unlock = inode_go_unlock, - .go_greedy = inode_greedy, - .go_type = LM_TYPE_INODE -}; - -struct gfs_glock_operations gfs_rgrp_glops = { - .go_xmote_th = rgrp_go_xmote_th, - .go_drop_th = rgrp_go_drop_th, - .go_sync = meta_go_sync, - .go_inval = meta_go_inval, - .go_demote_ok = rgrp_go_demote_ok, - .go_lock = rgrp_go_lock, - .go_unlock = rgrp_go_unlock, - .go_type = LM_TYPE_RGRP -}; - -struct gfs_glock_operations gfs_trans_glops = { - .go_xmote_th = trans_go_xmote_th, - .go_xmote_bh = trans_go_xmote_bh, - .go_drop_th = trans_go_drop_th, - .go_type = LM_TYPE_NONDISK -}; - -struct gfs_glock_operations gfs_iopen_glops = { - .go_xmote_th = gfs_glock_xmote_th, - .go_drop_th = gfs_glock_drop_th, - .go_callback = gfs_iopen_go_callback, - .go_type = LM_TYPE_IOPEN -}; - -struct gfs_glock_operations gfs_flock_glops = { - .go_xmote_th = gfs_glock_xmote_th, - .go_drop_th = gfs_glock_drop_th, - .go_type = LM_TYPE_FLOCK -}; - -struct gfs_glock_operations gfs_nondisk_glops = { - .go_xmote_th = gfs_glock_xmote_th, - .go_drop_th = gfs_glock_drop_th, - .go_demote_ok = nondisk_go_demote_ok, - .go_type = LM_TYPE_NONDISK -}; - -struct gfs_glock_operations gfs_quota_glops = { - .go_xmote_th = gfs_glock_xmote_th, - .go_drop_th = gfs_glock_drop_th, - .go_demote_ok = quota_go_demote_ok, - .go_type = LM_TYPE_QUOTA -}; diff --git a/gfs-kernel/src/gfs/glops.h b/gfs-kernel/src/gfs/glops.h deleted file mode 100644 index ce57c51..0000000 --- a/gfs-kernel/src/gfs/glops.h +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GLOPS_DOT_H__ -#define __GLOPS_DOT_H__ - -extern struct gfs_glock_operations gfs_meta_glops; -extern struct gfs_glock_operations gfs_inode_glops; -extern struct gfs_glock_operations gfs_rgrp_glops; -extern struct gfs_glock_operations gfs_trans_glops; -extern struct gfs_glock_operations gfs_iopen_glops; -extern struct gfs_glock_operations gfs_flock_glops; -extern struct gfs_glock_operations gfs_nondisk_glops; -extern struct gfs_glock_operations gfs_quota_glops; - -#endif /* __GLOPS_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/incore.h b/gfs-kernel/src/gfs/incore.h deleted file mode 100644 index 18291fe..0000000 --- a/gfs-kernel/src/gfs/incore.h +++ /dev/null @@ -1,1226 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * In-core (memory/RAM) structures. - * These do not appear on-disk. See gfs_ondisk.h for on-disk structures. - */ - -#ifndef __INCORE_DOT_H__ -#define __INCORE_DOT_H__ - -/* flags used in function call parameters */ - -#define DIO_NEW (0x00000001) /* Newly allocated metadata */ -#define DIO_FORCE (0x00000002) /* Force read of block from disk */ -#define DIO_CLEAN (0x00000004) /* Don't write to disk */ -#define DIO_DIRTY (0x00000008) /* Data changed, must write to disk */ -#define DIO_START (0x00000010) /* Start disk read or write */ -#define DIO_WAIT (0x00000020) /* Wait for disk r/w to complete */ - -#define DIO_METADATA (0x00000040) /* Process glock's protected metadata */ -#define DIO_DATA (0x00000080) /* Process glock's protected filedata */ -#define DIO_INVISIBLE (0x00000100) /* Don't monkey with glock's dirty bit */ -#define DIO_CHECK (0x00000200) /* Make sure all metadata has been synced */ -#define DIO_ALL (0x00000400) /* Flush all AIL transactions to disk */ - -/* Structure prototypes */ - -struct gfs_log_operations; -struct gfs_log_element; -struct gfs_meta_header_cache; -struct gfs_depend; -struct gfs_bitmap; -struct gfs_rgrpd; -struct gfs_bufdata; -struct gfs_glock_operations; -struct gfs_holder; -struct gfs_glock; -struct gfs_alloc; -struct gfs_inode; -struct gfs_file; -struct gfs_unlinked; -struct gfs_quota_le; -struct gfs_quota_data; -struct gfs_log_buf; -struct gfs_trans; -struct gfs_gl_hash_bucket; -struct gfs_sbd; - -typedef void (*gfs_glop_bh_t) (struct gfs_glock * gl, unsigned int ret); - -/* - * Structure of operations that are associated with each - * type of element in the log. - */ -struct gfs_log_operations { - /* - * Operations specific to a given log element (LE). - * These are typically executed individually via macros such as LO_ADD. - */ - - /* Add new LE to transaction */ - void (*lo_add) (struct gfs_sbd * sdp, struct gfs_log_element * le); - - /* Do any cleanup, etc., needed just before commit to incore log */ - void (*lo_trans_end) (struct gfs_sbd * sdp, - struct gfs_log_element * le); - - /* Print LE-specific info via printk() */ - void (*lo_print) (struct gfs_sbd * sdp, struct gfs_log_element * le, - unsigned int where); - - /* Find any incore transactions that overlap through this LE (e.g. - * share glocks), to determine if any transactions can be combined. */ - struct gfs_trans *(*lo_overlap_trans) (struct gfs_sbd * sdp, - struct gfs_log_element * le); - - /* Change LE from "new" to "incore" status, before write to log */ - void (*lo_incore_commit) (struct gfs_sbd * sdp, struct gfs_trans * tr, - struct gfs_log_element * le); - - /* Allow writes to in-place locations, after log is on-disk */ - void (*lo_add_to_ail) (struct gfs_sbd * sdp, - struct gfs_log_element * le); - - /* Clean up LE after log dump */ - void (*lo_clean_dump) (struct gfs_sbd * sdp, - struct gfs_log_element * le); - - /* - * Operations specific to a class of log elements. - * These are typically executed over a whole transaction by - * macros such as LO_TRANS_SIZE. Each LE-type-specific operation - * for each LE contributes its part to the overall result. - */ - - /* Determine LE-type-specific quantities of blocks of various types - * required for writing the log */ - void (*lo_trans_size) (struct gfs_sbd * sdp, struct gfs_trans * tr, - unsigned int *mblks, unsigned int *eblks, - unsigned int *blocks, unsigned int *bmem); - - /* Combine LE-type-specific values in new_tr and tr, result is in tr */ - void (*lo_trans_combine) (struct gfs_sbd * sdp, struct gfs_trans * tr, - struct gfs_trans * new_tr); - - /* Create control and metadata buffers that will make up the log */ - void (*lo_build_bhlist) (struct gfs_sbd * sdp, struct gfs_trans * tr); - - /* Calculate log space needed for this LE in a log dump */ - void (*lo_dump_size) (struct gfs_sbd * sdp, unsigned int *elements, - unsigned int *blocks, unsigned int *bmem); - - /* Add LE to log dump */ - void (*lo_build_dump) (struct gfs_sbd * sdp, struct gfs_trans * tr); - - /* - * Operations that happen at recovery time - */ - - /* Reset/init whatever before doing recovery */ - void (*lo_before_scan) (struct gfs_sbd * sdp, unsigned int jid, - struct gfs_log_header * head, - unsigned int pass); - - /* LE-specific recovery procedure */ - int (*lo_scan_elements) (struct gfs_sbd * sdp, - struct gfs_jindex * jdesc, - struct gfs_glock * gl, uint64_t start, - struct gfs_log_descriptor * desc, - unsigned int pass); - - /* Verify and report recovery results/statistics */ - void (*lo_after_scan) (struct gfs_sbd * sdp, unsigned int jid, - unsigned int pass); - - - /* - * Type of element (glock/buf/unlinked/quota) - */ - char *lo_name; -}; - -/* - * Structure that gets added to struct gfs_trans->tr_elements. They - * make up the "stuff" in each transaction. - */ -struct gfs_log_element { - struct gfs_log_operations *le_ops; /* Vector of functions */ - - struct gfs_trans *le_trans; /* We're part of this transaction */ - struct list_head le_list; /* Link to transaction's element list */ -}; - -/* - * Meta-header cache structure. - * One for each metadata block that we've de-allocated. - * Used to temporarily store gfs_meta_header structs for meta blocks that - * have been freshly turned into FREEMETA (alloc'd or de-alloc'd). Storing - * these (small) structures in-core allows us to release the (large) buffers, - * and not need to re-read the header from disk if/when we re-allocate the - * blocks to USEDMETA, as long as this node holds the EXCLUSIVE lock for the - * resource group containing the blocks. If we release the EX lock, we must - * throw away the rgrp's cached meta headers, since another node could change - * the blocks' contents. - * In-core superblock structure hosts the hashed cache, as well as a - * linear list of all cached, in most-recently-added order. - * Also, each resource group keeps a list of cached blocks within its scope. - */ -struct gfs_meta_header_cache { - /* Links to various lists */ - struct list_head mc_list_hash; /* Superblock's hashed list */ - struct list_head mc_list_single; /* Superblock's list, MRU order */ - struct list_head mc_list_rgd; /* Resource group's list */ - - uint64_t mc_block; /* Block # (in-place address) */ - struct gfs_meta_header mc_mh; /* Payload: the block's meta-header */ -}; - -/* - * Dependency cache structure. - * In-core superblock structure hosts the actual cache. - * Also, each resource group keeps a list of dependency blocks within its scope. - */ -struct gfs_depend { - /* Links to various lists */ - struct list_head gd_list_hash; /* Superblock's hashed list */ - struct list_head gd_list_rgd; /* Resource group's list */ - - struct gfs_rgrpd *gd_rgd; /* Resource group descriptor */ - uint64_t gd_formal_ino; /* Inode ID */ - unsigned long gd_time; /* Time (jiffies) when put on list */ -}; - -/* - * Block allocation bitmap descriptor structure. - * One of these for each FS block that contains bitmap data - * (i.e. the resource group header blocks and their following bitmap blocks). - * Each allocatable FS data block is represented by 2 bits (4 alloc states). - */ -struct gfs_bitmap { - uint32_t bi_offset; /* Byte offset of bitmap within this bit block - (non-zero only for an rgrp header block) */ - uint32_t bi_start; /* Data block (rgrp scope, 32-bit) represented - by the first bit-pair in this bit block */ - uint32_t bi_len; /* The number of bitmap bytes in this bit block */ -}; - -/* - * Resource Group (Rgrp) descriptor structure. - * There is one of these for each resource (block) group in the FS. - * The filesystem is divided into a number of resource groups to allow - * simultaneous block alloc operations by a number of nodes. - */ -struct gfs_rgrpd { - /* Links to superblock lists */ - struct list_head rd_list; /* On-disk-order list of all rgrps */ - struct list_head rd_list_mru; /* Most Recently Used list of all rgs */ - struct list_head rd_recent; /* recently used rgrps */ - uint32_t rd_try_counter; /* # of times we fail a try lock */ - - struct gfs_glock *rd_gl; /* Glock for this rgrp */ - - struct gfs_rindex rd_ri; /* Resource Index (on-disk) structure */ - struct gfs_rgrp rd_rg; /* Resource Group (on-disk) structure */ - uint64_t rd_rg_vn; /* Version #: if != glock's gl_vn, - we need to read rgrp fm disk */ - - /* Block alloc bitmap cache */ - struct gfs_bitmap *rd_bits; /* Array of block bitmap descriptors */ - struct buffer_head **rd_bh; /* Array of ptrs to block bitmap bh's */ - - /* Block allocation strategy, rgrp scope. Start at these blocks when - searching for next data/meta block to alloc */ - uint32_t rd_last_alloc_data; /* Most recent data block allocated */ - uint32_t rd_last_alloc_meta; /* Most recent meta block allocated */ - - struct list_head rd_mhc; /* Cached meta-headers for this rgrp */ - struct list_head rd_depend; /* Dependent inodes (MRU order) */ - - struct gfs_sbd *rd_sbd; /* FS incore superblock (fs instance) */ -}; - -/* - * Per-buffer data - * One of these is attached as GFS private data to each FS block's buffer_head. - * These keep track of a buffer's progress through the transaction pipeline, - * using the "new" embedded log element to attach it to a being-built - * transaction, and moving the attachment point to the "incore" LE once - * the transaction completes (at which time the buffer becomes a candidate - * to be written to the on-disk log). - * A buffer may be attached simultaneously to a new and an incore transaction, - * but no more than one of each: Only one new trans may be built at a time - * for a given buffer, obviously, since the buffer's contents are protected - * by an EXclusive glock when writing. And, when a transaction is completely - * built, GFS combines incore transactions that share glocks (see - * incore_commit()), i.e. the glock that protects the buffer, so a buffer - * never needs to be attached to more than one (combined) incore trans. - * Note that multiple transactions can modify the buffer since its most - * recent writes to disk. This principle applies to both in-place and - * journal block locations on-disk, allowing this node to keep modifying the - * cached data without writing it to disk, unless/until another node needs - * to access the data, or the Linux OS tells us to sync to disk. - * If a transaction follows another transaction before the first transaction's - * log completes (indicated by the in-place buffer head still being pinned - * in RAM), GFS copies the first transaction's results to a "frozen" - * image of the buffer, so the first transaction results (an atomic - * snapshot) can be logged properly, while the second transaction is - * modifying the "real" buffer. This frozen copy lives only until the new - * transaction is complete, at which point one of two things has occurred: - * 1). Buffer was logged successfully; frozen copy's job is done. - * 2). Buffer was not yet logged; frozen copy no longer needed, newer - * buffer becomes the log candidate. - * - * gfs_bufdata structs also link into the Active Items Lists (AIL) (buffers - * flushed to on-disk log, but not yet flushed to on-disk in-place locations) - * attached to: - * 1). The latest transaction to modify and log (on-disk) the buffer, and - * 2). The glock that protects the buffer's contents. - * The buffer is attached to only the most recent transaction's AIL - * list for a couple of reasons. One is that only the most up-to-date - * buffer content needs to be written to the in-place block on-disk. The - * other is that since there is a more recent copy of the block in - * the log, we don't need to keep the older copies in the log. We can - * remove them from the AIL and let the log space be reused for new - * transactions (GFS advances the log tail when removing buffers from AIL). - */ -struct gfs_bufdata { - struct buffer_head *bd_bh; /* We belong to this Linux buffer_head */ - struct gfs_glock *bd_gl; /* This glock protects buffer's payload */ - - /* Log elements map us to a particular set of log operations functions, - and to a particular transaction */ - struct gfs_log_element bd_new_le; /* New, incomplete transaction */ - struct gfs_log_element bd_incore_le; /* Complete (committed) trans */ - - char *bd_frozen; /* "Frozen" copy of buffer's data */ - struct semaphore bd_lock; /* Protects access to this structure */ - - /* "Pin" means keep buffer in RAM, don't write to disk (yet) */ - unsigned int bd_pinned; /* Recursive pin count */ - - /* Links to Active Items Lists */ - struct list_head bd_ail_tr_list; /* This buf's most recent trans' AIL */ - struct list_head bd_ail_gl_list; /* This buf's glock's AIL */ -}; - -/* - * Glock operations - * One set of operations for each glock, the set selected by type of glock. - * These functions get called at various points in a glock's lifetime. - * "xmote" = promote or demote (change lock state) a glock at inter-node scope. - * "th" = top half, "bh" = bottom half - * Some operations/fields are required (GFS assumes they are there): - * go_xmote_th - * go_drop_th - * go_type - * Other operations are optional (GFS checks for presence before calling). - */ -struct gfs_glock_operations { - - /* Acquire lock or change lock state at inter-node scope: - Does type-specific preparation (if any) - Uses gfs_glock_xmote_th to call lock module. */ - void (*go_xmote_th) (struct gfs_glock * gl, unsigned int state, - int flags); - - /* After acquiring or changing a lock at inter-node scope */ - void (*go_xmote_bh) (struct gfs_glock * gl); - - /* Release (unlock) a lock at inter-node scope: - Does type-specific preparation (if any) - Uses gfs_glock_drop_th to call lock module. */ - void (*go_drop_th) (struct gfs_glock * gl); - - /* After releasing a lock at inter-node scope */ - void (*go_drop_bh) (struct gfs_glock * gl); - - /* Sync dirty data to disk (e.g. before demoting an EX inter-node lock) - (another node needs to read the updated data from disk) */ - void (*go_sync) (struct gfs_glock * gl, int flags); - - /* Invalidate local cached data just after releasing an inter-node lock - (another node may change the on-disk data, so it's no good to us) */ - void (*go_inval) (struct gfs_glock * gl, int flags); - - /* Lock-type-specific check to see if it's okay to unlock a glock - at inter-node scope (and remove it from our glock cache) */ - int (*go_demote_ok) (struct gfs_glock * gl); - - /* After getting lock for first holder (within this node) */ - int (*go_lock) (struct gfs_glock * gl, int flags); - - /* After last holder (within this node) gives up lock (glock may - remain in glock cache, though) */ - void (*go_unlock) (struct gfs_glock * gl, int flags); - - /* After receiving a callback: another node needs the lock */ - void (*go_callback) (struct gfs_glock * gl, unsigned int state); - - /* Called when the glock layer marks a lock as being not greedy - anymore */ - void (*go_greedy) (struct gfs_glock * gl); - - /* Lock type: locks with same lock # (often an FS block #), - but different types, are different locks */ - int go_type; -}; - -/* - * Glock holder structure - * One for each holder of a glock. - * These coordinate the use, within this node, of an acquired inter-node glock. - * Once a node has acquired a glock, it may be shared within that node by - * several processes, or even by several recursive requests from the same - * process. Each is a separate "holder". Different holders may co-exist - * having requested different lock states, as long as the node holds the - * glock in a state that is compatible. A hold requestor may select, via - * flags, the rules by which sharing within the node is granted: - * LM_FLAG_ANY: Grant if glock state is any other than UNLOCKED. - * GL_EXACT: Grant only if glock state is exactly the requested state. - * GL_LOCAL_EXCL: Grant only one holder at a time within this node. - * With no flags, a hold will be granted to a SHARED request even if the - * node holds the glock in EXCLUSIVE mode. See relaxed_state_ok(). - * When a process needs to manipulate a lock, it requests it via one of - * these holder structures. If the request cannot be satisfied immediately, - * the holder structure gets queued on one of these lists in gfs_glock: - * 1) waiters1, for gaining exclusive access to the (local) glock structure. - * 2) waiters2, for demoting a lock (unlocking a glock, or changing its state - * to be less restrictive) or relenquishing "greedy" status. - * 3) waiters3, for promoting (locking a new glock, or changing a glock state - * to be more restrictive). - * When holding a lock, gfs_holder struct stays on glock's holder list. - * See gfs-kernel/src/harness/lm_interface.h for gh_state (LM_ST_...) - * and gh_flags (LM_FLAG...) fields. - * Also see glock.h for gh_flags field (GL_...) flags. - */ - -/* Action requests */ -#define HIF_MUTEX (0) /* Exclusive (local) access to glock struct */ -#define HIF_PROMOTE (1) /* Change lock to more restrictive state */ -#define HIF_DEMOTE (2) /* Change lock to less restrictive state */ -#define HIF_GREEDY (3) /* Wait for the glock to be unlocked */ - -/* States */ -#define HIF_ALLOCED (4) /* Holder structure is or was in use */ -#define HIF_DEALLOC (5) /* Toss holder struct as soon as queued request - * is satisfied */ -#define HIF_HOLDER (6) /* We have been granted a hold on the lock */ -#define HIF_FIRST (7) /* We are first holder to get the lock */ -#define HIF_RECURSE (8) /* >1 hold requests on same glock by same process*/ -#define HIF_ABORTED (9) /* Aborted before being submitted */ - -struct gfs_holder { - struct list_head gh_list; /* Link to one of glock's holder lists */ - - struct gfs_glock *gh_gl; /* Glock that we're holding */ - struct task_struct *gh_owner; /* Linux process that is the holder */ - - /* request to change lock state */ - unsigned int gh_state; /* LM_ST_... requested lock state */ - int gh_flags; /* GL_... or LM_FLAG_... req modifiers */ - - int gh_error; /* GLR_... CANCELLED/TRYFAILED/-errno */ - unsigned long gh_iflags; /* HIF_... holder state, see above */ - struct completion gh_wait; /* Wait for completion of ... */ -}; - -/* - * Glock Structure - * One for each inter-node lock held by this node. - * A glock is a local representation/abstraction of an inter-node lock. - * Inter-node locks are managed by a "lock module" (LM) which plugs in to - * the lock harness / glock interface (see gfs-kernel/harness). Different - * lock modules support different lock protocols (e.g. GULM, GDLM, no_lock). - * A glock may have one or more holders within a node. See gfs_holder above. - * Glocks are managed within a hash table hosted by the in-core superblock. - * After all holders have released a glock, it will stay in the hash table - * cache for a time (depending on lock type), during which the inter-node - * lock will not be released unless another node needs the lock (lock - * manager requests this via callback to GFS through LM on this node). This - * provides better performance in case this node needs the glock again soon. - * See comments for meta_go_demote_ok(), glops.c. - * Each glock has an associated vector of lock-type-specific "glops" functions - * which are called at important times during the life of a glock, and - * which define the type of lock (e.g. dinode, rgrp, non-disk, etc). - * See gfs_glock_operations above. - * A glock, at inter-node scope, is identified by the following dimensions: - * 1) lock number (usually a block # for on-disk protected entities, - * or a fixed assigned number for non-disk locks, e.g. MOUNT). - * 2) lock type (actually, the type of entity protected by the lock). - * 3) lock namespace, to support multiple GFS filesystems simultaneously. - * Namespace (usually cluster:filesystem) is specified when mounting. - * See man page for gfs_mount. - * Glocks require support of Lock Value Blocks (LVBs) by the inter-node lock - * manager. LVBs are small (32-byte) chunks of data associated with a given - * lock, that can be quickly shared between cluster nodes. Used for certain - * purposes such as sharing an rgroup's block usage statistics without - * requiring the overhead of: - * -- sync-to-disk by one node, then a - * -- read from disk by another node. - * - */ - -#define GLF_PLUG (0) /* Dummy */ -#define GLF_LOCK (1) /* Exclusive (local) access to glock - * structure */ -#define GLF_STICKY (2) /* Don't release this inter-node lock - * unless another node explicitly asks */ -#define GLF_PREFETCH (3) /* This lock has been (speculatively) - * prefetched, demote if not used soon */ -#define GLF_SYNC (4) /* Sync lock's protected data as soon as - * there are no more holders */ -#define GLF_DIRTY (5) /* There is dirty data for this lock, - * sync before releasing inter-node */ -#define GLF_SKIP_WAITERS2 (6) /* Make run_queue() ignore gl_waiters2 - * (demote/greedy) holders */ -#define GLF_GREEDY (7) /* This lock is ignoring callbacks - * (requests from other nodes) for now */ - -struct gfs_glock { - struct list_head gl_list; /* Link to hb_list in one of superblock's - * sd_gl_hash glock hash table buckets */ - unsigned long gl_flags; /* GLF_... see above */ - struct lm_lockname gl_name; /* Lock number and lock type */ - atomic_t gl_count; /* Usage count */ - - spinlock_t gl_spin; /* Protects some members of this struct */ - - /* Lock state reflects inter-node manager's lock state */ - unsigned int gl_state; /* LM_ST_... see harness/lm_interface.h */ - - /* Lists of gfs_holders */ - struct list_head gl_holders; /* all current holders of the glock */ - struct list_head gl_waiters1; /* HIF_MUTEX */ - struct list_head gl_waiters2; /* HIF_DEMOTE, HIF_GREEDY */ - struct list_head gl_waiters3; /* HIF_PROMOTE */ - - struct gfs_glock_operations *gl_ops; /* function vector, defines type */ - - /* State to remember for async lock requests */ - struct gfs_holder *gl_req_gh; /* Holder for request being serviced */ - gfs_glop_bh_t gl_req_bh; /* The bottom half to execute */ - - lm_lock_t *gl_lock; /* Lock module's private lock data */ - char *gl_lvb; /* Lock Value Block */ - atomic_t gl_lvb_count; /* LVB recursive usage (hold/unhold) count */ - - uint64_t gl_vn; /* Incremented when protected data changes */ - unsigned long gl_stamp; /* Glock cache retention timer */ - void *gl_object; /* The protected entity (e.g. a dinode) */ - - /* Incore transaction stuff */ - /* Log elements map us to a particular set of log operations functions, - and to a particular transaction */ - struct gfs_log_element gl_new_le; /* New, incomplete transaction */ - struct gfs_log_element gl_incore_le; /* Complete (committed) trans */ - - struct gfs_gl_hash_bucket *gl_bucket; /* Our bucket in sd_gl_hash */ - struct list_head gl_reclaim; /* Link to sd_reclaim_list */ - - struct gfs_sbd *gl_sbd; /* Superblock (FS instance) */ - - struct inode *gl_aspace; /* The buffers protected by this lock */ - struct list_head gl_ail_bufs; /* AIL buffers protected by us */ -}; - -/* - * In-Place Reservation structure - * Coordinates allocation of "in-place" (as opposed to journal) FS blocks, - * which contain persistent inode/file/directory data and metadata. - * These blocks are the allocatable blocks within resource groups (i.e. - * not including rgrp header and block alloc bitmap blocks). - * gfs_inplace_reserve() calculates a fulfillment plan for allocating blocks, - * based on block statistics in the resource group headers. - * Then, gfs_blkalloc() or gfs_metaalloc() walks the block alloc bitmaps - * to do the actual allocation. - */ -struct gfs_alloc { - /* Up to 4 quotas (including an inode's user and group quotas) - can track changes in block allocation */ - - unsigned int al_qd_num; /* # of quotas tracking changes */ - struct gfs_quota_data *al_qd[4]; /* Ptrs to quota structures */ - struct gfs_holder al_qd_ghs[4]; /* Holders for quota glocks */ - - /* Request, filled in by the caller to gfs_inplace_reserve() */ - - uint32_t al_requested_di; /* Number of dinodes to reserve */ - uint32_t al_requested_meta; /* Number of metadata blocks to reserve */ - uint32_t al_requested_data; /* Number of data blocks to reserve */ - - /* Fulfillment plan, filled in by gfs_inplace_reserve() */ - - char *al_file; /* Debug info, .c file making request */ - unsigned int al_line; /* Debug info, line of code making req */ - struct gfs_holder al_ri_gh; /* Glock holder for resource grp index */ - struct gfs_holder al_rgd_gh; /* Glock holder for al_rgd rgrp */ - struct gfs_rgrpd *al_rgd; /* Resource group from which to alloc */ - uint32_t al_reserved_meta; /* Alloc up to this # meta blocks from al_rgd */ - uint32_t al_reserved_data; /* Alloc up to this # data blocks from al_rgd */ - - /* Actual alloc, filled in by gfs_blkalloc()/gfs_metaalloc(), etc. */ - - uint32_t al_alloced_di; /* # dinode blocks allocated */ - uint32_t al_alloced_meta; /* # meta blocks allocated */ - uint32_t al_alloced_data; /* # data blocks allocated */ - - /* Dinode allocation crap */ - - struct gfs_unlinked *al_ul; /* Unlinked dinode log entry */ -}; - -/* - * Incore inode structure - */ - -#define GIF_QD_LOCKED (0) -#define GIF_PAGED (1) -#define GIF_SW_PAGED (2) - -struct gfs_inode { - struct gfs_inum i_num; /* Formal inode # and block address */ - - atomic_t i_count; /* Usage count */ - unsigned long i_flags; /* GIF_... see above */ - - uint64_t i_vn; /* Version #: if different from glock's vn, - we need to read inode from disk */ - struct gfs_dinode i_di; /* Dinode (on-disk) structure */ - - struct gfs_glock *i_gl; /* This glock protects this inode */ - struct gfs_sbd *i_sbd; /* Superblock (fs instance structure) */ - struct inode *i_vnode; /* Linux VFS inode structure */ - - struct gfs_holder i_iopen_gh; /* Glock holder for Inode Open lock */ - - /* Block allocation strategy, inode scope */ - struct gfs_alloc *i_alloc; /* In-place block reservation structure */ - uint64_t i_last_rg_alloc; /* Most recent blk alloc was fm this rgrp */ - - spinlock_t i_spin; - struct rw_semaphore i_rw_mutex; - - /* Cache of most-recently used buffers in indirect addressing chain */ - struct buffer_head *i_cache[GFS_MAX_META_HEIGHT]; - - unsigned int i_greedy; /* The amount of time to be greedy */ - unsigned long i_last_pfault; /* The time of the last page fault */ - - struct timeval i_dir_stat_st; /* Start time of stat counter */ - unsigned long i_dir_stats; /* stat counter for this directory */ - struct address_space_operations gfs_file_aops; -}; - -/* - * GFS per-fd structure - */ - -#define GFF_DID_DIRECT_ALLOC (0) - -struct gfs_file { - unsigned long f_flags; /* GFF_... see above */ - - struct semaphore f_fl_lock; /* Lock to protect flock operations */ - struct gfs_holder f_fl_gh; /* Holder for this f_vfile's flock */ - - struct gfs_inode *f_inode; /* Incore GFS inode */ - struct file *f_vfile; /* Linux file struct */ -}; - -/* - * Unlinked inode log entry incore structure - */ - -#define ULF_NEW_UL (0) /* Part of new (being built) trans */ -#define ULF_INCORE_UL (1) /* Part of incore-committed trans */ -#define ULF_IC_LIST (2) -#define ULF_OD_LIST (3) -#define ULF_LOCK (4) /* Protects access to this structure */ - -struct gfs_unlinked { - struct list_head ul_list; /* Link to superblock's sd_unlinked_list */ - unsigned int ul_count; /* Usage count */ - - struct gfs_inum ul_inum; /* Formal inode #, block addr */ - unsigned long ul_flags; /* ULF_... */ - - /* Log elements map us to a particular set of log operations functions, - and to a particular transaction */ - struct gfs_log_element ul_new_le; /* New, not yet committed */ - struct gfs_log_element ul_incore_le; /* Committed to incore log */ - struct gfs_log_element ul_ondisk_le; /* Committed to ondisk log */ -}; - -/* - * Quota log element - * One for each logged change in a block alloc value affecting a given quota. - * Only one of these for a given quota within a given transaction; - * multiple changes, within one transaction, for a given quota will be - * combined into one log element. - */ -struct gfs_quota_le { - /* Log element maps us to a particular set of log operations functions, - and to a particular transaction */ - struct gfs_log_element ql_le; /* Generic log element structure */ - - struct gfs_quota_data *ql_data; /* The quota we're changing */ - struct list_head ql_data_list; /* Link to quota's log element list */ - - int64_t ql_change; /* # of blocks alloc'd (+) or freed (-) */ -}; - -/* - * Quota structure - * One for each user or group quota. - * Summarizes all block allocation activity for a given quota, and supports - * recording updates of current block alloc values in GFS' special quota - * file, including the journaling of these updates, encompassing - * multiple transactions and log dumps. - */ - -#define QDF_USER (0) /* User (1) vs. group (0) quota */ -#define QDF_OD_LIST (1) /* Waiting for sync to quota file */ -#define QDF_LOCK (2) /* Protects access to this structure */ - -struct gfs_quota_data { - struct list_head qd_list; /* Link to superblock's sd_quota_list */ - unsigned int qd_count; /* Usage count */ - - uint32_t qd_id; /* User or group ID number */ - unsigned long qd_flags; /* QDF_... */ - - /* This list is for non-log-dump transactions */ - struct list_head qd_le_list; /* List of gfs_quota_le log elements */ - - /* Summary of block alloc changes affecting this quota, in various - stages of logging & syncing changes to the special quota file */ - int64_t qd_change_new; /* New, not yet committed to in-core log*/ - int64_t qd_change_ic; /* Committed to in-core log */ - int64_t qd_change_od; /* Committed to on-disk log */ - int64_t qd_change_sync; /* Being synced to the in-place quota file */ - - struct gfs_quota_le qd_ondisk_ql; /* Log element for log dump */ - uint64_t qd_sync_gen; /* Sync-to-quota-file generation # */ - - /* Glock provides protection for quota, *and* provides - lock value block (LVB) communication, between nodes, of current - quota values. Shared lock -> LVB read. EX lock -> LVB write. */ - struct gfs_glock *qd_gl; /* glock for this quota */ - struct gfs_quota_lvb qd_qb; /* LVB (limit/warn/value) */ - - unsigned long qd_last_warn; /* Jiffies of last warning to user */ -}; - -/* - * Log Buffer descriptor structure. - * One for each block buffer recorded in the log. - * When beginning a new transaction, GFS pre-allocates a number of these, - * and puts them on transaction's tr_free_bufs list. - * Logged buffers are of two types: - * 1). Exact copies of buffers to be written to in-place location in FS. - * 2). Log-only buffers such as log headers and control blocks (e.g. tags). - * A gfs_log_buf is required for both types; the ones for log-only buffers - * contain NULL in lb_unlock, and get cleaned up after the log write. - * lb_bh is a "fake" buffer head that directs Linux block I/O to write the buf - * to the on-disk log location, rather than the on-disk in-place location. - * Used for both types. - * lb_unlock points to the "real" buffer head that directs Linux to write the - * buf to its regular on-disk in-place filesystem location. Once the commit - * to the on-disk log is finished, GFS unlocks the "real" buffer so it can be - * written to in-place block, or modified by another transaction. - * Used only for type 1). - */ -struct gfs_log_buf { - /* Link to one of the transaction structure's lists */ - struct list_head lb_list; /* Link to tr_free_bufs or tr_list */ - - struct buffer_head lb_bh; /* "Fake" bh; for the log block */ - struct buffer_head *lb_unlock; /* "Real" bh; for the in-place block */ -}; - -/* - * Transaction structure - * One for each transaction - * This coordinates the logging and flushing of written metadata. - */ - -#define TRF_LOG_DUMP (0x00000001) -#define TRF_DUMMY (0x00000002) - -struct gfs_trans { - - /* Link to various lists */ - struct list_head tr_list; /* Superblk's incore trans or AIL list*/ - - /* Initial creation stuff */ - - char *tr_file; /* Debug info: .c file creating trans */ - unsigned int tr_line; /* Debug info: codeline creating trans */ - - /* Reservations for on-disk space in journal. - Meta blocks are copies of in-place filesystem blocks. - Extra blocks are log-only (log header and control blocks) */ - unsigned int tr_mblks_asked; /* # of meta log blocks requested */ - unsigned int tr_eblks_asked; /* # of extra log blocks requested */ - unsigned int tr_seg_reserved; /* # of segments actually reserved */ - - struct gfs_holder *tr_t_gh; /* Glock holder for this transaction */ - - /* Stuff filled in during creation */ - - unsigned int tr_flags; /* TRF_... */ - struct list_head tr_elements; /* List of this trans' log elements */ - - /* Stuff modified during the commit */ - - /* When creating a new transaction, GFS pre-allocates as many of - these buffers and descriptor structures as it might need for - all loggable filesystem (meta)data, and log-control (log-only, not - going to filesystem in-place location) data going to on-disk log. - It keeps them on these "free" lists until they get used (and linked - into tr_bufs list, below) or "refunded" if not needed. */ - unsigned int tr_num_free_bufs; /* List of free gfs_log_buf structs */ - struct list_head tr_free_bufs; /* .. 1 for each log block */ - unsigned int tr_num_free_bmem; /* List of free fs-block-size buffers */ - struct list_head tr_free_bmem; /* .. for log-only (e.g. tag) blocks */ - - /* Logged transaction starts with a (first) log header at a segment - boundary, and fills contiguous blocks after that. Each segment - boundary block gets another log header. */ - uint64_t tr_log_head; /* The next log block # to fill */ - uint64_t tr_first_head; /* Trans' first log header's block # */ - - /* gfs_log_buf structs move from tr_free_bufs to here when being used */ - struct list_head tr_bufs; /* List of buffers going to the log */ - - /* Stuff that's part of the Active Items List (AIL) */ - - struct list_head tr_ail_bufs; /* List of buffers on AIL list */ - - /* # log elements of various types on tr_elements list */ - - unsigned int tr_num_gl; /* Glocks */ - unsigned int tr_num_buf; /* Buffers */ - unsigned int tr_num_iul; /* Unlinked inodes */ - unsigned int tr_num_ida; /* De-allocated inodes */ - unsigned int tr_num_q; /* Quotas */ -}; - -#define GFS_GLOCKD_DEFAULT (1) -#define GFS_GLOCKD_MAX (32) - -struct gfs_args { - char ar_lockproto[GFS_LOCKNAME_LEN]; /* The name of the Lock Protocol */ - char ar_locktable[GFS_LOCKNAME_LEN]; /* The name of the Lock Table */ - char ar_hostdata[GFS_LOCKNAME_LEN]; /* The host specific data */ - - /* - * GFS can invoke some flock and disk caching optimizations if it is - * not in a cluster, i.e. is a local filesystem. The chosen lock - * module tells GFS, at mount time, if it supports clustering. - * The nolock module is the only one that does not support clustering; - * it sets to TRUE the local_fs field in the struct lm_lockops. - * GFS can either optimize, or ignore the opportunity. - * The user controls behavior via the following mount options. - */ - int ar_ignore_local_fs; /* Don't optimize even if local_fs is TRUE */ - int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */ - int ar_localcaching; /* Local-style caching (dangerous on multihost) */ - int ar_oopses_ok; /* Allow oopses */ - - int ar_debug; /* Oops on errors instead of trying to be graceful */ - int ar_upgrade; /* Upgrade ondisk/multihost format */ - - unsigned int ar_num_glockd; /* # of glock cleanup daemons to run - (more daemons => faster cleanup) */ - int ar_posix_acls; /* Enable posix acls */ - int ar_suiddir; /* suiddir support */ - int ar_noquota; /* Turn off quota support */ -}; - -struct gfs_tune { - spinlock_t gt_spin; - - unsigned int gt_ilimit1; - unsigned int gt_ilimit1_tries; - unsigned int gt_ilimit1_min; - unsigned int gt_ilimit2; - unsigned int gt_ilimit2_tries; - unsigned int gt_ilimit2_min; - unsigned int gt_demote_secs; /* Cache retention for unheld glock */ - unsigned int gt_incore_log_blocks; - unsigned int gt_jindex_refresh_secs; /* Check for new journal index */ - unsigned int gt_depend_secs; - - /* How often various daemons run (seconds) */ - unsigned int gt_scand_secs; /* Find unused glocks and inodes */ - unsigned int gt_recoverd_secs; /* Recover journal of crashed node */ - unsigned int gt_logd_secs; /* Update log tail as AIL flushes */ - unsigned int gt_quotad_secs; /* Sync changes to quota file, clean*/ - unsigned int gt_inoded_secs; /* Toss unused inodes */ - unsigned int gt_glock_purge; /* Purge glock */ - - unsigned int gt_quota_simul_sync; /* Max # quotavals to sync at once */ - unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ - unsigned int gt_atime_quantum; /* Min secs between atime updates */ - unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ - unsigned int gt_quota_scale_num; /* Numerator */ - unsigned int gt_quota_scale_den; /* Denominator */ - unsigned int gt_quota_enforce; - unsigned int gt_quota_account; - unsigned int gt_new_files_jdata; - unsigned int gt_new_files_directio; - unsigned int gt_max_atomic_write; /* Split large writes into this size*/ - unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ - unsigned int gt_lockdump_size; - unsigned int gt_stall_secs; /* Detects trouble! */ - unsigned int gt_complain_secs; - unsigned int gt_reclaim_limit; /* Max # glocks in reclaim list */ - unsigned int gt_entries_per_readdir; - unsigned int gt_prefetch_secs; /* Usage window for prefetched glocks */ - unsigned int gt_statfs_slots; - unsigned int gt_max_mhc; /* Max # of meta headers in mhc cache */ - unsigned int gt_greedy_default; - unsigned int gt_greedy_quantum; - unsigned int gt_greedy_max; - unsigned int gt_rgrp_try_threshold; - unsigned int gt_statfs_fast; - unsigned int gt_seq_readahead; -}; - -/* - * One bucket of the filesystem's sd_gl_hash glock hash table. - * - * A gfs_glock links into a bucket's list via glock's gl_list member. - * - */ -struct gfs_gl_hash_bucket { - rwlock_t hb_lock; /* Protects list */ - struct list_head hb_list; /* List of glocks in this bucket */ -}; - -/* - * "Super Block" Data Structure - * One per mounted filesystem. - * This is the big instance structure that ties everything together for - * a given mounted filesystem. Each GFS mount has its own, supporting - * mounts of multiple GFS filesystems on each node. - * Pointer to this is usually seen as "sdp" throughout code. - * This is a very large structure, as structures go, in part because it - * contains arrays of hash buckets for various in-core caches. - */ - -#define SDF_JOURNAL_LIVE (0) /* Journaling is active (journal is writeable)*/ -#define SDF_SHUTDOWN (1) /* FS abnormaly shutdown */ - -/* Run (1) / stop (0) flags for various daemons */ -#define SDF_SCAND_RUN (2) /* Put unused glocks on reclaim queue */ -#define SDF_GLOCKD_RUN (3) /* Reclaim (dealloc) unused glocks */ -#define SDF_RECOVERD_RUN (4) /* Recover journal of a crashed node */ -#define SDF_LOGD_RUN (5) /* Update log tail after AIL flushed */ -#define SDF_QUOTAD_RUN (6) /* Sync quota changes to file, cleanup */ -#define SDF_INODED_RUN (7) /* Deallocate unlinked inodes */ - -/* (Re)mount options from Linux VFS */ -#define SDF_NOATIME (8) /* Don't change access time */ -#define SDF_ROFS (9) /* Read-only mode */ - -/* Journal log dump support */ -#define SDF_NEED_LOG_DUMP (10) /* Need to rewrite unlink and quota tags */ -#define SDF_FOUND_UL_DUMP (11) /* Recovery found unlinked tags */ -#define SDF_FOUND_Q_DUMP (12) /* Recovery found qutoa tags */ -#define SDF_IN_LOG_DUMP (13) /* Serializes log dumps */ - -/* Glock cache */ -#define GFS_GL_HASH_SHIFT (13) /* # hash buckets = 8K */ -#define GFS_GL_HASH_SIZE (1 << GFS_GL_HASH_SHIFT) -#define GFS_GL_HASH_MASK (GFS_GL_HASH_SIZE - 1) - -/* Meta header cache */ -#define GFS_MHC_HASH_SHIFT (10) /* # hash buckets = 1K */ -#define GFS_MHC_HASH_SIZE (1 << GFS_MHC_HASH_SHIFT) -#define GFS_MHC_HASH_MASK (GFS_MHC_HASH_SIZE - 1) - -/* Dependency cache */ -#define GFS_DEPEND_HASH_SHIFT (10) /* # hash buckets = 1K */ -#define GFS_DEPEND_HASH_SIZE (1 << GFS_DEPEND_HASH_SHIFT) -#define GFS_DEPEND_HASH_MASK (GFS_DEPEND_HASH_SIZE - 1) - -struct gfs_sbd { - struct gfs_sb sd_sb; /* GFS on-disk Super Block image */ - - struct super_block *sd_vfs; /* Linux VFS device independent sb */ - - /* readahead */ - struct backing_dev_info sd_dev_info; - spinlock_t sd_dev_info_spin; - - struct gfs_args sd_args; /* Mount arguments */ - unsigned long sd_flags; /* SDF_... see above */ - - struct gfs_tune sd_tune; /* Filesystem tuning structure */ - - /* statfs */ - struct inode *sd_statfs_inode; - spinlock_t sd_statfs_spin; - struct gfs_statfs_change_host sd_statfs_master; - struct gfs_statfs_change_host sd_statfs_local; - unsigned long sd_statfs_sync_time; - - /* Resource group stuff */ - - struct gfs_inode *sd_riinode; /* Resource Index (rindex) inode */ - uint64_t sd_riinode_vn; /* Resource Index version # (detects - whether new rgrps have been added) */ - - struct list_head sd_rglist; /* List of all resource groups, - on-disk order */ - struct semaphore sd_rindex_lock;/* Serializes RIndex rereads */ - struct list_head sd_rg_mru_list;/* List of all resource groups, - most-recently-used (MRU) order */ - spinlock_t sd_rg_mru_lock; /* Protect mru list */ - struct list_head sd_rg_recent; /* List of rgrps from which blocks - were recently allocated */ - spinlock_t sd_rg_recent_lock; /* Protect recent list */ - struct gfs_rgrpd *sd_rg_forward;/* Next rgrp from which to attempt - a block alloc */ - spinlock_t sd_rg_forward_lock; /* Protect forward pointer */ - - unsigned int sd_rgcount; /* Total # of resource groups */ - - /* Constants computed on mount */ - - /* "bb" == "basic block" == 512Byte sector */ - uint32_t sd_fsb2bb; /* # 512B basic blocks in a FS block */ - uint32_t sd_fsb2bb_shift; /* Shift sector # to the right by - this to get FileSystem block addr */ - uint32_t sd_diptrs; /* Max # of block pointers in a dinode */ - uint32_t sd_inptrs; /* Max # of block pointers in an indirect blk */ - uint32_t sd_jbsize; /* Payload size (bytes) of a journaled metadata - block (GFS journals all meta blocks) */ - uint32_t sd_hash_bsize; /* sizeof(exhash hash block) */ - uint32_t sd_hash_bsize_shift; - uint32_t sd_hash_ptrs; /* Number of points in a hash block */ - uint32_t sd_max_dirres; /* Max blocks needed to add a directory entry */ - uint32_t sd_max_height; /* Max height of a file's tree */ - uint64_t sd_heightsize[GFS_MAX_META_HEIGHT]; - uint32_t sd_max_jheight; /* Max height, journaled file's tree */ - uint64_t sd_jheightsize[GFS_MAX_META_HEIGHT]; - - /* Lock Stuff */ - - /* Glock cache (all glocks currently held by this node for this FS) */ - struct gfs_gl_hash_bucket sd_gl_hash[GFS_GL_HASH_SIZE]; - - /* Glock reclaim support for scand and glockd */ - struct list_head sd_reclaim_list; /* List of glocks to reclaim */ - spinlock_t sd_reclaim_lock; - wait_queue_head_t sd_reclaim_wchan; - atomic_t sd_reclaim_count; /* # glocks on reclaim list */ - - /* Lock module tells us if we're first-to-mount, - which journal to use, etc. */ - struct lm_lockstruct sd_lockstruct; /* Info provided by lock module */ - - /* Other caches */ - - /* Meta-header cache (incore copies of on-disk meta headers) */ - struct list_head sd_mhc[GFS_MHC_HASH_SIZE]; /* hash buckets */ - struct list_head sd_mhc_single; /* Non-hashed list of all MHCs */ - spinlock_t sd_mhc_lock; - atomic_t sd_mhc_count; /* # MHCs in cache */ - - /* Dependency cache */ - struct list_head sd_depend[GFS_DEPEND_HASH_SIZE]; /* Hash buckets */ - spinlock_t sd_depend_lock; - atomic_t sd_depend_count; /* # dependencies in cache */ - - /* LIVE inter-node lock indicates that FS is mounted on at least - one node */ - struct gfs_holder sd_live_gh; /* Glock holder for LIVE lock */ - - /* For quiescing the filesystem */ - struct gfs_holder sd_freeze_gh; - struct semaphore sd_freeze_lock; - unsigned int sd_freeze_count; - - /* Inode Stuff */ - - struct gfs_inode *sd_rooti; /* FS's root inode */ - - /* Only 1 node at a time may rename (e.g. mv) directory from - one directory to another. */ - struct gfs_glock *sd_rename_gl; /* Rename glock */ - - /* Daemon stuff */ - - /* Scan for glocks and inodes to toss from memory */ - struct task_struct *sd_scand_process; /* Scand places on reclaim list*/ - unsigned int sd_glockd_num; /* # of glockd procs to do reclaiming*/ - - /* Recover journal of a crashed node */ - struct task_struct *sd_recoverd_process; - - /* Update log tail as AIL gets flushed to in-place on-disk blocks */ - struct task_struct *sd_logd_process; - - /* Sync quota updates to disk, and clean up unused quota structs */ - struct task_struct *sd_quotad_process; - - /* Clean up unused inode structures */ - struct task_struct *sd_inoded_process; - - /* Support for starting/stopping daemons */ - struct semaphore sd_thread_lock; - struct completion sd_thread_completion; - - /* Log stuff */ - - /* Transaction lock protects the following from one another: - normal write transaction, journal replay (recovery), fs upgrade, - fs read-only => read/write and read/write => read-only conversions. - Also, acquiring the transaction lock in a state other than shared - causes all other machines in the cluster to sync out their dirty - data, mark their journal as being clean, and prevent any new FS - modifications from occuring (i.e. quiesces the FS). */ - struct gfs_glock *sd_trans_gl; /* Transaction glock structure */ - - struct gfs_inode *sd_jiinode; /* Journal index inode */ - uint64_t sd_jiinode_vn; /* Journal index version # (detects - if new journals have been added) */ - - unsigned int sd_journals; /* Number of journals in the FS */ - struct gfs_jindex *sd_jindex; /* Array of journal descriptors */ - struct semaphore sd_jindex_lock; - unsigned long sd_jindex_refresh_time; /* Poll for new journals (secs) */ - - struct gfs_jindex sd_jdesc; /* This machine's journal descriptor */ - struct gfs_holder sd_journal_gh; /* This machine's jrnl glock holder */ - - uint64_t sd_sequence; /* Assigned to xactions in order they commit */ - uint64_t sd_log_head; /* Block number of next journal write */ - uint64_t sd_log_wrap; - - spinlock_t sd_log_seg_lock; - unsigned int sd_log_seg_free; /* # of free segments in the log */ - unsigned int sd_log_seg_ail2; /* # of freeable segments in the log */ - struct list_head sd_log_seg_list; - wait_queue_head_t sd_log_seg_wait; - - /* "Active Items List" of transactions that have been flushed to - on-disk log, and are waiting for flush to in-place on-disk blocks */ - struct list_head sd_log_ail; /* "next" is head, "prev" is tail */ - - /* Transactions committed incore, but not yet flushed to on-disk log */ - struct list_head sd_log_incore; /* "Next" is newest, "prev" is oldest */ - unsigned int sd_log_buffers; /* # of buffers in the incore log */ - - struct rw_semaphore sd_log_lock; /* Lock for access to log values */ - struct semaphore sd_log_flush_lock; /* Lock for function - log_flush_internal */ - - uint64_t sd_log_dump_last; - uint64_t sd_log_dump_last_wrap; - - /* - * Unlinked inode crap. - * List includes newly created, not-yet-linked inodes, - * as well as inodes that have been unlinked and are waiting - * to be de-allocated. - */ - struct list_head sd_unlinked_list; /* List of unlinked inodes */ - spinlock_t sd_unlinked_lock; /* Protects list and members */ - - atomic_t sd_unlinked_ic_count; - atomic_t sd_unlinked_od_count; - - /* Quota crap */ - - struct list_head sd_quota_list; /* List of all gfs_quota_data structs */ - spinlock_t sd_quota_lock; - - atomic_t sd_quota_count; /* # quotas on sd_quota_list */ - atomic_t sd_quota_od_count; /* # quotas waiting for sync to - special on-disk quota file */ - - struct gfs_inode *sd_qinode; /* Special on-disk quota file */ - - uint64_t sd_quota_sync_gen; /* Generation, incr when sync to file */ - unsigned long sd_quota_sync_time; /* Jiffies, last sync to quota file */ - - /* License crap */ - - struct gfs_inode *sd_linode; /* Special on-disk license file */ - - /* Recovery stuff */ - - /* Lock module tells GFS, via callback, when a journal needs recovery. - It stays on this list until recovery daemon performs recovery. */ - struct list_head sd_dirty_j; /* List of dirty journals */ - spinlock_t sd_dirty_j_lock; /* Protects list */ - - /* Statistics for 3 possible recovery actions for each buffer in log, - determined by comparing generation #s of logged block and - in-place block. Scope of stats is for one journal. */ - unsigned int sd_recovery_replays; /* newer than in-place; copy it */ - unsigned int sd_recovery_skips; /* older than in-place; ignore it */ - unsigned int sd_recovery_sames; /* same as in-place; ignore it */ - - /* Counters */ - - /* current quantities of various things */ - atomic_t sd_glock_count; /* # of gfs_glock structs alloc'd */ - atomic_t sd_glock_held_count; /* # of glocks locked by this node */ - atomic_t sd_inode_count; /* # of gfs_inode structs alloc'd */ - atomic_t sd_bufdata_count; /* # of gfs_bufdata structs alloc'd */ - - atomic_t sd_fh2dentry_misses; /* total # get_dentry misses */ - atomic_t sd_reclaimed; /* total # glocks reclaimed since mount */ - - /* total lock-related calls handled since mount */ - atomic_t sd_glock_nq_calls; - atomic_t sd_glock_dq_calls; - atomic_t sd_glock_prefetch_calls; - atomic_t sd_lm_lock_calls; - atomic_t sd_lm_unlock_calls; - atomic_t sd_lm_callbacks; - - atomic_t sd_lm_outstanding; - atomic_t sd_bio_reads; - atomic_t sd_bio_writes; - atomic_t sd_bio_outstanding; - - /* total calls from Linux VFS handled since mount */ - atomic_t sd_ops_address; - atomic_t sd_ops_dentry; - atomic_t sd_ops_export; - atomic_t sd_ops_file; - atomic_t sd_ops_inode; - atomic_t sd_ops_super; - atomic_t sd_ops_vm; - - char sd_fsname[256]; - - /* Debugging crud */ - - unsigned long sd_last_warning; - - spinlock_t sd_ail_lock; - struct list_head sd_recovery_bufs; - - struct list_head sd_list; -}; - -#endif /* __INCORE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/inode.c b/gfs-kernel/src/gfs/inode.c deleted file mode 100644 index bab613b..0000000 --- a/gfs-kernel/src/gfs/inode.c +++ /dev/null @@ -1,2234 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/posix_acl.h> - -#include "gfs.h" -#include "acl.h" -#include "bmap.h" -#include "dio.h" -#include "dir.h" -#include "eattr.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "log.h" -#include "ops_address.h" -#include "ops_file.h" -#include "ops_inode.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" -#include "unlinked.h" - -/** - * inode_attr_in - Copy attributes from the dinode into the VFS inode - * @ip: The GFS inode (with embedded disk inode data) - * @inode: The Linux VFS inode - * - */ - -static void -inode_attr_in(struct gfs_inode *ip, struct inode *inode) -{ - unsigned int mode; - - inode->i_ino = ip->i_num.no_formal_ino; - - switch (ip->i_di.di_type) { - case GFS_FILE_REG: - mode = S_IFREG; - inode->i_rdev = 0; - break; - case GFS_FILE_DIR: - mode = S_IFDIR; - inode->i_rdev = 0; - break; - case GFS_FILE_LNK: - mode = S_IFLNK; - inode->i_rdev = 0; - break; - case GFS_FILE_BLK: - mode = S_IFBLK; - inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor); - break; - case GFS_FILE_CHR: - mode = S_IFCHR; - inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor); - break; - case GFS_FILE_FIFO: - mode = S_IFIFO; - inode->i_rdev = 0; - break; - case GFS_FILE_SOCK: - mode = S_IFSOCK; - inode->i_rdev = 0; - break; - default: - if (gfs_consist_inode(ip)) - printk("GFS: fsid=%s: type = %u\n", - ip->i_sbd->sd_fsname, ip->i_di.di_type); - return; - }; - - inode->i_mode = mode | (ip->i_di.di_mode & S_IALLUGO); - inode->i_nlink = ip->i_di.di_nlink; - inode->i_uid = ip->i_di.di_uid; - inode->i_gid = ip->i_di.di_gid; - i_size_write(inode, ip->i_di.di_size); - inode->i_atime.tv_sec = ip->i_di.di_atime; - inode->i_mtime.tv_sec = ip->i_di.di_mtime; - inode->i_ctime.tv_sec = ip->i_di.di_ctime; - inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0; - inode->i_blksize = PAGE_SIZE; - inode->i_blocks = ip->i_di.di_blocks << - (ip->i_sbd->sd_sb.sb_bsize_shift - GFS_BASIC_BLOCK_SHIFT); - inode->i_generation = ip->i_di.di_header.mh_incarn; - - if (ip->i_di.di_flags & GFS_DIF_IMMUTABLE) - inode->i_flags |= S_IMMUTABLE; - else - inode->i_flags &= ~S_IMMUTABLE; - - if (ip->i_di.di_flags & GFS_DIF_APPENDONLY) - inode->i_flags |= S_APPEND; - else - inode->i_flags &= ~S_APPEND; -} - -/** - * gfs_inode_attr_in - Copy attributes from the dinode into the VFS inode - * @ip: The GFS inode (with embedded disk inode data) - * - */ - -void -gfs_inode_attr_in(struct gfs_inode *ip) -{ - struct inode *inode; - - inode = gfs_iget(ip, NO_CREATE); - if (inode) { - inode_attr_in(ip, inode); - iput(inode); - } - -} - -/** - * gfs_inode_attr_out - Copy attributes from VFS inode into the dinode - * @ip: The GFS inode - * - * Only copy out the attributes that we want the VFS layer - * to be able to modify. - */ - -void -gfs_inode_attr_out(struct gfs_inode *ip) -{ - struct inode *inode = ip->i_vnode; - - ip->i_di.di_mode = inode->i_mode & S_IALLUGO; - ip->i_di.di_uid = inode->i_uid; - ip->i_di.di_gid = inode->i_gid; - ip->i_di.di_atime = inode->i_atime.tv_sec; - ip->i_di.di_mtime = inode->i_mtime.tv_sec; - ip->i_di.di_ctime = inode->i_ctime.tv_sec; -} - -/** - * gfs_iget - Get/Create a struct inode for a struct gfs_inode - * @ip: the struct gfs_inode to get the struct inode for - * @create: CREATE -- create a new struct inode if one does not already exist - * NO_CREATE -- return NULL if inode doesn't exist - * - * Returns: A VFS inode, or NULL if NO_CREATE and none in existance - * - * If this function creates a new inode, it: - * Copies fields from the GFS on-disk (d)inode to the VFS inode - * Attaches the appropriate ops vectors to the VFS inode and address_space - * Attaches the VFS inode to the gfs_inode - * Inserts the new inode in the VFS inode hash, while avoiding races - */ - -struct inode * -gfs_iget(struct gfs_inode *ip, int create) -{ - struct inode *inode = NULL, *tmp; - - spin_lock(&ip->i_spin); - if (ip->i_vnode) - inode = igrab(ip->i_vnode); - spin_unlock(&ip->i_spin); - - if (inode || !create) - return inode; - - tmp = new_inode(ip->i_sbd->sd_vfs); - if (!tmp) - return NULL; - - inode_attr_in(ip, tmp); - - /* Attach GFS-specific ops vectors */ - if (ip->i_di.di_type == GFS_FILE_REG) { - tmp->i_op = &gfs_file_iops; - tmp->i_fop = &gfs_file_fops; - memcpy(&ip->gfs_file_aops, &gfs_file_aops, - sizeof(struct address_space_operations)); - tmp->i_mapping->a_ops = &ip->gfs_file_aops; - } else if (ip->i_di.di_type == GFS_FILE_DIR) { - tmp->i_op = &gfs_dir_iops; - tmp->i_fop = &gfs_dir_fops; - } else if (ip->i_di.di_type == GFS_FILE_LNK) { - tmp->i_op = &gfs_symlink_iops; - } else { - tmp->i_op = &gfs_dev_iops; - init_special_inode(tmp, tmp->i_mode, tmp->i_rdev); - } - - vn2ip(tmp) = NULL; - - /* Did another process successfully create an inode while we were - preparing this (tmp) one? If so, we can use that other one, and - trash the one we were preparing. - The other process might not be done inserting the inode in the - VFS hash table. If so, we need to wait until it is done, then - we can use it. */ - for (;;) { - spin_lock(&ip->i_spin); - if (!ip->i_vnode) - break; - inode = igrab(ip->i_vnode); - spin_unlock(&ip->i_spin); - - if (inode) { - iput(tmp); - return inode; - } - yield(); - } - - inode = tmp; - - gfs_inode_hold(ip); - ip->i_vnode = inode; - vn2ip(inode) = ip; - - spin_unlock(&ip->i_spin); - - insert_inode_hash(inode); - - return inode; -} - -/** - * gfs_copyin_dinode - Refresh the incore copy of the dinode - * @ip: The GFS inode - * - * Returns: errno - */ - -int -gfs_copyin_dinode(struct gfs_inode *ip) -{ - struct buffer_head *dibh; - int error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - return error; - - if (gfs_metatype_check(ip->i_sbd, dibh, GFS_METATYPE_DI)) { - brelse(dibh); - return -EIO; - } - - gfs_dinode_in(&ip->i_di, dibh->b_data); - brelse(dibh); - - if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - return -EIO; - } - - /* Handle a moved inode (not implemented yet) */ - if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - return -EIO; - } - - ip->i_vn = ip->i_gl->gl_vn; - - return 0; -} - -/** - * inode_create - create a struct gfs_inode, acquire Inode-Open (iopen) glock, - * read dinode from disk - * @i_gl: The (already held) glock covering the inode - * @inum: The inode number - * @io_gl: the iopen glock to acquire/hold (using holder in new gfs_inode) - * @io_state: the state the iopen glock should be acquired in - * @ipp: pointer to put the returned inode in - * - * Returns: errno - */ - -static int -inode_create(struct gfs_glock *i_gl, struct gfs_inum *inum, - struct gfs_glock *io_gl, unsigned int io_state, - struct gfs_inode **ipp) -{ - struct gfs_sbd *sdp = i_gl->gl_sbd; - struct gfs_inode *ip; - int error = 0; - - RETRY_MALLOC(ip = kmem_cache_alloc(gfs_inode_cachep, GFP_KERNEL), ip); - memset(ip, 0, sizeof(struct gfs_inode)); - - ip->i_num = *inum; - - atomic_set(&ip->i_count, 1); - - ip->i_gl = i_gl; - ip->i_sbd = sdp; - - spin_lock_init(&ip->i_spin); - init_rwsem(&ip->i_rw_mutex); - - ip->i_greedy = gfs_tune_get(sdp, gt_greedy_default); - - /* Lock the iopen glock (may be recursive) */ - error = gfs_glock_nq_init(io_gl, - io_state, GL_LOCAL_EXCL | GL_EXACT, - &ip->i_iopen_gh); - if (error) - goto fail; - - ip->i_iopen_gh.gh_owner = NULL; - - /* Assign the inode's glock as this iopen glock's protected object */ - spin_lock(&io_gl->gl_spin); - gfs_glock_hold(i_gl); - gl2gl(io_gl) = i_gl; - spin_unlock(&io_gl->gl_spin); - - /* Read dinode from disk */ - error = gfs_copyin_dinode(ip); - if (error) - goto fail_iopen; - - gfs_glock_hold(i_gl); - gl2ip(i_gl) = ip; - - /* initialize stat counter and timestamp */ - ip->i_dir_stats = 0; - do_gettimeofday(&ip->i_dir_stat_st); - - atomic_inc(&sdp->sd_inode_count); - - *ipp = ip; - - return 0; - - fail_iopen: - spin_lock(&io_gl->gl_spin); - gl2gl(io_gl) = NULL; - gfs_glock_put(i_gl); - spin_unlock(&io_gl->gl_spin); - - gfs_glock_dq_uninit(&ip->i_iopen_gh); - - fail: - gfs_flush_meta_cache(ip); - kmem_cache_free(gfs_inode_cachep, ip); - *ipp = NULL; - - return error; -} - -/** - * gfs_inode_get - Get an inode given its number - * @i_gl: The glock covering the inode - * @inum: The inode number - * @create: Flag to say if we are allowed to create a new struct gfs_inode - * @ipp: pointer to put the returned inode in - * - * Returns: errno - * - * If creating a new gfs_inode structure, reads dinode from disk. - */ - -int -gfs_inode_get(struct gfs_glock *i_gl, struct gfs_inum *inum, int create, - struct gfs_inode **ipp) -{ - struct gfs_glock *io_gl; - int error = 0; - - *ipp = gl2ip(i_gl); - if (*ipp) { - atomic_inc(&(*ipp)->i_count); - gfs_assert_warn(i_gl->gl_sbd, - (*ipp)->i_num.no_formal_ino == - inum->no_formal_ino); - } else if (create) { - error = gfs_glock_get(i_gl->gl_sbd, - inum->no_addr, &gfs_iopen_glops, - CREATE, &io_gl); - if (!error) { - error = inode_create(i_gl, inum, io_gl, - LM_ST_SHARED, ipp); - gfs_glock_put(io_gl); - } - } - - return error; -} - -/** - * gfs_inode_hold - hold a struct gfs_inode structure - * @ip: The GFS inode - * - */ - -void -gfs_inode_hold(struct gfs_inode *ip) -{ - gfs_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0,); - atomic_inc(&ip->i_count); -} - -/** - * gfs_inode_put - put a struct gfs_inode structure - * @ip: The GFS inode - * - */ - -void -gfs_inode_put(struct gfs_inode *ip) -{ - gfs_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0,); - atomic_dec(&ip->i_count); -} - -/** - * gfs_inode_destroy - Destroy a GFS inode structure with no references on it - * @ip: The GFS inode - * - * Also, unhold the iopen glock and release indirect addressing buffers. - * This function must be called with a glocks held on the inode and - * the associated iopen. - * - */ - -void -gfs_inode_destroy(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_glock *io_gl = ip->i_iopen_gh.gh_gl; - struct gfs_glock *i_gl = ip->i_gl; - - gfs_assert_warn(sdp, !atomic_read(&ip->i_count)); - gfs_assert(sdp, gl2gl(io_gl) == i_gl,); - - /* Unhold the iopen glock */ - spin_lock(&io_gl->gl_spin); - gl2gl(io_gl) = NULL; - gfs_glock_put(i_gl); - spin_unlock(&io_gl->gl_spin); - - gfs_glock_dq_uninit(&ip->i_iopen_gh); - - /* Release indirect addressing buffers, destroy the GFS inode struct */ - gfs_flush_meta_cache(ip); - kmem_cache_free(gfs_inode_cachep, ip); - - gl2ip(i_gl) = NULL; - gfs_glock_put(i_gl); - - atomic_dec(&sdp->sd_inode_count); -} - -/** - * dinode_mark_unused - Set UNUSED flag in on-disk dinode - * @ip: - * - * Also: - * -- Increment incarnation number, to indicate that it no longer - * represents the old inode. - * -- Update change time (ctime) - * - * Returns: errno - */ - -static int -dinode_mark_unused(struct gfs_inode *ip) -{ - struct buffer_head *dibh; - struct gfs_dinode *di; - uint32_t incarn; - uint64_t ctime; - uint32_t flags; - int error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - return error; - - di = (struct gfs_dinode *)dibh->b_data; - - gfs_trans_add_bh(ip->i_gl, dibh); - - incarn = gfs32_to_cpu(di->di_header.mh_incarn) + 1; - di->di_header.mh_incarn = cpu_to_gfs32(incarn); - - ctime = get_seconds(); - di->di_ctime = cpu_to_gfs64(ctime); - - flags = (gfs32_to_cpu(di->di_flags)) | GFS_DIF_UNUSED; - di->di_flags = cpu_to_gfs32(flags); - - brelse(dibh); - - return 0; -} - -/** - * dinode_dealloc - Put deallocate a dinode - * @ip: The GFS inode - * - * Returns: errno - */ - -static int -dinode_dealloc(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al; - struct gfs_rgrpd *rgd; - int error; - - if (ip->i_di.di_blocks != 1) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - return -EIO; - } - - al = gfs_alloc_get(ip); - - error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out; - - error = gfs_rindex_hold(sdp, &al->al_ri_gh); - if (error) - goto out_qs; - - rgd = gfs_blk2rgrpd(sdp, ip->i_num.no_addr); - if (!rgd) { - gfs_consist_inode(ip); - error = -EIO; - goto out_rindex_relse; - } - - error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &al->al_rgd_gh); - if (error) - goto out_rindex_relse; - - /* Trans may require: - One block for the RG header. - One block for the dinode bit. - One block for the dinode. - We also need a block for the unlinked change. - One block for the quota change. */ - - error = gfs_trans_begin(sdp, 3, 2); - if (error) - goto out_rg_gunlock; - - /* Set the UNUSED flag in the on-disk dinode block, increment incarn */ - error = dinode_mark_unused(ip); - if (error) - goto out_end_trans; - - /* De-allocate on-disk dinode block to FREEMETA */ - gfs_difree(rgd, ip); - - gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, &ip->i_num); - clear_bit(GLF_STICKY, &ip->i_gl->gl_flags); - - out_end_trans: - gfs_trans_end(sdp); - - out_rg_gunlock: - gfs_glock_dq_uninit(&al->al_rgd_gh); - - out_rindex_relse: - gfs_glock_dq_uninit(&al->al_ri_gh); - - out_qs: - gfs_quota_unhold_m(ip); - - out: - gfs_alloc_put(ip); - - return error; -} - -/** - * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode) - * @sdp: the filesystem - * @inum: the inode number to deallocate - * @io_gh: a holder for the iopen glock for this inode - * - * De-allocates all on-disk blocks, data and metadata, associated with an inode. - * All metadata blocks become GFS_BLKST_FREEMETA. - * All data blocks become GFS_BLKST_FREE. - * Also de-allocates incore gfs_inode structure. - * - * Returns: errno - */ - -static int -inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum, - struct gfs_holder *io_gh) -{ - struct gfs_inode *ip; - struct gfs_holder i_gh; - int error; - - /* Lock the inode as we blow it away */ - error = gfs_glock_nq_num(sdp, - inum->no_formal_ino, &gfs_inode_glops, - LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - return error; - - /* We reacquire the iopen lock here to avoid a race with the NFS server - calling gfs_read_inode() with the inode number of a inode we're in - the process of deallocating. And we can't keep our hold on the lock - from inode_dealloc_init() for deadlock reasons. We do, however, - overlap this iopen lock with the one to be acquired EX within - inode_create(), below (recursive EX locks will be granted to same - holder process, i.e. this process). */ - - gfs_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY, io_gh); - error = gfs_glock_nq(io_gh); - switch (error) { - case 0: - break; - case GLR_TRYFAILED: - error = 0; - goto fail; - default: - goto fail; - } - - gfs_assert_warn(sdp, !gl2ip(i_gh.gh_gl)); - error = inode_create(i_gh.gh_gl, inum, io_gh->gh_gl, LM_ST_EXCLUSIVE, - &ip); - - gfs_glock_dq(io_gh); - - if (error) - goto fail; - - /* Verify disk (d)inode, gfs inode, and VFS (v)inode are unused */ - if (ip->i_di.di_nlink) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - error = -EIO; - goto fail_iput; - } - gfs_assert_warn(sdp, atomic_read(&ip->i_count) == 1); - gfs_assert_warn(sdp, !ip->i_vnode); - - /* Free all on-disk directory leaves (if any) to FREEMETA state */ - if (ip->i_di.di_type == GFS_FILE_DIR && - (ip->i_di.di_flags & GFS_DIF_EXHASH)) { - error = gfs_dir_exhash_free(ip); - if (error) - goto fail_iput; - } - - /* Free all on-disk extended attribute blocks to FREEMETA state */ - if (ip->i_di.di_eattr) { - error = gfs_ea_dealloc(ip); - if (error) - goto fail_iput; - } - - /* Free all data blocks to FREE state, and meta blocks to FREEMETA */ - error = gfs_shrink(ip, 0, NULL); - if (error) - goto fail_iput; - - /* Set UNUSED flag and increment incarn # in on-disk dinode block, - and de-alloc the block to FREEMETA */ - error = dinode_dealloc(ip); - if (error) - goto fail_iput; - - /* Free the GFS inode structure, unhold iopen and inode glocks */ - gfs_inode_put(ip); - gfs_inode_destroy(ip); - - gfs_glock_dq_uninit(&i_gh); - - return 0; - - fail_iput: - gfs_inode_put(ip); - gfs_inode_destroy(ip); - - fail: - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * inode_dealloc_init - Try to deallocate an initialized on-disk inode (dinode) - * and all of its associated data and meta blocks - * @sdp: the filesystem - * - * Returns: 0 on success, -errno on error, 1 on busy (inode open) - */ - -static int -inode_dealloc_init(struct gfs_sbd *sdp, struct gfs_inum *inum) -{ - struct gfs_holder io_gh; - int error = 0; - - /* If not busy (on this node), de-alloc GFS incore inode, releasing - any indirect addressing buffers, and unholding iopen glock */ - gfs_try_toss_inode(sdp, inum); - - /* Does another process (cluster-wide) have this inode open? */ - error = gfs_glock_nq_num(sdp, - inum->no_addr, &gfs_iopen_glops, - LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &io_gh); - switch (error) { - case 0: - break; - case GLR_TRYFAILED: - return 1; - default: - return error; - } - - /* Unlock here to prevent deadlock */ - gfs_glock_dq(&io_gh); - - /* No other process in the entire cluster has this inode open; - we can remove it and all of its associated blocks from disk */ - error = inode_dealloc(sdp, inum, &io_gh); - gfs_holder_uninit(&io_gh); - - return error; -} - -/** - * inode_dealloc_uninit - dealloc an uninitialized on-disk inode (dinode) block - * @sdp: the filesystem - * - * Create a transaction to change dinode block's alloc state to FREEMETA - * - * Returns: 0 on success, -errno on error, 1 on busy - */ - -static int -inode_dealloc_uninit(struct gfs_sbd *sdp, struct gfs_inum *inum) -{ - struct gfs_rgrpd *rgd; - struct gfs_holder ri_gh, rgd_gh; - int error; - - error = gfs_rindex_hold(sdp, &ri_gh); - if (error) - return error; - - rgd = gfs_blk2rgrpd(sdp, inum->no_addr); - if (!rgd) { - gfs_consist(sdp); - error = -EIO; - goto fail; - } - - error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh); - if (error) - goto fail; - - /* Trans may require: - One block for the RG header. - One block for the dinode bit. - We also need a block for the unlinked change. */ - - error = gfs_trans_begin(sdp, 2, 1); - if (error) - goto fail_gunlock; - - gfs_difree_uninit(rgd, inum->no_addr); - gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, inum); - - gfs_trans_end(sdp); - - gfs_glock_dq_uninit(&rgd_gh); - gfs_glock_dq_uninit(&ri_gh); - - return 0; - - fail_gunlock: - gfs_glock_dq_uninit(&rgd_gh); - - fail: - gfs_glock_dq_uninit(&ri_gh); - - return error; -} - -/** - * gfs_inode_dealloc - Grab an unlinked inode off the list and try to free it. - * @sdp: the filesystem - * - * Returns: 0 on success, -errno on error, 1 on busy - */ - -int -gfs_inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum) -{ - if (inum->no_formal_ino) - return inode_dealloc_init(sdp, inum); - else - return inode_dealloc_uninit(sdp, inum); -} - -/** - * gfs_change_nlink - Change nlink count on inode - * @ip: The GFS inode - * @diff: The change in the nlink count required - * - * Returns: errno - */ - -int -gfs_change_nlink(struct gfs_inode *ip, int diff) -{ - struct buffer_head *dibh; - uint32_t nlink; - int error; - - nlink = ip->i_di.di_nlink + diff; - - /* Tricky. If we are reducing the nlink count, - but the new value ends up being bigger than the - old one, we must have underflowed. */ - if (diff < 0 && nlink > ip->i_di.di_nlink) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - return -EIO; - } - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - return error; - - ip->i_di.di_nlink = nlink; - ip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - return 0; -} - -/** - * gfs_lookupi - Look up a filename in a directory and return its inode - * @d_gh: An initialized holder for the directory glock - * @name: The name of the inode to look for - * @is_root: If TRUE, ignore the caller's permissions - * @i_gh: An uninitialized holder for the new inode glock - * - * There will always be a vnode (Linux VFS inode) for the d_gh inode unless - * @is_root is true. - * - * Returns: errno - */ - -int -gfs_lookupi(struct gfs_holder *d_gh, struct qstr *name, - int is_root, struct gfs_holder *i_gh) -{ - struct gfs_inode *dip = gl2ip(d_gh->gh_gl); - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_glock *gl; - struct gfs_inode *ip; - struct gfs_inum inum, inum2; - unsigned int type; - int error; - - i_gh->gh_gl = NULL; - - if (!name->len || name->len > GFS_FNAMESIZE) - return -ENAMETOOLONG; - - if (gfs_filecmp(name, ".", 1) || - (gfs_filecmp(name, "..", 2) && dip == sdp->sd_rooti)) { - gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); - error = gfs_glock_nq(d_gh); - if (!error) { - error = gfs_glock_nq_init(dip->i_gl, - LM_ST_SHARED, 0, - i_gh); - if (error) { - gfs_glock_dq(d_gh); - return error; - } - gfs_inode_hold(dip); - } - return error; - } - - if (gfs_assert_warn(sdp, !gfs_glock_is_locked_by_me(d_gh->gh_gl))) - return -EINVAL; - - gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); - error = gfs_glock_nq(d_gh); - if (error) - return error; - - if (!is_root) { - error = permission(dip->i_vnode, MAY_EXEC, NULL); - if (error) { - gfs_glock_dq(d_gh); - return error; - } - } - - error = gfs_dir_search(dip, name, &inum, &type); - if (error) { - gfs_glock_dq(d_gh); - if (error == -ENOENT) - error = 0; - return error; - } - - restart: - error = gfs_glock_get(sdp, inum.no_formal_ino, &gfs_inode_glops, - CREATE, &gl); - if (error) { - gfs_glock_dq(d_gh); - return error; - } - - /* Acquire the second lock */ - - if (gl->gl_name.ln_number < dip->i_gl->gl_name.ln_number) { - gfs_glock_dq(d_gh); - - error = gfs_glock_nq_init(gl, LM_ST_SHARED, - LM_FLAG_ANY | GL_LOCAL_EXCL, - i_gh); - if (error) - goto out; - - gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); - error = gfs_glock_nq(d_gh); - if (error) { - gfs_glock_dq_uninit(i_gh); - goto out; - } - - if (!is_root) { - error = permission(dip->i_vnode, MAY_EXEC, NULL); - if (error) { - gfs_glock_dq(d_gh); - gfs_glock_dq_uninit(i_gh); - goto out; - } - } - - error = gfs_dir_search(dip, name, &inum2, &type); - if (error) { - gfs_glock_dq(d_gh); - gfs_glock_dq_uninit(i_gh); - if (error == -ENOENT) - error = 0; - goto out; - } - - if (!gfs_inum_equal(&inum, &inum2)) { - gfs_glock_dq_uninit(i_gh); - gfs_glock_put(gl); - inum = inum2; - goto restart; - } - } else { - error = gfs_glock_nq_init(gl, LM_ST_SHARED, - LM_FLAG_ANY | GL_LOCAL_EXCL, - i_gh); - if (error) { - gfs_glock_dq(d_gh); - goto out; - } - } - - error = gfs_inode_get(gl, &inum, CREATE, &ip); - if (error) { - gfs_glock_dq(d_gh); - gfs_glock_dq_uninit(i_gh); - } else if (ip->i_di.di_type != type) { - gfs_consist_inode(dip); - gfs_inode_put(ip); - gfs_glock_dq(d_gh); - gfs_glock_dq_uninit(i_gh); - error = -EIO; - } - - out: - gfs_glock_put(gl); - - return error; -} - -/** - * create_ok - OK to create a new on-disk inode here? - * @dip: Directory in which dinode is to be created - * @name: Name of new dinode - * @type: GFS_FILE_XXX (regular file, dir, etc.) - * - * Returns: errno - */ - -static int -create_ok(struct gfs_inode *dip, struct qstr *name, unsigned int type) -{ - int error; - - error = permission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL); - if (error) - return error; - - /* Don't create entries in an unlinked directory */ - - if (!dip->i_di.di_nlink) - return -EPERM; - - error = gfs_dir_search(dip, name, NULL, NULL); - switch (error) { - case -ENOENT: - error = 0; - break; - case 0: - return -EEXIST; - default: - return error; - } - - if (dip->i_di.di_entries == (uint32_t)-1) - return -EFBIG; - if (type == GFS_FILE_DIR && dip->i_di.di_nlink == (uint32_t)-1) - return -EMLINK; - - return 0; -} - -/** - * dinode_alloc - Create an on-disk inode - * @dip: Directory in which to create the dinode - * @ul: - * - * Since this dinode is not yet linked, we also create an unlinked inode - * descriptor. - * - * Returns: errno - */ - -static int -dinode_alloc(struct gfs_inode *dip, struct gfs_unlinked **ul) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_alloc *al; - struct gfs_inum inum; - int error; - - /* Create in-place allocation structure, reserve 1 dinode */ - al = gfs_alloc_get(dip); - al->al_requested_di = 1; - error = gfs_inplace_reserve(dip); - if (error) - goto out; - - error = gfs_trans_begin(sdp, al->al_rgd->rd_ri.ri_length, 1); - if (error) - goto out_inplace; - - inum.no_formal_ino = 0; - error = gfs_dialloc(dip, &inum.no_addr); - if (error) - goto out_end_trans; - - *ul = gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &inum); - gfs_unlinked_lock(sdp, *ul); - - gfs_trans_add_gl(dip->i_gl); - - out_end_trans: - gfs_trans_end(sdp); - - out_inplace: - gfs_inplace_release(dip); - - out: - gfs_alloc_put(dip); - - return error; -} - -/** - * pick_formal_ino - Pick a formal inode number for a given inode - * @sdp: the filesystem - * @inum: the inode number structure - * - */ - -static void -pick_formal_ino(struct gfs_sbd *sdp, struct gfs_inum *inum) -{ - /* This won't always be true */ - inum->no_formal_ino = inum->no_addr; -} - -/** - * make_dinode - Fill in a new dinode structure - * @dip: the directory this inode is being created in - * @gl: The glock covering the new inode - * @inum: the inode number - * @type: the file type - * @mode: the file permissions - * @uid: - * @gid: - * - */ - -static int -make_dinode(struct gfs_inode *dip, - struct gfs_glock *gl, struct gfs_inum *inum, - unsigned int type, unsigned int mode, - unsigned int uid, unsigned int gid) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_dinode di; - struct buffer_head *dibh; - struct gfs_rgrpd *rgd; - int error; - - error = gfs_dread(gl, inum->no_addr, - DIO_NEW | DIO_START | DIO_WAIT, - &dibh); - if (error) - return error; - - gfs_trans_add_bh(gl, dibh); - gfs_metatype_set(dibh, GFS_METATYPE_DI, GFS_FORMAT_DI); - gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); - - memset(&di, 0, sizeof(struct gfs_dinode)); - - gfs_meta_header_in(&di.di_header, dibh->b_data); - - di.di_num = *inum; - - di.di_mode = mode & S_IALLUGO; - di.di_uid = uid; - di.di_gid = gid; - di.di_nlink = 1; - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = get_seconds(); - - rgd = gfs_blk2rgrpd(sdp, inum->no_addr); - if (!rgd) { - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: block = %"PRIu64"\n", - sdp->sd_fsname, inum->no_addr); - brelse(dibh); - return -EIO; - } - - di.di_rgrp = rgd->rd_ri.ri_addr; - di.di_goal_rgrp = di.di_rgrp; - di.di_goal_dblk = di.di_goal_mblk = inum->no_addr - rgd->rd_ri.ri_data1; - - if (type == GFS_FILE_REG) { - if ((dip->i_di.di_flags & GFS_DIF_INHERIT_JDATA) || - gfs_tune_get(sdp, gt_new_files_jdata)) - di.di_flags |= GFS_DIF_JDATA; - if ((dip->i_di.di_flags & GFS_DIF_INHERIT_DIRECTIO) || - gfs_tune_get(sdp, gt_new_files_directio)) - di.di_flags |= GFS_DIF_DIRECTIO; - } else if (type == GFS_FILE_DIR) { - di.di_flags |= (dip->i_di.di_flags & GFS_DIF_INHERIT_DIRECTIO); - di.di_flags |= (dip->i_di.di_flags & GFS_DIF_INHERIT_JDATA); - } - - di.di_type = type; - - gfs_dinode_out(&di, dibh->b_data); - brelse(dibh); - - return 0; -} - -/** - * inode_init_and_link - - * @dip: - * @name: - * @inum: - * @gl: - * @type: - * @mode: - * - * Returns: errno - */ - -static int -inode_init_and_link(struct gfs_inode *dip, struct qstr *name, - struct gfs_inum *inum, struct gfs_glock *gl, - unsigned int type, mode_t mode) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_alloc *al; - struct gfs_inode *ip; - unsigned int uid, gid; - int alloc_required; - void *acl_a_data = NULL, *acl_d_data = NULL; - unsigned int acl_size = 0, acl_blocks = 0; - int error; - - if (sdp->sd_args.ar_suiddir && - (dip->i_di.di_mode & S_ISUID) && - dip->i_di.di_uid) { - if (type == GFS_FILE_DIR) - mode |= S_ISUID; - else if (dip->i_di.di_uid != current->fsuid) - mode &= ~07111; - uid = dip->i_di.di_uid; - } else - uid = current->fsuid; - - if (dip->i_di.di_mode & S_ISGID) { - if (type == GFS_FILE_DIR) - mode |= S_ISGID; - gid = dip->i_di.di_gid; - } else - gid = current->fsgid; - - error = gfs_acl_new_prep(dip, type, &mode, - &acl_a_data, &acl_d_data, - &acl_size, &acl_blocks); - if (error) - return error; - - al = gfs_alloc_get(dip); - - error = gfs_quota_lock_m(dip, uid, gid); - if (error) - goto fail; - - error = gfs_quota_check(dip, uid, gid); - if (error) - goto fail_gunlock_q; - - if (acl_blocks) - alloc_required = TRUE; - else { - error = gfs_diradd_alloc_required(dip, name, &alloc_required); - if (error) - goto fail_gunlock_q; - } - - if (alloc_required) { - error = gfs_quota_check(dip, dip->i_di.di_uid, dip->i_di.di_gid); - if (error) - goto fail_gunlock_q; - - al->al_requested_meta = sdp->sd_max_dirres + acl_blocks; - - error = gfs_inplace_reserve(dip); - if (error) - goto fail_gunlock_q; - - /* Trans may require: - blocks for two dinodes, the directory blocks necessary for - a new entry, RG bitmap blocks for an allocation, - and one block for a quota change and - one block for an unlinked tag. */ - - error = gfs_trans_begin(sdp, - 2 + sdp->sd_max_dirres + acl_blocks + - al->al_rgd->rd_ri.ri_length, 2); - if (error) - goto fail_inplace; - } else { - error = gfs_rindex_hold(sdp, &al->al_ri_gh); - if (error) - goto fail_gunlock_q; - - /* Trans may require: - blocks for two dinodes, a leaf block, - and one block for a quota change and - one block for an unlinked tag. */ - - error = gfs_trans_begin(sdp, 3, 2); - if (error) - goto fail_inplace; - } - - error = gfs_dir_add(dip, name, inum, type); - if (error) - goto fail_end_trans; - - error = make_dinode(dip, gl, inum, type, mode, uid, gid); - if (error) - goto fail_end_trans; - - al->al_ul = gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, - &(struct gfs_inum){0, inum->no_addr}); - gfs_trans_add_quota(sdp, +1, uid, gid); - - error = gfs_inode_get(gl, inum, CREATE, &ip); - - /* This should only fail if we are already shutdown. */ - if (gfs_assert_withdraw(sdp, !error)) - goto fail_end_trans; - - if (acl_blocks) - error = gfs_acl_new_init(dip, ip, - acl_a_data, acl_d_data, - acl_size); - - if (!alloc_required) - gfs_glock_dq_uninit(&al->al_ri_gh); - - return error; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_inplace: - if (alloc_required) - gfs_inplace_release(dip); - else - gfs_glock_dq_uninit(&al->al_ri_gh); - - fail_gunlock_q: - gfs_quota_unlock_m(dip); - - fail: - gfs_alloc_put(dip); - if (acl_a_data) - kfree(acl_a_data); - else if (acl_d_data) - kfree(acl_d_data); - - return error; -} - -/** - * gfs_createi - Create a new inode - * @d_gh: An initialized holder for the directory glock - * @name: The name of the new file - * @type: The type of dinode (GFS_FILE_REG, GFS_FILE_DIR, GFS_FILE_LNK, ...) - * @mode: the permissions on the new inode - * @i_gh: An uninitialized holder for the new inode glock - * - * If the return value is 0, the glocks on both the directory and the new - * file are held. A transaction has been started and an inplace reservation - * is held, as well. - * - * Returns: errno - */ - -int -gfs_createi(struct gfs_holder *d_gh, struct qstr *name, - unsigned int type, unsigned int mode, - struct gfs_holder *i_gh) -{ - struct gfs_inode *dip = gl2ip(d_gh->gh_gl); - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_unlinked *ul; - struct gfs_inum inum; - struct gfs_holder io_gh; - int error; - - if (!name->len || name->len > GFS_FNAMESIZE) - return -ENAMETOOLONG; - - gfs_holder_reinit(LM_ST_EXCLUSIVE, 0, d_gh); - error = gfs_glock_nq(d_gh); - if (error) - return error; - - error = create_ok(dip, name, type); - if (error) - goto fail; - - error = dinode_alloc(dip, &ul); - if (error) - goto fail; - - inum.no_addr = ul->ul_inum.no_addr; - pick_formal_ino(sdp, &inum); - - if (inum.no_formal_ino < dip->i_num.no_formal_ino) { - gfs_glock_dq(d_gh); - - error = gfs_glock_nq_num(sdp, - inum.no_formal_ino, &gfs_inode_glops, - LM_ST_EXCLUSIVE, GL_SKIP, i_gh); - if (error) { - gfs_unlinked_unlock(sdp, ul); - return error; - } - - gfs_holder_reinit(LM_ST_EXCLUSIVE, 0, d_gh); - error = gfs_glock_nq(d_gh); - if (error) { - gfs_glock_dq_uninit(i_gh); - gfs_unlinked_unlock(sdp, ul); - return error; - } - - error = create_ok(dip, name, type); - if (error) - goto fail_gunlock_i; - } else { - error = gfs_glock_nq_num(sdp, - inum.no_formal_ino, &gfs_inode_glops, - LM_ST_EXCLUSIVE, GL_SKIP, i_gh); - if (error) - goto fail_ul; - } - - error = gfs_glock_nq_num(sdp, - inum.no_addr, &gfs_iopen_glops, - LM_ST_SHARED, GL_LOCAL_EXCL | GL_EXACT, - &io_gh); - if (error) - goto fail_gunlock_i; - - error = inode_init_and_link(dip, name, &inum, i_gh->gh_gl, type, mode); - if (error) - goto fail_gunlock_io; - - gfs_glock_dq_uninit(&io_gh); - - return 0; - - fail_gunlock_io: - gfs_glock_dq_uninit(&io_gh); - - fail_gunlock_i: - gfs_glock_dq_uninit(i_gh); - - fail_ul: - gfs_unlinked_unlock(sdp, ul); - - fail: - gfs_glock_dq(d_gh); - - return error; -} - -/** - * gfs_unlinki - Unlink a file - * @dip: The inode of the directory - * @name: The name of the file to be unlinked - * @ip: The inode of the file to be removed - * - * Assumes Glocks on both dip and ip are held. - * - * Returns: errno - */ - -int -gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = dip->i_sbd; - int error; - - error = gfs_dir_del(dip, name); - if (error) - return error; - - error = gfs_change_nlink(ip, -1); - if (error) - return error; - - /* If this inode is being unlinked from the directory structure, - we need to mark that in the log so that it isn't lost during - a crash. */ - - if (!ip->i_di.di_nlink) { - gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &ip->i_num); - set_bit(GLF_STICKY, &ip->i_gl->gl_flags); - } - - return 0; -} - -/** - * gfs_rmdiri - Remove a directory - * @dip: The parent directory of the directory to be removed - * @name: The name of the directory to be removed - * @ip: The GFS inode of the directory to be removed - * - * Assumes Glocks on dip and ip are held - * - * Returns: errno - */ - -int -gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct qstr dotname; - int error; - - if (ip->i_di.di_entries != 2) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - return -EIO; - } - - error = gfs_dir_del(dip, name); - if (error) - return error; - - error = gfs_change_nlink(dip, -1); - if (error) - return error; - - dotname.len = 1; - dotname.name = "."; - error = gfs_dir_del(ip, &dotname); - if (error) - return error; - - dotname.len = 2; - dotname.name = ".."; - error = gfs_dir_del(ip, &dotname); - if (error) - return error; - - error = gfs_change_nlink(ip, -2); - if (error) - return error; - - /* This inode is being unlinked from the directory structure and - we need to mark that in the log so that it isn't lost during - a crash. */ - - gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &ip->i_num); - set_bit(GLF_STICKY, &ip->i_gl->gl_flags); - - return 0; -} - -/* - * gfs_unlink_ok - check to see that a inode is still in a directory - * @dip: the directory - * @name: the name of the file - * @ip: the inode - * - * Assumes that the lock on (at least) @dip is held. - * - * Returns: 0 if the parent/child relationship is correct, errno if it isn't - */ - -int -gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, - struct gfs_inode *ip, struct gfs_inum *inump) -{ - struct gfs_inum inum; - unsigned int type; - int error; - - if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode)) - return -EPERM; - - if ((dip->i_di.di_mode & S_ISVTX) && - dip->i_di.di_uid != current->fsuid && - ip->i_di.di_uid != current->fsuid && - !capable(CAP_FOWNER)) - return -EPERM; - - if (IS_APPEND(dip->i_vnode)) - return -EPERM; - - error = permission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL); - if (error) - return error; - - error = gfs_dir_search(dip, name, &inum, &type); - if (error) - return error; - - if (inum.no_formal_ino != ip->i_num.no_formal_ino) { - /* - * Add for rename - bugzilla 190475 - * return new inum such that gfs_rename can - * do its silly rename. - */ - if (unlikely(inump)) { - inump->no_formal_ino = inum.no_formal_ino; - inump->no_addr = inum.no_addr; - } - - return -ENOENT; - } - - if (ip->i_di.di_type != type) { - gfs_consist_inode(dip); - return -EIO; - } - - return 0; -} - -/* - * gfs_ok_to_move - check if it's ok to move a directory to another directory - * @this: move this - * @to: to here - * - * Follow @to back to the root and make sure we don't encounter @this - * Assumes we already hold the rename lock. - * - * Returns: errno - */ - -int -gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to) -{ - struct gfs_sbd *sdp = this->i_sbd; - struct gfs_inode *tmp; - struct gfs_holder to_gh, tmp_gh; - struct qstr dotdot; - int error = 0; - - memset(&dotdot, 0, sizeof (struct qstr)); - dotdot.name = ".."; - dotdot.len = 2; - - gfs_inode_hold(to); - - for (;;) { - if (to == this) { - error = -EINVAL; - break; - } - if (to == sdp->sd_rooti) { - error = 0; - break; - } - - gfs_holder_init(to->i_gl, 0, 0, &to_gh); - - error = gfs_lookupi(&to_gh, &dotdot, TRUE, &tmp_gh); - if (error) { - gfs_holder_uninit(&to_gh); - break; - } - if (!tmp_gh.gh_gl) { - gfs_holder_uninit(&to_gh); - error = -ENOENT; - break; - } - - tmp = gl2ip(tmp_gh.gh_gl); - - gfs_glock_dq_uninit(&to_gh); - gfs_glock_dq_uninit(&tmp_gh); - - gfs_inode_put(to); - to = tmp; - } - - gfs_inode_put(to); - - return error; -} - -/** - * gfs_readlinki - return the contents of a symlink - * @ip: the symlink's inode - * @buf: a pointer to the buffer to be filled - * @len: a pointer to the length of @buf - * - * If @buf is too small, a piece of memory is kmalloc()ed and needs - * to be freed by the caller. - * - * Returns: errno - */ - -int -gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len) -{ - struct gfs_holder i_gh; - struct buffer_head *dibh; - unsigned int x; - int error; - - gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); - error = gfs_glock_nq_atime(&i_gh); - if (error) { - gfs_holder_uninit(&i_gh); - return error; - } - - if (!ip->i_di.di_size) { - gfs_consist_inode(ip); - error = -EIO; - goto out; - } - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto out; - - x = ip->i_di.di_size + 1; - if (x > *len) { - *buf = kmalloc(x, GFP_KERNEL); - if (!*buf) { - error = -ENOMEM; - goto out_brelse; - } - } - - memcpy(*buf, dibh->b_data + sizeof(struct gfs_dinode), x); - *len = x; - - out_brelse: - brelse(dibh); - - out: - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_glock_nq_atime - Acquire a hold on an inode's glock, and - * conditionally update the inode's atime - * @gh: the holder to acquire - * - * Tests atime (access time) for gfs_read, gfs_readdir and gfs_mmap - * Update if the difference between the current time and the inode's current - * atime is greater than an interval specified at mount (or default). - * - * Will not update if GFS mounted NOATIME (this is *the* place where NOATIME - * has an effect) or Read-Only. - * - * Returns: errno - */ - -int -gfs_glock_nq_atime(struct gfs_holder *gh) -{ - struct gfs_glock *gl = gh->gh_gl; - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_inode *ip = gl2ip(gl); - int64_t curtime, quantum = gfs_tune_get(sdp, gt_atime_quantum); - unsigned int state; - int flags; - int error; - - if (gfs_assert_warn(sdp, gh->gh_flags & GL_ATIME) || - gfs_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || - gfs_assert_warn(sdp, gl->gl_ops == &gfs_inode_glops)) - return -EINVAL; - - /* Save original request state of lock holder */ - state = gh->gh_state; - flags = gh->gh_flags; - - error = gfs_glock_nq(gh); - if (error) - return error; - - if (test_bit(SDF_NOATIME, &sdp->sd_flags) || - test_bit(SDF_ROFS, &sdp->sd_flags)) - return 0; - - curtime = get_seconds(); - if (curtime - ip->i_di.di_atime >= quantum) { - /* Get EX hold (force EX glock via !ANY) to write the dinode */ - gfs_glock_dq(gh); - gfs_holder_reinit(LM_ST_EXCLUSIVE, - gh->gh_flags & ~LM_FLAG_ANY, - gh); - error = gfs_glock_nq(gh); - if (error) - return error; - - /* Verify that atime hasn't been updated while we were - trying to get exclusive lock. */ - - curtime = get_seconds(); - if (curtime - ip->i_di.di_atime >= quantum) { - struct buffer_head *dibh; - - error = gfs_trans_begin(sdp, 1, 0); - if (error == -EROFS) - return 0; - if (error) - goto fail; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail_end_trans; - - ip->i_di.di_atime = curtime; - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - gfs_trans_end(sdp); - } - - /* If someone else has asked for the glock, - unlock and let them have it. Then reacquire - in the original state. */ - if (gfs_glock_is_blocking(gl)) { - gfs_glock_dq(gh); - gfs_holder_reinit(state, flags, gh); - return gfs_glock_nq(gh); - } - } - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail: - gfs_glock_dq(gh); - - return error; -} - -/** - * glock_compare_atime - Compare two struct gfs_glock structures for gfs_sort() - * @arg_a: the first structure - * @arg_b: the second structure - * - * Sort order determined by (in order of priority): - * -- lock number - * -- lock state (SHARED > EXCLUSIVE or GL_ATIME, which can demand EXCLUSIVE) - * - * Returns: 1 if A > B - * -1 if A < B - * 0 if A = B - */ - -static int -glock_compare_atime(const void *arg_a, const void *arg_b) -{ - struct gfs_holder *gh_a = *(struct gfs_holder **)arg_a; - struct gfs_holder *gh_b = *(struct gfs_holder **)arg_b; - struct lm_lockname *a = &gh_a->gh_gl->gl_name; - struct lm_lockname *b = &gh_b->gh_gl->gl_name; - int ret = 0; - - if (a->ln_number > b->ln_number) - ret = 1; - else if (a->ln_number < b->ln_number) - ret = -1; - else { - if (gh_a->gh_state == LM_ST_SHARED && - gh_b->gh_state == LM_ST_EXCLUSIVE) - ret = 1; - else if (gh_a->gh_state == LM_ST_SHARED && - (gh_b->gh_flags & GL_ATIME)) - ret = 1; - } - - return ret; -} - -/** - * gfs_glock_nq_m_atime - acquire multiple glocks where one may need an - * atime update - * @num_gh: the number of structures - * @ghs: an array of struct gfs_holder structures - * - * Returns: 0 on success (all glocks acquired), - * errno on failure (no glocks acquired) - */ - -int -gfs_glock_nq_m_atime(unsigned int num_gh, struct gfs_holder *ghs) -{ - struct gfs_holder **p; - unsigned int x; - int error = 0; - - if (!num_gh) - return 0; - - if (num_gh == 1) { - ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); - if (ghs->gh_flags & GL_ATIME) - error = gfs_glock_nq_atime(ghs); - else - error = gfs_glock_nq(ghs); - return error; - } - - p = kmalloc(num_gh * sizeof(struct gfs_holder *), GFP_KERNEL); - if (!p) - return -ENOMEM; - - for (x = 0; x < num_gh; x++) - p[x] = &ghs[x]; - - gfs_sort(p, num_gh, sizeof(struct gfs_holder *), glock_compare_atime); - - for (x = 0; x < num_gh; x++) { - p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); - - if (p[x]->gh_flags & GL_ATIME) - error = gfs_glock_nq_atime(p[x]); - else - error = gfs_glock_nq(p[x]); - - if (error) { - while (x--) - gfs_glock_dq(p[x]); - break; - } - } - - kfree(p); - return error; -} - -/** - * gfs_try_toss_vnode - See if we can toss a vnode from memory - * @ip: the inode - * - * Returns: TRUE if the vnode was tossed - */ - -void -gfs_try_toss_vnode(struct gfs_inode *ip) -{ - struct inode *inode; - - inode = gfs_iget(ip, NO_CREATE); - if (!inode) - return; - - d_prune_aliases(inode); - - if (ip->i_di.di_type == GFS_FILE_DIR) { - struct list_head *head = &inode->i_dentry; - struct dentry *d = NULL; - - spin_lock(&dcache_lock); - if (list_empty(head)) - spin_unlock(&dcache_lock); - else { - d = list_entry(head->next, struct dentry, d_alias); - dget_locked(d); - spin_unlock(&dcache_lock); - - if (have_submounts(d)) - dput(d); - else { - shrink_dcache_parent(d); - dput(d); - d_prune_aliases(inode); - } - } - } - - inode->i_nlink = 0; - iput(inode); -} - - -static int -__gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr) -{ - struct buffer_head *dibh; - int error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - inode_setattr(ip->i_vnode, attr); - gfs_inode_attr_out(ip); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - return error; -} - -/** - * gfs_setattr_simple - - * @ip: - * @attr: - * - * Called with a reference on the vnode. - * - * Returns: errno - */ - -int -gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr) -{ - int error; - - if (current_transaction) - return __gfs_setattr_simple(ip, attr); - - /* Trans may require: - one dinode block. */ - - error = gfs_trans_begin(ip->i_sbd, 1, 0); - if (error) - return error; - - error = __gfs_setattr_simple(ip, attr); - - gfs_trans_end(ip->i_sbd); - - return error; -} - -/** - * iah_make_jdata - - * @gl: - * @inum: - * - */ - -static void -iah_make_jdata(struct gfs_glock *gl, struct gfs_inum *inum) -{ - struct buffer_head *bh; - struct gfs_dinode *di; - uint32_t flags; - int error; - - error = gfs_dread(gl, inum->no_addr, DIO_START | DIO_WAIT, &bh); - - /* This should only fail if we are already shutdown. */ - if (gfs_assert_withdraw(gl->gl_sbd, !error)) - return; - - di = (struct gfs_dinode *)bh->b_data; - - flags = di->di_flags; - flags = gfs32_to_cpu(flags) | GFS_DIF_JDATA; - di->di_flags = cpu_to_gfs32(flags); - - brelse(bh); -} - -/** - * iah_super_update - Write superblock to disk - * @sdp: filesystem instance structure - * - * Returns: errno - * - * Update on-disk superblock, using (modified) data in sdp->sd_sb - */ - -static int -iah_super_update(struct gfs_sbd *sdp) -{ - struct gfs_glock *gl; - struct buffer_head *bh; - int error; - - error = gfs_glock_get(sdp, - GFS_SB_LOCK, &gfs_meta_glops, - NO_CREATE, &gl); - if (gfs_assert_withdraw(sdp, !error && gl)) /* This should already be held. */ - return -EINVAL; - - error = gfs_dread(gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, - DIO_START | DIO_WAIT, &bh); - if (!error) { - gfs_trans_add_bh(gl, bh); - gfs_sb_out(&sdp->sd_sb, bh->b_data); - brelse(bh); - } - - gfs_glock_put(gl); - - return error; -} - -/** - * inode_alloc_hidden - allocate on-disk inode for a special (hidden) file - * @sdp: the filesystem instance structure - * @inum: new dinode's block # and formal inode #, to be filled - * in by this function. - * - * Returns: errno - * - * This function is called only very rarely, when the first-to-mount - * node can't find a pre-existing special file (e.g. license or quota file) that - * it expects to find. This should happen only when upgrading from an older - * version of the filesystem. - * - * The @inum must be a member of sdp->sd_sb in order to get updated to on-disk - * superblock properly. - */ - -static int -inode_alloc_hidden(struct gfs_sbd *sdp, struct gfs_inum *inum) -{ - struct gfs_inode *dip = sdp->sd_rooti; - struct gfs_holder d_gh, i_gh; - struct gfs_unlinked *ul; - int error; - - error = gfs_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &d_gh); - if (error) - return error; - - error = dinode_alloc(dip, &ul); - if (error) - goto fail; - - inum->no_addr = ul->ul_inum.no_addr; - pick_formal_ino(sdp, inum); - - /* Don't worry about deadlock ordering here. We're the first - mounter and still under the mount lock (i.e. there is no - contention). */ - - error = gfs_glock_nq_num(sdp, - inum->no_formal_ino, &gfs_inode_glops, - LM_ST_EXCLUSIVE, GL_SKIP, &i_gh); - if (error) - goto fail_ul; - - gfs_alloc_get(dip); - - error = gfs_quota_hold_m(dip, 0, 0); - if (error) - goto fail_al; - - /* Trans may require: - The new inode, the superblock, - and one block for a quota change and - one block for an unlinked tag. */ - - error = gfs_trans_begin(sdp, 2, 2); - if (error) - goto fail_unhold; - - error = make_dinode(dip, i_gh.gh_gl, inum, GFS_FILE_REG, 0600, 0, 0); - if (error) - goto fail_end_trans; - - /* Hidden files get all of their data (not just metadata) journaled */ - iah_make_jdata(i_gh.gh_gl, inum); - - error = iah_super_update(sdp); - if (error) - goto fail_end_trans; - - gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, - &(struct gfs_inum){0, inum->no_addr}); - gfs_trans_add_quota(sdp, +1, 0, 0); - gfs_trans_add_gl(dip->i_gl); - - gfs_trans_end(sdp); - gfs_quota_unhold_m(dip); - gfs_alloc_put(dip); - - gfs_glock_dq_uninit(&i_gh); - gfs_glock_dq_uninit(&d_gh); - - gfs_unlinked_unlock(sdp, ul); - - gfs_log_flush(sdp); - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_unhold: - gfs_quota_unhold_m(dip); - - fail_al: - gfs_alloc_put(dip); - gfs_glock_dq_uninit(&i_gh); - - fail_ul: - gfs_unlinked_unlock(sdp, ul); - - fail: - gfs_glock_dq_uninit(&d_gh); - - return error; -} - -/** - * gfs_alloc_qinode - allocate a quota inode - * @sdp: The GFS superblock - * - * Returns: 0 on success, error code otherwise - */ - -int -gfs_alloc_qinode(struct gfs_sbd *sdp) -{ - return inode_alloc_hidden(sdp, &sdp->sd_sb.sb_quota_di); -} - -/** - * gfs_alloc_linode - allocate a license inode - * @sdp: The GFS superblock - * - * Returns: 0 on success, error code otherwise - */ - -int -gfs_alloc_linode(struct gfs_sbd *sdp) -{ - return inode_alloc_hidden(sdp, &sdp->sd_sb.sb_license_di); -} diff --git a/gfs-kernel/src/gfs/inode.h b/gfs-kernel/src/gfs/inode.h deleted file mode 100644 index 3c8142d..0000000 --- a/gfs-kernel/src/gfs/inode.h +++ /dev/null @@ -1,72 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __INODE_DOT_H__ -#define __INODE_DOT_H__ - -void gfs_inode_attr_in(struct gfs_inode *ip); -void gfs_inode_attr_out(struct gfs_inode *ip); -struct inode *gfs_iget(struct gfs_inode *ip, int create); - -int gfs_copyin_dinode(struct gfs_inode *ip); - -int gfs_inode_get(struct gfs_glock *i_gl, struct gfs_inum *inum, int create, - struct gfs_inode **ipp); -void gfs_inode_hold(struct gfs_inode *ip); -void gfs_inode_put(struct gfs_inode *ip); -void gfs_inode_destroy(struct gfs_inode *ip); - -int gfs_inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum); - -int gfs_change_nlink(struct gfs_inode *ip, int diff); -int gfs_lookupi(struct gfs_holder *d_gh, struct qstr *name, - int is_root, struct gfs_holder *i_gh); -int gfs_createi(struct gfs_holder *d_gh, struct qstr *name, - unsigned int type, unsigned int mode, - struct gfs_holder *i_gh); -int gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); -int gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); -int gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, - struct gfs_inode *ip, struct gfs_inum *inum); -int gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to); -int gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len); - -int gfs_glock_nq_atime(struct gfs_holder *gh); -int gfs_glock_nq_m_atime(unsigned int num_gh, struct gfs_holder *ghs); - -void gfs_try_toss_vnode(struct gfs_inode *ip); - -int gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr); - -/* Backwards compatibility functions */ - -int gfs_alloc_qinode(struct gfs_sbd *sdp); -int gfs_alloc_linode(struct gfs_sbd *sdp); - -struct inode *gfs_refresh_iobj(struct gfs_sbd *sdp, void *inum_obj, int *n); - -/* Inlines */ - -static __inline__ int -gfs_is_stuffed(struct gfs_inode *ip) -{ - return !ip->i_di.di_height; -} - -static __inline__ int -gfs_is_jdata(struct gfs_inode *ip) -{ - return ip->i_di.di_flags & GFS_DIF_JDATA; -} - -#endif /* __INODE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ioctl.c b/gfs-kernel/src/gfs/ioctl.c deleted file mode 100644 index 588bf89..0000000 --- a/gfs-kernel/src/gfs/ioctl.c +++ /dev/null @@ -1,1520 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> -#include <linux/gfs_ioctl.h> -#include <linux/vmalloc.h> - -#include "gfs.h" -#include "bmap.h" -#include "dio.h" -#include "dir.h" -#include "eattr.h" -#include "file.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "ioctl.h" -#include "log.h" -#include "quota.h" -#include "rgrp.h" -#include "super.h" -#include "trans.h" - -typedef int (*gi_filler_t) (struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count); - -#define ARG_SIZE (32) - -/** - * gi_skeleton - Setup a buffer that functions can print into - * @ip: - * @gi: - * @filler: - * - * Returns: -errno or count of bytes copied to userspace - */ - -static int -gi_skeleton(struct gfs_inode *ip, struct gfs_ioctl *gi, - gi_filler_t filler) -{ - unsigned int size = gfs_tune_get(ip->i_sbd, gt_lockdump_size); - char *buf; - unsigned int count = 0; - int error; - - if (size > gi->gi_size) - size = gi->gi_size; - - buf = vmalloc(size); - if (!buf) - return -ENOMEM; - - error = filler(ip, gi, buf, size, &count); - if (error) - goto out; - - if (copy_to_user(gi->gi_data, buf, count + 1)) - error = -EFAULT; - else - error = count + 1; - - out: - vfree(buf); - - return error; -} - -/** - * gi_get_cookie - Return the "cookie" (identifying string) for a - * filesystem mount - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_get_cookie(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - int error = -ENOBUFS; - - if (gi->gi_argc != 1) - return -EINVAL; - - gfs_printf("version 0\n"); - gfs_printf("%lu", (unsigned long)ip->i_sbd); - - error = 0; - - out: - return error; -} - -/** - * gi_get_super - Return the "struct gfs_sb" for a filesystem - * @sdp: - * @gi: - * - * Returns: errno - */ - -static int -gi_get_super(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - struct gfs_holder sb_gh; - struct buffer_head *bh; - struct gfs_sb *sb; - int error; - - if (gi->gi_argc != 1) - return -EINVAL; - if (gi->gi_size != sizeof(struct gfs_sb)) - return -EINVAL; - - sb = kmalloc(sizeof(struct gfs_sb), GFP_KERNEL); - if (!sb) - return -ENOMEM; - - error = gfs_glock_nq_num(sdp, - GFS_SB_LOCK, &gfs_meta_glops, - LM_ST_SHARED, 0, &sb_gh); - if (error) - goto out; - - error = gfs_dread(sb_gh.gh_gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, - DIO_START | DIO_WAIT, &bh); - if (error) { - gfs_glock_dq_uninit(&sb_gh); - goto out; - } - gfs_sb_in(sb, bh->b_data); - brelse(bh); - - gfs_glock_dq_uninit(&sb_gh); - - if (copy_to_user(gi->gi_data, sb, - sizeof(struct gfs_sb))) - error = -EFAULT; - else - error = sizeof(struct gfs_sb); - - out: - kfree(sb); - - return error; -} - -/** - * gi_get_args - Return the mount arguments - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_get_args(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - struct gfs_args *args = &ip->i_sbd->sd_args; - int error = -ENOBUFS; - - if (gi->gi_argc != 1) - return -EINVAL; - - gfs_printf("version 0\n"); - gfs_printf("lockproto %s\n", args->ar_lockproto); - gfs_printf("locktable %s\n", args->ar_locktable); - gfs_printf("hostdata %s\n", args->ar_hostdata); - gfs_printf("ignore_local_fs %d\n", args->ar_ignore_local_fs); - gfs_printf("localcaching %d\n", args->ar_localcaching); - gfs_printf("localflocks %d\n", args->ar_localflocks); - gfs_printf("oopses_ok %d\n", args->ar_oopses_ok); - gfs_printf("upgrade %d\n", args->ar_upgrade); - gfs_printf("num_glockd %u\n", args->ar_num_glockd); - gfs_printf("posix_acls %d\n", args->ar_posix_acls); - gfs_printf("suiddir %d\n", args->ar_suiddir); - - error = 0; - - out: - return error; -} - -/** - * gi_get_lockstruct - Return the information in the FS' lockstruct - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_get_lockstruct(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - struct lm_lockstruct *ls = &ip->i_sbd->sd_lockstruct; - int error = -ENOBUFS; - - if (gi->gi_argc != 1) - return -EINVAL; - - gfs_printf("version 0\n"); - gfs_printf("jid %u\n", ls->ls_jid); - gfs_printf("first %u\n", ls->ls_first); - gfs_printf("lvb_size %u\n", ls->ls_lvb_size); - gfs_printf("flags %d\n", ls->ls_flags); - - error = 0; - - out: - return error; -} - -/** - * gi_get_stat_gfs - Return a filesystem's space usage information - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_get_stat_gfs(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - struct gfs_stat_gfs sg; - int error; - - if (gi->gi_argc != 1) - return -EINVAL; - - error = gfs_stat_gfs(ip->i_sbd, &sg, TRUE); - if (error) - return error; - - error = -ENOBUFS; - - gfs_printf("version 0\n"); - gfs_printf("bsize %u\n", ip->i_sbd->sd_sb.sb_bsize); - gfs_printf("total_blocks %"PRIu64"\n", sg.sg_total_blocks); - gfs_printf("free %"PRIu64"\n", sg.sg_free); - gfs_printf("used_dinode %"PRIu64"\n", sg.sg_used_dinode); - gfs_printf("free_dinode %"PRIu64"\n", sg.sg_free_dinode); - gfs_printf("used_meta %"PRIu64"\n", sg.sg_used_meta); - gfs_printf("free_meta %"PRIu64"\n", sg.sg_free_meta); - - error = 0; - - out: - return error; -} - -/** - * handle_roll - Read a atomic_t as an unsigned int - * @a: a counter - * - * if @a is negative, reset it to zero - * - * Returns: the value of the counter - */ - -static unsigned int -handle_roll(atomic_t *a) -{ - int x = atomic_read(a); - if (x < 0) { - atomic_set(a, 0); - return 0; - } - return (unsigned int)x; -} - -/** - * gi_get_counters - Return usage counters - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_get_counters(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - struct gfs_sbd *sdp = ip->i_sbd; - int error = -ENOBUFS; - - if (gi->gi_argc != 1) - return -EINVAL; - - gfs_printf("version 0\n"); - gfs_printf("sd_glock_count:locks::%d\n", - atomic_read(&sdp->sd_glock_count)); - gfs_printf("sd_glock_held_count:locks held::%d\n", - atomic_read(&sdp->sd_glock_held_count)); - gfs_printf("sd_freeze_count:freeze count::%d\n", - sdp->sd_freeze_count); - gfs_printf("sd_inode_count:incore inodes::%d\n", - atomic_read(&sdp->sd_inode_count)); - gfs_printf("sd_bufdata_count:metadata buffers::%d\n", - atomic_read(&sdp->sd_bufdata_count)); - gfs_printf("sd_unlinked_ic_count:unlinked inodes::%d\n", - atomic_read(&sdp->sd_unlinked_ic_count)); - gfs_printf("sd_quota_count:quota IDs::%d\n", - atomic_read(&sdp->sd_quota_count)); - gfs_printf("sd_log_buffers:incore log buffers::%u\n", - sdp->sd_log_buffers); - gfs_printf("sd_log_seg_free:log segments free::%u\n", - sdp->sd_log_seg_free); - gfs_printf("ji_nsegment:log segments total::%u\n", - sdp->sd_jdesc.ji_nsegment); - gfs_printf("sd_mhc_count:meta header cache entries::%d\n", - atomic_read(&sdp->sd_mhc_count)); - gfs_printf("sd_depend_count:glock dependencies::%d\n", - atomic_read(&sdp->sd_depend_count)); - gfs_printf("sd_reclaim_count:glocks on reclaim list::%d\n", - atomic_read(&sdp->sd_reclaim_count)); - gfs_printf("sd_log_wrap:log wraps::%"PRIu64"\n", - sdp->sd_log_wrap); - gfs_printf("sd_lm_outstanding:outstanding LM calls::%d\n", - atomic_read(&sdp->sd_lm_outstanding)); - gfs_printf("sd_bio_outstanding:outstanding BIO calls::%u\n", - atomic_read(&sdp->sd_bio_outstanding)); - gfs_printf("sd_fh2dentry_misses:fh2dentry misses:diff:%u\n", - handle_roll(&sdp->sd_fh2dentry_misses)); - gfs_printf("sd_reclaimed:glocks reclaimed:diff:%u\n", - handle_roll(&sdp->sd_reclaimed)); - gfs_printf("sd_glock_nq_calls:glock nq calls:diff:%u\n", - handle_roll(&sdp->sd_glock_nq_calls)); - gfs_printf("sd_glock_dq_calls:glock dq calls:diff:%u\n", - handle_roll(&sdp->sd_glock_dq_calls)); - gfs_printf("sd_glock_prefetch_calls:glock prefetch calls:diff:%u\n", - handle_roll(&sdp->sd_glock_prefetch_calls)); - gfs_printf("sd_lm_lock_calls:lm_lock calls:diff:%u\n", - handle_roll(&sdp->sd_lm_lock_calls)); - gfs_printf("sd_lm_unlock_calls:lm_unlock calls:diff:%u\n", - handle_roll(&sdp->sd_lm_unlock_calls)); - gfs_printf("sd_lm_callbacks:lm callbacks:diff:%u\n", - handle_roll(&sdp->sd_lm_callbacks)); - gfs_printf("sd_ops_address:address operations:diff:%u\n", - handle_roll(&sdp->sd_ops_address)); - gfs_printf("sd_ops_dentry:dentry operations:diff:%u\n", - handle_roll(&sdp->sd_ops_dentry)); - gfs_printf("sd_ops_export:export operations:diff:%u\n", - handle_roll(&sdp->sd_ops_export)); - gfs_printf("sd_ops_file:file operations:diff:%u\n", - handle_roll(&sdp->sd_ops_file)); - gfs_printf("sd_ops_inode:inode operations:diff:%u\n", - handle_roll(&sdp->sd_ops_inode)); - gfs_printf("sd_ops_super:super operations:diff:%u\n", - handle_roll(&sdp->sd_ops_super)); - gfs_printf("sd_ops_vm:vm operations:diff:%u\n", - handle_roll(&sdp->sd_ops_vm)); - gfs_printf("sd_bio_reads:block I/O reads:diff:%u\n", - handle_roll(&sdp->sd_bio_reads) >> - (sdp->sd_sb.sb_bsize_shift - 9)); - gfs_printf("sd_bio_writes:block I/O writes:diff:%u\n", - handle_roll(&sdp->sd_bio_writes) >> - (sdp->sd_sb.sb_bsize_shift - 9)); - - error = 0; - - out: - return error; -} - -/** - * gi_get_tune - Return current values of the tuneable parameters - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_get_tune(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - struct gfs_tune *gt = &ip->i_sbd->sd_tune; - int error = -ENOBUFS; - - if (gi->gi_argc != 1) - return -EINVAL; - - spin_lock(>->gt_spin); - - gfs_printf("version 0\n"); - gfs_printf("ilimit1 %u\n", gt->gt_ilimit1); - gfs_printf("ilimit1_tries %u\n", gt->gt_ilimit1_tries); - gfs_printf("ilimit1_min %u\n", gt->gt_ilimit1_min); - gfs_printf("ilimit2 %u\n", gt->gt_ilimit2); - gfs_printf("ilimit2_tries %u\n", gt->gt_ilimit2_tries); - gfs_printf("ilimit2_min %u\n", gt->gt_ilimit2_min); - gfs_printf("demote_secs %u\n", gt->gt_demote_secs); - gfs_printf("incore_log_blocks %u\n", gt->gt_incore_log_blocks); - gfs_printf("jindex_refresh_secs %u\n", gt->gt_jindex_refresh_secs); - gfs_printf("depend_secs %u\n", gt->gt_depend_secs); - gfs_printf("scand_secs %u\n", gt->gt_scand_secs); - gfs_printf("recoverd_secs %u\n", gt->gt_recoverd_secs); - gfs_printf("logd_secs %u\n", gt->gt_logd_secs); - gfs_printf("quotad_secs %u\n", gt->gt_quotad_secs); - gfs_printf("inoded_secs %u\n", gt->gt_inoded_secs); - gfs_printf("glock_purge %u\n", gt->gt_glock_purge); - gfs_printf("quota_simul_sync %u\n", gt->gt_quota_simul_sync); - gfs_printf("quota_warn_period %u\n", gt->gt_quota_warn_period); - gfs_printf("atime_quantum %u\n", gt->gt_atime_quantum); - gfs_printf("quota_quantum %u\n", gt->gt_quota_quantum); - gfs_printf("quota_scale_num %u\n", gt->gt_quota_scale_num); - gfs_printf("quota_scale_den %u\n", gt->gt_quota_scale_den); - gfs_printf("quota_enforce %u\n", gt->gt_quota_enforce); - gfs_printf("quota_account %u\n", gt->gt_quota_account); - gfs_printf("new_files_jdata %u\n", gt->gt_new_files_jdata); - gfs_printf("new_files_directio %u\n", gt->gt_new_files_directio); - gfs_printf("max_atomic_write %u\n", gt->gt_max_atomic_write); - gfs_printf("max_readahead %u\n", gt->gt_max_readahead); - gfs_printf("lockdump_size %u\n", gt->gt_lockdump_size); - gfs_printf("stall_secs %u\n", gt->gt_stall_secs); - gfs_printf("complain_secs %u\n", gt->gt_complain_secs); - gfs_printf("reclaim_limit %u\n", gt->gt_reclaim_limit); - gfs_printf("entries_per_readdir %u\n", gt->gt_entries_per_readdir); - gfs_printf("prefetch_secs %u\n", gt->gt_prefetch_secs); - gfs_printf("statfs_slots %u\n", gt->gt_statfs_slots); - gfs_printf("max_mhc %u\n", gt->gt_max_mhc); - gfs_printf("greedy_default %u\n", gt->gt_greedy_default); - gfs_printf("greedy_quantum %u\n", gt->gt_greedy_quantum); - gfs_printf("greedy_max %u\n", gt->gt_greedy_max); - gfs_printf("rgrp_try_threshold %u\n", gt->gt_rgrp_try_threshold); - gfs_printf("statfs_fast %u\n", gt->gt_statfs_fast); - gfs_printf("seq_readahead %u\n", gt->gt_seq_readahead); - - error = 0; - - out: - spin_unlock(>->gt_spin); - - return error; -} - -#define tune_set(f, v) \ -do { \ - spin_lock(>->gt_spin); \ - gt->f = (v); \ - spin_unlock(>->gt_spin); \ -} while (0) - -/** - * gi_set_tune - Set a tuneable parameter - * @sdp: - * @gi: - * - * Returns: errno - */ - -static int -gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - struct gfs_tune *gt = &sdp->sd_tune; - char param[ARG_SIZE], value[ARG_SIZE]; - unsigned int x; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (gi->gi_argc != 3) - return -EINVAL; - - if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0) - return -EFAULT; - param[ARG_SIZE - 1] = 0; - - if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0) - return -EFAULT; - value[ARG_SIZE - 1] = 0; - - if (strcmp(param, "ilimit1") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_ilimit1, x); - - } else if (strcmp(param, "ilimit1_tries") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_ilimit1_tries, x); - - } else if (strcmp(param, "ilimit1_min") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_ilimit1_min, x); - - } else if (strcmp(param, "ilimit2") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_ilimit2, x); - - } else if (strcmp(param, "ilimit2_tries") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_ilimit2_tries, x); - - } else if (strcmp(param, "ilimit2_min") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_ilimit2_min, x); - - } else if (strcmp(param, "demote_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_demote_secs, x); - - } else if (strcmp(param, "incore_log_blocks") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_incore_log_blocks, x); - - } else if (strcmp(param, "jindex_refresh_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_jindex_refresh_secs, x); - - } else if (strcmp(param, "depend_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_depend_secs, x); - - } else if (strcmp(param, "scand_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_scand_secs, x); - wake_up_process(sdp->sd_scand_process); - - } else if (strcmp(param, "recoverd_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_recoverd_secs, x); - wake_up_process(sdp->sd_recoverd_process); - - } else if (strcmp(param, "logd_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_logd_secs, x); - wake_up_process(sdp->sd_logd_process); - - } else if (strcmp(param, "quotad_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_quotad_secs, x); - wake_up_process(sdp->sd_quotad_process); - - } else if (strcmp(param, "inoded_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_inoded_secs, x); - wake_up_process(sdp->sd_inoded_process); - - } else if (strcmp(param, "glock_purge") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_glock_purge, x); - - } else if (strcmp(param, "quota_simul_sync") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_quota_simul_sync, x); - - } else if (strcmp(param, "quota_warn_period") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_quota_warn_period, x); - - } else if (strcmp(param, "atime_quantum") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_atime_quantum, x); - - } else if (strcmp(param, "quota_quantum") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_quota_quantum, x); - - } else if (strcmp(param, "quota_scale") == 0) { - unsigned int y; - if (sscanf(value, "%u %u", &x, &y) != 2 || !y) - return -EINVAL; - spin_lock(>->gt_spin); - gt->gt_quota_scale_num = x; - gt->gt_quota_scale_den = y; - spin_unlock(>->gt_spin); - - } else if (strcmp(param, "quota_enforce") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - x = !!x; - spin_lock(>->gt_spin); - gt->gt_quota_enforce = x; - if (x) - gt->gt_quota_account = 1; - spin_unlock(>->gt_spin); - - } else if (strcmp(param, "quota_account") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - x = !!x; - spin_lock(>->gt_spin); - gt->gt_quota_account = x; - if (x) - spin_unlock(>->gt_spin); - else { - unsigned int y; - gt->gt_quota_enforce = 0; - spin_unlock(>->gt_spin); - for (y = 0; y < 2; y++) { - gfs_log_flush(sdp); - gfs_sync_meta(sdp); - gfs_quota_sync(sdp); - } - } - - } else if (strcmp(param, "new_files_jdata") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - x = !!x; - tune_set(gt_new_files_jdata, x); - - } else if (strcmp(param, "new_files_directio") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - x = !!x; - tune_set(gt_new_files_directio, x); - - } else if (strcmp(param, "max_atomic_write") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_max_atomic_write, x); - - } else if (strcmp(param, "max_readahead") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_max_readahead, x); - - } else if (strcmp(param, "lockdump_size") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_lockdump_size, x); - - } else if (strcmp(param, "stall_secs") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_stall_secs, x); - - } else if (strcmp(param, "complain_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_complain_secs, x); - - } else if (strcmp(param, "reclaim_limit") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_reclaim_limit, x); - - } else if (strcmp(param, "entries_per_readdir") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_entries_per_readdir, x); - - } else if (strcmp(param, "prefetch_secs") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_prefetch_secs, x); - - } else if (strcmp(param, "statfs_slots") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_statfs_slots, x); - - } else if (strcmp(param, "max_mhc") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_max_mhc, x); - - } else if (strcmp(param, "greedy_default") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_greedy_default, x); - - } else if (strcmp(param, "greedy_quantum") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_greedy_quantum, x); - - } else if (strcmp(param, "greedy_max") == 0) { - if (sscanf(value, "%u", &x) != 1 || !x) - return -EINVAL; - tune_set(gt_greedy_max, x); - - } else if (strcmp(param, "rgrp_try_threshold") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - tune_set(gt_rgrp_try_threshold, x); - - } else if (strcmp(param, "statfs_fast") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - error = gfs_statfs_init(sdp, x); - if (error) - return error; - else - tune_set(gt_statfs_fast, x); - - } else if (strcmp(param, "seq_readahead") == 0) { - if (sscanf(value, "%u", &x) != 1) - return -EINVAL; - error = gfs_reset_readahead(sdp, x); - if (error) - return error; - tune_set(gt_seq_readahead, x); - - } else - return -EINVAL; - - return 0; -} - -/** - * gi_do_reclaim - Reclaim unused metadata - * @ip: - * @gi: - * @buf: - * @size: - * @count: - * - * Returns: errno - */ - -static int -gi_do_reclaim(struct gfs_inode *ip, - struct gfs_ioctl *gi, - char *buf, - unsigned int size, - unsigned int *count) -{ - uint64_t inodes, metadata; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (gi->gi_argc != 1) - return -EINVAL; - - error = gfs_reclaim_metadata(ip->i_sbd, - &inodes, - &metadata); - if (error) - return error; - - error = -ENOBUFS; - - gfs_printf("version 0\n"); - gfs_printf("inodes %"PRIu64"\n", inodes); - gfs_printf("metadata %"PRIu64"\n", metadata); - - error = 0; - - out: - return error; -} - -/** - * gi_do_shrink - throw out unused glocks - * @sdp: - * @gi: - * - * Returns: 0 - */ - -static int -gi_do_shrink(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (gi->gi_argc != 1) - return -EINVAL; - gfs_gl_hash_clear(sdp, FALSE); - return 0; -} - -/** - * gi_get_file_stat - - * @ip: - * @gi: - * - * Returns: the number of bytes copied, or -errno - */ - -static int -gi_get_file_stat(struct gfs_inode *ip, struct gfs_ioctl *gi) -{ - struct gfs_holder i_gh; - struct gfs_dinode *di; - int error; - - if (gi->gi_argc != 1) - return -EINVAL; - if (gi->gi_size != sizeof(struct gfs_dinode)) - return -EINVAL; - - di = kmalloc(sizeof(struct gfs_dinode), GFP_KERNEL); - if (!di) - return -ENOMEM; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - goto out; - memcpy(di, &ip->i_di, sizeof(struct gfs_dinode)); - gfs_glock_dq_uninit(&i_gh); - - if (copy_to_user(gi->gi_data, di, - sizeof(struct gfs_dinode))) - error = -EFAULT; - else - error = sizeof(struct gfs_dinode); - - out: - kfree(di); - - return error; -} - -/** - * gi_set_file_flag - set or clear a flag on a file - * @ip: - * @gi: - * - * Returns: errno - */ - -static int -gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi) -{ - char buf[ARG_SIZE]; - int set; - uint32_t flag; - struct gfs_holder i_gh; - struct buffer_head *dibh; - int error; - - if (gi->gi_argc != 3) - return -EINVAL; - - if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) - return -EFAULT; - buf[ARG_SIZE - 1] = 0; - - if (strcmp(buf, "set") == 0) - set = TRUE; - else if (strcmp(buf, "clear") == 0) - set = FALSE; - else - return -EINVAL; - - if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0) - return -EFAULT; - buf[ARG_SIZE - 1] = 0; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - return error; - - error = -EACCES; - if (ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) - goto out; - - error = -EINVAL; - - if (strcmp(buf, "jdata") == 0) { - if (ip->i_di.di_type != GFS_FILE_REG || - ip->i_di.di_size) - goto out; - flag = GFS_DIF_JDATA; - } else if (strcmp(buf, "directio") == 0) { - if (ip->i_di.di_type != GFS_FILE_REG) - goto out; - flag = GFS_DIF_DIRECTIO; - } else if (strcmp(buf, "immutable") == 0) { - /* The IMMUTABLE flag can only be changed by - the relevant capability. */ - error = -EPERM; - if (!capable(CAP_LINUX_IMMUTABLE)) - goto out; - flag = GFS_DIF_IMMUTABLE; - } else if (strcmp(buf, "appendonly") == 0) { - /* The APPENDONLY flag can only be changed by - the relevant capability. */ - error = -EPERM; - if (!capable(CAP_LINUX_IMMUTABLE)) - goto out; - flag = GFS_DIF_APPENDONLY; - } else if (strcmp(buf, "inherit_jdata") == 0) { - if (ip->i_di.di_type != GFS_FILE_DIR) - goto out; - flag = GFS_DIF_INHERIT_JDATA; - } else if (strcmp(buf, "inherit_directio") == 0) { - if (ip->i_di.di_type != GFS_FILE_DIR) - goto out; - flag = GFS_DIF_INHERIT_DIRECTIO; - } else - goto out; - - error = gfs_trans_begin(ip->i_sbd, 1, 0); - if (error) - goto out; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto out_trans_end; - - if (set) - ip->i_di.di_flags |= flag; - else - ip->i_di.di_flags &= ~flag; - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - - brelse(dibh); - - out_trans_end: - gfs_trans_end(ip->i_sbd); - - out: - gfs_glock_dq_uninit(&i_gh); - - return error; - -} - -/** - * gi_get_file_meta - Return all the metadata for a file - * @ip: - * @gi: - * - * Returns: the number of bytes copied, or -errno - */ - -static int -gi_get_file_meta(struct gfs_inode *ip, struct gfs_ioctl *gi) -{ - struct gfs_holder i_gh; - struct gfs_user_buffer ub; - int error; - - if (gi->gi_argc != 1) - return -EINVAL; - - ub.ub_data = gi->gi_data; - ub.ub_size = gi->gi_size; - ub.ub_count = 0; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return error; - - error = -EACCES; - if (ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) - goto out; - - error = gfs_get_file_meta(ip, &ub); - if (error) - goto out; - - if (ip->i_di.di_type == GFS_FILE_DIR && - (ip->i_di.di_flags & GFS_DIF_EXHASH)) { - error = gfs_get_dir_meta(ip, &ub); - if (error) - goto out; - } - - if (ip->i_di.di_eattr) { - error = gfs_get_eattr_meta(ip, &ub); - if (error) - goto out; - } - - error = ub.ub_count; - - out: - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gi_do_file_flush - sync out all dirty data and - * drop the cache (and lock) for a file. - * @ip: - * @gi: - * - * Returns: errno - */ - -static int -gi_do_file_flush(struct gfs_inode *ip, struct gfs_ioctl *gi) -{ - if (gi->gi_argc != 1) - return -EINVAL; - gfs_glock_force_drop(ip->i_gl); - return 0; -} - -/** - * gi2hip - return the "struct gfs_inode" for a hidden file - * @sdp: - * @gi: - * - * Returns: the "struct gfs_inode" - */ - -static struct gfs_inode * -gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - char buf[ARG_SIZE]; - - if (gi->gi_argc != 2) - return ERR_PTR(-EINVAL); - - if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) - return ERR_PTR(-EFAULT); - buf[ARG_SIZE - 1] = 0; - - if (strcmp(buf, "jindex") == 0) - return sdp->sd_jiinode; - else if (strcmp(buf, "rindex") == 0) - return sdp->sd_riinode; - else if (strcmp(buf, "quota") == 0) - return sdp->sd_qinode; - else if (strcmp(buf, "license") == 0) - return sdp->sd_linode; - else - return ERR_PTR(-EINVAL); -} - -/** - * gi_get_hfile_stat - get stat info on a hidden file - * @sdp: - * @gi: - * - * Returns: the number of bytes copied, or -errno - */ - -static int -gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - struct gfs_inode *ip; - struct gfs_dinode *di; - struct gfs_holder i_gh; - int error; - - ip = gi2hip(sdp, gi); - if (IS_ERR(ip)) - return PTR_ERR(ip); - - if (gi->gi_size != sizeof(struct gfs_dinode)) - return -EINVAL; - - di = kmalloc(sizeof(struct gfs_dinode), GFP_KERNEL); - if (!di) - return -ENOMEM; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - goto out; - memcpy(di, &ip->i_di, sizeof(struct gfs_dinode)); - gfs_glock_dq_uninit(&i_gh); - - if (copy_to_user(gi->gi_data, di, - sizeof(struct gfs_dinode))) - error = -EFAULT; - else - error = sizeof(struct gfs_dinode); - - out: - kfree(di); - - return error; -} - -/** - * gi_do_hfile_read - Read data from a hidden file - * @sdp: - * @gi: - * - * Returns: the number of bytes read, or -errno - */ - -static int -gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - struct gfs_inode *ip; - struct gfs_holder i_gh; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - ip = gi2hip(sdp, gi); - if (IS_ERR(ip)) - return PTR_ERR(ip); - - if (!access_ok(VERIFY_WRITE, gi->gi_data, gi->gi_size)) - return -EFAULT; - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); - if (error) - return error; - - error = gfs_readi(ip, gi->gi_data, gi->gi_offset, gi->gi_size, - gfs_copy2user); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gi_do_hfile_write - Write data to a hidden file - * @sdp: - * @gi: - * - * Returns: the number of bytes written, or -errno - */ - -static int -gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - struct gfs_inode *ip; - struct gfs_alloc *al = NULL; - struct gfs_holder i_gh; - unsigned int data_blocks, ind_blocks; - int alloc_required; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - ip = gi2hip(sdp, gi); - if (IS_ERR(ip)) - return PTR_ERR(ip); - - if (!access_ok(VERIFY_READ, gi->gi_data, gi->gi_size)) - return -EFAULT; - - gfs_write_calc_reserv(ip, gi->gi_size, &data_blocks, &ind_blocks); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, - LM_FLAG_PRIORITY | GL_SYNC | GL_NOCANCEL_OTHER, - &i_gh); - if (error) - return error; - - if (!gfs_is_jdata(ip)) { - gfs_consist_inode(ip); - error = -EIO; - goto out; - } - - error = gfs_write_alloc_required(ip, gi->gi_offset, gi->gi_size, - &alloc_required); - if (error) - goto out; - - if (alloc_required) { - al = gfs_alloc_get(ip); - - error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, - NO_QUOTA_CHANGE); - if (error) - goto out_alloc; - - al->al_requested_meta = ind_blocks + data_blocks; - - error = gfs_inplace_reserve(ip); - if (error) - goto out_qs; - - /* Trans may require: - All blocks for a RG bitmap, all the "data" blocks, whatever - indirect blocks we need, a modified dinode, and a quota change */ - - error = gfs_trans_begin(sdp, - 1 + al->al_rgd->rd_ri.ri_length + - ind_blocks + data_blocks, 1); - if (error) - goto out_relse; - } else { - /* Trans may require: - All the "data" blocks and a modified dinode. */ - - error = gfs_trans_begin(sdp, 1 + data_blocks, 0); - if (error) - goto out_relse; - } - - error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size, - gfs_copy_from_user, NULL); - - gfs_trans_end(sdp); - - out_relse: - if (alloc_required) { - gfs_assert_warn(sdp, error || al->al_alloced_meta); - gfs_inplace_release(ip); - } - - out_qs: - if (alloc_required) - gfs_quota_unhold_m(ip); - - out_alloc: - if (alloc_required) - gfs_alloc_put(ip); - - out: - ip->i_gl->gl_vn++; - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gi_do_hfile_trunc - truncate a hidden file - * @sdp: - * @gi: - * - * Returns: the number of bytes copied, or -errno - */ - -static int -gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - struct gfs_inode *ip; - struct gfs_holder i_gh; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - ip = gi2hip(sdp, gi); - if (IS_ERR(ip)) - return PTR_ERR(ip); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SYNC, &i_gh); - if (error) - return error; - - error = gfs_truncatei(ip, gi->gi_offset, NULL); - - ip->i_gl->gl_vn++; - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gi_do_quota_sync - sync the outstanding quota changes for a FS - * @sdp: - * @gi: - * - * Returns: errno - */ - -static int -gi_do_quota_sync(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (gi->gi_argc != 1) - return -EINVAL; - return gfs_quota_sync(sdp); -} - -/** - * gi_do_quota_refresh - Refresh the a quota LVB from the quota file - * @sdp: - * @gi: - * - * Returns: errno - */ - -static int -gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - char buf[ARG_SIZE]; - int user; - uint32_t id; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (gi->gi_argc != 2) - return -EINVAL; - - if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) - return -EFAULT; - buf[ARG_SIZE - 1] = 0; - - switch (buf[0]) { - case 'u': - user = TRUE; - break; - case 'g': - user = FALSE; - break; - default: - return -EINVAL; - } - - if (buf[1] != ':') - return -EINVAL; - - if (sscanf(buf + 2, "%u", &id) != 1) - return -EINVAL; - - return gfs_quota_refresh(sdp, user, id); -} - -/** - * gi_do_quota_read - read quota values from the quota file - * @sdp: - * @gi: - * - * Returns: errno - */ - -static int -gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi) -{ - char buf[ARG_SIZE]; - int user; - uint32_t id; - struct gfs_quota q; - int error; - - if (gi->gi_argc != 2) - return -EINVAL; - if (gi->gi_size != sizeof(struct gfs_quota)) - return -EINVAL; - - if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) - return -EFAULT; - buf[ARG_SIZE - 1] = 0; - - switch (buf[0]) { - case 'u': - user = TRUE; - break; - case 'g': - user = FALSE; - break; - default: - return -EINVAL; - } - - if (buf[1] != ':') - return -EINVAL; - - if (sscanf(buf + 2, "%u", &id) != 1) - return -EINVAL; - - error = gfs_quota_read(sdp, user, id, &q); - if (error) - return error; - - if (copy_to_user(gi->gi_data, &q, sizeof(struct gfs_quota))) - return -EFAULT; - - return 0; -} - -/** - * gfs_ioctl_i - - * @ip: - * @arg: - * - * Returns: -errno or positive byte count - */ - -int -gfs_ioctl_i(struct gfs_inode *ip, void *arg) -{ - struct gfs_ioctl *gi_user = (struct gfs_ioctl *)arg; - struct gfs_ioctl gi; - char **argv; - char arg0[ARG_SIZE]; - int error = -EFAULT; - - if (copy_from_user(&gi, gi_user, sizeof(struct gfs_ioctl))) - return -EFAULT; - if (!gi.gi_argc) - return -EINVAL; - argv = kmalloc(gi.gi_argc * sizeof(char *), GFP_KERNEL); - if (!argv) - return -ENOMEM; - if (copy_from_user(argv, gi.gi_argv, - gi.gi_argc * sizeof(char *))) - goto out; - gi.gi_argv = argv; - - if (strncpy_from_user(arg0, argv[0], ARG_SIZE) < 0) - goto out; - arg0[ARG_SIZE - 1] = 0; - - if (strcmp(arg0, "get_cookie") == 0) - error = gi_skeleton(ip, &gi, gi_get_cookie); - else if (strcmp(arg0, "get_super") == 0) - error = gi_get_super(ip->i_sbd, &gi); - else if (strcmp(arg0, "get_args") == 0) - error = gi_skeleton(ip, &gi, gi_get_args); - else if (strcmp(arg0, "get_lockstruct") == 0) - error = gi_skeleton(ip, &gi, gi_get_lockstruct); - else if (strcmp(arg0, "get_stat_gfs") == 0) - error = gi_skeleton(ip, &gi, gi_get_stat_gfs); - else if (strcmp(arg0, "get_counters") == 0) - error = gi_skeleton(ip, &gi, gi_get_counters); - else if (strcmp(arg0, "get_tune") == 0) - error = gi_skeleton(ip, &gi, gi_get_tune); - else if (strcmp(arg0, "set_tune") == 0) - error = gi_set_tune(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_reclaim") == 0) - error = gi_skeleton(ip, &gi, gi_do_reclaim); - else if (strcmp(arg0, "do_shrink") == 0) - error = gi_do_shrink(ip->i_sbd, &gi); - else if (strcmp(arg0, "get_file_stat") == 0) - error = gi_get_file_stat(ip, &gi); - else if (strcmp(arg0, "set_file_flag") == 0) - error = gi_set_file_flag(ip, &gi); - else if (strcmp(arg0, "get_file_meta") == 0) - error = gi_get_file_meta(ip, &gi); - else if (strcmp(arg0, "get_file_meta_quota") == 0) - error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi); - else if (strcmp(arg0, "do_file_flush") == 0) - error = gi_do_file_flush(ip, &gi); - else if (strcmp(arg0, "get_hfile_stat") == 0) - error = gi_get_hfile_stat(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_hfile_read") == 0) - error = gi_do_hfile_read(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_hfile_write") == 0) - error = gi_do_hfile_write(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_hfile_trunc") == 0) - error = gi_do_hfile_trunc(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_quota_sync") == 0) - error = gi_do_quota_sync(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_quota_refresh") == 0) - error = gi_do_quota_refresh(ip->i_sbd, &gi); - else if (strcmp(arg0, "do_quota_read") == 0) - error = gi_do_quota_read(ip->i_sbd, &gi); - else - error = -ENOTTY; - - out: - kfree(argv); - - return error; -} diff --git a/gfs-kernel/src/gfs/ioctl.h b/gfs-kernel/src/gfs/ioctl.h deleted file mode 100644 index 7827bac..0000000 --- a/gfs-kernel/src/gfs/ioctl.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __IOCTL_DOT_H__ -#define __IOCTL_DOT_H__ - -int gfs_ioctl_i(struct gfs_inode *ip, void *arg); - -#endif /* __IOCTL_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/lm.c b/gfs-kernel/src/gfs/lm.c deleted file mode 100644 index d1b3fb2..0000000 --- a/gfs-kernel/src/gfs/lm.c +++ /dev/null @@ -1,500 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "lm.h" -#include "super.h" - -/** - * lm_cb - - * @fsdata: - * @type: - * @data: - * - */ - -static void -lm_cb(lm_fsdata_t *fsdata, unsigned int type, void *data) -{ - if (type == LM_CB_ASYNC) - atomic_dec(&((struct gfs_sbd *)fsdata)->sd_lm_outstanding); - gfs_glock_cb(fsdata, type, data); -} - -/** - * gfs_lm_mount - mount a locking protocol - * @sdp: the filesystem - * @args: mount arguements - * @silent: if TRUE, don't complain if the FS isn't a GFS fs - * - * Returns: errno - */ - -int -gfs_lm_mount(struct gfs_sbd *sdp, int silent) -{ - struct gfs_sb *sb = NULL; - char *proto, *table; - int error; - - proto = sdp->sd_args.ar_lockproto; - table = sdp->sd_args.ar_locktable; - - /* Try to autodetect */ - - if (!proto[0] || !table[0]) { - struct buffer_head *bh = sb_getblk(sdp->sd_vfs, - GFS_SB_ADDR >> sdp->sd_fsb2bb_shift); - lock_buffer(bh); - clear_buffer_dirty(bh); - clear_buffer_uptodate(bh); - unlock_buffer(bh); - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - - if (!buffer_uptodate(bh)) { - brelse(bh); - return -EIO; - } - - sb = kmalloc(sizeof(struct gfs_sb), GFP_KERNEL); - if (!sb) { - brelse(bh); - return -ENOMEM; - } - gfs_sb_in(sb, bh->b_data); - brelse(bh); - - error = gfs_check_sb(sdp, sb, silent); - if (error) - goto out; - - if (!proto[0]) - proto = sb->sb_lockproto; - - if (!table[0]) - table = sb->sb_locktable; - } - - printk("GFS: Trying to join cluster "%s", "%s"\n", - proto, table); - - atomic_inc(&sdp->sd_lm_outstanding); - error = lm_mount(proto, table, sdp->sd_args.ar_hostdata, - lm_cb, sdp, - GFS_MIN_LVB_SIZE, &sdp->sd_lockstruct); - atomic_dec(&sdp->sd_lm_outstanding); - if (error) { - printk("GFS: can't mount proto = %s, table = %s, hostdata = %s\n", - proto, table, sdp->sd_args.ar_hostdata); - goto out; - } - - if (gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_lockspace) || - gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_ops) || - gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_lvb_size >= GFS_MIN_LVB_SIZE)) { - lm_unmount(&sdp->sd_lockstruct); - goto out; - } - - snprintf(sdp->sd_fsname, 256, "%s.%u", - (*table) ? table : sdp->sd_vfs->s_id, - sdp->sd_lockstruct.ls_jid); - - printk("GFS: fsid=%s: Joined cluster. Now mounting FS...\n", - sdp->sd_fsname); - - out: - if (sb) - kfree(sb); - - return error; -} - -/** - * gfs_lm_others_may_mount - - * @sdp: - * - */ - -void -gfs_lm_others_may_mount(struct gfs_sbd *sdp) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - sdp->sd_lockstruct.ls_ops->lm_others_may_mount(sdp->sd_lockstruct.ls_lockspace); - atomic_dec(&sdp->sd_lm_outstanding); -} - -/** - * gfs_lm_unmount - Unmount lock protocol - * @sdp: The GFS superblock - * - */ - -void -gfs_lm_unmount(struct gfs_sbd *sdp) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - lm_unmount(&sdp->sd_lockstruct); - atomic_dec(&sdp->sd_lm_outstanding); -} - -/** - * gfs_lm_withdraw - - * @sdp: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...) -{ - va_list args; - - if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - return 0; - - va_start(args, fmt); - vprintk(fmt, args); - va_end(args); - - printk("GFS: fsid=%s: about to withdraw from the cluster\n", - sdp->sd_fsname); - printk("GFS: fsid=%s: waiting for outstanding I/O\n", - sdp->sd_fsname); - - if (sdp->sd_args.ar_debug) - BUG(); - - while (atomic_read(&sdp->sd_bio_outstanding)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 10); - } -/* - * I'm still not sure if we want to do this. If we do, we need to - * add code to cancel outstanding requests. - * - while (atomic_read(&sdp->sd_lm_outstanding)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 10); - } -*/ - - printk("GFS: fsid=%s: telling LM to withdraw\n", - sdp->sd_fsname); - - atomic_inc(&sdp->sd_lm_outstanding); - lm_withdraw(&sdp->sd_lockstruct); - atomic_dec(&sdp->sd_lm_outstanding); - - printk("GFS: fsid=%s: withdrawn\n", - sdp->sd_fsname); - - return -1; -} - -/** - * gfs_lm_get_lock - - * @sdp: - * @name: - * @lockp: - * - * Returns: errno - */ - -int -gfs_lm_get_lock(struct gfs_sbd *sdp, - struct lm_lockname *name, lm_lock_t **lockp) -{ - int error; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = -EIO; - else - error = sdp->sd_lockstruct.ls_ops->lm_get_lock(sdp->sd_lockstruct.ls_lockspace, - name, lockp); - atomic_dec(&sdp->sd_lm_outstanding); - - return error; -} - -/** - * gfs_lm_put_lock - - * @sdp: - * @lock: - * - */ - -void -gfs_lm_put_lock(struct gfs_sbd *sdp, lm_lock_t *lock) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - sdp->sd_lockstruct.ls_ops->lm_put_lock(lock); - atomic_dec(&sdp->sd_lm_outstanding); -} - -/** - * gfs_lm_lock - - * @sdp: - * @lock: - * @cur_state: - * @req_state: - * @flags: - * - * Returns: - */ - -unsigned int -gfs_lm_lock(struct gfs_sbd *sdp, lm_lock_t *lock, - unsigned int cur_state, unsigned int req_state, - unsigned int flags) -{ - int ret; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - ret = 0; - else - ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock, - cur_state, - req_state, flags); - if (ret != LM_OUT_ASYNC) - atomic_dec(&sdp->sd_lm_outstanding); - - return ret; -} - -/** - * gfs_lm_lock - - * @sdp: - * @lock: - * @cur_state: - * - * Returns: - */ - -unsigned int -gfs_lm_unlock(struct gfs_sbd *sdp, lm_lock_t *lock, - unsigned int cur_state) -{ - int ret; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - ret = 0; - else - ret = sdp->sd_lockstruct.ls_ops->lm_unlock(lock, cur_state); - if (ret != LM_OUT_ASYNC) - atomic_dec(&sdp->sd_lm_outstanding); - - return ret; -} - -/** - * gfs_lm_cancel - - * @sdp: - * @lock: - * - */ - -void -gfs_lm_cancel(struct gfs_sbd *sdp, lm_lock_t *lock) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - sdp->sd_lockstruct.ls_ops->lm_cancel(lock); - atomic_dec(&sdp->sd_lm_outstanding); -} - -/** - * gfs_lm_hold_lvb - - * @sdp: - * @lock: - * @lvbp: - * - * Returns: errno - */ - -int -gfs_lm_hold_lvb(struct gfs_sbd *sdp, lm_lock_t *lock, char **lvbp) -{ - int error; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = -EIO; - else - error = sdp->sd_lockstruct.ls_ops->lm_hold_lvb(lock, lvbp); - atomic_dec(&sdp->sd_lm_outstanding); - - return error; -} - -/** - * gfs_lm_unhold_lvb - - * @sdp: - * @lock: - * @lvb: - * - */ - -void -gfs_lm_unhold_lvb(struct gfs_sbd *sdp, lm_lock_t *lock, char *lvb) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - sdp->sd_lockstruct.ls_ops->lm_unhold_lvb(lock, lvb); - atomic_dec(&sdp->sd_lm_outstanding); -} - -/** - * gfs_lm_sync_lvb - - * @sdp: - * @lock: - * @lvb: - * - */ - -void -gfs_lm_sync_lvb(struct gfs_sbd *sdp, lm_lock_t *lock, char *lvb) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - sdp->sd_lockstruct.ls_ops->lm_sync_lvb(lock, lvb); - atomic_dec(&sdp->sd_lm_outstanding); -} - -/** - * gfs_lm_plock_get - - * @sdp: - * @name: - * @file: - * @fl: - * - * Returns: errno - */ - -int -gfs_lm_plock_get(struct gfs_sbd *sdp, - struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - int error; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = -EIO; - else - error = sdp->sd_lockstruct.ls_ops->lm_plock_get( - sdp->sd_lockstruct.ls_lockspace, - name, file, fl); - atomic_dec(&sdp->sd_lm_outstanding); - - return error; -} - -/** - * gfs_lm_plock - - * @sdp: - * @name: - * @file: - * @cmd: - * @fl: - * - * Returns: errno - */ - -int -gfs_lm_plock(struct gfs_sbd *sdp, - struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl) -{ - int error; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = -EIO; - else - error = sdp->sd_lockstruct.ls_ops->lm_plock( - sdp->sd_lockstruct.ls_lockspace, - name, file, cmd, fl); - atomic_dec(&sdp->sd_lm_outstanding); - - return error; -} - -/** - * gfs_lm_punlock - - * @sdp: - * @name: - * @file: - * @fl: - * - * Returns: errno - */ - -int -gfs_lm_punlock(struct gfs_sbd *sdp, - struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - int error; - - atomic_inc(&sdp->sd_lm_outstanding); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = posix_lock_file_wait(file, fl); - else - error = sdp->sd_lockstruct.ls_ops->lm_punlock( - sdp->sd_lockstruct.ls_lockspace, - name, file, fl); - atomic_dec(&sdp->sd_lm_outstanding); - - return error; -} - -/** - * gfs_lm_recovery_done - - * @sdp: - * @jid: - * @message: - * - */ - -void -gfs_lm_recovery_done(struct gfs_sbd *sdp, - unsigned int jid, unsigned int message) -{ - atomic_inc(&sdp->sd_lm_outstanding); - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - sdp->sd_lockstruct.ls_ops->lm_recovery_done(sdp->sd_lockstruct.ls_lockspace, - jid, - message); - atomic_dec(&sdp->sd_lm_outstanding); -} - - diff --git a/gfs-kernel/src/gfs/lm.h b/gfs-kernel/src/gfs/lm.h deleted file mode 100644 index 0f338a0..0000000 --- a/gfs-kernel/src/gfs/lm.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LM_DOT_H__ -#define __LM_DOT_H__ - -int gfs_lm_mount(struct gfs_sbd *sdp, int silent); -void gfs_lm_others_may_mount(struct gfs_sbd *sdp); -void gfs_lm_unmount(struct gfs_sbd *sdp); -int gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...) -__attribute__ ((format(printf, 2, 3))); -int gfs_lm_get_lock(struct gfs_sbd *sdp, - struct lm_lockname *name, lm_lock_t **lockp); -void gfs_lm_put_lock(struct gfs_sbd *sdp, lm_lock_t *lock); -unsigned int gfs_lm_lock(struct gfs_sbd *sdp, lm_lock_t *lock, - unsigned int cur_state, unsigned int req_state, - unsigned int flags); -unsigned int gfs_lm_unlock(struct gfs_sbd *sdp, lm_lock_t *lock, - unsigned int cur_state); -void gfs_lm_cancel(struct gfs_sbd *sdp, lm_lock_t *lock); -int gfs_lm_hold_lvb(struct gfs_sbd *sdp, lm_lock_t *lock, char **lvbp); -void gfs_lm_unhold_lvb(struct gfs_sbd *sdp, lm_lock_t *lock, char *lvb); -void gfs_lm_sync_lvb(struct gfs_sbd *sdp, lm_lock_t *lock, char *lvb); -int gfs_lm_plock_get(struct gfs_sbd *sdp, - struct lm_lockname *name, - struct file *file, struct file_lock *fl); -int gfs_lm_plock(struct gfs_sbd *sdp, - struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl); -int gfs_lm_punlock(struct gfs_sbd *sdp, - struct lm_lockname *name, - struct file *file, struct file_lock *fl); -void gfs_lm_recovery_done(struct gfs_sbd *sdp, - unsigned int jid, unsigned int message); - -#endif /* __LM_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/log.c b/gfs-kernel/src/gfs/log.c deleted file mode 100644 index 63ad8c0..0000000 --- a/gfs-kernel/src/gfs/log.c +++ /dev/null @@ -1,1529 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - What rolls down stairs - Alone or in pairs - Rolls over your neighbor's dog. - What's great for a snack - And fits on your back - It's log, log, log! - It's lo-og, lo-og, - It's big, it's heavy, it's wood. - It's lo-og, lo-og, - It's better than bad, it's good. - Everyone wants a log, - You're gonna love it, log - Come on and get your log, - Everyone needs a log... - LOG... FROM BLAMMO! - - -- The Ren and Stimpy Show -*/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/mm.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "log.h" -#include "lops.h" - -/** - * gfs_struct2blk - compute stuff - * @sdp: the filesystem - * @nstruct: the number of structures - * @ssize: the size of the structures - * - * Compute the number of log descriptor blocks needed to hold a certain number - * of structures of a certain size. - * - * Returns: the number of blocks needed (minimum is always 1) - */ - -unsigned int -gfs_struct2blk(struct gfs_sbd *sdp, unsigned int nstruct, unsigned int ssize) -{ - unsigned int blks; - unsigned int first, second; - - blks = 1; - first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_log_descriptor)) / ssize; - - if (nstruct > first) { - second = sdp->sd_sb.sb_bsize / ssize; - blks += DIV_RU(nstruct - first, second); - } - - return blks; -} - -/** - * gfs_blk2seg - Convert number of blocks into number of segments - * @sdp: The GFS superblock - * @blocks: The number of blocks - * - * Returns: The number of journal segments - */ - -unsigned int -gfs_blk2seg(struct gfs_sbd *sdp, unsigned int blocks) -{ - return DIV_RU(blocks, sdp->sd_sb.sb_seg_size - 1); -} - -/** - * log_distance - Compute distance between two journal blocks - * @sdp: The GFS superblock - * @newer: The most recent journal block of the pair - * @older: The older journal block of the pair - * - * Compute the distance (in the journal direction) between two - * blocks in the journal - * - * Returns: the distance in blocks - */ - -static __inline__ unsigned int -log_distance(struct gfs_sbd *sdp, uint64_t newer, uint64_t older) -{ - int64_t dist; - - dist = newer - older; - if (dist < 0) - dist += sdp->sd_jdesc.ji_nsegment * sdp->sd_sb.sb_seg_size; - - return dist; -} - -/** - * log_incr_head - Increment journal head (next block to fill in journal) - * @sdp: The GFS superblock - * @head: the variable holding the head of the journal - * - * Increment journal head by one. - * At the end of the journal, wrap head back to the start. - * Don't confuse journal/log head with a gfs_log_header! - */ - -static __inline__ void -log_incr_head(struct gfs_sbd *sdp, uint64_t * head) -{ - struct gfs_jindex *jdesc = &sdp->sd_jdesc; - - if (++*head == - jdesc->ji_addr + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size) - *head = jdesc->ji_addr; -} - -/** - * gfs_ail_start - Start I/O on the AIL - * @sdp: the filesystem - * @flags: DIO_ALL -- flush *all* AIL transactions to disk - * default -- flush first-on-list AIL transaction to disk - * - */ - -void -gfs_ail_start(struct gfs_sbd *sdp, int flags) -{ - struct list_head *head = &sdp->sd_log_ail; - struct list_head *first, *tmp; - struct gfs_trans *first_tr, *tr; - - gfs_log_lock(sdp); - - if (list_empty(head)) { - gfs_log_unlock(sdp); - return; - } - - first = head->prev; - first_tr = list_entry(first, struct gfs_trans, tr_list); - gfs_ail_start_trans(sdp, first_tr); - - if (flags & DIO_ALL) - first_tr = NULL; - - for (tmp = first->prev; tmp != head; tmp = tmp->prev) { - if (first_tr && gfs_ail_empty_trans(sdp, first_tr)) - break; - - tr = list_entry(tmp, struct gfs_trans, tr_list); - gfs_ail_start_trans(sdp, tr); - } - - gfs_log_unlock(sdp); -} - -/** - * current_tail - Find block number of current log tail - * @sdp: The GFS superblock - * - * Find the block number of the current tail of the log. - * Assumes that the log lock is held. - * - * Returns: The tail's block number (must be on a log segment boundary) - */ - -static uint64_t -current_tail(struct gfs_sbd *sdp) -{ - struct gfs_trans *tr; - uint64_t tail; - - if (list_empty(&sdp->sd_log_ail)) { - tail = sdp->sd_log_head; - - if (!gfs_log_is_header(sdp, tail)) { - tail--; - gfs_assert(sdp, gfs_log_is_header(sdp, tail), ); - } - } else { - tr = list_entry(sdp->sd_log_ail.prev, - struct gfs_trans, tr_list); - tail = tr->tr_first_head; - } - - return tail; -} - -/** - * gfs_ail_empty - move the tail of the log forward (if possible) - * @sdp: the filesystem - * - * Returns: TRUE if the AIL is empty - * - * Checks each transaction on sd_log_ail, to see if it has been successfully - * flushed to in-place blocks on disk. If so, removes trans from sd_log_ail, - * effectively advancing the tail of the log (freeing log segments so they - * can be overwritten). - * Adds # freed log segments to sd_log_seg_free. - */ - -int -gfs_ail_empty(struct gfs_sbd *sdp) -{ - struct list_head *head, *tmp, *prev; - struct gfs_trans *tr; - uint64_t oldtail, newtail; - unsigned int dist; - unsigned int segments; - int ret; - - gfs_log_lock(sdp); - - oldtail = current_tail(sdp); - - for (head = &sdp->sd_log_ail, tmp = head->prev, prev = tmp->prev; - tmp != head; - tmp = prev, prev = tmp->prev) { - tr = list_entry(tmp, struct gfs_trans, tr_list); - if (gfs_ail_empty_trans(sdp, tr)) { - list_del(&tr->tr_list); - kfree(tr); - } - } - - newtail = current_tail(sdp); - - if (oldtail != newtail) { - dist = log_distance(sdp, newtail, oldtail); - - segments = dist / sdp->sd_sb.sb_seg_size; - gfs_assert(sdp, segments * sdp->sd_sb.sb_seg_size == dist,); - - sdp->sd_log_seg_ail2 += segments; - gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= - sdp->sd_jdesc.ji_nsegment,); - } - - ret = list_empty(head); - - gfs_log_unlock(sdp); - - return ret; -} - -/** - * gfs_log_reserve - Make a log reservation - * @sdp: The GFS superblock - * @segments: The number of segments to reserve - * @jump_queue: if TRUE, don't care about fairness ordering - * - * Returns: errno - */ - -int -gfs_log_reserve(struct gfs_sbd *sdp, unsigned int segments, int jump_queue) -{ - struct list_head list; - unsigned int try = 0; - - if (gfs_assert_warn(sdp, segments)) - return -EINVAL; - if (gfs_assert_warn(sdp, segments < sdp->sd_jdesc.ji_nsegment)) - return -EINVAL; - - INIT_LIST_HEAD(&list); - - for (;;) { - spin_lock(&sdp->sd_log_seg_lock); - - if (list_empty(&list)) { - if (jump_queue) - list_add(&list, &sdp->sd_log_seg_list); - else { - list_add_tail(&list, &sdp->sd_log_seg_list); - while (sdp->sd_log_seg_list.next != &list) { - DECLARE_WAITQUEUE(__wait_chan, current); - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&sdp->sd_log_seg_wait, - &__wait_chan); - spin_unlock(&sdp->sd_log_seg_lock); - schedule(); - spin_lock(&sdp->sd_log_seg_lock); - remove_wait_queue(&sdp->sd_log_seg_wait, - &__wait_chan); - set_current_state(TASK_RUNNING); - } - } - } - - if (sdp->sd_log_seg_free > segments) { - sdp->sd_log_seg_free -= segments; - list_del(&list); - spin_unlock(&sdp->sd_log_seg_lock); - wake_up(&sdp->sd_log_seg_wait); - break; - } - - spin_unlock(&sdp->sd_log_seg_lock); - - if (try) { - gfs_log_flush(sdp); - gfs_ail_start(sdp, 0); - } - - gfs_ail_empty(sdp); - - try++; - yield(); - } - - return 0; -} - -/** - * gfs_log_release - Release a given number of log segments - * @sdp: The GFS superblock - * @segments: The number of segments - * - */ - -void -gfs_log_release(struct gfs_sbd *sdp, unsigned int segments) -{ - spin_lock(&sdp->sd_log_seg_lock); - sdp->sd_log_seg_free += segments; - gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= - sdp->sd_jdesc.ji_nsegment,); - spin_unlock(&sdp->sd_log_seg_lock); -} - -/** - * log_get_header - Get and initialize a journal header buffer - * @sdp: The GFS superblock - * @tr: The transaction that needs a log header - * @next: FALSE if this log header appears in midst of current transaction - * TRUE if this starts next transaction (and commits current trans) - * - * Returns: the initialized log buffer descriptor - * - * Initialize one of the transaction's pre-allocated buffers (and associated - * log buffer descriptor) to be a log header for this transaction. - * A log header gets written to *each* log segment boundary block, so journal - * recovery will quickly be able to get its bearings. A single transaction - * may span several log segments, which means that log headers will appear - * in the midst of that transaction (@next == FALSE). These headers get - * added to trans' list of buffers to write to log. - * Log commit is accomplished by writing the log header for the next - * transaction (@next == TRUE), with pre-incremented sequence number, - * and updated first-in-transaction block number. These headers do *not* get - * added to trans' buffer list, since they are written separately to disk - * *after* the trans gets completely flushed to on-disk log. - * NOTE: This buffer will *not* get written to an in-place location in the - * filesystem; it is for use only within the log. - */ - -static struct gfs_log_buf * -log_get_header(struct gfs_sbd *sdp, struct gfs_trans *tr, int next) -{ - struct gfs_log_buf *lb; - struct list_head *bmem; - struct gfs_log_header header; - - /* Make sure we're on a log segment boundary block */ - gfs_assert(sdp, gfs_log_is_header(sdp, tr->tr_log_head),); - - /* Grab a free log buffer descriptor (attached to trans) */ - gfs_assert(sdp, tr->tr_num_free_bufs && - !list_empty(&tr->tr_free_bufs),); - lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); - list_del(&lb->lb_list); - tr->tr_num_free_bufs--; - - /* Grab a free log buffer (attached to trans) */ - gfs_assert(sdp, tr->tr_num_free_bmem && - !list_empty(&tr->tr_free_bmem),); - bmem = tr->tr_free_bmem.next; - list_del(bmem); - tr->tr_num_free_bmem--; - - /* Create "fake" bh to write bmem to log header block */ - gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, (char *)bmem); - memset(bmem, 0, sdp->sd_sb.sb_bsize); - - memset(&header, 0, sizeof (header)); - - if (next) { - /* Fill in header for next transaction, committing previous */ - header.lh_header.mh_magic = GFS_MAGIC; - header.lh_header.mh_type = GFS_METATYPE_LH; - header.lh_header.mh_format = GFS_FORMAT_LH; - header.lh_first = tr->tr_log_head; - header.lh_sequence = sdp->sd_sequence + 1; - header.lh_tail = current_tail(sdp); - header.lh_last_dump = sdp->sd_log_dump_last; - } else { - /* Fill in another header for this transaction */ - header.lh_header.mh_magic = GFS_MAGIC; - header.lh_header.mh_type = GFS_METATYPE_LH; - header.lh_header.mh_format = GFS_FORMAT_LH; - header.lh_first = tr->tr_first_head; - header.lh_sequence = sdp->sd_sequence; - header.lh_tail = current_tail(sdp); - header.lh_last_dump = sdp->sd_log_dump_last; - - /* Attach log header buf to trans' list of bufs going to log */ - list_add(&lb->lb_list, &tr->tr_bufs); - } - - /* Copy log header struct to beginning and end of buffer's 1st 512B */ - gfs_log_header_out(&header, lb->lb_bh.b_data); - gfs_log_header_out(&header, - lb->lb_bh.b_data + GFS_BASIC_BLOCK - - sizeof(struct gfs_log_header)); - - /* Find next log buffer to fill */ - log_incr_head(sdp, &tr->tr_log_head); - - return lb; -} - -/** - * gfs_log_get_buf - Get and initialize a buffer to use for log control data - * @sdp: The GFS superblock - * @tr: The GFS transaction - * - * Initialize one of the transaction's pre-allocated buffers (and associated - * log buffer descriptor) to be used for log control data (e.g. log tags). - * Make sure this buffer is attached to the transaction, to be logged to disk. - * NOTE: This buffer will *not* get written to an in-place location in the - * filesystem; it is for use only within the log. - * - * Returns: the log buffer descriptor - */ - -struct gfs_log_buf * -gfs_log_get_buf(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_log_buf *lb; - struct list_head *bmem; - - /* If next block in log is on a segment boundary, we need to - write a log header */ - if (gfs_log_is_header(sdp, tr->tr_log_head)) - log_get_header(sdp, tr, FALSE); - - /* Grab a free buffer descriptor (attached to trans) */ - gfs_assert(sdp, tr->tr_num_free_bufs && - !list_empty(&tr->tr_free_bufs),); - lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); - list_del(&lb->lb_list); - tr->tr_num_free_bufs--; - - /* Grab a free buffer (attached to trans) */ - gfs_assert(sdp, tr->tr_num_free_bmem - && !list_empty(&tr->tr_free_bmem),); - bmem = tr->tr_free_bmem.next; - list_del(bmem); - tr->tr_num_free_bmem--; - - /* Create "fake" bh to write bmem to log block */ - gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, (char *)bmem); - memset(bmem, 0, sdp->sd_sb.sb_bsize); - - list_add(&lb->lb_list, &tr->tr_bufs); - - /* Find next log buffer to fill */ - log_incr_head(sdp, &tr->tr_log_head); - - return lb; -} - -/** - * gfs_log_fake_buf - Build a fake buffer head to write metadata buffer to log - * @sdp: the filesystem - * @tr: the transaction this is part of - * @data: the data the buffer_head should point to - * @unlock: a buffer_head to be unlocked when struct gfs_log_buf is torn down - * (i.e. the "real" buffer_head that will write to in-place location) - * - * Initialize one of the transaction's pre-allocated log buffer descriptors - * to be used for writing a metadata buffer into the log. - * Make sure this buffer is attached to the transaction, to be logged to disk. - * NOTE: This buffer *will* be written to in-place location within filesytem, - * in addition to being written into the log. - * - */ - -void -gfs_log_fake_buf(struct gfs_sbd *sdp, struct gfs_trans *tr, char *data, - struct buffer_head *unlock) -{ - struct gfs_log_buf *lb; - - if (gfs_log_is_header(sdp, tr->tr_log_head)) - log_get_header(sdp, tr, FALSE); - - /* Grab a free buffer descriptor (attached to trans) */ - gfs_assert(sdp, tr->tr_num_free_bufs && - !list_empty(&tr->tr_free_bufs),); - lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); - list_del(&lb->lb_list); - tr->tr_num_free_bufs--; - - /* Create "fake" bh to write data to log block */ - gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, data); - lb->lb_unlock = unlock; - - list_add(&lb->lb_list, &tr->tr_bufs); - - /* Find next log buffer to fill */ - log_incr_head(sdp, &tr->tr_log_head); -} - -/** - * check_seg_usage - Check that we didn't use too many segments - * @sdp: The GFS superblock - * @tr: The transaction - * - * Also, make sure we don't write ever get to a point where there are - * no dumps in the log (corrupting the log). Panic before we let - * that happen. - * - */ - -static void -check_seg_usage(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_jindex *jdesc = &sdp->sd_jdesc; - unsigned int dist; - unsigned int segments; - uint64_t head_off, head_wrap; - uint64_t dump_off, dump_wrap; - - dist = log_distance(sdp, tr->tr_log_head, tr->tr_first_head); - - segments = dist / sdp->sd_sb.sb_seg_size; - gfs_assert(sdp, segments * sdp->sd_sb.sb_seg_size == dist,); - gfs_assert(sdp, segments == tr->tr_seg_reserved,); - - if (sdp->sd_log_dump_last) { - int diff; - - head_off = tr->tr_first_head + - tr->tr_seg_reserved * sdp->sd_sb.sb_seg_size; - head_wrap = sdp->sd_log_wrap; - if (head_off >= jdesc->ji_addr + - jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size) { - head_off -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; - head_wrap++; - } - - dump_off = sdp->sd_log_dump_last; - dump_wrap = sdp->sd_log_dump_last_wrap; - - diff = (int)(head_wrap - dump_wrap); - switch (diff) { - case 0: - break; - - case 1: - if (head_off < dump_off - sdp->sd_sb.sb_seg_size) - break; - else if (head_off <= dump_off && - (tr->tr_flags & TRF_LOG_DUMP)) - break; - - default: - gfs_assert(sdp, FALSE, - printk("GFS: fsid=%s: head_off = %"PRIu64", head_wrap = %"PRIu64"\n" - "GFS: fsid=%s: dump_off = %"PRIu64", dump_wrap = %"PRIu64"\n", - sdp->sd_fsname, head_off, head_wrap, - sdp->sd_fsname, dump_off, dump_wrap);); - break; - } - } -} - -/** - * log_free_buf - Free a struct gfs_log_buf (and possibly the data it points to) - * @sdp: the filesystem - * @lb: the log buffer descriptor - * - * If buffer contains (meta)data to be written into filesystem in-place block, - * descriptor will point to the "real" (lb_unlock) buffer head. Unlock it. - * If buffer was used only for log header or control data (e.g. tags), we're - * done with it as soon as it gets written to on-disk log. Free it. - * Either way, we can free the log descriptor structure. - */ - -static void -log_free_buf(struct gfs_sbd *sdp, struct gfs_log_buf *lb) -{ - char *bmem; - - bmem = lb->lb_bh.b_data; - gfs_logbh_uninit(sdp, &lb->lb_bh); - - if (lb->lb_unlock) - gfs_unlock_buffer(lb->lb_unlock); - else - kfree(bmem); - - kfree(lb); -} - -/** - * sync_trans - Add "last" descriptor, sync transaction to on-disk log - * @sdp: The GFS superblock - * @tr: The transaction - * - * Add the "last" descriptor onto the end of the current transaction - * and sync the whole transaction out to on-disk log. - * Don't log-commit (i.e. write next transaction's log header) yet, though. - * - * Returns: errno - */ - -static int -sync_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *tmp, *head, *prev; - struct gfs_log_descriptor desc; - struct gfs_log_buf *lb; - uint64_t blk; - int error = 0, e; - - /* Build LAST descriptor */ - - lb = gfs_log_get_buf(sdp, tr); - - memset(&desc, 0, sizeof(struct gfs_log_descriptor)); - desc.ld_header.mh_magic = GFS_MAGIC; - desc.ld_header.mh_type = GFS_METATYPE_LD; - desc.ld_header.mh_format = GFS_FORMAT_LD; - desc.ld_type = GFS_LOG_DESC_LAST; - desc.ld_length = 1; - for (blk = tr->tr_log_head; !gfs_log_is_header(sdp, blk); blk++) - desc.ld_length++; - gfs_desc_out(&desc, lb->lb_bh.b_data); - - while (!gfs_log_is_header(sdp, tr->tr_log_head)) - log_incr_head(sdp, &tr->tr_log_head); - - check_seg_usage(sdp, tr); - - /* Start I/O - Go in "prev" direction to start the I/O in order. */ - - for (head = &tr->tr_bufs, tmp = head->prev, prev = tmp->prev; - tmp != head; - tmp = prev, prev = tmp->prev) { - lb = list_entry(tmp, struct gfs_log_buf, lb_list); - gfs_logbh_start(sdp, &lb->lb_bh); - } - - /* Wait on I/O - Go in "next" direction to minimize sleeps/wakeups. */ - - while (!list_empty(&tr->tr_bufs)) { - lb = list_entry(tr->tr_bufs.next, struct gfs_log_buf, lb_list); - - e = gfs_logbh_wait(sdp, &lb->lb_bh); - if (e) - error = e; - - list_del(&lb->lb_list); - log_free_buf(sdp, lb); - } - - return error; -} - -/** - * commit_trans - Commit the current transaction - * @sdp: The GFS superblock - * @tr: The transaction - * - * Write next header to commit - * - * Returns: errno - */ - -static int -commit_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_log_buf *lb; - int error; - - lb = log_get_header(sdp, tr, TRUE); - - gfs_logbh_start(sdp, &lb->lb_bh); - error = gfs_logbh_wait(sdp, &lb->lb_bh); - if (!error) { - spin_lock(&sdp->sd_log_seg_lock); - if (!(tr->tr_flags & TRF_DUMMY)) - sdp->sd_log_seg_free += sdp->sd_log_seg_ail2; - else - sdp->sd_log_seg_free += (sdp->sd_log_seg_ail2 - 1); - sdp->sd_log_seg_ail2 = 0; - spin_unlock(&sdp->sd_log_seg_lock); - } - log_free_buf(sdp, lb); - - return error; -} - -/** - * disk_commit - Write a transaction to the on-disk journal - * @sdp: The GFS superblock - * @tr: The transaction - * - * Returns: errno - */ - -static int -disk_commit(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - uint64_t last_dump, last_dump_wrap; - int error = 0; - - gfs_assert(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags),); - tr->tr_log_head = sdp->sd_log_head; - tr->tr_first_head = tr->tr_log_head - 1; - gfs_assert(sdp, gfs_log_is_header(sdp, tr->tr_first_head),); - - LO_BUILD_BHLIST(sdp, tr); - - if (!(tr->tr_flags & TRF_DUMMY)) - gfs_assert(sdp, !list_empty(&tr->tr_bufs),); - - error = sync_trans(sdp, tr); - if (error) { - /* Eat unusable commit buffer */ - log_free_buf(sdp, log_get_header(sdp, tr, TRUE)); - goto out; - } - - if (tr->tr_flags & TRF_LOG_DUMP) { - /* This commit header should point to the log dump we're - commiting as the current one. But save the copy of the - old one in case we have problems commiting the dump. */ - - last_dump = sdp->sd_log_dump_last; - last_dump_wrap = sdp->sd_log_dump_last_wrap; - - sdp->sd_log_dump_last = tr->tr_first_head; - sdp->sd_log_dump_last_wrap = sdp->sd_log_wrap; - - error = commit_trans(sdp, tr); - if (error) { - sdp->sd_log_dump_last = last_dump; - sdp->sd_log_dump_last_wrap = last_dump_wrap; - goto out; - } - } else { - error = commit_trans(sdp, tr); - if (error) - goto out; - } - - if (sdp->sd_log_head > tr->tr_log_head) - sdp->sd_log_wrap++; - sdp->sd_log_head = tr->tr_log_head; - sdp->sd_sequence++; - - out: - gfs_assert_warn(sdp, !tr->tr_num_free_bufs && - list_empty(&tr->tr_free_bufs)); - gfs_assert_warn(sdp, !tr->tr_num_free_bmem && - list_empty(&tr->tr_free_bmem)); - - return error; -} - -/** - * add_trans_to_ail - Add a ondisk commited transaction to the AIL - * @sdp: the filesystem - * @tr: the transaction - * - */ - -static void -add_trans_to_ail(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_log_element *le; - - while (!list_empty(&tr->tr_elements)) { - le = list_entry(tr->tr_elements.next, - struct gfs_log_element, le_list); - LO_ADD_TO_AIL(sdp, le); - } - - list_add(&tr->tr_list, &sdp->sd_log_ail); -} - -/** - * log_refund - Refund log segments to the free pool - * @sdp: The GFS superblock - * @tr: The transaction to examine - * - * Look at the number of segments reserved for this transaction and the - * number of segments actually needed for it. If they aren't the - * same, refund the difference to the free segment pool. - * - * De-alloc any unneeded log buffers and log buffer descriptors. - * - * Called with the log lock held. - */ - -static void -log_refund(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_log_buf *lb; - struct list_head *bmem; - unsigned int num_bufs = 0, num_bmem = 0; - unsigned int segments; - - LO_TRANS_SIZE(sdp, tr, NULL, NULL, &num_bufs, &num_bmem); - - segments = gfs_blk2seg(sdp, num_bufs + 1); - num_bufs += segments + 1; - num_bmem += segments + 1; - - /* Unreserve unneeded log segments */ - if (tr->tr_seg_reserved > segments) { - spin_lock(&sdp->sd_log_seg_lock); - sdp->sd_log_seg_free += tr->tr_seg_reserved - segments; - gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= - sdp->sd_jdesc.ji_nsegment,); - spin_unlock(&sdp->sd_log_seg_lock); - - tr->tr_seg_reserved = segments; - } else - gfs_assert(sdp, tr->tr_seg_reserved == segments,); - - /* De-alloc unneeded log buffer descriptors */ - gfs_assert(sdp, tr->tr_num_free_bufs >= num_bufs,); - while (tr->tr_num_free_bufs > num_bufs) { - lb = list_entry(tr->tr_free_bufs.next, - struct gfs_log_buf, lb_list); - list_del(&lb->lb_list); - kfree(lb); - tr->tr_num_free_bufs--; - } - - /* De-alloc unneeded log buffers */ - gfs_assert(sdp, tr->tr_num_free_bmem >= num_bmem,); - while (tr->tr_num_free_bmem > num_bmem) { - bmem = tr->tr_free_bmem.next; - list_del(bmem); - kfree(bmem); - tr->tr_num_free_bmem--; - } -} - -/** - * trans_combine - combine two transactions - * @sdp: the filesystem - * @tr: the surviving transaction - * @new_tr: the transaction that gets freed - * - * Assumes that the two transactions are independent. - */ - -static void -trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_trans *new_tr) -{ - struct gfs_log_element *le; - struct gfs_log_buf *lb; - struct list_head *bmem; - - tr->tr_file = __FILE__; - tr->tr_line = __LINE__; - tr->tr_seg_reserved += new_tr->tr_seg_reserved; - tr->tr_flags |= new_tr->tr_flags; - tr->tr_num_free_bufs += new_tr->tr_num_free_bufs; - tr->tr_num_free_bmem += new_tr->tr_num_free_bmem; - - /* Combine the log elements of the two transactions */ - - while (!list_empty(&new_tr->tr_elements)) { - le = list_entry(new_tr->tr_elements.next, - struct gfs_log_element, le_list); - gfs_assert(sdp, le->le_trans == new_tr,); - le->le_trans = tr; - list_move(&le->le_list, &tr->tr_elements); - } - - LO_TRANS_COMBINE(sdp, tr, new_tr); - - /* Move free log buffer descriptors to surviving trans */ - while (!list_empty(&new_tr->tr_free_bufs)) { - lb = list_entry(new_tr->tr_free_bufs.next, - struct gfs_log_buf, lb_list); - list_move(&lb->lb_list, &tr->tr_free_bufs); - new_tr->tr_num_free_bufs--; - } - /* Move free log buffers to surviving trans */ - while (!list_empty(&new_tr->tr_free_bmem)) { - bmem = new_tr->tr_free_bmem.next; - list_move(bmem, &tr->tr_free_bmem); - new_tr->tr_num_free_bmem--; - } - - gfs_assert_warn(sdp, !new_tr->tr_num_free_bufs); - gfs_assert_warn(sdp, !new_tr->tr_num_free_bmem); - - kfree(new_tr); -} - -static void -make_dummy_transaction(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_log_buf *lb; - struct list_head *bmem; - - memset(tr, 0, sizeof(struct gfs_trans)); - INIT_LIST_HEAD(&tr->tr_list); - INIT_LIST_HEAD(&tr->tr_elements); - INIT_LIST_HEAD(&tr->tr_free_bufs); - INIT_LIST_HEAD(&tr->tr_free_bmem); - INIT_LIST_HEAD(&tr->tr_bufs); - INIT_LIST_HEAD(&tr->tr_ail_bufs); - tr->tr_flags = TRF_DUMMY; - tr->tr_file = __FILE__; - tr->tr_line = __LINE__; - tr->tr_seg_reserved = 1; - while (tr->tr_num_free_bufs < 2) { - lb = gmalloc(sizeof(struct gfs_log_buf)); - memset(lb, 0, sizeof(struct gfs_log_buf)); - list_add(&lb->lb_list, &tr->tr_free_bufs); - tr->tr_num_free_bufs++; - } - while (tr->tr_num_free_bmem < 2) { - bmem = gmalloc(sdp->sd_sb.sb_bsize); - list_add(bmem, &tr->tr_free_bmem); - tr->tr_num_free_bmem++; - } -} - - -/** - * log_flush_internal - flush incore transaction(s) - * @sdp: the filesystem - * @gl: The glock structure to flush. If NULL, flush the whole incore log - * - * If a glock is provided, we flush, to on-disk log, all of the metadata for - * the one incore-committed (complete, but not-yet-flushed-to-log) - * transaction that the glock protects. - * If NULL, we combine *all* of the filesystem's incore-committed - * transactions into one big transaction, and flush it to the log. - */ - -static void -log_flush_internal(struct gfs_sbd *sdp, struct gfs_glock *gl) -{ - - struct gfs_trans *trans = NULL, *tr; - int error; - - gfs_log_lock(sdp); - - if (!gl && list_empty(&sdp->sd_log_incore)) { - if (sdp->sd_log_seg_ail2) { - trans = gmalloc(sizeof(struct gfs_trans)); - make_dummy_transaction(sdp, trans); - } - else - goto out; - } - - if (gl) { - if (!gl->gl_incore_le.le_trans) - goto out; - - trans = gl->gl_incore_le.le_trans; - - list_del(&trans->tr_list); - } else { - /* combine *all* transactions in incore list */ - while (!list_empty(&sdp->sd_log_incore)) { - tr = list_entry(sdp->sd_log_incore.next, - struct gfs_trans, tr_list); - - list_del(&tr->tr_list); - - if (trans) - trans_combine(sdp, trans, tr); - else - trans = tr; - } - } - - log_refund(sdp, trans); - - /* Actually do the stuff to commit the transaction */ - - error = disk_commit(sdp, trans); - if (error) - gfs_io_error(sdp); - - add_trans_to_ail(sdp, trans); - - if (log_distance(sdp, sdp->sd_log_head, sdp->sd_log_dump_last) * GFS_DUMPS_PER_LOG >= - sdp->sd_jdesc.ji_nsegment * sdp->sd_sb.sb_seg_size) - set_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags); - - out: - if (list_empty(&sdp->sd_log_incore)) - sdp->sd_vfs->s_dirt = FALSE; - - gfs_log_unlock(sdp); -} - -/** - * gfs_log_flush - flush the whole incore log - * @sdp: the filesystem - * - */ - -void -gfs_log_flush(struct gfs_sbd *sdp) -{ - down(&sdp->sd_log_flush_lock); /* unlocked in gfs_sync_buf */ - log_flush_internal(sdp, NULL); - up(&sdp->sd_log_flush_lock); /* locked in log_flush_internal */ - - /* Dump if we need to. */ - - if (test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) - gfs_log_dump(sdp, FALSE); -} - -/** - * ail_empty_gl - remove all buffers for a given lock from the AIL - * @gl: the glock - * - * None of the buffers should be dirty, locked, or pinned. - */ - -static void -ail_empty_gl(struct gfs_glock *gl) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_bufdata *bd; - struct list_head *pos, *tmp; - - spin_lock(&sdp->sd_ail_lock); - - list_for_each_safe(pos, tmp, &gl->gl_ail_bufs) { - bd = list_entry(pos, struct gfs_bufdata, bd_ail_gl_list); - gfs_bd_ail_tryremove(sdp, bd); - } - - spin_unlock(&sdp->sd_ail_lock); -} - -/** - * gfs_inval_buf - Invalidate all buffers associated with a glock - * @gl: the glock - * - */ - -void -gfs_inval_buf(struct gfs_glock *gl) -{ - struct inode *aspace = gl->gl_aspace; - struct address_space *mapping = gl->gl_aspace->i_mapping; - - /*down(&gl->gl_sbd->sd_log_flush_lock);*/ - ail_empty_gl(gl); - - atomic_inc(&aspace->i_writecount); - truncate_inode_pages(mapping, 0); - atomic_dec(&aspace->i_writecount); - - gfs_assert_withdraw(gl->gl_sbd, !mapping->nrpages); - /*up(&gl->gl_sbd->sd_log_flush_lock);*/ -} - -/** - * gfs_sync_buf - Sync all buffers associated with a glock - * @gl: The glock - * @flags: DIO_START | DIO_WAIT | DIO_CHECK - * - */ - -static void -gfs_sync_buf(struct gfs_glock *gl, int flags) -{ - struct address_space *mapping = gl->gl_aspace->i_mapping; - int error = 0; - - error = filemap_fdatawrite(mapping); - if (!error) - error = filemap_fdatawait(mapping); - if (!error) { - if (!(flags & DIO_INVISIBLE)) - ail_empty_gl(gl); - } - if (error) - gfs_io_error(gl->gl_sbd); - -} - -/** - * gfs_log_flush_glock - flush the incore log for a glock - * @gl: the glock - * - */ - -void -gfs_log_flush_glock(struct gfs_glock *gl, int flags) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - - down(&sdp->sd_log_flush_lock); - log_flush_internal(gl->gl_sbd, gl); - if (flags) - gfs_sync_buf(gl, flags | DIO_CHECK); - up(&sdp->sd_log_flush_lock); - - /* Dump if we need to. */ - - if (test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) - gfs_log_dump(sdp, FALSE); -} - -/** - * incore_commit - commit a transaction in-core - * @sdp: the filesystem - * @new_tr: the transaction to commit - * - * Add the transaction @new_tr to the end of the incore commit list. - * Pull up and merge any previously committed transactions that share - * locks. Also pull up any rename transactions that need it. - */ - -static void -incore_commit(struct gfs_sbd *sdp, struct gfs_trans *new_tr) -{ - struct gfs_log_element *le; - struct gfs_trans *trans = NULL, *exist_tr; - struct gfs_log_buf *lb; - struct list_head *bmem; - struct list_head *tmp, *head, *next; - - for (head = &new_tr->tr_elements, tmp = head->next; - tmp != head; - tmp = tmp->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - - /* Do overlap_trans log-op, if any, to find another - incore transaction with which we can combine new_tr */ - exist_tr = LO_OVERLAP_TRANS(sdp, le); - if (!exist_tr) - continue; - - if (exist_tr != trans) { - /* remove trans from superblock's sd_log_incore list */ - list_del(&exist_tr->tr_list); - - /* Maybe there's more than one that can be combined. - If so, combine them together before merging new_tr */ - if (trans) - trans_combine(sdp, trans, exist_tr); - else - trans = exist_tr; - } - } - - /* Yes, we can combine new_tr with pre-existing transaction(s) */ - if (trans) { - trans->tr_file = __FILE__; - trans->tr_line = __LINE__; - trans->tr_seg_reserved += new_tr->tr_seg_reserved; - trans->tr_flags |= new_tr->tr_flags; - trans->tr_num_free_bufs += new_tr->tr_num_free_bufs; - trans->tr_num_free_bmem += new_tr->tr_num_free_bmem; - - /* Move free log buffer descriptors to surviving trans */ - while (!list_empty(&new_tr->tr_free_bufs)) { - lb = list_entry(new_tr->tr_free_bufs.next, - struct gfs_log_buf, lb_list); - list_move(&lb->lb_list, &trans->tr_free_bufs); - new_tr->tr_num_free_bufs--; - } - - /* Move free log buffers to surviving trans */ - while (!list_empty(&new_tr->tr_free_bmem)) { - bmem = new_tr->tr_free_bmem.next; - list_move(bmem, &trans->tr_free_bmem); - new_tr->tr_num_free_bmem--; - } - } else - trans = new_tr; - - /* Do incore_commit log-op for each *new* log element (in new_tr). - Each commit log-op removes its log element from "new_tr" LE list, - and attaches an LE to "trans" LE list; if there was no trans - combining, "new_tr" is the same transaction as "trans". */ - for (head = &new_tr->tr_elements, tmp = head->next, next = tmp->next; - tmp != head; - tmp = next, next = next->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - LO_INCORE_COMMIT(sdp, trans, le); - } - - /* If we successfully combined transactions, new_tr should be empty */ - if (trans != new_tr) { - gfs_assert_warn(sdp, !new_tr->tr_num_free_bufs); - gfs_assert_warn(sdp, !new_tr->tr_num_free_bmem); - gfs_assert_warn(sdp, list_empty(&new_tr->tr_elements)); - kfree(new_tr); - } - - /* If we successfully combined transactions, we might have some log - segments that we reserved, and log buffers and buffer descriptors - that we allocated, but now don't need. */ - log_refund(sdp, trans); - - list_add(&trans->tr_list, &sdp->sd_log_incore); -} - -/** - * gfs_log_commit - Commit a transaction to the log - * @sdp: the filesystem - * @tr: the transaction - * - * Returns: errno - */ - -void -gfs_log_commit(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct gfs_log_buf *lb; - struct list_head *bmem; - unsigned int num_mblks = 0, num_eblks = 0, num_bufs = 0, num_bmem = 0; - unsigned int segments; - - /* Calculate actual log area needed for this trans */ - LO_TRANS_SIZE(sdp, tr, &num_mblks, &num_eblks, &num_bufs, &num_bmem); - - gfs_assert(sdp, num_mblks <= tr->tr_mblks_asked && - num_eblks <= tr->tr_eblks_asked, - printk("GFS: fsid=%s: type = (%s, %u)\n" - "GFS: fsid=%s: num_mblks = %u, tr->tr_mblks_asked = %u\n" - "GFS: fsid=%s: num_eblks = %u, tr->tr_eblks_asked = %u\n", - sdp->sd_fsname, tr->tr_file, tr->tr_line, - sdp->sd_fsname, num_mblks, tr->tr_mblks_asked, - sdp->sd_fsname, num_eblks, tr->tr_eblks_asked);); - - segments = gfs_blk2seg(sdp, num_bufs + 1); - num_bufs += segments + 1; - num_bmem += segments + 1; - - /* Alloc log buffer descriptors */ - while (num_bufs--) { - lb = gmalloc(sizeof(struct gfs_log_buf)); - memset(lb, 0, sizeof(struct gfs_log_buf)); - list_add(&lb->lb_list, &tr->tr_free_bufs); - tr->tr_num_free_bufs++; - } - /* Alloc log buffers */ - while (num_bmem--) { - bmem = gmalloc(sdp->sd_sb.sb_bsize); - list_add(bmem, &tr->tr_free_bmem); - tr->tr_num_free_bmem++; - } - - gfs_log_lock(sdp); - - incore_commit(sdp, tr); - - /* Flush log buffers to disk if we're over the threshold */ - if (sdp->sd_log_buffers > gfs_tune_get(sdp, gt_incore_log_blocks)) { - gfs_log_unlock(sdp); - gfs_log_flush(sdp); - } else { - sdp->sd_vfs->s_dirt = TRUE; - gfs_log_unlock(sdp); - } - -} - -/** - * gfs_log_dump - make a Log Dump entry in the log - * @sdp: the filesystem - * @force: if TRUE, always make the dump even if one has been made recently - * - */ - -void -gfs_log_dump(struct gfs_sbd *sdp, int force) -{ - struct gfs_log_element *le; - struct gfs_trans tr; - struct gfs_log_buf *lb; - struct list_head *bmem; - unsigned int num_bufs, num_bmem; - unsigned int segments; - int error; - - if (test_and_set_bit(SDF_IN_LOG_DUMP, &sdp->sd_flags)) { - gfs_assert(sdp, !force,); - return; - } - - memset(&tr, 0, sizeof(struct gfs_trans)); - INIT_LIST_HEAD(&tr.tr_elements); - INIT_LIST_HEAD(&tr.tr_free_bufs); - INIT_LIST_HEAD(&tr.tr_free_bmem); - INIT_LIST_HEAD(&tr.tr_bufs); - tr.tr_flags = TRF_LOG_DUMP; - tr.tr_file = __FILE__; - tr.tr_line = __LINE__; - - for (;;) { - gfs_log_lock(sdp); - - if (!force && !test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) - goto out; - - num_bufs = num_bmem = 0; - LO_DUMP_SIZE(sdp, NULL, &num_bufs, &num_bmem); - gfs_assert(sdp, num_bufs,); - segments = gfs_blk2seg(sdp, num_bufs + 1); - num_bufs += segments + 1; - num_bmem += segments + 1; - - if (tr.tr_seg_reserved >= segments && - tr.tr_num_free_bufs >= num_bufs && - tr.tr_num_free_bmem >= num_bmem) - break; - - gfs_log_unlock(sdp); - - if (tr.tr_seg_reserved < segments) { - error = gfs_log_reserve(sdp, - segments - tr.tr_seg_reserved, - TRUE); - gfs_assert(sdp, !error,); - tr.tr_seg_reserved = segments; - } - while (tr.tr_num_free_bufs < num_bufs) { - lb = gmalloc(sizeof(struct gfs_log_buf)); - memset(lb, 0, sizeof(struct gfs_log_buf)); - list_add(&lb->lb_list, &tr.tr_free_bufs); - tr.tr_num_free_bufs++; - } - while (tr.tr_num_free_bmem < num_bmem) { - bmem = gmalloc(sdp->sd_sb.sb_bsize); - list_add(bmem, &tr.tr_free_bmem); - tr.tr_num_free_bmem++; - } - } - - if (tr.tr_seg_reserved > segments) { - spin_lock(&sdp->sd_log_seg_lock); - sdp->sd_log_seg_free += tr.tr_seg_reserved - segments; - gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= - sdp->sd_jdesc.ji_nsegment,); - spin_unlock(&sdp->sd_log_seg_lock); - tr.tr_seg_reserved = segments; - } - while (tr.tr_num_free_bufs > num_bufs) { - lb = list_entry(tr.tr_free_bufs.next, - struct gfs_log_buf, lb_list); - list_del(&lb->lb_list); - kfree(lb); - tr.tr_num_free_bufs--; - } - while (tr.tr_num_free_bmem > num_bmem) { - bmem = tr.tr_free_bmem.next; - list_del(bmem); - kfree(bmem); - tr.tr_num_free_bmem--; - } - - LO_BUILD_DUMP(sdp, &tr); - - error = disk_commit(sdp, &tr); - if (error) - gfs_io_error(sdp); - - while (!list_empty(&tr.tr_elements)) { - le = list_entry(tr.tr_elements.next, - struct gfs_log_element, le_list); - LO_CLEAN_DUMP(sdp, le); - } - - /* If there isn't anything in the AIL, we won't get back the log - space we reserved unless we do it ourselves. */ - - if (list_empty(&sdp->sd_log_ail)) { - spin_lock(&sdp->sd_log_seg_lock); - sdp->sd_log_seg_free += tr.tr_seg_reserved; - gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= - sdp->sd_jdesc.ji_nsegment,); - spin_unlock(&sdp->sd_log_seg_lock); - } - - clear_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags); - - out: - gfs_log_unlock(sdp); - clear_bit(SDF_IN_LOG_DUMP, &sdp->sd_flags); -} - -/** - * gfs_log_shutdown - write a shutdown header into a journal - * @sdp: the filesystem - * - */ - -void -gfs_log_shutdown(struct gfs_sbd *sdp) -{ - struct gfs_log_buf *lb; - char *bmem; - struct gfs_log_header head; - struct gfs_log_descriptor desc; - unsigned int elements = 0; - int error; - - lb = gmalloc(sizeof(struct gfs_log_buf)); - memset(lb, 0, sizeof(struct gfs_log_buf)); - bmem = gmalloc(sdp->sd_sb.sb_bsize); - - gfs_log_lock(sdp); - - gfs_assert_withdraw(sdp, list_empty(&sdp->sd_log_ail)); - gfs_assert_withdraw(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 == - sdp->sd_jdesc.ji_nsegment); - gfs_assert_withdraw(sdp, !sdp->sd_log_buffers); - gfs_assert_withdraw(sdp, gfs_log_is_header(sdp, sdp->sd_log_head - 1)); - if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - goto out; - - /* Build a "last" log descriptor */ - - memset(&desc, 0, sizeof(struct gfs_log_descriptor)); - desc.ld_header.mh_magic = GFS_MAGIC; - desc.ld_header.mh_type = GFS_METATYPE_LD; - desc.ld_header.mh_format = GFS_FORMAT_LD; - desc.ld_type = GFS_LOG_DESC_LAST; - desc.ld_length = sdp->sd_sb.sb_seg_size - 1; - - /* Write the descriptor */ - - gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem); - memset(bmem, 0, sdp->sd_sb.sb_bsize); - gfs_desc_out(&desc, lb->lb_bh.b_data); - gfs_logbh_start(sdp, &lb->lb_bh); - error = gfs_logbh_wait(sdp, &lb->lb_bh); - gfs_logbh_uninit(sdp, &lb->lb_bh); - - if (error) - goto out; - - /* Move to the next header */ - - while (!gfs_log_is_header(sdp, sdp->sd_log_head)) - log_incr_head(sdp, &sdp->sd_log_head); - - LO_DUMP_SIZE(sdp, &elements, NULL, NULL); - - /* Build the shutdown header */ - - memset(&head, 0, sizeof (struct gfs_log_header)); - head.lh_header.mh_magic = GFS_MAGIC; - head.lh_header.mh_type = GFS_METATYPE_LH; - head.lh_header.mh_format = GFS_FORMAT_LH; - head.lh_flags = GFS_LOG_HEAD_UNMOUNT; - head.lh_first = sdp->sd_log_head; - head.lh_sequence = sdp->sd_sequence + 1; - /* Don't care about tail */ - head.lh_last_dump = (elements) ? sdp->sd_log_dump_last : 0; - - /* Write out the shutdown header */ - - gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem); - memset(bmem, 0, sdp->sd_sb.sb_bsize); - gfs_log_header_out(&head, lb->lb_bh.b_data); - gfs_log_header_out(&head, - lb->lb_bh.b_data + GFS_BASIC_BLOCK - - sizeof(struct gfs_log_header)); - gfs_logbh_start(sdp, &lb->lb_bh); - gfs_logbh_wait(sdp, &lb->lb_bh); - gfs_logbh_uninit(sdp, &lb->lb_bh); - - /* If a withdraw is called before we've a chance to relock the trans - * lock, the sd_log_head points to the wrong place, and a umount will - * fail on asserts because of this. - * Adding one puts sd_log_head at a value that passes the assert. The - * value may not be correct for on disk, but we've withdrawn so there is - * no more disk io. - * If we're not withdrawn, the next io will grab the trans lock, which - * will fill sd_log_head with the correct value. - */ - sdp->sd_log_head += 1; - - out: - gfs_log_unlock(sdp); - - kfree(lb); - kfree(bmem); -} diff --git a/gfs-kernel/src/gfs/log.h b/gfs-kernel/src/gfs/log.h deleted file mode 100644 index c4a2895..0000000 --- a/gfs-kernel/src/gfs/log.h +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOG_DOT_H__ -#define __LOG_DOT_H__ - -/** - * gfs_log_lock - acquire the right to mess with the log manager - * @sdp: the filesystem - * - */ - -static __inline__ void -gfs_log_lock(struct gfs_sbd *sdp) -{ - down_write(&sdp->sd_log_lock); -} - -/** - * gfs_log_unlock - release the right to mess with the log manager - * @sdp: the filesystem - * - */ - -static __inline__ void -gfs_log_unlock(struct gfs_sbd *sdp) -{ - up_write(&sdp->sd_log_lock); -} - -unsigned int gfs_struct2blk(struct gfs_sbd *sdp, unsigned int nstruct, - unsigned int ssize); -unsigned int gfs_blk2seg(struct gfs_sbd *sdp, unsigned int blocks); - -int gfs_log_reserve(struct gfs_sbd *sdp, unsigned int segments, int jump_queue); -void gfs_log_release(struct gfs_sbd *sdp, unsigned int segments); - -void gfs_ail_start(struct gfs_sbd *sdp, int flags); -int gfs_ail_empty(struct gfs_sbd *sdp); - -void gfs_log_commit(struct gfs_sbd *sdp, struct gfs_trans *trans); -void gfs_log_flush(struct gfs_sbd *sdp); -void gfs_log_flush_glock(struct gfs_glock *gl, int flags); - -void gfs_log_shutdown(struct gfs_sbd *sdp); - -void gfs_log_dump(struct gfs_sbd *sdp, int force); - -/* Internal crap used the log operations */ - -/** - * gfs_log_is_header - Discover if block is on journal header - * @sdp: The GFS superblock - * @block: The block number - * - * Returns: TRUE if the block is on a journal segment boundary, FALSE otherwise - */ - -static __inline__ int -gfs_log_is_header(struct gfs_sbd *sdp, uint64_t block) -{ - return !do_mod(block, sdp->sd_sb.sb_seg_size); -} - -struct gfs_log_buf *gfs_log_get_buf(struct gfs_sbd *sdp, struct gfs_trans *tr); -void gfs_log_fake_buf(struct gfs_sbd *sdp, struct gfs_trans *tr, char *data, - struct buffer_head *unlock); - -#endif /* __LOG_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/lops.c b/gfs-kernel/src/gfs/lops.c deleted file mode 100644 index de326c7..0000000 --- a/gfs-kernel/src/gfs/lops.c +++ /dev/null @@ -1,1661 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "log.h" -#include "lops.h" -#include "quota.h" -#include "recovery.h" -#include "trans.h" -#include "unlinked.h" - -/** - * generic_le_add - generic routine to add a log element to a transaction - * @sdp: the filesystem - * @le: the log entry - * - */ - -static void -generic_le_add(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - struct gfs_trans *tr; - - /* Make sure it's not attached to a transaction already */ - gfs_assert(sdp, le->le_ops && - !le->le_trans && - list_empty(&le->le_list),); - - /* Attach it to the (one) transaction being built by this process */ - tr = current_transaction; - gfs_assert(sdp, tr,); - - le->le_trans = tr; - list_add(&le->le_list, &tr->tr_elements); -} - -/** - * glock_trans_end - drop a glock reference - * @sdp: the filesystem - * @le: the log element - * - * Called before incore-committing a transaction - * Release reference that was taken in gfs_trans_add_gl() - */ - -static void -glock_trans_end(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); - - gfs_assert(sdp, gfs_glock_is_locked_by_me(gl) && - gfs_glock_is_held_excl(gl),); - gfs_glock_put(gl); -} - -/** - * glock_print - print debug info about a log element - * @sdp: the filesystem - * @le: the log element - * @where: is this a new transaction or a incore transaction - * - */ - -static void -glock_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) -{ - struct gfs_glock *gl; - - switch (where) { - case TRANS_IS_NEW: - gl = container_of(le, struct gfs_glock, gl_new_le); - break; - case TRANS_IS_INCORE: - gl = container_of(le, struct gfs_glock, gl_incore_le); - break; - default: - gfs_assert_warn(sdp, FALSE); - return; - } - - printk(" Glock: (%u, %"PRIu64")\n", - gl->gl_name.ln_type, - gl->gl_name.ln_number); -} - -/** - * glock_overlap_trans - Find any incore transactions that might overlap with - * (i.e. be combinable with the transaction containing) this LE - * @sdp: the filesystem - * @le: the log element - * - * Transactions that share a given glock are combinable. - * - * For a glock, the scope of the "search" is just the (max) one unique incore - * committed transaction to which the glock may be attached via its - * gl->gl_incore_le embedded log element. This trans may have previously - * been combined with other transactions, though (i.e. previous - * incore committed transactions that shared the same glock). - * - * Called as a beginning part of the incore commit of a transaction. - */ - -static struct gfs_trans * -glock_overlap_trans(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); - - return gl->gl_incore_le.le_trans; -} - -/** - * glock_incore_commit - commit this LE to the incore log - * @sdp: the filesystem - * @tr: the being-incore-committed transaction this LE is to be a part of - * @le: the log element (should be a gl->gl_new_le), which is attached - * to a "new" (just-ended) transaction. - * - * Attach glock's gl_incore_le to the being-incore-committed trans' LE list. - * Remove glock's gl_new_le from the just-ended new trans' LE list. - * If the just-ended new trans (le->le_trans) was combined (in incore_commit()) - * with a pre-existing incore trans (tr), this function effectively moves - * the LE from the new to the combined incore trans. - * If there was no combining, then the new trans itself is being committed - * (le->le_trans == tr); this function simply replaces the gl_new_le with a - * gl_incore_le on the trans' LE list. - * - * Make sure that this glock's gl_incore_le is attached to one and only one - * incore-committed transaction's (this one's) tr_elements list. - * One transaction (instead of a list of transactions) is sufficient, - * because incore_commit() combines multiple transactions that share a glock - * into one trans. - * Since transactions can contain multiple glocks, there are multiple - * possibilities for shared glocks, therefore multiple potential "bridges" - * for combining transactions. - */ - -static void -glock_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_log_element *le) -{ - struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); - - /* Transactions were combined, based on this glock */ - if (gl->gl_incore_le.le_trans) - gfs_assert(sdp, gl->gl_incore_le.le_trans == tr,); - else { - /* Attach gl->gl_incore_le to being-committed trans */ - gl->gl_incore_le.le_trans = tr; - list_add(&gl->gl_incore_le.le_list, &tr->tr_elements); - - /* If transactions were combined (via another shared glock), - the combined trans is getting a new glock log element */ - if (tr != le->le_trans) - tr->tr_num_gl++; - } - - /* Remove gl->gl_new_le from "new" trans */ - le->le_trans = NULL; - list_del_init(&le->le_list); -} - -/** - * glock_add_to_ail - Add this LE to the AIL - * @sdp: the filesystem - * @le: the log element - * - * Glocks don't really get added to AIL (there's nothing to write to disk), - * they just get removed from the transaction at this time. - */ - -static void -glock_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - le->le_trans = NULL; - list_del_init(&le->le_list); -} - -/** - * glock_trans_combine - combine two incore transactions - * @sdp: the filesystem - * @tr: the surviving transaction - * @new_tr: the transaction that's going to disappear - * - */ - -static void -glock_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_trans *new_tr) -{ - tr->tr_num_gl += new_tr->tr_num_gl; -} - -/** - * buf_print - print debug info about a log element - * @sdp: the filesystem - * @le: the log element - * @where: is this a new transaction or a incore transaction - * - */ - -static void -buf_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) -{ - struct gfs_bufdata *bd; - - switch (where) { - case TRANS_IS_NEW: - bd = container_of(le, struct gfs_bufdata, bd_new_le); - break; - case TRANS_IS_INCORE: - bd = container_of(le, struct gfs_bufdata, bd_incore_le); - break; - default: - gfs_assert_warn(sdp, FALSE); - return; - } - - printk(" Buffer: %"PRIu64"\n", (uint64_t)bd->bd_bh->b_blocknr); -} - -/** - * buf_incore_commit - commit this buffer LE to the incore log - * @sdp: the filesystem - * @tr: the incore transaction this LE is a part of - * @le: the log element for the "new" (just now complete) trans - * - * Invoked from incore_commit(). - * Move this buffer from "new" stage to "incore committed" stage of the - * transaction pipeline. - * If this buffer was already attached to a pre-existing incore trans, GFS is - * combining the new and incore transactions; decrement buffer's recursive - * pin count that was incremented when it was added to the new transaction, - * and remove the reference to the "new" (being swallowed) trans. - * Else, move this buffer's attach point from "new" to "incore" embedded LE - * (same transaction, just new status) and add this buf to (incore) trans' - * LE list. - */ - -static void -buf_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_log_element *le) -{ - struct gfs_bufdata *bd = container_of(le, struct gfs_bufdata, bd_new_le); - - /* We've completed our (atomic) changes to this buffer for this trans. - We no longer need the frozen copy. If frozen copy was not written - to on-disk log already, there's no longer a need to; we can now - write the "real" buffer (with more up-to-date content) instead. */ - if (bd->bd_frozen) { - kfree(bd->bd_frozen); - bd->bd_frozen = NULL; - } - - /* New trans being combined with pre-existing incore trans? */ - if (bd->bd_incore_le.le_trans) { - gfs_assert(sdp, bd->bd_incore_le.le_trans == tr,); - gfs_dunpin(sdp, bd->bd_bh, NULL); - } else { - bd->bd_incore_le.le_trans = tr; - list_add(&bd->bd_incore_le.le_list, &tr->tr_elements); - if (tr != le->le_trans) - tr->tr_num_buf++; - - sdp->sd_log_buffers++; - } - - /* Reset buffer's bd_new_le */ - le->le_trans = NULL; - list_del_init(&le->le_list); -} - -/** - * buf_add_to_ail - Add this LE to the AIL - * @sdp: the filesystem - * @le: the log element - * - */ - -static void -buf_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - struct gfs_bufdata *bd = container_of(le, - struct gfs_bufdata, - bd_incore_le); - - gfs_dunpin(sdp, bd->bd_bh, le->le_trans); - - le->le_trans = NULL; - list_del_init(&le->le_list); - - gfs_assert(sdp, sdp->sd_log_buffers,); - sdp->sd_log_buffers--; -} - -/** - * buf_trans_size - compute how much space the LE class takes up in a transaction - * @sdp: the filesystem - * @tr: the transaction - * @mblks: the number of regular metadata blocks - * @eblks: the number of extra blocks - * @blocks: the number of log blocks - * @bmem: the number of buffer-sized chunks of memory we need - * - */ - -static void -buf_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, - unsigned int *mblks, unsigned int *eblks, - unsigned int *blocks, unsigned int *bmem) -{ - unsigned int cblks; - - if (tr->tr_num_buf) { - cblks = gfs_struct2blk(sdp, tr->tr_num_buf, - sizeof(struct gfs_block_tag)); - - if (mblks) - *mblks += tr->tr_num_buf; - if (blocks) - *blocks += tr->tr_num_buf + cblks; - if (bmem) - *bmem += cblks; - } -} - -/** - * buf_trans_combine - combine two incore transactions - * @sdp: the filesystem - * @tr: the surviving transaction - * @new_tr: the transaction that's going to disappear - * - */ - -static void -buf_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_trans *new_tr) -{ - tr->tr_num_buf += new_tr->tr_num_buf; -} - -/** - * increment_generation - increment the generation number in metadata buffer - * @sdp: the filesystem - * @bd: the struct gfs_bufdata structure associated with the buffer - * - * Increment the generation # of the most recent buffer contents, as well as - * that of frozen buffer, if any. If there is a frozen buffer, only *it* - * will be going to the log now ... in this case, the current buffer will - * have its gen # incremented again later, when it gets written to log. - * Gen # is used by journal recovery (replay_block()) to determine whether - * to overwrite an inplace block with the logged block contents. - */ - -static void -increment_generation(struct gfs_sbd *sdp, struct gfs_bufdata *bd) -{ - struct gfs_meta_header *mh, *mh2; - uint64_t tmp64; - - mh = (struct gfs_meta_header *)bd->bd_bh->b_data; - - tmp64 = gfs64_to_cpu(mh->mh_generation) + 1; - tmp64 = cpu_to_gfs64(tmp64); - - if (bd->bd_frozen) { - mh2 = (struct gfs_meta_header *)bd->bd_frozen; - gfs_assert(sdp, mh->mh_generation == mh2->mh_generation,); - mh2->mh_generation = tmp64; - } - mh->mh_generation = tmp64; -} - -/** - * buf_build_bhlist - create the buffers that will make up the ondisk part of a transaction - * @sdp: the filesystem - * @tr: the transaction - * - * Create the log (transaction) descriptor block - */ - -static void -buf_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *tmp, *head; - struct gfs_log_element *le; - struct gfs_bufdata *bd; - struct gfs_log_descriptor desc; - struct gfs_block_tag tag; - struct gfs_log_buf *clb = NULL; - unsigned int num_ctl; - unsigned int offset = sizeof(struct gfs_log_descriptor); - unsigned int x, bufs; - - if (!tr->tr_num_buf) - return; - - /* set up control buffers for descriptor and tags */ - - num_ctl = gfs_struct2blk(sdp, tr->tr_num_buf, - sizeof(struct gfs_block_tag)); - - for (x = 0; x < num_ctl; x++) { - if (clb) - gfs_log_get_buf(sdp, tr); - else - clb = gfs_log_get_buf(sdp, tr); - } - - /* Init and copy log descriptor into 1st control block */ - memset(&desc, 0, sizeof(struct gfs_log_descriptor)); - desc.ld_header.mh_magic = GFS_MAGIC; - desc.ld_header.mh_type = GFS_METATYPE_LD; - desc.ld_header.mh_format = GFS_FORMAT_LD; - desc.ld_type = GFS_LOG_DESC_METADATA; - desc.ld_length = num_ctl + tr->tr_num_buf; - desc.ld_data1 = tr->tr_num_buf; - gfs_desc_out(&desc, clb->lb_bh.b_data); - - x = 1; - bufs = 0; - - for (head = &tr->tr_elements, tmp = head->next; - tmp != head; - tmp = tmp->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - - /* Skip over non-buffer (e.g. glock, unlinked, etc.) LEs */ - if (le->le_ops != &gfs_buf_lops) - continue; - - bd = container_of(le, struct gfs_bufdata, bd_incore_le); - - gfs_meta_check(sdp, bd->bd_bh); - - gfs_lock_buffer(bd->bd_bh); - - increment_generation(sdp, bd); - - /* Create "fake" buffer head to write block to on-disk log. Use - frozen copy if another transaction is modifying the "real" - buffer contents. Unlock real bh after log write completes, - so Linux can write real contents to inplace block. */ - gfs_log_fake_buf(sdp, tr, - (bd->bd_frozen) ? bd->bd_frozen : bd->bd_bh->b_data, - bd->bd_bh); - - /* find another buffer for tags if we're overflowing this one */ - if (offset + sizeof(struct gfs_block_tag) > sdp->sd_sb.sb_bsize) { - clb = list_entry(clb->lb_list.prev, - struct gfs_log_buf, lb_list); - if (gfs_log_is_header(sdp, clb->lb_bh.b_blocknr)) - clb = list_entry(clb->lb_list.prev, - struct gfs_log_buf, lb_list); - x++; - offset = 0; - } - - /* Write this LE's tag into a control buffer */ - memset(&tag, 0, sizeof(struct gfs_block_tag)); - tag.bt_blkno = bd->bd_bh->b_blocknr; - - gfs_block_tag_out(&tag, clb->lb_bh.b_data + offset); - - offset += sizeof(struct gfs_block_tag); - bufs++; - } - - gfs_assert(sdp, x == num_ctl,); - gfs_assert(sdp, bufs == tr->tr_num_buf,); -} - -/** - * buf_before_scan - called before journal replay - * @sdp: the filesystem - * @jid: the journal ID about to be replayed - * @head: the current head of the log - * @pass: the pass through the journal - * - */ - -static void -buf_before_scan(struct gfs_sbd *sdp, unsigned int jid, - struct gfs_log_header *head, unsigned int pass) -{ - if (pass == GFS_RECPASS_A1) - sdp->sd_recovery_replays = - sdp->sd_recovery_skips = - sdp->sd_recovery_sames = 0; -} - -/** - * replay_block - Replay a single metadata block - * @sdp: the filesystem - * @jdesc: the struct gfs_jindex structure for the journal being replayed - * @gl: the journal's glock - * @tag: the block tag describing the inplace location of the block - * @blkno: the location of the log's copy of the block - * - * Returns: errno - * - * Read in-place block from disk - * Read log (journal) block from disk - * Compare generation numbers - * Copy log block to in-place block on-disk if: - * log generation # > in-place generation # - * OR generation #s are ==, but data contained in block is different (corrupt) - */ - -static int -replay_block(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, struct gfs_block_tag *tag, uint64_t blkno) -{ - struct buffer_head *inplace_bh, *log_bh; - struct gfs_meta_header inplace_mh, log_mh; - int replay_block = TRUE; - int error = 0; - - gfs_replay_check(sdp); - - /* Warning: Using a real buffer here instead of a tempbh can be bad - on a OS that won't support multiple simultaneous buffers for the - same block on different glocks. */ - - error = gfs_dread(gl, tag->bt_blkno, - DIO_START | DIO_WAIT, &inplace_bh); - if (error) - return error; - if (gfs_meta_check(sdp, inplace_bh)) { - brelse(inplace_bh); - return -EIO; - } - gfs_meta_header_in(&inplace_mh, inplace_bh->b_data); - - error = gfs_dread(gl, blkno, DIO_START | DIO_WAIT, &log_bh); - if (error) { - brelse(inplace_bh); - return error; - } - if (gfs_meta_check(sdp, log_bh)) { - brelse(inplace_bh); - brelse(log_bh); - return -EIO; - } - gfs_meta_header_in(&log_mh, log_bh->b_data); - - if (log_mh.mh_generation < inplace_mh.mh_generation) { - replay_block = FALSE; - sdp->sd_recovery_skips++; - } else if (log_mh.mh_generation == inplace_mh.mh_generation) { - if (memcmp(log_bh->b_data, - inplace_bh->b_data, - sdp->sd_sb.sb_bsize) == 0) { - replay_block = FALSE; - sdp->sd_recovery_sames++; - } - } - - if (replay_block) { - memcpy(inplace_bh->b_data, - log_bh->b_data, - sdp->sd_sb.sb_bsize); - - error = gfs_replay_buf(gl, inplace_bh); - if (!error) - sdp->sd_recovery_replays++; - } - - brelse(log_bh); - brelse(inplace_bh); - - return error; -} - -/** - * buf_scan_elements - Replay a metadata log descriptor - * @sdp: the filesystem - * @jdesc: the struct gfs_jindex structure for the journal being replayed - * @gl: the journal's glock - * @start: the starting block of the descriptor - * @desc: the descriptor structure - * @pass: the pass through the journal - * - * Returns: errno - */ - -static int -buf_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t start, - struct gfs_log_descriptor *desc, unsigned int pass) -{ - struct gfs_block_tag tag; - struct buffer_head *bh; - uint64_t cblk = start; - unsigned int num_tags = desc->ld_data1; - unsigned int offset = sizeof(struct gfs_log_descriptor); - unsigned int x; - int error; - - if (pass != GFS_RECPASS_A1) - return 0; - if (desc->ld_type != GFS_LOG_DESC_METADATA) - return 0; - - x = gfs_struct2blk(sdp, num_tags, sizeof(struct gfs_block_tag)); - while (x--) { - error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); - if (error) - return error; - } - - for (;;) { - gfs_assert(sdp, num_tags,); - - error = gfs_dread(gl, cblk, DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - /* Do readahead for the inplace blocks in this control block */ - { - unsigned int o2 = offset; - unsigned int nt2 = num_tags; - - while (o2 + sizeof(struct gfs_block_tag) <= - sdp->sd_sb.sb_bsize) { - gfs_block_tag_in(&tag, bh->b_data + o2); - gfs_start_ra(gl, tag.bt_blkno, 1); - if (!--nt2) - break; - o2 += sizeof(struct gfs_block_tag); - } - } - - while (offset + sizeof(struct gfs_block_tag) <= - sdp->sd_sb.sb_bsize) { - gfs_block_tag_in(&tag, bh->b_data + offset); - - error = replay_block(sdp, jdesc, gl, &tag, start); - if (error) - goto out_drelse; - - if (!--num_tags) - goto out_drelse; - - error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); - if (error) - goto out_drelse; - - offset += sizeof(struct gfs_block_tag); - } - - brelse(bh); - - error = gfs_increment_blkno(sdp, jdesc, gl, &cblk, TRUE); - if (error) - return error; - - offset = 0; - } - - return 0; - - out_drelse: - brelse(bh); - - return error; -} - -/** - * buf_after_scan - called after journal replay - * @sdp: the filesystem - * @jid: the journal ID about to be replayed - * @pass: the pass through the journal - * - */ - -static void -buf_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) -{ - if (pass == GFS_RECPASS_A1) { - printk("GFS: fsid=%s: jid=%u: Replayed %u of %u blocks\n", - sdp->sd_fsname, jid, - sdp->sd_recovery_replays, - sdp->sd_recovery_replays + sdp->sd_recovery_skips + - sdp->sd_recovery_sames); - printk("GFS: fsid=%s: jid=%u: replays = %u, skips = %u, sames = %u\n", - sdp->sd_fsname, jid, sdp->sd_recovery_replays, - sdp->sd_recovery_skips, sdp->sd_recovery_sames); - } -} - -/** - * unlinked_print - print debug info about a log element - * @sdp: the filesystem - * @le: the log element - * @where: is this a new transaction or a incore transaction - * - */ - -static void -unlinked_print(struct gfs_sbd *sdp, struct gfs_log_element *le, - unsigned int where) -{ - struct gfs_unlinked *ul; - char *type; - - switch (where) { - case TRANS_IS_NEW: - ul = container_of(le, struct gfs_unlinked, ul_new_le); - type = (test_bit(ULF_NEW_UL, &ul->ul_flags)) ? - "unlink" : "dealloc"; - break; - case TRANS_IS_INCORE: - ul = container_of(le, struct gfs_unlinked, ul_incore_le); - type = (test_bit(ULF_INCORE_UL, &ul->ul_flags)) ? - "unlink" : "dealloc"; - break; - default: - gfs_assert_warn(sdp, FALSE); - return; - } - - printk(" unlinked: %"PRIu64"/%"PRIu64", %s\n", - ul->ul_inum.no_formal_ino, ul->ul_inum.no_addr, - type); -} - -/** - * unlinked_incore_commit - commit this LE to the incore log - * @sdp: the filesystem - * @tr: the incore transaction this LE is a part of - * @le: the log element - * - */ - -static void -unlinked_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_log_element *le) -{ - struct gfs_unlinked *ul = container_of(le, - struct gfs_unlinked, - ul_new_le); - int n = !!test_bit(ULF_NEW_UL, &ul->ul_flags); - int i = !!test_bit(ULF_INCORE_UL, &ul->ul_flags); - - if (ul->ul_incore_le.le_trans) { - gfs_assert(sdp, ul->ul_incore_le.le_trans == tr,); - gfs_assert(sdp, n != i,); - - ul->ul_incore_le.le_trans = NULL; - list_del_init(&ul->ul_incore_le.le_list); - gfs_unlinked_put(sdp, ul); - - if (i) { - gfs_assert(sdp, tr->tr_num_iul,); - tr->tr_num_iul--; - } else { - gfs_assert(sdp, tr->tr_num_ida,); - tr->tr_num_ida--; - } - } else { - gfs_unlinked_hold(sdp, ul); - ul->ul_incore_le.le_trans = tr; - list_add(&ul->ul_incore_le.le_list, &tr->tr_elements); - - if (n) { - set_bit(ULF_INCORE_UL, &ul->ul_flags); - if (tr != le->le_trans) - tr->tr_num_iul++; - } else { - clear_bit(ULF_INCORE_UL, &ul->ul_flags); - if (tr != le->le_trans) - tr->tr_num_ida++; - } - } - - if (n) { - gfs_unlinked_hold(sdp, ul); - gfs_assert(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags),); - set_bit(ULF_IC_LIST, &ul->ul_flags); - atomic_inc(&sdp->sd_unlinked_ic_count); - } else { - gfs_assert(sdp, test_bit(ULF_IC_LIST, &ul->ul_flags),); - clear_bit(ULF_IC_LIST, &ul->ul_flags); - gfs_unlinked_put(sdp, ul); - gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count),); - atomic_dec(&sdp->sd_unlinked_ic_count); - } - - le->le_trans = NULL; - list_del_init(&le->le_list); - gfs_unlinked_put(sdp, ul); -} - -/** - * unlinked_add_to_ail - Add this LE to the AIL - * @sdp: the filesystem - * @le: the log element - * - */ - -static void -unlinked_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - struct gfs_unlinked *ul = container_of(le, - struct gfs_unlinked, - ul_incore_le); - int i = !!test_bit(ULF_INCORE_UL, &ul->ul_flags); - - if (i) { - gfs_unlinked_hold(sdp, ul); - gfs_assert(sdp, !test_bit(ULF_OD_LIST, &ul->ul_flags),); - set_bit(ULF_OD_LIST, &ul->ul_flags); - atomic_inc(&sdp->sd_unlinked_od_count); - } else { - gfs_assert(sdp, test_bit(ULF_OD_LIST, &ul->ul_flags),); - clear_bit(ULF_OD_LIST, &ul->ul_flags); - gfs_unlinked_put(sdp, ul); - gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_od_count),); - atomic_dec(&sdp->sd_unlinked_od_count); - } - - le->le_trans = NULL; - list_del_init(&le->le_list); - gfs_unlinked_put(sdp, ul); -} - -/** - * unlinked_clean_dump - clean up a LE after a log dump - * @sdp: the filesystem - * @le: the log element - * - */ - -static void -unlinked_clean_dump(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - le->le_trans = NULL; - list_del_init(&le->le_list); -} - -/** - * unlinked_trans_size - compute how much space the LE class takes up in a transaction - * @sdp: the filesystem - * @tr: the transaction - * @mblks: the number of regular metadata blocks - * @eblks: the number of extra blocks - * @blocks: the number of log blocks - * @bmem: the number of buffer-sized chunks of memory we need - * - */ - -static void -unlinked_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, - unsigned int *mblks, unsigned int *eblks, - unsigned int *blocks, unsigned int *bmem) -{ - unsigned int ublks = 0; - - if (tr->tr_num_iul) - ublks = gfs_struct2blk(sdp, tr->tr_num_iul, - sizeof(struct gfs_inum)); - if (tr->tr_num_ida) - ublks += gfs_struct2blk(sdp, tr->tr_num_ida, - sizeof(struct gfs_inum)); - - if (eblks) - *eblks += ublks; - if (blocks) - *blocks += ublks; - if (bmem) - *bmem += ublks; -} - -/** - * unlinked_trans_combine - combine two incore transactions - * @sdp: the filesystem - * @tr: the surviving transaction - * @new_tr: the transaction that's going to disappear - * - */ - -static void -unlinked_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_trans *new_tr) -{ - tr->tr_num_iul += new_tr->tr_num_iul; - tr->tr_num_ida += new_tr->tr_num_ida; -} - -/** - * unlinked_build_bhlist - create the buffers that will make up the ondisk part of a transaction - * @sdp: the filesystem - * @tr: the transaction - * - * For unlinked and/or deallocated inode log elements (separately): - * Get a log block - * Create a log descriptor in beginning of that block - * Fill rest of block with gfs_inum structs to identify each inode - * that became unlinked/deallocated during this transaction. - * Get another log block if needed, continue filling with gfs_inums. - */ - -static void -unlinked_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *tmp, *head; - struct gfs_log_element *le; - struct gfs_unlinked *ul; - struct gfs_log_descriptor desc; - struct gfs_log_buf *lb; - unsigned int pass = 2; - unsigned int type, number; - unsigned int offset, entries; - - /* 2 passes: 1st for Unlinked, 2nd for De-Alloced inodes, - unless this is a log dump: just 1 pass, for Unlinked */ - while (pass--) { - if (tr->tr_flags & TRF_LOG_DUMP) { - if (pass) { - type = GFS_LOG_DESC_IUL; - number = tr->tr_num_iul; - } else - break; - } else { - if (pass) { - type = GFS_LOG_DESC_IUL; - number = tr->tr_num_iul; - } else { - type = GFS_LOG_DESC_IDA; - number = tr->tr_num_ida; - } - - if (!number) - continue; - } - - lb = gfs_log_get_buf(sdp, tr); - - /* Header: log descriptor */ - memset(&desc, 0, sizeof(struct gfs_log_descriptor)); - desc.ld_header.mh_magic = GFS_MAGIC; - desc.ld_header.mh_type = GFS_METATYPE_LD; - desc.ld_header.mh_format = GFS_FORMAT_LD; - desc.ld_type = type; - desc.ld_length = gfs_struct2blk(sdp, number, sizeof(struct gfs_inum)); - desc.ld_data1 = (tr->tr_flags & TRF_LOG_DUMP) ? TRUE : FALSE; - gfs_desc_out(&desc, lb->lb_bh.b_data); - - offset = sizeof(struct gfs_log_descriptor); - entries = 0; - - /* Look through transaction's log elements for Unlinked LEs */ - for (head = &tr->tr_elements, tmp = head->next; - tmp != head; - tmp = tmp->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - if (le->le_ops != &gfs_unlinked_lops) - continue; - if (tr->tr_flags & TRF_LOG_DUMP) - ul = container_of(le, - struct gfs_unlinked, - ul_ondisk_le); - else { - ul = container_of(le, - struct gfs_unlinked, - ul_incore_le); - if (!!test_bit(ULF_INCORE_UL, &ul->ul_flags) != pass) - continue; - } - - if (offset + sizeof(struct gfs_inum) > sdp->sd_sb.sb_bsize) { - offset = 0; - lb = gfs_log_get_buf(sdp, tr); - } - - /* Payload: write the inode identifier */ - gfs_inum_out(&ul->ul_inum, - lb->lb_bh.b_data + offset); - - offset += sizeof(struct gfs_inum); - entries++; - } - - gfs_assert(sdp, entries == number,); - } -} - -/** - * unlinked_dump_size - compute how much space the LE class takes up in a log dump - * @sdp: the filesystem - * @elements: the number of log elements in the dump - * @blocks: the number of blocks in the dump - * @bmem: the number of buffer-sized chunks of memory we need - * - */ - -static void -unlinked_dump_size(struct gfs_sbd *sdp, unsigned int *elements, - unsigned int *blocks, unsigned int *bmem) -{ - unsigned int c = atomic_read(&sdp->sd_unlinked_od_count); - unsigned int b = gfs_struct2blk(sdp, c, sizeof(struct gfs_inum)); - - if (elements) - *elements += c; - if (blocks) - *blocks += b; - if (bmem) - *bmem += b; -} - -/** - * unlinked_build_dump - create a transaction that represents a log dump for this LE class - * @sdp: the filesystem - * @tr: the transaction to fill - * - */ - -static void -unlinked_build_dump(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *tmp, *head; - struct gfs_unlinked *ul; - unsigned int x = 0; - - tr->tr_num_iul = atomic_read(&sdp->sd_unlinked_od_count); - - spin_lock(&sdp->sd_unlinked_lock); - - for (head = &sdp->sd_unlinked_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - ul = list_entry(tmp, struct gfs_unlinked, ul_list); - if (!test_bit(ULF_OD_LIST, &ul->ul_flags)) - continue; - - gfs_assert(sdp, !ul->ul_ondisk_le.le_trans,); - ul->ul_ondisk_le.le_trans = tr; - list_add(&ul->ul_ondisk_le.le_list, &tr->tr_elements); - - x++; - } - - spin_unlock(&sdp->sd_unlinked_lock); - - gfs_assert(sdp, x == atomic_read(&sdp->sd_unlinked_od_count),); -} - -/** - * unlinked_before_scan - called before a log dump is recovered - * @sdp: the filesystem - * @jid: the journal ID about to be scanned - * @head: the current head of the log - * @pass: the pass through the journal - * - */ - -static void -unlinked_before_scan(struct gfs_sbd *sdp, unsigned int jid, - struct gfs_log_header *head, unsigned int pass) -{ - if (pass == GFS_RECPASS_B1) - clear_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags); -} - -/** - * unlinked_scan_elements - scan unlinked inodes from the journal - * @sdp: the filesystem - * @jdesc: the struct gfs_jindex structure for the journal being scaned - * @gl: the journal's glock - * @start: the starting block of the descriptor - * @desc: the descriptor structure - * @pass: the pass through the journal - * - * Returns: errno - */ - -static int -unlinked_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t start, - struct gfs_log_descriptor *desc, unsigned int pass) -{ - struct gfs_inum inum; - struct buffer_head *bh; - unsigned int offset = sizeof(struct gfs_log_descriptor); - unsigned int x; - int error; - - if (pass != GFS_RECPASS_B1) - return 0; - - switch (desc->ld_type) { - case GFS_LOG_DESC_IUL: - if (test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags)) - gfs_assert(sdp, !desc->ld_data1,); - else { - gfs_assert(sdp, desc->ld_data1,); - set_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags); - } - break; - - case GFS_LOG_DESC_IDA: - gfs_assert(sdp, test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags),); - break; - - default: - return 0; - } - - for (x = 0; x < desc->ld_length; x++) { - error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - for (; - offset + sizeof(struct gfs_inum) <= sdp->sd_sb.sb_bsize; - offset += sizeof(struct gfs_inum)) { - gfs_inum_in(&inum, bh->b_data + offset); - - if (inum.no_addr) - gfs_unlinked_merge(sdp, desc->ld_type, &inum); - } - - brelse(bh); - - error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); - if (error) - return error; - - offset = 0; - } - - return 0; -} - -/** - * unlinked_after_scan - called after a log dump is recovered - * @sdp: the filesystem - * @jid: the journal ID about to be scanned - * @pass: the pass through the journal - * - */ - -static void -unlinked_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) -{ - if (pass == GFS_RECPASS_B1) { - gfs_assert(sdp, test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags),); - printk("GFS: fsid=%s: Found %d unlinked inodes\n", - sdp->sd_fsname, atomic_read(&sdp->sd_unlinked_ic_count)); - } -} - -/** - * quota_print - print debug info about a log element - * @sdp: the filesystem - * @le: the log element - * @where: is this a new transaction or a incore transaction - * - */ - -static void -quota_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) -{ - struct gfs_quota_le *ql; - - ql = container_of(le, struct gfs_quota_le, ql_le); - printk(" quota: %s %u: %"PRId64" blocks\n", - (test_bit(QDF_USER, &ql->ql_data->qd_flags)) ? "user" : "group", - ql->ql_data->qd_id, ql->ql_change); -} - -/** - * quota_incore_commit - commit this LE to the incore log - * @sdp: the filesystem - * @tr: the incore transaction this LE is a part of - * @le: the log element - * - */ - -static void -quota_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_log_element *le) -{ - struct gfs_quota_le *ql = container_of(le, struct gfs_quota_le, ql_le); - struct gfs_quota_data *qd = ql->ql_data; - - gfs_assert(sdp, ql->ql_change,); - - /* Make this change under the sd_quota_lock, so other processes - checking qd_change_ic don't have to acquire the log lock. */ - - spin_lock(&sdp->sd_quota_lock); - qd->qd_change_new -= ql->ql_change; - qd->qd_change_ic += ql->ql_change; - spin_unlock(&sdp->sd_quota_lock); - - if (le->le_trans == tr) - list_add(&ql->ql_data_list, &qd->qd_le_list); - else { - struct list_head *tmp, *head; - struct gfs_quota_le *tmp_ql; - int found = FALSE; - - for (head = &qd->qd_le_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - tmp_ql = list_entry(tmp, struct gfs_quota_le, ql_data_list); - if (tmp_ql->ql_le.le_trans != tr) - continue; - - tmp_ql->ql_change += ql->ql_change; - - list_del(&le->le_list); - gfs_quota_put(sdp, qd); - kfree(ql); - - if (!tmp_ql->ql_change) { - list_del(&tmp_ql->ql_data_list); - list_del(&tmp_ql->ql_le.le_list); - gfs_quota_put(sdp, tmp_ql->ql_data); - kfree(tmp_ql); - tr->tr_num_q--; - } - - found = TRUE; - break; - } - - if (!found) { - le->le_trans = tr; - list_move(&le->le_list, &tr->tr_elements); - tr->tr_num_q++; - list_add(&ql->ql_data_list, &qd->qd_le_list); - } - } -} - -/** - * quota_add_to_ail - Add this LE to the AIL - * @sdp: the filesystem - * @le: the log element - * - */ - -static void -quota_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - struct gfs_quota_le *ql = container_of(le, struct gfs_quota_le, ql_le); - struct gfs_quota_data *qd = ql->ql_data; - - qd->qd_change_od += ql->ql_change; - if (qd->qd_change_od) { - if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) { - gfs_quota_hold(sdp, qd); - set_bit(QDF_OD_LIST, &qd->qd_flags); - atomic_inc(&sdp->sd_quota_od_count); - } - } else { - gfs_assert(sdp, test_bit(QDF_OD_LIST, &qd->qd_flags),); - clear_bit(QDF_OD_LIST, &qd->qd_flags); - gfs_quota_put(sdp, qd); - gfs_assert(sdp, atomic_read(&sdp->sd_quota_od_count),); - atomic_dec(&sdp->sd_quota_od_count); - } - - list_del(&ql->ql_data_list); - list_del(&le->le_list); - gfs_quota_put(sdp, qd); - kfree(ql); -} - -/** - * quota_clean_dump - clean up a LE after a log dump - * @sdp: the filesystem - * @le: the log element - * - */ - -static void -quota_clean_dump(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - le->le_trans = NULL; - list_del_init(&le->le_list); -} - -/** - * quota_trans_size - compute how much space the LE class takes up in a transaction - * @sdp: the filesystem - * @tr: the transaction - * @mblks: the number of regular metadata blocks - * @eblks: the number of extra blocks - * @blocks: the number of log blocks - * @bmem: the number of buffer-sized chunks of memory we need - * - */ - -static void -quota_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, - unsigned int *mblks, unsigned int *eblks, - unsigned int *blocks, unsigned int *bmem) -{ - unsigned int qblks; - - if (tr->tr_num_q) { - qblks = gfs_struct2blk(sdp, tr->tr_num_q, - sizeof(struct gfs_quota_tag)); - - if (eblks) - *eblks += qblks; - if (blocks) - *blocks += qblks; - if (bmem) - *bmem += qblks; - } -} - -/** - * quota_trans_combine - combine two incore transactions - * @sdp: the filesystem - * @tr: the surviving transaction - * @new_tr: the transaction that's going to disappear - * - */ - -static void -quota_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, - struct gfs_trans *new_tr) -{ - tr->tr_num_q += new_tr->tr_num_q; -} - -/** - * quota_build_bhlist - create the buffers that will make up the ondisk part of a transaction - * @sdp: the filesystem - * @tr: the transaction - * - */ - -static void -quota_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *tmp, *head; - struct gfs_log_element *le; - struct gfs_quota_le *ql; - struct gfs_log_descriptor desc; - struct gfs_quota_tag tag; - struct gfs_log_buf *lb; - unsigned int offset = sizeof(struct gfs_log_descriptor), entries = 0; - - if (!tr->tr_num_q && !(tr->tr_flags & TRF_LOG_DUMP)) - return; - - lb = gfs_log_get_buf(sdp, tr); - - memset(&desc, 0, sizeof(struct gfs_log_descriptor)); - desc.ld_header.mh_magic = GFS_MAGIC; - desc.ld_header.mh_type = GFS_METATYPE_LD; - desc.ld_header.mh_format = GFS_FORMAT_LD; - desc.ld_type = GFS_LOG_DESC_Q; - desc.ld_length = gfs_struct2blk(sdp, tr->tr_num_q, - sizeof(struct gfs_quota_tag)); - desc.ld_data1 = tr->tr_num_q; - desc.ld_data2 = (tr->tr_flags & TRF_LOG_DUMP) ? TRUE : FALSE; - gfs_desc_out(&desc, lb->lb_bh.b_data); - - for (head = &tr->tr_elements, tmp = head->next; - tmp != head; - tmp = tmp->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - if (le->le_ops != &gfs_quota_lops) - continue; - - ql = container_of(le, struct gfs_quota_le, ql_le); - - if (offset + sizeof(struct gfs_quota_tag) > - sdp->sd_sb.sb_bsize) { - offset = 0; - lb = gfs_log_get_buf(sdp, tr); - } - - memset(&tag, 0, sizeof(struct gfs_quota_tag)); - tag.qt_change = ql->ql_change; - tag.qt_flags = (test_bit(QDF_USER, &ql->ql_data->qd_flags)) ? - GFS_QTF_USER : 0; - tag.qt_id = ql->ql_data->qd_id; - - gfs_quota_tag_out(&tag, lb->lb_bh.b_data + offset); - - offset += sizeof(struct gfs_quota_tag); - entries++; - } - - gfs_assert(sdp, entries == tr->tr_num_q,); -} - -/** - * quota_dump_size - compute how much space the LE class takes up in a log dump - * @sdp: the filesystem - * @elements: the number of log elements in the dump - * @blocks: the number of blocks in the dump - * @bmem: the number of buffer-sized chunks of memory we need - * - */ - -static void -quota_dump_size(struct gfs_sbd *sdp, unsigned int *elements, - unsigned int *blocks, unsigned int *bmem) -{ - unsigned int c = atomic_read(&sdp->sd_quota_od_count); - unsigned int b = gfs_struct2blk(sdp, c, sizeof(struct gfs_quota_tag)); - - if (elements) - *elements += c; - if (blocks) - *blocks += b; - if (bmem) - *bmem += b; -} - -/** - * quota_build_dump - create a transaction that represents a log dump for this LE class - * @sdp: the filesystem - * @tr: the transaction to fill - * - */ - -static void -quota_build_dump(struct gfs_sbd *sdp, struct gfs_trans *tr) -{ - struct list_head *tmp, *head; - struct gfs_quota_data *qd; - struct gfs_quota_le *ql; - unsigned int x = 0; - - tr->tr_num_q = atomic_read(&sdp->sd_quota_od_count); - - spin_lock(&sdp->sd_quota_lock); - - for (head = &sdp->sd_quota_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - qd = list_entry(tmp, struct gfs_quota_data, qd_list); - if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) - continue; - - ql = &qd->qd_ondisk_ql; - - ql->ql_le.le_ops = &gfs_quota_lops; - gfs_assert(sdp, !ql->ql_le.le_trans,); - ql->ql_le.le_trans = tr; - list_add(&ql->ql_le.le_list, &tr->tr_elements); - - ql->ql_data = qd; - ql->ql_change = qd->qd_change_od; - - x++; - } - - spin_unlock(&sdp->sd_quota_lock); - - gfs_assert(sdp, x == atomic_read(&sdp->sd_quota_od_count),); -} - -/** - * quota_before_scan - called before a log dump is recovered - * @sdp: the filesystem - * @jid: the journal ID about to be scanned - * @head: the current head of the log - * @pass: the pass through the journal - * - */ - -static void -quota_before_scan(struct gfs_sbd *sdp, unsigned int jid, - struct gfs_log_header *head, unsigned int pass) -{ - if (pass == GFS_RECPASS_B1) - clear_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags); -} - -/** - * quota_scan_elements - scan quota inodes from the journal - * @sdp: the filesystem - * @jdesc: the struct gfs_jindex structure for the journal being scaned - * @gl: the journal's glock - * @start: the starting block of the descriptor - * @desc: the descriptor structure - * @pass: the pass through the journal - * - * Returns: errno - */ - -static int -quota_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t start, - struct gfs_log_descriptor *desc, unsigned int pass) -{ - struct gfs_quota_tag tag; - struct buffer_head *bh; - unsigned int num_tags = desc->ld_data1; - unsigned int offset = sizeof(struct gfs_log_descriptor); - unsigned int x; - int error; - - if (pass != GFS_RECPASS_B1) - return 0; - if (desc->ld_type != GFS_LOG_DESC_Q) - return 0; - - if (test_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags)) - gfs_assert(sdp, !desc->ld_data2,); - else { - gfs_assert(sdp, desc->ld_data2,); - set_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags); - } - - if (!num_tags) - return 0; - - for (x = 0; x < desc->ld_length; x++) { - error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - while (offset + sizeof(struct gfs_quota_tag) <= - sdp->sd_sb.sb_bsize) { - gfs_quota_tag_in(&tag, bh->b_data + offset); - - error = gfs_quota_merge(sdp, &tag); - if (error) - goto out_drelse; - - if (!--num_tags) - goto out_drelse; - - offset += sizeof(struct gfs_quota_tag); - } - - brelse(bh); - - error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); - if (error) - return error; - - offset = 0; - } - - return 0; - - out_drelse: - brelse(bh); - - return error; -} - -/** - * quota_after_scan - called after a log dump is recovered - * @sdp: the filesystem - * @jid: the journal ID about to be scanned - * @pass: the pass through the journal - * - */ - -static void -quota_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) -{ - if (pass == GFS_RECPASS_B1) { - gfs_assert(sdp, !sdp->sd_sb.sb_quota_di.no_formal_ino || - test_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags),); - printk("GFS: fsid=%s: Found quota changes for %d IDs\n", - sdp->sd_fsname, atomic_read(&sdp->sd_quota_od_count)); - } -} - -struct gfs_log_operations gfs_glock_lops = { - .lo_add = generic_le_add, - .lo_trans_end = glock_trans_end, - .lo_print = glock_print, - .lo_overlap_trans = glock_overlap_trans, - .lo_incore_commit = glock_incore_commit, - .lo_add_to_ail = glock_add_to_ail, - .lo_trans_combine = glock_trans_combine, - .lo_name = "glock" -}; - -struct gfs_log_operations gfs_buf_lops = { - .lo_add = generic_le_add, - .lo_print = buf_print, - .lo_incore_commit = buf_incore_commit, - .lo_add_to_ail = buf_add_to_ail, - .lo_trans_size = buf_trans_size, - .lo_trans_combine = buf_trans_combine, - .lo_build_bhlist = buf_build_bhlist, - .lo_before_scan = buf_before_scan, - .lo_scan_elements = buf_scan_elements, - .lo_after_scan = buf_after_scan, - .lo_name = "buf" -}; - -struct gfs_log_operations gfs_unlinked_lops = { - .lo_add = generic_le_add, - .lo_print = unlinked_print, - .lo_incore_commit = unlinked_incore_commit, - .lo_add_to_ail = unlinked_add_to_ail, - .lo_clean_dump = unlinked_clean_dump, - .lo_trans_size = unlinked_trans_size, - .lo_trans_combine = unlinked_trans_combine, - .lo_build_bhlist = unlinked_build_bhlist, - .lo_dump_size = unlinked_dump_size, - .lo_build_dump = unlinked_build_dump, - .lo_before_scan = unlinked_before_scan, - .lo_scan_elements = unlinked_scan_elements, - .lo_after_scan = unlinked_after_scan, - .lo_name = "unlinked" -}; - -struct gfs_log_operations gfs_quota_lops = { - .lo_add = generic_le_add, - .lo_print = quota_print, - .lo_incore_commit = quota_incore_commit, - .lo_add_to_ail = quota_add_to_ail, - .lo_clean_dump = quota_clean_dump, - .lo_trans_size = quota_trans_size, - .lo_trans_combine = quota_trans_combine, - .lo_build_bhlist = quota_build_bhlist, - .lo_dump_size = quota_dump_size, - .lo_build_dump = quota_build_dump, - .lo_before_scan = quota_before_scan, - .lo_scan_elements = quota_scan_elements, - .lo_after_scan = quota_after_scan, - .lo_name = "quota" -}; - -struct gfs_log_operations *gfs_log_ops[] = { - &gfs_glock_lops, - &gfs_buf_lops, - &gfs_unlinked_lops, - &gfs_quota_lops, - NULL -}; diff --git a/gfs-kernel/src/gfs/lops.h b/gfs-kernel/src/gfs/lops.h deleted file mode 100644 index e127b29..0000000 --- a/gfs-kernel/src/gfs/lops.h +++ /dev/null @@ -1,179 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOPS_DOT_H__ -#define __LOPS_DOT_H__ - -extern struct gfs_log_operations gfs_glock_lops; -extern struct gfs_log_operations gfs_buf_lops; -extern struct gfs_log_operations gfs_unlinked_lops; -extern struct gfs_log_operations gfs_quota_lops; - -extern struct gfs_log_operations *gfs_log_ops[]; - -#define INIT_LE(le, lops) \ -do \ -{ \ - (le)->le_ops = (lops); \ - (le)->le_trans = NULL; \ - INIT_LIST_HEAD(&(le)->le_list); \ -} \ -while (0) - -#define LO_ADD(sdp, le) \ -do \ -{ \ - if ((le)->le_ops->lo_add) \ - (le)->le_ops->lo_add((sdp), (le)); \ -} \ -while (0) - -#define LO_TRANS_END(sdp, le) \ -do \ -{ \ - if ((le)->le_ops->lo_trans_end) \ - (le)->le_ops->lo_trans_end((sdp), (le)); \ -} \ -while (0) - -#define LO_PRINT(sdp, le, where) \ -do \ -{ \ - if ((le)->le_ops->lo_print) \ - (le)->le_ops->lo_print((sdp), (le), (where)); \ -} \ -while (0) - -static __inline__ struct gfs_trans * -LO_OVERLAP_TRANS(struct gfs_sbd *sdp, struct gfs_log_element *le) -{ - if (le->le_ops->lo_overlap_trans) - return le->le_ops->lo_overlap_trans(sdp, le); - else - return NULL; -} - -#define LO_INCORE_COMMIT(sdp, tr, le) \ -do \ -{ \ - if ((le)->le_ops->lo_incore_commit) \ - (le)->le_ops->lo_incore_commit((sdp), (tr), (le)); \ -} \ -while (0) - -#define LO_ADD_TO_AIL(sdp, le) \ -do \ -{ \ - if ((le)->le_ops->lo_add_to_ail) \ - (le)->le_ops->lo_add_to_ail((sdp), (le)); \ -} \ -while (0) - -#define LO_CLEAN_DUMP(sdp, le) \ -do \ -{ \ - if ((le)->le_ops->lo_clean_dump) \ - (le)->le_ops->lo_clean_dump((sdp), (le)); \ -} \ -while (0) - -#define LO_TRANS_SIZE(sdp, tr, mblks, eblks, blocks, bmem) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_trans_size) \ - gfs_log_ops[__lops_x]->lo_trans_size((sdp), (tr), (mblks), (eblks), (blocks), (bmem)); \ -} \ -while (0) - -#define LO_TRANS_COMBINE(sdp, tr, new_tr) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_trans_combine) \ - gfs_log_ops[__lops_x]->lo_trans_combine((sdp), (tr), (new_tr)); \ -} \ -while (0) - -#define LO_BUILD_BHLIST(sdp, tr) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_build_bhlist) \ - gfs_log_ops[__lops_x]->lo_build_bhlist((sdp), (tr)); \ -} \ -while (0) - -#define LO_DUMP_SIZE(sdp, elements, blocks, bmem) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_dump_size) \ - gfs_log_ops[__lops_x]->lo_dump_size((sdp), (elements), (blocks), (bmem)); \ -} \ -while (0) - -#define LO_BUILD_DUMP(sdp, tr) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_build_dump) \ - gfs_log_ops[__lops_x]->lo_build_dump((sdp), (tr)); \ -} \ -while (0) - -#define LO_BEFORE_SCAN(sdp, jid, head, pass) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_before_scan) \ - gfs_log_ops[__lops_x]->lo_before_scan((sdp), (jid), (head), (pass)); \ -} \ -while (0) - -static __inline__ int -LO_SCAN_ELEMENTS(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t start, - struct gfs_log_descriptor *desc, unsigned int pass) -{ - int x; - int error; - - for (x = 0; gfs_log_ops[x]; x++) - if (gfs_log_ops[x]->lo_scan_elements) { - error = gfs_log_ops[x]->lo_scan_elements(sdp, jdesc, gl, - start, desc, pass); - if (error) - return error; - } - - return 0; -} - -#define LO_AFTER_SCAN(sdp, jid, pass) \ -do \ -{ \ - int __lops_x; \ - for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ - if (gfs_log_ops[__lops_x]->lo_after_scan) \ - gfs_log_ops[__lops_x]->lo_after_scan((sdp), (jid), (pass)); \ -} \ -while (0) - -#endif /* __LOPS_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/lvb.c b/gfs-kernel/src/gfs/lvb.c deleted file mode 100644 index 8355796..0000000 --- a/gfs-kernel/src/gfs/lvb.c +++ /dev/null @@ -1,148 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" - -#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); - -#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} -#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} -#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} -#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} -#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} -#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} -#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} -#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} - -/** - * gfs_rgrp_lvb_in - Read in rgrp data - * @rb: the cpu-order structure - * @lvb: the lvb - * - */ - -void -gfs_rgrp_lvb_in(struct gfs_rgrp_lvb *rb, char *lvb) -{ - struct gfs_rgrp_lvb *str = (struct gfs_rgrp_lvb *)lvb; - - CPIN_32(rb, str, rb_magic); - CPIN_32(rb, str, rb_free); - CPIN_32(rb, str, rb_useddi); - CPIN_32(rb, str, rb_freedi); - CPIN_32(rb, str, rb_usedmeta); - CPIN_32(rb, str, rb_freemeta); -} - -/** - * gfs_rgrp_lvb_out - Write out rgrp data - * @rb: the cpu-order structure - * @lvb: the lvb - * - */ - -void -gfs_rgrp_lvb_out(struct gfs_rgrp_lvb *rb, char *lvb) -{ - struct gfs_rgrp_lvb *str = (struct gfs_rgrp_lvb *)lvb; - - CPOUT_32(rb, str, rb_magic); - CPOUT_32(rb, str, rb_free); - CPOUT_32(rb, str, rb_useddi); - CPOUT_32(rb, str, rb_freedi); - CPOUT_32(rb, str, rb_usedmeta); - CPOUT_32(rb, str, rb_freemeta); -} - -/** - * gfs_rgrp_lvb_print - Print out rgrp data - * @rb: the cpu-order structure - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - */ - -void -gfs_rgrp_lvb_print(struct gfs_rgrp_lvb *rb) -{ - pv(rb, rb_magic, "%u"); - pv(rb, rb_free, "%u"); - pv(rb, rb_useddi, "%u"); - pv(rb, rb_freedi, "%u"); - pv(rb, rb_usedmeta, "%u"); - pv(rb, rb_freemeta, "%u"); -} - -/** - * gfs_quota_lvb_in - Read in quota data - * @rb: the cpu-order structure - * @lvb: the lvb - * - */ - -void -gfs_quota_lvb_in(struct gfs_quota_lvb *qb, char *lvb) -{ - struct gfs_quota_lvb *str = (struct gfs_quota_lvb *)lvb; - - CPIN_32(qb, str, qb_magic); - CPIN_32(qb, str, qb_pad); - CPIN_64(qb, str, qb_limit); - CPIN_64(qb, str, qb_warn); - CPIN_64(qb, str, qb_value); -} - -/** - * gfs_quota_lvb_out - Write out quota data - * @rb: the cpu-order structure - * @lvb: the lvb - * - */ - -void -gfs_quota_lvb_out(struct gfs_quota_lvb *qb, char *lvb) -{ - struct gfs_quota_lvb *str = (struct gfs_quota_lvb *)lvb; - - CPOUT_32(qb, str, qb_magic); - CPOUT_32(qb, str, qb_pad); - CPOUT_64(qb, str, qb_limit); - CPOUT_64(qb, str, qb_warn); - CPOUT_64(qb, str, qb_value); -} - -/** - * gfs_quota_lvb_print - Print out quota data - * @rb: the cpu-order structure - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - */ - -void -gfs_quota_lvb_print(struct gfs_quota_lvb *qb) -{ - pv(qb, qb_magic, "%u"); - pv(qb, qb_pad, "%u"); - pv(qb, qb_limit, "%"PRIu64); - pv(qb, qb_warn, "%"PRIu64); - pv(qb, qb_value, "%"PRId64); -} diff --git a/gfs-kernel/src/gfs/lvb.h b/gfs-kernel/src/gfs/lvb.h deleted file mode 100644 index d87d22b..0000000 --- a/gfs-kernel/src/gfs/lvb.h +++ /dev/null @@ -1,66 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * Formats of Lock Value Blocks (LVBs) for various types of locks. - * These 32-bit data chunks can be shared quickly between nodes - * via the inter-node lock manager (via LAN instead of on-disk). - */ - -#ifndef __LVB_DOT_H__ -#define __LVB_DOT_H__ - -#define GFS_MIN_LVB_SIZE (32) - -/* - * Resource Group block allocation statistics - * Each resource group lock contains one of these in its LVB. - * Used for sharing approximate current statistics for statfs. - * Not used for actual block allocation. - */ -struct gfs_rgrp_lvb { - uint32_t rb_magic; /* GFS_MAGIC sanity check value */ - uint32_t rb_free; /* # free data blocks */ - uint32_t rb_useddi; /* # used dinode blocks */ - uint32_t rb_freedi; /* # free dinode blocks */ - uint32_t rb_usedmeta; /* # used metadata blocks */ - uint32_t rb_freemeta; /* # free metadata blocks */ -}; - -/* - * Quota - * Each quota lock contains one of these in its LVB. - * Keeps track of block allocation limits and current block allocation - * for either a cluster-wide user or a cluster-wide group. - */ -struct gfs_quota_lvb { - uint32_t qb_magic; /* GFS_MAGIC sanity check value */ - uint32_t qb_pad; - uint64_t qb_limit; /* Hard limit of # blocks to alloc */ - uint64_t qb_warn; /* Warn user when alloc is above this # */ - int64_t qb_value; /* Current # blocks allocated */ -}; - -/* Translation functions */ - -void gfs_rgrp_lvb_in(struct gfs_rgrp_lvb *rb, char *lvb); -void gfs_rgrp_lvb_out(struct gfs_rgrp_lvb *rb, char *lvb); -void gfs_quota_lvb_in(struct gfs_quota_lvb *qb, char *lvb); -void gfs_quota_lvb_out(struct gfs_quota_lvb *qb, char *lvb); - -/* Printing functions */ - -void gfs_rgrp_lvb_print(struct gfs_rgrp_lvb *rb); -void gfs_quota_lvb_print(struct gfs_quota_lvb *qb); - -#endif /* __LVB_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/main.c b/gfs-kernel/src/gfs/main.c deleted file mode 100644 index 7fd1758..0000000 --- a/gfs-kernel/src/gfs/main.c +++ /dev/null @@ -1,132 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/proc_fs.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "gfs.h" -#include "diaper.h" -#include "ops_fstype.h" -#include "proc.h" - -/** - * init_gfs_fs - Register GFS as a filesystem - * - * Returns: 0 on success, error code on failure - */ - -int __init -init_gfs_fs(void) -{ - int error; - - gfs_proc_init(); - - error = gfs_diaper_init(); - if (error) - goto fail; - - gfs_random_number = xtime.tv_nsec; - - gfs_glock_cachep = kmem_cache_create("gfs_glock", sizeof(struct gfs_glock), - 0, 0, - NULL, NULL); - gfs_inode_cachep = NULL; - gfs_bufdata_cachep = NULL; - gfs_mhc_cachep = NULL; - error = -ENOMEM; - if (!gfs_glock_cachep) - goto fail_diaper; - - gfs_inode_cachep = kmem_cache_create("gfs_inode", sizeof(struct gfs_inode), - 0, 0, - NULL, NULL); - if (!gfs_inode_cachep) - goto fail_diaper; - - gfs_bufdata_cachep = kmem_cache_create("gfs_bufdata", sizeof(struct gfs_bufdata), - 0, 0, - NULL, NULL); - if (!gfs_bufdata_cachep) - goto fail_diaper; - - gfs_mhc_cachep = kmem_cache_create("gfs_meta_header_cache", sizeof(struct gfs_meta_header_cache), - 0, 0, - NULL, NULL); - if (!gfs_mhc_cachep) - goto fail_diaper; - - error = register_filesystem(&gfs_fs_type); - if (error) - goto fail_diaper; - - printk("GFS %s (built %s %s) installed\n", - GFS_RELEASE_NAME, __DATE__, __TIME__); - - return 0; - - fail_diaper: - if (gfs_mhc_cachep) - kmem_cache_destroy(gfs_mhc_cachep); - - if (gfs_bufdata_cachep) - kmem_cache_destroy(gfs_bufdata_cachep); - - if (gfs_inode_cachep) - kmem_cache_destroy(gfs_inode_cachep); - - if (gfs_glock_cachep) - kmem_cache_destroy(gfs_glock_cachep); - - gfs_diaper_uninit(); - - fail: - gfs_proc_uninit(); - - return error; -} - -/** - * exit_gfs_fs - Unregister the file system - * - */ - -void __exit -exit_gfs_fs(void) -{ - unregister_filesystem(&gfs_fs_type); - - kmem_cache_destroy(gfs_mhc_cachep); - kmem_cache_destroy(gfs_bufdata_cachep); - kmem_cache_destroy(gfs_inode_cachep); - kmem_cache_destroy(gfs_glock_cachep); - - gfs_diaper_uninit(); - gfs_proc_uninit(); -} - -MODULE_DESCRIPTION("Global File System " GFS_RELEASE_NAME); -MODULE_AUTHOR("Red Hat, Inc."); -MODULE_LICENSE("GPL"); - -module_init(init_gfs_fs); -module_exit(exit_gfs_fs); - diff --git a/gfs-kernel/src/gfs/mount.c b/gfs-kernel/src/gfs/mount.c deleted file mode 100644 index 5bf0ba3..0000000 --- a/gfs-kernel/src/gfs/mount.c +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "mount.h" -#include "proc.h" - -/** - * gfs_make_args - Parse mount arguments - * @data: - * @args: - * - * Return: errno - */ - -int -gfs_make_args(char *data_arg, struct gfs_args *args) -{ - char *data = data_arg; - char *options, *x, *y; - int error = 0; - - /* If someone preloaded options, use those instead */ - - spin_lock(&gfs_proc_margs_lock); - if (gfs_proc_margs) { - data = gfs_proc_margs; - gfs_proc_margs = NULL; - } - spin_unlock(&gfs_proc_margs_lock); - - /* Set some defaults */ - - memset(args, 0, sizeof(struct gfs_args)); - args->ar_num_glockd = GFS_GLOCKD_DEFAULT; - - /* Split the options into tokens with the "," character and - process them */ - - for (options = data; (x = strsep(&options, ",")); ) { - if (!*x) - continue; - - y = strchr(x, '='); - if (y) - *y++ = 0; - - if (!strcmp(x, "lockproto")) { - if (!y) { - printk("GFS: need argument to lockproto\n"); - error = -EINVAL; - break; - } - strncpy(args->ar_lockproto, y, GFS_LOCKNAME_LEN); - args->ar_lockproto[GFS_LOCKNAME_LEN - 1] = 0; - } - - else if (!strcmp(x, "locktable")) { - if (!y) { - printk("GFS: need argument to locktable\n"); - error = -EINVAL; - break; - } - strncpy(args->ar_locktable, y, GFS_LOCKNAME_LEN); - args->ar_locktable[GFS_LOCKNAME_LEN - 1] = 0; - } - - else if (!strcmp(x, "hostdata")) { - if (!y) { - printk("GFS: need argument to hostdata\n"); - error = -EINVAL; - break; - } - strncpy(args->ar_hostdata, y, GFS_LOCKNAME_LEN); - args->ar_hostdata[GFS_LOCKNAME_LEN - 1] = 0; - } - - else if (!strcmp(x, "ignore_local_fs")) - args->ar_ignore_local_fs = TRUE; - - else if (!strcmp(x, "localflocks")) - args->ar_localflocks = TRUE; - - else if (!strcmp(x, "localcaching")) - args->ar_localcaching = TRUE; - - else if (!strcmp(x, "oopses_ok")) - args->ar_oopses_ok = TRUE; - - else if (!strcmp(x, "debug")) { - args->ar_oopses_ok = TRUE; - args->ar_debug = TRUE; - - } else if (!strcmp(x, "upgrade")) - args->ar_upgrade = TRUE; - - else if (!strcmp(x, "num_glockd")) { - if (!y) { - printk("GFS: need argument to num_glockd\n"); - error = -EINVAL; - break; - } - sscanf(y, "%u", &args->ar_num_glockd); - if (!args->ar_num_glockd || args->ar_num_glockd > GFS_GLOCKD_MAX) { - printk("GFS: 0 < num_glockd <= %u (not %u)\n", - GFS_GLOCKD_MAX, args->ar_num_glockd); - error = -EINVAL; - break; - } - } - - else if (!strcmp(x, "acl")) - args->ar_posix_acls = TRUE; - - else if (!strcmp(x, "suiddir")) - args->ar_suiddir = TRUE; - - else if (!strcmp(x, "noquota")) - args->ar_noquota = TRUE; - - /* Unknown */ - - else { - printk("GFS: unknown option: %s\n", x); - error = -EINVAL; - break; - } - } - - if (error) - printk("GFS: invalid mount option(s)\n"); - - if (data != data_arg) - kfree(data); - - return error; -} - diff --git a/gfs-kernel/src/gfs/mount.h b/gfs-kernel/src/gfs/mount.h deleted file mode 100644 index f24f139..0000000 --- a/gfs-kernel/src/gfs/mount.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __MOUNT_DOT_H__ -#define __MOUNT_DOT_H__ - -int gfs_make_args(char *data, struct gfs_args *args); - -#endif /* __MOUNT_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ondisk.c b/gfs-kernel/src/gfs/ondisk.c deleted file mode 100644 index f510a18..0000000 --- a/gfs-kernel/src/gfs/ondisk.c +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" - -#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> - diff --git a/gfs-kernel/src/gfs/ops_address.c b/gfs-kernel/src/gfs/ops_address.c deleted file mode 100644 index ae7359c..0000000 --- a/gfs-kernel/src/gfs/ops_address.c +++ /dev/null @@ -1,489 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/pagemap.h> -#include <linux/fs.h> - -#include "gfs.h" -#include "bmap.h" -#include "dio.h" -#include "file.h" -#include "glock.h" -#include "inode.h" -#include "ops_address.h" -#include "page.h" -#include "quota.h" -#include "trans.h" - -static int gfs_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to); -/** - * get_block - Fills in a buffer head with details about a block - * @inode: The inode - * @lblock: The block number to look up - * @bh_result: The buffer head to return the result in - * @create: Non-zero if we may add block to the file - * - * Returns: errno - */ - -static int -get_block(struct inode *inode, sector_t lblock, - struct buffer_head *bh_result, int create) -{ - struct gfs_inode *ip = vn2ip(inode); - int new = create; - uint64_t dblock; - int error; - - error = gfs_block_map(ip, lblock, &new, &dblock, NULL); - if (error) - return error; - - if (!dblock) - return 0; - - map_bh(bh_result, inode->i_sb, dblock); - if (new) - set_buffer_new(bh_result); - - return 0; -} - -/** - * get_block_noalloc - Fills in a buffer head with details about a block - * @inode: The inode - * @lblock: The block number to look up - * @bh_result: The buffer head to return the result in - * @create: Non-zero if we may add block to the file - * - * Returns: errno - */ - -static int -get_block_noalloc(struct inode *inode, sector_t lblock, - struct buffer_head *bh_result, int create) -{ - int error; - - error = get_block(inode, lblock, bh_result, FALSE); - if (error) - return error; - - if (gfs_assert_withdraw(vfs2sdp(inode->i_sb), - !create || buffer_mapped(bh_result))) - return -EIO; - - return 0; -} - -/** - * get_blocks - - * @inode: - * @lblock: - * @max_blocks: - * @bh_result: - * @create: - * - * Returns: errno - */ - -static int -get_blocks(struct inode *inode, sector_t lblock, - unsigned long max_blocks, - struct buffer_head *bh_result, int create) -{ - struct gfs_inode *ip = vn2ip(inode); - int new = create; - uint64_t dblock; - uint32_t extlen; - int error; - - error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); - if (error) - return error; - - if (!dblock) - return 0; - - map_bh(bh_result, inode->i_sb, dblock); - if (new) - set_buffer_new(bh_result); - - if (extlen > max_blocks) - extlen = max_blocks; - bh_result->b_size = extlen << inode->i_blkbits; - - return 0; -} - -/** - * get_blocks_noalloc - - * @inode: - * @lblock: - * @max_blocks: - * @bh_result: - * @create: - * - * Returns: errno - */ - -static int -get_blocks_noalloc(struct inode *inode, sector_t lblock, - unsigned long max_blocks, - struct buffer_head *bh_result, int create) -{ - int error; - - error = get_blocks(inode, lblock, max_blocks, bh_result, FALSE); - if (error) - return error; - - if (gfs_assert_withdraw(vfs2sdp(inode->i_sb), - !create || buffer_mapped(bh_result))) - return -EIO; - - return 0; -} - -/** - * gfs_writepage - Write complete page - * @page: Page to write - * - * Returns: errno - * - * Use Linux VFS block_write_full_page() to write one page, - * using GFS's get_block_noalloc to find which blocks to write. - */ - -static int -gfs_writepage(struct page *page, struct writeback_control *wbc) -{ - struct gfs_inode *ip = vn2ip(page->mapping->host); - struct gfs_sbd *sdp = ip->i_sbd; - int error; - - atomic_inc(&sdp->sd_ops_address); - - if (gfs_assert_withdraw(sdp, gfs_glock_is_held_excl(ip->i_gl))) { - unlock_page(page); - return -EIO; - } - if (current_transaction) { - redirty_page_for_writepage(wbc, page); - unlock_page(page); - return 0; - } - - error = block_write_full_page(page, get_block_noalloc, wbc); - - gfs_flush_meta_cache(ip); - - return error; -} - -/** - * stuffed_readpage - Fill in a Linux page with stuffed file data - * @ip: the inode - * @page: the page - * - * Returns: errno - */ - -static int -stuffed_readpage(struct gfs_inode *ip, struct page *page) -{ - struct buffer_head *dibh; - char *kaddr; - int error; - - error = gfs_get_inode_buffer(ip, &dibh); - if (!error) { - kaddr = (char *)kmap_atomic(page, KM_USER0); - memcpy(kaddr, - dibh->b_data + sizeof(struct gfs_dinode), - ip->i_di.di_size); - memset(kaddr + ip->i_di.di_size, - 0, - PAGE_CACHE_SIZE - ip->i_di.di_size); - kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(page); - brelse(dibh); - - SetPageUptodate(page); - } - - return error; -} - -/** - * readi_readpage - readpage that goes through gfs_internal_read() - * @page: The page to read - * - * Returns: errno - */ - -static int -readi_readpage(struct page *page) -{ - struct gfs_inode *ip = vn2ip(page->mapping->host); - void *kaddr; - int ret; - - kaddr = kmap(page); - - ret = gfs_internal_read(ip, kaddr, - (uint64_t)page->index << PAGE_CACHE_SHIFT, - PAGE_CACHE_SIZE); - if (ret >= 0) { - if (ret < PAGE_CACHE_SIZE) - memset(kaddr + ret, 0, PAGE_CACHE_SIZE - ret); - SetPageUptodate(page); - ret = 0; - } - - kunmap(page); - - unlock_page(page); - - return ret; -} - -/** - * gfs_readpage - readpage with locking - * @file: The file to read a page for - * @page: The page to read - * - * Returns: errno - */ - -static int -gfs_readpage(struct file *file, struct page *page) -{ - struct gfs_inode *ip = vn2ip(page->mapping->host); - struct gfs_sbd *sdp = ip->i_sbd; - int error; - - atomic_inc(&sdp->sd_ops_address); - - if (!gfs_glock_is_locked_by_me(ip->i_gl)) { - unlock_page(page); - return -ENOSYS; - } - - if (!gfs_is_jdata(ip)) { - if (gfs_is_stuffed(ip) && !page->index) { - error = stuffed_readpage(ip, page); - unlock_page(page); - } else - error = block_read_full_page(page, get_block); - } else - error = readi_readpage(page); - - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = -EIO; - - return error; -} - -/** - * gfs_prepare_write - Prepare to write a page to a file - * @file: The file to write to - * @page: The page which is to be prepared for writing - * @from: From (byte range within page) - * @to: To (byte range within page) - * - * Returns: errno - * - * Make sure file's inode is glocked; we shouldn't write without that! - * If GFS dinode is currently stuffed (small enough that all data fits within - * the dinode block), and new file size is too large, unstuff it. - * Use Linux VFS block_prepare_write() to write blocks, using GFS' get_block() - * to find which blocks to write. - */ - -static int -gfs_prepare_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct gfs_inode *ip = vn2ip(page->mapping->host); - struct gfs_sbd *sdp = ip->i_sbd; - int error = 0; - - atomic_inc(&sdp->sd_ops_address); - - /* We can't set commit_write in the structure in the declare */ - /* because if we do, loopback (loop.c) will interpret that to mean */ - /* it's okay to do buffered writes without locking through sendfile. */ - /* This is a kludge to get around the problem with loop.c because */ - /* the upstream community rejected my changes to loop.c. */ - ip->gfs_file_aops.commit_write = gfs_commit_write; - - if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl))) - return -ENOSYS; - - if (gfs_is_stuffed(ip)) { - uint64_t file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to; - - if (file_size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { - error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, page); - if (!error) - error = block_prepare_write(page, from, to, get_block); - } else if (!PageUptodate(page)) - error = stuffed_readpage(ip, page); - } else - error = block_prepare_write(page, from, to, get_block); - - return error; -} - -/** - * gfs_commit_write - Commit write to a file - * @file: The file to write to - * @page: The page containing the data - * @from: From (byte range within page) - * @to: To (byte range within page) - * - * Returns: errno - */ - -static int -gfs_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct inode *inode = page->mapping->host; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_sbd *sdp = ip->i_sbd; - int error; - - atomic_inc(&sdp->sd_ops_address); - - if (gfs_is_stuffed(ip)) { - struct buffer_head *dibh; - uint64_t file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to; - void *kaddr; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail; - - gfs_trans_add_bh(ip->i_gl, dibh); - - kaddr = kmap_atomic(page, KM_USER0); - memcpy(dibh->b_data + sizeof(struct gfs_dinode) + from, - (char *)kaddr + from, - to - from); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - - SetPageUptodate(page); - if (inode->i_size < file_size) { - i_size_write(inode, file_size); - mark_inode_dirty(inode); - } - brelse(dibh); - } else { - error = generic_commit_write(file, page, from, to); - if (error) - goto fail; - } - - ip->gfs_file_aops.commit_write = NULL; - return 0; - - fail: - ClearPageUptodate(page); - - return error; -} - -/** - * gfs_bmap - Block map function - * @mapping: Address space info - * @lblock: The block to map - * - * Returns: The disk address for the block or 0 on hole or error - */ - -static sector_t -gfs_bmap(struct address_space *mapping, sector_t lblock) -{ - struct gfs_inode *ip = vn2ip(mapping->host); - struct gfs_holder i_gh; - int dblock = 0; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_address); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return 0; - - if (!gfs_is_stuffed(ip)) - dblock = generic_block_bmap(mapping, lblock, get_block); - - gfs_glock_dq_uninit(&i_gh); - - return dblock; -} - -/** - * gfs_direct_IO - - * @rw: - * @iocb: - * @iov: - * @offset: - * @nr_segs: - * - * Returns: errno - */ - -static int -gfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t offset, unsigned long nr_segs) -{ - struct file *file = iocb->ki_filp; - struct inode *inode = file->f_mapping->host; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_sbd *sdp = ip->i_sbd; - get_blocks_t *gb = get_blocks; - - atomic_inc(&sdp->sd_ops_address); - - if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl)) || - gfs_assert_warn(sdp, !gfs_is_stuffed(ip))) - return -EINVAL; - - if (rw == WRITE && !current_transaction) - gb = get_blocks_noalloc; - - return blockdev_direct_IO_cluster_locking(rw, iocb, inode, - inode->i_sb->s_bdev, iov, - offset, nr_segs, gb, NULL); -} - -struct address_space_operations gfs_file_aops = { - .writepage = gfs_writepage, - .readpage = gfs_readpage, - .sync_page = block_sync_page, - .prepare_write = gfs_prepare_write, - .bmap = gfs_bmap, - .direct_IO = gfs_direct_IO, -}; diff --git a/gfs-kernel/src/gfs/ops_address.h b/gfs-kernel/src/gfs/ops_address.h deleted file mode 100644 index 32c3cc0..0000000 --- a/gfs-kernel/src/gfs/ops_address.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_ADDRESS_DOT_H__ -#define __OPS_ADDRESS_DOT_H__ - -extern struct address_space_operations gfs_file_aops; - -#endif /* __OPS_ADDRESS_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_dentry.c b/gfs-kernel/src/gfs/ops_dentry.c deleted file mode 100644 index a62639b..0000000 --- a/gfs-kernel/src/gfs/ops_dentry.c +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dir.h" -#include "glock.h" -#include "ops_dentry.h" - -/** - * gfs_drevalidate - Check directory lookup consistency - * @dentry: the mapping to check - * @nd: - * - * Check to make sure the lookup necessary to arrive at this inode from its - * parent is still good. - * - * Returns: 1 if the dentry is ok, 0 if it isn't - */ - -static int -gfs_drevalidate(struct dentry *dentry, struct nameidata *nd) -{ - struct dentry *parent = dget_parent(dentry); - struct gfs_inode *dip = vn2ip(parent->d_inode); - struct gfs_sbd *sdp = dip->i_sbd; - struct inode *inode; - struct gfs_holder d_gh; - struct gfs_inode *ip; - struct gfs_inum inum; - unsigned int type; - int error; - - lock_kernel(); - - atomic_inc(&sdp->sd_ops_dentry); - - if (sdp->sd_args.ar_localcaching) - goto valid; - - inode = dentry->d_inode; - if (inode && is_bad_inode(inode)) - goto invalid; - - error = gfs_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); - if (error) - goto fail; - - error = gfs_dir_search(dip, &dentry->d_name, &inum, &type); - switch (error) { - case 0: - if (!inode) - goto invalid_gunlock; - break; - case -ENOENT: - if (!inode) - goto valid_gunlock; - goto invalid_gunlock; - default: - goto fail_gunlock; - } - - ip = vn2ip(inode); - - if (ip->i_num.no_formal_ino != inum.no_formal_ino) - goto invalid_gunlock; - - if (ip->i_di.di_type != type) { - gfs_consist_inode(dip); - goto fail_gunlock; - } - - valid_gunlock: - gfs_glock_dq_uninit(&d_gh); - - valid: - unlock_kernel(); - dput(parent); - return 1; - - invalid_gunlock: - gfs_glock_dq_uninit(&d_gh); - - invalid: - if (inode && S_ISDIR(inode->i_mode)) { - if (have_submounts(dentry)) - goto valid; - shrink_dcache_parent(dentry); - } - d_drop(dentry); - - unlock_kernel(); - dput(parent); - return 0; - - fail_gunlock: - gfs_glock_dq_uninit(&d_gh); - - fail: - unlock_kernel(); - dput(parent); - return 0; -} - -struct dentry_operations gfs_dops = { - .d_revalidate = gfs_drevalidate, -}; diff --git a/gfs-kernel/src/gfs/ops_dentry.h b/gfs-kernel/src/gfs/ops_dentry.h deleted file mode 100644 index 9ad8070..0000000 --- a/gfs-kernel/src/gfs/ops_dentry.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_DENTRY_DOT_H__ -#define __OPS_DENTRY_DOT_H__ - -extern struct dentry_operations gfs_dops; - -#endif /* __OPS_DENTRY_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_export.c b/gfs-kernel/src/gfs/ops_export.c deleted file mode 100644 index c9cfb54..0000000 --- a/gfs-kernel/src/gfs/ops_export.c +++ /dev/null @@ -1,450 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dio.h" -#include "dir.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "ops_dentry.h" -#include "ops_export.h" -#include "rgrp.h" - -struct inode_cookie -{ - uint64_t formal_ino; - uint32_t gen; - int gen_valid; -}; - -struct get_name_filldir -{ - uint64_t formal_ino; - char *name; -}; - -/** - * gfs_decode_fh - - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -struct dentry * -gfs_decode_fh(struct super_block *sb, __u32 *fh, int fh_len, int fh_type, - int (*acceptable)(void *context, struct dentry *dentry), - void *context) -{ - struct inode_cookie this, parent; - - atomic_inc(&vfs2sdp(sb)->sd_ops_export); - - memset(&parent, 0, sizeof(struct inode_cookie)); - - switch (fh_type) { - case 6: - parent.gen_valid = TRUE; - parent.gen = gfs32_to_cpu(fh[5]); - case 5: - parent.formal_ino = ((uint64_t)gfs32_to_cpu(fh[3])) << 32; - parent.formal_ino |= (uint64_t)gfs32_to_cpu(fh[4]); - case 3: - this.gen_valid = TRUE; - this.gen = gfs32_to_cpu(fh[2]); - this.formal_ino = ((uint64_t)gfs32_to_cpu(fh[0])) << 32; - this.formal_ino |= (uint64_t)gfs32_to_cpu(fh[1]); - break; - default: - return NULL; - } - - return gfs_export_ops.find_exported_dentry(sb, &this, &parent, - acceptable, context); -} - -/** - * gfs_encode_fh - - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -int -gfs_encode_fh(struct dentry *dentry, __u32 *fh, int *len, - int connectable) -{ - struct inode *inode = dentry->d_inode; - struct gfs_inode *ip = vn2ip(inode); - int maxlen = *len; - - atomic_inc(&ip->i_sbd->sd_ops_export); - - if (maxlen < 3) - return 255; - - fh[0] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino >> 32)); - fh[1] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino & 0xFFFFFFFF)); - fh[2] = cpu_to_gfs32(inode->i_generation); /* dinode's mh_incarn */ - *len = 3; - - if (maxlen < 5 || !connectable) - return 3; - - spin_lock(&dentry->d_lock); - - inode = dentry->d_parent->d_inode; - ip = vn2ip(inode); - - fh[3] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino >> 32)); - fh[4] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino & 0xFFFFFFFF)); - *len = 5; - - if (maxlen < 6) { - spin_unlock(&dentry->d_lock); - return 5; - } - - fh[5] = cpu_to_gfs32(inode->i_generation); /* dinode's mh_incarn */ - - spin_unlock(&dentry->d_lock); - - *len = 6; - - return 6; -} - -/** - * get_name_filldir - - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -static int -get_name_filldir(void *opaque, - const char *name, unsigned int length, - uint64_t offset, - struct gfs_inum *inum, unsigned int type) -{ - struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; - - if (inum->no_formal_ino != gnfd->formal_ino) - return 0; - - memcpy(gnfd->name, name, length); - gnfd->name[length] = 0; - - return 1; -} - -/** - * gfs_get_name - - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -int gfs_get_name(struct dentry *parent, char *name, - struct dentry *child) -{ - struct inode *dir = parent->d_inode; - struct inode *inode = child->d_inode; - struct gfs_inode *dip, *ip; - struct get_name_filldir gnfd; - struct gfs_holder gh; - uint64_t offset = 0; - int error; - - if (!dir) - return -EINVAL; - - atomic_inc(&vfs2sdp(dir->i_sb)->sd_ops_export); - - if (!S_ISDIR(dir->i_mode) || !inode) - return -EINVAL; - - dip = vn2ip(dir); - ip = vn2ip(inode); - - *name = 0; - gnfd.formal_ino = ip->i_num.no_formal_ino; - gnfd.name = name; - - error = gfs_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); - if (error) - return error; - - error = gfs_dir_read(dip, &offset, &gnfd, get_name_filldir); - - gfs_glock_dq_uninit(&gh); - - if (!error && !*name) - error = -ENOENT; - - return error; -} - -/** - * gfs_get_parent - - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -struct dentry * -gfs_get_parent(struct dentry *child) -{ - struct gfs_inode *dip = vn2ip(child->d_inode); - struct gfs_holder d_gh, i_gh; - struct qstr dotdot = { .name = "..", .len = 2 }; - struct gfs_inode *ip; - struct inode *inode; - struct dentry *dentry; - int error; - - atomic_inc(&dip->i_sbd->sd_ops_export); - - gfs_holder_init(dip->i_gl, 0, 0, &d_gh); - error = gfs_lookupi(&d_gh, &dotdot, TRUE, &i_gh); - if (error) - goto fail; - - error = -ENOENT; - if (!i_gh.gh_gl) - goto fail; - - ip = gl2ip(i_gh.gh_gl); - - gfs_glock_dq_uninit(&d_gh); - gfs_glock_dq_uninit(&i_gh); - - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - if (!inode) - return ERR_PTR(-ENOMEM); - - dentry = d_alloc_anon(inode); - if (!dentry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - dentry->d_op = &gfs_dops; - return dentry; - - fail: - gfs_holder_uninit(&d_gh); - return ERR_PTR(error); -} - -/** - * gfs_refresh_iobj - - * @sdp: pointer to struct gfs_sbd - * @inum: pointer to struct gfs_inum - * @refresh: set to true if inode refreshed - * return: pointer to struct inode or errno - * - * This function was part of gfs_get_dentry where it - * - allocated a gfs_inode "ip" - * - disk-read in "ip" - * - allocated a vfs inode for this "ip". - * - * We yank it out to allow gfs_rename() to re-use - * this logic. - */ - -struct inode *gfs_refresh_iobj(struct gfs_sbd *sdp, void *inum_obj, int *miss) -{ - struct gfs_holder i_gh, ri_gh, rgd_gh; - struct gfs_rgrpd *rgd; - struct buffer_head *bh; - struct gfs_dinode *di; - struct gfs_inode *ip; - struct inode *inode; - struct gfs_inum *inum = (struct gfs_inum *) inum_obj; - int error; - - error = gfs_glock_nq_num(sdp, - inum->no_formal_ino, &gfs_inode_glops, - LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL, - &i_gh); - if (error) - return ERR_PTR(error); - - error = gfs_inode_get(i_gh.gh_gl, inum, NO_CREATE, &ip); - if (error) - goto fail; - if (ip) - goto out; - - /* - * Used by NFS support statistics for FHs that miss their dentres. - */ - if (miss) - *miss = 1; - - error = gfs_rindex_hold(sdp, &ri_gh); - if (error) - goto fail; - - error = -EINVAL; - rgd = gfs_blk2rgrpd(sdp, inum->no_addr); - if (!rgd) - goto fail_rindex; - - error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); - if (error) - goto fail_rindex; - - error = -ESTALE; - if (gfs_get_block_type(rgd, inum->no_addr) != GFS_BLKST_USEDMETA) - goto fail_rgd; - - error = gfs_dread(i_gh.gh_gl, inum->no_addr, - DIO_START | DIO_WAIT, &bh); - if (error) - goto fail_rgd; - - di = (struct gfs_dinode *)bh->b_data; - - error = -ESTALE; - if (gfs32_to_cpu(di->di_header.mh_magic) != GFS_MAGIC || - gfs32_to_cpu(di->di_header.mh_type) != GFS_METATYPE_DI || - (gfs32_to_cpu(di->di_flags) & GFS_DIF_UNUSED)) - goto fail_relse; - - brelse(bh); - gfs_glock_dq_uninit(&rgd_gh); - gfs_glock_dq_uninit(&ri_gh); - - error = gfs_inode_get(i_gh.gh_gl, inum, CREATE, &ip); - if (error) - goto fail; - - out: - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - gfs_glock_dq_uninit(&i_gh); - - if (!inode) - return ERR_PTR(-ENOMEM); - - return inode; - - fail_relse: - brelse(bh); - - fail_rgd: - gfs_glock_dq_uninit(&rgd_gh); - - fail_rindex: - gfs_glock_dq_uninit(&ri_gh); - - fail: - gfs_glock_dq_uninit(&i_gh); - return ERR_PTR(error); -} - -/** - * gfs_get_dentry - - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -struct dentry * -gfs_get_dentry(struct super_block *sb, void *inump) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - struct inode_cookie *cookie = (struct inode_cookie *)inump; - struct gfs_inum inum; - struct inode *inode; - struct dentry *dentry; - int dentry_miss=0; - - atomic_inc(&sdp->sd_ops_export); - - if (!cookie->formal_ino || - cookie->formal_ino == sdp->sd_jiinode->i_num.no_formal_ino || - cookie->formal_ino == sdp->sd_riinode->i_num.no_formal_ino || - cookie->formal_ino == sdp->sd_qinode->i_num.no_formal_ino || - cookie->formal_ino == sdp->sd_linode->i_num.no_formal_ino) - return ERR_PTR(-EINVAL); - - inum.no_formal_ino = cookie->formal_ino; - inum.no_addr = cookie->formal_ino; - - inode = gfs_refresh_iobj(sdp, &inum, &dentry_miss); - if (dentry_miss) - atomic_inc(&sdp->sd_fh2dentry_misses); - if (IS_ERR(inode)) - return ERR_PTR((long)inode); - - /* inode->i_generation is GFS dinode's mh_incarn value */ - if (cookie->gen_valid && cookie->gen != inode->i_generation) { - iput(inode); - return ERR_PTR(-ESTALE); - } - - dentry = d_alloc_anon(inode); - if (!dentry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - - dentry->d_op = &gfs_dops; - return dentry; -} - -struct export_operations gfs_export_ops = { - .decode_fh = gfs_decode_fh, - .encode_fh = gfs_encode_fh, - .get_name = gfs_get_name, - .get_parent = gfs_get_parent, - .get_dentry = gfs_get_dentry, -}; - diff --git a/gfs-kernel/src/gfs/ops_export.h b/gfs-kernel/src/gfs/ops_export.h deleted file mode 100644 index afd6e95..0000000 --- a/gfs-kernel/src/gfs/ops_export.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_EXPORT_DOT_H__ -#define __OPS_EXPORT_DOT_H__ - -extern struct export_operations gfs_export_ops; - -#endif /* __OPS_EXPORT_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_file.c b/gfs-kernel/src/gfs/ops_file.c deleted file mode 100644 index 628ab99..0000000 --- a/gfs-kernel/src/gfs/ops_file.c +++ /dev/null @@ -1,1879 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> -#include <linux/pagemap.h> -#include <linux/uio.h> -#include <linux/blkdev.h> -#include <linux/mm.h> -#include <linux/aio.h> -#include <asm/uaccess.h> -#include <linux/gfs_ioctl.h> -#include <linux/writeback.h> - -#include "gfs.h" -#include "bmap.h" -#include "dio.h" -#include "dir.h" -#include "file.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "ioctl.h" -#include "lm.h" -#include "log.h" -#include "ops_file.h" -#include "ops_vm.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" - -/* "bad" is for NFS support */ -struct filldir_bad_entry { - char *fbe_name; - unsigned int fbe_length; - uint64_t fbe_offset; - struct gfs_inum fbe_inum; - unsigned int fbe_type; -}; - -struct filldir_bad { - struct gfs_sbd *fdb_sbd; - - struct filldir_bad_entry *fdb_entry; - unsigned int fdb_entry_num; - unsigned int fdb_entry_off; - - char *fdb_name; - unsigned int fdb_name_size; - unsigned int fdb_name_off; -}; - -/* For regular, non-NFS */ -struct filldir_reg { - struct gfs_sbd *fdr_sbd; - int fdr_prefetch; - - filldir_t fdr_filldir; - void *fdr_opaque; -}; - -typedef ssize_t(*do_rw_t) (struct file * file, - char *buf, - size_t size, loff_t * offset, - struct kiocb *iocb, - unsigned int num_gh, struct gfs_holder * ghs); - -/** - * gfs_llseek - seek to a location in a file - * @file: the file - * @offset: the offset - * @origin: Where to seek from (SEEK_SET, SEEK_CUR, or SEEK_END) - * - * SEEK_END requires the glock for the file because it references the - * file's size. - * - * Returns: The new offset, or errno - */ - -static loff_t -gfs_llseek(struct file *file, loff_t offset, int origin) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - struct gfs_holder i_gh; - loff_t error; - - atomic_inc(&ip->i_sbd->sd_ops_file); - - if (origin == 2) { - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (!error) { - error = remote_llseek(file, offset, origin); - gfs_glock_dq_uninit(&i_gh); - } - } else - error = remote_llseek(file, offset, origin); - - return error; -} - -#define vma2state(vma) \ -((((vma)->vm_flags & (VM_MAYWRITE | VM_MAYSHARE)) == \ - (VM_MAYWRITE | VM_MAYSHARE)) ? \ - LM_ST_EXCLUSIVE : LM_ST_SHARED) \ - -/** - * functionname - summary - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -static ssize_t -walk_vm_hard(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb, do_rw_t operation) -{ - struct gfs_holder *ghs; - unsigned int num_gh = 0; - ssize_t count; - - { - struct super_block *sb = file->f_dentry->d_inode->i_sb; - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - unsigned long start = (unsigned long)buf; - unsigned long end = start + size; - int dumping = (current->flags & PF_DUMPCORE); - unsigned int x = 0; - - for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { - if (end <= vma->vm_start) - break; - if (vma->vm_file && - vma->vm_file->f_dentry->d_inode->i_sb == sb) { - num_gh++; - } - } - - ghs = kmalloc((num_gh + 1) * sizeof(struct gfs_holder), GFP_KERNEL); - if (!ghs) { - if (!dumping) - up_read(&mm->mmap_sem); - return -ENOMEM; - } - - for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { - if (end <= vma->vm_start) - break; - if (vma->vm_file) { - struct inode *inode = vma->vm_file->f_dentry->d_inode; - if (inode->i_sb == sb) - gfs_holder_init(vn2ip(inode)->i_gl, - vma2state(vma), - 0, &ghs[x++]); - } - } - - if (!dumping) - up_read(&mm->mmap_sem); - - gfs_assert(vfs2sdp(sb), x == num_gh,); - } - - count = operation(file, buf, size, offset, iocb, num_gh, ghs); - - while (num_gh--) - gfs_holder_uninit(&ghs[num_gh]); - kfree(ghs); - - return count; -} - -/** - * walk_vm - Walk the vmas associated with a buffer for read or write. - * If any of them are gfs, pass the gfs inode down to the read/write - * worker function so that locks can be acquired in the correct order. - * @file: The file to read/write from/to - * @buf: The buffer to copy to/from - * @size: The amount of data requested - * @offset: The current file offset - * @operation: The read or write worker function - * - * Outputs: Offset - updated according to number of bytes written - * - * Returns: The number of bytes written, errno on failure - */ - -static ssize_t -walk_vm(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb, - do_rw_t operation) -{ - if (current->mm) { - struct super_block *sb = file->f_dentry->d_inode->i_sb; - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - unsigned long start = (unsigned long)buf; - unsigned long end = start + size; - int dumping = (current->flags & PF_DUMPCORE); - - if (!dumping) - down_read(&mm->mmap_sem); - - for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { - if (end <= vma->vm_start) - break; - if (vma->vm_file && - vma->vm_file->f_dentry->d_inode->i_sb == sb) - goto do_locks; - } - - if (!dumping) - up_read(&mm->mmap_sem); - } - - { - struct gfs_holder gh; - return operation(file, buf, size, offset, iocb, 0, &gh); - } - - do_locks: - return walk_vm_hard(file, buf, size, offset, iocb, operation); -} - -/** - * functionname - summary - * @param1: description - * @param2: description - * @param3: description - * - * Function description - * - * Returns: what is returned - */ - -static ssize_t -do_read_readi(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - ssize_t count = 0; - - if (*offset < 0) - return -EINVAL; - if (!access_ok(VERIFY_WRITE, buf, size)) - return -EFAULT; - - if (!(file->f_flags & O_LARGEFILE)) { - if (*offset >= 0x7FFFFFFFull) - return -EFBIG; - if (*offset + size > 0x7FFFFFFFull) - size = 0x7FFFFFFFull - *offset; - } - - /* ToDo: not sure about iocb .. wcheng - */ - count = gfs_readi(ip, buf, *offset, size, gfs_copy2user); - - if (count > 0) - *offset += count; - - return count; -} - -/** - * grope_mapping - feel up a mapping that needs to be written - * @buf: the start of the memory to be written - * @size: the size of the memory to be written - * - * We do this after acquiring the locks on the mapping, - * but before starting the write transaction. We need to make - * sure that we don't cause recursive transactions if blocks - * need to be allocated to the file backing the mapping. - * - * Returns: errno - */ - -static int -grope_mapping(char *buf, size_t size) -{ - unsigned long start = (unsigned long)buf; - unsigned long stop = start + size; - char c; - - while (start < stop) { - if (copy_from_user(&c, (char *)start, 1)) - return -EFAULT; - - start += PAGE_CACHE_SIZE; - start &= PAGE_CACHE_MASK; - } - - return 0; -} - -/** - * do_read_direct - Read bytes from a file - * @file: The file to read from - * @buf: The buffer to copy into - * @size: The amount of data requested - * @offset: The current file offset - * @num_gh: The number of other locks we need to do the read - * @ghs: the locks we need plus one for our lock - * - * Outputs: Offset - updated according to number of bytes read - * - * Returns: The number of bytes read, errno on failure - */ - -static ssize_t -do_read_direct(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb, - unsigned int num_gh, struct gfs_holder *ghs) -{ - struct inode *inode = file->f_mapping->host; - struct gfs_inode *ip = vn2ip(inode); - unsigned int state = LM_ST_DEFERRED; - int flags = 0; - unsigned int x; - ssize_t count = 0; - int error; - - for (x = 0; x < num_gh; x++) - if (ghs[x].gh_gl == ip->i_gl) { - state = LM_ST_SHARED; - flags |= GL_LOCAL_EXCL; - break; - } - - down_read(&inode->i_alloc_sem); - - gfs_holder_init(ip->i_gl, state, flags, &ghs[num_gh]); - - if (num_gh && atomic_read(¤t->mm->mm_users) > 1) { - error = grope_mapping(buf, size); - if (error) - goto out; - } - - error = gfs_glock_nq_m(num_gh + 1, ghs); - if (error) - goto out; - - error = -EINVAL; - if (gfs_is_jdata(ip)) - goto out_gunlock; - - if (gfs_is_stuffed(ip)) { - size_t mask = bdev_hardsect_size(inode->i_sb->s_bdev) - 1; - - if (((*offset) & mask) || (((unsigned long)buf) & mask)) - goto out_gunlock; - - count = do_read_readi(file, buf, size & ~mask, offset, iocb); - } - else { - if (!iocb) - count = generic_file_read(file, buf, size, offset); - else { - struct iovec local_iov = { .iov_base = buf, .iov_len = size}; - count = __generic_file_aio_read(iocb, &local_iov, 1, offset); - } - } - - error = 0; - - out_gunlock: - gfs_glock_dq_m(num_gh + 1, ghs); - - out: - up_read(&inode->i_alloc_sem); - gfs_holder_uninit(&ghs[num_gh]); - - return (count) ? count : error; -} - -/** - * do_read_buf - Read bytes from a file - * @file: The file to read from - * @buf: The buffer to copy into - * @size: The amount of data requested - * @offset: The current file offset - * @num_gh: The number of other locks we need to do the read - * @ghs: the locks we need plus one for our lock - * - * Outputs: Offset - updated according to number of bytes read - * - * Returns: The number of bytes read, errno on failure - */ - -static ssize_t -do_read_buf(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb, - unsigned int num_gh, struct gfs_holder *ghs) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - ssize_t count = 0; - int error; - - gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &ghs[num_gh]); - - if (num_gh && atomic_read(¤t->mm->mm_users) > 1) { - error = grope_mapping(buf, size); - if (error) - goto out; - } - - error = gfs_glock_nq_m_atime(num_gh + 1, ghs); - if (error) - goto out; - - if (gfs_is_jdata(ip) || - (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags))) - count = do_read_readi(file, buf, size, offset, iocb); - else { - if (!iocb) { - count = generic_file_read(file, buf, size, offset); - } else { - struct iovec local_iov = { - .iov_base = (char __user *)buf, - .iov_len = size - }; - - count = __generic_file_aio_read(iocb, - &local_iov, 1, offset); - if (count == -EIOCBQUEUED) - count = wait_on_sync_kiocb(iocb); - } - } - - gfs_glock_dq_m(num_gh + 1, ghs); - - out: - gfs_holder_uninit(&ghs[num_gh]); - - return (count) ? count : error; -} - -static ssize_t -__gfs_read(struct file *file, char *buf, size_t size, loff_t *offset, struct kiocb *iocb) -{ - atomic_inc(&vfs2sdp(file->f_mapping->host->i_sb)->sd_ops_file); - - if (file->f_flags & O_DIRECT) - return walk_vm(file, buf, size, offset, iocb, do_read_direct); - else - return walk_vm(file, buf, size, offset, iocb, do_read_buf); -} - -/** - * gfs_read - Read bytes from a file - * @file: The file to read from - * @buf: The buffer to copy into - * @size: The amount of data requested - * @offset: The current file offset - * - * Outputs: Offset - updated according to number of bytes read - * - * Returns: The number of bytes read, errno on failure - */ - -static ssize_t -gfs_read(struct file *file, char *buf, size_t size, loff_t *offset) -{ - return(__gfs_read(file, buf, size, offset, NULL)); -} - -/* - * generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) - */ -static ssize_t -gfs_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) -{ - struct file *filp = iocb->ki_filp; - - BUG_ON(iocb->ki_pos != pos); - return(__gfs_read(filp, buf, count, &iocb->ki_pos, iocb)); -} - -/** - * do_write_direct_alloc - Write bytes to a file - * @file: The file to write to - * @buf: The buffer to copy from - * @size: The amount of data requested - * @offset: The current file offset - * - * Outputs: Offset - updated according to number of bytes written - * - * Returns: The number of bytes written, errno on failure - */ - -static ssize_t -do_write_direct_alloc(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb) -{ - struct inode *inode = file->f_mapping->host; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = NULL; - struct iovec local_iov = { .iov_base = buf, .iov_len = size }; - struct buffer_head *dibh; - unsigned int data_blocks, ind_blocks; - ssize_t count; - int error; - - gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks); - - al = gfs_alloc_get(ip); - - error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto fail; - - error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); - if (error) - goto fail_gunlock_q; - - al->al_requested_meta = ind_blocks; - al->al_requested_data = data_blocks; - - error = gfs_inplace_reserve(ip); - if (error) - goto fail_gunlock_q; - - /* Trans may require: - All blocks for a RG bitmap, whatever indirect blocks we - need, a modified dinode, and a quota change. */ - - error = gfs_trans_begin(sdp, - 1 + al->al_rgd->rd_ri.ri_length + ind_blocks, - 1); - if (error) - goto fail_ipres; - - if ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID)) { - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail_end_trans; - - ip->i_di.di_mode &= (ip->i_di.di_mode & S_IXGRP) ? (~(S_ISUID | S_ISGID)) : (~S_ISUID); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - if (gfs_is_stuffed(ip)) { - error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); - if (error) - goto fail_end_trans; - } - - if (!iocb) - count = generic_file_write_nolock(file, &local_iov, 1, offset); - else - count = generic_file_aio_write_nolock(iocb, &local_iov, 1, offset); - - if (count < 0) { - error = count; - goto fail_end_trans; - } - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail_end_trans; - - if (ip->i_di.di_size < inode->i_size) - ip->i_di.di_size = inode->i_size; - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - gfs_trans_end(sdp); - - /* Question (wcheng) - * 1. should IS_SYNC flush glock ? - * 2. does gfs_log_flush_glock flush data ? - */ - if (file->f_flags & O_SYNC) - gfs_log_flush_glock(ip->i_gl, 0); - - gfs_inplace_release(ip); - gfs_quota_unlock_m(ip); - gfs_alloc_put(ip); - - if (file->f_mapping->nrpages) { - error = filemap_fdatawrite(file->f_mapping); - if (!error) - error = filemap_fdatawait(file->f_mapping); - } - if (error) - return error; - - return count; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_ipres: - gfs_inplace_release(ip); - - fail_gunlock_q: - gfs_quota_unlock_m(ip); - - fail: - gfs_alloc_put(ip); - - return error; -} - -/** - * do_write_direct - Write bytes to a file - * @file: The file to write to - * @buf: The buffer to copy from - * @size: The amount of data requested - * @offset: The current file offset - * @num_gh: The number of other locks we need to do the read - * @gh: the locks we need plus one for our lock - * - * Outputs: Offset - updated according to number of bytes written - * - * Returns: The number of bytes written, errno on failure - */ - -static ssize_t -do_write_direct(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb, - unsigned int num_gh, struct gfs_holder *ghs) -{ - struct inode *inode = file->f_mapping->host; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_file *fp = vf2fp(file); - unsigned int state = LM_ST_DEFERRED; - int alloc_required; - unsigned int x; - size_t s; - ssize_t count = 0; - int error; - - if (test_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags)) - state = LM_ST_EXCLUSIVE; - else - for (x = 0; x < num_gh; x++) - if (ghs[x].gh_gl == ip->i_gl) { - state = LM_ST_EXCLUSIVE; - break; - } - - down_write(&inode->i_alloc_sem); - - restart: - - gfs_holder_init(ip->i_gl, state, 0, &ghs[num_gh]); - - if (num_gh && atomic_read(¤t->mm->mm_users) > 1) { - error = grope_mapping(buf, size); - if (error) - goto out; - } - - error = gfs_glock_nq_m(num_gh + 1, ghs); - if (error) - goto out; - - error = -EINVAL; - if (gfs_is_jdata(ip)) - goto out_gunlock; - - if (num_gh) { - error = grope_mapping(buf, size); - if (error) - goto out_gunlock; - } - - if (file->f_flags & O_APPEND) - *offset = ip->i_di.di_size; - - if (!(file->f_flags & O_LARGEFILE)) { - error = -EFBIG; - if (*offset >= 0x7FFFFFFFull) - goto out_gunlock; - if (*offset + size > 0x7FFFFFFFull) - size = 0x7FFFFFFFull - *offset; - } - - if (gfs_is_stuffed(ip) || - *offset + size > ip->i_di.di_size || - ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID))) - alloc_required = TRUE; - else { - error = gfs_write_alloc_required(ip, *offset, size, - &alloc_required); - if (error) - goto out_gunlock; - } - - if (alloc_required && state != LM_ST_EXCLUSIVE) { - gfs_glock_dq_m(num_gh + 1, ghs); - gfs_holder_uninit(&ghs[num_gh]); - state = LM_ST_EXCLUSIVE; - goto restart; - } - - if (alloc_required) { - set_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags); - - /* for asynchronous IO, the buffer can not be splitted */ - if (iocb) { - count = do_write_direct_alloc(file, buf, size, offset, iocb); - goto out_iocb_write; - } - - /* split large writes into smaller atomic transactions */ - while (size) { - s = gfs_tune_get(sdp, gt_max_atomic_write); - if (s > size) - s = size; - - error = do_write_direct_alloc(file, buf, s, offset, iocb); - if (error < 0) - goto out_gunlock; - - buf += error; - size -= error; - count += error; - } - } else { - struct iovec local_iov = { .iov_base = buf, .iov_len = size }; - struct gfs_holder t_gh; - - clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags); - - error = gfs_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); - if (error) - goto out_gunlock; - - /* Todo: It would be nice if init_sync_kiocb is exported. - * .. wcheng - */ - if (!iocb) - count = - generic_file_write_nolock(file, &local_iov, 1, offset); - else { - count = - generic_file_aio_write_nolock(iocb, &local_iov, 1, offset); - } - gfs_glock_dq_uninit(&t_gh); - } - - out_iocb_write: - error = 0; - - out_gunlock: - gfs_glock_dq_m(num_gh + 1, ghs); - - out: - up_write(&inode->i_alloc_sem); - gfs_holder_uninit(&ghs[num_gh]); - - return (count) ? count : error; -} - -/** - * do_do_write_buf - Write bytes to a file - * @file: The file to write to - * @buf: The buffer to copy from - * @size: The amount of data requested - * @offset: The current file offset - * - * Outputs: Offset - updated according to number of bytes written - * - * Returns: The number of bytes written, errno on failure - */ - -static ssize_t -do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset, - struct kiocb *iocb) -{ - struct inode *inode = file->f_mapping->host; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = NULL; - struct buffer_head *dibh; - unsigned int data_blocks, ind_blocks; - int alloc_required, journaled; - ssize_t count; - int error; - unsigned int posix = sdp->sd_args.ar_posix_acls ? 4 : 0; - - journaled = gfs_is_jdata(ip); - - gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks); - - error = gfs_write_alloc_required(ip, *offset, size, &alloc_required); - if (error) - return error; - - if (alloc_required) { - al = gfs_alloc_get(ip); - - error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto fail; - - error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); - if (error) - goto fail_gunlock_q; - - if (journaled) - al->al_requested_meta = ind_blocks + data_blocks; - else { - al->al_requested_meta = ind_blocks; - al->al_requested_data = data_blocks; - } - - error = gfs_inplace_reserve(ip); - if (error) - goto fail_gunlock_q; - - /* Trans may require: - All blocks for a RG bitmap, whatever indirect blocks we - need, a modified dinode, and a quota change. */ - - error = gfs_trans_begin(sdp, - 1 + al->al_rgd->rd_ri.ri_length + - ind_blocks + posix + - ((journaled) ? data_blocks : 0), 1); - if (error) - goto fail_ipres; - } else { - /* Trans may require: - A modified dinode. */ - - error = gfs_trans_begin(sdp, posix + - 1 + ((journaled) ? data_blocks : 0), 0); - if (error) - goto fail_ipres; - } - - if ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID)) { - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail_end_trans; - - ip->i_di.di_mode &= (ip->i_di.di_mode & S_IXGRP) ? (~(S_ISUID | S_ISGID)) : (~S_ISUID); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - if (journaled || - (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags) && - *offset + size <= sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode))) { - - count = gfs_writei(ip, buf, *offset, size, gfs_copy_from_user, iocb); - if (count < 0) { - error = count; - goto fail_end_trans; - } - if (gfs_is_stuffed(ip)){ - struct page *page; - page = find_get_page(file->f_mapping, 0); - if (page) { - ClearPageUptodate(page); - page_cache_release(page); - } - } - *offset += count; - } else { - struct iovec local_iov = { .iov_base = buf, .iov_len = size }; - - if (!iocb) { - count = generic_file_write_nolock(file, &local_iov, 1, offset); - } else { - count = generic_file_aio_write_nolock(iocb, - &local_iov, 1, offset); - if (count == -EIOCBQUEUED) - count = wait_on_sync_kiocb(iocb); - } - if (count < 0) { - error = count; - goto fail_end_trans; - } - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail_end_trans; - - if (ip->i_di.di_size < inode->i_size) - ip->i_di.di_size = inode->i_size; - ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - gfs_trans_end(sdp); - - if (file->f_flags & O_SYNC || IS_SYNC(inode)) { - gfs_log_flush_glock(ip->i_gl, 0); - error = filemap_fdatawrite(file->f_mapping); - if (error == 0) - error = filemap_fdatawait(file->f_mapping); - if (error) - goto fail_ipres; - } - - if (alloc_required) { - gfs_assert_warn(sdp, count != size || - al->al_alloced_meta || - al->al_alloced_data); - gfs_inplace_release(ip); - gfs_quota_unlock_m(ip); - gfs_alloc_put(ip); - } - - return count; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_ipres: - if (alloc_required) - gfs_inplace_release(ip); - - fail_gunlock_q: - if (alloc_required) - gfs_quota_unlock_m(ip); - - fail: - if (alloc_required) - gfs_alloc_put(ip); - - return error; -} - -/** - * do_write_buf - Write bytes to a file - * @file: The file to write to - * @buf: The buffer to copy from - * @size: The amount of data requested - * @offset: The current file offset - * @num_gh: The number of other locks we need to do the read - * @gh: the locks we need plus one for our lock - * - * Outputs: Offset - updated according to number of bytes written - * - * Returns: The number of bytes written, errno on failure - */ - -static ssize_t -do_write_buf(struct file *file, - char *buf, size_t size, loff_t *offset, - struct kiocb *iocb, - unsigned int num_gh, struct gfs_holder *ghs) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - struct gfs_sbd *sdp = ip->i_sbd; - size_t s; - ssize_t count = 0; - int error; - struct inode *inode = file->f_mapping->host; - - gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh]); - - if (num_gh && atomic_read(¤t->mm->mm_users) > 1) { - error = grope_mapping(buf, size); - if (error) - goto out; - } - - error = gfs_glock_nq_m(num_gh + 1, ghs); - if (error) - goto out; - - if (num_gh) { - error = grope_mapping(buf, size); - if (error) - goto out_gunlock; - } - - if (file->f_flags & O_APPEND) - *offset = ip->i_di.di_size; - - if (!(file->f_flags & O_LARGEFILE)) { - error = -EFBIG; - if (*offset >= 0x7FFFFFFFull) - goto out_gunlock; - if (*offset + size > 0x7FFFFFFFull) - size = 0x7FFFFFFFull - *offset; - } - - /* split large writes into smaller atomic transactions */ - while (size) { - s = gfs_tune_get(sdp, gt_max_atomic_write); - if (s > size) - s = size; - - error = do_do_write_buf(file, buf, s, offset, iocb); - if (error < 0) - goto out_gunlock; - - buf += error; - size -= error; - count += error; - } - - error = 0; - if (inode->i_size < ip->i_di.di_size) { - i_size_write(inode, ip->i_di.di_size); - mark_inode_dirty(inode); - } - - out_gunlock: - gfs_glock_dq_m(num_gh + 1, ghs); - - out: - gfs_holder_uninit(&ghs[num_gh]); - - return (count) ? count : error; -} - -/** - * gfs_write - Write bytes to a file - * @file: The file to write to - * @buf: The buffer to copy from - * @size: The amount of data requested - * @offset: The current file offset - * - * Outputs: Offset - updated according to number of bytes written - * - * Returns: The number of bytes written, errno on failure - */ - -static ssize_t -__gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset, struct kiocb *iocb) -{ - struct inode *inode = file->f_mapping->host; - ssize_t count; - - atomic_inc(&vfs2sdp(inode->i_sb)->sd_ops_file); - - if (*offset < 0) - return -EINVAL; - if (!access_ok(VERIFY_READ, buf, size)) - return -EFAULT; - - down(&inode->i_sem); - if (file->f_flags & O_DIRECT) - count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_direct); - else - count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_buf); - up(&inode->i_sem); - - return count; -} - -static ssize_t -gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset) -{ - return(__gfs_write(file, buf, size, offset, NULL)); -} - -static ssize_t -gfs_aio_write(struct kiocb *iocb, const char __user *buf, size_t size, loff_t pos) -{ - struct file *file = iocb->ki_filp; - - BUG_ON(iocb->ki_pos != pos); - - /* things to check: - * const char __user *buf (aio) and const char *buf (sio) - */ - return(__gfs_write(file, buf, size, &iocb->ki_pos, iocb)); -} -/** - * filldir_reg_func - Report a directory entry to the caller of gfs_dir_read() - * @opaque: opaque data used by the function - * @name: the name of the directory entry - * @length: the length of the name - * @offset: the entry's offset in the directory - * @inum: the inode number the entry points to - * @type: the type of inode the entry points to - * - * Returns: 0 on success, 1 if buffer full - */ - -static int -filldir_reg_func(void *opaque, - const char *name, unsigned int length, - uint64_t offset, - struct gfs_inum *inum, unsigned int type) -{ - struct filldir_reg *fdr = (struct filldir_reg *)opaque; - struct gfs_sbd *sdp = fdr->fdr_sbd; - unsigned int vfs_type; - int error; - - switch (type) { - case GFS_FILE_NON: - vfs_type = DT_UNKNOWN; - break; - case GFS_FILE_REG: - vfs_type = DT_REG; - break; - case GFS_FILE_DIR: - vfs_type = DT_DIR; - break; - case GFS_FILE_LNK: - vfs_type = DT_LNK; - break; - case GFS_FILE_BLK: - vfs_type = DT_BLK; - break; - case GFS_FILE_CHR: - vfs_type = DT_CHR; - break; - case GFS_FILE_FIFO: - vfs_type = DT_FIFO; - break; - case GFS_FILE_SOCK: - vfs_type = DT_SOCK; - break; - default: - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: type = %u\n", - sdp->sd_fsname, type); - return -EIO; - } - - error = fdr->fdr_filldir(fdr->fdr_opaque, name, length, offset, - inum->no_formal_ino, vfs_type); - if (error) - return 1; - - /* Prefetch locks */ - if (fdr->fdr_prefetch && !(length == 1 && *name == '.')) { - gfs_glock_prefetch_num(sdp, - inum->no_formal_ino, &gfs_inode_glops, - LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY); - gfs_glock_prefetch_num(sdp, - inum->no_addr, &gfs_iopen_glops, - LM_ST_SHARED, LM_FLAG_TRY); - } - - return 0; -} - -static inline int -high_stat_rate(struct gfs_inode *ip) -{ - struct timeval now, diff; - unsigned long milli = 0; - unsigned int rate = 0; /* stats per second in this dir */ - - do_gettimeofday(&now); - diff.tv_sec = now.tv_sec - ip->i_dir_stat_st.tv_sec; - diff.tv_usec = now.tv_usec - ip->i_dir_stat_st.tv_usec; - if (diff.tv_usec < 0) { - diff.tv_usec += 1000000; - diff.tv_sec--; - } - milli = (diff.tv_sec * 1000) + (diff.tv_usec / 1000); - if (milli) - rate = (ip->i_dir_stats * 1000) / milli; - - if (rate > 10) /* More than 10 stats/sec */ - return 1; - return 0; -} - -/** - * readdir_reg - Read directory entries from a directory - * @file: The directory to read from - * @dirent: Buffer for dirents - * @filldir: Function used to do the copying - * - * Returns: errno - */ - -static int -readdir_reg(struct file *file, void *dirent, filldir_t filldir) -{ - struct gfs_inode *dip = vn2ip(file->f_mapping->host); - struct filldir_reg fdr; - struct gfs_holder d_gh; - uint64_t offset = file->f_pos; - int error; - - fdr.fdr_sbd = dip->i_sbd; - fdr.fdr_prefetch = high_stat_rate(dip) ? TRUE : FALSE; - fdr.fdr_filldir = filldir; - fdr.fdr_opaque = dirent; - - /* reset stat counter and timestamp */ - dip->i_dir_stats = 0; - do_gettimeofday(&dip->i_dir_stat_st); - - gfs_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); - error = gfs_glock_nq_atime(&d_gh); - if (error) { - gfs_holder_uninit(&d_gh); - return error; - } - - error = gfs_dir_read(dip, &offset, &fdr, filldir_reg_func); - - gfs_glock_dq_uninit(&d_gh); - - file->f_pos = offset; - - return error; -} - -/** - * filldir_bad_func - Report a directory entry to the caller of gfs_dir_read() - * @opaque: opaque data used by the function - * @name: the name of the directory entry - * @length: the length of the name - * @offset: the entry's offset in the directory - * @inum: the inode number the entry points to - * @type: the type of inode the entry points to - * - * For supporting NFS. - * - * Returns: 0 on success, 1 if buffer full - */ - -static int -filldir_bad_func(void *opaque, - const char *name, unsigned int length, - uint64_t offset, - struct gfs_inum *inum, unsigned int type) -{ - struct filldir_bad *fdb = (struct filldir_bad *)opaque; - struct gfs_sbd *sdp = fdb->fdb_sbd; - struct filldir_bad_entry *fbe; - - if (fdb->fdb_entry_off == fdb->fdb_entry_num || - fdb->fdb_name_off + length > fdb->fdb_name_size) - return 1; - - fbe = &fdb->fdb_entry[fdb->fdb_entry_off]; - fbe->fbe_name = fdb->fdb_name + fdb->fdb_name_off; - memcpy(fbe->fbe_name, name, length); - fbe->fbe_length = length; - fbe->fbe_offset = offset; - fbe->fbe_inum = *inum; - fbe->fbe_type = type; - - fdb->fdb_entry_off++; - fdb->fdb_name_off += length; - - /* Prefetch locks */ - if (!(length == 1 && *name == '.')) { - gfs_glock_prefetch_num(sdp, - inum->no_formal_ino, &gfs_inode_glops, - LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY); - gfs_glock_prefetch_num(sdp, - inum->no_addr, &gfs_iopen_glops, - LM_ST_SHARED, LM_FLAG_TRY); - } - - return 0; -} - -/** - * readdir_bad - Read directory entries from a directory - * @file: The directory to read from - * @dirent: Buffer for dirents - * @filldir: Function used to do the copying - * - * For supporting NFS. - * - * Returns: errno - */ - -static int -readdir_bad(struct file *file, void *dirent, filldir_t filldir) -{ - struct gfs_inode *dip = vn2ip(file->f_mapping->host); - struct gfs_sbd *sdp = dip->i_sbd; - struct filldir_reg fdr; - unsigned int entries, size; - struct filldir_bad *fdb; - struct gfs_holder d_gh; - uint64_t offset = file->f_pos; - unsigned int x; - struct filldir_bad_entry *fbe; - int error; - - entries = gfs_tune_get(sdp, gt_entries_per_readdir); - size = sizeof(struct filldir_bad) + - entries * (sizeof(struct filldir_bad_entry) + GFS_FAST_NAME_SIZE); - - fdb = kmalloc(size, GFP_KERNEL); - if (!fdb) - return -ENOMEM; - memset(fdb, 0, size); - - fdb->fdb_sbd = sdp; - fdb->fdb_entry = (struct filldir_bad_entry *)(fdb + 1); - fdb->fdb_entry_num = entries; - fdb->fdb_name = ((char *)fdb) + sizeof(struct filldir_bad) + - entries * sizeof(struct filldir_bad_entry); - fdb->fdb_name_size = entries * GFS_FAST_NAME_SIZE; - - gfs_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); - error = gfs_glock_nq_atime(&d_gh); - if (error) { - gfs_holder_uninit(&d_gh); - goto out; - } - - error = gfs_dir_read(dip, &offset, fdb, filldir_bad_func); - - gfs_glock_dq_uninit(&d_gh); - - fdr.fdr_sbd = sdp; - fdr.fdr_prefetch = FALSE; - fdr.fdr_filldir = filldir; - fdr.fdr_opaque = dirent; - - for (x = 0; x < fdb->fdb_entry_off; x++) { - fbe = &fdb->fdb_entry[x]; - - error = filldir_reg_func(&fdr, - fbe->fbe_name, fbe->fbe_length, - fbe->fbe_offset, - &fbe->fbe_inum, fbe->fbe_type); - if (error) { - file->f_pos = fbe->fbe_offset; - error = 0; - goto out; - } - } - - file->f_pos = offset; - - out: - kfree(fdb); - - return error; -} - -/** - * gfs_readdir - Read directory entries from a directory - * @file: The directory to read from - * @dirent: Buffer for dirents - * @filldir: Function used to do the copying - * - * Returns: errno - */ - -static int -gfs_readdir(struct file *file, void *dirent, filldir_t filldir) -{ - int error; - - atomic_inc(&vfs2sdp(file->f_mapping->host->i_sb)->sd_ops_file); - - /* Use "bad" one if we're called from NFS daemon */ - if (strcmp(current->comm, "nfsd") != 0) - error = readdir_reg(file, dirent, filldir); - else - error = readdir_bad(file, dirent, filldir); - - return error; -} - -/** - * gfs_ioctl - do an ioctl on a file - * @inode: the inode - * @file: the file pointer - * @cmd: the ioctl command - * @arg: the argument - * - * Returns: errno - */ - -static int -gfs_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct gfs_inode *ip = vn2ip(inode); - - atomic_inc(&ip->i_sbd->sd_ops_file); - - switch (cmd) { - case GFS_IOCTL_IDENTIFY: { - unsigned int x = GFS_MAGIC; - if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned int))) - return -EFAULT; - return 0; - } - - case GFS_IOCTL_SUPER: - return gfs_ioctl_i(ip, (void *)arg); - - default: - return -ENOTTY; - } -} - -/** - * gfs_mmap - We don't support shared writable mappings right now - * @file: The file to map - * @vma: The VMA which described the mapping - * - * Returns: 0 or error code - */ - -static int -gfs_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - struct gfs_holder i_gh; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_file); - - gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); - error = gfs_glock_nq_atime(&i_gh); - if (error) { - gfs_holder_uninit(&i_gh); - return error; - } - - if (gfs_is_jdata(ip)) { - if (vma->vm_flags & VM_MAYSHARE) - error = -ENOSYS; - else - vma->vm_ops = &gfs_vm_ops_private; - } else { - /* This is VM_MAYWRITE instead of VM_WRITE because a call - to mprotect() can turn on VM_WRITE later. */ - - if ((vma->vm_flags & (VM_MAYSHARE | VM_MAYWRITE)) == (VM_MAYSHARE | VM_MAYWRITE)) - vma->vm_ops = &gfs_vm_ops_sharewrite; - else - vma->vm_ops = &gfs_vm_ops_private; - } - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_open - open a file - * @inode: the inode to open - * @file: the struct file for this opening - * - * Returns: errno - */ - -static int -gfs_open(struct inode *inode, struct file *file) -{ - struct gfs_inode *ip = vn2ip(inode); - struct gfs_holder i_gh; - struct gfs_file *fp; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_file); - - fp = kmalloc(sizeof(struct gfs_file), GFP_KERNEL); - if (!fp) - return -ENOMEM; - memset(fp, 0, sizeof(struct gfs_file)); - - init_MUTEX(&fp->f_fl_lock); - - fp->f_inode = ip; - fp->f_vfile = file; - - gfs_assert_warn(ip->i_sbd, !vf2fp(file)); - vf2fp(file) = fp; - - if (ip->i_di.di_type == GFS_FILE_REG) { - error = gfs_glock_nq_init(ip->i_gl, - LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); - if (error) - goto fail; - - if (!(file->f_flags & O_LARGEFILE) && - ip->i_di.di_size > 0x7FFFFFFFull) { - error = -EFBIG; - goto fail_gunlock; - } - - /* Listen to the Direct I/O flag */ - - if (ip->i_di.di_flags & GFS_DIF_DIRECTIO) - file->f_flags |= O_DIRECT; - - /* Don't let the user open O_DIRECT on a jdata file */ - - if ((file->f_flags & O_DIRECT) && gfs_is_jdata(ip)) { - error = -EINVAL; - goto fail_gunlock; - } - - gfs_glock_dq_uninit(&i_gh); - } - - return 0; - - fail_gunlock: - gfs_glock_dq_uninit(&i_gh); - - fail: - vf2fp(file) = NULL; - kfree(fp); - - return error; -} - -/** - * gfs_close - called to close a struct file - * @inode: the inode the struct file belongs to - * @file: the struct file being closed - * - * Returns: errno - */ - -static int -gfs_close(struct inode *inode, struct file *file) -{ - struct gfs_sbd *sdp = vfs2sdp(inode->i_sb); - struct gfs_file *fp; - - atomic_inc(&sdp->sd_ops_file); - - fp = vf2fp(file); - vf2fp(file) = NULL; - - if (!gfs_assert_warn(sdp, fp)) - kfree(fp); - - return 0; -} - -/** - * gfs_fsync - sync the dirty data for a file (across the cluster) - * @file: the file that points to the dentry (we ignore this) - * @dentry: the dentry that points to the inode to sync - * - * Returns: errno - * - * Obtain an EXCLUSIVE lock on the file, to force other node to sync file's - * dirty data to disk, as it releases the EXCLUSIVE lock. - */ - -static int -gfs_fsync(struct file *file, struct dentry *dentry, int datasync) -{ - struct gfs_inode *ip = vn2ip(dentry->d_inode); - struct gfs_holder i_gh; - struct inode *inode = dentry->d_inode; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_file); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return error; - - if (gfs_is_jdata(ip)) - gfs_log_flush_glock(ip->i_gl, 0); - else { - if ((!datasync) || (inode->i_state & I_DIRTY_DATASYNC)) { - struct writeback_control wbc = { - .sync_mode = WB_SYNC_ALL, - .nr_to_write = 0, - }; - error = sync_inode(inode, &wbc); - } - } - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_lock - acquire/release a posix lock on a file - * @file: the file pointer - * @cmd: either modify or retrieve lock state, possibly wait - * @fl: type and range of lock - * - * Returns: errno - */ - -static int -gfs_lock(struct file *file, int cmd, struct file_lock *fl) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - struct gfs_sbd *sdp = ip->i_sbd; - struct lm_lockname name = - { .ln_number = ip->i_num.no_formal_ino, - .ln_type = LM_TYPE_PLOCK }; - - atomic_inc(&sdp->sd_ops_file); - - if (!(fl->fl_flags & FL_POSIX)) - return -ENOLCK; - if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID && - fl->fl_type != F_UNLCK) - return -ENOLCK; - - if (sdp->sd_args.ar_localflocks) { - if (IS_GETLK(cmd)) - return LOCK_USE_CLNT; - return posix_lock_file_wait(file, fl); - } - - if (IS_GETLK(cmd)) - return gfs_lm_plock_get(sdp, &name, file, fl); - else if (fl->fl_type == F_UNLCK) - return gfs_lm_punlock(sdp, &name, file, fl); - else - return gfs_lm_plock(sdp, &name, file, cmd, fl); -} - -/** - * gfs_sendfile - Send bytes to a file or socket - * @in_file: The file to read from - * @out_file: The file to write to - * @count: The amount of data - * @offset: The beginning file offset - * - * Outputs: offset - updated according to number of bytes read - * - * Returns: The number of bytes sent, errno on failure - */ - -static ssize_t -gfs_sendfile(struct file *in_file, loff_t *offset, size_t count, read_actor_t actor, void __user *target) -{ - struct gfs_inode *ip = vn2ip(in_file->f_mapping->host); - struct gfs_holder gh; - ssize_t retval; - - atomic_inc(&ip->i_sbd->sd_ops_file); - - gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); - - retval = gfs_glock_nq_atime(&gh); - if (retval) - goto out; - - if (gfs_is_jdata(ip)) - retval = -ENOSYS; - else - retval = generic_file_sendfile(in_file, offset, count, actor, target); - - gfs_glock_dq(&gh); - - out: - gfs_holder_uninit(&gh); - - return retval; -} - -/** - * do_flock - Acquire a flock on a file - * @file: - * @cmd: - * @fl: - * - * Returns: errno - */ - -static int -do_flock(struct file *file, int cmd, struct file_lock *fl) -{ - struct gfs_file *fp = vf2fp(file); - struct gfs_holder *fl_gh = &fp->f_fl_gh; - struct gfs_inode *ip = fp->f_inode; - struct gfs_glock *gl; - unsigned int state; - int flags; - int error = 0; - - state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; - flags = ((IS_SETLKW(cmd)) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE; - - down(&fp->f_fl_lock); - - gl = fl_gh->gh_gl; - if (gl) { - if (fl_gh->gh_state == state) - goto out; - gfs_glock_hold(gl); - flock_lock_file_wait(file, - &(struct file_lock){.fl_type = F_UNLCK}); - gfs_glock_dq_uninit(fl_gh); - } else { - error = gfs_glock_get(ip->i_sbd, - ip->i_num.no_formal_ino, &gfs_flock_glops, - CREATE, &gl); - if (error) - goto out; - } - - gfs_holder_init(gl, state, flags, fl_gh); - gfs_glock_put(gl); - - error = gfs_glock_nq(fl_gh); - if (error) { - gfs_holder_uninit(fl_gh); - if (error == GLR_TRYFAILED) - error = -EAGAIN; - } else { - error = flock_lock_file_wait(file, fl); - gfs_assert_warn(ip->i_sbd, !error); - } - - out: - up(&fp->f_fl_lock); - - return error; -} - -/** - * do_unflock - Release a flock on a file - * @file: the file - * @fl: - * - */ - -static void -do_unflock(struct file *file, struct file_lock *fl) -{ - struct gfs_file *fp = vf2fp(file); - struct gfs_holder *fl_gh = &fp->f_fl_gh; - - down(&fp->f_fl_lock); - flock_lock_file_wait(file, fl); - if (fl_gh->gh_gl) - gfs_glock_dq_uninit(fl_gh); - up(&fp->f_fl_lock); -} - -/** - * gfs_flock - acquire/release a flock lock on a file - * @file: the file pointer - * @cmd: either modify or retrieve lock state, possibly wait - * @fl: type and range of lock - * - * Returns: errno - */ - -static int -gfs_flock(struct file *file, int cmd, struct file_lock *fl) -{ - struct gfs_inode *ip = vn2ip(file->f_mapping->host); - struct gfs_sbd *sdp = ip->i_sbd; - - atomic_inc(&ip->i_sbd->sd_ops_file); - - if (!(fl->fl_flags & FL_FLOCK)) - return -ENOLCK; - if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) - return -ENOLCK; - - if (sdp->sd_args.ar_localflocks) - return flock_lock_file_wait(file, fl); - - if (fl->fl_type == F_UNLCK) { - do_unflock(file, fl); - return 0; - } else - return do_flock(file, cmd, fl); -} - -/* - * VFS layer offers a "bd_inode_backing_dev_info" pointer to allow - * filesystem overriding its block device generic readahead value. - * We'll take this advantage to tune for large sequential write. - */ -struct backing_dev_info gfs_file_backing_dev_info = { - .ra_pages = 0, /* place holder */ - .memory_backed = 0, /* place holder */ - .unplug_io_fn = default_unplug_io_fn, -}; - -int gfs_reset_readahead(struct gfs_sbd *sdp, unsigned int file_ra) -{ - unsigned int max_ra; - struct backing_dev_info *bdi; - struct super_block *vfs_sb=sdp->sd_vfs; - - /* user wants to reset back to default */ - if (file_ra == 0) { - vfs_sb->s_bdev->bd_inode_backing_dev_info = NULL; - return 0; - } - - /* can't exceed gfs max readahead */ - max_ra = gfs_tune_get(sdp, gt_max_readahead); - if (file_ra > max_ra) { - printk("GFS: einval - readahead exceeds max\n"); - return -EINVAL; - } - - bdi = sdp->sd_vfs->s_bdev->bd_inode_backing_dev_info; - - /* sanity check */ - if (gfs_tune_get(sdp, gt_seq_readahead) && !bdi) { - printk("GFS: error - gt_seq_readahead set but bdi is NULL\n"); - return -EIO; - } - - /* add pointer */ - if (!bdi) { - bdi = &sdp->sd_dev_info; - vfs_sb->s_bdev->bd_inode_backing_dev_info = bdi; - *bdi = *(vfs_sb->s_bdev->bd_inode->i_data.backing_dev_info); - } - - /* now change the setting */ - bdi->ra_pages = file_ra; - - return 0; -} - -struct file_operations gfs_file_fops = { - .llseek = gfs_llseek, - .read = gfs_read, - .write = gfs_write, - .aio_read = gfs_aio_read, - .aio_write = gfs_aio_write, - .ioctl = gfs_ioctl, - .mmap = gfs_mmap, - .open = gfs_open, - .release = gfs_close, - .fsync = gfs_fsync, - .lock = gfs_lock, - .sendfile = gfs_sendfile, - .flock = gfs_flock, -}; - -struct file_operations gfs_dir_fops = { - .readdir = gfs_readdir, - .ioctl = gfs_ioctl, - .open = gfs_open, - .release = gfs_close, - .fsync = gfs_fsync, - .lock = gfs_lock, - .flock = gfs_flock, -}; diff --git a/gfs-kernel/src/gfs/ops_file.h b/gfs-kernel/src/gfs/ops_file.h deleted file mode 100644 index c4ed373..0000000 --- a/gfs-kernel/src/gfs/ops_file.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_FILE_DOT_H__ -#define __OPS_FILE_DOT_H__ - -extern struct file_operations gfs_file_fops; -extern struct file_operations gfs_dir_fops; - -#endif /* __OPS_FILE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_fstype.c b/gfs-kernel/src/gfs/ops_fstype.c deleted file mode 100644 index de23cbd..0000000 --- a/gfs-kernel/src/gfs/ops_fstype.c +++ /dev/null @@ -1,786 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/vmalloc.h> -#include <linux/blkdev.h> - -#include "gfs.h" -#include "daemon.h" -#include "diaper.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "lm.h" -#include "mount.h" -#include "ops_export.h" -#include "ops_fstype.h" -#include "ops_super.h" -#include "proc.h" -#include "quota.h" -#include "recovery.h" -#include "rgrp.h" -#include "super.h" -#include "unlinked.h" - -/** - * gfs_read_super - Read in superblock - * @sb: The VFS superblock - * @data: Mount options - * @silent: Don't complain if it's not a GFS filesystem - * - * Returns: errno - * - * After cross-linking Linux VFS incore superblock and our GFS incore superblock - * (filesystem instance structures) to one another, we: - * -- Init some of our GFS incore superblock, including some temporary - * block-size values (enough to read on-disk superblock). - * -- Set up some things in Linux VFS superblock. - * -- Mount a lock module, init glock system (incl. glock reclaim daemons), - * and init some important inter-node locks (MOUNT, LIVE, SuperBlock). - * -- Read-in the GFS on-disk superblock (1st time, to get enough info - * to do filesystem upgrade and journal replay, incl. journal index). - * -- Upgrade on-disk filesystem format (rarely needed). - * -- Replay journal(s) (always; replay *all* journals if we're first-to-mount). - * -- Read-in on-disk superblock and journal index special file again (2nd time, - * assumed 100% valid now after journal replay). - * -- Read-in info on other special (hidden) files (root inode, resource index, - * quota inode, license inode). - * -- Start other daemons (journal/log recovery, log tail, quota updates, inode - * reclaim) for periodic maintenance. - * - */ - -static int -fill_super(struct super_block *sb, void *data, int silent) -{ - struct gfs_sbd *sdp; - struct gfs_holder mount_gh, sb_gh, ji_gh; - struct inode *inode; - int super = TRUE, jindex = TRUE; - unsigned int x; - int error; - - sdp = vmalloc(sizeof(struct gfs_sbd)); - if (!sdp) { - printk("GFS: can't alloc struct gfs_sbd\n"); - error = -ENOMEM; - goto fail; - } - - memset(sdp, 0, sizeof(struct gfs_sbd)); - - vfs2sdp(sb) = sdp; - sdp->sd_vfs = sb; - gfs_diaper_register_sbd(sb->s_bdev, sdp); - - /* Init rgrp variables */ - - INIT_LIST_HEAD(&sdp->sd_rglist); - init_MUTEX(&sdp->sd_rindex_lock); - INIT_LIST_HEAD(&sdp->sd_rg_mru_list); - spin_lock_init(&sdp->sd_rg_mru_lock); - INIT_LIST_HEAD(&sdp->sd_rg_recent); - spin_lock_init(&sdp->sd_rg_recent_lock); - spin_lock_init(&sdp->sd_rg_forward_lock); - - spin_lock_init(&sdp->sd_statfs_spin); - - for (x = 0; x < GFS_GL_HASH_SIZE; x++) { - sdp->sd_gl_hash[x].hb_lock = RW_LOCK_UNLOCKED; - INIT_LIST_HEAD(&sdp->sd_gl_hash[x].hb_list); - } - - INIT_LIST_HEAD(&sdp->sd_reclaim_list); - spin_lock_init(&sdp->sd_reclaim_lock); - init_waitqueue_head(&sdp->sd_reclaim_wchan); - - for (x = 0; x < GFS_MHC_HASH_SIZE; x++) - INIT_LIST_HEAD(&sdp->sd_mhc[x]); - INIT_LIST_HEAD(&sdp->sd_mhc_single); - spin_lock_init(&sdp->sd_mhc_lock); - - for (x = 0; x < GFS_DEPEND_HASH_SIZE; x++) - INIT_LIST_HEAD(&sdp->sd_depend[x]); - spin_lock_init(&sdp->sd_depend_lock); - - init_MUTEX(&sdp->sd_freeze_lock); - - init_MUTEX(&sdp->sd_thread_lock); - init_completion(&sdp->sd_thread_completion); - - spin_lock_init(&sdp->sd_log_seg_lock); - INIT_LIST_HEAD(&sdp->sd_log_seg_list); - init_waitqueue_head(&sdp->sd_log_seg_wait); - INIT_LIST_HEAD(&sdp->sd_log_ail); - INIT_LIST_HEAD(&sdp->sd_log_incore); - init_rwsem(&sdp->sd_log_lock); - init_MUTEX(&sdp->sd_log_flush_lock); - INIT_LIST_HEAD(&sdp->sd_unlinked_list); - spin_lock_init(&sdp->sd_unlinked_lock); - INIT_LIST_HEAD(&sdp->sd_quota_list); - spin_lock_init(&sdp->sd_quota_lock); - - INIT_LIST_HEAD(&sdp->sd_dirty_j); - spin_lock_init(&sdp->sd_dirty_j_lock); - - spin_lock_init(&sdp->sd_ail_lock); - INIT_LIST_HEAD(&sdp->sd_recovery_bufs); - - gfs_tune_init(&sdp->sd_tune); - - error = gfs_make_args((char *)data, &sdp->sd_args); - if (error) { - printk("GFS: can't parse mount arguments\n"); - goto fail_vfree; - } - - /* Copy VFS mount flags */ - - if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) - set_bit(SDF_NOATIME, &sdp->sd_flags); - if (sb->s_flags & MS_RDONLY) - set_bit(SDF_ROFS, &sdp->sd_flags); - - /* Set up Linux Virtual (VFS) Super Block */ - - sb->s_magic = GFS_MAGIC; - sb->s_op = &gfs_super_ops; - sb->s_export_op = &gfs_export_ops; - - /* Don't let the VFS update atimes. GFS handles this itself. */ - sb->s_flags |= MS_NOATIME | MS_NODIRATIME; - sb->s_maxbytes = MAX_LFS_FILESIZE; - - /* If we were mounted with -o acl (to support POSIX access control - lists), tell VFS */ - if (sdp->sd_args.ar_posix_acls) - sb->s_flags |= MS_POSIXACL; - - /* Turn off quota stuff if we get the noquota mount option, don't - need to grab the sd_tune lock here since its before anything - touches the sd_tune values */ - if (sdp->sd_args.ar_noquota) { - sdp->sd_tune.gt_quota_enforce = 0; - sdp->sd_tune.gt_quota_account = 0; - } - - /* Set up the buffer cache and fill in some fake block size values - to allow us to read-in the on-disk superblock. */ - - sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS_BASIC_BLOCK); - sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits; - sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS_BASIC_BLOCK_SHIFT; - sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; - - if (sizeof(struct gfs_sb) > sdp->sd_sb.sb_bsize) { - printk("GFS: sizeof(struct gfs_sb) > sdp->sd_sb.sb_bsize\n" - "GFS: %u > %u\n", - (unsigned int)sizeof(struct gfs_sb), sdp->sd_sb.sb_bsize); - error = -EINVAL; - goto fail_vfree; - } - - /* Mount an inter-node lock module, check for local optimizations */ - - error = gfs_lm_mount(sdp, silent); - if (error) - goto fail_vfree; - - if ((sdp->sd_lockstruct.ls_flags & LM_LSFLAG_LOCAL) && - !sdp->sd_args.ar_ignore_local_fs) { - /* Force local [p|f]locks */ - sdp->sd_args.ar_localflocks = TRUE; - - /* Force local read ahead and caching */ - sdp->sd_args.ar_localcaching = TRUE; - - /* Allow the machine to oops */ - sdp->sd_args.ar_oopses_ok = TRUE; - } - - /* Start up the scand thread */ - - error = kernel_thread(gfs_scand, sdp, 0); - if (error < 0) { - printk("GFS: fsid=%s: can't start scand thread: %d\n", - sdp->sd_fsname, error); - goto fail_lockproto; - } - wait_for_completion(&sdp->sd_thread_completion); - - /* Start up the glockd thread */ - - for (sdp->sd_glockd_num = 0; - sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd; - sdp->sd_glockd_num++) { - error = kernel_thread(gfs_glockd, sdp, 0); - if (error < 0) { - printk("GFS: fsid=%s: can't start glockd thread: %d\n", - sdp->sd_fsname, error); - goto fail_glockd; - } - wait_for_completion(&sdp->sd_thread_completion); - } - - /* Only one node may mount at a time */ - error = gfs_glock_nq_num(sdp, - GFS_MOUNT_LOCK, &gfs_nondisk_glops, - LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE, - &mount_gh); - if (error) { - printk("GFS: fsid=%s: can't acquire mount glock: %d\n", - sdp->sd_fsname, error); - goto fail_glockd; - } - - /* Show that cluster is alive */ - error = gfs_glock_nq_num(sdp, - GFS_LIVE_LOCK, &gfs_nondisk_glops, - LM_ST_SHARED, LM_FLAG_NOEXP | GL_EXACT, - &sdp->sd_live_gh); - if (error) { - printk("GFS: fsid=%s: can't acquire live glock: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_mount; - } - - sdp->sd_live_gh.gh_owner = NULL; - - /* Read the SuperBlock from disk, get enough info to enable us - to read-in the journal index and replay all journals. */ - - error = gfs_glock_nq_num(sdp, - GFS_SB_LOCK, &gfs_meta_glops, - (sdp->sd_args.ar_upgrade) ? LM_ST_EXCLUSIVE : LM_ST_SHARED, - 0, &sb_gh); - if (error) { - printk("GFS: fsid=%s: can't acquire superblock glock: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_live; - } - - error = gfs_read_sb(sdp, sb_gh.gh_gl, silent); - if (error) { - printk("GFS: fsid=%s: can't read superblock: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_sb; - } - - /* Set up the buffer cache and SB for real, now that we know block - sizes, version #s, locations of important on-disk inodes, etc. */ - - error = -EINVAL; - if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { - printk("GFS: fsid=%s: FS block size (%u) is too small for device block size (%u)\n", - sdp->sd_fsname, sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); - goto fail_gunlock_sb; - } - if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { - printk("GFS: fsid=%s: FS block size (%u) is too big for machine page size (%u)\n", - sdp->sd_fsname, sdp->sd_sb.sb_bsize, - (unsigned int)PAGE_SIZE); - goto fail_gunlock_sb; - } - - /* Get rid of buffers from the original block size */ - sb_gh.gh_gl->gl_ops->go_inval(sb_gh.gh_gl, DIO_METADATA | DIO_DATA); - sb_gh.gh_gl->gl_aspace->i_blkbits = sdp->sd_sb.sb_bsize_shift; - - sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); - set_blocksize(gfs_diaper_2real(sb->s_bdev), sdp->sd_sb.sb_bsize); - - /* Read-in journal index inode (but not the file contents, yet) */ - - error = gfs_get_jiinode(sdp); - if (error) { - printk("GFS: fsid=%s: can't get journal index inode: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_sb; - } - - init_MUTEX(&sdp->sd_jindex_lock); - - /* Get a handle on the transaction glock; we need this for disk format - upgrade and journal replays, as well as normal operation. */ - - error = gfs_glock_get(sdp, GFS_TRANS_LOCK, &gfs_trans_glops, - CREATE, &sdp->sd_trans_gl); - if (error) - goto fail_ji_free; - set_bit(GLF_STICKY, &sdp->sd_trans_gl->gl_flags); - - /* Upgrade GFS on-disk format version numbers if we need to */ - - if (sdp->sd_args.ar_upgrade) { - error = gfs_do_upgrade(sdp, sb_gh.gh_gl); - if (error) - goto fail_trans_gl; - } - - /* Load in the journal index special file */ - - error = gfs_jindex_hold(sdp, &ji_gh); - if (error) { - printk("GFS: fsid=%s: can't read journal index: %d\n", - sdp->sd_fsname, error); - goto fail_trans_gl; - } - - /* Discover this node's journal number (lock module tells us - which one to use), and lock it */ - error = -EINVAL; - if (sdp->sd_lockstruct.ls_jid >= sdp->sd_journals) { - printk("GFS: fsid=%s: can't mount journal #%u\n", - sdp->sd_fsname, sdp->sd_lockstruct.ls_jid); - printk("GFS: fsid=%s: there are only %u journals (0 - %u)\n", - sdp->sd_fsname, sdp->sd_journals, sdp->sd_journals - 1); - goto fail_gunlock_ji; - } - sdp->sd_jdesc = sdp->sd_jindex[sdp->sd_lockstruct.ls_jid]; - sdp->sd_log_seg_free = sdp->sd_jdesc.ji_nsegment; - sdp->sd_log_seg_ail2 = 0; - - error = gfs_glock_nq_num(sdp, - sdp->sd_jdesc.ji_addr, &gfs_meta_glops, - LM_ST_EXCLUSIVE, LM_FLAG_NOEXP, - &sdp->sd_journal_gh); - if (error) { - printk("GFS: fsid=%s: can't acquire the journal glock: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_ji; - } - - if (sdp->sd_lockstruct.ls_first) { - /* We're first node within cluster to mount this filesystem, - replay ALL of the journals, then let lock module know - that we're done. */ - for (x = 0; x < sdp->sd_journals; x++) { - error = gfs_recover_journal(sdp, - x, sdp->sd_jindex + x, - TRUE); - if (error) { - printk("GFS: fsid=%s: error recovering journal %u: %d\n", - sdp->sd_fsname, x, error); - goto fail_gunlock_journal; - } - } - - gfs_lm_others_may_mount(sdp); - } else { - /* We're not the first; replay only our own journal. */ - error = gfs_recover_journal(sdp, - sdp->sd_lockstruct.ls_jid, - &sdp->sd_jdesc, - TRUE); - if (error) { - printk("GFS: fsid=%s: error recovering my journal: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_journal; - } - } - - gfs_glock_dq_uninit(&ji_gh); - jindex = FALSE; - - /* Disown my Journal glock */ - - sdp->sd_journal_gh.gh_owner = NULL; - - /* Drop our buffer cache and reread all the things we read before - the journal replay, on the unlikely chance that the replay might - have affected (corrected/updated) the superblock contents - or journal index. */ - - error = gfs_read_sb(sdp, sb_gh.gh_gl, FALSE); - if (error) { - printk("GFS: fsid=%s: can't read superblock: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_journal; - } - - gfs_glock_force_drop(sdp->sd_jiinode->i_gl); - - error = gfs_jindex_hold(sdp, &ji_gh); - if (error) { - printk("GFS: fsid=%s: can't read journal index: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_journal; - } - gfs_glock_dq_uninit(&ji_gh); - - /* Make the FS read/write */ - - if (!test_bit(SDF_ROFS, &sdp->sd_flags)) { - error = gfs_make_fs_rw(sdp); - if (error) { - printk("GFS: fsid=%s: can't make FS RW: %d\n", - sdp->sd_fsname, error); - goto fail_gunlock_journal; - } - } - - /* Start up the journal recovery thread */ - - error = kernel_thread(gfs_recoverd, sdp, 0); - if (error < 0) { - printk("GFS: fsid=%s: can't start recoverd thread: %d\n", - sdp->sd_fsname, error); - goto fail_make_ro; - } - wait_for_completion(&sdp->sd_thread_completion); - - /* Read in the resource index inode */ - - error = gfs_get_riinode(sdp); - if (error) { - printk("GFS: fsid=%s: can't get resource index inode: %d\n", - sdp->sd_fsname, error); - goto fail_recoverd; - } - - /* Get the root inode */ - - error = gfs_get_rootinode(sdp); - if (error) { - printk("GFS: fsid=%s: can't read in root inode: %d\n", - sdp->sd_fsname, error); - goto fail_ri_free; - } - - /* Read in the quota inode */ - - error = gfs_get_qinode(sdp); - if (error) { - printk("GFS: fsid=%s: can't get quota file inode: %d\n", - sdp->sd_fsname, error); - goto fail_root_free; - } - - /* Read in the license inode */ - - /* Piggy back fast df on this inode location - * sb->sb_quota_di.no_formal_ino = jindex_dinode + 2; - * sb->sb_quota_di.no_addr = jindex_dinode + 2; - * sb->sb_license_di.no_formal_ino = jindex_dinode + 3; - * sb->sb_license_di.no_addr = jindex_dinode + 3; - */ - - error = gfs_get_linode(sdp); - if (error) { - printk("GFS: fsid=%s: can't get license/statfs file inode: %d\n", - sdp->sd_fsname, error); - goto fail_qi_free; - } - - /* We're through with the superblock lock */ - - gfs_glock_dq_uninit(&sb_gh); - super = FALSE; - - /* Get the root inode/dentry */ - - inode = gfs_iget(sdp->sd_rooti, CREATE); - if (!inode) { - printk("GFS: fsid=%s: can't get root inode\n", sdp->sd_fsname); - error = -ENOMEM; - goto fail_li_free; - } - - sb->s_root = d_alloc_root(inode); - if (!sb->s_root) { - iput(inode); - printk("GFS: fsid=%s: can't get root dentry\n", sdp->sd_fsname); - error = -ENOMEM; - goto fail_li_free; - } - - /* Start up the logd thread */ - - sdp->sd_jindex_refresh_time = jiffies; - - error = kernel_thread(gfs_logd, sdp, 0); - if (error < 0) { - printk("GFS: fsid=%s: can't start logd thread: %d\n", - sdp->sd_fsname, error); - goto fail_dput; - } - wait_for_completion(&sdp->sd_thread_completion); - - /* Start up the quotad thread */ - - error = kernel_thread(gfs_quotad, sdp, 0); - if (error < 0) { - printk("GFS: fsid=%s: can't start quotad thread: %d\n", - sdp->sd_fsname, error); - goto fail_logd; - } - wait_for_completion(&sdp->sd_thread_completion); - - /* Start up the inoded thread */ - - error = kernel_thread(gfs_inoded, sdp, 0); - if (error < 0) { - printk("GFS: fsid=%s: can't start inoded thread: %d\n", - sdp->sd_fsname, error); - goto fail_quotad; - } - wait_for_completion(&sdp->sd_thread_completion); - - /* Get a handle on the rename lock */ - - error = gfs_glock_get(sdp, GFS_RENAME_LOCK, &gfs_nondisk_glops, - CREATE, &sdp->sd_rename_gl); - if (error) - goto fail_inoded; - - gfs_proc_fs_add(sdp); - - gfs_glock_dq_uninit(&mount_gh); - - return 0; - - fail_inoded: - down(&sdp->sd_thread_lock); - clear_bit(SDF_INODED_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_inoded_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - fail_quotad: - down(&sdp->sd_thread_lock); - clear_bit(SDF_QUOTAD_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_quotad_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - fail_logd: - down(&sdp->sd_thread_lock); - clear_bit(SDF_LOGD_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_logd_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - fail_dput: - dput(sb->s_root); - - fail_li_free: - gfs_inode_put(sdp->sd_linode); - - fail_qi_free: - gfs_inode_put(sdp->sd_qinode); - - fail_root_free: - gfs_inode_put(sdp->sd_rooti); - - fail_ri_free: - gfs_inode_put(sdp->sd_riinode); - gfs_clear_rgrpd(sdp); - - fail_recoverd: - down(&sdp->sd_thread_lock); - clear_bit(SDF_RECOVERD_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_recoverd_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - fail_make_ro: - gfs_glock_force_drop(sdp->sd_trans_gl); - clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); - gfs_unlinked_cleanup(sdp); - gfs_quota_cleanup(sdp); - - fail_gunlock_journal: - gfs_glock_dq_uninit(&sdp->sd_journal_gh); - - fail_gunlock_ji: - if (jindex) - gfs_glock_dq_uninit(&ji_gh); - - fail_trans_gl: - gfs_glock_put(sdp->sd_trans_gl); - - fail_ji_free: - gfs_inode_put(sdp->sd_jiinode); - gfs_clear_journals(sdp); - - fail_gunlock_sb: - if (super) - gfs_glock_dq_uninit(&sb_gh); - - fail_gunlock_live: - gfs_glock_dq_uninit(&sdp->sd_live_gh); - - fail_gunlock_mount: - gfs_glock_dq_uninit(&mount_gh); - - fail_glockd: - clear_bit(SDF_GLOCKD_RUN, &sdp->sd_flags); - wake_up(&sdp->sd_reclaim_wchan); - while (sdp->sd_glockd_num) { - wait_for_completion(&sdp->sd_thread_completion); - sdp->sd_glockd_num--; - } - - down(&sdp->sd_thread_lock); - clear_bit(SDF_SCAND_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_scand_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - fail_lockproto: - gfs_gl_hash_clear(sdp, TRUE); - gfs_lm_unmount(sdp); - gfs_clear_dirty_j(sdp); - while (invalidate_inodes(sb)) - yield(); - - fail_vfree: - vfree(sdp); - - fail: - vfs2sdp(sb) = NULL; - return error; -} - -/** - * gfs_test_bdev_super - - * @sb: - * @data: - * - */ - -int -gfs_test_bdev_super(struct super_block *sb, void *data) -{ - return (void *)sb->s_bdev == data; -} - -/** - * gfs_test_bdev_super - - * @sb: - * @data: - * - */ - -int -gfs_set_bdev_super(struct super_block *sb, void *data) -{ - sb->s_bdev = data; - sb->s_dev = sb->s_bdev->bd_dev; - return 0; -} - -/** - * gfs_get_sb - - * @fs_type: - * @flags: - * @dev_name: - * @data: - * - * Rip off of get_sb_bdev(). - * - * Returns: the new superblock - */ - -struct super_block * -gfs_get_sb(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) -{ - struct block_device *real, *diaper; - struct super_block *sb; - int error = 0; - - real = open_bdev_excl(dev_name, flags, fs_type); - if (IS_ERR(real)) - return (struct super_block *)real; - - diaper = gfs_diaper_get(real, flags); - if (IS_ERR(diaper)) { - close_bdev_excl(real); - return (struct super_block *)diaper; - } - - down(&diaper->bd_mount_sem); - sb = sget(fs_type, gfs_test_bdev_super, gfs_set_bdev_super, diaper); - up(&diaper->bd_mount_sem); - if (IS_ERR(sb)) - goto out; - - if (sb->s_root) { - if ((flags ^ sb->s_flags) & MS_RDONLY) { - up_write(&sb->s_umount); - deactivate_super(sb); - sb = ERR_PTR(-EBUSY); - } - goto out; - } else { - char buf[BDEVNAME_SIZE]; - - sb->s_flags = flags; - strlcpy(sb->s_id, bdevname(real, buf), sizeof(sb->s_id)); - sb->s_old_blocksize = block_size(real); - sb_set_blocksize(sb, sb->s_old_blocksize); - set_blocksize(real, sb->s_old_blocksize); - error = fill_super(sb, data, (flags & MS_VERBOSE) ? 1 : 0); - if (error) { - up_write(&sb->s_umount); - deactivate_super(sb); - sb = ERR_PTR(error); - } else - sb->s_flags |= MS_ACTIVE; - } - - return sb; - - out: - gfs_diaper_put(diaper); - close_bdev_excl(real); - return sb; -} - -/** - * gfs_kill_sb - - * @sb: - * - * Rip off of kill_block_super(). - * - */ - -void -gfs_kill_sb(struct super_block *sb) -{ - struct block_device *diaper = sb->s_bdev; - struct block_device *real = gfs_diaper_2real(diaper); - unsigned long bsize = sb->s_old_blocksize; - - generic_shutdown_super(sb); - set_blocksize(diaper, bsize); - set_blocksize(real, bsize); - gfs_diaper_put(diaper); - close_bdev_excl(real); -} - -struct file_system_type gfs_fs_type = { - .name = "gfs", - .fs_flags = FS_REQUIRES_DEV, - .get_sb = gfs_get_sb, - .kill_sb = gfs_kill_sb, - .owner = THIS_MODULE, -}; diff --git a/gfs-kernel/src/gfs/ops_fstype.h b/gfs-kernel/src/gfs/ops_fstype.h deleted file mode 100644 index 1eeba5a..0000000 --- a/gfs-kernel/src/gfs/ops_fstype.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_FSTYPE_DOT_H__ -#define __OPS_FSTYPE_DOT_H__ - -int gfs_test_bdev_super(struct super_block *sb, void *data); -int gfs_set_bdev_super(struct super_block *sb, void *data); - -extern struct file_system_type gfs_fs_type; - -#endif /* __OPS_FSTYPE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_inode.c b/gfs-kernel/src/gfs/ops_inode.c deleted file mode 100644 index 2199c65..0000000 --- a/gfs-kernel/src/gfs/ops_inode.c +++ /dev/null @@ -1,1836 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/namei.h> -#include <linux/utsname.h> -#include <asm/uaccess.h> -#include <linux/mm.h> -#include <linux/xattr.h> -#include <linux/posix_acl.h> -#include <cluster/cnxman.h> - -#include "gfs.h" -#include "acl.h" -#include "bmap.h" -#include "diaper.h" -#include "dio.h" -#include "dir.h" -#include "eaops.h" -#include "eattr.h" -#include "glock.h" -#include "inode.h" -#include "ops_dentry.h" -#include "ops_inode.h" -#include "page.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" -#include "unlinked.h" - -/** - * gfs_create - Create a file - * @dir: The directory in which to create the file - * @dentry: The dentry of the new file - * @mode: The mode of the new file - * - * Returns: errno - */ - -static int -gfs_create(struct inode *dir, struct dentry *dentry, - int mode, struct nameidata *nd) -{ - struct gfs_inode *dip = vn2ip(dir), *ip; - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_holder d_gh, i_gh; - struct inode *inode; - int new = TRUE; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - gfs_holder_init(dip->i_gl, 0, 0, &d_gh); - - for (;;) { - error = gfs_createi(&d_gh, &dentry->d_name, - GFS_FILE_REG, mode, - &i_gh); - if (!error) - break; - else if (error != -EEXIST || (nd && - (nd->intent.open.flags & O_EXCL))) { - gfs_holder_uninit(&d_gh); - return error; - } - - error = gfs_lookupi(&d_gh, &dentry->d_name, - FALSE, &i_gh); - if (!error) { - if (i_gh.gh_gl) { - new = FALSE; - break; - } - } else { - gfs_holder_uninit(&d_gh); - return error; - } - } - - ip = gl2ip(i_gh.gh_gl); - - if (new) { - gfs_trans_end(sdp); - if (dip->i_alloc->al_rgd) - gfs_inplace_release(dip); - gfs_quota_unlock_m(dip); - gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); - gfs_alloc_put(dip); - } - - gfs_glock_dq_uninit(&d_gh); - gfs_glock_dq_uninit(&i_gh); - - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - if (!inode) - return -ENOMEM; - - d_instantiate(dentry, inode); - if (new) - mark_inode_dirty(inode); - - return 0; -} - -/** get_my_node_id - Returns the node id of the local node - * - * Returns: the nodeid as int. If we are not part of a cluster - * return 0. - */ -static int get_my_nodeid(void) -{ - /* we want to keep the information. */ - static struct kcl_cluster_node *us=NULL; - - /* if we already have our information, return it.*/ - if (us) - return us->node_id; - - /* we are here, i.e. we need to collect information */ - us = kmalloc(sizeof (struct kcl_cluster_node), GFP_KERNEL); - if (kcl_get_node_by_nodeid(0, us)) - { - /* request failed. Cleaning up. Returning 0.*/ - kfree(us); - us = NULL; - return 0; - } - /* return collected data */ - return us->node_id; -} - -/** - * lookup_cdpn_sub_at - Maybe lookup a Context Dependent Pathname - * @sdp: the filesystem - * @dentry: the original dentry to lookup - * @new_dentry: the new dentry, if this was a substitutable path. - * - * Returns: the new dentry, a ERR_PTR, or NULL - */ - -static struct dentry * -lookup_cdpn_sub_at(struct gfs_sbd *sdp, struct dentry *dentry) -{ - struct dentry *parent, *new = NULL; - char *buf; - - buf = kmalloc(2 * __NEW_UTS_LEN + 2, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - parent = dget_parent(dentry); - - if (gfs_filecmp(&dentry->d_name, "@hostname", 9)) - new = lookup_one_len(system_utsname.nodename, - parent, - strlen(system_utsname.nodename)); - else if (gfs_filecmp(&dentry->d_name, "@nodeid", 7)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%s%i", "node", - get_my_nodeid())); - else if (gfs_filecmp(&dentry->d_name, "@mach", 5)) - new = lookup_one_len(system_utsname.machine, - parent, - strlen(system_utsname.machine)); - else if (gfs_filecmp(&dentry->d_name, "@os", 3)) - new = lookup_one_len(system_utsname.sysname, - parent, - strlen(system_utsname.sysname)); - else if (gfs_filecmp(&dentry->d_name, "@uid", 4)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%u", current->fsuid)); - else if (gfs_filecmp(&dentry->d_name, "@gid", 4)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%u", current->fsgid)); - else if (gfs_filecmp(&dentry->d_name, "@sys", 4)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%s_%s", - system_utsname.machine, - system_utsname.sysname)); - else if (gfs_filecmp(&dentry->d_name, "@jid", 4)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%u", - sdp->sd_lockstruct.ls_jid)); - - dput(parent); - kfree(buf); - - return new; -} - -/** - * lookup_cdpn_sub_brace - Maybe lookup a Context Dependent Pathname - * @sdp: the filesystem - * @dentry: the original dentry to lookup - * @new_dentry: the new dentry, if this was a substitutable path. - * - * Returns: the new dentry, a ERR_PTR, or NULL - */ - -static struct dentry * -lookup_cdpn_sub_brace(struct gfs_sbd *sdp, struct dentry *dentry) -{ - struct dentry *parent, *new = NULL; - char *buf; - - buf = kmalloc(2 * __NEW_UTS_LEN + 2, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - parent = dget_parent(dentry); - - if (gfs_filecmp(&dentry->d_name, "{hostname}", 10)) - new = lookup_one_len(system_utsname.nodename, - parent, - strlen(system_utsname.nodename)); - else if (gfs_filecmp(&dentry->d_name, "{nodeid}", 8)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%s%i", "node", - get_my_nodeid())); - else if (gfs_filecmp(&dentry->d_name, "{mach}", 6)) - new = lookup_one_len(system_utsname.machine, - parent, - strlen(system_utsname.machine)); - else if (gfs_filecmp(&dentry->d_name, "{os}", 4)) - new = lookup_one_len(system_utsname.sysname, - parent, - strlen(system_utsname.sysname)); - else if (gfs_filecmp(&dentry->d_name, "{uid}", 5)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%u", current->fsuid)); - else if (gfs_filecmp(&dentry->d_name, "{gid}", 5)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%u", current->fsgid)); - else if (gfs_filecmp(&dentry->d_name, "{sys}", 5)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%s_%s", - system_utsname.machine, - system_utsname.sysname)); - else if (gfs_filecmp(&dentry->d_name, "{jid}", 5)) - new = lookup_one_len(buf, - parent, - sprintf(buf, "%u", - sdp->sd_lockstruct.ls_jid)); - - dput(parent); - kfree(buf); - - return new; -} - -/** - * gfs_lookup - Look up a filename in a directory and return its inode - * @dir: The directory inode - * @dentry: The dentry of the new inode - * @nd: passed from Linux VFS, ignored by us - * - * Called by the VFS layer. Lock dir and call gfs_lookupi() - * - * Returns: errno - */ - -static struct dentry * -gfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -{ - struct gfs_inode *dip = vn2ip(dir), *ip; - struct gfs_holder d_gh, i_gh; - struct inode *inode = NULL; - int error; - - atomic_inc(&dip->i_sbd->sd_ops_inode); - - /* Do Context Dependent Path Name expansion */ - - if (*dentry->d_name.name == '@' && dentry->d_name.len > 1) { - struct dentry *new_dentry; - new_dentry = lookup_cdpn_sub_at(dip->i_sbd, dentry); - if (new_dentry) - return new_dentry; - } else if (*dentry->d_name.name == '{' && dentry->d_name.len > 2) { - struct dentry *new_dentry; - new_dentry = lookup_cdpn_sub_brace(dip->i_sbd, dentry); - if (new_dentry) - return new_dentry; - } - - dentry->d_op = &gfs_dops; - - gfs_holder_init(dip->i_gl, 0, 0, &d_gh); - - error = gfs_lookupi(&d_gh, &dentry->d_name, FALSE, &i_gh); - if (error) { - gfs_holder_uninit(&d_gh); - return ERR_PTR(error); - } - - if (i_gh.gh_gl) { - ip = gl2ip(i_gh.gh_gl); - - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - gfs_glock_dq_uninit(&d_gh); - gfs_glock_dq_uninit(&i_gh); - - if (!inode) - return ERR_PTR(-ENOMEM); - } else - gfs_holder_uninit(&d_gh); - - if (inode) - return d_splice_alias(inode, dentry); - d_add(dentry, inode); - - return NULL; -} - -/** - * gfs_link - Link to a file - * @old_dentry: The inode to link - * @dir: Add link to this directory - * @dentry: The name of the link - * - * Link the inode in "old_dentry" into the directory "dir" with the - * name in "dentry". - * - * Returns: errno - */ - -static int -gfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) -{ - struct gfs_inode *dip = vn2ip(dir); - struct gfs_sbd *sdp = dip->i_sbd; - struct inode *inode = old_dentry->d_inode; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_alloc *al = NULL; - struct gfs_holder ghs[2]; - int alloc_required; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - if (ip->i_di.di_type == GFS_FILE_DIR) - return -EPERM; - - gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); - gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); - - error = gfs_glock_nq_m(2, ghs); - if (error) - goto fail; - - error = permission(dir, MAY_WRITE | MAY_EXEC, NULL); - if (error) - goto fail_gunlock; - - error = gfs_dir_search(dip, &dentry->d_name, NULL, NULL); - switch (error) { - case -ENOENT: - break; - case 0: - error = -EEXIST; - default: - goto fail_gunlock; - } - - if (!dip->i_di.di_nlink) { - error = -EINVAL; - goto fail_gunlock; - } - if (dip->i_di.di_entries == (uint32_t)-1) { - error = -EFBIG; - goto fail_gunlock; - } - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { - error = -EPERM; - goto fail_gunlock; - } - if (!ip->i_di.di_nlink) { - error = -EINVAL; - goto fail_gunlock; - } - if (ip->i_di.di_nlink == (uint32_t)-1) { - error = -EMLINK; - goto fail_gunlock; - } - - error = gfs_diradd_alloc_required(dip, &dentry->d_name, &alloc_required); - if (error) - goto fail_gunlock; - - if (alloc_required) { - al = gfs_alloc_get(dip); - - error = gfs_quota_lock_m(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto fail_alloc; - - error = gfs_quota_check(dip, dip->i_di.di_uid, dip->i_di.di_gid); - if (error) - goto fail_gunlock_q; - - al->al_requested_meta = sdp->sd_max_dirres; - - error = gfs_inplace_reserve(dip); - if (error) - goto fail_gunlock_q; - - /* Trans may require: - two dinode blocks, directory modifications to add an entry, - RG bitmap blocks to allocate from, and quota change */ - - error = gfs_trans_begin(sdp, - 2 + sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length, - 1); - if (error) - goto fail_ipres; - } else { - /* Trans may require: - Two dinode blocks and a leaf block. */ - - error = gfs_trans_begin(sdp, 3, 0); - if (error) - goto fail_ipres; - } - - error = gfs_dir_add(dip, &dentry->d_name, &ip->i_num, ip->i_di.di_type); - if (error) - goto fail_end_trans; - - error = gfs_change_nlink(ip, +1); - if (error) - goto fail_end_trans; - - gfs_trans_end(sdp); - - if (alloc_required) { - gfs_assert_warn(sdp, al->al_alloced_meta); - gfs_inplace_release(dip); - gfs_quota_unlock_m(dip); - gfs_alloc_put(dip); - } - - gfs_glock_dq_m(2, ghs); - - gfs_holder_uninit(&ghs[0]); - gfs_holder_uninit(&ghs[1]); - - atomic_inc(&inode->i_count); - - d_instantiate(dentry, inode); - mark_inode_dirty(inode); - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_ipres: - if (alloc_required) - gfs_inplace_release(dip); - - fail_gunlock_q: - if (alloc_required) - gfs_quota_unlock_m(dip); - - fail_alloc: - if (alloc_required) - gfs_alloc_put(dip); - - fail_gunlock: - gfs_glock_dq_m(2, ghs); - - fail: - gfs_holder_uninit(&ghs[0]); - gfs_holder_uninit(&ghs[1]); - - return error; -} - -/** - * gfs_unlink - Unlink a file - * @dir: The inode of the directory containing the file to unlink - * @dentry: The file itself - * - * Unlink a file. Call gfs_unlinki() - * - * Returns: errno - */ - -static int -gfs_unlink(struct inode *dir, struct dentry *dentry) -{ - struct gfs_inode *dip = vn2ip(dir); - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_inode *ip = vn2ip(dentry->d_inode); - struct gfs_holder ghs[2]; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); - gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); - - error = gfs_glock_nq_m(2, ghs); - if (error) - goto fail; - - error = gfs_unlink_ok(dip, &dentry->d_name, ip, NULL); - if (error) - goto fail_gunlock; - - /* Trans may require: - Two dinode blocks and one modified directory leaf block - and one unlinked tag. */ - - error = gfs_trans_begin(sdp, 3, 1); - if (error) - goto fail_gunlock; - - error = gfs_unlinki(dip, &dentry->d_name, ip); - if (error) - goto fail_end_trans; - - gfs_trans_end(sdp); - - gfs_glock_dq_m(2, ghs); - - gfs_holder_uninit(&ghs[0]); - gfs_holder_uninit(&ghs[1]); - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_gunlock: - gfs_glock_dq_m(2, ghs); - - fail: - gfs_holder_uninit(&ghs[0]); - gfs_holder_uninit(&ghs[1]); - - return error; -} - -/** - * gfs_symlink - Create a symlink - * @dir: The directory to create the symlink in - * @dentry: The dentry to put the symlink in - * @symname: The thing which the link points to - * - * Returns: errno - */ - -static int -gfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) -{ - struct gfs_inode *dip = vn2ip(dir), *ip; - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_holder d_gh, i_gh; - struct inode *inode; - struct buffer_head *dibh; - int size; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - /* Must be stuffed with a null terminator for gfs_follow_link() */ - size = strlen(symname); - if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode) - 1) - return -ENAMETOOLONG; - - gfs_holder_init(dip->i_gl, 0, 0, &d_gh); - - error = gfs_createi(&d_gh, &dentry->d_name, - GFS_FILE_LNK, S_IFLNK | S_IRWXUGO, - &i_gh); - if (error) { - gfs_holder_uninit(&d_gh); - return error; - } - - ip = gl2ip(i_gh.gh_gl); - - ip->i_di.di_size = size; - - error = gfs_get_inode_buffer(ip, &dibh); - - if (!gfs_assert_withdraw(sdp, !error)) { - gfs_dinode_out(&ip->i_di, dibh->b_data); - memcpy(dibh->b_data + sizeof(struct gfs_dinode), symname, size); - brelse(dibh); - } - - gfs_trans_end(sdp); - if (dip->i_alloc->al_rgd) - gfs_inplace_release(dip); - gfs_quota_unlock_m(dip); - gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); - gfs_alloc_put(dip); - - gfs_glock_dq_uninit(&d_gh); - gfs_glock_dq_uninit(&i_gh); - - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - if (!inode) - return -ENOMEM; - - d_instantiate(dentry, inode); - mark_inode_dirty(inode); - - return 0; -} - -/** - * gfs_mkdir - Make a directory - * @dir: The parent directory of the new one - * @dentry: The dentry of the new directory - * @mode: The mode of the new directory - * - * Returns: errno - */ - -static int -gfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - struct gfs_inode *dip = vn2ip(dir), *ip; - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_holder d_gh, i_gh; - struct inode *inode; - struct buffer_head *dibh; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - gfs_holder_init(dip->i_gl, 0, 0, &d_gh); - - error = gfs_createi(&d_gh, &dentry->d_name, - GFS_FILE_DIR, S_IFDIR | mode, - &i_gh); - if (error) { - gfs_holder_uninit(&d_gh); - return error; - } - - ip = gl2ip(i_gh.gh_gl); - - ip->i_di.di_nlink = 2; - ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); - ip->i_di.di_flags |= GFS_DIF_JDATA; - ip->i_di.di_payload_format = GFS_FORMAT_DE; - ip->i_di.di_entries = 2; - - error = gfs_get_inode_buffer(ip, &dibh); - - if (!gfs_assert_withdraw(sdp, !error)) { - struct gfs_dinode *di = (struct gfs_dinode *)dibh->b_data; - struct gfs_dirent *dent; - - gfs_dirent_alloc(ip, dibh, 1, &dent); - - dent->de_inum = di->di_num; /* already GFS endian */ - dent->de_hash = gfs_dir_hash(".", 1); - dent->de_hash = cpu_to_gfs32(dent->de_hash); - dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); - memcpy((char *) (dent + 1), ".", 1); - di->di_entries = cpu_to_gfs32(1); - - gfs_dirent_alloc(ip, dibh, 2, &dent); - - gfs_inum_out(&dip->i_num, (char *) &dent->de_inum); - dent->de_hash = gfs_dir_hash("..", 2); - dent->de_hash = cpu_to_gfs32(dent->de_hash); - dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); - memcpy((char *) (dent + 1), "..", 2); - - gfs_dinode_out(&ip->i_di, (char *)di); - - brelse(dibh); - } - - error = gfs_change_nlink(dip, +1); - gfs_assert_withdraw(sdp, !error); /* dip already pinned */ - - gfs_trans_end(sdp); - if (dip->i_alloc->al_rgd) - gfs_inplace_release(dip); - gfs_quota_unlock_m(dip); - gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); - gfs_alloc_put(dip); - - gfs_glock_dq_uninit(&d_gh); - gfs_glock_dq_uninit(&i_gh); - - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - if (!inode) - return -ENOMEM; - - d_instantiate(dentry, inode); - mark_inode_dirty(inode); - - return 0; -} - -/** - * gfs_rmdir - Remove a directory - * @dir: The parent directory of the directory to be removed - * @dentry: The dentry of the directory to remove - * - * Remove a directory. Call gfs_rmdiri() - * - * Returns: errno - */ - -static int -gfs_rmdir(struct inode *dir, struct dentry *dentry) -{ - struct gfs_inode *dip = vn2ip(dir); - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_inode *ip = vn2ip(dentry->d_inode); - struct gfs_holder ghs[2]; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); - gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); - - error = gfs_glock_nq_m(2, ghs); - if (error) - goto fail; - - error = gfs_unlink_ok(dip, &dentry->d_name, ip, NULL); - if (error) - goto fail_gunlock; - - if (ip->i_di.di_entries < 2) { - if (gfs_consist_inode(ip)) - gfs_dinode_print(&ip->i_di); - error = -EIO; - goto fail_gunlock; - } - if (ip->i_di.di_entries > 2) { - error = -ENOTEMPTY; - goto fail_gunlock; - } - - /* Trans may require: - Two dinode blocks, one directory leaf block containing the - entry to be rmdired, two leaf blocks containing . and .. of - the directory being rmdired, and one unlinked tag */ - - error = gfs_trans_begin(sdp, 5, 1); - if (error) - goto fail_gunlock; - - error = gfs_rmdiri(dip, &dentry->d_name, ip); - if (error) - goto fail_end_trans; - - gfs_trans_end(sdp); - - gfs_glock_dq_m(2, ghs); - - gfs_holder_uninit(&ghs[0]); - gfs_holder_uninit(&ghs[1]); - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_gunlock: - gfs_glock_dq_m(2, ghs); - - fail: - gfs_holder_uninit(&ghs[0]); - gfs_holder_uninit(&ghs[1]); - - return error; -} - -/** - * gfs_mknod - Make a special file - * @dir: The directory in which the special file will reside - * @dentry: The dentry of the special file - * @mode: The mode of the special file - * @rdev: The device specification of the special file - * - */ - -static int -gfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -{ - struct gfs_inode *dip = vn2ip(dir), *ip; - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_holder d_gh, i_gh; - struct inode *inode; - struct buffer_head *dibh; - uint16_t type = 0; - uint32_t major = 0, minor = 0; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - switch (mode & S_IFMT) { - case S_IFBLK: - type = GFS_FILE_BLK; - major = MAJOR(dev); - minor = MINOR(dev); - break; - case S_IFCHR: - type = GFS_FILE_CHR; - major = MAJOR(dev); - minor = MINOR(dev); - break; - case S_IFIFO: - type = GFS_FILE_FIFO; - break; - case S_IFSOCK: - type = GFS_FILE_SOCK; - break; - default: - printk("GFS: fsid=%s: mknod() with invalid type (%d)\n", - sdp->sd_fsname, mode); - return -EINVAL; - }; - - gfs_holder_init(dip->i_gl, 0, 0, &d_gh); - - error = gfs_createi(&d_gh, &dentry->d_name, - type, mode, - &i_gh); - if (error) { - gfs_holder_uninit(&d_gh); - return error; - } - - ip = gl2ip(i_gh.gh_gl); - - ip->i_di.di_major = major; - ip->i_di.di_minor = minor; - - error = gfs_get_inode_buffer(ip, &dibh); - - if (!gfs_assert_withdraw(sdp, !error)) { - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - } - - gfs_trans_end(sdp); - if (dip->i_alloc->al_rgd) - gfs_inplace_release(dip); - gfs_quota_unlock_m(dip); - gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); - gfs_alloc_put(dip); - - gfs_glock_dq_uninit(&d_gh); - gfs_glock_dq_uninit(&i_gh); - - inode = gfs_iget(ip, CREATE); - gfs_inode_put(ip); - - if (!inode) - return -ENOMEM; - - d_instantiate(dentry, inode); - mark_inode_dirty(inode); - - return 0; -} - -/* - * Obtain a clone dentry with correct inode: - * - * This is to work around the window between lock_rename() - * and gfs_rename() where another node may have renamed the - * target file (bugzilla 190475). The bug most likely occurs - * in a mail server environment. - * - * Return true if the dentry has been successfully updated. - */ -static int -gfs_refresh_dentry(struct gfs_sbd *sdp, struct dentry **f_dentry, - struct gfs_inum *inump) -{ - struct inode *inode; - struct dentry *dentry, *sdentry=*f_dentry; - - dentry = d_alloc(sdentry->d_parent, &sdentry->d_name); - if (!dentry) - return 0; - - /* Get the fully updated inode */ - inode = NULL; - if (inump->no_formal_ino) { - inode = gfs_refresh_iobj(sdp, inump, NULL); - if (IS_ERR(inode)) { - dput(dentry); - return 0; - } - } - - /* - * Remove the old dentry from cache to avoid - * another lookup. - */ - if (!d_unhashed(sdentry)) { - d_drop(sdentry); - } - - /* Instantiate the new dentry */ - dentry->d_op = &gfs_dops; - - d_splice_alias(inode, dentry); - - /* Return with success */ - *f_dentry = dentry; - return 1; -} - -/* - * Check lock order for the new ino: - * return 1: if it could lead to deadlock - * return 0: if ordering is ok. - */ - -static int -gfs_check_lock_order(struct gfs_holder *ghs, int n_gh, uint64_t ino) -{ - int x; - - /* no fancy algorithm here since max n_gh is 4 */ - for (x = 0; x < n_gh; x++) { - if (ino < ghs[x].gh_gl->gl_name.ln_number) - return 1; - } - - return 0; -} - -/** - * gfs_rename - Rename a file - * @odir: Parent directory of old file name - * @odentry: The old dentry of the file - * @ndir: Parent directory of new file name - * @ndentry: The new dentry of the file - * - * Returns: errno - */ - -static int -gfs_rename(struct inode *odir, struct dentry *odentry, - struct inode *ndir, struct dentry *ndentry) -{ - struct gfs_inode *odip = vn2ip(odir); - struct gfs_inode *ndip = vn2ip(ndir); - struct gfs_inode *ip = vn2ip(odentry->d_inode); - struct gfs_inode *nip = NULL; - struct gfs_sbd *sdp = odip->i_sbd; - struct qstr name; - struct gfs_alloc *al; - struct gfs_holder ghs[5], r_gh; - unsigned int num_gh; - int dir_rename = FALSE; - int alloc_required; - unsigned int x; - int error; - int once_cnt=0, has_ndentry=0; - struct gfs_inum new_inum; - - atomic_inc(&sdp->sd_ops_inode); - - gfs_unlinked_limit(sdp); - - odir->i_sb->s_type->fs_flags &= ~FS_ODD_RENAME; - - if (ndentry->d_inode) { - nip = vn2ip(ndentry->d_inode); - if (ip == nip) - return 0; - } - - /* Make sure we aren't trying to move a directory into its subdir */ - - if (ip->i_di.di_type == GFS_FILE_DIR && odip != ndip) { - dir_rename = TRUE; - - error = gfs_glock_nq_init(sdp->sd_rename_gl, - LM_ST_EXCLUSIVE, 0, - &r_gh); - if (error) - return error; - - error = gfs_ok_to_move(ip, ndip); - if (error) - goto fail; - } - - num_gh = 1; - gfs_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); - if (odip != ndip) { - gfs_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs+num_gh); - num_gh++; - } - - gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs+num_gh); - num_gh++; - if (nip) { - gfs_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); - num_gh++; - } - - error = gfs_glock_nq_m(num_gh, ghs); - if (error) - goto fail_uninit; - - /* Check out the old directory */ - - error = gfs_unlink_ok(odip, &odentry->d_name, ip, NULL); - if (error) - goto fail_gunlock; - -gfs_rename_retry: - - /* Check out the new directory */ - - if (nip) { - /* Zero out this field so we can know whether gfs_unlink_ok - * could fill in the correct inode numbers. - */ - new_inum.no_formal_ino = 0; - error = gfs_unlink_ok(ndip, &ndentry->d_name, nip, &new_inum); - - if (unlikely(error)) { - /* - * Handle a rare race condition that the new file - * could have been renamed by another node - the - * correct inode number is passed into new_inum. - * We only allow this to happen once. - */ - if ((error == -ENOENT) && (!once_cnt) - && (new_inum.no_formal_ino)) - { - if (gfs_check_lock_order(ghs, num_gh, - new_inum.no_formal_ino)) - /* fail rename with -ENOENT */ - goto fail_gunlock; - - if (gfs_refresh_dentry(sdp,&ndentry,&new_inum)) - { - odir->i_sb->s_type->fs_flags - |= FS_ODD_RENAME; - has_ndentry = 1; - nip = vn2ip(ndentry->d_inode); - if (nip) { - once_cnt++; - error = gfs_glock_nq_init(nip->i_gl, - LM_ST_EXCLUSIVE, 0, - &ghs[num_gh++]); - if (error) { - num_gh--; - error = -ENOENT; - } - else - goto gfs_rename_retry; - } - } - } - goto fail_gunlock; - } - - if (nip->i_di.di_type == GFS_FILE_DIR) { - if (nip->i_di.di_entries < 2) { - if (gfs_consist_inode(nip)) - gfs_dinode_print(&nip->i_di); - error = -EIO; - goto fail_gunlock; - } - if (nip->i_di.di_entries > 2) { - error = -ENOTEMPTY; - goto fail_gunlock; - } - } - } else { - error = permission(ndir, MAY_WRITE | MAY_EXEC, NULL); - if (error) - goto fail_gunlock; - - error = gfs_dir_search(ndip, &ndentry->d_name, NULL, NULL); - switch (error) { - case -ENOENT: - error = 0; - break; - case 0: - error = -EEXIST; - default: - goto fail_gunlock; - }; - - if (odip != ndip) { - if (!ndip->i_di.di_nlink) { - error = -EINVAL; - goto fail_gunlock; - } - if (ndip->i_di.di_entries == (uint32_t)-1) { - error = -EFBIG; - goto fail_gunlock; - } - if (ip->i_di.di_type == GFS_FILE_DIR && - ndip->i_di.di_nlink == (uint32_t)-1) { - error = -EMLINK; - goto fail_gunlock; - } - } - } - - error = gfs_diradd_alloc_required(ndip, &ndentry->d_name, &alloc_required); - if (error) - goto fail_gunlock; - - if (alloc_required) { - al = gfs_alloc_get(ndip); - - error = gfs_quota_lock_m(ndip, - NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto fail_alloc; - - error = gfs_quota_check(ndip, ndip->i_di.di_uid, ndip->i_di.di_gid); - if (error) - goto fail_gunlock_q; - - al->al_requested_meta = sdp->sd_max_dirres; - - error = gfs_inplace_reserve(ndip); - if (error) - goto fail_gunlock_q; - - /* Trans may require: - Dinodes for the srcdir, srcino, dstdir, dstino. Blocks for - adding the entry to dstdir. RG bitmaps for that allocation. - One leaf block in the srcdir for removal of the entry. - One leaf block for changing .. in srcino (if it's a directory). - Two leaf blocks for removing . and .. from dstino (if it exists - and it's a directory), one unlinked tag, and one quota block. */ - - error = gfs_trans_begin(sdp, - 8 + sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length, - 2); - if (error) - goto fail_ipres; - } else { - /* Trans may require: - Dinodes for the srcdir, srcino, dstdir, dstino. One block for - adding the entry to dstdir. - One leaf block in the srcdir for removal of the entry. - One leaf block for changing .. in srcino (if it's a directory). - Two leaf blocks for removing . and .. from dstino (if it exists - and it's a directory), and one unlinked tag. */ - - error = gfs_trans_begin(sdp, 9, 1); - if (error) - goto fail_ipres; - } - - /* Remove the target file, if it exists */ - - if (nip) { - if (nip->i_di.di_type == GFS_FILE_DIR) - error = gfs_rmdiri(ndip, &ndentry->d_name, nip); - else - error = gfs_unlinki(ndip, &ndentry->d_name, nip); - - if (error) - goto fail_end_trans; - } - - if (dir_rename) { - error = gfs_change_nlink(ndip, +1); - if (error) - goto fail_end_trans; - error = gfs_change_nlink(odip, -1); - if (error) - goto fail_end_trans; - - name.len = 2; - name.name = ".."; - - error = gfs_dir_mvino(ip, &name, &ndip->i_num, GFS_FILE_DIR); - if (error) - goto fail_end_trans; - } - - error = gfs_dir_del(odip, &odentry->d_name); - if (error) - goto fail_end_trans; - - error = gfs_dir_add(ndip, &ndentry->d_name, &ip->i_num, ip->i_di.di_type); - if (error) - goto fail_end_trans; - - if (dir_rename) - gfs_trans_add_gl(sdp->sd_rename_gl); - - gfs_trans_end(sdp); - - if (alloc_required) { - /* Don't check al->al_alloced_meta and friends. */ - gfs_inplace_release(ndip); - gfs_quota_unlock_m(ndip); - gfs_alloc_put(ndip); - } - - gfs_glock_dq_m(num_gh, ghs); - - for (x = 0; x < num_gh; x++) - gfs_holder_uninit(&ghs[x]); - - if (dir_rename) - gfs_glock_dq_uninit(&r_gh); - - - /* dput new dentry as vfs layer still uses old entry */ - if (unlikely(has_ndentry)) { - d_move(odentry, ndentry); - dput(ndentry); - dput(ndentry); - } - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_ipres: - if (alloc_required) - gfs_inplace_release(ndip); - - fail_gunlock_q: - if (alloc_required) - gfs_quota_unlock_m(ndip); - - fail_alloc: - if (alloc_required) - gfs_alloc_put(ndip); - - fail_gunlock: - gfs_glock_dq_m(num_gh, ghs); - - fail_uninit: - for (x = 0; x < num_gh; x++) - gfs_holder_uninit(&ghs[x]); - - fail: - if (dir_rename) - gfs_glock_dq_uninit(&r_gh); - - if (unlikely(has_ndentry)) { - d_move(odentry, ndentry); - dput(ndentry); - dput(ndentry); - } - - return error; -} - -/** - * gfs_readlink - Read the value of a symlink - * @dentry: the symlink - * @buf: the buffer to read the symlink data into - * @size: the size of the buffer - * - * Returns: errno - */ - -static int -gfs_readlink(struct dentry *dentry, char *user_buf, int user_size) -{ - struct gfs_inode *ip = vn2ip(dentry->d_inode); - char array[GFS_FAST_NAME_SIZE], *buf = array; - unsigned int len = GFS_FAST_NAME_SIZE; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_inode); - - error = gfs_readlinki(ip, &buf, &len); - if (error) - return error; - - if (user_size > len - 1) - user_size = len - 1; - - if (copy_to_user(user_buf, buf, user_size)) - error = -EFAULT; - else - error = user_size; - - if (buf != array) - kfree(buf); - - return error; -} - -/** - * gfs_follow_link - Follow a symbolic link - * @dentry: The dentry of the link - * @nd: Data that we pass to vfs_follow_link() - * - * This can handle symlinks of any size. It is optimised for symlinks - * under GFS_FAST_NAME_SIZE. - * - * Returns: 0 on success or error code - */ - -static int -gfs_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - struct gfs_inode *ip = vn2ip(dentry->d_inode); - char array[GFS_FAST_NAME_SIZE], *buf = array; - unsigned int len = GFS_FAST_NAME_SIZE; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_inode); - - error = gfs_readlinki(ip, &buf, &len); - if (!error) { - error = vfs_follow_link(nd, buf); - if (buf != array) - kfree(buf); - } - - return error; -} - -/** - * gfs_permission_i - - * @inode: - * @mask: - * @nd: ignored - * - * Shamelessly ripped from ext3 - * - * Returns: errno - */ - -static int -gfs_permission_i(struct inode *inode, int mask, struct nameidata *nd) -{ - int mode = inode->i_mode; - - /* Nobody gets write access to a read-only fs */ - if ((mask & MAY_WRITE) && - IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - - /* Nobody gets write access to an immutable file */ - if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) - return -EACCES; - - if (current->fsuid == inode->i_uid) - mode >>= 6; - else if (IS_POSIXACL(inode)) { - struct posix_acl *acl = NULL; - int error; - - /* The access ACL cannot grant access if the group class - permission bits don't contain all requested permissions. */ - if (((mode >> 3) & mask & S_IRWXO) != mask) - goto check_groups; - - error = gfs_acl_get(vn2ip(inode), TRUE, &acl); - if (error) - return error; - - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - if (error == -EACCES) - goto check_capabilities; - return error; - } else - goto check_groups; - } else { - check_groups: - if (in_group_p(inode->i_gid)) - mode >>= 3; - } - - if ((mode & mask & S_IRWXO) == mask) - return 0; - - check_capabilities: - /* Allowed to override Discretionary Access Control? */ - if (!(mask & MAY_EXEC) || - (inode->i_mode & S_IXUGO) || - S_ISDIR(inode->i_mode)) - if (capable(CAP_DAC_OVERRIDE)) - return 0; - - /* Read and search granted if capable(CAP_DAC_READ_SEARCH) */ - if (capable(CAP_DAC_READ_SEARCH) && - ((mask == MAY_READ) || - (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))) - return 0; - - return -EACCES; -} - -/** - * gfs_permission - - * @inode: - * @mask: - * @nd: passed from Linux VFS, ignored by us - * - * Returns: errno - */ - -static int -gfs_permission(struct inode *inode, int mask, struct nameidata *nd) -{ - struct gfs_inode *ip = vn2ip(inode); - struct gfs_holder i_gh; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_inode); - - error = gfs_glock_nq_init(ip->i_gl, - LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); - if (error) - return error; - - error = gfs_permission_i(inode, mask, nd); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_setattr - Change attributes on an inode - * @dentry: The dentry which is changing - * @attr: The structure describing the change - * - * The VFS layer wants to change one or more of an inodes attributes. Write - * that change out to disk. - * - * Returns: errno - */ - -static int -gfs_setattr(struct dentry *dentry, struct iattr *attr) -{ - struct inode *inode = dentry->d_inode; - struct gfs_inode *ip = vn2ip(inode); - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_holder i_gh; - int error; - - atomic_inc(&sdp->sd_ops_inode); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - return error; - - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { - error = -EPERM; - goto fail; - } - - error = inode_change_ok(inode, attr); - if (error) - goto fail; - - if (attr->ia_valid & ATTR_SIZE) { - /* Is there a reason for this?? - error = permission(inode, MAY_WRITE, NULL); - if (error) - goto fail; - */ - - if (attr->ia_size != ip->i_di.di_size) { - error = vmtruncate(inode, attr->ia_size); - if (error) - goto fail; - } - - error = gfs_truncatei(ip, attr->ia_size, gfs_truncator_page); - if (error) - goto fail; - - if ((sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) && - !gfs_is_jdata(ip)) - i_gh.gh_flags |= GL_SYNC; - } - - else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) { - struct gfs_alloc *al; - struct buffer_head *dibh; - uint32_t ouid, ogid, nuid, ngid; - - ouid = ip->i_di.di_uid; - ogid = ip->i_di.di_gid; - nuid = attr->ia_uid; - ngid = attr->ia_gid; - - if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) - ouid = nuid = NO_QUOTA_CHANGE; - if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) - ogid = ngid = NO_QUOTA_CHANGE; - - al = gfs_alloc_get(ip); - - error = gfs_quota_lock_m(ip, nuid, ngid); - if (error) - goto fail_alloc; - - if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { - error = gfs_quota_check(ip, nuid, ngid); - if (error) - goto fail_gunlock_q; - } - - /* Trans may require: - one dinode block and one quota change block */ - - error = gfs_trans_begin(sdp, 1, 1); - if (error) - goto fail_gunlock_q; - - error = gfs_get_inode_buffer(ip, &dibh); - if (error) - goto fail_end_trans; - - if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { - gfs_trans_add_quota(sdp, -ip->i_di.di_blocks, - ouid, ogid); - gfs_trans_add_quota(sdp, ip->i_di.di_blocks, - nuid, ngid); - } - - inode_setattr(inode, attr); - gfs_inode_attr_out(ip); - - gfs_trans_add_bh(ip->i_gl, dibh); - gfs_dinode_out(&ip->i_di, dibh->b_data); - brelse(dibh); - - gfs_trans_end(sdp); - - gfs_quota_unlock_m(ip); - gfs_alloc_put(ip); - } - - else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) { - error = gfs_acl_chmod(ip, attr); - if (error) - goto fail; - } - - else { - error = gfs_setattr_simple(ip, attr); - if (error) - goto fail; - } - - gfs_glock_dq_uninit(&i_gh); - - mark_inode_dirty(inode); - - return error; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_gunlock_q: - gfs_quota_unlock_m(ip); - - fail_alloc: - gfs_alloc_put(ip); - - fail: - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_getattr - Read out an inode's attributes - * @mnt: ? - * @dentry: The dentry to stat - * @stat: The inode's stats - * - * Returns: errno - */ - -static int -gfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -{ - struct inode *inode = dentry->d_inode, *p_inode = NULL; - struct gfs_inode *ip = vn2ip(inode), *pi = NULL; - struct gfs_holder gh; - struct block_device *blk_dev; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_inode); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); - if (!error) - { - generic_fillattr(inode, stat); - blk_dev = gfs_diaper_2real(inode->i_sb->s_bdev); - if (blk_dev && strcmp(current->comm, "rpc.mountd")) - stat->dev = blk_dev->bd_dev; - if (S_ISREG(inode->i_mode) && dentry->d_parent - && dentry->d_parent->d_inode) { - p_inode = igrab(dentry->d_parent->d_inode); - if (p_inode) { - pi = vn2ip(p_inode); - pi->i_dir_stats++; - iput(p_inode); - } - } - gfs_glock_dq_uninit(&gh); - } - - return error; -} - -/** - * gfs_setxattr - Set (or create or replace) an inode's extended attribute - * @dentry: - * @name: - * @data: - * @size: - * @flags: - * - * Returns: errno - */ - -int -gfs_setxattr(struct dentry *dentry, const char *name, - const void *data, size_t size, - int flags) -{ - struct gfs_ea_request er; - - atomic_inc(&vfs2sdp(dentry->d_inode->i_sb)->sd_ops_inode); - - memset(&er, 0, sizeof(struct gfs_ea_request)); - er.er_type = gfs_ea_name2type(name, &er.er_name); - if (er.er_type == GFS_EATYPE_UNUSED) - return -EOPNOTSUPP; - er.er_data = (char *)data; - er.er_name_len = strlen(er.er_name); - er.er_data_len = size; - er.er_flags = flags; - - return gfs_ea_set(vn2ip(dentry->d_inode), &er); -} - -/** - * gfs_getxattr - - * @dentry: - * @name: - * @data: - * @size: - * - * Returns: The number of bytes put into data, or -errno - */ - -ssize_t -gfs_getxattr(struct dentry *dentry, const char *name, - void *data, size_t size) -{ - struct gfs_ea_request er; - - atomic_inc(&vfs2sdp(dentry->d_inode->i_sb)->sd_ops_inode); - - memset(&er, 0, sizeof(struct gfs_ea_request)); - er.er_type = gfs_ea_name2type(name, &er.er_name); - if (er.er_type == GFS_EATYPE_UNUSED) - return -EOPNOTSUPP; - er.er_data = data; - er.er_name_len = strlen(er.er_name); - er.er_data_len = size; - - return gfs_ea_get(vn2ip(dentry->d_inode), &er); -} - -/** - * gfs_listxattr - - * @dentry: - * @buffer: - * @size: - * - * Returns: The number of bytes put into data, or -errno - */ - -ssize_t -gfs_listxattr(struct dentry *dentry, char *buffer, size_t size) -{ - struct gfs_ea_request er; - - atomic_inc(&vfs2sdp(dentry->d_inode->i_sb)->sd_ops_inode); - - memset(&er, 0, sizeof(struct gfs_ea_request)); - er.er_data = (size) ? buffer : NULL; - er.er_data_len = size; - - return gfs_ea_list(vn2ip(dentry->d_inode), &er); -} - -/** - * gfs_removexattr - - * @dentry: - * @name: - * - * Returns: errno - */ - -int -gfs_removexattr(struct dentry *dentry, const char *name) -{ - struct gfs_ea_request er; - - atomic_inc(&vfs2sdp(dentry->d_inode->i_sb)->sd_ops_inode); - - memset(&er, 0, sizeof(struct gfs_ea_request)); - er.er_type = gfs_ea_name2type(name, &er.er_name); - if (er.er_type == GFS_EATYPE_UNUSED) - return -EOPNOTSUPP; - er.er_name_len = strlen(er.er_name); - - return gfs_ea_remove(vn2ip(dentry->d_inode), &er); -} - -struct inode_operations gfs_file_iops = { - .permission = gfs_permission, - .setattr = gfs_setattr, - .getattr = gfs_getattr, - .setxattr = gfs_setxattr, - .getxattr = gfs_getxattr, - .listxattr = gfs_listxattr, - .removexattr = gfs_removexattr, -}; - -struct inode_operations gfs_dev_iops = { - .permission = gfs_permission, - .setattr = gfs_setattr, - .getattr = gfs_getattr, - .setxattr = gfs_setxattr, - .getxattr = gfs_getxattr, - .listxattr = gfs_listxattr, - .removexattr = gfs_removexattr, -}; - -struct inode_operations gfs_dir_iops = { - .create = gfs_create, - .lookup = gfs_lookup, - .link = gfs_link, - .unlink = gfs_unlink, - .symlink = gfs_symlink, - .mkdir = gfs_mkdir, - .rmdir = gfs_rmdir, - .mknod = gfs_mknod, - .rename = gfs_rename, - .permission = gfs_permission, - .setattr = gfs_setattr, - .getattr = gfs_getattr, - .setxattr = gfs_setxattr, - .getxattr = gfs_getxattr, - .listxattr = gfs_listxattr, - .removexattr = gfs_removexattr, -}; - -struct inode_operations gfs_symlink_iops = { - .readlink = gfs_readlink, - .follow_link = gfs_follow_link, - .permission = gfs_permission, - .setattr = gfs_setattr, - .getattr = gfs_getattr, - .setxattr = gfs_setxattr, - .getxattr = gfs_getxattr, - .listxattr = gfs_listxattr, - .removexattr = gfs_removexattr, -}; - diff --git a/gfs-kernel/src/gfs/ops_inode.h b/gfs-kernel/src/gfs/ops_inode.h deleted file mode 100644 index 8edb55a..0000000 --- a/gfs-kernel/src/gfs/ops_inode.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_INODE_DOT_H__ -#define __OPS_INODE_DOT_H__ - -extern struct inode_operations gfs_file_iops; -extern struct inode_operations gfs_dir_iops; -extern struct inode_operations gfs_symlink_iops; -extern struct inode_operations gfs_dev_iops; - -#endif /* __OPS_INODE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_super.c b/gfs-kernel/src/gfs/ops_super.c deleted file mode 100644 index 9acabb4..0000000 --- a/gfs-kernel/src/gfs/ops_super.c +++ /dev/null @@ -1,480 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/vmalloc.h> -#include <linux/statfs.h> -#include <linux/seq_file.h> -#include <linux/mount.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "inode.h" -#include "lm.h" -#include "log.h" -#include "ops_super.h" -#include "page.h" -#include "proc.h" -#include "quota.h" -#include "recovery.h" -#include "rgrp.h" -#include "super.h" -#include "mount.h" - -/** - * gfs_write_inode - Make sure the inode is stable on the disk - * @inode: The inode - * @sync: synchronous write flag - * - * Returns: errno - */ - -static int -gfs_write_inode(struct inode *inode, int sync) -{ - struct gfs_inode *ip = vn2ip(inode); - - atomic_inc(&ip->i_sbd->sd_ops_super); - - if (ip && sync) - gfs_log_flush_glock(ip->i_gl, 0); - - return 0; -} - -/** - * gfs_put_inode - put an inode - * @inode: The inode - * - * If i_nlink is zero, any dirty data for the inode is thrown away. - * If a process on another machine has the file open, it may need that - * data. So, sync it out. - */ - -static void -gfs_put_inode(struct inode *inode) -{ - struct gfs_sbd *sdp = vfs2sdp(inode->i_sb); - struct gfs_inode *ip = vn2ip(inode); - - atomic_inc(&sdp->sd_ops_super); - - if (ip && - !inode->i_nlink && - S_ISREG(inode->i_mode) && - !sdp->sd_args.ar_localcaching) - gfs_sync_page_i(inode, DIO_START | DIO_WAIT); -} - -/** - * gfs_put_super - Unmount the filesystem - * @sb: The VFS superblock - * - */ - -static void -gfs_put_super(struct super_block *sb) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - int error; - - if (!sdp) - return; - - atomic_inc(&sdp->sd_ops_super); - - gfs_proc_fs_del(sdp); - - /* Unfreeze the filesystem, if we need to */ - - down(&sdp->sd_freeze_lock); - if (sdp->sd_freeze_count) - gfs_glock_dq_uninit(&sdp->sd_freeze_gh); - up(&sdp->sd_freeze_lock); - - /* Kill off the inode thread */ - down(&sdp->sd_thread_lock); - clear_bit(SDF_INODED_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_inoded_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - /* Kill off the quota thread */ - down(&sdp->sd_thread_lock); - clear_bit(SDF_QUOTAD_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_quotad_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - /* Kill off the log thread */ - down(&sdp->sd_thread_lock); - clear_bit(SDF_LOGD_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_logd_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - /* Kill off the recoverd thread */ - down(&sdp->sd_thread_lock); - clear_bit(SDF_RECOVERD_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_recoverd_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - /* Kill off the glockd threads */ - clear_bit(SDF_GLOCKD_RUN, &sdp->sd_flags); - wake_up(&sdp->sd_reclaim_wchan); - while (sdp->sd_glockd_num) { - wait_for_completion(&sdp->sd_thread_completion); - sdp->sd_glockd_num--; - } - - /* Kill off the scand thread */ - down(&sdp->sd_thread_lock); - clear_bit(SDF_SCAND_RUN, &sdp->sd_flags); - wake_up_process(sdp->sd_scand_process); - up(&sdp->sd_thread_lock); - wait_for_completion(&sdp->sd_thread_completion); - - if (!test_bit(SDF_ROFS, &sdp->sd_flags)) { - error = gfs_make_fs_ro(sdp); - if (error) - gfs_io_error(sdp); - } - - /* At this point, we're through modifying the disk */ - - /* Release stuff */ - - gfs_inode_put(sdp->sd_riinode); - gfs_inode_put(sdp->sd_jiinode); - gfs_inode_put(sdp->sd_rooti); - gfs_inode_put(sdp->sd_qinode); - gfs_inode_put(sdp->sd_linode); - - gfs_glock_put(sdp->sd_trans_gl); - gfs_glock_put(sdp->sd_rename_gl); - - gfs_glock_dq_uninit(&sdp->sd_journal_gh); - - gfs_glock_dq_uninit(&sdp->sd_live_gh); - - /* Get rid of rgrp bitmap structures */ - gfs_clear_rgrpd(sdp); - gfs_clear_journals(sdp); - - /* Take apart glock structures and buffer lists */ - gfs_gl_hash_clear(sdp, TRUE); - - /* Unmount the locking protocol */ - gfs_lm_unmount(sdp); - - /* At this point, we're through participating in the lockspace */ - - gfs_clear_dirty_j(sdp); - - /* Get rid of any extra inodes */ - while (invalidate_inodes(sb)) - yield(); - - vfree(sdp); - - vfs2sdp(sb) = NULL; -} - -/** - * gfs_write_super - disk commit all incore transactions - * @sb: the filesystem - * - * This function is called every time sync(2) is called. - * After this exits, all dirty buffers and synced. - */ - -static void -gfs_write_super(struct super_block *sb) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - atomic_inc(&sdp->sd_ops_super); - gfs_log_flush(sdp); -} - -/** - * gfs_write_super_lockfs - prevent further writes to the filesystem - * @sb: the VFS structure for the filesystem - * - */ - -static void -gfs_write_super_lockfs(struct super_block *sb) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - int error; - - atomic_inc(&sdp->sd_ops_super); - - for (;;) { - error = gfs_freeze_fs(sdp); - if (!error) - break; - - switch (error) { - case -EBUSY: - printk("GFS: fsid=%s: waiting for recovery before freeze\n", - sdp->sd_fsname); - break; - - default: - printk("GFS: fsid=%s: error freezing FS: %d\n", - sdp->sd_fsname, error); - break; - } - - printk("GFS: fsid=%s: retrying...\n", sdp->sd_fsname); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - } -} - -/** - * gfs_unlockfs - reallow writes to the filesystem - * @sb: the VFS structure for the filesystem - * - */ - -static void -gfs_unlockfs(struct super_block *sb) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - - atomic_inc(&sdp->sd_ops_super); - - gfs_unfreeze_fs(sdp); -} - -/** - * gfs_statfs - Gather and return stats about the filesystem - * @sb: The superblock - * @statfsbuf: The buffer - * - * Returns: 0 on success or error code - */ - -static int -gfs_statfs(struct super_block *sb, struct kstatfs *buf) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - struct gfs_stat_gfs sg; - int error; - - atomic_inc(&sdp->sd_ops_super); - - if (gfs_tune_get(sdp, gt_statfs_fast)) - return(gfs_statfs_fast(sdp, (void *)buf)); - - error = gfs_stat_gfs(sdp, &sg, TRUE); - if (error) - return error; - - memset(buf, 0, sizeof(struct kstatfs)); - - buf->f_type = GFS_MAGIC; - buf->f_bsize = sdp->sd_sb.sb_bsize; - buf->f_blocks = sg.sg_total_blocks; - buf->f_bfree = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; - buf->f_bavail = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; - buf->f_files = sg.sg_used_dinode + sg.sg_free_dinode + - sg.sg_free_meta + sg.sg_free; - buf->f_ffree = sg.sg_free_dinode + sg.sg_free_meta + sg.sg_free; - buf->f_namelen = GFS_FNAMESIZE; - - return 0; -} - -/** - * gfs_remount_fs - called when the FS is remounted - * @sb: the filesystem - * @flags: the remount flags - * @data: extra data passed in (not used right now) - * - * Returns: errno - */ - -static int -gfs_remount_fs(struct super_block *sb, int *flags, char *data) -{ - struct gfs_sbd *sdp = vfs2sdp(sb); - struct gfs_tune *gt = &sdp->sd_tune; - int error = 0; - struct gfs_args *args; - - atomic_inc(&sdp->sd_ops_super); - - args = kmalloc(sizeof(struct gfs_args), GFP_KERNEL); - if (!args) - return -ENOMEM; - - error = gfs_make_args(data, args); - if (error) { - printk("GFS: can't parse remount arguments\n"); - goto out; - } - if (args->ar_posix_acls) { - sdp->sd_args.ar_posix_acls = TRUE; - sb->s_flags |= MS_POSIXACL; - } - else { - if (sdp->sd_args.ar_posix_acls == TRUE) - printk("GFS: remounting without ACLs\n"); - sdp->sd_args.ar_posix_acls = FALSE; - sb->s_flags &= ~MS_POSIXACL; - } - - if (args->ar_noquota) { - if (sdp->sd_args.ar_noquota == FALSE) - printk("GFS: remounting without quota\n"); - sdp->sd_args.ar_noquota = TRUE; - spin_lock(>->gt_spin); - gt->gt_quota_enforce = 0; - gt->gt_quota_account = 0; - spin_unlock(>->gt_spin); - } - else { - if (sdp->sd_args.ar_noquota == TRUE) - printk("GFS: remounting with quota\n"); - sdp->sd_args.ar_noquota = FALSE; - spin_lock(>->gt_spin); - gt->gt_quota_enforce = 1; - gt->gt_quota_account = 1; - spin_unlock(>->gt_spin); - } - - if (*flags & (MS_NOATIME | MS_NODIRATIME)) - set_bit(SDF_NOATIME, &sdp->sd_flags); - else - clear_bit(SDF_NOATIME, &sdp->sd_flags); - - if (*flags & MS_RDONLY) { - if (!test_bit(SDF_ROFS, &sdp->sd_flags)) - error = gfs_make_fs_ro(sdp); - } else if (!(*flags & MS_RDONLY) && - test_bit(SDF_ROFS, &sdp->sd_flags)) { - error = gfs_make_fs_rw(sdp); - } - - /* Don't let the VFS update atimes. GFS handles this itself. */ - *flags |= MS_NOATIME | MS_NODIRATIME; - -out: - kfree(args); - return error; -} - -/** - * gfs_clear_inode - Deallocate an inode when VFS is done with it - * @inode: The VFS inode - * - * If there's a GFS incore inode structure attached to the VFS inode: - * -- Detach them from one another. - * -- Schedule reclaim of GFS inode struct, the glock protecting it, and - * the associated iopen glock. - */ - -static void -gfs_clear_inode(struct inode *inode) -{ - struct gfs_inode *ip = vn2ip(inode); - - atomic_inc(&vfs2sdp(inode->i_sb)->sd_ops_super); - - if (ip) { - spin_lock(&ip->i_spin); - ip->i_vnode = NULL; - vn2ip(inode) = NULL; - spin_unlock(&ip->i_spin); - - gfs_glock_schedule_for_reclaim(ip->i_gl); - gfs_inode_put(ip); - } -} - -/** - * gfs_show_options - Show mount options for /proc/mounts - * @s: seq_file structure - * @mnt: vfsmount - * - * Returns: 0 on success or error code - */ - -static int -gfs_show_options(struct seq_file *s, struct vfsmount *mnt) -{ - struct gfs_sbd *sdp = vfs2sdp(mnt->mnt_sb); - struct gfs_args *args = &sdp->sd_args; - - atomic_inc(&sdp->sd_ops_super); - - if (args->ar_lockproto[0]) { - seq_printf(s, ",lockproto="); - seq_puts(s, args->ar_lockproto); - } - if (args->ar_locktable[0]) { - seq_printf(s, ",locktable="); - seq_puts(s, args->ar_locktable); - } - if (args->ar_hostdata[0]) { - seq_printf(s, ",hostdata="); - seq_puts(s, args->ar_hostdata); - } - if (args->ar_ignore_local_fs) - seq_printf(s, ",ignore_local_fs"); - if (args->ar_localflocks) - seq_printf(s, ",localflocks"); - if (args->ar_localcaching) - seq_printf(s, ",localcaching"); - if (args->ar_oopses_ok) - seq_printf(s, ",oopses_ok"); - if (args->ar_debug) - seq_printf(s, ",debug"); - if (args->ar_upgrade) - seq_printf(s, ",upgrade"); - if (args->ar_num_glockd != GFS_GLOCKD_DEFAULT) - seq_printf(s, ",num_glockd=%u", args->ar_num_glockd); - if (args->ar_posix_acls) - seq_printf(s, ",acl"); - if (args->ar_noquota) - seq_printf(s, ",noquota"); - if (args->ar_suiddir) - seq_printf(s, ",suiddir"); - - return 0; -} - -struct super_operations gfs_super_ops = { - .write_inode = gfs_write_inode, - .put_inode = gfs_put_inode, - .put_super = gfs_put_super, - .write_super = gfs_write_super, - .write_super_lockfs = gfs_write_super_lockfs, - .unlockfs = gfs_unlockfs, - .statfs = gfs_statfs, - .remount_fs = gfs_remount_fs, - .clear_inode = gfs_clear_inode, - .show_options = gfs_show_options, -}; diff --git a/gfs-kernel/src/gfs/ops_super.h b/gfs-kernel/src/gfs/ops_super.h deleted file mode 100644 index 57e9a4a..0000000 --- a/gfs-kernel/src/gfs/ops_super.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_SUPER_DOT_H__ -#define __OPS_SUPER_DOT_H__ - -extern struct super_operations gfs_super_ops; - -#endif /* __OPS_SUPER_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/ops_vm.c b/gfs-kernel/src/gfs/ops_vm.c deleted file mode 100644 index dcd5d0d..0000000 --- a/gfs-kernel/src/gfs/ops_vm.c +++ /dev/null @@ -1,238 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/mm.h> -#include <linux/pagemap.h> - -#include "gfs.h" -#include "bmap.h" -#include "glock.h" -#include "inode.h" -#include "ops_vm.h" -#include "page.h" -#include "quota.h" -#include "rgrp.h" -#include "trans.h" - -/** - * pfault_be_greedy - - * @ip: - * - */ - -static void -pfault_be_greedy(struct gfs_inode *ip) -{ - unsigned int time; - - spin_lock(&ip->i_spin); - time = ip->i_greedy; - ip->i_last_pfault = jiffies; - spin_unlock(&ip->i_spin); - - gfs_inode_hold(ip); - if (gfs_glock_be_greedy(ip->i_gl, time)) - gfs_inode_put(ip); -} - -/** - * gfs_private_nopage - - * @area: - * @address: - * @type: - * - * Returns: the page - */ - -static struct page * -gfs_private_nopage(struct vm_area_struct *area, - unsigned long address, int *type) -{ - struct gfs_inode *ip = vn2ip(area->vm_file->f_mapping->host); - struct gfs_holder i_gh; - struct page *result; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_vm); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); - if (error) - return NULL; - - set_bit(GIF_PAGED, &ip->i_flags); - - result = filemap_nopage(area, address, type); - - if (result && result != NOPAGE_OOM) - pfault_be_greedy(ip); - - gfs_glock_dq_uninit(&i_gh); - - return result; -} - -/** - * alloc_page_backing - - * @ip: - * @index: - * - * Returns: errno - */ - -static int -alloc_page_backing(struct gfs_inode *ip, unsigned long index) -{ - struct gfs_sbd *sdp = ip->i_sbd; - uint64_t lblock = index << (PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift); - unsigned int blocks = PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift; - struct gfs_alloc *al; - unsigned int x; - int error; - - al = gfs_alloc_get(ip); - - error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); - if (error) - goto out; - - error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); - if (error) - goto out_gunlock_q; - - gfs_write_calc_reserv(ip, PAGE_CACHE_SIZE, - &al->al_requested_data, &al->al_requested_meta); - - error = gfs_inplace_reserve(ip); - if (error) - goto out_gunlock_q; - - /* Trans may require: - a dinode block, RG bitmaps to allocate from, - indirect blocks, and a quota block */ - - error = gfs_trans_begin(sdp, - 1 + al->al_rgd->rd_ri.ri_length + - al->al_requested_meta, 1); - if (error) - goto out_ipres; - - if (gfs_is_stuffed(ip)) { - error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, NULL); - if (error) - goto out_trans; - } - - for (x = 0; x < blocks; ) { - uint64_t dblock; - unsigned int extlen; - int new = TRUE; - - error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); - if (error) - goto out_trans; - - lblock += extlen; - x += extlen; - } - - gfs_assert_warn(sdp, al->al_alloced_meta || al->al_alloced_data); - - out_trans: - gfs_trans_end(sdp); - - out_ipres: - gfs_inplace_release(ip); - - out_gunlock_q: - gfs_quota_unlock_m(ip); - - out: - gfs_alloc_put(ip); - - return error; -} - -/** - * gfs_sharewrite_nopage - - * @area: - * @address: - * @type: - * - * Returns: the page - */ - -static struct page * -gfs_sharewrite_nopage(struct vm_area_struct *area, - unsigned long address, int *type) -{ - struct gfs_inode *ip = vn2ip(area->vm_file->f_mapping->host); - struct gfs_holder i_gh; - struct page *result = NULL; - unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff; - int alloc_required; - int error; - - atomic_inc(&ip->i_sbd->sd_ops_vm); - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - return NULL; - - if (gfs_is_jdata(ip)) - goto out; - - set_bit(GIF_PAGED, &ip->i_flags); - set_bit(GIF_SW_PAGED, &ip->i_flags); - - error = gfs_write_alloc_required(ip, (uint64_t)index << PAGE_CACHE_SHIFT, - PAGE_CACHE_SIZE, &alloc_required); - if (error) - goto out; - - result = filemap_nopage(area, address, type); - if (!result || result == NOPAGE_OOM) - goto out; - - if (alloc_required) { - error = alloc_page_backing(ip, index); - if (error) { - page_cache_release(result); - result = NULL; - goto out; - } - set_page_dirty(result); - } - - pfault_be_greedy(ip); - - out: - gfs_glock_dq_uninit(&i_gh); - - return result; -} - -struct vm_operations_struct gfs_vm_ops_private = { - .nopage = gfs_private_nopage, -}; - -struct vm_operations_struct gfs_vm_ops_sharewrite = { - .nopage = gfs_sharewrite_nopage, -}; - diff --git a/gfs-kernel/src/gfs/ops_vm.h b/gfs-kernel/src/gfs/ops_vm.h deleted file mode 100644 index 9e6e56d..0000000 --- a/gfs-kernel/src/gfs/ops_vm.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OPS_VM_DOT_H__ -#define __OPS_VM_DOT_H__ - -extern struct vm_operations_struct gfs_vm_ops_private; -extern struct vm_operations_struct gfs_vm_ops_sharewrite; - -#endif /* __OPS_VM_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/page.c b/gfs-kernel/src/gfs/page.c deleted file mode 100644 index 692c5a9..0000000 --- a/gfs-kernel/src/gfs/page.c +++ /dev/null @@ -1,279 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/pagemap.h> -#include <linux/mm.h> - -#include "gfs.h" -#include "bmap.h" -#include "inode.h" -#include "page.h" - -/** - * gfs_inval_pte - Sync and invalidate all PTEs associated with a glock - * @gl: the glock - * - */ - -void -gfs_inval_pte(struct gfs_glock *gl) -{ - struct gfs_inode *ip; - struct inode *inode; - - ip = gl2ip(gl); - if (!ip || - ip->i_di.di_type != GFS_FILE_REG) - return; - - if (!test_bit(GIF_PAGED, &ip->i_flags)) - return; - - inode = gfs_iget(ip, NO_CREATE); - if (inode) { - unmap_shared_mapping_range(inode->i_mapping, 0, 0); - iput(inode); - - if (test_bit(GIF_SW_PAGED, &ip->i_flags)) - set_bit(GLF_DIRTY, &gl->gl_flags); - } - - clear_bit(GIF_SW_PAGED, &ip->i_flags); -} - -/** - * gfs_inval_page - Invalidate all pages associated with a glock - * @gl: the glock - * - */ - -void -gfs_inval_page(struct gfs_glock *gl) -{ - struct gfs_inode *ip; - struct inode *inode; - - ip = gl2ip(gl); - if (!ip || - ip->i_di.di_type != GFS_FILE_REG) - return; - - inode = gfs_iget(ip, NO_CREATE); - if (inode) { - struct address_space *mapping = inode->i_mapping; - - truncate_inode_pages(mapping, 0); - gfs_assert_withdraw(ip->i_sbd, !mapping->nrpages); - - iput(inode); - } - - clear_bit(GIF_PAGED, &ip->i_flags); -} - -/** - * gfs_sync_page_i - Sync the data pages (not metadata) for a struct inode - * @inode: the inode - * @flags: DIO_START | DIO_WAIT - * - */ - -void -gfs_sync_page_i(struct inode *inode, int flags) -{ - struct address_space *mapping = inode->i_mapping; - int error = 0; - - if (flags & DIO_START) - error = filemap_fdatawrite(mapping); - if (!error && (flags & DIO_WAIT)) - error = filemap_fdatawait(mapping); - - /* Find a better way to report this to the user. */ - if (error) - gfs_io_error_inode(vn2ip(inode)); -} - -/** - * gfs_sync_page - Sync the data pages (not metadata) associated with a glock - * @gl: the glock - * @flags: DIO_START | DIO_WAIT - * - * Syncs data (not metadata) for a regular file. - * No-op for all other types. - */ - -void -gfs_sync_page(struct gfs_glock *gl, int flags) -{ - struct gfs_inode *ip; - struct inode *inode; - - ip = gl2ip(gl); - if (!ip || - ip->i_di.di_type != GFS_FILE_REG) - return; - - inode = gfs_iget(ip, NO_CREATE); - if (inode) { - gfs_sync_page_i(inode, flags); - iput(inode); - } -} - -/** - * gfs_unstuffer_page - unstuff a stuffed inode into a block cached by a page - * @ip: the inode - * @dibh: the dinode buffer - * @block: the block number that was allocated - * @private: any locked page held by the caller process - * - * Returns: errno - */ - -int -gfs_unstuffer_page(struct gfs_inode *ip, struct buffer_head *dibh, - uint64_t block, void *private) -{ - struct inode *inode = ip->i_vnode; - struct page *page = (struct page *)private; - struct buffer_head *bh; - int release = FALSE; - - if (!page || page->index) { - page = grab_cache_page(inode->i_mapping, 0); - if (!page) - return -ENOMEM; - release = TRUE; - } - - if (!PageUptodate(page)) { - void *kaddr = kmap(page); - - memcpy(kaddr, - dibh->b_data + sizeof(struct gfs_dinode), - ip->i_di.di_size); - memset(kaddr + ip->i_di.di_size, - 0, - PAGE_CACHE_SIZE - ip->i_di.di_size); - kunmap(page); - - SetPageUptodate(page); - } - - if (!page_has_buffers(page)) - create_empty_buffers(page, 1 << inode->i_blkbits, - (1 << BH_Uptodate)); - - bh = page_buffers(page); - - if (!buffer_mapped(bh)) - map_bh(bh, inode->i_sb, block); - else if (gfs_assert_warn(ip->i_sbd, - bh->b_bdev == inode->i_sb->s_bdev && - bh->b_blocknr == block)) - map_bh(bh, inode->i_sb, block); - - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - - if (release) { - unlock_page(page); - page_cache_release(page); - } - - return 0; -} - -/** - * gfs_truncator_page - truncate a partial data block in the page cache - * @ip: the inode - * @size: the size the file should be - * - * Returns: errno - */ - -int -gfs_truncator_page(struct gfs_inode *ip, uint64_t size) -{ - struct inode *inode = ip->i_vnode; - struct page *page; - struct buffer_head *bh; - void *kaddr; - uint64_t lbn, dbn; - unsigned long index; - unsigned int offset; - unsigned int bufnum; - int not_new = 0; - int error; - - lbn = size >> inode->i_blkbits; - error = gfs_block_map(ip, - lbn, ¬_new, - &dbn, NULL); - if (error || !dbn) - return error; - - index = size >> PAGE_CACHE_SHIFT; - offset = size & (PAGE_CACHE_SIZE - 1); - bufnum = lbn - (index << (PAGE_CACHE_SHIFT - inode->i_blkbits)); - - /* Not in a transaction here -- a non-disk-I/O error is ok. */ - - page = read_cache_page(inode->i_mapping, index, - (filler_t *)inode->i_mapping->a_ops->readpage, - NULL); - if (IS_ERR(page)) - return PTR_ERR(page); - - lock_page(page); - - if (!PageUptodate(page) || PageError(page)) { - error = -EIO; - goto out; - } - - kaddr = kmap(page); - memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); - kunmap(page); - - if (!page_has_buffers(page)) - create_empty_buffers(page, 1 << inode->i_blkbits, - (1 << BH_Uptodate)); - - for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page) - /* Do nothing */; - - if (!buffer_mapped(bh)) - map_bh(bh, inode->i_sb, dbn); - else if (gfs_assert_warn(ip->i_sbd, - bh->b_bdev == inode->i_sb->s_bdev && - bh->b_blocknr == dbn)) - map_bh(bh, inode->i_sb, dbn); - - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - - out: - unlock_page(page); - page_cache_release(page); - - return error; -} diff --git a/gfs-kernel/src/gfs/page.h b/gfs-kernel/src/gfs/page.h deleted file mode 100644 index fd5d299..0000000 --- a/gfs-kernel/src/gfs/page.h +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __PAGE_DOT_H__ -#define __PAGE_DOT_H__ - -void gfs_inval_pte(struct gfs_glock *gl); -void gfs_inval_page(struct gfs_glock *gl); -void gfs_sync_page_i(struct inode *inode, int flags); -void gfs_sync_page(struct gfs_glock *gl, int flags); - -int gfs_unstuffer_page(struct gfs_inode *ip, struct buffer_head *dibh, - uint64_t block, void *private); -int gfs_truncator_page(struct gfs_inode *ip, uint64_t size); - -#endif /* __PAGE_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/proc.c b/gfs-kernel/src/gfs/proc.c deleted file mode 100644 index a79497b..0000000 --- a/gfs-kernel/src/gfs/proc.c +++ /dev/null @@ -1,505 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/proc_fs.h> -#include <linux/module.h> -#include <asm/uaccess.h> - -#include "gfs.h" -#include "glock.h" -#include "lm.h" -#include "proc.h" -#include "super.h" -#include "diaper.h" - -struct list_head gfs_fs_list; -struct semaphore gfs_fs_lock; -char *gfs_proc_margs; -spinlock_t gfs_proc_margs_lock; -spinlock_t req_lock; - -/** - * gfs_proc_fs_add - Add a FS to the list of mounted FSs - * @sdp: - * - */ - -void -gfs_proc_fs_add(struct gfs_sbd *sdp) -{ - down(&gfs_fs_lock); - list_add(&sdp->sd_list, &gfs_fs_list); - up(&gfs_fs_lock); -} - -/** - * gfs_proc_fs_del - Remove a FS from the list of mounted FSs - * @sdp: - * - */ - -void -gfs_proc_fs_del(struct gfs_sbd *sdp) -{ - down(&gfs_fs_lock); - list_del(&sdp->sd_list); - up(&gfs_fs_lock); -} - -/** - * do_list - Copy the list of mountes FSs to userspace - * @user_buf: - * @size: - * - * @Returns: -errno, or the number of bytes copied to userspace - */ - -static ssize_t -do_list(char *user_buf, size_t size) -{ - struct list_head *tmp; - struct gfs_sbd *sdp = NULL; - unsigned int x; - char num[21]; - char device_id[32]; - char *buf; - int error = 0; - struct block_device *bdevice; - - down(&gfs_fs_lock); - - x = 0; - for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { - sdp = list_entry(tmp, struct gfs_sbd, sd_list); - bdevice = gfs_diaper_2real(sdp->sd_vfs->s_bdev); - sprintf(device_id, "%u:%u", MAJOR(bdevice->bd_dev), - MINOR(bdevice->bd_dev)); - x += sprintf(num, "%lu", (unsigned long)sdp) + - strlen(device_id) + - strlen(sdp->sd_fsname) + 3; - } - - if (!x) - goto out; - - error = -EFBIG; - if (x > size) - goto out; - - error = -ENOMEM; - buf = kmalloc(x + 1, GFP_KERNEL); - if (!buf) - goto out; - - x = 0; - for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { - sdp = list_entry(tmp, struct gfs_sbd, sd_list); - bdevice = gfs_diaper_2real(sdp->sd_vfs->s_bdev); - sprintf(device_id, "%u:%u", MAJOR(bdevice->bd_dev), - MINOR(bdevice->bd_dev)); - x += sprintf(buf + x, "%lu %s %s\n", - (unsigned long)sdp, device_id, sdp->sd_fsname); - } - - if (copy_to_user(user_buf, buf, x)) - error = -EFAULT; - else - error = x; - - kfree(buf); - - out: - up(&gfs_fs_lock); - - return error; -} - -/** - * find_argument - - * @p: - * - * Returns: - */ - -static char * -find_argument(char *p) -{ - char *p2; - - while (*p == ' ' || *p == '\n') - p++; - if (!*p) - return NULL; - for (p2 = p; *p2; p2++) /* do nothing */; - p2--; - while (*p2 == ' ' || *p2 == '\n') - *p2-- = 0; - - return p; -} - -/** - * do_freeze - freeze a filesystem - * @p: the freeze command - * - * Returns: errno - */ - -static int -do_freeze(char *p) -{ - struct list_head *tmp; - struct gfs_sbd *sdp; - char num[21]; - int error = 0; - - p = find_argument(p + 6); - if (!p) - return -ENOENT; - - down(&gfs_fs_lock); - - for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { - sdp = list_entry(tmp, struct gfs_sbd, sd_list); - sprintf(num, "%lu", (unsigned long)sdp); - if (strcmp(num, p) == 0) - break; - } - - if (tmp == &gfs_fs_list) - error = -ENOENT; - else - error = gfs_freeze_fs(sdp); - - up(&gfs_fs_lock); - - return error; -} - -/** - * do_unfreeze - unfreeze a filesystem - * @p: the unfreeze command - * - * Returns: errno - */ - -static int -do_unfreeze(char *p) -{ - struct list_head *tmp; - struct gfs_sbd *sdp; - char num[21]; - int error = 0; - - p = find_argument(p + 8); - if (!p) - return -ENOENT; - - down(&gfs_fs_lock); - - for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { - sdp = list_entry(tmp, struct gfs_sbd, sd_list); - sprintf(num, "%lu", (unsigned long)sdp); - if (strcmp(num, p) == 0) - break; - } - - if (tmp == &gfs_fs_list) - error = -ENOENT; - else - gfs_unfreeze_fs(sdp); - - up(&gfs_fs_lock); - - return error; -} - -/** - * do_margs - Pass in mount arguments - * @p: the margs command - * - * Returns: errno - */ - -static int -do_margs(char *p) -{ - char *new_buf, *old_buf; - - p = find_argument(p + 5); - if (!p) - return -ENOENT; - - new_buf = kmalloc(strlen(p) + 1, GFP_KERNEL); - if (!new_buf) - return -ENOMEM; - strcpy(new_buf, p); - - spin_lock(&gfs_proc_margs_lock); - old_buf = gfs_proc_margs; - gfs_proc_margs = new_buf; - spin_unlock(&gfs_proc_margs_lock); - - if (old_buf) - kfree(old_buf); - - return 0; -} - -/** - * do_withdraw - withdraw a from the cluster for one filesystem - * @p: the cookie of the filesystem - * - * Returns: errno - */ - -static int -do_withdraw(char *p) -{ - struct list_head *tmp; - struct gfs_sbd *sdp; - char num[21]; - int error = 0; - - p = find_argument(p + 8); - if (!p) - return -ENOENT; - - down(&gfs_fs_lock); - - for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { - sdp = list_entry(tmp, struct gfs_sbd, sd_list); - sprintf(num, "%lu", (unsigned long)sdp); - if (strcmp(num, p) == 0) - break; - } - - if (tmp == &gfs_fs_list) - error = -ENOENT; - else - gfs_lm_withdraw(sdp, - "GFS: fsid=%s: withdrawing from cluster at user's request\n", - sdp->sd_fsname); - - up(&gfs_fs_lock); - - return error; -} - -/** - * do_lockdump - Copy out the lock hash table to userspace - * @p: the cookie of the filesystem - * @buf: - * @size: - * - * Returns: errno - */ - -static int -do_lockdump(char *p, char *buf, size_t size) -{ - struct list_head *tmp; - struct gfs_sbd *sdp; - char num[21]; - struct gfs_user_buffer ub; - int error = 0; - - p = find_argument(p + 8); - if (!p) - return -ENOENT; - - down(&gfs_fs_lock); - - for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { - sdp = list_entry(tmp, struct gfs_sbd, sd_list); - sprintf(num, "%lu", (unsigned long)sdp); - if (strcmp(num, p) == 0) - break; - } - - if (tmp == &gfs_fs_list) - error = -ENOENT; - else { - ub.ub_data = buf; - ub.ub_size = size; - ub.ub_count = 0; - - error = gfs_dump_lockstate(sdp, &ub); - if (!error) - error = ub.ub_count; - } - - up(&gfs_fs_lock); - - return error; -} - -/** - * gfs_proc_write - take a command from userspace - * @file: - * @buf: - * @size: - * @offset: - * - * Returns: -errno or the number of bytes taken - */ - -static ssize_t -gfs_proc_write(struct file *file, const char *buf, size_t size, loff_t *offset) -{ - char *p; - - spin_lock(&req_lock); - p = file->private_data; - file->private_data = NULL; - spin_unlock(&req_lock); - - if (p) - kfree(p); - - if (!size) - return -EINVAL; - - p = kmalloc(size + 1, GFP_KERNEL); - if (!p) - return -ENOMEM; - p[size] = 0; - - if (copy_from_user(p, buf, size)) { - kfree(p); - return -EFAULT; - } - - spin_lock(&req_lock); - file->private_data = p; - spin_unlock(&req_lock); - - return size; -} - -/** - * gfs_proc_read - return the results of a command - * @file: - * @buf: - * @size: - * @offset: - * - * Returns: -errno or the number of bytes returned - */ - -static ssize_t -gfs_proc_read(struct file *file, char *buf, size_t size, loff_t *offset) -{ - char *p; - int error; - - spin_lock(&req_lock); - p = file->private_data; - file->private_data = NULL; - spin_unlock(&req_lock); - - if (!p) - return -ENOENT; - - if (!size) { - kfree(p); - return -EINVAL; - } - - if (strncmp(p, "list", 4) == 0) - error = do_list(buf, size); - else if (strncmp(p, "freeze", 6) == 0) - error = do_freeze(p); - else if (strncmp(p, "unfreeze", 8) == 0) - error = do_unfreeze(p); - else if (strncmp(p, "margs", 5) == 0) - error = do_margs(p); - else if (strncmp(p, "withdraw", 8) == 0) - error = do_withdraw(p); - else if (strncmp(p, "lockdump", 8) == 0) - error = do_lockdump(p, buf, size); - else - error = -ENOSYS; - - kfree(p); - - return error; -} - -/** - * gfs_proc_close - free any mismatches writes - * @inode: - * @file: - * - * Returns: 0 - */ - -static int -gfs_proc_close(struct inode *inode, struct file *file) -{ - if (file->private_data) - kfree(file->private_data); - return 0; -} - -static struct file_operations gfs_proc_fops = -{ - .owner = THIS_MODULE, - .write = gfs_proc_write, - .read = gfs_proc_read, - .release = gfs_proc_close, -}; - -/** - * gfs_proc_init - initialize GFS' proc interface - * - */ - -void -gfs_proc_init(void) -{ - struct proc_dir_entry *pde; - - INIT_LIST_HEAD(&gfs_fs_list); - init_MUTEX(&gfs_fs_lock); - gfs_proc_margs = NULL; - spin_lock_init(&gfs_proc_margs_lock); - spin_lock_init(&req_lock); - - pde = create_proc_entry("fs/gfs", S_IFREG | 0600, NULL); - if (pde) { - pde->owner = THIS_MODULE; - pde->proc_fops = &gfs_proc_fops; - } -} - -/** - * gfs_proc_uninit - uninitialize GFS' proc interface - * - */ - -void -gfs_proc_uninit(void) -{ - if (gfs_proc_margs) - kfree(gfs_proc_margs); - remove_proc_entry("fs/gfs", NULL); -} - diff --git a/gfs-kernel/src/gfs/proc.h b/gfs-kernel/src/gfs/proc.h deleted file mode 100644 index 132d1cc..0000000 --- a/gfs-kernel/src/gfs/proc.h +++ /dev/null @@ -1,27 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __PROC_DOT_H__ -#define __PROC_DOT_H__ - -/* Allow args to be passed to GFS when using an initial ram disk */ -extern char *gfs_proc_margs; -extern spinlock_t gfs_proc_margs_lock; - -void gfs_proc_fs_add(struct gfs_sbd *sdp); -void gfs_proc_fs_del(struct gfs_sbd *sdp); - -void gfs_proc_init(void); -void gfs_proc_uninit(void); - -#endif /* __PROC_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/quota.c b/gfs-kernel/src/gfs/quota.c deleted file mode 100644 index 0e91a34..0000000 --- a/gfs-kernel/src/gfs/quota.c +++ /dev/null @@ -1,1152 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/tty.h> - -#include "gfs.h" -#include "bmap.h" -#include "file.h" -#include "glock.h" -#include "glops.h" -#include "log.h" -#include "quota.h" -#include "rgrp.h" -#include "super.h" -#include "trans.h" - -/** - * gfs_quota_get - Get a structure to represent a quota change - * @sdp: the filesystem - * @user: TRUE if this is a user quota - * @id: the uid or gid - * @create: if TRUE, create the structure, otherwise return NULL - * @qdp: the returned quota structure - * - * Returns: errno - */ - -int -gfs_quota_get(struct gfs_sbd *sdp, int user, uint32_t id, int create, - struct gfs_quota_data **qdp) -{ - struct gfs_quota_data *qd = NULL, *new_qd = NULL; - struct list_head *tmp, *head; - int error; - - *qdp = NULL; - - for (;;) { - spin_lock(&sdp->sd_quota_lock); - - for (head = &sdp->sd_quota_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - qd = list_entry(tmp, struct gfs_quota_data, qd_list); - if (qd->qd_id == id && - !test_bit(QDF_USER, &qd->qd_flags) == !user) { - qd->qd_count++; - break; - } - } - - if (tmp == head) - qd = NULL; - - if (!qd && new_qd) { - qd = new_qd; - list_add(&qd->qd_list, &sdp->sd_quota_list); - new_qd = NULL; - } - - spin_unlock(&sdp->sd_quota_lock); - - if (qd || !create) { - if (new_qd) { - gfs_lvb_unhold(new_qd->qd_gl); - kfree(new_qd); - atomic_dec(&sdp->sd_quota_count); - } - *qdp = qd; - return 0; - } - - new_qd = kmalloc(sizeof(struct gfs_quota_data), GFP_KERNEL); - if (!new_qd) - return -ENOMEM; - memset(new_qd, 0, sizeof(struct gfs_quota_data)); - - new_qd->qd_count = 1; - - new_qd->qd_id = id; - if (user) - set_bit(QDF_USER, &new_qd->qd_flags); - - INIT_LIST_HEAD(&new_qd->qd_le_list); - - error = gfs_glock_get(sdp, 2 * (uint64_t)id + ((user) ? 0 : 1), - &gfs_quota_glops, CREATE, - &new_qd->qd_gl); - if (error) { - kfree(new_qd); - return error; - } - - error = gfs_lvb_hold(new_qd->qd_gl); - - gfs_glock_put(new_qd->qd_gl); - - if (error) { - kfree(new_qd); - return error; - } - - atomic_inc(&sdp->sd_quota_count); - } -} - -/** - * gfs_quota_hold - increment the usage count on a struct gfs_quota_data - * @sdp: the filesystem - * @qd: the structure - * - */ - -void -gfs_quota_hold(struct gfs_sbd *sdp, struct gfs_quota_data *qd) -{ - spin_lock(&sdp->sd_quota_lock); - gfs_assert(sdp, qd->qd_count,); - qd->qd_count++; - spin_unlock(&sdp->sd_quota_lock); -} - -/** - * gfs_quota_put - decrement the usage count on a struct gfs_quota_data - * @sdp: the filesystem - * @qd: the structure - * - * Free the structure if its reference count hits zero. - * - */ - -void -gfs_quota_put(struct gfs_sbd *sdp, struct gfs_quota_data *qd) -{ - spin_lock(&sdp->sd_quota_lock); - gfs_assert(sdp, qd->qd_count,); - qd->qd_count--; - spin_unlock(&sdp->sd_quota_lock); -} - -/** - * quota_find - Find a quota change to sync to the quota file - * @sdp: the filesystem - * - * The returned structure is locked and needs to be unlocked - * with quota_unlock(). - * - * Returns: A quota structure, or NULL - */ - -static struct gfs_quota_data * -quota_find(struct gfs_sbd *sdp) -{ - struct list_head *tmp, *head; - struct gfs_quota_data *qd = NULL; - - if (test_bit(SDF_ROFS, &sdp->sd_flags)) - return NULL; - - gfs_log_lock(sdp); - spin_lock(&sdp->sd_quota_lock); - - if (!atomic_read(&sdp->sd_quota_od_count)) - goto out; - - for (head = &sdp->sd_quota_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - qd = list_entry(tmp, struct gfs_quota_data, qd_list); - - if (test_bit(QDF_LOCK, &qd->qd_flags)) - continue; - if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) - continue; - if (qd->qd_sync_gen >= sdp->sd_quota_sync_gen) - continue; - - list_move_tail(&qd->qd_list, &sdp->sd_quota_list); - - set_bit(QDF_LOCK, &qd->qd_flags); - qd->qd_count++; - qd->qd_change_sync = qd->qd_change_od; - - goto out; - } - - qd = NULL; - - out: - spin_unlock(&sdp->sd_quota_lock); - gfs_log_unlock(sdp); - - return qd; -} - -/** - * quota_trylock - Try to lock a given quota entry - * @sdp: the filesystem - * @qd: the quota data structure - * - * Returns: TRUE if the lock was successful, FALSE, otherwise - */ - -static int -quota_trylock(struct gfs_sbd *sdp, struct gfs_quota_data *qd) -{ - int ret = FALSE; - - if (test_bit(SDF_ROFS, &sdp->sd_flags)) - return FALSE; - - gfs_log_lock(sdp); - spin_lock(&sdp->sd_quota_lock); - - if (test_bit(QDF_LOCK, &qd->qd_flags)) - goto out; - if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) - goto out; - - list_move_tail(&qd->qd_list, &sdp->sd_quota_list); - - set_bit(QDF_LOCK, &qd->qd_flags); - qd->qd_count++; - qd->qd_change_sync = qd->qd_change_od; - - ret = TRUE; - - out: - spin_unlock(&sdp->sd_quota_lock); - gfs_log_unlock(sdp); - - return ret; -} - -/** - * quota_unlock - drop and a reference on a quota structure - * @sdp: the filesystem - * @qd: the quota inode structure - * - */ - -static void -quota_unlock(struct gfs_sbd *sdp, struct gfs_quota_data *qd) -{ - spin_lock(&sdp->sd_quota_lock); - - gfs_assert_warn(sdp, test_bit(QDF_LOCK, &qd->qd_flags)); - clear_bit(QDF_LOCK, &qd->qd_flags); - - gfs_assert(sdp, qd->qd_count,); - qd->qd_count--; - - spin_unlock(&sdp->sd_quota_lock); -} - -/** - * gfs_quota_merge - add/remove a quota change from the in-memory list - * @sdp: the filesystem - * @tag: the quota change tag - * - * Returns: errno - */ - -int -gfs_quota_merge(struct gfs_sbd *sdp, struct gfs_quota_tag *tag) -{ - struct gfs_quota_data *qd; - int error; - - error = gfs_quota_get(sdp, - tag->qt_flags & GFS_QTF_USER, tag->qt_id, - CREATE, &qd); - if (error) - return error; - - gfs_assert(sdp, qd->qd_change_ic == qd->qd_change_od,); - - gfs_log_lock(sdp); - - qd->qd_change_ic += tag->qt_change; - qd->qd_change_od += tag->qt_change; - - if (qd->qd_change_od) { - if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) { - gfs_quota_hold(sdp, qd); - set_bit(QDF_OD_LIST, &qd->qd_flags); - atomic_inc(&sdp->sd_quota_od_count); - } - } else { - gfs_assert_warn(sdp, test_bit(QDF_OD_LIST, &qd->qd_flags)); - clear_bit(QDF_OD_LIST, &qd->qd_flags); - gfs_quota_put(sdp, qd); - gfs_assert(sdp, atomic_read(&sdp->sd_quota_od_count) > 0,); - atomic_dec(&sdp->sd_quota_od_count); - } - - gfs_log_unlock(sdp); - - gfs_quota_put(sdp, qd); - - return 0; -} - -/** - * gfs_quota_scan - Look for unused struct gfs_quota_data structures to throw away - * @sdp: the filesystem - * - */ - -void -gfs_quota_scan(struct gfs_sbd *sdp) -{ - struct list_head *head, *tmp, *next; - struct gfs_quota_data *qd; - LIST_HEAD(dead); - - spin_lock(&sdp->sd_quota_lock); - - for (head = &sdp->sd_quota_list, tmp = head->next, next = tmp->next; - tmp != head; - tmp = next, next = next->next) { - qd = list_entry(tmp, struct gfs_quota_data, qd_list); - if (!qd->qd_count) - list_move(&qd->qd_list, &dead); - } - - spin_unlock(&sdp->sd_quota_lock); - - while (!list_empty(&dead)) { - qd = list_entry(dead.next, struct gfs_quota_data, qd_list); - - gfs_assert_warn(sdp, !qd->qd_count); - gfs_assert_warn(sdp, !test_bit(QDF_OD_LIST, &qd->qd_flags) && - !test_bit(QDF_LOCK, &qd->qd_flags)); - gfs_assert_warn(sdp, !qd->qd_change_new && !qd->qd_change_ic && - !qd->qd_change_od); - - list_del(&qd->qd_list); - gfs_lvb_unhold(qd->qd_gl); - kfree(qd); - atomic_dec(&sdp->sd_quota_count); - } -} - -/** - * gfs_quota_cleanup - get rid of any extra struct gfs_quota_data structures - * @sdp: the filesystem - * - */ - -void -gfs_quota_cleanup(struct gfs_sbd *sdp) -{ - struct gfs_quota_data *qd; - - restart: - gfs_log_lock(sdp); - - spin_lock(&sdp->sd_quota_lock); - - while (!list_empty(&sdp->sd_quota_list)) { - qd = list_entry(sdp->sd_quota_list.next, - struct gfs_quota_data, - qd_list); - - if (qd->qd_count > 1) { - spin_unlock(&sdp->sd_quota_lock); - gfs_log_unlock(sdp); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - goto restart; - - } else if (qd->qd_count) { - gfs_assert_warn(sdp, - test_bit(QDF_OD_LIST, &qd->qd_flags) && - !test_bit(QDF_LOCK, &qd->qd_flags)); - gfs_assert_warn(sdp, qd->qd_change_od && - qd->qd_change_od == qd->qd_change_ic); - gfs_assert_warn(sdp, !qd->qd_change_new); - - list_del(&qd->qd_list); - atomic_dec(&sdp->sd_quota_od_count); - - spin_unlock(&sdp->sd_quota_lock); - gfs_lvb_unhold(qd->qd_gl); - kfree(qd); - atomic_dec(&sdp->sd_quota_count); - spin_lock(&sdp->sd_quota_lock); - - } else { - gfs_assert_warn(sdp, - !test_bit(QDF_OD_LIST, &qd->qd_flags) && - !test_bit(QDF_LOCK, &qd->qd_flags)); - gfs_assert_warn(sdp, !qd->qd_change_new && - !qd->qd_change_ic && - !qd->qd_change_od); - - list_del(&qd->qd_list); - - spin_unlock(&sdp->sd_quota_lock); - gfs_lvb_unhold(qd->qd_gl); - kfree(qd); - atomic_dec(&sdp->sd_quota_count); - spin_lock(&sdp->sd_quota_lock); - } - } - - spin_unlock(&sdp->sd_quota_lock); - - gfs_assert(sdp, !atomic_read(&sdp->sd_quota_od_count),); - - gfs_log_unlock(sdp); -} - -/** - * sort_qd - figure out the order between two quota data structures - * @a: first quota data structure - * @b: second quota data structure - * - * Returns: -1 if @a comes before @b, 0 if @a equals @b, 1 if @b comes before @a - */ - -static int -sort_qd(const void *a, const void *b) -{ - struct gfs_quota_data *qd_a = *(struct gfs_quota_data **)a; - struct gfs_quota_data *qd_b = *(struct gfs_quota_data **)b; - int ret = 0; - - if (!test_bit(QDF_USER, &qd_a->qd_flags) != - !test_bit(QDF_USER, &qd_b->qd_flags)) { - if (test_bit(QDF_USER, &qd_a->qd_flags)) - ret = -1; - else - ret = 1; - } else { - if (qd_a->qd_id < qd_b->qd_id) - ret = -1; - else if (qd_a->qd_id > qd_b->qd_id) - ret = 1; - } - - return ret; -} - -/** - * do_quota_sync - Sync a bunch quota changes to the quota file - * @sdp: the filesystem - * @qda: an array of struct gfs_quota_data structures to be synced - * @num_qd: the number of elements in @qda - * - * Returns: errno - */ - -static int -do_quota_sync(struct gfs_sbd *sdp, struct gfs_quota_data **qda, - unsigned int num_qd) -{ - struct gfs_inode *ip = sdp->sd_qinode; - struct gfs_alloc *al = NULL; - struct gfs_holder i_gh, *ghs; - struct gfs_quota q; - char buf[sizeof(struct gfs_quota)]; - uint64_t offset; - unsigned int qx, x; - int ar; - unsigned int nalloc = 0; - unsigned int data_blocks, ind_blocks; - int error; - - gfs_write_calc_reserv(ip, sizeof(struct gfs_quota), &data_blocks, - &ind_blocks); - - ghs = kmalloc(num_qd * sizeof(struct gfs_holder), GFP_KERNEL); - if (!ghs) - return -ENOMEM; - - gfs_sort(qda, num_qd, sizeof (struct gfs_quota_data *), sort_qd); - for (qx = 0; qx < num_qd; qx++) { - error = gfs_glock_nq_init(qda[qx]->qd_gl, - LM_ST_EXCLUSIVE, - GL_NOCACHE, &ghs[qx]); - if (error) - goto fail; - } - - error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); - if (error) - goto fail; - - for (x = 0; x < num_qd; x++) { - offset = (2 * (uint64_t)qda[x]->qd_id + - ((test_bit(QDF_USER, &qda[x]->qd_flags)) ? 0 : 1)) * - sizeof(struct gfs_quota); - - error = gfs_write_alloc_required(ip, offset, - sizeof(struct gfs_quota), - &ar); - if (error) - goto fail_gunlock; - - if (ar) - nalloc++; - } - - if (nalloc) { - al = gfs_alloc_get(ip); - - error = - gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, - NO_QUOTA_CHANGE); - if (error) - goto fail_alloc; - - al->al_requested_meta = nalloc * (data_blocks + ind_blocks); - - error = gfs_inplace_reserve(ip); - if (error) - goto fail_qs; - - /* Trans may require: - two (journaled) data blocks, a dinode block, RG bitmaps to allocate from, - indirect blocks, and a quota block */ - - error = gfs_trans_begin(sdp, - 1 + al->al_rgd->rd_ri.ri_length + - num_qd * data_blocks + - nalloc * ind_blocks, - gfs_struct2blk(sdp, num_qd + 2, - sizeof(struct gfs_quota_tag))); - if (error) - goto fail_ipres; - } else { - /* Trans may require: - Data blocks, a dinode block, and quota blocks */ - - error = gfs_trans_begin(sdp, - 1 + data_blocks * num_qd, - gfs_struct2blk(sdp, num_qd, - sizeof(struct gfs_quota_tag))); - if (error) - goto fail_gunlock; - } - - for (x = 0; x < num_qd; x++) { - offset = (2 * (uint64_t)qda[x]->qd_id + - ((test_bit(QDF_USER, &qda[x]->qd_flags)) ? 0 : 1)) * - sizeof(struct gfs_quota); - - /* The quota file may not be a multiple of sizeof(struct gfs_quota) bytes. */ - memset(buf, 0, sizeof(struct gfs_quota)); - - error = gfs_internal_read(ip, buf, offset, - sizeof(struct gfs_quota)); - if (error < 0) - goto fail_end_trans; - - gfs_quota_in(&q, buf); - q.qu_value += qda[x]->qd_change_sync; - gfs_quota_out(&q, buf); - - error = gfs_internal_write(ip, buf, offset, - sizeof(struct gfs_quota)); - if (error < 0) - goto fail_end_trans; - else if (error != sizeof(struct gfs_quota)) { - error = -EIO; - goto fail_end_trans; - } - - if (test_bit(QDF_USER, &qda[x]->qd_flags)) - gfs_trans_add_quota(sdp, -qda[x]->qd_change_sync, - qda[x]->qd_id, NO_QUOTA_CHANGE); - else - gfs_trans_add_quota(sdp, -qda[x]->qd_change_sync, - NO_QUOTA_CHANGE, qda[x]->qd_id); - - memset(&qda[x]->qd_qb, 0, sizeof(struct gfs_quota_lvb)); - qda[x]->qd_qb.qb_magic = GFS_MAGIC; - qda[x]->qd_qb.qb_limit = q.qu_limit; - qda[x]->qd_qb.qb_warn = q.qu_warn; - qda[x]->qd_qb.qb_value = q.qu_value; - - gfs_quota_lvb_out(&qda[x]->qd_qb, qda[x]->qd_gl->gl_lvb); - } - - gfs_trans_end(sdp); - - if (nalloc) { - gfs_assert_warn(sdp, al->al_alloced_meta); - gfs_inplace_release(ip); - gfs_quota_unhold_m(ip); - gfs_alloc_put(ip); - } - - gfs_glock_dq_uninit(&i_gh); - - for (x = 0; x < num_qd; x++) - gfs_glock_dq_uninit(&ghs[x]); - - kfree(ghs); - - gfs_log_flush_glock(ip->i_gl, 0); - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_ipres: - if (nalloc) - gfs_inplace_release(ip); - - fail_qs: - if (nalloc) - gfs_quota_unhold_m(ip); - - fail_alloc: - if (nalloc) - gfs_alloc_put(ip); - - fail_gunlock: - gfs_glock_dq_uninit(&i_gh); - - fail: - while (qx--) - gfs_glock_dq_uninit(&ghs[qx]); - - kfree(ghs); - - return error; -} - -/** - * glock_q - Acquire a lock for a quota entry - * @sdp: the filesystem - * @qd: the quota data structure to glock - * @force_refresh: If TRUE, always read from the quota file - * @q_gh: the glock holder for the quota lock - * - * Returns: errno - */ - -static int -glock_q(struct gfs_sbd *sdp, struct gfs_quota_data *qd, int force_refresh, - struct gfs_holder *q_gh) -{ - struct gfs_holder i_gh; - struct gfs_quota q; - char buf[sizeof(struct gfs_quota)]; - int error; - - restart: - error = gfs_glock_nq_init(qd->qd_gl, LM_ST_SHARED, 0, q_gh); - if (error) - return error; - - gfs_quota_lvb_in(&qd->qd_qb, qd->qd_gl->gl_lvb); - - if (force_refresh || - qd->qd_qb.qb_magic != GFS_MAGIC) { - gfs_glock_dq_uninit(q_gh); - error = gfs_glock_nq_init(qd->qd_gl, - LM_ST_EXCLUSIVE, GL_NOCACHE, - q_gh); - if (error) - return error; - - error = gfs_glock_nq_init(sdp->sd_qinode->i_gl, - LM_ST_SHARED, 0, - &i_gh); - if (error) - goto fail; - - memset(buf, 0, sizeof(struct gfs_quota)); - - error = gfs_internal_read(sdp->sd_qinode, buf, - (2 * (uint64_t)qd->qd_id + - ((test_bit(QDF_USER, &qd->qd_flags)) ? 0 : 1)) * - sizeof(struct gfs_quota), - sizeof(struct gfs_quota)); - if (error < 0) - goto fail_gunlock; - - gfs_glock_dq_uninit(&i_gh); - - gfs_quota_in(&q, buf); - - memset(&qd->qd_qb, 0, sizeof(struct gfs_quota_lvb)); - qd->qd_qb.qb_magic = GFS_MAGIC; - qd->qd_qb.qb_limit = q.qu_limit; - qd->qd_qb.qb_warn = q.qu_warn; - qd->qd_qb.qb_value = q.qu_value; - - gfs_quota_lvb_out(&qd->qd_qb, qd->qd_gl->gl_lvb); - - gfs_glock_dq_uninit(q_gh); - force_refresh = FALSE; - goto restart; - } - - return 0; - - fail_gunlock: - gfs_glock_dq_uninit(&i_gh); - - fail: - gfs_glock_dq_uninit(q_gh); - - return error; -} - -/** - * gfs_quota_hold_m - Hold the quota structures for up to 4 IDs - * @ip: Two of the IDs are the UID and GID from this file - * @uid: a UID or the constant NO_QUOTA_CHANGE - * @gid: a GID or the constant NO_QUOTA_CHANGE - * - * The struct gfs_quota_data structures representing the locks are - * stored in the ip->i_alloc->al_qd array. - * - * Returns: errno - */ - -int -gfs_quota_hold_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - unsigned int x = 0; - int error; - - if (gfs_assert_warn(sdp, !al->al_qd_num && - !test_bit(GIF_QD_LOCKED, &ip->i_flags))) - return -EIO; - - if (!gfs_tune_get(sdp, gt_quota_account)) - return 0; - - error = gfs_quota_get(sdp, TRUE, ip->i_di.di_uid, - CREATE, &al->al_qd[x]); - if (error) - goto fail; - x++; - - error = gfs_quota_get(sdp, FALSE, ip->i_di.di_gid, - CREATE, &al->al_qd[x]); - if (error) - goto fail; - x++; - - if (uid != NO_QUOTA_CHANGE) { - error = gfs_quota_get(sdp, TRUE, uid, - CREATE, &al->al_qd[x]); - if (error) - goto fail; - x++; - } - - if (gid != NO_QUOTA_CHANGE) { - error = gfs_quota_get(sdp, FALSE, gid, - CREATE, &al->al_qd[x]); - if (error) - goto fail; - x++; - } - - al->al_qd_num = x; - - return 0; - - fail: - if (x) { - al->al_qd_num = x; - gfs_quota_unhold_m(ip); - } - - return error; -} - -/** - * gfs_quota_unhold_m - throw away some quota locks - * @ip: the inode who's ip->i_alloc->al_qd array holds the structures - * - */ - -void -gfs_quota_unhold_m(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - unsigned int x; - - gfs_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); - - for (x = 0; x < al->al_qd_num; x++) { - gfs_quota_put(sdp, al->al_qd[x]); - al->al_qd[x] = NULL; - } - al->al_qd_num = 0; -} - -/** - * gfs_quota_lock_m - Acquire the quota locks for up to 4 IDs - * @ip: Two of the IDs are the UID and GID from this file - * @uid: a UID or the constant NO_QUOTA_CHANGE - * @gid: a GID or the constant NO_QUOTA_CHANGE - * - * The struct gfs_quota_data structures representing the locks are - * stored in the ip->i_alloc->al_qd array. - * - * Returns: errno - */ - -int -gfs_quota_lock_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - unsigned int x; - int error; - - gfs_quota_hold_m(ip, uid, gid); - - if (!gfs_tune_get(sdp, gt_quota_enforce)) - return 0; - if (capable(CAP_SYS_RESOURCE)) - return 0; - - gfs_sort(al->al_qd, al->al_qd_num, - sizeof(struct gfs_quota_data *), sort_qd); - - for (x = 0; x < al->al_qd_num; x++) { - error = glock_q(sdp, al->al_qd[x], FALSE, &al->al_qd_ghs[x]); - if (error) - goto fail; - } - - set_bit(GIF_QD_LOCKED, &ip->i_flags); - - return 0; - - fail: - while (x--) - gfs_glock_dq_uninit(&al->al_qd_ghs[x]); - - return error; -} - -/** - * gfs_quota_unlock_m - drop some quota locks - * @ip: the inode who's ip->i_alloc->al_qd array holds the locks - * - */ - -void -gfs_quota_unlock_m(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - struct gfs_quota_data *qd, *qda[4]; - int64_t value; - unsigned int count = 0; - unsigned int x; - int do_sync; - - if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) - goto out; - - for (x = 0; x < al->al_qd_num; x++) { - qd = al->al_qd[x]; - - spin_lock(&sdp->sd_quota_lock); - value = qd->qd_change_new + qd->qd_change_ic; - spin_unlock(&sdp->sd_quota_lock); - - do_sync = TRUE; - if (!qd->qd_qb.qb_limit) - do_sync = FALSE; - else if (qd->qd_qb.qb_value >= (int64_t)qd->qd_qb.qb_limit) - do_sync = FALSE; - else { - struct gfs_tune *gt = &sdp->sd_tune; - unsigned int num, den; - int64_t v; - - spin_lock(>->gt_spin); - num = gt->gt_quota_scale_num; - den = gt->gt_quota_scale_den; - spin_unlock(>->gt_spin); - - v = value * gfs_num_journals(sdp) * num; - do_div(v, den); - v += qd->qd_qb.qb_value; - if (v < (int64_t)qd->qd_qb.qb_limit) - do_sync = FALSE; - } - - gfs_glock_dq_uninit(&al->al_qd_ghs[x]); - - if (do_sync) { - gfs_log_flush(sdp); - if (quota_trylock(sdp, qd)) - qda[count++] = qd; - } - } - - if (count) { - do_quota_sync(sdp, qda, count); - - for (x = 0; x < count; x++) - quota_unlock(sdp, qda[x]); - } - - out: - gfs_quota_unhold_m(ip); -} - -/** - * print_quota_message - print a message to the user's tty about quotas - * @sdp: the filesystem - * @qd: the quota ID that the message is about - * @type: the type of message ("exceeded" or "warning") - * - * Returns: errno - */ - -static int -print_quota_message(struct gfs_sbd *sdp, struct gfs_quota_data *qd, char *type) -{ - struct tty_struct *tty; - char *line; - int len; - - line = kmalloc(256, GFP_KERNEL); - if (!line) - return -ENOMEM; - - len = snprintf(line, 256, "GFS: fsid=%s: quota %s for %s %u\r\n", - sdp->sd_fsname, type, - (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group", - qd->qd_id); - - if (current->signal) { - tty = current->signal->tty; - if (tty && tty->driver->write) - tty->driver->write(tty, 0, line, len); - } - - kfree(line); - - return 0; -} - -/** - * gfs_quota_check - Check to see if a block allocation is possible - * @ip: the inode who's ip->i_res.ir_qd array holds the quota locks - * @uid: the UID the block is allocated for - * @gid: the GID the block is allocated for - * - */ - -int -gfs_quota_check(struct gfs_inode *ip, uint32_t uid, uint32_t gid) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - struct gfs_quota_data *qd; - int64_t value; - unsigned int x; - int error = 0; - - if (!al) - return 0; - - if (!gfs_tune_get(sdp, gt_quota_enforce)) - return 0; - - for (x = 0; x < al->al_qd_num; x++) { - qd = al->al_qd[x]; - - if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || - (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) - continue; - - spin_lock(&sdp->sd_quota_lock); - value = qd->qd_change_new + qd->qd_change_ic; - spin_unlock(&sdp->sd_quota_lock); - value += qd->qd_qb.qb_value; - - if (qd->qd_qb.qb_limit && (int64_t)qd->qd_qb.qb_limit < value) { - print_quota_message(sdp, qd, "exceeded"); - error = -EDQUOT; - break; - } else if (qd->qd_qb.qb_warn && - (int64_t)qd->qd_qb.qb_warn < value && - time_after_eq(jiffies, - qd->qd_last_warn + - gfs_tune_get(sdp, gt_quota_warn_period) * HZ)) { - error = print_quota_message(sdp, qd, "warning"); - qd->qd_last_warn = jiffies; - } - } - - return error; -} - -/** - * gfs_quota_sync - Sync quota changes to the quota file - * @sdp: the filesystem - * - * Returns: errno - */ - -int -gfs_quota_sync(struct gfs_sbd *sdp) -{ - struct gfs_quota_data **qda; - unsigned int max_qd = gfs_tune_get(sdp, gt_quota_simul_sync); - unsigned int num_qd; - unsigned int x; - int error = 0; - - sdp->sd_quota_sync_gen++; - - qda = kmalloc(max_qd * sizeof(struct gfs_quota_data *), GFP_KERNEL); - if (!qda) - return -ENOMEM; - memset(qda, 0, max_qd * sizeof(struct gfs_quota_data *)); - - do { - num_qd = 0; - - for (;;) { - qda[num_qd] = quota_find(sdp); - if (!qda[num_qd]) - break; - - if (++num_qd == max_qd) - break; - } - - if (num_qd) { - error = do_quota_sync(sdp, qda, num_qd); - if (!error) - for (x = 0; x < num_qd; x++) - qda[x]->qd_sync_gen = - sdp->sd_quota_sync_gen; - - for (x = 0; x < num_qd; x++) - quota_unlock(sdp, qda[x]); - } - } - while (!error && num_qd == max_qd); - - kfree(qda); - - return error; -} - -/** - * gfs_quota_refresh - Refresh the LVB for a given quota ID - * @sdp: the filesystem - * @user: - * @id: - * - * Returns: errno - */ - -int -gfs_quota_refresh(struct gfs_sbd *sdp, int user, uint32_t id) -{ - struct gfs_quota_data *qd; - struct gfs_holder q_gh; - int error; - - error = gfs_quota_get(sdp, user, id, CREATE, &qd); - if (error) - return error; - - error = glock_q(sdp, qd, TRUE, &q_gh); - if (!error) - gfs_glock_dq_uninit(&q_gh); - - gfs_quota_put(sdp, qd); - - return error; -} - -/** - * gfs_quota_read - Read the info a given quota ID - * @sdp: the filesystem - * @user: - * @id: - * @q: - * - * Returns: errno - */ - -int -gfs_quota_read(struct gfs_sbd *sdp, int user, uint32_t id, - struct gfs_quota *q) -{ - struct gfs_quota_data *qd; - struct gfs_holder q_gh; - int error; - - if (((user) ? (id != current->fsuid) : (!in_group_p(id))) && - !capable(CAP_SYS_ADMIN)) - return -EACCES; - - error = gfs_quota_get(sdp, user, id, CREATE, &qd); - if (error) - return error; - - error = glock_q(sdp, qd, FALSE, &q_gh); - if (error) - goto out; - - memset(q, 0, sizeof(struct gfs_quota)); - q->qu_limit = qd->qd_qb.qb_limit; - q->qu_warn = qd->qd_qb.qb_warn; - q->qu_value = qd->qd_qb.qb_value; - - spin_lock(&sdp->sd_quota_lock); - q->qu_value += qd->qd_change_new + qd->qd_change_ic; - spin_unlock(&sdp->sd_quota_lock); - - gfs_glock_dq_uninit(&q_gh); - - out: - gfs_quota_put(sdp, qd); - - return error; -} diff --git a/gfs-kernel/src/gfs/quota.h b/gfs-kernel/src/gfs/quota.h deleted file mode 100644 index 8a12fff..0000000 --- a/gfs-kernel/src/gfs/quota.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __QUOTA_DOT_H__ -#define __QUOTA_DOT_H__ - -#define NO_QUOTA_CHANGE ((uint32_t)-1) - -int gfs_quota_get(struct gfs_sbd *sdp, int user, uint32_t id, int create, - struct gfs_quota_data **qdp); -void gfs_quota_hold(struct gfs_sbd *sdp, struct gfs_quota_data *qd); -void gfs_quota_put(struct gfs_sbd *sdp, struct gfs_quota_data *qd); - -int gfs_quota_merge(struct gfs_sbd *sdp, struct gfs_quota_tag *tag); -void gfs_quota_scan(struct gfs_sbd *sdp); -void gfs_quota_cleanup(struct gfs_sbd *sdp); - -int gfs_quota_hold_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid); -void gfs_quota_unhold_m(struct gfs_inode *ip); - -int gfs_quota_lock_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid); -void gfs_quota_unlock_m(struct gfs_inode *ip); - -int gfs_quota_check(struct gfs_inode *ip, uint32_t uid, uint32_t gid); - -int gfs_quota_sync(struct gfs_sbd *sdp); -int gfs_quota_refresh(struct gfs_sbd *sdp, int user, uint32_t id); -int gfs_quota_read(struct gfs_sbd *sdp, int user, uint32_t id, - struct gfs_quota *q); - -#endif /* __QUOTA_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/recovery.c b/gfs-kernel/src/gfs/recovery.c deleted file mode 100644 index 2ecee04..0000000 --- a/gfs-kernel/src/gfs/recovery.c +++ /dev/null @@ -1,783 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "glops.h" -#include "lm.h" -#include "log.h" -#include "lops.h" -#include "recovery.h" - -#define bn2seg(bn) (((uint32_t)((bn) - jdesc->ji_addr)) / sdp->sd_sb.sb_seg_size) -#define seg2bn(seg) ((seg) * sdp->sd_sb.sb_seg_size + jdesc->ji_addr) - -struct dirty_j { - struct list_head dj_list; - unsigned int dj_jid; - struct gfs_jindex dj_desc; -}; - -/** - * gfs_add_dirty_j - add a jid to the list of dirty journals - * @sdp: the filesystem - * @jid: the journal ID number - * - */ - -void -gfs_add_dirty_j(struct gfs_sbd *sdp, unsigned int jid) -{ - struct dirty_j *dj; - - dj = gmalloc(sizeof(struct dirty_j)); - memset(dj, 0, sizeof(struct dirty_j)); - - dj->dj_jid = jid; - - spin_lock(&sdp->sd_dirty_j_lock); - list_add(&dj->dj_list, &sdp->sd_dirty_j); - spin_unlock(&sdp->sd_dirty_j_lock); -} - -/** - * get_dirty_j - return a dirty journal from the list - * @sdp: the filesystem - * - * Returns: a struct dirty_j or NULL - */ - -static struct dirty_j * -get_dirty_j(struct gfs_sbd *sdp) -{ - struct dirty_j *dj = NULL; - - spin_lock(&sdp->sd_dirty_j_lock); - if (!list_empty(&sdp->sd_dirty_j)) { - dj = list_entry(sdp->sd_dirty_j.prev, struct dirty_j, dj_list); - list_del(&dj->dj_list); - } - spin_unlock(&sdp->sd_dirty_j_lock); - - return dj; -} - -/** - * gfs_clear_dirty_j - destroy the list of dirty journals - * @sdp: the filesystem - * - */ - -void -gfs_clear_dirty_j(struct gfs_sbd *sdp) -{ - struct dirty_j *dj; - for (;;) { - dj = get_dirty_j(sdp); - if (!dj) - break; - kfree(dj); - } -} - -/** - * gfs_log_header - read the log header for a given segment - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @seg: the segment to look at - * @lh: the log header to return - * - * Read the log header for a given segement in a given journal. Do a few - * sanity checks on it. - * - * Returns: 0 on success, 1 if the header was invalid or incomplete and, errno on error - */ - -static int -get_log_header(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint32_t seg, struct gfs_log_header *lh) -{ - struct buffer_head *bh; - struct gfs_log_header lh2; - int error; - - error = gfs_dread(gl, seg2bn(seg), DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - gfs_log_header_in(lh, bh->b_data); - gfs_log_header_in(&lh2, - bh->b_data + GFS_BASIC_BLOCK - - sizeof(struct gfs_log_header)); - - brelse(bh); - - if (memcmp(lh, &lh2, sizeof(struct gfs_log_header)) != 0 || - lh->lh_header.mh_magic != GFS_MAGIC || - lh->lh_header.mh_type != GFS_METATYPE_LH) - error = 1; - - return error; -} - -/** - * find_good_lh - find a good log header - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @seg: the segment to start searching from (it's also filled in with a new value.) - * @lh: the log header to fill in - * @forward: if true search forward in the log, else search backward - * - * Call get_log_header() to get a log header for a segment, but if the - * segment is bad, either scan forward or backward until we find a good one. - * - * Returns: errno - */ - -static int -find_good_lh(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint32_t *seg, struct gfs_log_header *lh, - int forward) -{ - int error; - uint32_t orig_seg = *seg; - - for (;;) { - error = get_log_header(sdp, jdesc, gl, *seg, lh); - if (error <= 0) - return error; - - if (forward) { - if (++*seg == jdesc->ji_nsegment) - *seg = 0; - } else { - if (*seg-- == 0) - *seg = jdesc->ji_nsegment - 1; - } - - if (*seg == orig_seg) { - gfs_consist(sdp); - return -EIO; - } - } -} - -/** - * verify_jhead - make sure we've found the head of the log - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @head: this is filled in with the log descriptor of the head - * - * At this point, seg and lh should be either the head of the log or just - * before. Scan forward until we find the head. - * - * Returns: errno - */ - -static int -verify_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, struct gfs_log_header *head) -{ - struct gfs_log_header lh; - uint32_t seg; - int error; - - seg = bn2seg(head->lh_first); - - for (;;) { - if (++seg == jdesc->ji_nsegment) - seg = 0; - - error = get_log_header(sdp, jdesc, gl, seg, &lh); - if (error < 0) - return error; - - if (error == 1) - continue; - if (lh.lh_sequence == head->lh_sequence) - continue; - - if (lh.lh_sequence < head->lh_sequence) - break; - - memcpy(head, &lh, sizeof(struct gfs_log_header)); - } - - return 0; -} - -/** - * gfs_find_jhead - find the head of a log - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @head: the log descriptor for the head of the log is returned here - * - * Do a binary search of a journal and find the valid log entry with the - * highest sequence number. (i.e. the log head) - * - * Returns: errno - */ - -int -gfs_find_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, struct gfs_log_header *head) -{ - struct gfs_log_header lh1, lh_m; - uint32_t seg1, seg2, seg_m; - int error; - - seg1 = 0; - seg2 = jdesc->ji_nsegment - 1; - - gfs_log_lock(sdp); - for (;;) { - seg_m = (seg1 + seg2) / 2; - - error = find_good_lh(sdp, jdesc, gl, &seg1, &lh1, TRUE); - if (error) - break; - - if (seg1 == seg_m) { - error = verify_jhead(sdp, jdesc, gl, &lh1); - if (unlikely(error)) { - printk("GFS: verify_jhead error=%d\n", error); - gfs_log_unlock(sdp); - return error; - } - memcpy(head, &lh1, sizeof(struct gfs_log_header)); - break; - } - - error = find_good_lh(sdp, jdesc, gl, &seg_m, &lh_m, FALSE); - if (error) - break; - - if (lh1.lh_sequence <= lh_m.lh_sequence) - seg1 = seg_m; - else - seg2 = seg_m; - } - - gfs_log_unlock(sdp); - return error; -} - -/** - * gfs_increment_blkno - move to the next block in a journal - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @addr: the block number to increment - * @skip_header: if this is TRUE, skip log headers - * - * Replace @addr with the location of the next block in the log. - * Take care of journal wrap and skip of log header if necessary. - * - * Returns: errno - */ - -int -gfs_increment_blkno(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t *addr, int skip_headers) -{ - struct gfs_log_header header; - int error; - - (*addr)++; - - /* Handle journal wrap */ - - if (*addr == seg2bn(jdesc->ji_nsegment)) - *addr -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; - - gfs_start_ra(gl, *addr, - jdesc->ji_addr + - jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size - *addr); - - /* Handle landing on a header block */ - - if (skip_headers && !do_mod(*addr, sdp->sd_sb.sb_seg_size)) { - error = get_log_header(sdp, jdesc, gl, bn2seg(*addr), &header); - if (error < 0) - return error; - - if (error) { /* Corrupt headers here are bad */ - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: *addr = %"PRIu64"\n", - sdp->sd_fsname, *addr); - return -EIO; - } - if (header.lh_first == *addr) { - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: *addr = %"PRIu64"\n", - sdp->sd_fsname, *addr); - gfs_log_header_print(&header); - return -EIO; - } - - (*addr)++; - /* Can't wrap here */ - } - - return 0; -} - -/** - * foreach_descriptor - go through the active part of the log - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @start: the first log header in the active region - * @end: the last log header (don't process the contents of this entry)) - * @pass: the recovery pass - * - * Call a given function once for every log descriptor in the active - * portion of the log. - * - * Returns: errno - */ - -static int -foreach_descriptor(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t start, uint64_t end, - unsigned int pass) -{ - struct gfs_log_header header; - struct gfs_log_descriptor desc; - struct buffer_head *bh; - int error = 0; - - while (start != end) { - if (do_mod(start, sdp->sd_sb.sb_seg_size)) { - gfs_consist(sdp); - return -EIO; - } - - error = get_log_header(sdp, jdesc, gl, bn2seg(start), &header); - if (error < 0) - return error; - - if (error) { /* Corrupt headers here are bad */ - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: start = %"PRIu64"\n", - sdp->sd_fsname, start); - return -EIO; - } - if (header.lh_first != start) { - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: start = %"PRIu64"\n", - sdp->sd_fsname, start); - gfs_log_header_print(&header); - return -EIO; - } - - start++; - - for (;;) { - error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); - if (error) - return error; - - if (gfs_metatype_check(sdp, bh, GFS_METATYPE_LD)) { - brelse(bh); - return -EIO; - } - - gfs_desc_in(&desc, bh->b_data); - brelse(bh); - - if (desc.ld_type != GFS_LOG_DESC_LAST) { - error = LO_SCAN_ELEMENTS(sdp, jdesc, gl, start, - &desc, pass); - if (error) - return error; - - while (desc.ld_length--) { - error = gfs_increment_blkno(sdp, jdesc, gl, - &start, TRUE); - if (error) - return error; - } - } else { - while (desc.ld_length--) { - error = gfs_increment_blkno(sdp, jdesc, gl, - &start, - !!desc.ld_length); - if (error) - return error; - } - - break; - } - } - } - - return error; -} - -/** - * clean_journal - mark a dirty journal as being clean - * @sdp: the filesystem - * @jdesc: the journal - * @gl: the journal's glock - * @head: the head journal to start from - * - * Returns: errno - */ - -static int -clean_journal(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, struct gfs_log_header *head) -{ - struct gfs_log_header lh; - struct gfs_log_descriptor desc; - struct buffer_head *bh; - uint32_t seg; - uint64_t blkno; - int error; - - seg = bn2seg(head->lh_first); - - for (;;) { - if (++seg == jdesc->ji_nsegment) - seg = 0; - - error = get_log_header(sdp, jdesc, gl, seg, &lh); - if (error < 0) - return error; - - /* Rewrite corrupt header blocks */ - - if (error == 1) { - bh = gfs_dgetblk(gl, seg2bn(seg)); - - gfs_prep_new_buffer(bh); - gfs_buffer_clear(bh); - gfs_log_header_out(head, bh->b_data); - gfs_log_header_out(head, - bh->b_data + GFS_BASIC_BLOCK - - sizeof(struct gfs_log_header)); - - error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); - brelse(bh); - if (error) - return error; - } - - /* Stop when we get to the end of the log. */ - - if (lh.lh_sequence < head->lh_sequence) - break; - } - - /* Build a "last" descriptor for the transaction we are - about to commit by writing the shutdown header. */ - - memset(&desc, 0, sizeof(struct gfs_log_descriptor)); - desc.ld_header.mh_magic = GFS_MAGIC; - desc.ld_header.mh_type = GFS_METATYPE_LD; - desc.ld_header.mh_format = GFS_FORMAT_LD; - desc.ld_type = GFS_LOG_DESC_LAST; - desc.ld_length = 0; - - for (blkno = head->lh_first + 1; blkno != seg2bn(seg);) { - if (do_mod(blkno, sdp->sd_sb.sb_seg_size)) - desc.ld_length++; - if (++blkno == seg2bn(jdesc->ji_nsegment)) - blkno -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; - } - - /* Write the descriptor */ - - bh = gfs_dgetblk(gl, head->lh_first + 1); - - gfs_prep_new_buffer(bh); - gfs_buffer_clear(bh); - gfs_desc_out(&desc, bh->b_data); - - error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); - brelse(bh); - if (error) - return error; - - /* Build a log header that says the journal is clean */ - - memset(&lh, 0, sizeof(struct gfs_log_header)); - lh.lh_header.mh_magic = GFS_MAGIC; - lh.lh_header.mh_type = GFS_METATYPE_LH; - lh.lh_header.mh_format = GFS_FORMAT_LH; - lh.lh_flags = GFS_LOG_HEAD_UNMOUNT; - lh.lh_first = seg2bn(seg); - lh.lh_sequence = head->lh_sequence + 1; - /* Don't care about tail */ - lh.lh_last_dump = head->lh_last_dump; - - /* Write the header */ - - bh = gfs_dgetblk(gl, lh.lh_first); - - gfs_prep_new_buffer(bh); - gfs_buffer_clear(bh); - gfs_log_header_out(&lh, bh->b_data); - gfs_log_header_out(&lh, - bh->b_data + GFS_BASIC_BLOCK - - sizeof(struct gfs_log_header)); - - error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); - brelse(bh); - - return error; -} - -/** - * gfs_recover_journal - recovery a given journal - * @sdp: the filesystem - * @jid: the number of the journal to recover - * @jdesc: the struct gfs_jindex describing the journal - * @wait: Don't return until the journal is clean (or an error is encountered) - * - * Acquire the journal's lock, check to see if the journal is clean, and - * do recovery if necessary. - * - * Returns: errno - */ - -int -gfs_recover_journal(struct gfs_sbd *sdp, - unsigned int jid, struct gfs_jindex *jdesc, - int wait) -{ - struct gfs_log_header head; - struct gfs_holder j_gh, t_gh; - unsigned long t; - int error; - - printk("GFS: fsid=%s: jid=%u: Trying to acquire journal lock...\n", - sdp->sd_fsname, jid); - - /* Aquire the journal lock so we can do recovery */ - - error = gfs_glock_nq_num(sdp, - jdesc->ji_addr, &gfs_meta_glops, - LM_ST_EXCLUSIVE, - LM_FLAG_NOEXP | - ((wait) ? 0 : LM_FLAG_TRY) | - GL_NOCACHE, &j_gh); - switch (error) { - case 0: - break; - - case GLR_TRYFAILED: - printk("GFS: fsid=%s: jid=%u: Busy\n", sdp->sd_fsname, jid); - error = 0; - - default: - goto fail; - }; - - printk("GFS: fsid=%s: jid=%u: Looking at journal...\n", - sdp->sd_fsname, jid); - - error = gfs_find_jhead(sdp, jdesc, j_gh.gh_gl, &head); - if (error) - goto fail_gunlock; - - if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { - if (test_bit(SDF_ROFS, &sdp->sd_flags)) { - printk("GFS: fsid=%s: jid=%u: Can't replay: read-only FS\n", - sdp->sd_fsname, jid); - error = -EROFS; - goto fail_gunlock; - } - - printk("GFS: fsid=%s: jid=%u: Acquiring the transaction lock...\n", - sdp->sd_fsname, jid); - - t = jiffies; - - /* Acquire an exclusive hold on the transaction lock */ - - error = gfs_glock_nq_init(sdp->sd_trans_gl, - LM_ST_EXCLUSIVE, - LM_FLAG_NOEXP | - LM_FLAG_PRIORITY | - GL_NOCANCEL | - GL_NOCACHE, - &t_gh); - if (error) - goto fail_gunlock; - - if (test_bit(SDF_ROFS, &sdp->sd_flags)) { - printk("GFS: fsid=%s: jid=%u: Can't replay: read-only FS\n", - sdp->sd_fsname, jid); - error = -EROFS; - goto fail_gunlock_tr; - } - - printk("GFS: fsid=%s: jid=%u: Replaying journal...\n", - sdp->sd_fsname, jid); - - set_bit(GLF_DIRTY, &j_gh.gh_gl->gl_flags); - - LO_BEFORE_SCAN(sdp, jid, &head, GFS_RECPASS_A1); - - error = foreach_descriptor(sdp, jdesc, j_gh.gh_gl, - head.lh_tail, head.lh_first, - GFS_RECPASS_A1); - if (error) - goto fail_gunlock_tr; - - LO_AFTER_SCAN(sdp, jid, GFS_RECPASS_A1); - - gfs_replay_wait(sdp); - - error = clean_journal(sdp, jdesc, j_gh.gh_gl, &head); - if (error) - goto fail_gunlock_tr; - - gfs_glock_dq_uninit(&t_gh); - - t = DIV_RU(jiffies - t, HZ); - - printk("GFS: fsid=%s: jid=%u: Journal replayed in %lus\n", - sdp->sd_fsname, jid, t); - } - - gfs_lm_recovery_done(sdp, jid, LM_RD_SUCCESS); - - gfs_glock_dq_uninit(&j_gh); - - printk("GFS: fsid=%s: jid=%u: Done\n", sdp->sd_fsname, jid); - - return 0; - - fail_gunlock_tr: - gfs_replay_wait(sdp); - gfs_glock_dq_uninit(&t_gh); - - fail_gunlock: - gfs_glock_dq_uninit(&j_gh); - - printk("GFS: fsid=%s: jid=%u: %s\n", - sdp->sd_fsname, jid, (error) ? "Failed" : "Done"); - - fail: - gfs_lm_recovery_done(sdp, jid, LM_RD_GAVEUP); - - return error; -} - -/** - * gfs_check_journals - Recover any dirty journals - * @sdp: the filesystem - * - */ - -void -gfs_check_journals(struct gfs_sbd *sdp) -{ - struct dirty_j *dj; - - for (;;) { - dj = get_dirty_j(sdp); - if (!dj) - break; - - down(&sdp->sd_jindex_lock); - - if (dj->dj_jid != sdp->sd_lockstruct.ls_jid && - dj->dj_jid < sdp->sd_journals) { - memcpy(&dj->dj_desc, - sdp->sd_jindex + dj->dj_jid, - sizeof(struct gfs_jindex)); - up(&sdp->sd_jindex_lock); - - gfs_recover_journal(sdp, - dj->dj_jid, &dj->dj_desc, - FALSE); - - } else { - up(&sdp->sd_jindex_lock); - gfs_lm_recovery_done(sdp, dj->dj_jid, LM_RD_GAVEUP); - } - - kfree(dj); - } -} - -/** - * gfs_recover_dump - recover the log elements in this machine's journal - * @sdp: the filesystem - * - * Returns: errno - */ - -int -gfs_recover_dump(struct gfs_sbd *sdp) -{ - struct gfs_log_header head; - int error; - - error = gfs_find_jhead(sdp, &sdp->sd_jdesc, sdp->sd_journal_gh.gh_gl, - &head); - if (error) - goto fail; - - if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { - gfs_consist(sdp); - return -EIO; - } - if (!head.lh_last_dump) - return error; - - printk("GFS: fsid=%s: Scanning for log elements...\n", - sdp->sd_fsname); - - LO_BEFORE_SCAN(sdp, sdp->sd_lockstruct.ls_jid, &head, GFS_RECPASS_B1); - - error = foreach_descriptor(sdp, &sdp->sd_jdesc, sdp->sd_journal_gh.gh_gl, - head.lh_last_dump, head.lh_first, - GFS_RECPASS_B1); - if (error) - goto fail; - - LO_AFTER_SCAN(sdp, sdp->sd_lockstruct.ls_jid, GFS_RECPASS_B1); - - /* We need to make sure if we crash during the next log dump that - all intermediate headers in the transaction point to the last - log dump before the one we're making so we don't lose it. */ - - sdp->sd_log_dump_last = head.lh_last_dump; - - printk("GFS: fsid=%s: Done\n", sdp->sd_fsname); - - return 0; - - fail: - printk("GFS: fsid=%s: Failed\n", sdp->sd_fsname); - - return error; -} diff --git a/gfs-kernel/src/gfs/recovery.h b/gfs-kernel/src/gfs/recovery.h deleted file mode 100644 index a797152..0000000 --- a/gfs-kernel/src/gfs/recovery.h +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __RECOVERY_DOT_H__ -#define __RECOVERY_DOT_H__ - -#define GFS_RECPASS_A1 (12) -#define GFS_RECPASS_B1 (14) - -void gfs_add_dirty_j(struct gfs_sbd *sdp, unsigned int jid); -void gfs_clear_dirty_j(struct gfs_sbd *sdp); - -int gfs_find_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, struct gfs_log_header *head); -int gfs_increment_blkno(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, - struct gfs_glock *gl, uint64_t *addr, - int skip_headers); - -int gfs_recover_journal(struct gfs_sbd *sdp, - unsigned int jid, struct gfs_jindex *jdesc, - int wait); -void gfs_check_journals(struct gfs_sbd *sdp); - -int gfs_recover_dump(struct gfs_sbd *sdp); - -#endif /* __RECOVERY_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/rgrp.c b/gfs-kernel/src/gfs/rgrp.c deleted file mode 100644 index ab6c6ef..0000000 --- a/gfs-kernel/src/gfs/rgrp.c +++ /dev/null @@ -1,2165 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <linux/types.h> - -#include "gfs.h" -#include "bits.h" -#include "dio.h" -#include "file.h" -#include "glock.h" -#include "glops.h" -#include "rgrp.h" -#include "super.h" -#include "trans.h" - -/** - * mhc_hash: find the mhc hash bucket for a buffer - * @bh: the buffer - * - * Returns: The bucket number - */ - -static unsigned int -mhc_hash(struct buffer_head *bh) -{ - uint64_t blkno; - unsigned int h; - - blkno = bh->b_blocknr; - h = gfs_hash(&blkno, sizeof(uint64_t)) & GFS_MHC_HASH_MASK; - - return h; -} - -/** - * mhc_trim - Throw away cached meta-headers, if there are too many of them - * @sdp: The filesystem instance - * @max: Max # of cached meta-headers allowed to survive - * - * Walk filesystem's list of cached meta-headers, in least-recently-used order, - * and keep throwing them away until we're under the max threshold. - */ - -static void -mhc_trim(struct gfs_sbd *sdp, unsigned int max) -{ - struct gfs_meta_header_cache *mc; - - for (;;) { - spin_lock(&sdp->sd_mhc_lock); - if (list_empty(&sdp->sd_mhc_single)) { - spin_unlock(&sdp->sd_mhc_lock); - return; - } else { - mc = list_entry(sdp->sd_mhc_single.prev, - struct gfs_meta_header_cache, - mc_list_single); - list_del(&mc->mc_list_hash); - list_del(&mc->mc_list_single); - list_del(&mc->mc_list_rgd); - spin_unlock(&sdp->sd_mhc_lock); - - kmem_cache_free(gfs_mhc_cachep, mc); - atomic_dec(&sdp->sd_mhc_count); - - if (atomic_read(&sdp->sd_mhc_count) <= max) - return; - } - } -} - -/** - * gfs_mhc_add - add buffer(s) to the cache of metadata headers - * @rgd: Resource Group in which the buffered block(s) reside - * @bh: an array of buffer_head pointers - * @num: the number of bh pointers in the array - * - * Increment each meta-header's generation # by 2. - * Alloc and add each gfs_meta-header_cache to 3 lists/caches: - * Filesystem's meta-header cache (hash) - * Filesystem's list of cached meta-headers - * Resource Group's list of cached meta-headers - * If we now have too many cached, throw some older ones away - */ - -void -gfs_mhc_add(struct gfs_rgrpd *rgd, - struct buffer_head **bh, unsigned int num) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - unsigned int x; - - for (x = 0; x < num; x++) { - struct gfs_meta_header_cache *mc; - struct list_head *head; - uint64_t gen; - - if (gfs_meta_check(sdp, bh[x])) - return; - - mc = kmem_cache_alloc(gfs_mhc_cachep, GFP_KERNEL); - if (!mc) - return; - memset(mc, 0, sizeof(struct gfs_meta_header_cache)); - - mc->mc_block = bh[x]->b_blocknr; - memcpy(&mc->mc_mh, bh[x]->b_data, - sizeof(struct gfs_meta_header)); - - gen = gfs64_to_cpu(mc->mc_mh.mh_generation) + 2; - mc->mc_mh.mh_generation = cpu_to_gfs64(gen); - - head = &sdp->sd_mhc[mhc_hash(bh[x])]; - - spin_lock(&sdp->sd_mhc_lock); - list_add(&mc->mc_list_hash, head); - list_add(&mc->mc_list_single, &sdp->sd_mhc_single); - list_add(&mc->mc_list_rgd, &rgd->rd_mhc); - spin_unlock(&sdp->sd_mhc_lock); - - atomic_inc(&sdp->sd_mhc_count); - } - - x = gfs_tune_get(sdp, gt_max_mhc); - - /* If we've got too many cached, throw some older ones away */ - if (atomic_read(&sdp->sd_mhc_count) > x) - mhc_trim(sdp, x); -} - -/** - * gfs_mhc_fish - Try to fill in a meta buffer with meta-header from the cache - * @sdp: the filesystem - * @bh: the buffer to fill in - * - * Returns: TRUE if the buffer was cached, FALSE otherwise - * - * If buffer is referenced in meta-header cache (search using hash): - * Copy the cached meta-header into the buffer (instead of reading from disk). - * Note that only the meta-header portion of the buffer will have valid data - * (as would be on disk), rest of buffer does *not* reflect disk contents. - * Remove cached gfs_meta_header_cache from all cache lists, free its memory. - */ - -int -gfs_mhc_fish(struct gfs_sbd *sdp, struct buffer_head *bh) -{ - struct list_head *tmp, *head; - struct gfs_meta_header_cache *mc; - - head = &sdp->sd_mhc[mhc_hash(bh)]; - - spin_lock(&sdp->sd_mhc_lock); - - for (tmp = head->next; - tmp != head; - tmp = tmp->next) { - mc = list_entry(tmp, struct gfs_meta_header_cache, mc_list_hash); - if (mc->mc_block != bh->b_blocknr) - continue; - - list_del(&mc->mc_list_hash); - list_del(&mc->mc_list_single); - list_del(&mc->mc_list_rgd); - spin_unlock(&sdp->sd_mhc_lock); - - gfs_prep_new_buffer(bh); - memcpy(bh->b_data, &mc->mc_mh, - sizeof(struct gfs_meta_header)); - - kmem_cache_free(gfs_mhc_cachep, mc); - atomic_dec(&sdp->sd_mhc_count); - - return TRUE; - } - - spin_unlock(&sdp->sd_mhc_lock); - - return FALSE; -} - -/** - * gfs_mhc_zap - Throw away an RG's list of cached metadata headers - * @rgd: The resource group whose list we want to clear - * - * Simply throw away all cached metadata headers on RG's list, - * and free their memory. - */ - -void -gfs_mhc_zap(struct gfs_rgrpd *rgd) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_meta_header_cache *mc; - - spin_lock(&sdp->sd_mhc_lock); - - while (!list_empty(&rgd->rd_mhc)) { - mc = list_entry(rgd->rd_mhc.next, - struct gfs_meta_header_cache, - mc_list_rgd); - - list_del(&mc->mc_list_hash); - list_del(&mc->mc_list_single); - list_del(&mc->mc_list_rgd); - spin_unlock(&sdp->sd_mhc_lock); - - kmem_cache_free(gfs_mhc_cachep, mc); - atomic_dec(&sdp->sd_mhc_count); - - spin_lock(&sdp->sd_mhc_lock); - } - - spin_unlock(&sdp->sd_mhc_lock); -} - -/** - * depend_hash() - Turn glock number into hash bucket number - * @formal_ino: - * - * Returns: The number of the corresponding hash bucket - */ - -static unsigned int -depend_hash(uint64_t formal_ino) -{ - unsigned int h; - - h = gfs_hash(&formal_ino, sizeof(uint64_t)); - h &= GFS_DEPEND_HASH_MASK; - - return h; -} - -/** - * depend_sync_one - Sync metadata (not data) for a dependency inode - * @sdp: filesystem instance - * @gd: dependency descriptor - * - * Remove dependency from superblock's hash table and rgrp's list. - * Sync dependency inode's metadata to log and in-place location. - */ - -static void -depend_sync_one(struct gfs_sbd *sdp, struct gfs_depend *gd) -{ - struct gfs_glock *gl; - - spin_lock(&sdp->sd_depend_lock); - list_del(&gd->gd_list_hash); - spin_unlock(&sdp->sd_depend_lock); - list_del(&gd->gd_list_rgd); - - gl = gfs_glock_find(sdp, - &(struct lm_lockname){gd->gd_formal_ino, - LM_TYPE_INODE}); - if (gl) { - if (gl->gl_ops->go_sync) - gl->gl_ops->go_sync(gl, - DIO_METADATA | - DIO_INVISIBLE); - gfs_glock_put(gl); - } - - kfree(gd); - atomic_dec(&sdp->sd_depend_count); -} - -/** - * depend_sync_old - Sync older rgrp-dependent inodes to disk. - * @rgd: Resource group containing dependent inodes - * - * Look at oldest entries in resource group's dependency list, - * sync 'em if they're older than timeout threshold. - */ - -static void -depend_sync_old(struct gfs_rgrpd *rgd) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_depend *gd; - - while (!list_empty(&rgd->rd_depend)) { - /* Oldest entries are in prev direction */ - gd = list_entry(rgd->rd_depend.prev, - struct gfs_depend, - gd_list_rgd); - - if (time_before(jiffies, - gd->gd_time + - gfs_tune_get(sdp, gt_depend_secs) * HZ)) - return; - - depend_sync_one(sdp, gd); - } -} - -/** - * gfs_depend_add - Add a dependent inode to rgrp's and filesystem's list - * @rgd: Resource group containing blocks associated with inode - * @formal_ino: inode - * - * Dependent inodes must be flushed to log and in-place blocks before - * releasing an EXCLUSIVE rgrp lock. - * Find pre-existing dependency for this inode/rgrp combination in - * incore superblock struct's sd_depend hash table, or create a new one. - * Either way, move or attach dependency to head of superblock's hash bucket - * and top of rgrp's list. - * If we create a new one, take a moment to sync older dependencies to disk. - */ - -void -gfs_depend_add(struct gfs_rgrpd *rgd, uint64_t formal_ino) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct list_head *head, *tmp; - struct gfs_depend *gd; - - head = &sdp->sd_depend[depend_hash(formal_ino)]; - - spin_lock(&sdp->sd_depend_lock); - - for (tmp = head->next; - tmp != head; - tmp = tmp->next) { - gd = list_entry(tmp, struct gfs_depend, gd_list_hash); - if (gd->gd_rgd == rgd && - gd->gd_formal_ino == formal_ino) { - list_move(&gd->gd_list_hash, head); - spin_unlock(&sdp->sd_depend_lock); - list_move(&gd->gd_list_rgd, &rgd->rd_depend); - gd->gd_time = jiffies; - return; - } - } - - spin_unlock(&sdp->sd_depend_lock); - - gd = gmalloc(sizeof(struct gfs_depend)); - memset(gd, 0, sizeof(struct gfs_depend)); - - gd->gd_rgd = rgd; - gd->gd_formal_ino = formal_ino; - gd->gd_time = jiffies; - - spin_lock(&sdp->sd_depend_lock); - list_add(&gd->gd_list_hash, head); - spin_unlock(&sdp->sd_depend_lock); - list_add(&gd->gd_list_rgd, &rgd->rd_depend); - - atomic_inc(&sdp->sd_depend_count); - - depend_sync_old(rgd); -} - -/** - * gfs_depend_sync - Sync metadata (not data) for an rgrp's dependent inodes - * @rgd: Resource group containing the dependent inodes - * - * As long as this node owns an EXCLUSIVE lock on the rgrp, we can keep - * rgrp's modified metadata blocks in buffer cache. - * - * When this node releases the EX lock, we must flush metadata, so other - * nodes can read the modified content from disk. - */ - -void -gfs_depend_sync(struct gfs_rgrpd *rgd) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_depend *gd; - - while (!list_empty(&rgd->rd_depend)) { - gd = list_entry(rgd->rd_depend.next, - struct gfs_depend, - gd_list_rgd); - depend_sync_one(sdp, gd); - } -} - -/** - * rgrp_verify - Verify that a resource group is consistent - * @sdp: the filesystem - * @rgd: the rgrp - * - * Somebody should have already called gfs_glock_rg() on this RG. - */ - -static void -rgrp_verify(struct gfs_rgrpd *rgd) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_bitmap *bits = NULL; - uint32_t length = rgd->rd_ri.ri_length; - uint32_t count[4], tmp; - int buf, x; - - memset(count, 0, 4 * sizeof(uint32_t)); - - /* Count # blocks in each of 4 possible allocation states */ - for (buf = 0; buf < length; buf++) { - bits = &rgd->rd_bits[buf]; - for (x = 0; x < 4; x++) - count[x] += gfs_bitcount(rgd, - rgd->rd_bh[buf]->b_data + - bits->bi_offset, - bits->bi_len, x); - } - - if (count[0] != rgd->rd_rg.rg_free) { - if (gfs_consist_rgrpd(rgd)) - printk("GFS: fsid=%s: free data mismatch: %u != %u\n", - sdp->sd_fsname, count[0], rgd->rd_rg.rg_free); - return; - } - - tmp = rgd->rd_ri.ri_data - - (rgd->rd_rg.rg_usedmeta + rgd->rd_rg.rg_freemeta) - - (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi) - - rgd->rd_rg.rg_free; - if (count[1] != tmp) { - if (gfs_consist_rgrpd(rgd)) - printk("GFS: fsid=%s: used data mismatch: %u != %u\n", - sdp->sd_fsname, count[1], tmp); - return; - } - - if (count[2] != rgd->rd_rg.rg_freemeta) { - if (gfs_consist_rgrpd(rgd)) - printk("GFS: fsid=%s: free metadata mismatch: %u != %u\n", - sdp->sd_fsname, count[2], rgd->rd_rg.rg_freemeta); - return; - } - - tmp = rgd->rd_rg.rg_usedmeta + - (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi); - if (count[3] != tmp) { - if (gfs_consist_rgrpd(rgd)) - printk("GFS: fsid=%s: used metadata mismatch: %u != %u\n", - sdp->sd_fsname, count[3], tmp); - return; - } -} - -/** - * gfs_blk2rgrpd - Find resource group for a given data/meta block number - * @sdp: The GFS superblock - * @n: The data block number - * - * Returns: The resource group, or NULL if not found - * - * Don't try to use this for non-allocatable block numbers (i.e. rgrp header - * or bitmap blocks); it's for allocatable (data/meta) blocks only. - */ - -struct gfs_rgrpd * -gfs_blk2rgrpd(struct gfs_sbd *sdp, uint64_t blk) -{ - struct list_head *tmp, *head; - struct gfs_rgrpd *rgd = NULL; - struct gfs_rindex *ri; - - spin_lock(&sdp->sd_rg_mru_lock); - - for (head = &sdp->sd_rg_mru_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - rgd = list_entry(tmp, struct gfs_rgrpd, rd_list_mru); - ri = &rgd->rd_ri; - - if (ri->ri_data1 <= blk && blk < ri->ri_data1 + ri->ri_data) { - list_move(&rgd->rd_list_mru, &sdp->sd_rg_mru_list); - spin_unlock(&sdp->sd_rg_mru_lock); - return rgd; - } - } - - spin_unlock(&sdp->sd_rg_mru_lock); - - return NULL; -} - -/** - * gfs_rgrpd_get_first - get the first Resource Group in the filesystem - * @sdp: The GFS superblock - * - * Returns: The first rgrp in the filesystem - */ - -struct gfs_rgrpd * -gfs_rgrpd_get_first(struct gfs_sbd *sdp) -{ - gfs_assert(sdp, !list_empty(&sdp->sd_rglist),); - return list_entry(sdp->sd_rglist.next, struct gfs_rgrpd, rd_list); -} - -/** - * gfs_rgrpd_get_next - get the next RG - * @rgd: A RG - * - * Returns: The next rgrp - */ - -struct gfs_rgrpd * -gfs_rgrpd_get_next(struct gfs_rgrpd *rgd) -{ - if (rgd->rd_list.next == &rgd->rd_sbd->sd_rglist) - return NULL; - return list_entry(rgd->rd_list.next, struct gfs_rgrpd, rd_list); -} - -/** - * clear_rgrpdi - Clear up rgrps - * @sdp: The GFS superblock - * - */ - -void -clear_rgrpdi(struct gfs_sbd *sdp) -{ - struct gfs_rgrpd *rgd; - struct gfs_glock *gl; - - spin_lock(&sdp->sd_rg_forward_lock); - sdp->sd_rg_forward = NULL; - spin_unlock(&sdp->sd_rg_forward_lock); - - spin_lock(&sdp->sd_rg_recent_lock); - while (!list_empty(&sdp->sd_rg_recent)) { - rgd = list_entry(sdp->sd_rg_recent.next, - struct gfs_rgrpd, rd_recent); - list_del(&rgd->rd_recent); - } - spin_unlock(&sdp->sd_rg_recent_lock); - - while (!list_empty(&sdp->sd_rglist)) { - rgd = list_entry(sdp->sd_rglist.next, - struct gfs_rgrpd, rd_list); - gl = rgd->rd_gl; - - list_del(&rgd->rd_list); - list_del(&rgd->rd_list_mru); - - if (gl) { - gfs_glock_force_drop(gl); - if (atomic_read(&gl->gl_lvb_count)) - gfs_lvb_unhold(gl); - gl2rgd(gl) = NULL; - gfs_glock_put(gl); - } - - if (rgd->rd_bits) - kfree(rgd->rd_bits); - if (rgd->rd_bh) - kfree(rgd->rd_bh); - - kfree(rgd); - } -} - -/** - * gfs_clear_rgrpd - Clear up rgrps - * @sdp: The GFS superblock - * - */ - -void -gfs_clear_rgrpd(struct gfs_sbd *sdp) -{ - down(&sdp->sd_rindex_lock); - clear_rgrpdi(sdp); - up(&sdp->sd_rindex_lock); -} - -/** - * gfs_compute_bitstructs - Compute the bitmap sizes - * @rgd: The resource group descriptor - * - * Calculates bitmap descriptors, one for each block that contains bitmap data - * - * Returns: errno - */ - -static int -compute_bitstructs(struct gfs_rgrpd *rgd) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_bitmap *bits; - uint32_t length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ - uint32_t bytes_left, bytes; - int x; - - rgd->rd_bits = kmalloc(length * sizeof(struct gfs_bitmap), GFP_KERNEL); - if (!rgd->rd_bits) - return -ENOMEM; - memset(rgd->rd_bits, 0, length * sizeof(struct gfs_bitmap)); - - bytes_left = rgd->rd_ri.ri_bitbytes; - - for (x = 0; x < length; x++) { - bits = &rgd->rd_bits[x]; - - /* small rgrp; bitmap stored completely in header block */ - if (length == 1) { - bytes = bytes_left; - bits->bi_offset = sizeof(struct gfs_rgrp); - bits->bi_start = 0; - bits->bi_len = bytes; - /* header block */ - } else if (x == 0) { - bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs_rgrp); - bits->bi_offset = sizeof(struct gfs_rgrp); - bits->bi_start = 0; - bits->bi_len = bytes; - /* last block */ - } else if (x + 1 == length) { - bytes = bytes_left; - bits->bi_offset = sizeof(struct gfs_meta_header); - bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; - bits->bi_len = bytes; - /* other blocks */ - } else { - bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs_meta_header); - bits->bi_offset = sizeof(struct gfs_meta_header); - bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; - bits->bi_len = bytes; - } - - bytes_left -= bytes; - } - - if (bytes_left) { - gfs_consist_rgrpd(rgd); - return -EIO; - } - if ((rgd->rd_bits[length - 1].bi_start + - rgd->rd_bits[length - 1].bi_len) * GFS_NBBY != - rgd->rd_ri.ri_data) { - if (gfs_consist_rgrpd(rgd)) { - gfs_rindex_print(&rgd->rd_ri); - printk("GFS: fsid=%s: start=%u len=%u offset=%u\n", - sdp->sd_fsname, - rgd->rd_bits[length - 1].bi_start, - rgd->rd_bits[length - 1].bi_len, - rgd->rd_bits[length - 1].bi_offset); - } - return -EIO; - } - - rgd->rd_bh = kmalloc(length * sizeof(struct buffer_head *), GFP_KERNEL); - if (!rgd->rd_bh) { - kfree(rgd->rd_bits); - return -ENOMEM; - } - memset(rgd->rd_bh, 0, length * sizeof(struct buffer_head *)); - - return 0; -} - -/** - * gfs_ri_update - Pull in a new resource index from the disk - * @gl: The glock covering the rindex inode - * - * Returns: 0 on successful update, error code otherwise - */ - -static int -gfs_ri_update(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrpd *rgd; - char buf[sizeof(struct gfs_rindex)]; - int error; - - if (do_mod(ip->i_di.di_size, sizeof(struct gfs_rindex))) { - gfs_consist_inode(ip); - return -EIO; - } - - clear_rgrpdi(sdp); - - for (sdp->sd_rgcount = 0;; sdp->sd_rgcount++) { - error = gfs_internal_read(ip, buf, - sdp->sd_rgcount * - sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (!error) - break; - if (error != sizeof(struct gfs_rindex)) { - if (error > 0) - error = -EIO; - goto fail; - } - - rgd = kmalloc(sizeof(struct gfs_rgrpd), GFP_KERNEL); - error = -ENOMEM; - if (!rgd) - goto fail; - memset(rgd, 0, sizeof(struct gfs_rgrpd)); - - INIT_LIST_HEAD(&rgd->rd_mhc); - INIT_LIST_HEAD(&rgd->rd_depend); - rgd->rd_sbd = sdp; - - list_add_tail(&rgd->rd_list, &sdp->sd_rglist); - list_add_tail(&rgd->rd_list_mru, &sdp->sd_rg_mru_list); - - gfs_rindex_in(&rgd->rd_ri, buf); - - error = compute_bitstructs(rgd); - if (error) - goto fail; - - error = gfs_glock_get(sdp, rgd->rd_ri.ri_addr, &gfs_rgrp_glops, - CREATE, &rgd->rd_gl); - if (error) - goto fail; - - error = gfs_lvb_hold(rgd->rd_gl); - if (error) - goto fail; - - gl2rgd(rgd->rd_gl) = rgd; - rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; - } - - sdp->sd_riinode_vn = ip->i_gl->gl_vn; - - return 0; - - fail: - clear_rgrpdi(sdp); - - return error; -} - -/** - * gfs_rindex_hold - Grab a lock on the rindex - * @sdp: The GFS superblock - * @ri_gh: the glock holder - * - * We grab a lock on the rindex inode to make sure that it doesn't - * change whilst we are performing an operation. We keep this lock - * for quite long periods of time compared to other locks. This - * doesn't matter, since it is shared and it is very, very rarely - * accessed in the exclusive mode (i.e. only when expanding the filesystem). - * - * This makes sure that we're using the latest copy of the resource index - * special file, which might have been updated if someone expanded the - * filesystem (via gfs_grow utility), which adds new resource groups. - * - * Returns: 0 on success, error code otherwise - */ - -int -gfs_rindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ri_gh) -{ - struct gfs_inode *ip = sdp->sd_riinode; - struct gfs_glock *gl = ip->i_gl; - int error; - - error = gfs_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh); - if (error) - return error; - - /* Read new copy from disk if we don't have the latest */ - if (sdp->sd_riinode_vn != gl->gl_vn) { - down(&sdp->sd_rindex_lock); - if (sdp->sd_riinode_vn != gl->gl_vn) { - error = gfs_ri_update(ip); - if (error) - gfs_glock_dq_uninit(ri_gh); - } - up(&sdp->sd_rindex_lock); - } - - return error; -} - -/** - * gfs_rgrp_read - Read in a RG's header and bitmaps - * @rgd: the struct gfs_rgrpd describing the RG to read in - * - * Read in all of a Resource Group's header and bitmap blocks. - * Caller must eventually call gfs_rgrp_relse() to free the bitmaps. - * - * Returns: errno - */ - -int -gfs_rgrp_read(struct gfs_rgrpd *rgd) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_glock *gl = rgd->rd_gl; - unsigned int x, length = rgd->rd_ri.ri_length; - int error; - - for (x = 0; x < length; x++) { - gfs_assert_warn(sdp, !rgd->rd_bh[x]); - rgd->rd_bh[x] = gfs_dgetblk(gl, rgd->rd_ri.ri_addr + x); - } - - for (x = 0; x < length; x++) { - error = gfs_dreread(sdp, rgd->rd_bh[x], DIO_START); - if (error) - goto fail; - } - - for (x = length; x--;) { - error = gfs_dreread(sdp, rgd->rd_bh[x], DIO_WAIT); - if (error) - goto fail; - if (gfs_metatype_check(sdp, rgd->rd_bh[x], - (x) ? GFS_METATYPE_RB : GFS_METATYPE_RG)) { - error = -EIO; - goto fail; - } - } - - if (rgd->rd_rg_vn != gl->gl_vn) { - gfs_rgrp_in(&rgd->rd_rg, (rgd->rd_bh[0])->b_data); - rgd->rd_rg_vn = gl->gl_vn; - } - - return 0; - - fail: - for (x = 0; x < length; x++) { - brelse(rgd->rd_bh[x]); - rgd->rd_bh[x] = NULL; - } - - return error; -} - -/** - * gfs_rgrp_relse - Release RG bitmaps read in with gfs_rgrp_read() - * @rgd: the struct gfs_rgrpd describing the RG to read in - * - */ - -void -gfs_rgrp_relse(struct gfs_rgrpd *rgd) -{ - int x, length = rgd->rd_ri.ri_length; - - for (x = 0; x < length; x++) { - brelse(rgd->rd_bh[x]); - rgd->rd_bh[x] = NULL; - } -} - -/** - * gfs_rgrp_lvb_fill - copy RG usage data out of the struct gfs_rgrp into the struct gfs_rgrp_lvb - * @rgd: the resource group data structure - * - */ - -void -gfs_rgrp_lvb_fill(struct gfs_rgrpd *rgd) -{ - struct gfs_rgrp *rg = &rgd->rd_rg; - struct gfs_rgrp_lvb *rb = (struct gfs_rgrp_lvb *)rgd->rd_gl->gl_lvb; - - rb->rb_magic = cpu_to_gfs32(GFS_MAGIC); - rb->rb_free = cpu_to_gfs32(rg->rg_free); - rb->rb_useddi = cpu_to_gfs32(rg->rg_useddi); - rb->rb_freedi = cpu_to_gfs32(rg->rg_freedi); - rb->rb_usedmeta = cpu_to_gfs32(rg->rg_usedmeta); - rb->rb_freemeta = cpu_to_gfs32(rg->rg_freemeta); -} - -/** - * gfs_rgrp_lvb_init - Init the data of a RG LVB - * @rgd: the resource group data structure - * - * Returns: errno - */ - -int -gfs_rgrp_lvb_init(struct gfs_rgrpd *rgd) -{ - struct gfs_glock *gl = rgd->rd_gl; - struct gfs_holder rgd_gh; - int error; - - error = gfs_glock_nq_init(gl, LM_ST_EXCLUSIVE, 0, &rgd_gh); - if (!error) { - gfs_rgrp_lvb_fill(rgd); - gfs_glock_dq_uninit(&rgd_gh); - } - - return error; -} - -/** - * gfs_alloc_get - allocate a struct gfs_alloc structure for an inode - * @ip: the incore GFS inode structure - * - * Alloc and zero an in-place reservation structure, - * and attach it to the GFS incore inode. - * - * FIXME: Don't use gmalloc() - * - * Returns: the struct gfs_alloc - */ - -struct gfs_alloc * -gfs_alloc_get(struct gfs_inode *ip) -{ - struct gfs_alloc *al = ip->i_alloc; - - gfs_assert_warn(ip->i_sbd, !al); - - al = gmalloc(sizeof(struct gfs_alloc)); - memset(al, 0, sizeof(struct gfs_alloc)); - - ip->i_alloc = al; - - return al; -} - -/** - * gfs_alloc_put - throw away the struct gfs_alloc for an inode - * @ip: the inode - * - */ - -void -gfs_alloc_put(struct gfs_inode *ip) -{ - struct gfs_alloc *al = ip->i_alloc; - - if (gfs_assert_warn(ip->i_sbd, al)) - return; - - ip->i_alloc = NULL; - kfree(al); -} - -/** - * try_rgrp_fit - See if a given reservation will fit in a given RG - * @rgd: the RG data - * @al: the struct gfs_alloc structure describing the reservation - * - * If there's room for the requested blocks to be allocated from the RG: - * Sets the $al_reserved_data field in @al. - * Sets the $al_reserved_meta field in @al. - * Sets the $al_rgd field in @al. - * - * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) - */ - -static int -try_rgrp_fit(struct gfs_rgrpd *rgd, struct gfs_alloc *al) -{ - uint32_t freeblks = rgd->rd_rg.rg_free; - uint32_t freemeta = rgd->rd_rg.rg_freemeta; - uint32_t metares = al->al_requested_meta; - uint32_t datares = al->al_requested_data; - - /* First take care of the data blocks required */ - - if (freeblks < al->al_requested_data) - return 0; - - freeblks -= al->al_requested_data; - - /* Then take care of the dinodes */ - - metares += al->al_requested_di; - - /* Then take care of the metadata blocks */ - - while (freemeta < metares) { - if (freeblks < GFS_META_CLUMP) - return 0; - - freeblks -= GFS_META_CLUMP; - freemeta += GFS_META_CLUMP; - - datares += GFS_META_CLUMP; - } - - al->al_rgd = rgd; - al->al_reserved_meta = metares; - al->al_reserved_data = datares; - - return 1; -} - -/** - * recent_rgrp_first - get first RG from "recent" list - * @sdp: The GFS superblock - * @rglast: address of the rgrp used last - * - * Returns: The first rgrp in the recent list - */ - -static struct gfs_rgrpd * -recent_rgrp_first(struct gfs_sbd *sdp, uint64_t rglast) -{ - struct list_head *tmp, *head; - struct gfs_rgrpd *rgd = NULL; - - spin_lock(&sdp->sd_rg_recent_lock); - - if (list_empty(&sdp->sd_rg_recent)) - goto out; - - if (!rglast) - goto first; - - for (head = &sdp->sd_rg_recent, tmp = head->next; - tmp != head; - tmp = tmp->next) { - rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); - if (rgd->rd_ri.ri_addr == rglast) - goto out; - } - - first: - rgd = list_entry(sdp->sd_rg_recent.next, struct gfs_rgrpd, rd_recent); - - out: - spin_unlock(&sdp->sd_rg_recent_lock); - - return rgd; -} - -/** - * recent_rgrp_next - get next RG from "recent" list - * @cur_rgd: current rgrp - * @remove: - * - * Returns: The next rgrp in the recent list - */ - -static struct gfs_rgrpd * -recent_rgrp_next(struct gfs_rgrpd *cur_rgd, int remove) -{ - struct gfs_sbd *sdp = cur_rgd->rd_sbd; - struct list_head *tmp, *head; - struct gfs_rgrpd *rgd; - - spin_lock(&sdp->sd_rg_recent_lock); - - for (head = &sdp->sd_rg_recent, tmp = head->next; - tmp != head; - tmp = tmp->next) { - rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); - if (rgd == cur_rgd) { - if (cur_rgd->rd_recent.next != head) - rgd = list_entry(cur_rgd->rd_recent.next, - struct gfs_rgrpd, rd_recent); - else - rgd = NULL; - - if (remove) - list_del(&cur_rgd->rd_recent); - - goto out; - } - } - - rgd = NULL; - if (!list_empty(head)) - rgd = list_entry(head->next, struct gfs_rgrpd, rd_recent); - - out: - spin_unlock(&sdp->sd_rg_recent_lock); - - return rgd; -} - -/** - * recent_rgrp_add - add an RG to tail of "recent" list - * @new_rgd: The rgrp to add - * - * Before adding, make sure that: - * 1) it's not already on the list - * 2) there's still room for more entries - * The capacity limit imposed on the "recent" list is basically a node's "share" - * of rgrps within a cluster, i.e. (total # rgrps) / (# nodes (journals)) - */ - -static void -recent_rgrp_add(struct gfs_rgrpd *new_rgd) -{ - struct gfs_sbd *sdp = new_rgd->rd_sbd; - struct list_head *tmp, *head; - struct gfs_rgrpd *rgd = NULL; - unsigned int count = 0; - unsigned int max = sdp->sd_rgcount / gfs_num_journals(sdp); - - spin_lock(&sdp->sd_rg_recent_lock); - - for (head = &sdp->sd_rg_recent, tmp = head->next; - tmp != head; - tmp = tmp->next) { - rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); - if (rgd == new_rgd) - goto out; - - if (++count >= max) - goto out; - } - new_rgd->rd_try_counter = 0; - list_add_tail(&new_rgd->rd_recent, &sdp->sd_rg_recent); - - out: - spin_unlock(&sdp->sd_rg_recent_lock); -} - -/** - * forward_rgrp_get - get an rgrp to try next from full list - * @sdp: The GFS superblock - * - * Returns: The rgrp to try next - */ - -static struct gfs_rgrpd * -forward_rgrp_get(struct gfs_sbd *sdp) -{ - struct gfs_rgrpd *rgd; - unsigned int journals = gfs_num_journals(sdp); - unsigned int rg = 0, x; - - spin_lock(&sdp->sd_rg_forward_lock); - - rgd = sdp->sd_rg_forward; - if (!rgd) { - if (sdp->sd_rgcount >= journals) - rg = sdp->sd_rgcount * - sdp->sd_lockstruct.ls_jid / - journals; - - for (x = 0, rgd = gfs_rgrpd_get_first(sdp); - x < rg; - x++, rgd = gfs_rgrpd_get_next(rgd)) - /* Do Nothing */; - - sdp->sd_rg_forward = rgd; - } - - spin_unlock(&sdp->sd_rg_forward_lock); - - return rgd; -} - -/** - * forward_rgrp_set - set the forward rgrp pointer - * @sdp: the filesystem - * @rgd: The new forward rgrp - * - */ - -static void -forward_rgrp_set(struct gfs_sbd *sdp, struct gfs_rgrpd *rgd) -{ - spin_lock(&sdp->sd_rg_forward_lock); - sdp->sd_rg_forward = rgd; - spin_unlock(&sdp->sd_rg_forward_lock); -} - -/** - * get_local_rgrp - Choose and lock a rgrp for allocation - * @ip: the inode to reserve space for - * @rgp: the chosen and locked rgrp - * - * Try to acquire rgrp in way which avoids contending with others. - * - * Returns: errno - */ - -static int -get_local_rgrp(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrpd *rgd, *begin = NULL; - struct gfs_alloc *al = ip->i_alloc; - int flags = LM_FLAG_TRY; - int skipped = 0; - int loops = 0; - int error; - int try_flag; - unsigned int try_threshold = gfs_tune_get(sdp, gt_rgrp_try_threshold); - - /* Try recently successful rgrps */ - - rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); - - while (rgd) { - try_flag = (rgd->rd_try_counter >= try_threshold) ? - 0: LM_FLAG_TRY; - error = gfs_glock_nq_init(rgd->rd_gl, - LM_ST_EXCLUSIVE, try_flag, - &al->al_rgd_gh); - switch (error) { - case 0: - if (try_rgrp_fit(rgd, al)) { - rgd->rd_try_counter = 0; - goto out; - } - gfs_glock_dq_uninit(&al->al_rgd_gh); - rgd = recent_rgrp_next(rgd, TRUE); - break; - - case GLR_TRYFAILED: - rgd->rd_try_counter++; - rgd = recent_rgrp_next(rgd, FALSE); - break; - - default: - return error; - } - } - - /* Go through full list of rgrps */ - - begin = rgd = forward_rgrp_get(sdp); - - for (;;) { - error = gfs_glock_nq_init(rgd->rd_gl, - LM_ST_EXCLUSIVE, flags, - &al->al_rgd_gh); - switch (error) { - case 0: - if (try_rgrp_fit(rgd, al)) - goto out; - gfs_glock_dq_uninit(&al->al_rgd_gh); - break; - - case GLR_TRYFAILED: - skipped++; - break; - - default: - return error; - } - - rgd = gfs_rgrpd_get_next(rgd); - if (!rgd) - rgd = gfs_rgrpd_get_first(sdp); - - if (rgd == begin) { - if (++loops >= 2 || !skipped) - return -ENOSPC; - flags = 0; - } - } - - out: - ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; - - if (begin) { - recent_rgrp_add(rgd); - rgd = gfs_rgrpd_get_next(rgd); - if (!rgd) - rgd = gfs_rgrpd_get_first(sdp); - forward_rgrp_set(sdp, rgd); - } - - return 0; -} - -/** - * gfs_inplace_reserve_i - Reserve space in the filesystem - * @ip: the inode to reserve space for - * - * Acquire resource group locks to allow for the maximum allocation - * described by "res". - * - * This should probably become more complex again, but for now, let's go - * for simple (one resource group) reservations. - * - * Returns: errno - */ - -int -gfs_inplace_reserve_i(struct gfs_inode *ip, - char *file, unsigned int line) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - int error; - - if (gfs_assert_warn(sdp, - al->al_requested_di || - al->al_requested_data || - al->al_requested_meta)) - return -EINVAL; - - error = gfs_rindex_hold(sdp, &al->al_ri_gh); - if (error) - return error; - - error = get_local_rgrp(ip); - if (error) { - gfs_glock_dq_uninit(&al->al_ri_gh); - return error; - } - - gfs_depend_sync(al->al_rgd); - - al->al_file = file; - al->al_line = line; - - return 0; -} - -/** - * gfs_inplace_release - release an inplace reservation - * @ip: the inode the reservation was taken out on - * - * Release a reservation made by gfs_inplace_reserve(). - */ - -void -gfs_inplace_release(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - - if (gfs_assert_warn(sdp, al->al_alloced_di <= al->al_requested_di) == -1) - printk("GFS: fsid=%s: al_alloced_di = %u, al_requested_di = %u\n" - "GFS: fsid=%s: al_file = %s, al_line = %u\n", - sdp->sd_fsname, al->al_alloced_di, al->al_requested_di, - sdp->sd_fsname, al->al_file, al->al_line); - if (gfs_assert_warn(sdp, al->al_alloced_meta <= al->al_reserved_meta) == -1) - printk("GFS: fsid=%s: al_alloced_meta = %u, al_reserved_meta = %u\n" - "GFS: fsid=%s: al_file = %s, al_line = %u\n", - sdp->sd_fsname, al->al_alloced_meta, al->al_reserved_meta, - sdp->sd_fsname, al->al_file, al->al_line); - if (gfs_assert_warn(sdp, al->al_alloced_data <= al->al_reserved_data) == -1) - printk("GFS: fsid=%s: al_alloced_data = %u, al_reserved_data = %u\n" - "GFS: fsid=%s: al_file = %s, al_line = %u\n", - sdp->sd_fsname, al->al_alloced_data, al->al_reserved_data, - sdp->sd_fsname, al->al_file, al->al_line); - - al->al_rgd = NULL; - gfs_glock_dq_uninit(&al->al_rgd_gh); - gfs_glock_dq_uninit(&al->al_ri_gh); -} - -/** - * gfs_get_block_type - Check a block in a RG is of given type - * @rgd: the resource group holding the block - * @block: the block number - * - * Returns: The block type (GFS_BLKST_*) - */ - -unsigned char -gfs_get_block_type(struct gfs_rgrpd *rgd, uint64_t block) -{ - struct gfs_bitmap *bits = NULL; - uint32_t length, rgrp_block, buf_block; - unsigned int buf; - unsigned char type; - - length = rgd->rd_ri.ri_length; - rgrp_block = block - rgd->rd_ri.ri_data1; - - for (buf = 0; buf < length; buf++) { - bits = &rgd->rd_bits[buf]; - if (rgrp_block < (bits->bi_start + bits->bi_len) * GFS_NBBY) - break; - } - - gfs_assert(rgd->rd_sbd, buf < length,); - buf_block = rgrp_block - bits->bi_start * GFS_NBBY; - - type = gfs_testbit(rgd, - rgd->rd_bh[buf]->b_data + bits->bi_offset, - bits->bi_len, buf_block); - - return type; -} - -/** - * blkalloc_internal - find a block in @old_state, change allocation - * state to @new_state - * @rgd: the resource group descriptor - * @goal: the goal block within the RG (start here to search for avail block) - * @old_state: GFS_BLKST_XXX the before-allocation state to find - * @new_state: GFS_BLKST_XXX the after-allocation block state - * - * Walk rgrp's bitmap to find bits that represent a block in @old_state. - * Add the found bitmap buffer to the transaction. - * Set the found bits to @new_state to change block's allocation state. - * - * This function never fails, because we wouldn't call it unless we - * know (from reservation results, etc.) that a block is available. - * - * Scope of @goal and returned block is just within rgrp (32-bit), - * not the whole filesystem (64-bit). - * - * Returns: the block # allocated (32-bit rgrp scope) - */ - -static uint32_t -blkalloc_internal(struct gfs_rgrpd *rgd, - uint32_t goal, - unsigned char old_state, unsigned char new_state) -{ - struct gfs_bitmap *bits = NULL; - uint32_t length = rgd->rd_ri.ri_length; - uint32_t blk = 0; - unsigned int buf, x; - - /* Find bitmap block that contains bits for goal block */ - for (buf = 0; buf < length; buf++) { - bits = &rgd->rd_bits[buf]; - if (goal < (bits->bi_start + bits->bi_len) * GFS_NBBY) - break; - } - - gfs_assert(rgd->rd_sbd, buf < length,); - - /* Convert scope of "goal" from rgrp-wide to within found bit block */ - goal -= bits->bi_start * GFS_NBBY; - - /* Search (up to entire) bitmap in this rgrp for allocatable block. - "x <= length", instead of "x < length", because we typically start - the search in the middle of a bit block, but if we can't find an - allocatable block anywhere else, we want to be able wrap around and - search in the first part of our first-searched bit block. */ - for (x = 0; x <= length; x++) { - blk = gfs_bitfit(rgd, - rgd->rd_bh[buf]->b_data + bits->bi_offset, - bits->bi_len, goal, old_state); - if (blk != BFITNOENT) - break; - - /* Try next bitmap block (wrap back to rgrp header if at end) */ - buf = (buf + 1) % length; - bits = &rgd->rd_bits[buf]; - goal = 0; - } - - if (unlikely(x > length)) { - printk("GFS error: possible RG corruption\n"); - printk(" please run gfs_fsck after withdraw\n"); - dump_stack(); - if (gfs_assert_withdraw(rgd->rd_sbd, x <= length)) - blk = 0; - } - - /* Attach bitmap buffer to trans, modify bits to do block alloc */ - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[buf]); - gfs_setbit(rgd, - rgd->rd_bh[buf]->b_data + bits->bi_offset, - bits->bi_len, blk, new_state); - - /* Return allocated block #, rgrp scope (32-bit) */ - return bits->bi_start * GFS_NBBY + blk; -} - -/** - * blkfree_internal - Change alloc state of given block(s) - * @sdp: the filesystem - * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks - * @blen: the length of the block run (all must lie within ONE RG!) - * @new_state: GFS_BLKST_XXX the after-allocation block state - * - * Returns: Resource group containing the block(s) - * - * Find rgrp containing @bstart. - * For each block in run: - * Find allocation bitmap buffer. - * Add bitmap buffer to transaction. - * Set bits to new state. - * Typically used to free blocks to GFS_BLKST_FREE or GFS_BLKST_FREEMETA, - * but @new_state can be any GFS_BLKST_XXX - * - */ - -static struct gfs_rgrpd * -blkfree_internal(struct gfs_sbd *sdp, uint64_t bstart, uint32_t blen, - unsigned char new_state) -{ - struct gfs_rgrpd *rgd; - struct gfs_bitmap *bits = NULL; - uint32_t length, rgrp_blk, buf_blk; - unsigned int buf; - - /* Find rgrp */ - rgd = gfs_blk2rgrpd(sdp, bstart); - if (!rgd) { - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: block = %"PRIu64"\n", - sdp->sd_fsname, bstart); - return NULL; - } - - length = rgd->rd_ri.ri_length; - - /* Convert blk # from filesystem scope (64-bit) to RG scope (32-bit) */ - rgrp_blk = bstart - rgd->rd_ri.ri_data1; - - while (blen--) { - /* Find bitmap buffer for this block */ - for (buf = 0; buf < length; buf++) { - bits = &rgd->rd_bits[buf]; - if (rgrp_blk < (bits->bi_start + bits->bi_len) * GFS_NBBY) - break; - } - - gfs_assert(rgd->rd_sbd, buf < length,); - - /* Find bits and set 'em */ - buf_blk = rgrp_blk - bits->bi_start * GFS_NBBY; - rgrp_blk++; - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[buf]); - gfs_setbit(rgd, - rgd->rd_bh[buf]->b_data + bits->bi_offset, - bits->bi_len, buf_blk, new_state); - } - - return rgd; -} - -/** - * clump_alloc - Allocate a clump of metadata blocks - * @rgd: the resource group in which to allocate - * @first: returns the first block allocated - * - * Returns: errno - * - * Bitmap-allocate a clump of metadata blocks - * Write metadata blocks to disk with dummy meta-headers - * Add meta-headers to incore meta-header cache - */ - -static int -clump_alloc(struct gfs_rgrpd *rgd, uint32_t *first) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - struct gfs_meta_header mh; - struct buffer_head **bh; - uint32_t goal, blk; - unsigned int x; - int error = 0; - - /* Dummy meta-header template */ - memset(&mh, 0, sizeof(struct gfs_meta_header)); - mh.mh_magic = GFS_MAGIC; - mh.mh_type = GFS_METATYPE_NONE; - - /* Array of bh pointers used in several steps */ - bh = gmalloc(GFS_META_CLUMP * sizeof(struct buffer_head *)); - memset(bh, 0, GFS_META_CLUMP * sizeof(struct buffer_head *)); - - /* Since we're looking for data blocks to change into meta blocks, - use last alloc'd *data* (not meta) block as start point */ - goal = rgd->rd_last_alloc_data; - - for (x = 0; x < GFS_META_CLUMP; x++) { - blk = blkalloc_internal(rgd, goal, GFS_BLKST_FREE, - GFS_BLKST_FREEMETA); - if (!x) - *first = blk; - - bh[x] = gfs_dgetblk(rgd->rd_gl, rgd->rd_ri.ri_data1 + blk); - - gfs_prep_new_buffer(bh[x]); - - gfs_meta_header_out(&mh, bh[x]->b_data); - ((struct gfs_meta_header *)bh[x]->b_data)->mh_generation = 0; - - /* start write of new meta-buffer to disk */ - error = gfs_dwrite(sdp, bh[x], DIO_DIRTY | DIO_START); - if (error) - goto out; - - goal = blk; - } - - /* Block alloc start point for next time */ - rgd->rd_last_alloc_data = goal; - - /* Wait for all new meta-buffers to get on-disk */ - for (x = 0; x < GFS_META_CLUMP; x++) { - error = gfs_dwrite(sdp, bh[x], DIO_WAIT); - if (error) - goto out; - } - - /* Add all new meta-headers to meta-header cache */ - gfs_mhc_add(rgd, bh, GFS_META_CLUMP); - - gfs_assert_withdraw(sdp, rgd->rd_rg.rg_free >= GFS_META_CLUMP); - rgd->rd_rg.rg_free -= GFS_META_CLUMP; - rgd->rd_rg.rg_freemeta += GFS_META_CLUMP; - - out: - for (x = 0; x < GFS_META_CLUMP; x++) - if (bh[x]) { - gfs_dwrite(sdp, bh[x], DIO_WAIT); - brelse(bh[x]); - } - kfree(bh); - - return error; -} - -/** - * gfs_blkalloc - Allocate a data block - * @ip: the inode to allocate the data block for - * @block: the block allocated - * - */ - -void -gfs_blkalloc(struct gfs_inode *ip, uint64_t *block) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - struct gfs_rgrpd *rgd = al->al_rgd; - uint32_t goal, blk; - int same; - - same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); - goal = (same) ? ip->i_di.di_goal_dblk : rgd->rd_last_alloc_data; - - blk = blkalloc_internal(rgd, goal, - GFS_BLKST_FREE, GFS_BLKST_USED); - rgd->rd_last_alloc_data = blk; - - if (!same) { - ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; - ip->i_di.di_goal_mblk = 0; - } - ip->i_di.di_goal_dblk = blk; - - *block = rgd->rd_ri.ri_data1 + blk; - - gfs_assert_withdraw(sdp, rgd->rd_rg.rg_free); - rgd->rd_rg.rg_free--; - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); - - al->al_alloced_data++; - - gfs_trans_add_quota(sdp, +1, ip->i_di.di_uid, ip->i_di.di_gid); - - /* total=0, free=-1, dinodes=0 */ - gfs_statfs_modify(sdp, 0, -1, 0); -} - -/** - * gfs_metaalloc - Allocate a metadata block to a file - * @ip: the file - * @block: the block allocated - * - * Returns: errno - */ - -int -gfs_metaalloc(struct gfs_inode *ip, uint64_t *block) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_alloc *al = ip->i_alloc; - struct gfs_rgrpd *rgd = al->al_rgd; - uint32_t goal, blk; - int same; - int error; - - same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); - - if (!rgd->rd_rg.rg_freemeta) { - error = clump_alloc(rgd, &goal); - if (error) - return error; - - al->al_alloced_data += GFS_META_CLUMP; - } else - goal = (same) ? ip->i_di.di_goal_mblk : rgd->rd_last_alloc_meta; - - blk = blkalloc_internal(rgd, goal, - GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); - rgd->rd_last_alloc_meta = blk; - - if (!same) { - ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; - ip->i_di.di_goal_dblk = 0; - } - ip->i_di.di_goal_mblk = blk; - - *block = rgd->rd_ri.ri_data1 + blk; - - gfs_assert_withdraw(sdp, rgd->rd_rg.rg_freemeta); - rgd->rd_rg.rg_freemeta--; - rgd->rd_rg.rg_usedmeta++; - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); - - al->al_alloced_meta++; - - gfs_trans_add_quota(sdp, +1, ip->i_di.di_uid, ip->i_di.di_gid); - - /* total=0, free=-1, dinode=0 */ - gfs_statfs_modify(sdp, 0, -1, 0); - - return 0; -} - -/** - * gfs_dialloc - Allocate a dinode - * @dip: the directory that the inode is going in - * @block: the block (result) which this function allocates as the dinode - * (64-bit filesystem scope) - * - * Returns: errno - */ - -int -gfs_dialloc(struct gfs_inode *dip, uint64_t *block) -{ - struct gfs_sbd *sdp = dip->i_sbd; - struct gfs_alloc *al = dip->i_alloc; - struct gfs_rgrpd *rgd = al->al_rgd; - uint32_t goal, blk; - int error = 0; - - if (rgd->rd_rg.rg_freemeta) - /* pick up where we left off last time */ - goal = rgd->rd_last_alloc_meta; - else { - /* no free meta blocks, allocate a bunch more */ - error = clump_alloc(rgd, &goal); - if (error) - return error; - - al->al_alloced_data += GFS_META_CLUMP; - } - - /* Alloc the dinode; 32-bit "blk" is block offset within rgrp */ - blk = blkalloc_internal(rgd, goal, - GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); - - /* remember where we left off, for next time */ - rgd->rd_last_alloc_meta = blk; - - /* convert from rgrp scope (32-bit) to filesystem scope (64-bit) */ - *block = rgd->rd_ri.ri_data1 + blk; - - gfs_assert_withdraw(rgd->rd_sbd, rgd->rd_rg.rg_freemeta); - rgd->rd_rg.rg_freemeta--; - rgd->rd_rg.rg_useddi++; - - /* Attach rgrp header to trans, update freemeta and useddi stats */ - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); - - /* Update stats in in-place reservation struct */ - al->al_alloced_di++; - al->al_alloced_meta++; - - /* total=0, free=-1, dinodes=1 */ - gfs_statfs_modify(sdp, 0, -1, +1); - - return error; -} - -/** - * gfs_blkfree - free a contiguous run of data block(s) - * @ip: the inode these blocks are being freed from - * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks - * @blen: the length of the block run (all must lie within ONE RG!) - * - * Bitmap-deallocate the blocks (to FREE data state), add bitmap blks to trans - * Update rgrp alloc statistics in rgrp header, add rgrp header buf to trans - * Update quotas, add to trans. - */ - -void -gfs_blkfree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrpd *rgd; - - rgd = blkfree_internal(sdp, bstart, blen, GFS_BLKST_FREE); - if (!rgd) - return; - - rgd->rd_rg.rg_free += blen; - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); - - gfs_trans_add_quota(sdp, -(int64_t)blen, - ip->i_di.di_uid, - ip->i_di.di_gid); - /* total=0, free=+blen, dinodes=0 */ - gfs_statfs_modify(sdp, 0, blen, 0); -} - -/** - * gfs_metafree - free a contiguous run of metadata block(s) - * @ip: the inode these blocks are being freed from - * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks - * @blen: the length of the block run (all must lie within ONE RG!) - * - * Bitmap-deallocate the blocks (to FREEMETA state), add bitmap blks to trans. - * Update rgrp alloc statistics in rgrp header, add rgrp header to trans. - * Update quotas (quotas include metadata, not just data block usage), - * add to trans. - * Release deallocated buffers, add to meta-header cache (we save these in-core - * so we don't need to re-read meta blocks if/when they are re-alloc'd). - */ - -void -gfs_metafree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen) -{ - struct gfs_sbd *sdp = ip->i_sbd; - struct gfs_rgrpd *rgd; - - rgd = blkfree_internal(sdp, bstart, blen, GFS_BLKST_FREEMETA); - if (!rgd) - return; - - if (rgd->rd_rg.rg_usedmeta < blen) - gfs_consist_rgrpd(rgd); - rgd->rd_rg.rg_usedmeta -= blen; - rgd->rd_rg.rg_freemeta += blen; - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); - - /* total=0, free=blen, dinode=0 */ - gfs_statfs_modify(sdp, 0, blen, 0); - - gfs_trans_add_quota(sdp, -(int64_t)blen, - ip->i_di.di_uid, - ip->i_di.di_gid); - gfs_wipe_buffers(ip, rgd, bstart, blen); -} - -/** - * gfs_difree_uninit - free a dinode block - * @rgd: the resource group that contains the dinode - * @addr: the dinode address - * - * De-allocate the dinode to FREEMETA using block alloc bitmap. - * Update rgrp's block usage statistics (used dinode--, free meta++). - * Add rgrp header to transaction. - */ - -void -gfs_difree_uninit(struct gfs_rgrpd *rgd, uint64_t addr) -{ - struct gfs_rgrpd *tmp_rgd; - - tmp_rgd = blkfree_internal(rgd->rd_sbd, addr, 1, - GFS_BLKST_FREEMETA); - if (!tmp_rgd) - return; - gfs_assert_withdraw(rgd->rd_sbd, rgd == tmp_rgd); - - if (!rgd->rd_rg.rg_useddi) - gfs_consist_rgrpd(rgd); - rgd->rd_rg.rg_useddi--; - rgd->rd_rg.rg_freemeta++; - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); - - /* total=0, free=1, dinodes=-1 */ - gfs_statfs_modify(rgd->rd_sbd, 0, +1, -1); -} - -/** - * gfs_difree - free a dinode block - * @rgd: the resource group that contains the dinode - * @ip: the inode representing the dinode to free - * - * Free the dinode block to FREEMETA, update rgrp's block usage stats. - * Update quotas (quotas include metadata, not just data block usage), - * add to trans. - * Release deallocated buffers, add to meta-header cache (we save these in-core - * so we don't need to re-read meta blocks if/when they are re-alloc'd). - */ - -void -gfs_difree(struct gfs_rgrpd *rgd, struct gfs_inode *ip) -{ - gfs_difree_uninit(rgd, ip->i_num.no_addr); - gfs_trans_add_quota(ip->i_sbd, -1, ip->i_di.di_uid, ip->i_di.di_gid); - gfs_wipe_buffers(ip, rgd, ip->i_num.no_addr, 1); -} - -/** - * gfs_rlist_add - add a RG to a list of RGs - * @sdp: the filesystem - * @rlist: the list of resource groups - * @block: the block - * - * Figure out what RG a block belongs to and add that RG to the list - * - * FIXME: Don't use gmalloc() - * - */ - -void -gfs_rlist_add(struct gfs_sbd *sdp, struct gfs_rgrp_list *rlist, uint64_t block) -{ - struct gfs_rgrpd *rgd; - struct gfs_rgrpd **tmp; - unsigned int new_space; - unsigned int x; - - if (gfs_assert_warn(sdp, !rlist->rl_ghs)) - return; - - rgd = gfs_blk2rgrpd(sdp, block); - if (!rgd) { - if (gfs_consist(sdp)) - printk("GFS: fsid=%s: block = %"PRIu64"\n", - sdp->sd_fsname, block); - return; - } - - for (x = 0; x < rlist->rl_rgrps; x++) - if (rlist->rl_rgd[x] == rgd) - return; - - if (rlist->rl_rgrps == rlist->rl_space) { - new_space = rlist->rl_space + 10; - - tmp = gmalloc(new_space * sizeof(struct gfs_rgrpd *)); - - if (rlist->rl_rgd) { - memcpy(tmp, rlist->rl_rgd, - rlist->rl_space * sizeof(struct gfs_rgrpd *)); - kfree(rlist->rl_rgd); - } - - rlist->rl_space = new_space; - rlist->rl_rgd = tmp; - } - - rlist->rl_rgd[rlist->rl_rgrps++] = rgd; -} - -/** - * gfs_rlist_alloc - all RGs have been added to the rlist, now allocate - * and initialize an array of glock holders for them - * @rlist: the list of resource groups - * @state: the lock state to acquire the RG lock in - * @flags: the modifier flags for the holder structures - * - * FIXME: Don't use gmalloc() - * - */ - -void -gfs_rlist_alloc(struct gfs_rgrp_list *rlist, unsigned int state, int flags) -{ - unsigned int x; - - rlist->rl_ghs = gmalloc(rlist->rl_rgrps * sizeof(struct gfs_holder)); - for (x = 0; x < rlist->rl_rgrps; x++) - gfs_holder_init(rlist->rl_rgd[x]->rd_gl, - state, flags, - &rlist->rl_ghs[x]); -} - -/** - * gfs_rlist_free - free a resource group list - * @list: the list of resource groups - * - */ - -void -gfs_rlist_free(struct gfs_rgrp_list *rlist) -{ - unsigned int x; - - if (rlist->rl_rgd) - kfree(rlist->rl_rgd); - - if (rlist->rl_ghs) { - for (x = 0; x < rlist->rl_rgrps; x++) - gfs_holder_uninit(&rlist->rl_ghs[x]); - kfree(rlist->rl_ghs); - } -} - -/** - * gfs_reclaim_metadata - reclaims unused metadata - * @sdp: the file system - * @inodes: - * @metadata: - * - * This function will look through the resource groups and - * free the unused metadata. - * - * Returns: errno - */ - -int -gfs_reclaim_metadata(struct gfs_sbd *sdp, - uint64_t *inodes, - uint64_t *metadata) -{ - struct gfs_holder ji_gh, ri_gh, rgd_gh, t_gh; - struct gfs_rgrpd *rgd; - struct gfs_rgrp *rg; - struct gfs_dinode *di; - struct gfs_inum next; - struct buffer_head *bh; - uint32_t flags; - uint32_t goal; - unsigned int x; - int error = 0; - - *inodes = *metadata = 0; - - /* Acquire the jindex lock here so we don't deadlock with a - process writing the the jindex inode. :-( */ - - error = gfs_jindex_hold(sdp, &ji_gh); - if (error) - goto fail; - - error = gfs_rindex_hold(sdp, &ri_gh); - if (error) - goto fail_jindex_relse; - - for (rgd = gfs_rgrpd_get_first(sdp); - rgd; - rgd = gfs_rgrpd_get_next(rgd)) { - error = gfs_glock_nq_init(rgd->rd_gl, - LM_ST_EXCLUSIVE, GL_NOCACHE, - &rgd_gh); - if (error) - goto fail_rindex_relse; - - rgrp_verify(rgd); - - rg = &rgd->rd_rg; - - if (!rg->rg_freedi && !rg->rg_freemeta) { - gfs_glock_dq_uninit(&rgd_gh); - continue; - } - - gfs_mhc_zap(rgd); - gfs_depend_sync(rgd); - - error = gfs_lock_fs_check_clean(sdp, LM_ST_EXCLUSIVE, &t_gh); - if (error) - goto fail_gunlock_rg; - - error = gfs_trans_begin(sdp, rgd->rd_ri.ri_length, 0); - if (error) - goto fail_unlock_fs; - - next = rg->rg_freedi_list; - - for (x = rg->rg_freedi; x--;) { - if (!next.no_formal_ino || !next.no_addr) { - gfs_consist_rgrpd(rgd); - error = -EIO; - goto fail_end_trans; - } - - blkfree_internal(sdp, next.no_addr, 1, GFS_BLKST_FREE); - - error = gfs_dread(rgd->rd_gl, next.no_addr, - DIO_FORCE | DIO_START | DIO_WAIT, &bh); - if (error) - goto fail_end_trans; - - di = (struct gfs_dinode *)bh->b_data; - flags = di->di_flags; - flags = gfs32_to_cpu(flags); - if (!(flags & GFS_DIF_UNUSED)) { - gfs_consist_rgrpd(rgd); - brelse(bh); - error = -EIO; - goto fail_end_trans; - } - - gfs_inum_in(&next, (char *)&di->di_next_unused); - - brelse(bh); - - rg->rg_freedi--; - rg->rg_free++; - (*inodes)++; - } - - if (next.no_formal_ino || next.no_addr) { - gfs_consist_rgrpd(rgd); - error = -EIO; - goto fail_end_trans; - } - rg->rg_freedi_list = next; - - goal = 0; - for (x = rg->rg_freemeta; x--;) { - goal = blkalloc_internal(rgd, goal, - GFS_BLKST_FREEMETA, GFS_BLKST_FREE); - rg->rg_freemeta--; - rg->rg_free++; - (*metadata)++; - } - - gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); - gfs_rgrp_out(rg, rgd->rd_bh[0]->b_data); - - gfs_trans_end(sdp); - - gfs_glock_dq_uninit(&t_gh); - - gfs_glock_dq_uninit(&rgd_gh); - } - - gfs_glock_dq_uninit(&ri_gh); - - gfs_glock_dq_uninit(&ji_gh); - - return 0; - - fail_end_trans: - gfs_trans_end(sdp); - - fail_unlock_fs: - gfs_glock_dq_uninit(&t_gh); - - fail_gunlock_rg: - gfs_glock_dq_uninit(&rgd_gh); - - fail_rindex_relse: - gfs_glock_dq_uninit(&ri_gh); - - fail_jindex_relse: - gfs_glock_dq_uninit(&ji_gh); - - fail: - return error; -} diff --git a/gfs-kernel/src/gfs/rgrp.h b/gfs-kernel/src/gfs/rgrp.h deleted file mode 100644 index ab7f556..0000000 --- a/gfs-kernel/src/gfs/rgrp.h +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __RGRP_DOT_H__ -#define __RGRP_DOT_H__ - -void gfs_mhc_add(struct gfs_rgrpd *rgd, struct buffer_head **bh, - unsigned int num); -int gfs_mhc_fish(struct gfs_sbd *sdp, struct buffer_head *bh); -void gfs_mhc_zap(struct gfs_rgrpd *rgd); - -void gfs_depend_add(struct gfs_rgrpd *rgd, uint64_t formal_ino); -void gfs_depend_sync(struct gfs_rgrpd *rgd); - -struct gfs_rgrpd *gfs_blk2rgrpd(struct gfs_sbd *sdp, uint64_t blk); -struct gfs_rgrpd *gfs_rgrpd_get_first(struct gfs_sbd *sdp); -struct gfs_rgrpd *gfs_rgrpd_get_next(struct gfs_rgrpd *rgd); - -void gfs_clear_rgrpd(struct gfs_sbd *sdp); - -int gfs_rindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ri_gh); - -int gfs_rgrp_read(struct gfs_rgrpd *rgd); -void gfs_rgrp_relse(struct gfs_rgrpd *rgd); - -void gfs_rgrp_lvb_fill(struct gfs_rgrpd *rgd); -int gfs_rgrp_lvb_init(struct gfs_rgrpd *rgd); - -struct gfs_alloc *gfs_alloc_get(struct gfs_inode *ip); -void gfs_alloc_put(struct gfs_inode *ip); - -int gfs_inplace_reserve_i(struct gfs_inode *ip, - char *file, unsigned int line); -#define gfs_inplace_reserve(ip) \ -gfs_inplace_reserve_i((ip), __FILE__, __LINE__) - -void gfs_inplace_release(struct gfs_inode *ip); - -unsigned char gfs_get_block_type(struct gfs_rgrpd *rgd, uint64_t block); - -void gfs_blkalloc(struct gfs_inode *ip, uint64_t *block); -int gfs_metaalloc(struct gfs_inode *ip, uint64_t *block); -int gfs_dialloc(struct gfs_inode *dip, uint64_t *block); - -void gfs_blkfree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen); -void gfs_metafree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen); -void gfs_difree_uninit(struct gfs_rgrpd *rgd, uint64_t addr); -void gfs_difree(struct gfs_rgrpd *rgd, struct gfs_inode *ip); - -extern void gfs_statfs_modify(struct gfs_sbd *sdp, - int64_t total, - int64_t free, - int64_t dinodes); -/* - * gfs_rgrp_list - * - * Used to collect a list of all resource groups spanned by a given - * inode/file/directory - */ -struct gfs_rgrp_list { - unsigned int rl_rgrps; /* # (qty) of rgrps in list (array) */ - unsigned int rl_space; /* Current capacity in list for rgrps */ - struct gfs_rgrpd **rl_rgd; /* Array of ptrs to rgrp descriptors */ - struct gfs_holder *rl_ghs; /* Array of glock holders for rgrps */ -}; - -void gfs_rlist_add(struct gfs_sbd *sdp, struct gfs_rgrp_list *rlist, - uint64_t block); -void gfs_rlist_alloc(struct gfs_rgrp_list *rlist, unsigned int state, - int flags); -void gfs_rlist_free(struct gfs_rgrp_list *rlist); - -int gfs_reclaim_metadata(struct gfs_sbd *sdp, - uint64_t *inodes, - uint64_t *metadata); - -#endif /* __RGRP_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/super.c b/gfs-kernel/src/gfs/super.c deleted file mode 100644 index 3752d96..0000000 --- a/gfs-kernel/src/gfs/super.c +++ /dev/null @@ -1,1287 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/statfs.h> -#include <linux/types.h> -#include <linux/buffer_head.h> -#include <linux/vmalloc.h> - -#include "gfs.h" -#include "dio.h" -#include "file.h" -#include "format.h" -#include "glock.h" -#include "glops.h" -#include "inode.h" -#include "log.h" -#include "quota.h" -#include "recovery.h" -#include "rgrp.h" -#include "super.h" -#include "unlinked.h" -#include "trans.h" - -/** - * gfs_tune_init - Fill a gfs_tune structure with default values - * @gt: tune - * - */ - -void -gfs_tune_init(struct gfs_tune *gt) -{ - spin_lock_init(>->gt_spin); - - gt->gt_ilimit1 = 100; - gt->gt_ilimit1_tries = 3; - gt->gt_ilimit1_min = 1; - gt->gt_ilimit2 = 500; - gt->gt_ilimit2_tries = 10; - gt->gt_ilimit2_min = 3; - gt->gt_demote_secs = 300; - gt->gt_incore_log_blocks = 1024; - gt->gt_jindex_refresh_secs = 60; - gt->gt_depend_secs = 60; - gt->gt_scand_secs = 5; - gt->gt_recoverd_secs = 60; - gt->gt_logd_secs = 1; - gt->gt_quotad_secs = 5; - gt->gt_inoded_secs = 15; - gt->gt_glock_purge = 0; - gt->gt_quota_simul_sync = 64; - gt->gt_quota_warn_period = 10; - gt->gt_atime_quantum = 3600; - gt->gt_quota_quantum = 60; - gt->gt_quota_scale_num = 1; - gt->gt_quota_scale_den = 1; - gt->gt_quota_enforce = 1; - gt->gt_quota_account = 1; - gt->gt_new_files_jdata = 0; - gt->gt_new_files_directio = 0; - gt->gt_max_atomic_write = 4 << 20; - gt->gt_max_readahead = 1 << 18; - gt->gt_lockdump_size = 131072; - gt->gt_stall_secs = 600; - gt->gt_complain_secs = 10; - gt->gt_reclaim_limit = 5000; - gt->gt_entries_per_readdir = 32; - gt->gt_prefetch_secs = 10; - gt->gt_statfs_slots = 64; - gt->gt_max_mhc = 10000; - gt->gt_greedy_default = HZ / 10; - gt->gt_greedy_quantum = HZ / 40; - gt->gt_greedy_max = HZ / 4; - gt->gt_rgrp_try_threshold = 100; - gt->gt_statfs_fast = 0; -} - -/** - * gfs_check_sb - Check superblock - * @sdp: the filesystem - * @sb: The superblock - * @silent: Don't print a message if the check fails - * - * Checks the version code of the FS is one that we understand how to - * read and that the sizes of the various on-disk structures have not - * changed. - */ - -int -gfs_check_sb(struct gfs_sbd *sdp, struct gfs_sb *sb, int silent) -{ - unsigned int x; - - if (sb->sb_header.mh_magic != GFS_MAGIC || - sb->sb_header.mh_type != GFS_METATYPE_SB) { - if (!silent) - printk("GFS: not a GFS filesystem\n"); - return -EINVAL; - } - - /* If format numbers match exactly, we're done. */ - - if (sb->sb_fs_format == GFS_FORMAT_FS && - sb->sb_multihost_format == GFS_FORMAT_MULTI) - return 0; - - if (sb->sb_fs_format != GFS_FORMAT_FS) { - for (x = 0; gfs_old_fs_formats[x]; x++) - if (gfs_old_fs_formats[x] == sb->sb_fs_format) - break; - - if (!gfs_old_fs_formats[x]) { - printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", - GFS_FORMAT_FS, GFS_FORMAT_MULTI, - sb->sb_fs_format, sb->sb_multihost_format); - printk("GFS: I don't know how to upgrade this FS\n"); - return -EINVAL; - } - } - - if (sb->sb_multihost_format != GFS_FORMAT_MULTI) { - for (x = 0; gfs_old_multihost_formats[x]; x++) - if (gfs_old_multihost_formats[x] == sb->sb_multihost_format) - break; - - if (!gfs_old_multihost_formats[x]) { - printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", - GFS_FORMAT_FS, GFS_FORMAT_MULTI, - sb->sb_fs_format, sb->sb_multihost_format); - printk("GFS: I don't know how to upgrade this FS\n"); - return -EINVAL; - } - } - - if (!sdp->sd_args.ar_upgrade) { - printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", - GFS_FORMAT_FS, GFS_FORMAT_MULTI, - sb->sb_fs_format, sb->sb_multihost_format); - printk("GFS: Use the "upgrade" mount option to upgrade the FS\n"); - printk("GFS: See the manual for more details\n"); - return -EINVAL; - } - - return 0; -} - -/** - * gfs_read_sb - Read super block - * @sdp: The GFS superblock - * @gl: the glock for the superblock (assumed to be held) - * @silent: Don't print message if mount fails - * - */ - -int -gfs_read_sb(struct gfs_sbd *sdp, struct gfs_glock *gl, int silent) -{ - struct buffer_head *bh; - uint32_t hash_blocks, ind_blocks, leaf_blocks; - uint32_t tmp_blocks; - unsigned int x; - int error; - - error = gfs_dread(gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, - DIO_FORCE | DIO_START | DIO_WAIT, &bh); - if (error) { - if (!silent) - printk("GFS: fsid=%s: can't read superblock\n", - sdp->sd_fsname); - return error; - } - - gfs_assert(sdp, sizeof(struct gfs_sb) <= bh->b_size,); - gfs_sb_in(&sdp->sd_sb, bh->b_data); - brelse(bh); - - error = gfs_check_sb(sdp, &sdp->sd_sb, silent); - if (error) - return error; - - sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - - GFS_BASIC_BLOCK_SHIFT; - sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; - sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) / - sizeof(uint64_t); - sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_indirect)) / - sizeof(uint64_t); - sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs_meta_header); - sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; - sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; - sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); - - /* Compute maximum reservation required to add a entry to a directory */ - - hash_blocks = DIV_RU(sizeof(uint64_t) * (1 << GFS_DIR_MAX_DEPTH), - sdp->sd_jbsize); - - ind_blocks = 0; - for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { - tmp_blocks = DIV_RU(tmp_blocks, sdp->sd_inptrs); - ind_blocks += tmp_blocks; - } - - leaf_blocks = 2 + GFS_DIR_MAX_DEPTH; - - sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks; - - sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); - sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; - for (x = 2;; x++) { - uint64_t space, d; - uint32_t m; - - space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; - d = space; - m = do_div(d, sdp->sd_inptrs); - - if (d != sdp->sd_heightsize[x - 1] || m) - break; - sdp->sd_heightsize[x] = space; - } - sdp->sd_max_height = x; - gfs_assert(sdp, sdp->sd_max_height <= GFS_MAX_META_HEIGHT,); - - sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); - sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; - for (x = 2;; x++) { - uint64_t space, d; - uint32_t m; - - space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; - d = space; - m = do_div(d, sdp->sd_inptrs); - - if (d != sdp->sd_jheightsize[x - 1] || m) - break; - sdp->sd_jheightsize[x] = space; - } - sdp->sd_max_jheight = x; - gfs_assert(sdp, sdp->sd_max_jheight <= GFS_MAX_META_HEIGHT,); - - return 0; -} - -/** - * gfs_do_upgrade - upgrade a filesystem - * @sdp: The GFS superblock - * - */ - -int -gfs_do_upgrade(struct gfs_sbd *sdp, struct gfs_glock *sb_gl) -{ - struct gfs_holder ji_gh, t_gh, j_gh; - struct gfs_log_header lh; - struct buffer_head *bh; - unsigned int x; - int error; - - /* If format numbers match exactly, we're done. */ - - if (sdp->sd_sb.sb_fs_format == GFS_FORMAT_FS && - sdp->sd_sb.sb_multihost_format == GFS_FORMAT_MULTI) { - printk("GFS: fsid=%s: no upgrade necessary\n", - sdp->sd_fsname); - sdp->sd_args.ar_upgrade = FALSE; - return 0; - } - - error = gfs_jindex_hold(sdp, &ji_gh); - if (error) - goto fail; - - error = gfs_glock_nq_init(sdp->sd_trans_gl, - LM_ST_EXCLUSIVE, GL_NOCACHE, - &t_gh); - if (error) - goto fail_ji_relse; - - if (test_bit(SDF_ROFS, &sdp->sd_flags)) { - printk("GFS: fsid=%s: can't upgrade: read-only FS\n", - sdp->sd_fsname); - error = -EROFS; - goto fail_gunlock_tr; - } - - for (x = 0; x < sdp->sd_journals; x++) { - error = gfs_glock_nq_num(sdp, - sdp->sd_jindex[x].ji_addr, - &gfs_meta_glops, LM_ST_SHARED, - LM_FLAG_TRY | GL_NOCACHE, &j_gh); - switch (error) { - case 0: - break; - - case GLR_TRYFAILED: - printk("GFS: fsid=%s: journal %u is busy\n", - sdp->sd_fsname, x); - error = -EBUSY; - - default: - goto fail_gunlock_tr; - } - - error = gfs_find_jhead(sdp, &sdp->sd_jindex[x], - j_gh.gh_gl, &lh); - - gfs_glock_dq_uninit(&j_gh); - - if (error) - goto fail_gunlock_tr; - - if (!(lh.lh_flags & GFS_LOG_HEAD_UNMOUNT) || lh.lh_last_dump) { - printk("GFS: fsid=%s: journal %u is busy\n", - sdp->sd_fsname, x); - error = -EBUSY; - goto fail_gunlock_tr; - } - } - - /* We don't need to journal this change because we're changing - only one sector of one block. We definitely don't want to have - the journaling code running at this point. */ - - error = gfs_dread(sb_gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, - DIO_START | DIO_WAIT, &bh); - if (error) - goto fail_gunlock_tr; - - gfs_sb_in(&sdp->sd_sb, bh->b_data); - - error = gfs_check_sb(sdp, &sdp->sd_sb, FALSE); - if (error) { - gfs_consist(sdp); - brelse(bh); - goto fail_gunlock_tr; - } - - sdp->sd_sb.sb_fs_format = GFS_FORMAT_FS; - sdp->sd_sb.sb_multihost_format = GFS_FORMAT_MULTI; - - gfs_sb_out(&sdp->sd_sb, bh->b_data); - - set_bit(GLF_DIRTY, &sb_gl->gl_flags); - error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); - - brelse(bh); - - gfs_glock_dq_uninit(&t_gh); - - gfs_glock_dq_uninit(&ji_gh); - - if (!error) { - printk("GFS: fsid=%s: upgrade successful\n", - sdp->sd_fsname); - sdp->sd_args.ar_upgrade = FALSE; - } - - return error; - - fail_gunlock_tr: - gfs_glock_dq_uninit(&t_gh); - - fail_ji_relse: - gfs_glock_dq_uninit(&ji_gh); - - fail: - if (error == -EBUSY) - printk("GFS: fsid=%s: can't upgrade: the FS is still busy or contains dirty journals\n", - sdp->sd_fsname); - else - printk("GFS: fsid=%s: can't upgrade: %d\n", - sdp->sd_fsname, error); - - return error; -} - -/** - * clear_journalsi - Clear all the journal index information (without locking) - * @sdp: The GFS superblock - * - */ - -static void -clear_journalsi(struct gfs_sbd *sdp) -{ - if (sdp->sd_jindex) { - kfree(sdp->sd_jindex); - sdp->sd_jindex = NULL; - } - sdp->sd_journals = 0; -} - -/** - * gfs_clear_journals - Clear all the journal index information - * @sdp: The GFS superblock - * - */ - -void -gfs_clear_journals(struct gfs_sbd *sdp) -{ - down(&sdp->sd_jindex_lock); - clear_journalsi(sdp); - up(&sdp->sd_jindex_lock); -} - -/** - * gfs_ji_update - Update the journal index information - * @ip: The journal index inode - * - * Returns: errno - */ - -static int -gfs_ji_update(struct gfs_inode *ip) -{ - struct gfs_sbd *sdp = ip->i_sbd; - char buf[sizeof(struct gfs_jindex)]; - unsigned int j; - int error; - - if (do_mod(ip->i_di.di_size, sizeof(struct gfs_jindex))) { - gfs_consist_inode(ip); - return -EIO; - } - - clear_journalsi(sdp); - - sdp->sd_jindex = kmalloc(ip->i_di.di_size, GFP_KERNEL); - if (!sdp->sd_jindex) - return -ENOMEM; - memset(sdp->sd_jindex, 0, ip->i_di.di_size); - - for (j = 0;; j++) { - error = gfs_internal_read(ip, buf, - j * sizeof(struct gfs_jindex), - sizeof(struct gfs_jindex)); - if (!error) - break; - if (error != sizeof(struct gfs_jindex)) { - if (error > 0) - error = -EIO; - goto fail; - } - - gfs_jindex_in(sdp->sd_jindex + j, buf); - } - - sdp->sd_journals = j; - sdp->sd_jiinode_vn = ip->i_gl->gl_vn; - - return 0; - - fail: - clear_journalsi(sdp); - return error; -} - -/** - * gfs_jindex_hold - Grab a lock on the jindex - * @sdp: The GFS superblock - * @ji_gh: the holder for the jindex glock - * - * This makes sure that we're using the latest copy of the journal index - * special file (this describes all of the journals for this filesystem), - * which might have been updated if someone added journals - * (via gfs_jadd utility). - * - * This is very similar to the gfs_rindex_hold() function, except that - * in general we hold the jindex lock for longer periods of time and - * we grab it far less frequently (in general) then the rgrp lock. - * - * Returns: errno - */ - -int -gfs_jindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ji_gh) -{ - struct gfs_inode *ip = sdp->sd_jiinode; - struct gfs_glock *gl = ip->i_gl; - int error; - - error = gfs_glock_nq_init(gl, LM_ST_SHARED, 0, ji_gh); - if (error) - return error; - - /* Read new copy from disk if we don't have the latest */ - if (sdp->sd_jiinode_vn != gl->gl_vn) { - down(&sdp->sd_jindex_lock); - if (sdp->sd_jiinode_vn != gl->gl_vn) - error = gfs_ji_update(ip); - up(&sdp->sd_jindex_lock); - } - - if (error) - gfs_glock_dq_uninit(ji_gh); - - return error; -} - -/** - * gfs_get_jiinode - Read-in the special (hidden) journal index inode - * @sdp: The GFS superblock - * - * Returns: errno - * - * This reads-in just the dinode, not the special file contents that describe - * the journals themselves (see gfs_jindex_hold()). - */ - -int -gfs_get_jiinode(struct gfs_sbd *sdp) -{ - struct gfs_holder ji_gh; - int error; - - error = gfs_glock_nq_num(sdp, - sdp->sd_sb.sb_jindex_di.no_formal_ino, - &gfs_inode_glops, - LM_ST_SHARED, GL_LOCAL_EXCL, - &ji_gh); - if (error) - return error; - - error = gfs_inode_get(ji_gh.gh_gl, &sdp->sd_sb.sb_jindex_di, - CREATE, &sdp->sd_jiinode); - if (!error) { - sdp->sd_jiinode_vn = ji_gh.gh_gl->gl_vn - 1; - set_bit(GLF_STICKY, &ji_gh.gh_gl->gl_flags); - } - - gfs_glock_dq_uninit(&ji_gh); - - return error; -} - -/** - * gfs_get_riinode - Read in the special (hidden) resource group index inode - * @sdp: The GFS superblock - * - * Returns: errno - * - * This reads-in just the dinode, not the special file contents that describe - * the resource groups themselves (see gfs_rindex_hold()). - */ - -int -gfs_get_riinode(struct gfs_sbd *sdp) -{ - struct gfs_holder ri_gh; - int error; - - error = gfs_glock_nq_num(sdp, - sdp->sd_sb.sb_rindex_di.no_formal_ino, - &gfs_inode_glops, - LM_ST_SHARED, GL_LOCAL_EXCL, - &ri_gh); - if (error) - return error; - - error = gfs_inode_get(ri_gh.gh_gl, &sdp->sd_sb.sb_rindex_di, - CREATE, &sdp->sd_riinode); - if (!error) { - sdp->sd_riinode_vn = ri_gh.gh_gl->gl_vn - 1; - set_bit(GLF_STICKY, &ri_gh.gh_gl->gl_flags); - } - - gfs_glock_dq_uninit(&ri_gh); - - return error; -} - -/** - * gfs_get_rootinode - Read in the filesystem's root inode - * @sdp: The GFS superblock - * - * Returns: errno - */ - -int -gfs_get_rootinode(struct gfs_sbd *sdp) -{ - struct gfs_holder i_gh; - int error; - - error = gfs_glock_nq_num(sdp, - sdp->sd_sb.sb_root_di.no_formal_ino, - &gfs_inode_glops, - LM_ST_SHARED, GL_LOCAL_EXCL, - &i_gh); - if (error) - return error; - - error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_root_di, - CREATE, &sdp->sd_rooti); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_get_qinode - Read in the special (hidden) quota inode - * @sdp: The GFS superblock - * - * If one is not on-disk already, create a new one. - * Does not read in file contents, just the dinode. - * - * Returns: errno - */ - -int -gfs_get_qinode(struct gfs_sbd *sdp) -{ - struct gfs_holder i_gh; - int error; - - /* Create, if not on-disk already */ - if (!sdp->sd_sb.sb_quota_di.no_formal_ino) { - error = gfs_alloc_qinode(sdp); - if (error) - return error; - } - - error = gfs_glock_nq_num(sdp, - sdp->sd_sb.sb_quota_di.no_formal_ino, - &gfs_inode_glops, - LM_ST_SHARED, GL_LOCAL_EXCL, - &i_gh); - if (error) - return error; - - error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_quota_di, - CREATE, &sdp->sd_qinode); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_get_linode - Read in the special (hidden) license inode - * @sdp: The GFS superblock - * - * If one is not on-disk already, create a new one. - * Does not read in file contents, just the dinode. - * - * Returns: errno - */ - -int -gfs_get_linode(struct gfs_sbd *sdp) -{ - struct gfs_holder i_gh; - int error; - - /* Create, if not on-disk already */ - if (!sdp->sd_sb.sb_license_di.no_formal_ino) { - error = gfs_alloc_linode(sdp); - if (error) - return error; - } - - error = gfs_glock_nq_num(sdp, - sdp->sd_sb.sb_license_di.no_formal_ino, - &gfs_inode_glops, - LM_ST_SHARED, GL_LOCAL_EXCL, - &i_gh); - if (error) - return error; - - /* iopen obtained in via gfs_glock_get(..gfs_iopen_glops) */ - error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_license_di, - CREATE, &sdp->sd_linode); - - gfs_glock_dq_uninit(&i_gh); - - return error; -} - -/** - * gfs_make_fs_rw - Turn a Read-Only FS into a Read-Write one - * @sdp: the filesystem - * - * Returns: errno - */ - -int -gfs_make_fs_rw(struct gfs_sbd *sdp) -{ - struct gfs_glock *j_gl = sdp->sd_journal_gh.gh_gl; - struct gfs_holder t_gh; - struct gfs_log_header head; - int error; - - error = gfs_glock_nq_init(sdp->sd_trans_gl, - LM_ST_SHARED, - GL_LOCAL_EXCL | GL_EXACT, - &t_gh); - if (error) - return error; - - j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); - - error = gfs_find_jhead(sdp, &sdp->sd_jdesc, j_gl, &head); - if (error) - goto fail; - - if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { - gfs_consist(sdp); - error = -EIO; - goto fail; - } - - /* Initialize some head of the log stuff */ - sdp->sd_sequence = head.lh_sequence; - sdp->sd_log_head = head.lh_first + 1; - - error = gfs_recover_dump(sdp); - if (error) - goto fail; - - set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); - clear_bit(SDF_ROFS, &sdp->sd_flags); - - set_bit(GLF_DIRTY, &j_gl->gl_flags); - gfs_log_dump(sdp, TRUE); - - gfs_glock_dq_uninit(&t_gh); - - return 0; - - fail: - t_gh.gh_flags |= GL_NOCACHE; - gfs_glock_dq_uninit(&t_gh); - - return error; -} - -/** - * gfs_make_fs_ro - Turn a Read-Write FS into a Read-Only one - * @sdp: the filesystem - * - * Returns: errno - */ - -int -gfs_make_fs_ro(struct gfs_sbd *sdp) -{ - struct gfs_holder t_gh; - int error; - - error = gfs_glock_nq_init(sdp->sd_trans_gl, - LM_ST_SHARED, - GL_LOCAL_EXCL | GL_EXACT | GL_NOCACHE, - &t_gh); - if (error && - !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - return error; - - gfs_statfs_sync(sdp); - gfs_log_flush(sdp); - gfs_quota_sync(sdp); - gfs_quota_scan(sdp); - - gfs_sync_meta(sdp); - gfs_log_dump(sdp, TRUE); - gfs_log_shutdown(sdp); - - set_bit(SDF_ROFS, &sdp->sd_flags); - clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); - - if (t_gh.gh_gl) - gfs_glock_dq_uninit(&t_gh); - - gfs_unlinked_cleanup(sdp); - gfs_quota_cleanup(sdp); - - return error; -} - -/** - * stat_gfs_fill - fill in the sg for a given RG - * @rgd: the RG - * @sg: the sg structure - * - * Returns: 0 on success, -ESTALE if the LVB is invalid - */ - -static int -stat_gfs_fill(struct gfs_rgrpd *rgd, struct gfs_stat_gfs *sg) -{ - struct gfs_rgrp_lvb *rb = (struct gfs_rgrp_lvb *)rgd->rd_gl->gl_lvb; - - if (gfs32_to_cpu(rb->rb_magic) != GFS_MAGIC) - return -ESTALE; - - sg->sg_total_blocks += rgd->rd_ri.ri_data; - sg->sg_free += gfs32_to_cpu(rb->rb_free); - sg->sg_used_dinode += gfs32_to_cpu(rb->rb_useddi); - sg->sg_free_dinode += gfs32_to_cpu(rb->rb_freedi); - sg->sg_used_meta += gfs32_to_cpu(rb->rb_usedmeta); - sg->sg_free_meta += gfs32_to_cpu(rb->rb_freemeta); - - return 0; -} - -/** - * stat_gfs_async - Stat a filesystem using asynchronous locking - * @sdp: the filesystem - * @sg: the sg info that will be returned - * @interruptible: TRUE if we should look for signals. - * - * Any error (other than a signal) will cause this routine to fall back - * to the synchronous version. - * - * FIXME: This really shouldn't busy wait like this. - * - * Returns: errno - */ - -static int -stat_gfs_async(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) -{ - struct gfs_rgrpd *rgd_next = gfs_rgrpd_get_first(sdp); - struct gfs_holder *gha, *gh; - unsigned int slots = gfs_tune_get(sdp, gt_statfs_slots); - unsigned int x; - int done; - int error = 0, err; - - memset(sg, 0, sizeof(struct gfs_stat_gfs)); - - gha = vmalloc(slots * sizeof(struct gfs_holder)); - if (!gha) - return -ENOMEM; - memset(gha, 0, slots * sizeof(struct gfs_holder)); - - for (;;) { - done = TRUE; - - for (x = 0; x < slots; x++) { - gh = gha + x; - - if (gh->gh_gl && gfs_glock_poll(gh)) { - err = gfs_glock_wait(gh); - if (err) { - gfs_holder_uninit(gh); - error = err; - } else { - if (!error) - error = stat_gfs_fill(gl2rgd(gh->gh_gl), sg); - gfs_glock_dq_uninit(gh); - } - } - - if (gh->gh_gl) - done = FALSE; - else if (rgd_next && !error) { - error = gfs_glock_nq_init(rgd_next->rd_gl, - LM_ST_SHARED, - GL_LOCAL_EXCL | GL_SKIP | GL_ASYNC, - gh); - rgd_next = gfs_rgrpd_get_next(rgd_next); - done = FALSE; - } - - if (interruptible && signal_pending(current)) - error = -ERESTARTSYS; - } - - if (done) - break; - - yield(); - } - - vfree(gha); - - return error; -} - -/** - * stat_gfs_sync - Stat a filesystem using synchronous locking - * @sdp: the filesystem - * @sg: the sg info that will be returned - * @interruptible: TRUE if we should look for signals. - * - * Returns: errno - */ - -static int -stat_gfs_sync(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) -{ - struct gfs_holder rgd_gh; - struct gfs_rgrpd *rgd; - int error; - - memset(sg, 0, sizeof(struct gfs_stat_gfs)); - - for (rgd = gfs_rgrpd_get_first(sdp); - rgd; - rgd = gfs_rgrpd_get_next(rgd)) { - for (;;) { - error = gfs_glock_nq_init(rgd->rd_gl, - LM_ST_SHARED, - GL_LOCAL_EXCL | GL_SKIP, - &rgd_gh); - if (error) - return error; - - error = stat_gfs_fill(rgd, sg); - - gfs_glock_dq_uninit(&rgd_gh); - - if (!error) - break; - - error = gfs_rgrp_lvb_init(rgd); - if (error) - return error; - } - - if (interruptible && signal_pending(current)) - return -ERESTARTSYS; - } - - return 0; -} - -/** - * gfs_stat_gfs - Do a statfs - * @sdp: the filesystem - * @sg: the sg structure - * @interruptible: Stop if there is a signal pending - * - * Returns: errno - */ - -int -gfs_stat_gfs(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) -{ - struct gfs_holder ri_gh; - int error; - - error = gfs_rindex_hold(sdp, &ri_gh); - if (error) - return error; - - error = stat_gfs_async(sdp, sg, interruptible); - if (error == -ESTALE) - error = stat_gfs_sync(sdp, sg, interruptible); - - gfs_glock_dq_uninit(&ri_gh); - - return error; -} - -/** - * gfs_lock_fs_check_clean - Stop all writes to the FS and check that all journals are clean - * @sdp: the file system - * @state: the state to put the transaction lock into - * @t_gh: the hold on the transaction lock - * - * Returns: errno - */ - -int -gfs_lock_fs_check_clean(struct gfs_sbd *sdp, unsigned int state, - struct gfs_holder *t_gh) -{ - struct gfs_holder ji_gh, cl_gh; - struct gfs_log_header lh; - unsigned int x; - int error; - - error = gfs_jindex_hold(sdp, &ji_gh); - if (error) - return error; - - error = gfs_glock_nq_num(sdp, - GFS_CRAP_LOCK, &gfs_meta_glops, - LM_ST_SHARED, GL_NOCACHE, - &cl_gh); - if (error) - goto fail; - - error = gfs_glock_nq_init(sdp->sd_trans_gl, state, - LM_FLAG_PRIORITY | GL_EXACT | GL_NOCACHE, - t_gh); - if (error) - goto fail_gunlock_craplock; - - for (x = 0; x < sdp->sd_journals; x++) { - error = gfs_find_jhead(sdp, &sdp->sd_jindex[x], - cl_gh.gh_gl, &lh); - if (error) - goto fail_gunlock_trans; - - if (!(lh.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { - error = -EBUSY; - goto fail_gunlock_trans; - } - } - - gfs_glock_dq_uninit(&cl_gh); - gfs_glock_dq_uninit(&ji_gh); - - return 0; - - fail_gunlock_trans: - gfs_glock_dq_uninit(t_gh); - - fail_gunlock_craplock: - gfs_glock_dq_uninit(&cl_gh); - - fail: - gfs_glock_dq_uninit(&ji_gh); - - return error; -} - -/** - * gfs_freeze_fs - freezes the file system - * @sdp: the file system - * - * This function flushes data and meta data for all machines by - * aquiring the transaction log exclusively. All journals are - * ensured to be in a clean state as well. - * - * Returns: errno - */ - -int -gfs_freeze_fs(struct gfs_sbd *sdp) -{ - int error = 0; - - down(&sdp->sd_freeze_lock); - - if (!sdp->sd_freeze_count++) { - error = gfs_lock_fs_check_clean(sdp, LM_ST_DEFERRED, - &sdp->sd_freeze_gh); - if (error) - sdp->sd_freeze_count--; - else - sdp->sd_freeze_gh.gh_owner = NULL; - } - - up(&sdp->sd_freeze_lock); - - return error; -} - -/** - * gfs_unfreeze_fs - unfreezes the file system - * @sdp: the file system - * - * This function allows the file system to proceed by unlocking - * the exclusively held transaction lock. Other GFS nodes are - * now free to acquire the lock shared and go on with their lives. - * - */ - -void -gfs_unfreeze_fs(struct gfs_sbd *sdp) -{ - down(&sdp->sd_freeze_lock); - - if (sdp->sd_freeze_count && !--sdp->sd_freeze_count) - gfs_glock_dq_uninit(&sdp->sd_freeze_gh); - - up(&sdp->sd_freeze_lock); -} - -/* - * 03/02/07 wcheng@redhat.com - * Fast statfs implementation - mostly based on GFS2 implementation. - */ - -void gfs_statfs_change_in(struct gfs_statfs_change_host *sc, const void *buf) -{ - const struct gfs_statfs_change *str = buf; - - sc->sc_total = be64_to_cpu(str->sc_total); - sc->sc_free = be64_to_cpu(str->sc_free); - sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); -} - -void gfs_statfs_change_out(const struct gfs_statfs_change_host *sc, void *buf) -{ - struct gfs_statfs_change *str = buf; - - str->sc_total = cpu_to_be64(sc->sc_total); - str->sc_free = cpu_to_be64(sc->sc_free); - str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); -} - -int gfs_statfs_init(struct gfs_sbd *sdp, int flag) -{ - int error; - - /* if flag == 0, do we want to turn this off ? */ - if (!flag) - return 0; - - error = gfs_statfs_start(sdp); - if (error) - printk("GFS: fsid=%s: can't initialize statfs subsystem: %d\n", - sdp->sd_fsname, error); - - return error; -} -int gfs_statfs_start(struct gfs_sbd *sdp) -{ - struct gfs_stat_gfs sg; - struct gfs_inode *m_ip; - struct gfs_statfs_change_host *m_sc = &sdp->sd_statfs_master; - struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; - struct buffer_head *m_bh; - struct gfs_holder gh; - int error; - - printk("GFS: fsid=%s: fast statfs start time = %lu\n", - sdp->sd_fsname, get_seconds()); - - /* created via gfs_get_linode() in fill_super(). */ - /* gfs_inode_glops */ - m_ip = sdp->sd_linode; - - /* get real statistics */ - error = gfs_stat_gfs(sdp, &sg, TRUE); - if (error) - return error; - - /* make sure the page is refreshed via glock flushing */ - error = gfs_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, - &gh); - if (error) - goto gfs_statfs_start_out; - - error = gfs_get_inode_buffer(m_ip, &m_bh); - if (error) - goto gfs_statfs_start_unlock; - - error = gfs_trans_begin(sdp, 1, 0); - if (error) - goto gfs_statfs_start_bh; - - spin_lock(&sdp->sd_statfs_spin); - m_sc->sc_total = sg.sg_total_blocks; - m_sc->sc_free = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; - m_sc->sc_dinodes = sg.sg_used_dinode; - memset(l_sc, 0, sizeof(struct gfs_statfs_change_host)); - spin_unlock(&sdp->sd_statfs_spin); - - gfs_trans_add_bh(m_ip->i_gl, m_bh); - gfs_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs_dinode)); - - gfs_trans_end(sdp); - -gfs_statfs_start_bh: - brelse(m_bh); - -gfs_statfs_start_unlock: - gfs_glock_dq_uninit(&gh); - -gfs_statfs_start_out: - return 0; -} - -void gfs_statfs_modify(struct gfs_sbd *sdp, - int64_t total, - int64_t free, - int64_t dinodes) -{ - struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; - - spin_lock(&sdp->sd_statfs_spin); - l_sc->sc_total += total; - l_sc->sc_free += free; - l_sc->sc_dinodes += dinodes; - spin_unlock(&sdp->sd_statfs_spin); -} - -int gfs_statfs_sync(struct gfs_sbd *sdp) -{ - struct gfs_inode *m_ip = sdp->sd_linode; - struct gfs_statfs_change_host *m_sc = &sdp->sd_statfs_master; - struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; - struct gfs_holder gh; - struct buffer_head *m_bh; - int error; - - error = gfs_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, - &gh); - if (error) - return error; - - error = gfs_get_inode_buffer(m_ip, &m_bh); - if (error) - goto gfs_statfs_sync_out; - - /* if no change, simply return */ - spin_lock(&sdp->sd_statfs_spin); - gfs_statfs_change_in(m_sc, m_bh->b_data + - sizeof(struct gfs_dinode)); - if (!l_sc->sc_total && !l_sc->sc_free && !l_sc->sc_dinodes) { - spin_unlock(&sdp->sd_statfs_spin); - goto out_bh; - } - spin_unlock(&sdp->sd_statfs_spin); - - error = gfs_trans_begin(sdp, 1, 0); - if (error) - goto out_bh; - - spin_lock(&sdp->sd_statfs_spin); - m_sc->sc_total += l_sc->sc_total; - m_sc->sc_free += l_sc->sc_free; - m_sc->sc_dinodes += l_sc->sc_dinodes; - memset(l_sc, 0, sizeof(struct gfs_statfs_change_host)); - spin_unlock(&sdp->sd_statfs_spin); - - gfs_trans_add_bh(m_ip->i_gl, m_bh); - gfs_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs_dinode)); - - gfs_trans_end(sdp); - -out_bh: - brelse(m_bh); - -gfs_statfs_sync_out: - gfs_glock_dq_uninit(&gh); - return error; -} - -int gfs_statfs_fast(struct gfs_sbd *sdp, void *b) -{ - struct kstatfs *buf = (struct kstatfs *)b; - struct gfs_statfs_change_host sc, *m_sc = &sdp->sd_statfs_master; - struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; - - spin_lock(&sdp->sd_statfs_spin); - - sc.sc_total = m_sc->sc_total + l_sc->sc_total; - sc.sc_free = m_sc->sc_free + l_sc->sc_free; - sc.sc_dinodes = m_sc->sc_dinodes + l_sc->sc_dinodes; - spin_unlock(&sdp->sd_statfs_spin); - - if (sc.sc_free < 0) - sc.sc_free = 0; - if (sc.sc_free > sc.sc_total) - sc.sc_free = sc.sc_total; - if (sc.sc_dinodes < 0) - sc.sc_dinodes = 0; - - /* fill in the statistics */ - memset(buf, 0, sizeof(struct kstatfs)); - - buf->f_type = GFS_MAGIC; buf->f_bsize = sdp->sd_sb.sb_bsize; - buf->f_blocks = sc.sc_total; - buf->f_bfree = sc.sc_free; - buf->f_bavail = sc.sc_free; - buf->f_files = sc.sc_dinodes + sc.sc_free; - buf->f_ffree = sc.sc_free; - buf->f_namelen = GFS_FNAMESIZE; - - return 0; -} diff --git a/gfs-kernel/src/gfs/super.h b/gfs-kernel/src/gfs/super.h deleted file mode 100644 index 70d78c1..0000000 --- a/gfs-kernel/src/gfs/super.h +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __SUPER_DOT_H__ -#define __SUPER_DOT_H__ - -void gfs_tune_init(struct gfs_tune *gt); - -int gfs_check_sb(struct gfs_sbd *sdp, struct gfs_sb *sb, int silent); -int gfs_read_sb(struct gfs_sbd *sdp, struct gfs_glock *gl, int silent); -int gfs_do_upgrade(struct gfs_sbd *sdp, struct gfs_glock *gl_sb); - -static __inline__ unsigned int -gfs_num_journals(struct gfs_sbd *sdp) -{ - unsigned int num; - down(&sdp->sd_jindex_lock); - num = sdp->sd_journals; - up(&sdp->sd_jindex_lock); - return num; -} - -int gfs_jindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ji_gh); -void gfs_clear_journals(struct gfs_sbd *sdp); - -int gfs_get_jiinode(struct gfs_sbd *sdp); -int gfs_get_riinode(struct gfs_sbd *sdp); -int gfs_get_rootinode(struct gfs_sbd *sdp); -int gfs_get_qinode(struct gfs_sbd *sdp); -int gfs_get_linode(struct gfs_sbd *sdp); - -int gfs_make_fs_rw(struct gfs_sbd *sdp); -int gfs_make_fs_ro(struct gfs_sbd *sdp); - -int gfs_statfs_init(struct gfs_sbd *sdp, int flag); -int gfs_statfs_sync(struct gfs_sbd *sdp); -int gfs_statfs_fast(struct gfs_sbd *sdp, void *buf); - -struct gfs_stat_gfs { - uint64_t sg_total_blocks; - uint64_t sg_free; - uint64_t sg_used_dinode; - uint64_t sg_free_dinode; - uint64_t sg_used_meta; - uint64_t sg_free_meta; -}; - -int gfs_stat_gfs(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, - int interruptible); - -int gfs_lock_fs_check_clean(struct gfs_sbd *sdp, unsigned int state, - struct gfs_holder *t_gh); -int gfs_freeze_fs(struct gfs_sbd *sdp); -void gfs_unfreeze_fs(struct gfs_sbd *sdp); - -int gfs_reset_readahead(struct gfs_sbd *sdp, unsigned int file_ra); - -#endif /* __SUPER_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/trans.c b/gfs-kernel/src/gfs/trans.c deleted file mode 100644 index 56aa336..0000000 --- a/gfs-kernel/src/gfs/trans.c +++ /dev/null @@ -1,463 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "dio.h" -#include "glock.h" -#include "log.h" -#include "lops.h" -#include "quota.h" -#include "trans.h" -#include "unlinked.h" - -/** - * gfs_trans_print - Print a transaction to the console - * @sdp: the filesystem - * @tr: The GFS transaction - * @where: Situation of transaction - * - */ - -void -gfs_trans_print(struct gfs_sbd *sdp, struct gfs_trans *tr, unsigned int where) -{ - struct gfs_log_element *le; - struct list_head *tmp, *head; - unsigned int mblks = 0, eblks = 0; - - LO_TRANS_SIZE(sdp, tr, &mblks, &eblks, NULL, NULL); - - printk("Transaction: (%s, %u)\n", tr->tr_file, tr->tr_line); - printk(" tr_mblks_asked = %u, tr_eblks_asked = %u, tr_seg_reserved = %u\n", - tr->tr_mblks_asked, tr->tr_eblks_asked, tr->tr_seg_reserved); - printk(" mblks = %u, eblks = %u\n", mblks, eblks); - printk(" tr_flags = 0x%.8X\n", tr->tr_flags); - - for (head = &tr->tr_elements, tmp = head->next; - tmp != head; - tmp = tmp->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - LO_PRINT(sdp, le, where); - } - - printk("End Trans\n"); -} - -/** - * gfs_trans_begin_i - Prepare to start a transaction - * @sdp: The GFS superblock - * @meta_blocks: Reserve this many metadata blocks in the log - * @extra_blocks: Number of non-metadata blocks to reserve - * - * Allocate the struct gfs_trans struct. - * Grab a shared TRANSaction lock (protects this transaction from - * overlapping with unusual fs writes, e.g. journal replay, fs upgrade, - * while allowing simultaneous transaction writes throughout cluster). - * Reserve space in the log. @meta_blocks and @extra_blocks must indicate - * the worst case (maximum) size of the transaction. - * Record this transaction as the *one* transaction being built by this - * Linux process, in current->journal_info. - * - * Returns: errno - */ - -int -gfs_trans_begin_i(struct gfs_sbd *sdp, - unsigned int meta_blocks, unsigned int extra_blocks, - char *file, unsigned int line) -{ - struct gfs_trans *tr; - unsigned int blocks; - int error; - - if (test_bit(SDF_ROFS, &sdp->sd_flags)) - return -EROFS; - - tr = kmalloc(sizeof(struct gfs_trans), GFP_KERNEL); - if (!tr) - return -ENOMEM; - memset(tr, 0, sizeof(struct gfs_trans)); - - INIT_LIST_HEAD(&tr->tr_elements); - INIT_LIST_HEAD(&tr->tr_free_bufs); - INIT_LIST_HEAD(&tr->tr_free_bmem); - INIT_LIST_HEAD(&tr->tr_bufs); - INIT_LIST_HEAD(&tr->tr_ail_bufs); - tr->tr_file = file; - tr->tr_line = line; - - error = -ENOMEM; - tr->tr_t_gh = gfs_holder_get(sdp->sd_trans_gl, LM_ST_SHARED, 0); - if (!tr->tr_t_gh) - goto fail; - - error = gfs_glock_nq(tr->tr_t_gh); - if (error) - goto fail_holder_put; - - /* Do log reservation */ - - tr->tr_mblks_asked = meta_blocks; - tr->tr_eblks_asked = extra_blocks; - - blocks = 1; - if (meta_blocks) - blocks += gfs_struct2blk(sdp, meta_blocks, - sizeof(struct gfs_block_tag)) + - meta_blocks; - blocks += extra_blocks; - tr->tr_seg_reserved = gfs_blk2seg(sdp, blocks); - - error = gfs_log_reserve(sdp, tr->tr_seg_reserved, FALSE); - if (error) - goto fail_gunlock; - - gfs_assert(sdp, !current_transaction,); - current_transaction = tr; - - return 0; - - fail_gunlock: - gfs_glock_dq(tr->tr_t_gh); - - fail_holder_put: - gfs_holder_put(tr->tr_t_gh); - - fail: - kfree(tr); - - return error; -} - -/** - * gfs_trans_end - End a transaction - * @sdp: The GFS superblock - * - * If buffers were actually added to the transaction, - * commit it. - * - */ - -void -gfs_trans_end(struct gfs_sbd *sdp) -{ - struct gfs_trans *tr; - struct gfs_holder *t_gh; - struct list_head *tmp, *head; - struct gfs_log_element *le; - - /* Linux task struct indicates current new trans for this process. - * We're done building it, so set it to NULL */ - tr = current_transaction; - gfs_assert(sdp, tr,); - current_transaction = NULL; - - t_gh = tr->tr_t_gh; - tr->tr_t_gh = NULL; - - /* If no buffers were ever added to trans, forget it */ - if (list_empty(&tr->tr_elements)) { - gfs_log_release(sdp, tr->tr_seg_reserved); - kfree(tr); - - gfs_glock_dq(t_gh); - gfs_holder_put(t_gh); - - return; - } - - /* Do trans_end log-operation for each log element */ - for (head = &tr->tr_elements, tmp = head->next; - tmp != head; - tmp = tmp->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - LO_TRANS_END(sdp, le); - } - - gfs_log_commit(sdp, tr); - - gfs_glock_dq(t_gh); - gfs_holder_put(t_gh); - - if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) - gfs_log_flush(sdp); -} - -/** - * gfs_trans_add_gl - Add a glock to a transaction - * @gl: the glock - * - * If not already attached, add the given glock to this process's transaction. - * - * Even though no glock info will be written to the on-disk log, the glocks - * associated with a transaction provide bridges by which to combine - * a just-built transaction with an earlier incore committed transaction - * that was protected by the same glock. See incore_commit(). - * Combining transactions makes for more efficient logging. - * - * Note that more than one glock may be associated with a single transaction. - * However, a given glock protects no more than *one* transaction at a - * given stage in the transaction pipeline (i.e. new or incore-committed). - * After all, the process holds the glock EX (so no other process can be - * building a separate trans protected by this glock), and the process can - * build only one transaction at a time. - * - * Rules: - * This process must hold the glock in EXclusive mode, since we're going - * to be writing to something protected by this glock. - */ - -void -gfs_trans_add_gl(struct gfs_glock *gl) -{ - if (!gl->gl_new_le.le_trans) { - gfs_assert_withdraw(gl->gl_sbd, - gfs_glock_is_locked_by_me(gl) && - gfs_glock_is_held_excl(gl)); - gfs_glock_hold(gl); /* Released in glock_trans_end() */ - - /* Ask for eventual flush of (meta)data protected by this glock, - once trans is complete and logged. */ - set_bit(GLF_DIRTY, &gl->gl_flags); - - /* Invoke generic_le_add() */ - LO_ADD(gl->gl_sbd, &gl->gl_new_le); - gl->gl_new_le.le_trans->tr_num_gl++; - } -} - -/** - * gfs_trans_add_bh - Add a to-be-modified buffer to the current transaction - * @gl: the glock the buffer belongs to - * @bh: The buffer to add - * - * Add a to-be-modified buffer to the current being-built (i.e. new) trans, - * and pin the buffer in memory. - * - * Caller must hold the glock protecting this buffer. - * - * Call this as many times as you want during transaction formation. It does - * its attachment work only once. After buffer is attached to trans, the - * process building the trans can modify the buffer again and again (calling - * this function before each change). Only the final result (within this trans) - * will be written to log. A good example is when allocating blocks in an RG, - * a given bitmap buffer may be updated many times within a transaction. - * - * Note: This final result will also be written to its in-place location, - * unless this transaction gets combined with a later transaction, - * in which case only the later result will go to in-place. - * - */ - -void -gfs_trans_add_bh(struct gfs_glock *gl, struct buffer_head *bh) -{ - struct gfs_sbd *sdp = gl->gl_sbd; - struct gfs_bufdata *bd; - - /* Make sure GFS private info struct is attached to buffer head */ - bd = bh2bd(bh); - if (!bd) { - gfs_attach_bufdata(bh, gl); - bd = bh2bd(bh); - } - - /* If buffer has already been attached to trans, we're done */ - if (bd->bd_new_le.le_trans) - return; - - gfs_meta_check(sdp, bh); - - gfs_assert(sdp, bd->bd_gl == gl,); - - /* Make sure glock is attached to trans */ - if (!gl->gl_new_le.le_trans) - gfs_trans_add_gl(gl); - - gfs_dpin(sdp, bh); - - /* Attach buffer to trans */ - LO_ADD(sdp, &bd->bd_new_le); - bd->bd_new_le.le_trans->tr_num_buf++; -} - -/** - * gfs_trans_add_unlinked - Add an unlinked or dealloced tag to - * the current transaction - * @sdp: the filesystem - * @type: the type of entry - * @inum: the inode number - * - * Returns: the unlinked structure - */ - -struct gfs_unlinked * -gfs_trans_add_unlinked(struct gfs_sbd *sdp, unsigned int type, - struct gfs_inum *inum) -{ - struct gfs_unlinked *ul; - - /* Find in fileystem's unlinked list, or create */ - ul = gfs_unlinked_get(sdp, inum, CREATE); - - LO_ADD(sdp, &ul->ul_new_le); - - switch (type) { - case GFS_LOG_DESC_IUL: - set_bit(ULF_NEW_UL, &ul->ul_flags); - ul->ul_new_le.le_trans->tr_num_iul++; - break; - case GFS_LOG_DESC_IDA: - clear_bit(ULF_NEW_UL, &ul->ul_flags); - ul->ul_new_le.le_trans->tr_num_ida++; - break; - default: - gfs_assert(sdp, FALSE,); - break; - } - - return ul; -} - -/** - * gfs_trans_add_quota - Add quota changes to a transaction - * @sdp: the filesystem - * @change: The number of blocks allocated (positive) or freed (negative) - * @uid: the user ID doing the change - * @gid: the group ID doing the change - * - */ - -void -gfs_trans_add_quota(struct gfs_sbd *sdp, int64_t change, - uint32_t uid, uint32_t gid) -{ - struct gfs_trans *tr; - struct list_head *tmp, *head, *next; - struct gfs_log_element *le; - struct gfs_quota_le *ql; - int found_uid, found_gid; - int error; - - if (!gfs_tune_get(sdp, gt_quota_account)) - return; - if (gfs_assert_warn(sdp, change)) - return; - - found_uid = (uid == NO_QUOTA_CHANGE); - found_gid = (gid == NO_QUOTA_CHANGE); - - if (gfs_assert_warn(sdp, !found_uid || !found_gid)) - return; - - tr = current_transaction; - gfs_assert(sdp, tr,); - - for (head = &tr->tr_elements, tmp = head->next, next = tmp->next; - tmp != head; - tmp = next, next = next->next) { - le = list_entry(tmp, struct gfs_log_element, le_list); - if (le->le_ops != &gfs_quota_lops) - continue; - - ql = container_of(le, struct gfs_quota_le, ql_le); - - if (test_bit(QDF_USER, &ql->ql_data->qd_flags)) { - if (ql->ql_data->qd_id == uid) { - ql->ql_change += change; - - spin_lock(&sdp->sd_quota_lock); - ql->ql_data->qd_change_new += change; - spin_unlock(&sdp->sd_quota_lock); - - list_del(&le->le_list); - - if (ql->ql_change) - list_add(&le->le_list, - &tr->tr_elements); - else { - gfs_quota_put(sdp, ql->ql_data); - kfree(ql); - tr->tr_num_q--; - } - - gfs_assert(sdp, !found_uid,); - found_uid = TRUE; - if (found_gid) - break; - } - } else { - if (ql->ql_data->qd_id == gid) { - ql->ql_change += change; - - spin_lock(&sdp->sd_quota_lock); - ql->ql_data->qd_change_new += change; - spin_unlock(&sdp->sd_quota_lock); - - list_del(&le->le_list); - - if (ql->ql_change) - list_add(&le->le_list, - &tr->tr_elements); - else { - gfs_quota_put(sdp, ql->ql_data); - kfree(ql); - tr->tr_num_q--; - } - - gfs_assert(sdp, !found_gid,); - found_gid = TRUE; - if (found_uid) - break; - } - } - } - - while (!found_uid || !found_gid) { - ql = gmalloc(sizeof(struct gfs_quota_le)); - memset(ql, 0, sizeof(struct gfs_quota_le)); - - INIT_LE(&ql->ql_le, &gfs_quota_lops); - - if (found_uid) { - error = gfs_quota_get(sdp, FALSE, gid, - NO_CREATE, - &ql->ql_data); - found_gid = TRUE; - } else { - error = gfs_quota_get(sdp, TRUE, uid, - NO_CREATE, - &ql->ql_data); - found_uid = TRUE; - } - - gfs_assert(sdp, !error && ql->ql_data,); - - ql->ql_change = change; - - spin_lock(&sdp->sd_quota_lock); - ql->ql_data->qd_change_new += change; - spin_unlock(&sdp->sd_quota_lock); - - LO_ADD(sdp, &ql->ql_le); - tr->tr_num_q++; - } -} diff --git a/gfs-kernel/src/gfs/trans.h b/gfs-kernel/src/gfs/trans.h deleted file mode 100644 index ec5eda3..0000000 --- a/gfs-kernel/src/gfs/trans.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __TRANS_DOT_H__ -#define __TRANS_DOT_H__ - -#define TRANS_IS_NEW (53) -#define TRANS_IS_INCORE (54) -void gfs_trans_print(struct gfs_sbd *sdp, struct gfs_trans *tr, - unsigned int where); - -int gfs_trans_begin_i(struct gfs_sbd *sdp, - unsigned int meta_blocks, unsigned int extra_blocks, - char *file, unsigned int line); -#define gfs_trans_begin(sdp, mb, eb) \ -gfs_trans_begin_i((sdp), (mb), (eb), __FILE__, __LINE__) - -void gfs_trans_end(struct gfs_sbd *sdp); - -void gfs_trans_add_gl(struct gfs_glock *gl); -void gfs_trans_add_bh(struct gfs_glock *gl, struct buffer_head *bh); -struct gfs_unlinked *gfs_trans_add_unlinked(struct gfs_sbd *sdp, unsigned int type, - struct gfs_inum *inum); -void gfs_trans_add_quota(struct gfs_sbd *sdp, int64_t change, uint32_t uid, - uint32_t gid); - -#endif /* __TRANS_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/unlinked.c b/gfs-kernel/src/gfs/unlinked.c deleted file mode 100644 index b933129..0000000 --- a/gfs-kernel/src/gfs/unlinked.c +++ /dev/null @@ -1,444 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> - -#include "gfs.h" -#include "inode.h" -#include "log.h" -#include "lops.h" -#include "unlinked.h" - -/** - * gfs_unlinked_get - Get a structure to represent an unlinked inode - * @sdp: the filesystem - * @inum: identifies the inode that's unlinked - * @create: if TRUE, we're allowed to create the structure if we can't find it, - * otherwise return NULL - * - * Returns: the structure, or NULL - * - * Search the filesystem's list of gfs_unlinked to find a match. - * If none found, create a new one and place on list. - */ - -struct gfs_unlinked * -gfs_unlinked_get(struct gfs_sbd *sdp, struct gfs_inum *inum, int create) -{ - struct gfs_unlinked *ul = NULL, *new_ul = NULL; - struct list_head *tmp, *head; - - for (;;) { - spin_lock(&sdp->sd_unlinked_lock); - - for (head = &sdp->sd_unlinked_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - ul = list_entry(tmp, struct gfs_unlinked, ul_list); - if (gfs_inum_equal(&ul->ul_inum, inum)) { - ul->ul_count++; - break; - } - } - - if (tmp == head) - ul = NULL; - - /* 2nd pass, still not there; add the new_ul we prepared */ - if (!ul && new_ul) { - ul = new_ul; - list_add(&ul->ul_list, &sdp->sd_unlinked_list); - new_ul = NULL; - } - - spin_unlock(&sdp->sd_unlinked_lock); - - /* 1st pass; we found pre-existing, OR not allowed to create. - 2nd pass; another process added it, or we did */ - if (ul || !create) { - if (new_ul) - /* someone beat us to it; forget our new_ul */ - kfree(new_ul); - return ul; - } - - /* No match on list, 1st time through loop. - Prepare new_ul, then repeat loop to find out if another - process has created or unlinked an inode and put its - gfs_unlinked on list while we've been preparing this one. */ - new_ul = gmalloc(sizeof(struct gfs_unlinked)); - memset(new_ul, 0, sizeof(struct gfs_unlinked)); - - new_ul->ul_count = 1; - new_ul->ul_inum = *inum; - - INIT_LE(&new_ul->ul_new_le, &gfs_unlinked_lops); - INIT_LE(&new_ul->ul_incore_le, &gfs_unlinked_lops); - INIT_LE(&new_ul->ul_ondisk_le, &gfs_unlinked_lops); - } -} - -/** - * gfs_unlinked_hold - increment the usage count on a struct gfs_unlinked - * @sdp: the filesystem - * @ul: the structure - * - */ - -void -gfs_unlinked_hold(struct gfs_sbd *sdp, struct gfs_unlinked *ul) -{ - spin_lock(&sdp->sd_unlinked_lock); - gfs_assert(sdp, ul->ul_count,); - ul->ul_count++; - spin_unlock(&sdp->sd_unlinked_lock); -} - -/** - * gfs_unlinked_put - decrement the usage count on a struct gfs_unlinked - * @sdp: the filesystem - * @ul: the structure - * - * Free the structure if its reference count hits zero. - * - */ - -void -gfs_unlinked_put(struct gfs_sbd *sdp, struct gfs_unlinked *ul) -{ - spin_lock(&sdp->sd_unlinked_lock); - - gfs_assert(sdp, ul->ul_count,); - ul->ul_count--; - - if (!ul->ul_count) { - gfs_assert_warn(sdp, - !test_bit(ULF_IC_LIST, &ul->ul_flags) && - !test_bit(ULF_OD_LIST, &ul->ul_flags) && - !test_bit(ULF_LOCK, &ul->ul_flags)); - list_del(&ul->ul_list); - spin_unlock(&sdp->sd_unlinked_lock); - kfree(ul); - } else - spin_unlock(&sdp->sd_unlinked_lock); -} - -/** - * unlinked_find - Find a inode to try to deallocate - * @sdp: the filesystem - * - * The returned structure is locked and needs to be unlocked - * with gfs_unlinked_unlock(). - * - * Returns: A unlinked structure, or NULL - */ - -struct gfs_unlinked * -unlinked_find(struct gfs_sbd *sdp) -{ - struct list_head *tmp, *head; - struct gfs_unlinked *ul = NULL; - - if (test_bit(SDF_ROFS, &sdp->sd_flags)) - return NULL; - - gfs_log_lock(sdp); - spin_lock(&sdp->sd_unlinked_lock); - - if (!atomic_read(&sdp->sd_unlinked_ic_count)) - goto out; - - for (head = &sdp->sd_unlinked_list, tmp = head->next; - tmp != head; - tmp = tmp->next) { - ul = list_entry(tmp, struct gfs_unlinked, ul_list); - - if (test_bit(ULF_LOCK, &ul->ul_flags)) - continue; - if (!test_bit(ULF_IC_LIST, &ul->ul_flags)) - continue; - - list_move_tail(&ul->ul_list, &sdp->sd_unlinked_list); - - set_bit(ULF_LOCK, &ul->ul_flags); - ul->ul_count++; - - goto out; - } - - ul = NULL; - - out: - spin_unlock(&sdp->sd_unlinked_lock); - gfs_log_unlock(sdp); - - return ul; -} - -/** - * gfs_unlinked_lock - lock a unlinked structure - * @sdp: the filesystem - * @ul: the unlinked inode structure - * - */ - -void -gfs_unlinked_lock(struct gfs_sbd *sdp, struct gfs_unlinked *ul) -{ - spin_lock(&sdp->sd_unlinked_lock); - - gfs_assert_warn(sdp, !test_bit(ULF_LOCK, &ul->ul_flags)); - set_bit(ULF_LOCK, &ul->ul_flags); - - ul->ul_count++; - - spin_unlock(&sdp->sd_unlinked_lock); -} - -/** - * gfs_unlinked_unlock - drop a reference on a unlinked structure - * @sdp: the filesystem - * @ul: the unlinked inode structure - * - */ - -void -gfs_unlinked_unlock(struct gfs_sbd *sdp, struct gfs_unlinked *ul) -{ - spin_lock(&sdp->sd_unlinked_lock); - - gfs_assert_warn(sdp, test_bit(ULF_LOCK, &ul->ul_flags)); - clear_bit(ULF_LOCK, &ul->ul_flags); - - gfs_assert(sdp, ul->ul_count,); - ul->ul_count--; - - if (!ul->ul_count) { - gfs_assert_warn(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags) && - !test_bit(ULF_OD_LIST, &ul->ul_flags)); - list_del(&ul->ul_list); - spin_unlock(&sdp->sd_unlinked_lock); - kfree(ul); - } else - spin_unlock(&sdp->sd_unlinked_lock); -} - -/** - * gfs_unlinked_merge - add/remove a unlinked inode from the in-memory list - * @sdp: the filesystem - * @type: is this a unlink tag or a dealloc tag - * @inum: the inode number - * - * Called during journal recovery. - */ - -void -gfs_unlinked_merge(struct gfs_sbd *sdp, unsigned int type, - struct gfs_inum *inum) -{ - struct gfs_unlinked *ul; - - gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) == - atomic_read(&sdp->sd_unlinked_od_count),); - - ul = gfs_unlinked_get(sdp, inum, CREATE); - - gfs_log_lock(sdp); - - switch (type) { - case GFS_LOG_DESC_IUL: - gfs_unlinked_hold(sdp, ul); - gfs_unlinked_hold(sdp, ul); - gfs_assert(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags) && - !test_bit(ULF_OD_LIST, &ul->ul_flags),); - set_bit(ULF_IC_LIST, &ul->ul_flags); - set_bit(ULF_OD_LIST, &ul->ul_flags); - atomic_inc(&sdp->sd_unlinked_ic_count); - atomic_inc(&sdp->sd_unlinked_od_count); - - break; - - case GFS_LOG_DESC_IDA: - gfs_assert(sdp, test_bit(ULF_IC_LIST, &ul->ul_flags) && - test_bit(ULF_OD_LIST, &ul->ul_flags),); - clear_bit(ULF_IC_LIST, &ul->ul_flags); - clear_bit(ULF_OD_LIST, &ul->ul_flags); - gfs_unlinked_put(sdp, ul); - gfs_unlinked_put(sdp, ul); - gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) > 0,); - atomic_dec(&sdp->sd_unlinked_ic_count); - gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_od_count) > 0,); - atomic_dec(&sdp->sd_unlinked_od_count); - - break; - } - - gfs_log_unlock(sdp); - - gfs_unlinked_put(sdp, ul); -} - -/** - * gfs_unlinked_cleanup - get rid of any extra struct gfs_unlinked structures - * @sdp: the filesystem - * - */ - -void -gfs_unlinked_cleanup(struct gfs_sbd *sdp) -{ - struct gfs_unlinked *ul; - - restart: - gfs_log_lock(sdp); - - gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) == - atomic_read(&sdp->sd_unlinked_od_count),); - - spin_lock(&sdp->sd_unlinked_lock); - - while (!list_empty(&sdp->sd_unlinked_list)) { - ul = list_entry(sdp->sd_unlinked_list.next, - struct gfs_unlinked, ul_list); - - if (ul->ul_count > 2) { - spin_unlock(&sdp->sd_unlinked_lock); - gfs_log_unlock(sdp); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - goto restart; - } - gfs_assert(sdp, ul->ul_count == 2,); - - gfs_assert_warn(sdp, - test_bit(ULF_IC_LIST, &ul->ul_flags) && - test_bit(ULF_OD_LIST, &ul->ul_flags) && - !test_bit(ULF_LOCK, &ul->ul_flags)); - - list_del(&ul->ul_list); - - atomic_dec(&sdp->sd_unlinked_ic_count); - atomic_dec(&sdp->sd_unlinked_od_count); - - spin_unlock(&sdp->sd_unlinked_lock); - kfree(ul); - spin_lock(&sdp->sd_unlinked_lock); - } - - spin_unlock(&sdp->sd_unlinked_lock); - - gfs_assert(sdp, !atomic_read(&sdp->sd_unlinked_ic_count) && - !atomic_read(&sdp->sd_unlinked_od_count),); - - gfs_log_unlock(sdp); -} - -/** - * gfs_unlinked_limit - limit the number of inodes waiting to be deallocated - * @sdp: the filesystem - * - * Returns: errno - */ - -void -gfs_unlinked_limit(struct gfs_sbd *sdp) -{ - unsigned int tries = 0, min = 0; - int error; - - if (atomic_read(&sdp->sd_unlinked_ic_count) >= - gfs_tune_get(sdp, gt_ilimit2)) { - tries = gfs_tune_get(sdp, gt_ilimit2_tries); - min = gfs_tune_get(sdp, gt_ilimit2_min); - } else if (atomic_read(&sdp->sd_unlinked_ic_count) >= - gfs_tune_get(sdp, gt_ilimit1)) { - tries = gfs_tune_get(sdp, gt_ilimit1_tries); - min = gfs_tune_get(sdp, gt_ilimit1_min); - } - - while (tries--) { - struct gfs_unlinked *ul = unlinked_find(sdp); - if (!ul) - break; - - error = gfs_inode_dealloc(sdp, &ul->ul_inum); - - gfs_unlinked_unlock(sdp, ul); - - if (!error) { - if (!--min) - break; - } else if (error != 1) - break; - } -} - -/** - * gfs_unlinked_dealloc - Go through the list of inodes to be deallocated - * @sdp: the filesystem - * - * Returns: errno - */ - -void -gfs_unlinked_dealloc(struct gfs_sbd *sdp) -{ - unsigned int hits, strikes; - int error; - - for (;;) { - hits = 0; - strikes = 0; - - for (;;) { - struct gfs_unlinked *ul = unlinked_find(sdp); - if (!ul) - return; - - error = gfs_inode_dealloc(sdp, &ul->ul_inum); - - gfs_unlinked_unlock(sdp, ul); - - if (!error) { - hits++; - if (strikes) - strikes--; - } else if (error == 1) { - strikes++; - if (strikes >= atomic_read(&sdp->sd_unlinked_ic_count)) { - error = 0; - break; - } - } else - goto out; - } - - if (!hits || !test_bit(SDF_INODED_RUN, &sdp->sd_flags)) - break; - - cond_resched(); - } - - out: - if (error && - error != -EROFS && - !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - printk("GFS: fsid=%s: error deallocating inodes: %d\n", - sdp->sd_fsname, error); -} diff --git a/gfs-kernel/src/gfs/unlinked.h b/gfs-kernel/src/gfs/unlinked.h deleted file mode 100644 index fe676f1..0000000 --- a/gfs-kernel/src/gfs/unlinked.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UNLINKED_DOT_H__ -#define __UNLINKED_DOT_H__ - -struct gfs_unlinked *gfs_unlinked_get(struct gfs_sbd *sdp, - struct gfs_inum *inum, int create); -void gfs_unlinked_hold(struct gfs_sbd *sdp, struct gfs_unlinked *ul); -void gfs_unlinked_put(struct gfs_sbd *sdp, struct gfs_unlinked *ul); - -void gfs_unlinked_lock(struct gfs_sbd *sdp, struct gfs_unlinked *ul); -void gfs_unlinked_unlock(struct gfs_sbd *sdp, struct gfs_unlinked *ul); - -void gfs_unlinked_merge(struct gfs_sbd *sdp, unsigned int type, - struct gfs_inum *inum); -void gfs_unlinked_cleanup(struct gfs_sbd *sdp); - -void gfs_unlinked_limit(struct gfs_sbd *sdp); -void gfs_unlinked_dealloc(struct gfs_sbd *sdp); - -#endif /* __UNLINKED_DOT_H__ */ diff --git a/gfs-kernel/src/gfs/util.c b/gfs-kernel/src/gfs/util.c deleted file mode 100644 index e6308a1..0000000 --- a/gfs-kernel/src/gfs/util.c +++ /dev/null @@ -1,584 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/semaphore.h> -#include <linux/completion.h> -#include <linux/buffer_head.h> -#include <asm/uaccess.h> - -#include "gfs.h" -#include "glock.h" -#include "lm.h" - -uint32_t gfs_random_number; - -kmem_cache_t *gfs_glock_cachep = NULL; -kmem_cache_t *gfs_inode_cachep = NULL; -kmem_cache_t *gfs_bufdata_cachep = NULL; -kmem_cache_t *gfs_mhc_cachep = NULL; - -/** - * gfs_random - Generate a random 32-bit number - * - * Generate a semi-crappy 32-bit pseudo-random number without using - * floating point. - * - * The PRNG is from "Numerical Recipes in C" (second edition), page 284. - * - * Returns: a 32-bit random number - */ - -uint32_t -gfs_random(void) -{ - gfs_random_number = 0x0019660D * gfs_random_number + 0x3C6EF35F; - return gfs_random_number; -} - -/** - * hash_more_internal - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * @hash: the hash from a previous call - * - * Take some data and convert it to a 32-bit hash. - * - * This is the 32-bit FNV-1a hash from: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * Hash guts - * - * Returns: the hash - */ - -static __inline__ uint32_t -hash_more_internal(const void *data, unsigned int len, uint32_t hash) -{ - unsigned char *p = (unsigned char *)data; - unsigned char *e = p + len; - uint32_t h = hash; - - while (p < e) { - h ^= (uint32_t)(*p++); - h *= 0x01000193; - } - - return h; -} - -/** - * gfs_hash - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * Take some data and convert it to a 32-bit hash. - * - * This is the 32-bit FNV-1a hash from: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * Returns: the hash - */ - -uint32_t -gfs_hash(const void *data, unsigned int len) -{ - uint32_t h = 0x811C9DC5; - h = hash_more_internal(data, len, h); - return h; -} - -/** - * gfs_hash_more - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * @hash: the hash from a previous call - * - * Take some data and convert it to a 32-bit hash. - * - * This is the 32-bit FNV-1a hash from: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * This version let's you hash together discontinuous regions. - * For example, to compute the combined hash of the memory in - * (data1, len1), (data2, len2), and (data3, len3) you: - * - * h = gfs_hash(data1, len1); - * h = gfs_hash_more(data2, len2, h); - * h = gfs_hash_more(data3, len3, h); - * - * Returns: the hash - */ - -uint32_t -gfs_hash_more(const void *data, unsigned int len, uint32_t hash) -{ - uint32_t h; - h = hash_more_internal(data, len, hash); - return h; -} - -/* Byte-wise swap two items of size SIZE. */ - -#define SWAP(a, b, size) \ -do { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (__size-- > 1); \ -} while (0) - -/** - * gfs_sort - Sort base array using shell sort algorithm - * @base: the input array - * @num_elem: number of elements in array - * @size: size of each element in array - * @compar: fxn to compare array elements (returns negative - * for lt, 0 for eq, and positive for gt - * - * Sorts the array passed in using the compar fxn to compare elements using - * the shell sort algorithm - */ - -void -gfs_sort(void *base, unsigned int num_elem, unsigned int size, - int (*compar) (const void *, const void *)) -{ - register char *pbase = (char *)base; - int i, j, k, h; - static int cols[16] = {1391376, 463792, 198768, 86961, - 33936, 13776, 4592, 1968, - 861, 336, 112, 48, - 21, 7, 3, 1}; - - for (k = 0; k < 16; k++) { - h = cols[k]; - for (i = h; i < num_elem; i++) { - j = i; - while (j >= h && - (*compar)((void *)(pbase + size * (j - h)), - (void *)(pbase + size * j)) > 0) { - SWAP(pbase + size * j, - pbase + size * (j - h), - size); - j = j - h; - } - } - } -} - -/** - * gfs_assert_i - Cause the machine to panic if @assertion is false - * @sdp: - * @assertion: - * @function: - * @file: - * @line: - * - */ - -void -gfs_assert_i(struct gfs_sbd *sdp, - char *assertion, - const char *function, - char *file, unsigned int line) -{ - if (sdp->sd_args.ar_oopses_ok) { - printk("GFS: fsid=%s: assertion "%s" failed\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, assertion, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); - BUG(); - } - dump_stack(); - panic("GFS: fsid=%s: assertion "%s" failed\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, assertion, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gfs_assert_withdraw_i - Cause the machine to withdraw if @assertion is false - * @sdp: - * @assertion: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -int -gfs_assert_withdraw_i(struct gfs_sbd *sdp, - char *assertion, - const char *function, - char *file, unsigned int line) -{ - int me; - me = gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: assertion "%s" failed\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, assertion, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); - return (me) ? -1 : -2; -} - -/** - * gfs_assert_warn_i - Print a message to the console if @assertion is false - * @sdp: - * @assertion: - * @function: - * @file: - * @line: - * - * Returns: -1 if we printed something - * -2 if we didn't - */ - -int -gfs_assert_warn_i(struct gfs_sbd *sdp, - char *assertion, - const char *function, - char *file, unsigned int line) -{ - if (time_before(jiffies, - sdp->sd_last_warning + - gfs_tune_get(sdp, gt_complain_secs) * HZ)) - return -2; - - printk("GFS: fsid=%s: warning: assertion "%s" failed\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, assertion, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); - - sdp->sd_last_warning = jiffies; - if (sdp->sd_args.ar_debug) - BUG(); - - - return -1; -} - -/** - * gfs_consist_i - Flag a filesystem consistency error and withdraw - * @sdp: - * @cluster_wide: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_consist_i(struct gfs_sbd *sdp, int cluster_wide, - const char *function, - char *file, unsigned int line) -{ - return gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: filesystem consistency error\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gfs_consist_inode_i - Flag an inode consistency error and withdraw - * @ip: - * @cluster_wide: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_consist_inode_i(struct gfs_inode *ip, int cluster_wide, - const char *function, - char *file, unsigned int line) -{ - struct gfs_sbd *sdp = ip->i_sbd; - return gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: filesystem consistency error\n" - "GFS: fsid=%s: inode = %"PRIu64"/%"PRIu64"\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, ip->i_num.no_formal_ino, ip->i_num.no_addr, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gfs_consist_rgrpd_i - Flag a RG consistency error and withdraw - * @rgd: - * @cluster_wide: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_consist_rgrpd_i(struct gfs_rgrpd *rgd, int cluster_wide, - const char *function, - char *file, unsigned int line) -{ - struct gfs_sbd *sdp = rgd->rd_sbd; - return gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: filesystem consistency error\n" - "GFS: fsid=%s: RG = %"PRIu64"\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, rgd->rd_ri.ri_addr, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gfs_meta_check_ii - Flag a magic number consistency error and withdraw - * @sdp: - * @bh: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -int -gfs_meta_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, - const char *function, - char *file, unsigned int line) -{ - int me; - me = gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: invalid metadata block\n" - "GFS: fsid=%s: bh = %"PRIu64" (magic)\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, (uint64_t)bh->b_blocknr, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); - return (me) ? -1 : -2; -} - -/** - * gfs_metatype_check_ii - Flag a metadata type consistency error and withdraw - * @sdp: - * @bh: - * @type: - * @t: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -int -gfs_metatype_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, - uint32_t type, uint32_t t, - const char *function, - char *file, unsigned int line) -{ - int me; - me = gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: invalid metadata block\n" - "GFS: fsid=%s: bh = %"PRIu64" (type: exp=%u, found=%u)\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, (uint64_t)bh->b_blocknr, type, t, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); - return (me) ? -1 : -2; -} - -/** - * gfs_io_error_i - Flag an I/O error and withdraw - * @sdp: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_io_error_i(struct gfs_sbd *sdp, - const char *function, - char *file, unsigned int line) -{ - return gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: I/O error\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gfs_io_error_inode_i - Flag an inode I/O error and withdraw - * @ip: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_io_error_inode_i(struct gfs_inode *ip, - const char *function, - char *file, unsigned int line) -{ - struct gfs_sbd *sdp = ip->i_sbd; - return gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: I/O error\n" - "GFS: fsid=%s: inode = %"PRIu64"/%"PRIu64"\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, ip->i_num.no_formal_ino, ip->i_num.no_addr, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gfs_io_error_bh_i - Flag a buffer I/O error and withdraw - * @sdp: - * @bh: - * @function: - * @file: - * @line: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int -gfs_io_error_bh_i(struct gfs_sbd *sdp, struct buffer_head *bh, - const char *function, - char *file, unsigned int line) -{ - return gfs_lm_withdraw(sdp, - "GFS: fsid=%s: fatal: I/O error\n" - "GFS: fsid=%s: block = %"PRIu64"\n" - "GFS: fsid=%s: function = %s\n" - "GFS: fsid=%s: file = %s, line = %u\n" - "GFS: fsid=%s: time = %lu\n", - sdp->sd_fsname, - sdp->sd_fsname, (uint64_t)bh->b_blocknr, - sdp->sd_fsname, function, - sdp->sd_fsname, file, line, - sdp->sd_fsname, get_seconds()); -} - -/** - * gmalloc - malloc a small amount of memory - * @size: the number of bytes to malloc - * - * Returns: the memory - */ - -void * -gmalloc(unsigned int size) -{ - void *p; - RETRY_MALLOC(p = kmalloc(size, GFP_KERNEL), p); - return p; -} - -/** - * gfs_add_bh_to_ub - copy a buffer up to user space - * @ub: the structure representing where to copy - * @bh: the buffer - * - * Returns: errno - */ - -int -gfs_add_bh_to_ub(struct gfs_user_buffer *ub, struct buffer_head *bh) -{ - uint64_t blkno = bh->b_blocknr; - - if (ub->ub_count + sizeof(uint64_t) + bh->b_size > ub->ub_size) - return -ENOMEM; - - if (copy_to_user(ub->ub_data + ub->ub_count, - &blkno, - sizeof(uint64_t))) - return -EFAULT; - ub->ub_count += sizeof(uint64_t); - - if (copy_to_user(ub->ub_data + ub->ub_count, - bh->b_data, - bh->b_size)) - return -EFAULT; - ub->ub_count += bh->b_size; - - return 0; -} - diff --git a/gfs-kernel/src/gfs/util.h b/gfs-kernel/src/gfs/util.h deleted file mode 100644 index 2d6f66c..0000000 --- a/gfs-kernel/src/gfs/util.h +++ /dev/null @@ -1,343 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UTIL_DOT_H__ -#define __UTIL_DOT_H__ - - -/* Utility functions */ - -extern uint32_t gfs_random_number; -uint32_t gfs_random(void); - -uint32_t gfs_hash(const void *data, unsigned int len); -uint32_t gfs_hash_more(const void *data, unsigned int len, uint32_t hash); - -void gfs_sort(void *base, unsigned int num_elem, unsigned int size, - int (*compar) (const void *, const void *)); - - -/* Error handling */ - -/** - * gfs_assert - Cause the machine to panic if @assertion is false - * @sdp: - * @assertion: - * @todo: - * - */ - -void gfs_assert_i(struct gfs_sbd *sdp, - char *assertion, - const char *function, - char *file, unsigned int line) -__attribute__ ((noreturn)); -#define gfs_assert(sdp, assertion, todo) \ -do { \ - if (unlikely(!(assertion))) { \ - {todo} \ - gfs_assert_i((sdp), #assertion, \ - __FUNCTION__, __FILE__, __LINE__); \ - } \ -} while (0) - -/** - * gfs_assert_withdraw - Cause the machine to withdraw if @assertion is false - * @sdp: - * @assertion: - * - * Returns: 0 if things are ok, - * -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -int gfs_assert_withdraw_i(struct gfs_sbd *sdp, - char *assertion, - const char *function, - char *file, unsigned int line); -#define gfs_assert_withdraw(sdp, assertion) \ -((likely(assertion)) ? 0 : \ - gfs_assert_withdraw_i((sdp), #assertion, \ - __FUNCTION__, __FILE__, __LINE__)) - -/** - * gfs_assert_warn - Print a message to the console if @assertion is false - * @sdp: - * @assertion: - * - * Returns: 0 if things are ok, - * -1 if we printed something - * -2 if we didn't - */ - -int gfs_assert_warn_i(struct gfs_sbd *sdp, - char *assertion, - const char *function, - char *file, unsigned int line); -#define gfs_assert_warn(sdp, assertion) \ -((likely(assertion)) ? 0 : \ - gfs_assert_warn_i((sdp), #assertion, \ - __FUNCTION__, __FILE__, __LINE__)) - -/** - * gfs_consist - Flag a filesystem consistency error and withdraw - * gfs_cconsist - Flag a filesystem consistency error and withdraw cluster - * @sdp: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int gfs_consist_i(struct gfs_sbd *sdp, int cluster_wide, - const char *function, - char *file, unsigned int line); -#define gfs_consist(sdp)\ -gfs_consist_i((sdp), FALSE, __FUNCTION__, __FILE__, __LINE__) -#define gfs_cconsist(sdp)\ -gfs_consist_i((sdp), TRUE, __FUNCTION__, __FILE__, __LINE__) - -/** - * gfs_consist_inode - Flag an inode consistency error and withdraw - * gfs_cconsist_inode - Flag an inode consistency error and withdraw cluster - * @ip: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int gfs_consist_inode_i(struct gfs_inode *ip, int cluster_wide, - const char *function, - char *file, unsigned int line); -#define gfs_consist_inode(ip) \ -gfs_consist_inode_i((ip), FALSE, __FUNCTION__, __FILE__, __LINE__) -#define gfs_cconsist_inode(ip) \ -gfs_consist_inode_i((ip), TRUE, __FUNCTION__, __FILE__, __LINE__) - -/** - * gfs_consist_rgrpd - Flag a RG consistency error and withdraw - * gfs_cconsist_rgrpd - Flag a RG consistency error and withdraw cluster - * @rgd: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int gfs_consist_rgrpd_i(struct gfs_rgrpd *rgd, int cluster_wide, - const char *function, - char *file, unsigned int line); -#define gfs_consist_rgrpd(rgd) \ -gfs_consist_rgrpd_i((rgd), FALSE, __FUNCTION__, __FILE__, __LINE__) -#define gfs_cconsist_rgrpd(rgd) \ -gfs_consist_rgrpd_i((rgd), TRUE, __FUNCTION__, __FILE__, __LINE__) - -/** - * gfs_meta_check - Flag a magic number consistency error and withdraw - * @sdp: - * @bh: - * - * Returns: 0 if things are ok, - * -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -int gfs_meta_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, - const char *function, - char *file, unsigned int line); -static __inline__ int -gfs_meta_check_i(struct gfs_sbd *sdp, struct buffer_head *bh, - const char *function, - char *file, unsigned int line) -{ - uint32_t magic; - magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; - magic = gfs32_to_cpu(magic); - if (likely(magic == GFS_MAGIC)) - return 0; - return gfs_meta_check_ii(sdp, bh, function, file, line); -} -#define gfs_meta_check(sdp, bh) \ -gfs_meta_check_i((sdp), (bh), \ - __FUNCTION__, __FILE__, __LINE__) - -/** - * gfs_metatype_check - Flag a metadata type consistency error and withdraw - * @sdp: - * @bh: - * @type: - * - * Returns: 0 if things are ok, - * -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -int gfs_metatype_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, - uint32_t type, uint32_t t, - const char *function, - char *file, unsigned int line); -static __inline__ int -gfs_metatype_check_i(struct gfs_sbd *sdp, struct buffer_head *bh, - uint32_t type, - const char *function, - char *file, unsigned int line) -{ - uint32_t magic, t; - magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; - magic = gfs32_to_cpu(magic); - if (unlikely(magic != GFS_MAGIC)) - return gfs_meta_check_ii(sdp, bh, function, file, line); - t = ((struct gfs_meta_header *)(bh)->b_data)->mh_type; - t = gfs32_to_cpu(t); - if (unlikely(t != type)) - return gfs_metatype_check_ii(sdp, bh, type, t, function, file, line); - return 0; -} -#define gfs_metatype_check(sdp, bh, type) \ -gfs_metatype_check_i((sdp), (bh), (type), \ - __FUNCTION__, __FILE__, __LINE__) - -/** - * gfs_metatype_check2 - Flag a metadata type consistency error and withdraw - * @sdp: - * @bh: - * @type1: - * @type2: - * - * Returns: 0 if things are ok, - * -1 if this call withdrew the machine, - * -2 if it was already withdrawn - */ - -static __inline__ int -gfs_metatype_check2_i(struct gfs_sbd *sdp, struct buffer_head *bh, - uint32_t type1, uint32_t type2, - const char *function, - char *file, unsigned int line) -{ - uint32_t magic, t; - magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; - magic = gfs32_to_cpu(magic); - if (unlikely(magic != GFS_MAGIC)) - return gfs_meta_check_ii(sdp, bh, function, file, line); - t = ((struct gfs_meta_header *)(bh)->b_data)->mh_type; - t = gfs32_to_cpu(t); - if (unlikely(t != type1 && t != type2)) - return gfs_metatype_check_ii(sdp, bh, type1, t, function, file, line); - return 0; -} -#define gfs_metatype_check2(sdp, bh, type1, type2) \ -gfs_metatype_check2_i((sdp), (bh), (type1), (type2), \ - __FUNCTION__, __FILE__, __LINE__) - -/** - * gfs_metatype_set - set the metadata type on a buffer - * @bh: - * @type: - * @format: - * - */ - -static __inline__ void -gfs_metatype_set(struct buffer_head *bh, uint32_t type, uint32_t format) -{ - struct gfs_meta_header *mh; - mh = (struct gfs_meta_header *)bh->b_data; - mh->mh_type = cpu_to_gfs32(type); - mh->mh_format = cpu_to_gfs32(format); -} - -/** - * gfs_io_error - Flag an I/O error and withdraw - * @sdp: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int gfs_io_error_i(struct gfs_sbd *sdp, - const char *function, - char *file, unsigned int line); -#define gfs_io_error(sdp) \ -gfs_io_error_i((sdp), __FUNCTION__, __FILE__, __LINE__); - -/** - * gfs_io_error_inode - Flag an inode I/O error and withdraw - * @ip: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int gfs_io_error_inode_i(struct gfs_inode *ip, - const char *function, - char *file, unsigned int line); -#define gfs_io_error_inode(ip) \ -gfs_io_error_inode_i((ip), __FUNCTION__, __FILE__, __LINE__); - -/** - * gfs_io_error_bh - Flag a buffer I/O error and withdraw - * @sdp: - * @bh: - * - * Returns: -1 if this call withdrew the machine, - * 0 if it was already withdrawn - */ - -int gfs_io_error_bh_i(struct gfs_sbd *sdp, struct buffer_head *bh, - const char *function, - char *file, unsigned int line); -#define gfs_io_error_bh(sdp, bh) \ -gfs_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); - - -/* Memory stuff */ - -#define RETRY_MALLOC(do_this, until_this) \ -for (;;) { \ - { do_this; } \ - if (until_this) \ - break; \ - printk("GFS: out of memory: %s, %u\n", __FILE__, __LINE__); \ - dump_stack(); \ - yield(); \ -} - -extern kmem_cache_t *gfs_glock_cachep; -extern kmem_cache_t *gfs_inode_cachep; -extern kmem_cache_t *gfs_bufdata_cachep; -extern kmem_cache_t *gfs_mhc_cachep; - -void *gmalloc(unsigned int size); - - -struct gfs_user_buffer { - char *ub_data; - unsigned int ub_size; - unsigned int ub_count; -}; -int gfs_add_bh_to_ub(struct gfs_user_buffer *ub, struct buffer_head *bh); - - -static __inline__ unsigned int -gfs_tune_get_i(struct gfs_tune *gt, unsigned int *p) -{ - unsigned int x; - spin_lock(>->gt_spin); - x = *p; - spin_unlock(>->gt_spin); - return x; -} -#define gfs_tune_get(sdp, field) \ -gfs_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field) - - -#endif /* __UTIL_DOT_H__ */ diff --git a/gfs-kernel/src/gulm/Makefile b/gfs-kernel/src/gulm/Makefile deleted file mode 100644 index e81f798..0000000 --- a/gfs-kernel/src/gulm/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = ../.. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/src/linux-orig -linux_patched = ${top_srcdir}/src/linux-patched - -PWD := $(shell pwd) - -TARGET = lock_gulm.patch -SYMVERFILE := ${PWD}/../harness/lock_harness.symvers - -obj-m := lock_gulm.o -lock_gulm-objs := gulm_core.o \ - gulm_firstlock.o \ - gulm_fs.o \ - gulm_jid.o \ - gulm_lock_queue.o \ - gulm_lt.o \ - gulm_main.o \ - gulm_plock.o \ - gulm_recsig.o \ - handler.o \ - lg_core.o \ - lg_lock.o \ - lg_main.o \ - utils_tostr.o \ - xdr_base.o \ - xdr_io.o \ - xdr_socket.o - -EXTRA_CFLAGS += -I$(obj) - -all: - rm -f linux lm_interface.h - ln -s . linux - ln -s ${top_srcdir}/src/harness/lm_interface.h . - ${MAKE} -C ${KERNEL_SRC} M=${PWD} symverfile=${SYMVERFILE} modules USING_KBUILD=yes - ${KERNEL_SRC}/scripts/mod/modpost -m -i ${SYMVERFILE} ../gulm/lock_gulm.o -o lock_gulm.symvers - -install: all - install -d ${module_dir}/fs/gfs_locking/lock_gulm - install lock_gulm.ko ${module_dir}/fs/gfs_locking/lock_gulm - -uninstall: - ${UNINSTALL} lock_gulm.ko ${module_dir}/fs/gfs_locking/lock_gulm - -clean: - rm -rf linux lm_interface.h *.mod.c .lock_gulm.ko.cmd \ - .tmp_versions *o .*.o.cmd *~ - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -rlt --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir}/src ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/fs/gfs_locking/lock_gulm - cp *.[ch] ${linux_patched}/fs/gfs_locking/lock_gulm diff --git a/gfs-kernel/src/gulm/gio_wiretypes.h b/gfs-kernel/src/gulm/gio_wiretypes.h deleted file mode 100644 index 21b3b19..0000000 --- a/gfs-kernel/src/gulm/gio_wiretypes.h +++ /dev/null @@ -1,486 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gio_wiretypes_h__ -#define __gio_wiretypes_h__ - -/* an attempt to do something about tracking changes to the protocol over - * the wires. - * If I was really cute, this would be effectivily a checksum of this file. - */ -#define GIO_WIREPROT_VERS (0x67000015) - -/*****************Error codes. - * everyone uses these same error codes. - */ -#define gio_Err_Ok (0) -#define gio_Err_BadLogin (1001) -#define gio_Err_BadCluster (1003) -#define gio_Err_BadConfig (1004) -#define gio_Err_BadGeneration (1005) -#define gio_Err_BadWireProto (1019) - -#define gio_Err_NotAllowed (1006) -#define gio_Err_Unknown_Cs (1007) -#define gio_Err_BadStateChg (1008) -#define gio_Err_MemoryIssues (1009) - -#define gio_Err_TryFailed (1011) -#define gio_Err_AlreadyPend (1013) -#define gio_Err_Canceled (1015) - -/* next free error code: 1002 1010 1012 1014 1016 1017 1018 1020 */ - -/* - * Error: just sort of a generic error code thing. - * uint32: gERR - * uint32: opcode that this is in reply to. (can be zeros) - * uint32: error code - */ -#define gulm_err_reply (0x67455252) /* gERR */ - -#define gulm_nop (0x674e4f50) /* gNOP */ - -/********************* Core *****************/ -/* - * login request - * uint32: gCL0 - * uint32: proto version - * string: cluster ID - * string: My Name - * uint64: generation number - * uint32: config CRC - * uint32: rank - * login reply - * uint32: gCL1 - * uint64: generation number - * uint32: error code - * uint32: rank - * uint8: ama - * If I am the Master or Arbitrating and there are no errors, A - * serialization of the current nodelist follows. And a client or slave - * is connecting (not resources). - * - * logout request: - * uint32: gCL2 - * string: node name - * uint8: S/P/A/M/R - * logout reply: Don't seem to use this.... - * uint32: gCL3 - * uint32: error code - * - * resource login request: - * uint32: gCL4 - * uint32: proto version - * string: cluster ID - * string: resource name - * uint32: options - * login reply (gCL1) is sent in return. - * - * beat req - * uint32: gCB0 - * string: My Name - * beat rpl - * uint32: gCB1 - * uint32: error code - * - * Membership Request - * uint32: gCMA - * string: node name - * - * Membership update - * uint32: gCMU - * string: node name - * IPv6: IP - * uint8: Current State - * - * Membership list request info. - * uint32: gCMl - * - * Membership list info. - * uint32: gCML - * list_start_marker - * string: node name - * IPv6: IP - * uint8: state - * uint8: laststate - * uint8: mode (S/P/A/M/C) - * uint32: missed beats - * uint64: last beat - * uint64: delay avg - * uint64: max delay - * list_stop_marker - * - * Request Resource info - * uint32: gCR0 - * - * Resource list info - * uint32: gCR1 - * list_start_marker - * string: name - * list_stop_marker - * - * Force node into Expired: - * uint32: gCFE - * string: node name - * - * Core state request: - * uint32: gCSR - * - * Core state changes: - * uint32: gCSC - * uint8: state (slave, pending, arbitrating, master) - * uint8: quorate (true/false) - * If state == Slave, then the next two will follow. - * IPv6: MasterIP - * string: MasterName - * - * Quorum Change: - * uint32: gCQC - * uint8: quorate (true/false) - * - * Core shutdown req: - * uint32: gCSD - * - * Switch core from current state into Pending: - * uint32: gCSP - * - * Fetch the current config - * uint32: gCC0 - * Current Config Reply: - * uint32: gCC1 - * list start: - * string: key - * string: value - * list stop: - * - */ -#define gulm_core_login_req (0x67434c00) /* gCL0 */ -#define gulm_core_login_rpl (0x67434c01) /* gCL1 */ -#define gulm_core_logout_req (0x67434c02) /* gCL2 */ -#define gulm_core_logout_rpl (0x67434c03) /* gCL3 */ -#define gulm_core_reslgn_req (0x67434c04) /* gCL4 */ -#define gulm_core_beat_req (0x67434200) /* gCB0 */ -#define gulm_core_beat_rpl (0x67434201) /* gCB1 */ -#define gulm_core_mbr_req (0x67434d41) /* gCMA */ -#define gulm_core_mbr_updt (0x67434d55) /* gCMU */ -#define gulm_core_mbr_lstreq (0x67434d6c) /* gCMl */ -#define gulm_core_mbr_lstrpl (0x67434d4c) /* gCML */ -#define gulm_core_mbr_force (0x67434645) /* gCFE */ -#define gulm_core_res_req (0x67435200) /* gCR0 */ -#define gulm_core_res_list (0x67435201) /* gCR1 */ -#define gulm_core_state_req (0x67435352) /* gCSR */ -#define gulm_core_state_chgs (0x67435343) /* gCSC */ -#define gulm_core_quorm_chgs (0x67435143) /* gCSC */ -#define gulm_core_shutdown (0x67435344) /* gCSD */ -#define gulm_core_forcepend (0x67435350) /* gCSP */ -#define gulm_core_configreq (0x67434300) /* gCC0 */ -#define gulm_core_configrpl (0x67434301) /* gCC1 */ - -/* in the st field */ -#define gio_Mbr_Logged_in (0x05) -#define gio_Mbr_Logged_out (0x06) -#define gio_Mbr_Expired (0x07) -#define gio_Mbr_Killed (0x08) -#define gio_Mbr_OM_lgin (0x09) - -/* in the ama field */ -#define gio_Mbr_ama_Slave (0x01) -#define gio_Mbr_ama_Master (0x02) -#define gio_Mbr_ama_Pending (0x03) -#define gio_Mbr_ama_Arbitrating (0x04) -#define gio_Mbr_ama_Resource (0x05) -#define gio_Mbr_ama_Client (0x06) -/* the Client entery is ONLY for mode tracking. - * nodelist reply is the only place it is used. - */ - -/* options that affect behavors on services. (resources) */ -#define gulm_svc_opt_important (0x00000001) -#define gulm_svc_opt_locked (0x00000002) - -/********************* Info Traffic ***************** - * - * Note that for many of these, they can be sent to all of the servers and - * will get sane replies. Some of these can only be sent to specific - * servers. - * - * stats req: - * uint32: gIS0 - * stats rpl: - * uint32: gIS1 - * list start: - * string: key - * string: value - * list stop: - * Notes: - * The stats reply is a set of string pairs. This way the server can send - * whatever things it wants, and the same client code will work for - * anything. - * - * set verbosity: - * uint32: gIV0 - * string: verb flags (with -/+) to [un]set - * Note: - * We don't bother with a reply for this. If the server got it, it works. - * If it didn't, it cannot send an error back anyways. - * - * close socket: - * uint32: gSC0 - * Note: - * Tells the server to close this connection cleanly. We're done with - * it. This is *not* the same as loging out. You must login before you - * can logout. And many commands sent from gulm_tool happen without - * logging in. These commands would be useful for clients in many cases, - * so I don't want to put a close at the end of them, but if I don't, - * there will be error messages printed on the console when gulm_tool - * calls them. - * So we need a way to close a connection cleanly that has not been - * logged in. - * - * request slave list: - * uint32: gIL0 - * slave list replay: - * uint32: gIL1 - * list start: - * string: name - * uint32: poller idx - * list stop: - */ -#define gulm_info_stats_req (0x67495300) /* gIS0 */ -#define gulm_info_stats_rpl (0x67495301) /* gIS1 */ -#define gulm_info_set_verbosity (0x67495600) /* gIV0 */ -#define gulm_socket_close (0x67534300) /* gSC0 */ -#define gulm_info_slave_list_req (0x67494c00) /* gIL0 */ -#define gulm_info_slave_list_rpl (0x67494c01) /* gIL1 */ - -/********************* Lock Traffic ***************** - * All lock traffic. - * - * login req: - * uint32: gLL0 - * uint32: proto version - * string: node name - * uint8: Client/Slave - * login rpl: - * uint32: gLL1 - * uint32: error code - * uint8: Slave/Master - * xdr of current lock state if no errors and master sending reply - * and you're a slave. - * - * logout req: - * uint32: gLL2 - * logout rpl: - * uint32: gLL3 - * - * select lockspace: - * uint32: gLS0 - * raw: usually just four bytes for lockspace name. - * but can be most anything. - * uh, i think i assume that it is only four bytes in some places. - * Need to look into this... - * - * lock req: - * uint32: gLR0 - * raw: key - * uint64: sub id - * uint64: start - * uint64: stop - * uint8: state - * uint32: flags - * raw: lvb -- Only exists if hasLVB flag is true. - * lock rpl: - * uint32: gLR1 - * raw: key - * uint64: sub id - * uint64: start - * uint64: stop - * uint8: state - * uint32: flags - * uint32: error code - * raw: lvb -- Only exists if hasLVB flag is true. - * - * lock state update: - * uint32: gLRU - * string: node name - * uint64: sub id - * uint64: start - * uint64: stop - * raw: key - * uint8: state - * uint32: flags - * raw: lvb -- Only exists if hasLVB flag is true. - * - * Action req: - * uint32: gLA0 - * raw: key - * uint64: sub id - * uint8: action - * raw: lvb -- Only exists if action is SyncLVB - * Action Rpl: - * uint32: gLA1 - * raw: key - * uint64: sub id - * uint8: action - * uint32: error code - * - * Action update: - * uint32: gLAU - * string: node name - * uint64: sub id - * raw: key - * uint8: action - * raw: lvb -- Only exists if action is SyncLVB - * - * Slave Update Rply: -- for both actions and requests. - * uint32: gLUR - * raw: key - * - * Query Lock Request: - * uint32: gLQ0 - * raw: key - * uint64: subid - * uint64: start - * uint64: stop - * uint8: state - * - * Query Lock Reply: - * uint32: gLQ1 - * raw: key - * uint64: subid - * uint64: start - * uint64: stop - * uint8: state - * uint32: error - * list start mark - * string: node - * uint64: subid - * uint64: start - * uint64: stop - * uint8: state - * list stop mark - * - * Drop lock Callback: - * uint32: gLC0 - * raw: key - * uint64: subid - * uint8: state - * - * Drop all locks callback: This is the highwater locks thing - * uint32: gLC2 - * - * Drop expired locks: - * uint32: gLEO - * string: node name if NULL, then drop all exp for mask. - * raw: keymask if keymask & key == key, then dropexp on this lock. - * - * Expire Locks: - * uint32: gLEE - * string: node name cannot be NULL - * raw: keymask if keymask & key == key, then expire on this lock. - * - * Lock list req: - * uint32: gLD0 - * Lock list rpl: - * uint32: gLD1 - * list start mark - * uint8: key length - * raw: key - * uint8: lvb length - * if lvb length > 0, raw: LVB - * uint32: Holder count - * list start mark - * string: holders - * uint64: subid - * uint8: state - * uint64: start - * uint64: stop - * list stop mark - * uint32: LVB holder count - * list start mark - * string: LVB Holders - * uint64: subid - * list stop mark - * uint32: Expired holder count - * list start mark - * string: ExpHolders - * uint64: subid - * list stop mark - * list stop mark - * - */ -#define gulm_lock_login_req (0x674C4C00) /* gLL0 */ -#define gulm_lock_login_rpl (0x674C4C01) /* gLL1 */ -#define gulm_lock_logout_req (0x674C4C02) /* gLL2 */ -#define gulm_lock_logout_rpl (0x674C4C03) /* gLL3 */ -#define gulm_lock_sel_lckspc (0x674C5300) /* gLS0 */ -#define gulm_lock_state_req (0x674C5200) /* gLR0 */ -#define gulm_lock_state_rpl (0x674C5201) /* gLR1 */ -#define gulm_lock_state_updt (0x674C5255) /* gLRU */ -#define gulm_lock_action_req (0x674C4100) /* gLA0 */ -#define gulm_lock_action_rpl (0x674C4101) /* gLA1 */ -#define gulm_lock_action_updt (0x674C4155) /* gLAU */ -#define gulm_lock_update_rpl (0x674c5552) /* gLUR */ -#define gulm_lock_query_req (0x674c5100) /* gLQ0 */ -#define gulm_lock_query_rpl (0x674c5101) /* gLQ1 */ -#define gulm_lock_cb_state (0x674C4300) /* gLC0 */ -#define gulm_lock_cb_dropall (0x674C4302) /* gLC2 */ -#define gulm_lock_drop_exp (0x674C454F) /* gLEO */ -#define gulm_lock_expire (0x674C4545) /* gLEE */ -#define gulm_lock_dump_req (0x674c4400) /* gLD0 */ -#define gulm_lock_dump_rpl (0x674c4401) /* gLD1 */ -#define gulm_lock_rerunqueues (0x674c5251) /* gLRQ */ - -/* marks for the login */ -#define gio_lck_st_Slave (0x00) -#define gio_lck_st_Client (0x01) - -/* state change requests */ -#define gio_lck_st_Unlock (0x00) -#define gio_lck_st_Exclusive (0x01) -#define gio_lck_st_Deferred (0x02) -#define gio_lck_st_Shared (0x03) -/* actions */ -#define gio_lck_st_Cancel (0x09) -#define gio_lck_st_HoldLVB (0x0b) -#define gio_lck_st_UnHoldLVB (0x0c) -#define gio_lck_st_SyncLVB (0x0d) - -/* flags */ - /* only valid with Try. Tells server to send out a drop lock callback. */ -#define gio_lck_fg_Do_CB (0x00000001) - /* try to get, if there are conflicts, return error instead of blocking */ -#define gio_lck_fg_Try (0x00000002) - /* Either Shared or Deferred. Only valid when state is Shr or Dfr. */ -#define gio_lck_fg_Any (0x00000004) - /* Ignore any expired holders on lock. */ -#define gio_lck_fg_NoExp (0x00000008) - /* There is an LVB attached to this lock msg. */ -#define gio_lck_fg_hasLVB (0x00000010) - /* Only returned by server. There was no internal unlocking to grant req. */ -#define gio_lck_fg_Cachable (0x00000020) - /* Put this request onto the front of the request queues. */ -#define gio_lck_fg_Piority (0x00000040) - /* this is just an idea, but it might be useful. Basically just says to - * not keep the exp hold, just drop this hold like a shared would be. - * no idea if it would be useful or sane. (but its two lines of code) - */ -#define gio_lck_fg_DropOnExp (0x00000080) - /* this is saved on each holder, basically, you are gonna ignore any - * callbacks about this lock, so tell the server not to even bother - * sending them. A tiny performance boost by lowering the network load. - */ -#define gio_lck_fg_NoCallBacks (0x00000100) - -#endif /*__gio_wiretypes_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gfs-kernel/src/gulm/gulm.h b/gfs-kernel/src/gulm/gulm.h deleted file mode 100644 index b13d2ff..0000000 --- a/gfs-kernel/src/gulm/gulm.h +++ /dev/null @@ -1,256 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef GULM_DOT_H -#define GULM_DOT_H - -#define GULM_RELEASE_NAME "<CVS>" - -/* uh, do I need all of these headers? */ -#ifdef MODVERSIONS -#include <linux/modversions.h> -#endif /* MODVERSIONS */ -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <asm/atomic.h> -#include <linux/config.h> -#include <linux/version.h> -#include <linux/smp_lock.h> -#include <linux/list.h> -#include <linux/types.h> -#include <linux/fs.h> - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#if (BITS_PER_LONG == 64) -#define PRIu64 "lu" -#define PRId64 "ld" -#define PRIo64 "lo" -#define PRIx64 "lx" -#define PRIX64 "lX" -#define SCNu64 "lu" -#define SCNd64 "ld" -#define SCNo64 "lo" -#define SCNx64 "lx" -#define SCNX64 "lX" -#else -#define PRIu64 "Lu" -#define PRId64 "Ld" -#define PRIo64 "Lo" -#define PRIx64 "Lx" -#define PRIX64 "LX" -#define SCNu64 "Lu" -#define SCNd64 "Ld" -#define SCNo64 "Lo" -#define SCNx64 "Lx" -#define SCNX64 "LX" -#endif - - -#undef MAX -#define MAX(a,b) ((a>b)?a:b) - -#undef MIN -#define MIN(a,b) ((a<b)?a:b) - -/* Divide x by y. Round up if there is a remainder. */ -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) - -#include <linux/lm_interface.h> - -#include "gulm_prints.h" - -#include "libgulm.h" - -#include "handler.h" - -/* Really should try to avoid using this. - */ -#define RETRY_MALLOC(do_this, until_this) \ -for (;;) { \ - { do_this; } \ - if (until_this) \ - break; \ - printk("LOCK_GULM: out of memory: %s, %u\n", __FILE__, __LINE__); \ - yield(); \ -} - -/* Some fixed length constants. - * Some of these should be made dynamic in size in the future. - */ -#define GIO_KEY_SIZE (48) -#define GIO_LVB_SIZE (32) -#define GIO_NAME_SIZE (32) -#define GIO_NAME_LEN (GIO_NAME_SIZE-1) -#define GULM_CRC_INIT (0x6d696b65) - -/* a hash bucket - * this puts the bucket list and the spinlock for the list next to each - * other. Mostly because it makes things nice and easy if we're on a - * nonsmp machine and the spinlocks don't exist. (previously I tried to - * malloc nothing. kernel wasn't happy about that.) - * - * An array of these makes a hash table. - */ -struct gulm_hash_bucket_s { - struct list_head bucket; - spinlock_t lock; -}; -typedef struct gulm_hash_bucket_s gulm_hb_t; - -/* What we know about this filesytem */ -struct gulm_fs_s { - struct list_head fs_list; - char fs_name[GIO_NAME_SIZE]; /* lock table name */ - - lm_callback_t cb; /* file system callback function */ - lm_fsdata_t *fsdata; /* private file system data */ - - callback_qu_t cq; - - uint32_t fsJID; - uint32_t lvb_size; - - /* Stuff for the first mounter lock and state */ - int firstmounting; - /* the recovery done func needs to behave slightly differnt when we are - * the first node in an fs. - */ - - /* Stuff for JID mapping locks */ - uint32_t JIDcount; /* how many JID locks are there. */ - struct semaphore headerlock; -}; -typedef struct gulm_fs_s gulm_fs_t; - -typedef struct gulm_cm_s { - uint8_t myName[64]; - uint8_t clusterID[256]; /* doesn't need to be 256. */ - uint8_t starts; - - uint32_t handler_threads; /* howmany to have */ - uint32_t verbosity; - - uint64_t GenerationID; - - /* lm interface pretty much requires that we maintian a table of - * locks. The way lvbs work is a prefect example of why. As is - * the panic you get if you send a cb up about a lock that has been - * put away. - */ - gulm_hb_t *gfs_lockmap; - - gulm_interface_p hookup; - -} gulm_cm_t; - -/* things about each lock. */ -typedef struct gulm_lock_s { - struct list_head gl_list; - atomic_t count; /* gfs can call multiple gets and puts for same lock. */ - - uint8_t *key; - uint16_t keylen; - gulm_fs_t *fs; /* which fs we belong to */ - char *lvb; - int cur_state; /* for figuring out wat reply to tell gfs. */ -} gulm_lock_t; - - -/*****************************************************************************/ -/* cross pollenate prototypes */ - -/* from gulm_firstlock.c */ -int get_mount_lock (gulm_fs_t * fs, int *first); -int downgrade_mount_lock (gulm_fs_t * fs); -int drop_mount_lock (gulm_fs_t * fs); - -/* from gulm_lt.c */ -int gulm_lt_init (void); -void gulm_lt_release(void); -int pack_lock_key(uint8_t *key, uint16_t keylen, uint8_t type, - uint8_t *fsname, uint8_t *pk, uint8_t pklen); -int pack_drop_mask(uint8_t *mask, uint16_t mlen, uint8_t *fsname); -void do_drop_lock_req (uint8_t *key, uint16_t keylen, uint8_t state); -int gulm_get_lock (lm_lockspace_t * lockspace, struct lm_lockname *name, - lm_lock_t ** lockp); -void gulm_put_lock (lm_lock_t * lock); -unsigned int gulm_lock (lm_lock_t * lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags); -unsigned int gulm_unlock (lm_lock_t * lock, unsigned int cur_state); -void gulm_cancel (lm_lock_t * lock); -int gulm_hold_lvb (lm_lock_t * lock, char **lvbp); -void gulm_unhold_lvb (lm_lock_t * lock, char *lvb); -void gulm_sync_lvb (lm_lock_t * lock, char *lvb); - -/* from gulm_plock.c */ -int gulm_punlock (lm_lockspace_t * lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl); -int gulm_plock (lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl); -int gulm_plock_get (lm_lockspace_t * lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl); - -/*from gulm_core.c */ -void cm_logout (void); -int cm_login (void); -void delete_ipnames (struct list_head *namelist); - -/* from gulm_fs.c */ -void init_gulm_fs (void); -void request_journal_replay (uint8_t * name); -void check_all_for_stales(void); -void passup_droplocks (void); -gulm_fs_t *get_fs_by_name (uint8_t * name); -void dump_internal_lists (void); -void gulm_recovery_done (lm_lockspace_t * lockspace, - unsigned int jid, unsigned int message); -void gulm_unmount (lm_lockspace_t * lockspace); -void gulm_others_may_mount (lm_lockspace_t * lockspace); -int gulm_mount (char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t * fsdata, - unsigned int min_lvb_size, struct lm_lockstruct *lockstruct); -void gulm_withdraw (lm_lockspace_t * lockspace); - -/* from gulm_jid.c */ -void jid_fs_init (gulm_fs_t * fs); -void jid_fs_release (gulm_fs_t * fs); -void get_journalID (gulm_fs_t * fs); -int lookup_name_by_jid (gulm_fs_t * fs, uint32_t jid, uint8_t * name); -void release_JID (gulm_fs_t * fs, uint32_t jid); -void put_journalID (gulm_fs_t * fs, int leavebehind); -void check_for_stale_expires (gulm_fs_t * fs); - -int find_jid_by_name_and_mark_replay (gulm_fs_t * fs, uint8_t * name, uint32_t * jid); - -/* to be called from the lg_lock callbacks. */ -void jid_header_lock_drop (uint8_t * key, uint16_t keylen); -void sig_watcher_lock_drop(uint8_t * key, uint16_t keylen); - -/* from gulm_recsig.c */ -void tap_sig(gulm_fs_t *fs, uint8_t *name, uint8_t len); -int watch_sig(gulm_fs_t *fs, uint8_t *name, uint8_t len, - void(*func)(void *misc), void *misc); -void sig_watcher_init(void); - -extern struct lm_lockops gulm_ops; - -#endif /* GULM_DOT_H */ -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_core.c b/gfs-kernel/src/gulm/gulm_core.c deleted file mode 100644 index 4680b50..0000000 --- a/gfs-kernel/src/gulm/gulm_core.c +++ /dev/null @@ -1,259 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/file.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "gulm_lock_queue.h" -#include "utils_tostr.h" - -extern gulm_cm_t gulm_cm; - -/* private vars. */ -int cm_thd_running; -struct completion cm_thd_startup; -struct task_struct *cm_thd_task; -/** - */ -int -gulm_core_login_reply (void *misc, uint64_t gen, uint32_t error, - uint32_t rank, uint8_t corestate) -{ - if (error != 0) { - log_err ("Core returned error %d:%s.\n", error, - gio_Err_to_str (error)); - cm_thd_running = FALSE; - return error; - } - - if( gulm_cm.GenerationID != 0 ) { - GULM_ASSERT(gulm_cm.GenerationID == gen, - printk("us: %"PRIu64" them: %"PRIu64"\n", - gulm_cm.GenerationID,gen); - ); - } - gulm_cm.GenerationID = gen; - - - log_msg (lgm_Network2, "Logged into local core.\n"); - - return 0; -} - -/** - * gulm_core_logout_reply - - * @misc: - * - * - * Returns: int - */ -int -gulm_core_logout_reply (void *misc) -{ - log_msg (lgm_Network2, "Logged out of local core.\n"); - return 0; -} - -/** - */ -int -gulm_core_nodechange (void *misc, char *nodename, - struct in6_addr *nodeip, uint8_t nodestate) -{ - if (nodestate == lg_core_Fenced) { - request_journal_replay (nodename); - } - /* if me and state is logout, Need to close out things if we can. - */ - if (gulm_cm.starts && nodestate == lg_core_Logged_out && - strcmp(gulm_cm.myName, nodename) == 0 ) { - glq_shutdown (); - cm_thd_running = FALSE; - lg_core_logout (gulm_cm.hookup); - return -1; - } - return 0; -} - -int gulm_core_statechange (void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr *masterip, char *mastername) -{ - int *cst = (int *)misc; - if( misc != NULL ) { - if( corestate != lg_core_Slave && - corestate != lg_core_Master ) { - *cst = TRUE; - }else{ - *cst = FALSE; - } - } - if( corestate == lg_core_Slave || - corestate == lg_core_Master ) { - /* we should be part of a live, quorate cluster now. */ - check_all_for_stales(); - } - return 0; -} - -/** - */ -int -gulm_core_error (void *misc, uint32_t err) -{ - log_err ("Got error code %d %#x back fome some reason!\n", err, err); - return 0; -} - -static lg_core_callbacks_t core_cb = { - login_reply:gulm_core_login_reply, - logout_reply:gulm_core_logout_reply, - nodechange:gulm_core_nodechange, - statechange:gulm_core_statechange, - error:gulm_core_error -}; - -/** - * cm_io_recving_thread - - * @data: - * - * - * Returns: int - */ -int -cm_io_recving_thread (void *data) -{ - int err; - - daemonize ("gulm_res_recvd"); - cm_thd_task = current; - complete (&cm_thd_startup); - - while (cm_thd_running) { - err = lg_core_handle_messages (gulm_cm.hookup, &core_cb, NULL); - if (err != 0) { - log_err - ("Got an error in gulm_res_recvd err: %d\n", err); - if (!cm_thd_running) - break; - /* - * Pause a bit, then try to log back into the local - * lock_gulmd. Keep doing this until an outside force - * stops us. (which I don't think there is any at this - * point. forceunmount would be one, if we ever do - * that.) - * - * If we are still in the gulm_mount() function, we - * should not retry. We should just exit. - * - * Is this really smart? There is zero garuntees - * that the state of things will be usable when we - * return. - * - */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (3 * HZ); - - while ((err = - lg_core_login (gulm_cm.hookup, TRUE)) != 0) { - log_err - ("Got a %d trying to login to lock_gulmd. Is it running?\n", - err); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (3 * HZ); - } - } - } /* while( gulm_cm.cm_thd_running ) */ - - complete (&cm_thd_startup); - return 0; -} - -/** - * cm_logout - - */ -void -cm_logout (void) -{ - - if (cm_thd_running) { - cm_thd_running = FALSE; - lg_core_logout (gulm_cm.hookup); - - /* wait for thread to finish */ - wait_for_completion (&cm_thd_startup); - } - -} - -/** - * cm_login - - * - * Returns: int - */ -int -cm_login (void) -{ - int err = -1; - int cst=TRUE; - - cm_thd_running = FALSE; - init_completion (&cm_thd_startup); - - err = lg_core_login (gulm_cm.hookup, TRUE); - if (err != 0) { - log_err - ("Got a %d trying to login to lock_gulmd. Is it running?\n", - err); - goto exit; - } - /* handle login reply. which will start the lt thread. */ - err = lg_core_handle_messages (gulm_cm.hookup, &core_cb, NULL); - if (err != 0) { - goto exit; - } - - /* do not pass go until Slave(client) or Master */ - while(cst) { - lg_core_corestate(gulm_cm.hookup); - err = lg_core_handle_messages (gulm_cm.hookup, &core_cb, &cst); - if (err != 0) { - goto exit; - } - if(cst) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (3 * HZ); - /* TODO if interrupted, exit */ - } - } - - /* start recver thread. */ - cm_thd_running = TRUE; - err = kernel_thread (cm_io_recving_thread, NULL, 0); - if (err < 0) { - log_err ("Failed to start gulm_res_recvd. (%d)\n", err); - goto exit; - } - wait_for_completion (&cm_thd_startup); - - err = 0; - exit: - if (err > 0) err = - err; - return err; -} -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_firstlock.c b/gfs-kernel/src/gulm/gulm_firstlock.c deleted file mode 100644 index da17b8f..0000000 --- a/gfs-kernel/src/gulm/gulm_firstlock.c +++ /dev/null @@ -1,310 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/file.h> -#include <linux/crc32.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "handler.h" -#include "gulm_lock_queue.h" - -extern gulm_cm_t gulm_cm; - -/****************************************************************************/ -struct gulm_flck_return_s { - int error; - struct completion sleep; -}; - -/** - * gulm_firstlock_finish - - * @item: - * - * - * Returns: void - */ -void gulm_firstlock_finish (struct glck_req *item) -{ - struct gulm_flck_return_s *g = (struct gulm_flck_return_s *)item->misc; - g->error = item->error; - complete (&g->sleep); -} - -/** - * gulm_cancel_firstlock - - * @misc: - * - */ -void gulm_cancel_firstlock (void *misc) -{ - gulm_fs_t *fs = (gulm_fs_t *)misc; - glckr_t *item; - - item = glq_get_new_req(); - if( item == NULL ) { - log_err ("Out of memory, Cannot cancel Firstlock request.\n"); - return; - } - - /* after cancel is processed, glq will call kfree on item->key. */ - item->key = kmalloc(GIO_KEY_SIZE, GFP_KERNEL); - if (item->key == NULL) { - glq_recycle_req(item); - log_err ("Out of memory, Cannot cancel Firstlock request.\n"); - return; - } - item->keylen = pack_lock_key(item->key, GIO_KEY_SIZE, 'F', - fs->fs_name, "irstMount", 9); - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_cancel; - item->finish = NULL; - - glq_cancel(item); -} - -/** - * do_lock_time_out - - * @d: - * - * after timeout, set cancel request on the handler queue. (since we cannot - * call it from within the timer code. (socket io within interrupt space is - * bad.)) - * - */ -static void -do_lock_time_out (unsigned long d) -{ - gulm_fs_t *fs = (gulm_fs_t *)d; - qu_function_call (&fs->cq, gulm_cancel_firstlock, fs); -} - -/** - * get_mount_lock - - * @fs: - * @first: - * - * Get the Firstmount lock. - * We try to grab it Exl. IF we get that, then we are the first client - * mounting this fs. Otherwise we grab it shared to show that there are - * clients using this fs. - * - * Returns: int - */ -int -get_mount_lock (gulm_fs_t * fs, int *first) -{ - int err, keylen; - struct timer_list locktimeout; - struct gulm_flck_return_s gret; - uint8_t key[GIO_KEY_SIZE]; - glckr_t *item; - - keylen = pack_lock_key(key, GIO_KEY_SIZE, 'F', fs->fs_name, "irstMount", 9); - if( keylen <= 0 ) return keylen; - - - try_it_again: - *first = FALSE; /* assume we're not first */ - - item = glq_get_new_req(); - if (item == NULL) { - err = -ENOMEM; - goto fail; - } - - /* glq does not try to free the key for state or action requests. */ - item->key = key; - item->keylen = keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Exclusive; - item->flags = lg_lock_flag_Try|lg_lock_flag_IgnoreExp|lg_lock_flag_NoCallBacks; - item->error = gret.error = 0; - - init_completion (&gret.sleep); - - item->misc = &gret; - item->finish = gulm_firstlock_finish; - - glq_queue (item); - wait_for_completion (&gret.sleep); - - if (gret.error == 0) { - /* we got the lock, we're the first mounter. */ - *first = TRUE; - log_msg (lgm_locking, "fsid=%s: Got mount lock Exclusive.\n", - fs->fs_name); - return 0; - } else { - log_msg (lgm_locking, - "fsid=%s: Didn't get mount lock Exl, someone else " - "was first, trying for shared.\n", fs->fs_name); - - /* the try failed, pick it up shared. - * If it takes too long, start over. - * */ - init_timer (&locktimeout); - locktimeout.function = do_lock_time_out; - locktimeout.data = (unsigned long)fs; - mod_timer (&locktimeout, jiffies + (120 * HZ)); - - item = glq_get_new_req(); - if (item == NULL) { - err = -ENOMEM; - goto fail; - } - - item->key = key; - item->keylen = keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Shared; - item->flags = lg_lock_flag_NoCallBacks; - item->error = gret.error = 0; - - init_completion (&gret.sleep); - - item->misc = &gret; - item->finish = gulm_firstlock_finish; - - glq_queue (item); - wait_for_completion (&gret.sleep); - - del_timer (&locktimeout); - - if (gret.error == 0) { - /* kewl we got it. */ - log_msg (lgm_locking, - "fsid=%s: Got mount lock shared.\n", - fs->fs_name); - return 0; - } - - log_msg (lgm_locking, - "fsid=%s: Shared req timed out, trying Exl again.\n", - fs->fs_name); - goto try_it_again; - } - fail: - log_err ("Exit get_mount_lock err=%d\n", err); - return err; -} - -/** - * downgrade_mount_lock - - * @fs: - * - * drop the Firstmount lock down to shared. This lets others mount. - * - * Returns: int - */ -int -downgrade_mount_lock (gulm_fs_t * fs) -{ - int keylen; - struct gulm_flck_return_s gret; - uint8_t key[GIO_KEY_SIZE]; - glckr_t *item; - - keylen = pack_lock_key(key, GIO_KEY_SIZE, 'F', - fs->fs_name, "irstMount", 9); - if( keylen <= 0 ) return keylen; - - item = glq_get_new_req(); - if (item == NULL) { - return -ENOMEM; - } - - item->key = key; - item->keylen = keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Shared; - item->flags = lg_lock_flag_NoCallBacks; - item->error = gret.error = 0; - - init_completion (&gret.sleep); - - item->misc = &gret; - item->finish = gulm_firstlock_finish; - - glq_queue (item); - wait_for_completion (&gret.sleep); - - if (gret.error != 0) - log_err ("fsid=%s: Couldn't unlock mount lock!!!!!! %d\n", - fs->fs_name, gret.error); - return 0; -} - -/** - * drop_mount_lock - drop our hold on the firstmount lock. - * @fs: <> the filesystem pointer. - * - * Returns: int - */ -int -drop_mount_lock (gulm_fs_t * fs) -{ - int keylen; - struct gulm_flck_return_s gret; - uint8_t key[GIO_KEY_SIZE]; - glckr_t *item; - - keylen = pack_lock_key(key, GIO_KEY_SIZE, 'F', fs->fs_name, "irstMount", 9); - if( keylen <= 0 ) return keylen; - - item = glq_get_new_req(); - if (item == NULL) { - return -ENOMEM; - } - - item->key = key; - item->keylen = keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Unlock; - item->flags = 0; - item->error = gret.error = 0; - - init_completion (&gret.sleep); - - item->misc = &gret; - item->finish = gulm_firstlock_finish; - - glq_queue (item); - wait_for_completion (&gret.sleep); - - if (gret.error != 0) - log_err ("fsid=%s: Couldn't unlock mount lock!!!!!! %d\n", - fs->fs_name, gret.error); - return 0; -} - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_fs.c b/gfs-kernel/src/gulm/gulm_fs.c deleted file mode 100644 index 707b3e4..0000000 --- a/gfs-kernel/src/gulm/gulm_fs.c +++ /dev/null @@ -1,782 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/utsname.h> /* for extern system_utsname */ - -#include "handler.h" -#include "gulm_lock_queue.h" - -/* things about myself */ -extern gulm_cm_t gulm_cm; - -/* globals for this file.*/ -uint32_t filesystems_count = 0; -LIST_HEAD (filesystems_list); -struct semaphore filesystem_lck; /* we use a sema instead of a spin - * here because all of the - * interruptible things we do - * inside of it. If i stop doing - * nasty things within this it - * doesn't need to be a sema. - */ -struct semaphore start_stop_lock; -atomic_t start_stop_cnt; - -/** - * init_gulm_fs - - */ -void -init_gulm_fs (void) -{ - init_MUTEX (&filesystem_lck); - init_MUTEX (&start_stop_lock); - atomic_set (&start_stop_cnt, 0); -} - -/*****************************************************************************/ -struct rjrpf_s { - gulm_fs_t *fs; - uint8_t *name; -}; - -void -request_journal_replay_per_fs (void *d) -{ - struct rjrpf_s *rf = (struct rjrpf_s *) d; - uint32_t jid; - unsigned int ujid; - - /* lookup jid <=> name mapping */ - if (find_jid_by_name_and_mark_replay (rf->fs, rf->name, &jid) != 0) { - log_msg (lgm_JIDMap, - "In fs (%s), no jid for name (%s) was found.\n", - rf->fs->fs_name, rf->name); - } else { - log_msg (lgm_JIDMap, - "In fs (%s), jid %d was found for name (%s).\n", - rf->fs->fs_name, jid, rf->name); - - /* all that the replay journal call back into gfs does is - * malloc some memory and add it to a list. So we really - * don't need to queue that action. Since that is what gfs - * is doing. - * - * This will need to change if gfs changes. - * - * Basically, we assume that the callback is non-blocking. - */ - ujid = jid; - rf->fs->cb (rf->fs->fsdata, LM_CB_NEED_RECOVERY, &ujid); - } - - kfree (rf->name); - kfree (rf); - -} - -/** - * request_journal_replay - give a journal replay request to mounted filesystems - * @name: < the name of the node that died. - * - * - * Returns: void - */ -void -request_journal_replay (uint8_t * name) -{ - struct list_head *tmp; - gulm_fs_t *fs; - struct rjrpf_s *rf; - - log_msg (lgm_Always, "Checking for journals for node "%s"\n", - name); - - down (&filesystem_lck); - - list_for_each (tmp, &filesystems_list) { - fs = list_entry (tmp, gulm_fs_t, fs_list); - - /* we don't want to process replay requests when we are - * still in the first mounter state. All the journals are - * getting replayed anyways, and there could be some issue - * with stuff happening twice. - */ - if (fs->firstmounting) - continue; - - /* due to the way the new jid mapping code works, we had to - * move it out of here. - * (making calls to the lock server. Things can deadlock - * if the jid mapping calls are made from this thread of - * execution.) - * - * I need to look over this. There HAS to be a better way - * to manage the way we figgure out which journals gfs - * needs to replay. - */ - - rf = kmalloc (sizeof (struct rjrpf_s), GFP_KERNEL); - GULM_ASSERT (rf != NULL,); - - rf->fs = fs; - rf->name = kmalloc (strlen (name) + 1, GFP_KERNEL); - GULM_ASSERT (rf->name != NULL,); - memcpy (rf->name, name, strlen (name) + 1); - - qu_function_call (&fs->cq, request_journal_replay_per_fs, rf); - - } - up (&filesystem_lck); -} - -/* can you say kludges kids?! I *knew* you could. */ -void -cast_check_for_stale_expires(void*d) -{ - check_for_stale_expires(d); -} -/** - * check_all_for_stales - - * - * scan every fs we've got for possible journals that need replaying. - * - */ -void -check_all_for_stales(void) -{ - struct list_head *tmp; - gulm_fs_t *fs; - down (&filesystem_lck); - - list_for_each (tmp, &filesystems_list) { - fs = list_entry (tmp, gulm_fs_t, fs_list); - if (!fs->firstmounting) { - qu_function_call (&fs->cq, cast_check_for_stale_expires, fs); - } - } - up (&filesystem_lck); -} - -/** - * passup_droplocks - - */ -void -passup_droplocks (void) -{ - struct list_head *tmp; - gulm_fs_t *fs; - down (&filesystem_lck); - list_for_each (tmp, &filesystems_list) { - fs = list_entry (tmp, gulm_fs_t, fs_list); - qu_drop_req (&fs->cq, fs->cb, fs->fsdata, LM_CB_DROPLOCKS, 0, - 0); - /* If this decides to block someday, we need to change this - * function. - */ - } - up (&filesystem_lck); -} - -#if 0 -/** - * dump_internal_lists - - * - */ -void -dump_internal_lists (void) -{ - struct list_head *tmp; - gulm_fs_t *fs; - down (&filesystem_lck); - list_for_each (tmp, &filesystems_list) { - fs = list_entry (tmp, gulm_fs_t, fs_list); - log_msg (lgm_Always, "Handler queue for %s\n", fs->fs_name); - display_handler_queue (&fs->cq); - /* other lists? */ - } - up (&filesystem_lck); -} -#endif - -/** - * get_fs_by_name - - * @name: - * - * - * Returns: gulm_fs_t - */ -gulm_fs_t * -get_fs_by_name (uint8_t * name) -{ - struct list_head *tmp; - gulm_fs_t *fs = NULL; - down (&filesystem_lck); - list_for_each (tmp, &filesystems_list) { - fs = list_entry (tmp, gulm_fs_t, fs_list); - if (strcmp (name, fs->fs_name) == 0) { - up (&filesystem_lck); - return fs; - } - } - up (&filesystem_lck); - return NULL; -} - -/*****************************************************************************/ - -/** - * start_gulm_threads - - * @host_data: - * - * - * Returns: int - */ -int -start_gulm_threads (char *csnm, char *hostdata) -{ - int error = 0; - - down (&start_stop_lock); - atomic_inc (&start_stop_cnt); - if (atomic_read (&start_stop_cnt) == 1) { - /* first one. get stuff going */ - strncpy (gulm_cm.clusterID, csnm, 255); - gulm_cm.clusterID[255] = '\0'; - - if (hostdata != NULL && strlen (hostdata) > 0) { - strncpy (gulm_cm.myName, hostdata, 64); - } else { - strncpy (gulm_cm.myName, system_utsname.nodename, 64); - } - gulm_cm.myName[63] = '\0'; - - - error = lg_initialize (&gulm_cm.hookup, gulm_cm.clusterID, - "GFS Kernel Interface"); - if (error != 0) { - log_err ("lg_initialize failed, %d\n", error); - goto fail; - } - gulm_cm.starts = TRUE; - - /* breaking away from ccs. just hardcoding defaults here. - * Noone really used these anyways and if ppl want them - * badly, we'll find another way to set them. (modprobe - * options for example. or maybe sysfs?) - * ppl want verbosity - * */ - gulm_cm.handler_threads = 2; - gulm_cm.verbosity = lgm_Network ; - - error = cm_login (); - if (error != 0) { - log_err ("cm_login failed. %d\n", error); - goto fail; - } - error = glq_startup (); - if (error != 0) { - log_err ("glq_startup failed. %d\n", error); - goto fail; - } - - } - fail: - up (&start_stop_lock); - return error; -} - -/** - * stop_gulm_threads - - */ -void -stop_gulm_threads (void) -{ - down (&start_stop_lock); - atomic_dec (&start_stop_cnt); - if (atomic_read (&start_stop_cnt) == 0) { - /* last one, put it all away. */ - glq_shutdown (); - cm_logout (); - lg_release (gulm_cm.hookup); - gulm_cm.hookup = NULL; - gulm_cm.GenerationID = 0; - } - up (&start_stop_lock); -} - -/*****************************************************************************/ -/** - * send_drop_exp - - * @fs: - * @name: - * - * - * Returns: int - */ -int send_drop_exp (gulm_fs_t * fs, char *name) -{ - glckr_t *item; - - item = glq_get_new_req(); - if( item == NULL ) { - log_err("drop_exp: failed to get needed memory. skipping.\n"); - return -ENOMEM; - } - - item->keylen = 3 + strlen(fs->fs_name); - item->key = kmalloc(item->keylen, GFP_KERNEL); - if (item->key == NULL) { - glq_recycle_req(item); - log_err("drop_exp: failed to get needed memory. skipping.\n"); - return -ENOMEM; - } - item->keylen = pack_drop_mask(item->key, item->keylen, fs->fs_name); - - /* lvb is name for drops. */ - if (name != NULL) { - item->lvblen = strlen(name) +1; - item->lvb = kmalloc(item->lvblen, GFP_KERNEL); - if (item->lvb == NULL) { - glq_recycle_req(item); /* frees key for us */ - log_err("drop_exp: failed to get needed memory. skipping.\n"); - return -ENOMEM; - } - memcpy(item->lvb, name, item->lvblen); - } else { - item->lvb = NULL; - item->lvblen = 0; - } - - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_drop; - item->state = 0; - item->flags = 0; - item->error = 0; - item->finish = NULL; - - glq_queue (item); - - return 0; -} -/** - * expire_my_locks - - * @fs: - * - * - * Returns: int - */ -int expire_my_locks (gulm_fs_t * fs) -{ - glckr_t *item; - - item = glq_get_new_req(); - if( item == NULL ) { - log_err("drop_exp: failed to get needed memory. skipping.\n"); - return -ENOMEM; - } - - item->keylen = 3 + strlen(fs->fs_name); - item->key = kmalloc(item->keylen, GFP_KERNEL); - if (item->key == NULL) { - glq_recycle_req(item); - log_err("drop_exp: failed to get needed memory. skipping.\n"); - return -ENOMEM; - } - item->keylen = pack_drop_mask(item->key, item->keylen, fs->fs_name); - - /* lvb is name for drops. */ - item->lvblen = strlen(gulm_cm.myName) +1; - item->lvb = kmalloc(item->lvblen, GFP_KERNEL); - if (item->lvb == NULL) { - glq_recycle_req(item); /* frees key for us */ - log_err("drop_exp: failed to get needed memory. skipping.\n"); - return -ENOMEM; - } - memcpy(item->lvb, gulm_cm.myName, item->lvblen); - - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_expire; - item->state = 0; - item->flags = 0; - item->error = 0; - item->finish = NULL; - - glq_queue (item); - - return 0; -} -/*****************************************************************************/ - -/** - * gulm_check_replays - - * @misc: - * - * - * Returns: void - */ -void gulm_check_replays(void *misc) -{ - gulm_fs_t *fs = (gulm_fs_t*)misc; - qu_function_call (&fs->cq, cast_check_for_stale_expires, fs); -} - -/** - * gulm_mount - * @table_name: clusterID:FS_Name - * @host_data: - * @cb: GFS callback function - * @fsdata: opaque GFS handle - * @lockstruct: the structure of crap to fill in - * - * Returns: 0 on success, -EXXX on failure - */ -int -gulm_mount (char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t * fsdata, - unsigned int min_lvb_size, struct lm_lockstruct *lockstruct) -{ - gulm_fs_t *gulm; - char *work=NULL, *tbln; - int first; - int error = -1; - struct list_head *lltmp; - - work = kmalloc(256, GFP_KERNEL); - if(work == NULL ) { - log_err("Out of Memory.\n"); - error = -ENOMEM; - goto fail; - } - strncpy (work, table_name, 256); - - tbln = strstr (work, ":"); - if (tbln == NULL) { - log_err - ("Malformed table name. Couldn't find separator ':' between " - "clusterID and lockspace name.\n"); - error = -1; - goto fail; - } - *tbln++ = '\0'; - - /* make sure that the cluster name exists. */ - if (strlen (work) <= 0) { - log_err ("Cluster name "%s" is too short.\n", work); - error = -EPROTO; - goto fail; - } - if (strlen (work) > 16) { - log_err ("Cluster name "%s" is too long.\n", work); - error = -EPROTO; - goto fail; - } - - /* the second one is an artifact of the way I use the name. - * A better fix to this will happen when I actually get dynamic key - * lengths working. - */ - if (strlen (tbln) > MIN (GIO_NAME_LEN, (GIO_KEY_SIZE - 15))) { - log_err - ("Warning! lockspace name (%s) is longer than %d chars!\n", - tbln, MIN (GIO_NAME_LEN, (GIO_KEY_SIZE - 15))); - error = -EPROTO; - goto fail; - } - if (strlen (tbln) <= 0) { - log_err ("Table name "%s" is too short.\n", tbln); - error = -EPROTO; - goto fail; - } - - /* Check to make sure this lock table isn't already being used */ - down (&filesystem_lck); - list_for_each (lltmp, &filesystems_list) { - gulm = list_entry (lltmp, gulm_fs_t, fs_list); - if (!strncmp (gulm->fs_name, tbln, GIO_NAME_LEN)) { - log_err (""%s" is already in use\n", tbln); - error = -EEXIST; - up (&filesystem_lck); - goto fail; - } - } - up (&filesystem_lck); - - /* Set up our main structure */ - - gulm = kmalloc (sizeof (gulm_fs_t), GFP_KERNEL); - if (!gulm) { - log_err ("out of memory\n"); - error = -ENOMEM; - goto fail; - } - memset (gulm, 0, sizeof (gulm_fs_t)); - - INIT_LIST_HEAD (&gulm->fs_list); - - strncpy (gulm->fs_name, tbln, GIO_NAME_LEN); - gulm->cb = cb; - gulm->fsdata = fsdata; - gulm->lvb_size = min_lvb_size; - - if ((error = start_gulm_threads (work, host_data)) != 0) { - log_err ("Got a %d trying to start the threads.\n", error); - goto fail_free_gulm; - } - - if ((error = - start_callback_qu (&gulm->cq, gulm_cm.handler_threads)) < 0) { - log_err ("fsid=%s: Failed to start the callback handler.\n", - gulm->fs_name); - goto fail_free_gulm; - } - - /* the mount lock HAS to be the first thing done in the LTs for this fs. */ - error = get_mount_lock (gulm, &first); - if (error != 0) { - log_err("fsid=%s: Error %d while trying to get the mount lock\n", - gulm->fs_name, error); - goto fail_callback; - } - - error = watch_sig(gulm, gulm->fs_name, strlen(gulm->fs_name)+1, gulm_check_replays, gulm); - if( error != 0 ) { - log_err("fsid=%s: couldn't watch CFR because %d\n", - gulm->fs_name, error); - goto fail_mountlock; - } - - jid_fs_init (gulm); - get_journalID (gulm); - - /* things act a bit different until the first mounter is finished. - */ - if (first) - gulm->firstmounting = TRUE; - - /* Success */ - down (&filesystem_lck); - list_add (&gulm->fs_list, &filesystems_list); - filesystems_count++; - up (&filesystem_lck); - - log_msg (lgm_JIDMap, "fsid=%s: We will be using jid %d\n", - gulm->fs_name, gulm->fsJID); - - lockstruct->ls_jid = gulm->fsJID; - lockstruct->ls_first = first; - lockstruct->ls_lvb_size = gulm->lvb_size; - lockstruct->ls_lockspace = gulm; - lockstruct->ls_ops = &gulm_ops; - lockstruct->ls_flags = 0; - log_msg (lgm_Network2, "Done: %s, async mode\n", table_name); - - gulm_cm.starts = FALSE; - if(work != NULL ) kfree(work); - return 0; - -fail_mountlock: - drop_mount_lock (gulm); - - fail_callback: - stop_callback_qu (&gulm->cq); - - fail_free_gulm: - stop_gulm_threads (); - kfree (gulm); - - fail: - - if(work != NULL ) kfree(work); - gulm_cm.starts = FALSE; - log_msg (lgm_Always, "fsid=%s: Exiting gulm_mount with errors %d\n", - table_name, error); - /* VFS does weird things with the error results, so before we try - * to return a gulm error code, flip it to -1. - */ - if (error > 999 || error < -999 ) error = -1; - return error; -} - -/** - * gulm_others_may_mount - * @lockspace: handle to specific lock space - * - * GFS calls this function if it was the first mounter after it's done - * checking all the journals. - * - */ -void -gulm_others_may_mount (lm_lockspace_t * lockspace) -{ - gulm_fs_t *fs = (gulm_fs_t *) lockspace; - int err = 0; - - /* first send the drop all exp message. - * */ - err = send_drop_exp (fs, NULL); - if (err < 0) - log_err - ("fsid=%s: Problems sending DropExp request to LTPX: %d\n", - fs->fs_name, err); - - /* then move the FirstMountLock to shared so others can mount. */ - err = downgrade_mount_lock (fs); - - if (err < 0) { - log_err ("fsid=%s: error sending Fs_FinMount_Req.(%d)\n", - fs->fs_name, err); - } - - /* first mounter is all done. let the gulm_recovery_done function - * behave as normal now. - */ - fs->firstmounting = FALSE; -} - -/** - * gulm_umount - * @lockspace: handle to specific lock space - * - */ -void -gulm_unmount (lm_lockspace_t * lockspace) -{ - gulm_fs_t *gulm_fs = (gulm_fs_t *) lockspace; - - down (&filesystem_lck); - list_del (&gulm_fs->fs_list); - --filesystems_count; - up (&filesystem_lck); - - /* close and release stuff */ - watch_sig(gulm_fs, gulm_fs->fs_name, strlen(gulm_fs->fs_name)+1, NULL, NULL); - drop_mount_lock (gulm_fs); - put_journalID (gulm_fs, FALSE); - jid_fs_release (gulm_fs); - - stop_callback_qu (&gulm_fs->cq); - - kfree (gulm_fs); - - stop_gulm_threads (); - -} - -/** - * gulm_withdraw - * @lockspace: handle to specific lock space - * - */ -void -gulm_withdraw(lm_lockspace_t * lockspace) -{ - gulm_fs_t *gulm_fs = (gulm_fs_t *) lockspace; - down (&filesystem_lck); - list_del (&gulm_fs->fs_list); - --filesystems_count; - up (&filesystem_lck); - - /* close and release stuff */ - drop_mount_lock (gulm_fs); - /* leave this around for others to clean up. - * marking myself as being replayed right away so in bad cases, - * atleast check_for_stale will find us. - * */ - put_journalID (gulm_fs, TRUE); - jid_fs_release (gulm_fs); - - stop_callback_qu (&gulm_fs->cq); - - expire_my_locks (gulm_fs); - tap_sig(gulm_fs, gulm_fs->fs_name, strlen(gulm_fs->fs_name)+1); - - /* need to let things run through the queues. - * Only really an issue if you happen to be the only gfs/gulm fs - * mounted. - * */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout( 2 * HZ); - - kfree (gulm_fs); - - stop_gulm_threads (); -} - -/** - * gulm_recovery_done - - * @lockspace: - * @jid: - * - * Returns: void - */ -void -gulm_recovery_done (lm_lockspace_t * lockspace, unsigned int jid, - unsigned int message) -{ - gulm_fs_t *fs = (gulm_fs_t *) lockspace; - int err; - uint8_t *name=NULL; - - if (message != LM_RD_SUCCESS) { - /* Need to start thinking about how I want to use this... */ - goto exit; - } - - name = kmalloc(64, GFP_KERNEL); - if(name == NULL) { - log_err("out of memory.\n"); - goto exit; - } - - if (jid == fs->fsJID) { /* this may be drifting crud through. */ - /* hey! its me! */ - strncpy (name, gulm_cm.myName, 64); - } else if (lookup_name_by_jid (fs, jid, name) != 0) { - log_msg (lgm_JIDMap, - "fsid=%s: Could not find a client for jid %d\n", - fs->fs_name, jid); - goto exit; - } - if (strlen (name) == 0) { - log_msg (lgm_JIDMap, "fsid=%s: No one mapped to jid %d\n", - fs->fs_name, jid); - goto exit; - } - log_msg (lgm_JIDMap, "fsid=%s: Found %s for jid %d\n", - fs->fs_name, name, jid); - - err = send_drop_exp (fs, name); - - if (jid != fs->fsJID) { - /* rather dumb to do this to ourselves right after we mount... */ - log_msg (lgm_JIDMap, - "fsid=%s: Clearing JID %d for use by others\n", - fs->fs_name, jid); - release_JID (fs, jid); - } - - /* If someone died while replaying someoneelse's journal, there will be - * stale expired jids. - */ - check_for_stale_expires (fs); - -exit: - if(name!=NULL) kfree(name); -} -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_jid.c b/gfs-kernel/src/gulm/gulm_jid.c deleted file mode 100644 index 1bc690b..0000000 --- a/gfs-kernel/src/gulm/gulm_jid.c +++ /dev/null @@ -1,643 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/file.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "gulm_lock_queue.h" - -extern gulm_cm_t gulm_cm; - -/****************************************************************************/ - -/* jid locks: - * - * Header lock: "JHeader" + \0\0\0 + fsname - * lvb: <uint32> :number of JIDs - * Mappinglock: "JM" + <uint32> + \0\0\0\0 + fsname - * lvb: [012] + <node name> - * 0: unused - * 1: replaying journal - * 2: Mounted - * list lock : "JL" + "listlock" + fsname - * Node Locks : "JN" + <nodename[8]> + fsname - * - */ -#define jid_header_lvb_size (8) - -/** - * jid_get_header_name - - * @fs: < - * @key: <> - * @keylen: <> - * - * key is buffer to write to, keylen is size of buffer on input, and real - * length on output. - * - * Returns: int - */ -int -jid_get_header_name (uint8_t * fsname, uint8_t * key, uint16_t * keylen) -{ - int len; - - len = pack_lock_key(key, *keylen, 'J', fsname, "Header", 6); - if( len <=0 ) return len; - - *keylen = len; - - return 0; -} - -/** - * jid_get_lock_name - - * @fs: < - * @jid: < - * @key: <> - * @keylen: <> - * - * key is buffer to write to, keylen is size of buffer on input, and real - * length on output. - * - * Returns: int - */ -int -jid_get_lock_name (uint8_t * fsname, uint32_t jid, uint8_t * key, - uint16_t * keylen) -{ - int len; - uint8_t temp[9]; - - temp[0] = 'M'; - temp[1] = (jid >> 0) & 0xff; - temp[2] = (jid >> 8) & 0xff; - temp[3] = (jid >> 16) & 0xff; - temp[4] = (jid >> 24) & 0xff; - temp[5] = 0; - temp[6] = 0; - temp[7] = 0; - temp[8] = 0; - - len = pack_lock_key(key, *keylen, 'J', fsname, temp, 9); - if( len <=0 ) return len; - - *keylen = len; - - return 0; -} - -/** - * gulm_jid_finish - - * @item: - * - * - * Returns: void - */ -void gulm_jid_finish (struct glck_req *item) -{ - struct completion *sleep = (struct completion *)item->misc; - complete (sleep); -} - -/** - * jid_lvb_action - - * @key: - * @keylen: - * @lvb: - * @lvblen: - * @action: - * - * - * Returns: void - */ -void jid_lvb_action (uint8_t * key, uint16_t keylen, uint8_t * lvb, - uint16_t lvblen, uint8_t action) -{ - struct completion sleep; - glckr_t *item; - - item = glq_get_new_req(); - if (item == NULL) { - return; - } - - item->key = key; - item->keylen = keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_action; - item->state = action; - item->flags = 0; - item->error = 0; - item->lvb = lvb; - item->lvblen = lvblen; - - init_completion (&sleep); - - item->misc = &sleep; - item->finish = gulm_jid_finish; - - glq_queue (item); - wait_for_completion (&sleep); -} -void -jid_sync_lvb (uint8_t * key, uint16_t keylen, uint8_t * lvb, uint16_t lvblen) -{ - jid_lvb_action (key, keylen, lvb, lvblen, lg_lock_act_SyncLVB); -} -void -jid_unhold_lvb (uint8_t * key, uint16_t keylen) -{ - jid_lvb_action (key, keylen, NULL, 0, lg_lock_act_UnHoldLVB); -} -void -jid_hold_lvb (uint8_t * key, uint16_t keylen) -{ - jid_lvb_action (key, keylen, NULL, 0, lg_lock_act_HoldLVB); -} - - -/** - * jid_get_lock_state_inr - - * @key: - * @keylen: - * @state: - * @flags: - * @lvb: - * @lvblen: - * - * - */ -void -jid_get_lock_state_inr (uint8_t * key, uint16_t keylen, uint8_t state, - uint32_t flags, uint8_t * lvb, uint16_t lvblen) -{ - struct completion sleep; - glckr_t *item; - GULM_ASSERT (keylen > 6, - printk("keylen: %d\n", keylen);); - - init_completion (&sleep); - - item = glq_get_new_req(); - if (item == NULL) { - return; - } - - item->key = key; - item->keylen = keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = state; - item->flags = flags; - item->error = 0; - item->lvb = lvb; - item->lvblen = lvblen; - - item->misc = &sleep; - item->finish = gulm_jid_finish; - - glq_queue (item); - - wait_for_completion (&sleep); -} - -/** - * jid_get_lock_state_lvb - - * @key: - * @keylen: - * @state: - * @lvb: - * @lvblen: - * - * - */ -void -jid_get_lock_state_lvb (uint8_t * key, uint16_t keylen, uint8_t state, - uint8_t * lvb, uint16_t lvblen) -{ - jid_get_lock_state_inr (key, keylen, state, 0, lvb, lvblen); -} -/** - * jid_get_lock_state - - * @key: - * @keylen: - * @state: - * - * - */ -void -jid_get_lock_state (uint8_t * key, uint16_t keylen, uint8_t state) -{ - jid_get_lock_state_inr (key, keylen, state, 0, NULL, 0); -} - -/****************************************************************************/ - -/** - * jid_rehold_lvbs - - * @fs: - * - * - */ -void -jid_rehold_lvbs (gulm_fs_t * fs) -{ - int i; - uint32_t oldjcnt; - uint8_t key[GIO_KEY_SIZE], lvb[jid_header_lvb_size]; - uint16_t keylen = GIO_KEY_SIZE; - - oldjcnt = fs->JIDcount; - - jid_get_header_name (fs->fs_name, key, &keylen); - jid_get_lock_state_lvb (key, keylen, lg_lock_state_Shared, lvb, - jid_header_lvb_size); - fs->JIDcount = (uint32_t) (lvb[0]) << 0; - fs->JIDcount |= (uint32_t) (lvb[1]) << 8; - fs->JIDcount |= (uint32_t) (lvb[2]) << 16; - fs->JIDcount |= (uint32_t) (lvb[3]) << 24; - - if( fs->JIDcount > oldjcnt ) { - for (i = oldjcnt; i < fs->JIDcount; i++) { - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, i, key, &keylen); - jid_hold_lvb (key, keylen); - } - } - -} - -void -jid_grow_space (gulm_fs_t * fs) -{ - uint8_t key[GIO_KEY_SIZE], lvb[jid_header_lvb_size]; - uint16_t keylen = GIO_KEY_SIZE; - uint32_t jidc; - - keylen = sizeof (key); - jid_get_header_name (fs->fs_name, key, &keylen); - jid_get_lock_state_lvb (key, keylen, lg_lock_state_Exclusive, lvb, - jid_header_lvb_size); - jidc = (uint32_t) (lvb[0]) << 0; - jidc |= (uint32_t) (lvb[1]) << 8; - jidc |= (uint32_t) (lvb[2]) << 16; - jidc |= (uint32_t) (lvb[3]) << 24; - jidc += 1; - lvb[3] = (jidc >> 24) & 0xff; - lvb[2] = (jidc >> 16) & 0xff; - lvb[1] = (jidc >> 8) & 0xff; - lvb[0] = (jidc >> 0) & 0xff; - jid_sync_lvb (key, keylen, lvb, jid_header_lvb_size); - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - /* do an unlock here, so that when rehold grabs it shared, there is no - * lvb writing. yeah, bit icky. fix some other day. - */ - - jid_rehold_lvbs (fs); -} - -/** - * lookup_name_by_jid - - * @fs: - * @jid: - * @name: - * - * - * Returns: int - */ -int -lookup_name_by_jid (gulm_fs_t * fs, uint32_t jid, uint8_t * name) -{ - uint8_t key[GIO_KEY_SIZE], lvb[64]; - uint16_t keylen = GIO_KEY_SIZE; - int err = 0; - - if (jid >= fs->JIDcount) { - err = -1; - goto exit; - } - - jid_get_lock_name (fs->fs_name, jid, key, &keylen); - jid_get_lock_state_inr (key, keylen, lg_lock_state_Exclusive, - lg_lock_flag_IgnoreExp, lvb, 64); - - if (lvb[0] != 0) { - memcpy (name, &lvb[1], strlen (&lvb[1]) + 1); - } else { - err = -1; - } - - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - - exit: - return err; -} - -/** - * Release_JID - - * @fs: - * @jid: - * - * This is called when a node replays someone else's journal. - * - */ -void -release_JID (gulm_fs_t * fs, uint32_t jid) -{ - uint8_t key[GIO_KEY_SIZE], lvb[64]; - uint16_t keylen = GIO_KEY_SIZE; - - /* there is no such, so this becomes a nop. */ - if (jid >= fs->JIDcount) - return; - - jid_get_lock_name (fs->fs_name, jid, key, &keylen); - jid_get_lock_state_inr (key, keylen, lg_lock_state_Exclusive, - lg_lock_flag_IgnoreExp, lvb, 64); - if (lvb[0] == 1 ) { - /* if byte0 is 2, then that node is alive. They're waiting - * for us to finish, but once we're done, it would be mean - * to mark their jid as free. So we leave the byte alone. - * - * Actually, If the byte isn't 1 (which means we are - * replaying the journal) don't change it. - * - * Remind: 0 = free, 1 = replaying, 2 = owned. - */ - lvb[0] = 0; - jid_sync_lvb (key, keylen, lvb, strlen (&lvb[1]) + 2); - } - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - -} - -/** - * put_journalID - - * @fs: - * - * This is called when this node unmounts or withdraws. - * - */ -void -put_journalID (gulm_fs_t * fs, int leavebehind) -{ - uint8_t key[GIO_KEY_SIZE], lvb[64]; - uint16_t keylen = GIO_KEY_SIZE; - - /* there is no such, so this becomes a nop. */ - if (fs->fsJID >= fs->JIDcount) - return; - - jid_get_lock_name (fs->fs_name, fs->fsJID, key, &keylen); - jid_get_lock_state_inr (key, keylen, lg_lock_state_Exclusive, - lg_lock_flag_IgnoreExp, lvb, 64); - if(leavebehind) - lvb[0] = 1; - else - lvb[0] = 0; - jid_sync_lvb (key, keylen, lvb, strlen (&lvb[1]) + 2); - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); -} - -/** - * get_journalID - - * @fs: - * @jid: - * - * grab EXL on names until we find one we want. (or have all.) - * grab that one. - * Unlock everything we got. - * - * Returns: int - */ -void -get_journalID (gulm_fs_t * fs) -{ - uint8_t key[GIO_KEY_SIZE], lvb[64]; - uint16_t keylen = GIO_KEY_SIZE; - int i, first_clear = -1, lockedto; - -retry: - /* find an empty space, or ourselves again */ - for (i = 0, lockedto = 0; i < fs->JIDcount; i++, lockedto++) { - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, i, key, &keylen); - jid_get_lock_state_inr (key, keylen, lg_lock_state_Exclusive, - lg_lock_flag_IgnoreExp, lvb, 64); - if (first_clear == -1 && lvb[0] == 0 ) { - first_clear = i; - } else if (strcmp (gulm_cm.myName, &lvb[1]) == 0) { - first_clear = i; - break; - } - } - if (first_clear >= 0) { - /* we should be hold all jid mapping locks up to this one - * (and maybe beyond) EXL, so just lvb sync to the one we - * want. - */ - lvb[0] = 2; - memcpy (&lvb[1], gulm_cm.myName, strlen (gulm_cm.myName) + 1); - - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, first_clear, key, &keylen); - jid_sync_lvb (key, keylen, lvb, strlen (gulm_cm.myName) + 2); - - fs->fsJID = first_clear; - } - - /* unlock them so others can find */ - for (; lockedto >= 0; lockedto--) { - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, lockedto, key, &keylen); - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - } - - if (first_clear < 0) { - jid_grow_space (fs); - goto retry; - } -} - -/** - * find_jid_by_name_and_mark_replay - - * @fs: - * @name: - * @jid: - * - * - * Returns: int - */ -int -find_jid_by_name_and_mark_replay (gulm_fs_t * fs, uint8_t * name, - uint32_t * jid) -{ - uint32_t i, found = -1; - uint8_t key[GIO_KEY_SIZE], lvb[64]; - uint16_t keylen = GIO_KEY_SIZE; - - for (i = 0; i < fs->JIDcount; i++) { - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, i, key, &keylen); - jid_get_lock_state_inr (key, keylen, lg_lock_state_Exclusive, - lg_lock_flag_IgnoreExp, lvb, 64); - if (strcmp (name, &lvb[1]) == 0) { - *jid = i; - found = 0; - lvb[0] = 1; - jid_sync_lvb (key, keylen, lvb, strlen (&lvb[1]) + 2); - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - break; - } - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - - } - - return found; -} - -/** - * Check_for_replays - - * @fs: - * - * - * Returns: int - */ -void -check_for_stale_expires (gulm_fs_t * fs) -{ - uint32_t i; - uint8_t key[GIO_KEY_SIZE], lvb[64]; - uint16_t keylen = GIO_KEY_SIZE; - unsigned int ujid; - - for (i = 0; i < fs->JIDcount; i++) { - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, i, key, &keylen); - jid_get_lock_state_inr (key, keylen, lg_lock_state_Exclusive, - lg_lock_flag_IgnoreExp, lvb, 64); - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - - if (lvb[0] == 1) { - log_msg (lgm_JIDMap, - "fsid=%s: stale JID %d found\n", - fs->fs_name, i); - ujid = i; - fs->cb (fs->fsdata, LM_CB_NEED_RECOVERY, &ujid); - } - } -} - - -/** - * jid_fs_init - - * @fs: - * - */ -void -jid_fs_init (gulm_fs_t * fs) -{ - uint8_t key[GIO_KEY_SIZE]; - uint16_t keylen = GIO_KEY_SIZE; - - fs->JIDcount = 0; - - init_MUTEX (&fs->headerlock); - - jid_get_header_name (fs->fs_name, key, &keylen); - jid_hold_lvb (key, keylen); - jid_rehold_lvbs (fs); -} - -/** - * jid_fs_release - - * @fs: - * - */ -void -jid_fs_release (gulm_fs_t * fs) -{ - uint32_t i; - uint8_t key[GIO_KEY_SIZE]; - uint16_t keylen = GIO_KEY_SIZE; - for (i = 0; i < fs->JIDcount; i++) { - keylen = sizeof (key); - jid_get_lock_name (fs->fs_name, i, key, &keylen); - jid_unhold_lvb (key, keylen); - } - keylen = GIO_KEY_SIZE; - jid_get_header_name (fs->fs_name, key, &keylen); - jid_unhold_lvb (key, keylen); - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); -} - -/** - * jid_unlock_callback - - * @d: - * - * *MUST* be called from a Handler thread. - * - * Returns: int - */ -void -jid_unlock_callback (void *d) -{ - uint8_t key[GIO_KEY_SIZE]; - uint16_t keylen = GIO_KEY_SIZE; - - gulm_fs_t *fs = (gulm_fs_t *) d; - jid_get_header_name (fs->fs_name, key, &keylen); - - jid_get_lock_state (key, keylen, lg_lock_state_Unlock); - - jid_rehold_lvbs (fs); -} - -/** - * jid_header_lock_drop - - * @key: - * @keylen: - * - * Returns: void - */ -void -jid_header_lock_drop (uint8_t * key, uint16_t keylen) -{ - gulm_fs_t *fs; - uint8_t *fsname; - uint8_t len; - uint8_t ktype, jtype; - ktype = key[0]; - len = key[1]; - fsname = &key[2]; - jtype = key[4 + len]; - - /* make sure this is the header lock.... */ - if (ktype == 'J' && jtype == 'H' && - (fs = get_fs_by_name (fsname)) != NULL) { - qu_function_call (&fs->cq, jid_unlock_callback, fs); - } -} - - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_lock_queue.c b/gfs-kernel/src/gulm/gulm_lock_queue.c deleted file mode 100644 index 34e8f84..0000000 --- a/gfs-kernel/src/gulm/gulm_lock_queue.c +++ /dev/null @@ -1,841 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/file.h> -#include <linux/smp_lock.h> -#include <linux/crc32.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "handler.h" - -#include "gulm_lock_queue.h" - -/* The Queues. */ -struct list_head glq_Free; -spinlock_t glq_FreeLock; -unsigned int glq_FreeCount; -struct list_head glq_OutQueue; -spinlock_t glq_OutLock; -unsigned int glq_OutCount; -#define ReplyMapBits (13) -#define ReplyMapSize (1 << ReplyMapBits) -#define ReplyMapMask (ReplyMapSize - 1) -gulm_hb_t *glq_ReplyMap; - -/* The Threads. */ -struct task_struct *glq_recver_task = NULL; -struct task_struct *glq_sender_task = NULL; -struct completion glq_startedup; -int glq_running; -wait_queue_head_t glq_send_wchan; - -/* */ -extern gulm_cm_t gulm_cm; - -/* The code. */ -/** - * glq_init - - * - * Returns: int - */ -int glq_init(void) -{ - int i; - - glq_running = FALSE; - glq_recver_task = NULL; - glq_sender_task = NULL; - init_waitqueue_head (&glq_send_wchan); - init_completion (&glq_startedup); - - INIT_LIST_HEAD (&glq_Free); - spin_lock_init (&glq_FreeLock); - glq_FreeCount = 0; - INIT_LIST_HEAD (&glq_OutQueue); - spin_lock_init (&glq_OutLock); - glq_OutCount = 0; - - glq_ReplyMap = vmalloc(sizeof(gulm_hb_t) * ReplyMapSize); - if( glq_ReplyMap == NULL ) { - return -ENOMEM; - } - for(i=0; i < ReplyMapSize; i++) { - INIT_LIST_HEAD (&glq_ReplyMap[i].bucket); - spin_lock_init (&glq_ReplyMap[i].lock); - } - /* ?Add some empty reqs to the Free list right now? */ - return 0; -} - -/** - * glq_release - - * - * doesn't grab spins, because by the time this is called, there should be - * no other threads anywhere that could possibly be working on these lists. - * - * Returns: void - */ -void glq_release(void) -{ - struct list_head *tmp, *lltmp; - glckr_t *item; - int i; - - list_for_each_safe (tmp, lltmp, &glq_OutQueue) { - item = list_entry (tmp, glckr_t, list); - list_del (tmp); - if (item->key != NULL) kfree (item->key); - if (item->lvb != NULL) kfree (item->lvb); - kfree (item); - } - glq_FreeCount = 0; - list_for_each_safe (tmp, lltmp, &glq_Free) { - item = list_entry (tmp, glckr_t, list); - list_del (tmp); - if (item->key != NULL) kfree (item->key); - if (item->lvb != NULL) kfree (item->lvb); - kfree (item); - } - glq_OutCount = 0; - for(i=0; i < ReplyMapSize; i++) { - list_for_each_safe (tmp, lltmp, &glq_ReplyMap[i].bucket) { - item = list_entry (tmp, glckr_t, list); - list_del (tmp); - if (item->key != NULL) kfree (item->key); - if (item->lvb != NULL) kfree (item->lvb); - kfree (item); - } - } - - vfree(glq_ReplyMap); -} - -/** - * glq_get_new_req - - * - * WARNING! For state and action requests, glq will not free the key or - * lvb pointers. For drop and cancel glq WILL free the pointer when it is - * finished. - * - * Returns: glckr_t - */ -glckr_t *glq_get_new_req(void) -{ - struct list_head *tmp; - glckr_t *item = NULL; - - /* try to reclaim a recycled req first. */ - spin_lock (&glq_FreeLock); - if (!list_empty (&glq_Free)) { - tmp = glq_Free.next; - list_del (tmp); - item = list_entry (tmp, glckr_t, list); - glq_FreeCount --; - } - spin_unlock (&glq_FreeLock); - - /* nothing on Free list, make new. */ - if (item == NULL) { - item = kmalloc(sizeof(glckr_t), GFP_KERNEL); - if (item == NULL) - return NULL; - memset(item, 0, sizeof(glckr_t)); - } - - /* initialize. - * reset list so its good. - */ - INIT_LIST_HEAD (&item->list); - - return item; -} - -/** - * glq_recycle_req - - * @lckr_t: - * - * assumes that item is not on any lists. - * - * Returns: void - */ -void glq_recycle_req(glckr_t *item) -{ - /* clean it up */ - INIT_LIST_HEAD (&item->list); - - if (item->type == glq_req_type_drop || - item->type == glq_req_type_cancel || - item->type == glq_req_type_expire) { - if (item->key != NULL) { - kfree(item->key); - item->key = NULL; - } - if (item->lvb != NULL) { - kfree(item->lvb); - item->lvb = NULL; - } - } else { - item->key = NULL; - item->lvb = NULL; - } - item->misc = NULL; - item->finish = NULL; - - /* everything else is ignoreable. */ - - /* onto the Free list. unless too many. */ - spin_lock (&glq_FreeLock); - if (glq_FreeCount > 20) { /* XXX icky hidden constant */ - kfree (item); - }else{ - list_add (&item->list, &glq_Free); - glq_FreeCount ++; - } - spin_unlock (&glq_FreeLock); -} - -/** - * glq_duplicate - - * @old: - * - * Creates a new glckr that is a copy of the old. *EVERYTHING* is copied. - * - * Returns: glckr_t - */ -glckr_t *glq_duplicate(glckr_t *old) -{ - glckr_t *new; - new = glq_get_new_req(); - if(new == NULL) return NULL; - - /* these fields just copy over */ - new->subid = old->subid; - new->start = old->start; - new->stop = old->stop; - new->type = old->type; - new->state = old->state; - new->flags = old->flags; - new->error = old->error; - new->misc = old->misc; - new->finish = old->finish; - - /* key and lvb field are handled differently based on the type - * field. - */ - new->keylen = old->keylen; - new->lvblen = old->lvblen; - if(new->type == glq_req_type_drop || - new->type == glq_req_type_cancel || - new->type == glq_req_type_expire) { - /* Need to malloc new and memcpy */ - if(old->key == NULL) { - new->key = NULL; - }else{ - new->key = kmalloc(new->keylen, GFP_KERNEL); - if(new->key == NULL) { - glq_recycle_req(new); - return NULL; - } - memcpy(new->key, old->key, new->keylen); - } - if(old->lvb == NULL) { - new->lvb = NULL; - }else{ - new->lvb = kmalloc(new->lvblen, GFP_KERNEL); - if(new->lvb == NULL) { - glq_recycle_req(new); - return NULL; - } - memcpy(new->lvb, old->lvb, new->lvblen); - } - }else{ - /* just copy pointer */ - new->key = old->key; - new->lvb = old->lvb; - } - - return new; -} - -/** - * glq_calc_hash_key_long - - * @key: - * @keylen: - * @subid: - * @start: - * @stop: - * - * - * Returns: int - */ -int glq_calc_hash_key_long(uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop) -{ - int ret = GULM_CRC_INIT; - ret = crc32 (ret, &keylen, sizeof(uint16_t)); - ret = crc32 (ret, key, keylen); - ret = crc32 (ret, &subid, sizeof(uint64_t)); - ret = crc32 (ret, &start, sizeof(uint64_t)); - ret = crc32 (ret, &stop, sizeof(uint64_t)); - ret &= ReplyMapMask; - return ret; -} - -/** - * glq_calc_hash_key - - * @item: - * - * - * Returns: int - */ -int glq_calc_hash_key(glckr_t *item) -{ - return glq_calc_hash_key_long (item->key, item->keylen, item->subid, - item->start, item->stop); -} - -/** - * glq_queue - - * @item: - * - * - * Returns: void - */ -void glq_queue(glckr_t *item) -{ - spin_lock (&glq_OutLock); - list_add (&item->list, &glq_OutQueue); - glq_OutCount++; - spin_unlock (&glq_OutLock); - wake_up (&glq_send_wchan); -} - -/** - * glq_cancel - - * @item: - * - * You MUST call glq_get_new_req() and fill that with the info of the - * request you want to cancel. - * - * Returns: void - */ -void glq_cancel(glckr_t *cancel) -{ - int found = FALSE; - struct list_head *tmp, *lltmp; - glckr_t *item = NULL; - - spin_lock (&glq_OutLock); - list_for_each_safe (tmp, lltmp, &glq_OutQueue) { - item = list_entry (tmp, glckr_t, list); - if (item->subid == cancel->subid && - item->start == cancel->start && - item->stop == cancel->stop && - item->keylen == cancel->keylen && - memcmp(item->key, cancel->key, cancel->keylen) ) { - /* found it. */ - list_del (tmp); - found = TRUE; - break; - } - } - spin_unlock(&glq_OutLock); - - if (!found) { - /* send cancel request to server. */ - cancel->type = glq_req_type_cancel; - glq_queue (cancel); - }else{ - /* finish it here */ - item->error = lg_err_Canceled; - if (item->finish != NULL ) - item->finish (item); - glq_recycle_req (item); - glq_recycle_req (cancel); - } -} - -/** - * glq_send_queue_empty - - * - * Returns: int - */ -static int glq_send_queue_empty(void) -{ - int ret; - spin_lock (&glq_OutLock); - ret = list_empty (&glq_OutQueue); - spin_unlock (&glq_OutLock); - return ret; -} - -/** - * glq_sender_thread - - * @data: - * - * - * Returns: int - */ -int glq_sender_thread(void *data) -{ - int err=0, bucket; - struct list_head *tmp; - glckr_t *item = NULL; - DECLARE_WAITQUEUE (__wait_chan, current); - - daemonize ("gulm_glq_sender"); - glq_sender_task = current; - complete (&glq_startedup); - - while (glq_running) { - /* wait for item */ - current->state = TASK_INTERRUPTIBLE; - add_wait_queue (&glq_send_wchan, &__wait_chan); - if( glq_send_queue_empty () ) - schedule (); - remove_wait_queue (&glq_send_wchan, &__wait_chan); - current->state = TASK_RUNNING; - if (!glq_running) break; - - /* pull item off queue */ - spin_lock (&glq_OutLock); - if (list_empty (&glq_OutQueue) ) { - spin_unlock (&glq_OutLock); - continue; - } - tmp = glq_OutQueue.prev; - list_del (tmp); - glq_OutCount--; - spin_unlock (&glq_OutLock); - item = list_entry (tmp, glckr_t, list); - - /* send to local ltpx or die */ - if (item->type == glq_req_type_state ) { - INIT_LIST_HEAD (&item->list); - bucket = glq_calc_hash_key(item); - spin_lock (&glq_ReplyMap[bucket].lock); - list_add (&item->list, &glq_ReplyMap[bucket].bucket); - spin_unlock (&glq_ReplyMap[bucket].lock); - err = lg_lock_state_req (gulm_cm.hookup, item->key, - item->keylen, item->subid, item->start, - item->stop, item->state, item->flags, - item->lvb, item->lvblen); - } else if (item->type == glq_req_type_action) { - INIT_LIST_HEAD (&item->list); - bucket = glq_calc_hash_key(item); - spin_lock (&glq_ReplyMap[bucket].lock); - list_add (&item->list, &glq_ReplyMap[bucket].bucket); - spin_unlock (&glq_ReplyMap[bucket].lock); - err = lg_lock_action_req (gulm_cm.hookup, item->key, - item->keylen, item->subid, item->state, - item->lvb, item->lvblen); - } else if (item->type == glq_req_type_query ) { - INIT_LIST_HEAD (&item->list); - bucket = glq_calc_hash_key(item); - spin_lock (&glq_ReplyMap[bucket].lock); - list_add (&item->list, &glq_ReplyMap[bucket].bucket); - spin_unlock (&glq_ReplyMap[bucket].lock); - err = lg_lock_query_req (gulm_cm.hookup, item->key, - item->keylen, item->subid, item->start, - item->stop, item->state); - } else if (item->type == glq_req_type_drop) { - err = lg_lock_drop_exp (gulm_cm.hookup, item->lvb, - item->key, item->keylen); - /* drop exp has no reply. */ - glq_recycle_req (item); - } else if (item->type == glq_req_type_expire) { - err = lg_lock_expire (gulm_cm.hookup, item->lvb, - item->key, item->keylen); - /* expire has no reply. */ - glq_recycle_req (item); - } else if (item->type == glq_req_type_cancel) { - err = lg_lock_cancel_req (gulm_cm.hookup, item->key, - item->keylen, item->subid); - /* cancels have no reply. */ - glq_recycle_req (item); - } else { - /* bad type. */ - log_err ("Unknown send type %d, tossing request.\n", - item->type); - glq_recycle_req (item); - } - if (err != 0 ) { - log_err ("gulm_glq_sender error %d\n", err); - glq_running = FALSE; - glq_recycle_req (item); - break; - } - } - complete (&glq_startedup); - return 0; -} - -/** - * glq_login_reply - - * @misc: - * @err: - * @which: - * - * - * Returns: int - */ -int glq_login_reply (void *misc, uint32_t error, uint8_t which) -{ - if (error != 0) { - glq_running = FALSE; - log_err ("glq: Got error %d from login request.\n", error); - } - return error; -} - -/** - * glq_logout_reply - - * @misc: - * - * - * Returns: int - */ -int glq_logout_reply (void *misc) -{ - glq_running = FALSE; /* if it isn't already. */ - return 0; -} - -/** - * glq_lock_state - - * @misc: - * @key: - * @keylen: - * @state: - * @flags: - * @error: - * @LVB: - * @LVBlen: - * - * - * Returns: int - */ -int -glq_lock_state (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint32_t error, - uint8_t * LVB, uint16_t LVBlen) -{ - int bucket, found = FALSE; - struct list_head *tmp; - glckr_t *item=NULL; - - /* lookup and remove from ReplyMap */ - bucket = glq_calc_hash_key_long(key, keylen, subid, start, stop); - spin_lock (&glq_ReplyMap[bucket].lock); - list_for_each(tmp, &glq_ReplyMap[bucket].bucket) { - item = list_entry (tmp, glckr_t, list); - if (item->subid == subid && - item->start == start && - item->stop == stop && - item->keylen == keylen && - memcmp(item->key, key, keylen) == 0 ) { - /* found it. */ - list_del (tmp); - found = TRUE; - break; - } - } - spin_unlock(&glq_ReplyMap[bucket].lock); - - if( !found ) { - /* not found complaint */ - return 0; - } - - /* restuff results */ - item->state = state; - item->flags = flags; - item->error = error; - if (item->lvb != NULL && LVB != NULL) { - item->lvblen = MIN(item->lvblen, LVBlen); - memcpy(item->lvb, LVB, item->lvblen); - } - - /* call finish */ - if (item->finish != NULL) item->finish (item); - - /* put on Free */ - glq_recycle_req(item); - return 0; -} - -/** - * glq_lock_action - - * @misc: - * @key: - * @keylen: - * @action: - * @error: - * - * - * Returns: int - */ -int -glq_lock_action (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint8_t action, uint32_t error) -{ - int bucket, found = FALSE; - struct list_head *tmp; - glckr_t *item = NULL; - - /* lookup and remove from ReplyMap */ - bucket = glq_calc_hash_key_long(key, keylen, subid, 0, ~((uint64_t)0)); - spin_lock (&glq_ReplyMap[bucket].lock); - list_for_each(tmp, &glq_ReplyMap[bucket].bucket) { - item = list_entry (tmp, glckr_t, list); - if (item->subid == subid && - item->start == 0 && - item->stop == ~((uint64_t)0) && - item->keylen == keylen && - memcmp(item->key, key, keylen) == 0 ) { - /* found it. */ - list_del (tmp); - found = TRUE; - break; - } - } - spin_unlock(&glq_ReplyMap[bucket].lock); - - if( !found ) { - /* not found complaint */ - return 0; - } - - /* restuff results */ - item->error = error; - - /* call finish */ - if (item->finish != NULL) item->finish (item); - - /* put on Free */ - glq_recycle_req(item); - return 0; -} - -/** - * glq_lock_query - - * this is an ugly interface..... - * there is somehting that needs to be done here to clean things up. I'm - * not sure what that is right now, and I need to have somehting working. - * So we're going with this for now. - * - */ -int -glq_lock_query (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t error, uint8_t * cnode, - uint64_t csubid, uint64_t cstart, uint64_t cstop, - uint8_t cstate) -{ - int bucket, found = FALSE; - struct list_head *tmp; - glckr_t *item = NULL; - - /* lookup and remove from ReplyMap */ - bucket = glq_calc_hash_key_long(key, keylen, subid, start, stop); - spin_lock (&glq_ReplyMap[bucket].lock); - list_for_each(tmp, &glq_ReplyMap[bucket].bucket) { - item = list_entry (tmp, glckr_t, list); - if (item->subid == subid && - item->start == start && - item->stop == stop && - item->keylen == keylen && - memcmp(item->key, key, keylen) == 0 ) { - /* found it. */ - list_del (tmp); - found = TRUE; - break; - } - } - spin_unlock(&glq_ReplyMap[bucket].lock); - - if( !found ) { - /* not found complaint */ - return 0; - } - - /* restuff results */ - item->error = error; - item->subid = csubid; - item->start = cstart; - item->stop = cstop; - item->state = cstate; - - /* call finish */ - if (item->finish != NULL) item->finish (item); - - /* put on Free */ - glq_recycle_req(item); - return 0; -} - -/** - * glq_drop_lock_req - - * @misc: - * @key: - * @keylen: - * @state: - * - * - * Returns: int - */ -int -glq_drop_lock_req (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint8_t state) -{ - do_drop_lock_req (key, keylen, state); - jid_header_lock_drop (key, keylen); - sig_watcher_lock_drop (key, keylen); - return 0; -} - -/** - * glq_drop_all - - * @misc: - * - * - * Returns: int - */ -int glq_drop_all (void *misc) -{ - passup_droplocks (); - return 0; -} - -/** - * glq_error - - * @misc: - * @error: - * - * - * Returns: int - */ -int glq_error (void *misc, uint32_t error) -{ - log_err ("glq: weird last gasp error %d\n", error); - return error; -} - -static lg_lockspace_callbacks_t glq_lock_ops = { - login_reply:glq_login_reply, - logout_reply:glq_logout_reply, - lock_state:glq_lock_state, - lock_action:glq_lock_action, - lock_query:glq_lock_query, - drop_lock_req:glq_drop_lock_req, - drop_all:glq_drop_all, - error:glq_error -}; -/** - * glq_recving_thread - - * @data: - * - * - * Returns: int - */ -int glq_recving_thread(void *data) -{ - int err; - daemonize ("gulm_glq_recver"); - glq_recver_task = current; - complete (&glq_startedup); - - while (glq_running) { - err = lg_lock_handle_messages (gulm_cm.hookup, &glq_lock_ops, NULL); - if (err != 0) { - log_err ("gulm_glq_recver error %d\n", err); - glq_running = FALSE; - wake_up (&glq_send_wchan); - break; - } - } - complete (&glq_startedup); - return 0; -} - -/** - * glq_shutdown - - * - * Returns: void - */ -void glq_shutdown(void) -{ - if (glq_running) glq_running = FALSE; - if (glq_sender_task != NULL) { - wake_up (&glq_send_wchan); - wait_for_completion (&glq_startedup); - glq_sender_task = NULL; - } - if (glq_recver_task != NULL) { - lg_lock_logout (gulm_cm.hookup); - wait_for_completion (&glq_startedup); - glq_recver_task = NULL; - } -} - -/** - * glq_startup - - * - * Returns: int - */ -int glq_startup(void) -{ - int err; - - if (glq_running) return 0; - - err = lg_lock_login (gulm_cm.hookup, "GFS "); - if (err != 0) { - log_err ("Failed to send lock login. %d\n", err); - return -err; - } - - glq_running = TRUE; - if( glq_recver_task == NULL ) { - err = kernel_thread (glq_recving_thread, NULL, 0); - if( err < 0 ) { - log_err ("Failed to start glq_recving_thread %d\n", - err); - glq_shutdown(); - return err; - } - wait_for_completion (&glq_startedup); - } - - if (glq_sender_task == NULL) { - err = kernel_thread (glq_sender_thread, NULL, 0); - if( err < 0 ) { - log_err ("Failed to start glq_sender_thread %d\n", - err); - glq_shutdown(); - return err; - } - wait_for_completion (&glq_startedup); - } - return 0; -} - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_lock_queue.h b/gfs-kernel/src/gulm/gulm_lock_queue.h deleted file mode 100644 index aa8d8ef..0000000 --- a/gfs-kernel/src/gulm/gulm_lock_queue.h +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - -/* - * So what if we change this to a request chain like I've got in the - * servers. There are three lists. Free, Send, Reply. Where the Reply - * list is actually more of a hash. - * - * Activity goes: - * - Grab struct from Free, malloc if needed. - * - Stuff, stick on Send. - * - Send, sends, then sticks on Reply. - * - When handle_messages gets a reply, it looks up on Reply and handles - * from there. - * - * If Reply is a hash, it must be keyed on all important parts! - * (keyname, subid, start, stop) - */ -#ifndef __gulm_lockqueue_h__ -#define __gulm_lockqueue_h__ -#define glq_req_type_state (1) -#define glq_req_type_action (2) -#define glq_req_type_drop (3) -#define glq_req_type_cancel (4) -#define glq_req_type_query (5) -#define glq_req_type_expire (6) -typedef struct glck_req { - struct list_head list; - - /* these five for the key for hash-map look ups. - * Any part of any of these can change and thus be a unique request. - * (this struct is only put into a hash map to match replies.) - */ - uint8_t *key; - uint16_t keylen; - uint64_t subid; - uint64_t start; - uint64_t stop; - - /* other info about this request. */ - uint8_t type; - uint8_t state; /* also action */ /* changes on reply (anyflag) */ - uint32_t flags; /* changes on reply */ - uint8_t *lvb; /* changes on reply */ - uint16_t lvblen; - uint32_t error; /* changes on reply */ - - /* when we get a reply, do this - * this glck_req will not be on any list when finish is called. Upon - * the return of finish, it will be placed onto the Free list. - */ - void *misc; - void (*finish)(struct glck_req *glck); - -} glckr_t; - -/* prototypes */ -int glq_init(void); -int glq_startup(void); -void glq_shutdown(void); -void glq_release(void); -glckr_t *glq_get_new_req(void); -void glq_recycle_req(glckr_t *); -glckr_t *glq_duplicate(glckr_t *old); -void glq_queue(glckr_t *); -void glq_cancel(glckr_t *); - - -#endif /*__gulm_lockqueue_h__*/ -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_log_msg_bits.h b/gfs-kernel/src/gulm/gulm_log_msg_bits.h deleted file mode 100644 index 6413ed2..0000000 --- a/gfs-kernel/src/gulm/gulm_log_msg_bits.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gulm_log_msg_bits_h__ -#define __gulm_log_msg_bits_h__ -/* log_msg bit flags - * These got thier own file so I can easily include them in both user and - * kernel space. - * */ -#define lgm_Always (0x00000000) /*Print Message no matter what */ -#define lgm_Network (0x00000001) -#define lgm_Network2 (0x00000002) -#define lgm_Stomith (0x00000004) -#define lgm_Heartbeat (0x00000008) -#define lgm_locking (0x00000010) -#define lgm_FuncDebug (0x00000020) -#define lgm_Forking (0x00000040) -#define lgm_JIDMap (0x00000080) -#define lgm_Subscribers (0x00000100) -#define lgm_LockUpdates (0x00000200) -#define lgm_LoginLoops (0x00000400) -#define lgm_Network3 (0x00000800) -#define lgm_JIDUpdates (0x00001000) -#define lgm_ServerState (0x00002000) - -#define lgm_ReallyAll (0xffffffff) - -#define lgm_BitFieldSize (32) - -#endif /*__gulm_log_msg_bits_h__*/ diff --git a/gfs-kernel/src/gulm/gulm_lt.c b/gfs-kernel/src/gulm/gulm_lt.c deleted file mode 100644 index 85d6346..0000000 --- a/gfs-kernel/src/gulm/gulm_lt.c +++ /dev/null @@ -1,1002 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/file.h> -#include <linux/crc32.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "handler.h" -#include "gulm_lock_queue.h" -#include "utils_tostr.h" - -#define gulm_gfs_lmBits (13) -#define gulm_gfs_lmSize (1 << gulm_gfs_lmBits) -#define gulm_gfs_lmMask (gulm_gfs_lmSize - 1) - -extern gulm_cm_t gulm_cm; - -/****************************************************************************/ -/* A bunch of prints that hopefully contain more information that is also - * useful - * - * these are a mess. - */ - -/** - * lck_key_to_hex - - * @key: - * @len: - * @workspace: <> place to put string. !! better be 2x len !! - * - * - * Returns: char - */ -static char * -lck_key_to_hex (uint8_t * key, uint16_t len, char *workspace) -{ - int i; - for (i = 0; i < len; i++) - sprintf (&workspace[i * 2], "%02x", (key[i] & 0xff)); - return workspace; -} - -#if 0 -static void __inline__ -db_lck_entered (gulm_lock_t * lck) -{ - char bb[GIO_KEY_SIZE * 2 + 3]; - lck_key_to_hex (lck->key, lck->keylen, bb); - printk ("Started lock 0x%s cur:%#x req:%#x flags:%#x\n", bb, - lck->cur_state, lck->req_state, lck->flags); -} -static void __inline__ -db_lck_exited (gulm_lock_t * lck) -{ - char bb[GIO_KEY_SIZE * 2 + 3]; - lck_key_to_hex (lck->key, lck->keylen, bb); - printk ("Finished lock 0x%s result:%#x\n", bb, lck->result); -} -#endif - -static void __inline__ -dump_gulm_lock_t (gulm_lock_t * lck) -{ - char bb[GIO_KEY_SIZE * 2 + 3]; - - lck_key_to_hex (lck->key, lck->keylen, bb); - log_msg (lgm_Always, " key = 0x%s\n", bb); - log_msg (lgm_Always, " cur_state = %d\n", lck->cur_state); -} - -/* DEBUG_BY_LOCK is gone. I may later add something back if needed. - * - * I love the idea of being able to log only certain locks, I just cannot - * think of an easy way to do it. The best I can come up with is some - * pattern (or set of) that are used to decide which locks get logged. But - * that could be expensive if the pattern is checked everytime, and won't - * behave as expected if only applied in get_lock. - * */ - -/* The old log functions. - * These need their own sort of clean up someday as well. - * */ -#define log_msg_lk(key, keylen, fmt, args...) {\ - uint8_t bb[GIO_KEY_SIZE*2 +3]; \ - lck_key_to_hex( key, keylen, bb); \ - printk(PROTO_NAME ": On lock 0x%s " fmt , bb , ## args ); \ - } - -#define log_err_lk(key, keylen, fmt, args...) {\ - uint8_t bb[GIO_KEY_SIZE*2 +3]; \ - lck_key_to_hex( key, keylen, bb); \ - printk(KERN_ERR PROTO_NAME ": ERROR On lock 0x%s " fmt , bb , ## args ); \ - } - -#define log_msg_lck(lck, fmt, args...) {\ - uint8_t bb[GIO_KEY_SIZE*2 +3]; \ - lck_key_to_hex( (lck)->key, (lck)->keylen, bb); \ - printk(PROTO_NAME ": On lock 0x%s " fmt , bb , ## args ); \ - } - -#define log_err_lck(lck, fmt, args...) {\ - uint8_t bb[GIO_KEY_SIZE*2 +3]; \ - lck_key_to_hex( (lck)->key, (lck)->keylen, bb); \ - printk(KERN_ERR PROTO_NAME ": ERROR On lock 0x%s " fmt , bb , ## args ); \ - } - -#ifdef DEBUG_LVB -static void __inline__ -print_lk_lvb (uint8_t * key, uint8_t * lvb, uint8_t st, uint8_t * dir) -{ - uint8_t bk[GIO_KEY_SIZE * 2 + 3]; - uint8_t bl[GIO_LVB_SIZE * 2 + 3]; - int i; - for (i = 0; i < GIO_KEY_SIZE; i++) - sprintf (&bk[(i * 2)], "%02x", (key[i]) & 0xff); - for (i = 0; i < GIO_LVB_SIZE; i++) - sprintf (&bl[(i * 2)], "%02x", (lvb[i]) & 0xff); - printk (PROTO_NAME ": On lock 0x%s with state %d\n\t%s LVB 0x%s\n", - bk, st, dir, bl); -} - -#define lvb_log_msg_lk(k, fmt, args...) log_msg_lk( k , fmt , ## args ) -#define lvb_log_msg(fmt, args...) log_msg(lgm_Always , fmt , ## args ) -#else /*DEBUG_LVB */ -#define print_lk_lvb(k,l,s,d) -#define lvb_log_msg_lk(k, fmt, args...) -#define lvb_log_msg(fmt, args...) -#endif /*DEBUG_LVB */ - -/****************************************************************************/ -/** - * pack_lock_key - - * @key: - * @keylen: - * - * key is: <type><fsname len><fsname>\0<pk len><pk>\0 - * <type> is: G J F N P - * <fsname len> is 0-256 - * - * Returns: int - */ -int pack_lock_key(uint8_t *key, uint16_t keylen, uint8_t type, - uint8_t *fsname, uint8_t *pk, uint8_t pklen) -{ - int fsnlen; - fsnlen = strlen(fsname); - - if( keylen <= (fsnlen + pklen + 5) ) return -1; - - memset (key, 0, keylen); - - key[0] = type; - - key[1] = fsnlen; - memcpy(&key[2], fsname, fsnlen); - key[2 + fsnlen] = 0; - - key[3 + fsnlen] = pklen; - - memcpy(&key[4 + fsnlen], pk, pklen); - - key[4 + fsnlen + pklen] = 0; - - return fsnlen + pklen + 5; -} - -/** - * unpack_lock_key - - * @key: < - * @keylen: < - * @type: > - * @fsname: > - * @fsnlen: > - * @pk: > - * @pklen: > - * - * if you're gonna fiddle with bytes returned here, copy first! - * - * this is broken. do I even really need this? - * - * Returns: int - */ -int unpack_lock_key(uint8_t *key, uint16_t keylen, uint8_t *type, - uint8_t **fsname, uint8_t *fsnlen, - uint8_t **pk, uint8_t *pklen) -{ - int fsnl, pkl; - if( type != NULL ) - *type = key[0]; - - fsnl = key[1]; - if( fsnlen != NULL && *fsname != NULL ) { - *fsnlen = key[1]; - *fsname = &key[2]; - } - - /* 0 = key[2 + fsnl] */ - - pkl = key[3 + fsnl]; - if( pklen != NULL && *pk != NULL ) { - *pklen = key[3 + fsnl]; - *pk = &key[4 + fsnl]; - } - - /* 0 = key[4 + fsnl + *pklen] */ - - return fsnl + pkl + 5; -} - -/** - * pack_drop_mask - - * @mask: - * @fsname: - * - * - * Returns: int - */ -int pack_drop_mask(uint8_t *mask, uint16_t mlen, uint8_t *fsname) -{ - int fsnlen; - fsnlen = strlen(fsname); - - memset (mask, 0, mlen); - - mask[0] = 0xff; - mask[1] = fsnlen; - memcpy(&mask[2], fsname, fsnlen); - mask[2 + fsnlen] = 0; - /* rest should be 0xff */ - - return 3 + fsnlen; -} - -/** - * gulm_lt_init - - * - * Returns: int - */ -int gulm_lt_init (void) -{ - int i; - gulm_cm.gfs_lockmap = vmalloc(sizeof(gulm_hb_t) * gulm_gfs_lmSize); - if (gulm_cm.gfs_lockmap == NULL) - return -ENOMEM; - for(i=0; i < gulm_gfs_lmSize; i++) { - spin_lock_init (&gulm_cm.gfs_lockmap[i].lock); - INIT_LIST_HEAD (&gulm_cm.gfs_lockmap[i].bucket); - } - return 0; -} - -/** - * gulm_lt_release - - */ -void gulm_lt_release(void) -{ - struct list_head *tmp, *lltmp; - gulm_lock_t *lck; - int i; - - for(i=0; i < gulm_gfs_lmSize; i++) { - list_for_each_safe (tmp, lltmp, &gulm_cm.gfs_lockmap[i].bucket) { - lck = list_entry (tmp, gulm_lock_t, gl_list); - list_del (tmp); - - if (lck->lvb != NULL) kfree (lck->lvb); - - kfree(lck); - } - } - - vfree (gulm_cm.gfs_lockmap); -} - -/** - * find_and_mark_lock - - * @key: - * @keylen: - * @lockp: - * - * looks for a lock struct of key. If found, marks it. - * - * Returns: TRUE or FALSE - */ -int -find_and_mark_lock (uint8_t * key, uint8_t keylen, gulm_lock_t ** lockp) -{ - int found = FALSE; - uint32_t bkt; - gulm_lock_t *lck = NULL; - struct list_head *tmp; - - /* now find the lock */ - bkt = crc32 (GULM_CRC_INIT, key, keylen); - bkt &= gulm_gfs_lmMask; - - spin_lock (&gulm_cm.gfs_lockmap[bkt].lock); - list_for_each (tmp, &gulm_cm.gfs_lockmap[bkt].bucket) { - lck = list_entry (tmp, gulm_lock_t, gl_list); - if (memcmp (lck->key, key, keylen) == 0) { - found = TRUE; - atomic_inc (&lck->count); - break; - } - } - spin_unlock (&gulm_cm.gfs_lockmap[bkt].lock); - - if (found) - *lockp = lck; - - return found; -} - -/** - * mark_lock - - * @lck: - * - * like above, but since we have the lock, don't search for it. - * - * Returns: int - */ -void __inline__ -mark_lock (gulm_lock_t * lck) -{ - atomic_inc (&lck->count); -} - -/** - * unmark_and_release_lock - - * @lck: - * - * decrement the counter on a lock, freeing it if it reaches 0. - * (also removes it from the hash table) - * - * TRUE if lock was freed. - * - * Returns: TRUE or FALSE - */ -int -unmark_and_release_lock (gulm_lock_t * lck) -{ - uint32_t bkt; - int deld = FALSE; - - bkt = crc32 (GULM_CRC_INIT, lck->key, lck->keylen); - bkt &= gulm_gfs_lmMask; - - spin_lock (&gulm_cm.gfs_lockmap[bkt].lock); - if (atomic_dec_and_test (&lck->count)) { - list_del (&lck->gl_list); - deld = TRUE; - } - spin_unlock (&gulm_cm.gfs_lockmap[bkt].lock); - if (deld) { - if (lck->lvb != NULL) { - kfree (lck->lvb); - } - kfree (lck->key); - kfree (lck); - } - - return deld; -} - -/****************************************************************************/ - -/** - * gulm_key_to_lm_lockname - - * @key: - * @lockname: - * - */ -void -gulm_key_to_lm_lockname (uint8_t * key, struct lm_lockname *lockname) -{ - int pos; - - pos = key[1] + 4; - /* pos now points to the first byte of the GFS lockname that was - * embedded in the gulm lock key, skipping over the fs name. - */ - - (*lockname).ln_type = key[pos]; - (*lockname).ln_number = (u64) (key[pos+1]) << 56; - (*lockname).ln_number |= (u64) (key[pos+2]) << 48; - (*lockname).ln_number |= (u64) (key[pos+3]) << 40; - (*lockname).ln_number |= (u64) (key[pos+4]) << 32; - (*lockname).ln_number |= (u64) (key[pos+5]) << 24; - (*lockname).ln_number |= (u64) (key[pos+6]) << 16; - (*lockname).ln_number |= (u64) (key[pos+7]) << 8; - (*lockname).ln_number |= (u64) (key[pos+8]) << 0; -} - -/** - * do_drop_lock_req - - * @key: - * @keylen: - * @state: - * - * - * Returns: void - */ -void -do_drop_lock_req (uint8_t *key, uint16_t keylen, uint8_t state) -{ - gulm_lock_t *lck; - unsigned int type; - struct lm_lockname lockname; - - if (!find_and_mark_lock (key, keylen, &lck)) { - return; - } - - switch (state) { - case lg_lock_state_Unlock: - type = LM_CB_DROPLOCKS; - break; - case lg_lock_state_Exclusive: - type = LM_CB_NEED_E; - break; - case lg_lock_state_Shared: - type = LM_CB_NEED_S; - break; - case lg_lock_state_Deferred: - type = LM_CB_NEED_D; - break; - default: - type = LM_CB_DROPLOCKS; - break; - } - gulm_key_to_lm_lockname (key, &lockname); - - qu_drop_req (&lck->fs->cq, lck->fs->cb, lck->fs->fsdata, type, - lockname.ln_type, lockname.ln_number); - - unmark_and_release_lock (lck); -} - -/****************************************************************************/ - -/** - * calc_lock_result - - * @lck: - * @state: - * @error: - * @flags: - * - * This calculates the correct result to return for gfs lock requests. - * - * Returns: int - */ -int -calc_lock_result (gulm_lock_t * lck, - uint8_t state, uint32_t error, uint32_t flags) -{ - gulm_fs_t *fs = lck->fs; - int result = -69; - - /* adjust result based on success status. */ - switch (error) { - case lg_err_Ok: - /* set result to current lock state. */ - switch (state) { - case lg_lock_state_Shared: - result = LM_ST_SHARED; - break; - case lg_lock_state_Deferred: - result = LM_ST_DEFERRED; - break; - case lg_lock_state_Exclusive: - result = LM_ST_EXCLUSIVE; - break; - case lg_lock_state_Unlock: - result = LM_ST_UNLOCKED; - break; - default: - GULM_ASSERT (0, - dump_gulm_lock_t (lck); - log_err_lck - (lck, "fsid=%s: Anit no lock state %d.\n", - fs->fs_name, state); - ); - break; - } - - /* if no internal unlocks, it is cachable. */ - if (result != LM_ST_UNLOCKED && (flags & lg_lock_flag_Cachable)) - result |= LM_OUT_CACHEABLE; - - break; - case lg_err_Canceled: - result = LM_OUT_CANCELED | lck->cur_state; - break; - case lg_err_TryFailed: - result = lck->cur_state; /* if we didn't get it. */ - break; - default: - log_err_lck(lck, "state:%#x error:%d flags:%#x", - state, error, flags); - result = -error; - break; - } - - return result; -} - -/****************************************************************************/ - -/** - * gulm_get_lock - - * @lockspace: - * @name: - * @lockp: - * - * Returns: 0 on success, -EXXX on failure - */ -int -gulm_get_lock (lm_lockspace_t * lockspace, struct lm_lockname *name, - lm_lock_t ** lockp) -{ - int err=0, len, bkt; - gulm_fs_t *fs = (gulm_fs_t *) lockspace; - uint8_t key[GIO_KEY_SIZE]; - uint8_t temp[9]; - gulm_lock_t *lck=NULL; - - temp[0] = name->ln_type & 0xff; - temp[1] = (name->ln_number >> 56) & 0xff; - temp[2] = (name->ln_number >> 48) & 0xff; - temp[3] = (name->ln_number >> 40) & 0xff; - temp[4] = (name->ln_number >> 32) & 0xff; - temp[5] = (name->ln_number >> 24) & 0xff; - temp[6] = (name->ln_number >> 16) & 0xff; - temp[7] = (name->ln_number >> 8) & 0xff; - temp[8] = (name->ln_number >> 0) & 0xff; - - len = pack_lock_key(key, GIO_KEY_SIZE, 'G', fs->fs_name, temp, 9); - if( len <=0 ) {err = len; goto exit;} - - if (!find_and_mark_lock (key, len, &lck)) { - /* not found, must create. */ - lck = kmalloc(sizeof(gulm_lock_t), GFP_KERNEL); - if (lck == NULL) { - err = -ENOMEM; - goto exit; - } - INIT_LIST_HEAD (&lck->gl_list); - atomic_set (&lck->count, 1); - lck->key = kmalloc (len, GFP_KERNEL); - if (lck->key == NULL) { - kfree(lck); - err = -ENOMEM; - goto exit; - } - memcpy (lck->key, key, len); - lck->keylen = len; - lck->fs = fs; - lck->lvb = NULL; - lck->cur_state = LM_ST_UNLOCKED; - - bkt = crc32 (GULM_CRC_INIT, key, len); - bkt &= gulm_gfs_lmMask; - - spin_lock (&gulm_cm.gfs_lockmap[bkt].lock); - list_add (&lck->gl_list, &gulm_cm.gfs_lockmap[bkt].bucket); - spin_unlock (&gulm_cm.gfs_lockmap[bkt].lock); - - } - *lockp = lck; - -exit: - return err; -} - -/** - * gulm_put_lock - - * @lock: - * - * - * Returns: void - */ -void -gulm_put_lock (lm_lock_t * lock) -{ - unmark_and_release_lock ((gulm_lock_t *) lock); -} - -/** - * gulm_lock_finish - - * @glck: - * - * - * Returns: void - */ -void gulm_lock_finish (struct glck_req *item) -{ - int result; - gulm_lock_t *lck = (gulm_lock_t *)item->misc; - gulm_fs_t *fs = lck->fs; - struct lm_lockname lockname; - - result = calc_lock_result (lck, item->state, item->error, item->flags); - /* requeue lock requests on error. We should be able to retry from - * most any error. Will need to watch the logs though.... - * Since the current item *will* be freed when this function - * returns, we will have to make a new one to do this. No big deal, - * but probably worth a new function. - */ - if( result < 0 ) { - struct glck_req *new=NULL; - RETRY_MALLOC(new = glq_duplicate(item), new); - glq_queue(new); - return; - } - - gulm_key_to_lm_lockname (lck->key, &lockname); - - qu_async_rpl (&fs->cq, fs->cb, fs->fsdata, &lockname, result); - - /* marked in gulm_lock() */ - unmark_and_release_lock (lck); -} - -/** - * gulm_lock - - * @lock: - * @cur_state: - * @req_state: - * @flags: - * - * - * Returns: int - */ -unsigned int -gulm_lock (lm_lock_t * lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags) -{ - glckr_t *item; - gulm_lock_t *lck = (gulm_lock_t *) lock; - gulm_fs_t *fs = lck->fs; - - item = glq_get_new_req(); - if (item == NULL) { - return -ENOMEM; - } - - mark_lock (lck); /* matching unmark is in gulm_lock_finish */ - - item->key = lck->key; - item->keylen = lck->keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - - switch (req_state) { - case LM_ST_EXCLUSIVE: - item->state = lg_lock_state_Exclusive; - break; - case LM_ST_DEFERRED: - item->state = lg_lock_state_Deferred; - break; - case LM_ST_SHARED: - item->state = lg_lock_state_Shared; - break; - case LM_ST_UNLOCKED: - item->state = lg_lock_state_Unlock; - break; - default: - GULM_ASSERT (0, log_err ("fsid=%s: Anit no lock state %d.\n", - fs->fs_name, req_state);); - break; - } - item->flags = 0; - if (flags & LM_FLAG_TRY) { - item->flags |= lg_lock_flag_Try; - } - if (flags & LM_FLAG_TRY_1CB) { - item->flags |= lg_lock_flag_Try | lg_lock_flag_DoCB; - } - if (flags & LM_FLAG_NOEXP) { - item->flags |= lg_lock_flag_IgnoreExp; - } - if (flags & LM_FLAG_ANY) { - item->flags |= lg_lock_flag_Any; - } - if (flags & LM_FLAG_PRIORITY) { - item->flags |= lg_lock_flag_Piority; - } - if (lck->lvb != NULL) { - item->lvb = lck->lvb; - item->lvblen = fs->lvb_size; - }else{ - item->lvb = NULL; - item->lvblen = 0; - } - item->error = 0; - - item->misc = lck; - item->finish = gulm_lock_finish; - - lck->cur_state = cur_state; - - glq_queue (item); - - return LM_OUT_ASYNC; -} - -/** - * gulm_unlock - - * @lock: - * @cur_state: - * - * - * Returns: int - */ -unsigned int -gulm_unlock (lm_lock_t * lock, unsigned int cur_state) -{ - int e; - e = gulm_lock (lock, cur_state, LM_ST_UNLOCKED, 0); - return e; -} - -/** - * gulm_cancel - - * @lock: - * - */ -void -gulm_cancel (lm_lock_t * lock) -{ - glckr_t *item; - gulm_lock_t *lck = (gulm_lock_t *) lock; - - mark_lock (lck); - - item = glq_get_new_req(); - if( item == NULL ) goto exit; - - /* have to make a copy for cancel req. */ - item->key = kmalloc(lck->keylen, GFP_KERNEL); - if (item->key == NULL) { - glq_recycle_req(item); - goto exit; - } - memcpy(item->key, lck->key, lck->keylen); - item->keylen = lck->keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_cancel; - item->finish = NULL; - - glq_cancel(item); - -exit: - unmark_and_release_lock (lck); -} - -/****************************************************************************/ -struct gulm_lvb_temp_s { - int error; - struct completion sleep; -}; - -/** - * gulm_lvb_finish - - * @glck: - * - * - * Returns: void - */ -void gulm_lvb_finish(struct glck_req *glck) -{ - struct gulm_lvb_temp_s *g = (struct gulm_lvb_temp_s *)glck->misc; - g->error = glck->error; - complete (&g->sleep); -} - -/** - * gulm_hold_lvb - - * @lock: - * @lvbp: - * - * - * Returns: 0 on success, -EXXX on failure - */ -int -gulm_hold_lvb (lm_lock_t * lock, char **lvbp) -{ - int err = -1; - struct gulm_lvb_temp_s ghlt; - glckr_t *item; - gulm_lock_t *lck = (gulm_lock_t *) lock; - gulm_fs_t *fs = lck->fs; - - mark_lock (lck); - - item = glq_get_new_req(); - if( item == NULL ) { - err = -ENOMEM; - goto fail; - } - - item->key = lck->key; - item->keylen = lck->keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_action; - item->state = lg_lock_act_HoldLVB; - item->flags = 0; - item->error = ghlt.error = 0; - - init_completion (&ghlt.sleep); - - item->misc = &ghlt; - item->finish = gulm_lvb_finish; - - lck->lvb = kmalloc (fs->lvb_size, GFP_KERNEL); - if (lck->lvb == NULL) { - err = -ENOMEM; - goto fail; - } - memset (lck->lvb, 0, fs->lvb_size); - - item->lvb = lck->lvb; - item->lvblen = fs->lvb_size; - - glq_queue (item); - wait_for_completion (&ghlt.sleep); - /* after here, item is no longer valid - * (memory was probably freed.) - * is why we use ghlt.error and not item->error. - */ - - if (ghlt.error != lg_err_Ok) { - log_err ("fsid=%s: Got error %d on hold lvb request.\n", - fs->fs_name, ghlt.error); - kfree (lck->lvb); - lck->lvb = NULL; - goto fail; - } - - *lvbp = lck->lvb; - - unmark_and_release_lock (lck); - - lvb_log_msg_lk (lck->key, "fsid=%s: Exiting gulm_hold_lvb\n", - fs->fs_name); - return 0; - fail: - unmark_and_release_lock (lck); - if (err != 0) - log_msg (lgm_Always, - "fsid=%s: Exiting gulm_hold_lvb with errors (%d)\n", - fs->fs_name, err); - return err; -} - -/** - * gulm_unhold_lvb - - * @lock: - * @lvb: - * - * - * Returns: void - */ -void -gulm_unhold_lvb (lm_lock_t * lock, char *lvb) -{ - struct gulm_lvb_temp_s ghlt; - glckr_t *item; - gulm_lock_t *lck = (gulm_lock_t *) lock; - gulm_fs_t *fs = lck->fs; - - mark_lock (lck); - - item = glq_get_new_req(); - if( item == NULL ) { - log_err("unhold_lvb: failed to get needed memory. skipping.\n"); - goto exit; - } - - item->key = lck->key; - item->keylen = lck->keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_action; - item->state = lg_lock_act_UnHoldLVB; - item->flags = 0; - item->error = ghlt.error = 0; - - init_completion (&ghlt.sleep); - - item->misc = &ghlt; - item->finish = gulm_lvb_finish; - - item->lvb = lck->lvb; - item->lvblen = fs->lvb_size; - - glq_queue (item); - wait_for_completion (&ghlt.sleep); - /* after here, item is no longer valid - * (memory was probably freed.) - * is why we use ghlt.error and not item->error. - */ - - if (ghlt.error != lg_err_Ok) { - log_err ("fsid=%s: Got error %d on unhold LVB request.\n", - lck->fs->fs_name, ghlt.error); - } - /* free it always. GFS thinks it is gone no matter what the server - * thinks. (and as much as i hate to say it this way, far better to - * leak in userspace than in kernel space.) - */ - if (lck->lvb != NULL) - kfree (lck->lvb); - lck->lvb = NULL; - exit: - unmark_and_release_lock (lck); - lvb_log_msg ("Exiting gulm_unhold_lvb\n"); -} - -/** - * gulm_sync_lvb - - * @lock: - * @lvb: - * - */ -void -gulm_sync_lvb (lm_lock_t * lock, char *lvb) -{ - struct gulm_lvb_temp_s ghlt; - glckr_t *item; - gulm_lock_t *lck = (gulm_lock_t *) lock; - gulm_fs_t *fs = lck->fs; - - mark_lock (lck); - - item = glq_get_new_req(); - if( item == NULL ) { - log_err("sync_lvb: failed to get needed memory. skipping.\n"); - goto exit; - } - - item->key = lck->key; - item->keylen = lck->keylen; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_action; - item->state = lg_lock_act_SyncLVB; - item->flags = 0; - item->error = ghlt.error = 0; - - init_completion (&ghlt.sleep); - - item->misc = &ghlt; - item->finish = gulm_lvb_finish; - - item->lvb = lck->lvb; - item->lvblen = fs->lvb_size; - - glq_queue (item); - wait_for_completion (&ghlt.sleep); - /* after here, item is no longer valid - * (memory was probably freed.) - * is why we use ghlt.error and not item->error. - */ - - if (ghlt.error != lg_err_Ok) { - log_err ("fsid=%s: Got error %d on sync LVB request.\n", - lck->fs->fs_name, ghlt.error); - } - - exit: - unmark_and_release_lock (lck); - lvb_log_msg ("Exiting gulm_sync_lvb\n"); - -} - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_main.c b/gfs-kernel/src/gulm/gulm_main.c deleted file mode 100644 index 64910df..0000000 --- a/gfs-kernel/src/gulm/gulm_main.c +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/init.h> - -#include "gulm_lock_queue.h" - -MODULE_DESCRIPTION ("Grand Unified Locking Module " GULM_RELEASE_NAME); -MODULE_AUTHOR ("Red Hat, Inc."); -MODULE_LICENSE ("GPL"); - -gulm_cm_t gulm_cm; - -struct lm_lockops gulm_ops = { - lm_proto_name:PROTO_NAME, - lm_mount:gulm_mount, - lm_others_may_mount:gulm_others_may_mount, - lm_unmount:gulm_unmount, - lm_withdraw:gulm_withdraw, - lm_get_lock:gulm_get_lock, - lm_put_lock:gulm_put_lock, - lm_lock:gulm_lock, - lm_unlock:gulm_unlock, - lm_cancel:gulm_cancel, - lm_hold_lvb:gulm_hold_lvb, - lm_unhold_lvb:gulm_unhold_lvb, - lm_sync_lvb:gulm_sync_lvb, - lm_plock_get:gulm_plock_get, - lm_plock:gulm_plock, - lm_punlock:gulm_punlock, - lm_recovery_done:gulm_recovery_done, - lm_owner:THIS_MODULE, -}; - -/** - * init_gulm - Initialize the gulm module - * - * Returns: 0 on success, -EXXX on failure - */ -int __init -init_gulm (void) -{ - int error; - - memset (&gulm_cm, 0, sizeof (gulm_cm_t)); - gulm_cm.hookup = NULL; - - /* register with the lm layers. */ - error = lm_register_proto (&gulm_ops); - if (error) - goto fail; - - error = glq_init(); - if (error != 0 ) - goto lm_fail; - - error = gulm_lt_init(); - if (error != 0) - goto glq_fail; - - init_gulm_fs (); - sig_watcher_init (); - - printk ("Gulm %s (built %s %s) installed\n", - GULM_RELEASE_NAME, __DATE__, __TIME__); - - return 0; - -glq_fail: - glq_release(); - - lm_fail: - lm_unregister_proto (&gulm_ops); - - fail: - return error; -} - -/** - * exit_gulm - cleanup the gulm module - * - */ - -void __exit -exit_gulm (void) -{ - gulm_lt_release(); - glq_release(); - lm_unregister_proto (&gulm_ops); -} - -module_init (init_gulm); -module_exit (exit_gulm); - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_plock.c b/gfs-kernel/src/gulm/gulm_plock.c deleted file mode 100644 index a9cb0bd..0000000 --- a/gfs-kernel/src/gulm/gulm_plock.c +++ /dev/null @@ -1,321 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/file.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "gulm_lock_queue.h" - -/*****************************************************************************/ -/** - * gulm_plock_packname - - * @fsname: - * @num: - * @key: - * @keylen: - * - * - * Returns: int - */ -int gulm_plock_packname(uint8_t * fsname, uint64_t num, uint8_t *key, uint16_t keylen) -{ - uint8_t temp[8]; - temp[0] = (num >> 56) & 0xff; - temp[1] = (num >> 48) & 0xff; - temp[2] = (num >> 40) & 0xff; - temp[3] = (num >> 32) & 0xff; - temp[4] = (num >> 24) & 0xff; - temp[5] = (num >> 16) & 0xff; - temp[6] = (num >> 8) & 0xff; - temp[7] = (num >> 0) & 0xff; - return pack_lock_key(key, keylen, 'P', fsname, temp, 8); -} - -struct gulm_pqur_s { - uint64_t start; - uint64_t stop; - uint64_t subid; - int error; - uint8_t state; - struct completion sleep; -}; -/** - * gulm_plock_query_finish - - * @glck: - * - * - * Returns: void - */ -void gulm_plock_query_finish(struct glck_req *glck) -{ - struct gulm_pqur_s *g = (struct gulm_pqur_s *)glck->misc; - g->error = glck->error; - g->start = glck->start; - g->stop = glck->stop; - g->subid = glck->subid; - g->state = glck->state; - complete (&g->sleep); -} -/** - * gulm_plock_get - - */ -int -gulm_plock_get (lm_lockspace_t * lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - int err = 0; - struct gulm_pqur_s pqur; - uint8_t key[GIO_KEY_SIZE]; - gulm_fs_t *fs = (gulm_fs_t *) lockspace; - glckr_t *item; - - item = glq_get_new_req(); - if( item == NULL ) { - err = -ENOMEM; - goto fail; - } - - item->keylen = gulm_plock_packname(fs->fs_name, name->ln_number, - key, GIO_KEY_SIZE); - item->key = key; - item->subid = (unsigned long) fl->fl_owner; - item->start = fl->fl_start; - item->stop = fl->fl_end; - item->type = glq_req_type_query; - if (fl->fl_type == F_WRLCK) { - item->state = lg_lock_state_Exclusive; - } else { - item->state = lg_lock_state_Shared; - } - item->flags = lg_lock_flag_NoCallBacks; - item->error = pqur.error = 0; - - init_completion (&pqur.sleep); - - item->misc = &pqur; - item->finish = gulm_plock_query_finish; - - glq_queue (item); - wait_for_completion (&pqur.sleep); - - if (pqur.error == lg_err_TryFailed) { - err = -EAGAIN; - fl->fl_start = pqur.start; - fl->fl_end = pqur.stop; - fl->fl_pid = pqur.subid; - if( pqur.state == lg_lock_state_Exclusive ) - fl->fl_type = F_WRLCK; - else - fl->fl_type = F_RDLCK; - } else if (pqur.error == 0) { - fl->fl_type = F_UNLCK; - } else { - err = -pqur.error; - } - -fail: - return err; -} - -struct gulm_plock_req_wait_s { - int error; - int done; - wait_queue_head_t waiter; -}; - -/** - * gulm_plock_req_finish - - * @glck: - * - * - * Returns: void - */ -void gulm_plock_req_finish(struct glck_req *glck) -{ - struct gulm_plock_req_wait_s *g = (struct gulm_plock_req_wait_s *)glck->misc; - g->error = glck->error; - g->done = TRUE; - wake_up (&g->waiter); -} -/** - * do_plock_cancel - - * @item: - * - * - * Returns: void - */ -void do_plock_cancel(glckr_t *item) -{ - glckr_t *cancel; - cancel = glq_get_new_req(); - if( cancel == NULL ) { - log_err ("Out of memory, Cannot cancel plock request.\n"); - return; - } - - /* after cancel is processed, glq will call kfree on item->key. */ - cancel->key = kmalloc(item->keylen, GFP_KERNEL); - if (cancel->key == NULL) { - glq_recycle_req(cancel); - log_err ("Out of memory, Cannot cancel plock request.\n"); - return; - } - memcpy(cancel->key, item->key, item->keylen); - cancel->keylen = item->keylen; - cancel->subid = item->subid; - cancel->start = item->start; - cancel->stop = item->stop; - cancel->type = glq_req_type_cancel; - cancel->finish = NULL; - - glq_cancel(cancel); -} -/** - * gulm_plock - - * - */ -int -gulm_plock (lm_lockspace_t *lockspace, struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl) -{ - int err = 0; - struct gulm_plock_req_wait_s pwait; - uint8_t key[GIO_KEY_SIZE]; - gulm_fs_t *fs = (gulm_fs_t *) lockspace; - glckr_t *item; - - item = glq_get_new_req(); - if( item == NULL ) { - err = -ENOMEM; - goto fail; - } - - item->keylen = gulm_plock_packname(fs->fs_name, name->ln_number, - key, GIO_KEY_SIZE); - item->key = key; - item->subid = (unsigned long) fl->fl_owner; - item->start = fl->fl_start; - item->stop = fl->fl_end; - item->type = glq_req_type_state; - if (fl->fl_type == F_WRLCK) { - item->state = lg_lock_state_Exclusive; - } else { - item->state = lg_lock_state_Shared; - } - item->flags = lg_lock_flag_NoCallBacks; - if (!IS_SETLKW(cmd)) - item->flags |= lg_lock_flag_Try; - item->error = pwait.error = 0; - - pwait.done = FALSE; - init_waitqueue_head(&pwait.waiter); - - item->misc = &pwait; - item->finish = gulm_plock_req_finish; - - glq_queue (item); - err = wait_event_interruptible(pwait.waiter, pwait.done); - if( err != 0 ) { - /* signals. */ - /* send cancel req. */ - do_plock_cancel(item); - /* wait for canceled (or success if we were too slow in - * canceling) */ - wait_event(pwait.waiter, pwait.done); - } - - if (pwait.error == lg_err_TryFailed) { - err = -EAGAIN; - } else if (pwait.error == lg_err_Canceled) { - err = -EINTR; - } else { - err = -pwait.error; - } - - if ( err == 0) err = posix_lock_file_wait(file, fl); - -fail: - return err; -} - -struct gulm_pret_s { - int error; - struct completion sleep; -}; - -/** - * gulm_plock_finish - - * @glck: - * - * - * Returns: void - */ -void gulm_plock_finish(struct glck_req *glck) -{ - struct gulm_pret_s *g = (struct gulm_pret_s *)glck->misc; - g->error = glck->error; - complete (&g->sleep); -} - -/** - * gulm_unplock - - */ -int -gulm_punlock (lm_lockspace_t * lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - int err = 0; - struct gulm_pret_s pret; - uint8_t key[GIO_KEY_SIZE]; - gulm_fs_t *fs = (gulm_fs_t *) lockspace; - glckr_t *item; - - item = glq_get_new_req(); - if( item == NULL ) { - err = -ENOMEM; - goto fail; - } - - item->keylen = gulm_plock_packname(fs->fs_name, name->ln_number, - key, GIO_KEY_SIZE); - item->key = key; - item->subid = (unsigned long) fl->fl_owner; - item->start = fl->fl_start; - item->stop = fl->fl_end; - item->type = glq_req_type_state; - item->state = lg_lock_state_Unlock; - item->flags = 0; - item->error = pret.error = 0; - - init_completion (&pret.sleep); - - item->misc = &pret; - item->finish = gulm_plock_finish; - - glq_queue (item); - wait_for_completion (&pret.sleep); - - err = -pret.error; - if ( err == 0) err = posix_lock_file_wait(file, fl); - -fail: - return err; -} - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/gulm_prints.h b/gfs-kernel/src/gulm/gulm_prints.h deleted file mode 100644 index 081beec..0000000 --- a/gfs-kernel/src/gulm/gulm_prints.h +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gulm_prints_h__ -#define __gulm_prints_h__ -#include "gulm_log_msg_bits.h" - -#define PROTO_NAME "lock_gulm" - -#ifdef GULM_ASSERT -#undef GULM_ASSERT -#endif -#define GULM_ASSERT(x, do) \ -{ \ - if (!(x)) \ - { \ - printk("\n"PROTO_NAME": Assertion failed on line %d of file %s\n" \ - PROTO_NAME": assertion: "%s"\n", \ - __LINE__, __FILE__, #x ); \ - {do} \ - panic("\n"PROTO_NAME": Record message above and reboot.\n"); \ - } \ -} - -#define log_msg(v, fmt, args...) if(((v)&gulm_cm.verbosity)==(v)||(v)==lgm_Always) {\ - printk(PROTO_NAME ": " fmt, ## args); \ -} -#define log_err(fmt, args...) {\ - printk(KERN_ERR PROTO_NAME ": ERROR " fmt, ## args); \ -} - -#define log_nop(fmt, args...) -#define TICK printk("TICK==>" PROTO_NAME ": [%s:%d] pid:%d\n" , __FILE__ , __LINE__ , current->pid ) - -#endif /*__gulm_prints_h__*/ diff --git a/gfs-kernel/src/gulm/gulm_recsig.c b/gfs-kernel/src/gulm/gulm_recsig.c deleted file mode 100644 index 20f8149..0000000 --- a/gfs-kernel/src/gulm/gulm_recsig.c +++ /dev/null @@ -1,337 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/file.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "gulm_lock_queue.h" - -/* This is some speed hackery to abuse the locking system to allow clients - * to notify each other of things. It is a super simple signaling type - * system. All you can know is that a signal was touched. Pretty - * sreightforword. - * - * I really would rather have something else. I've a couple of good ideas, - * and will most likely switch to one of those at a later date. But this - * is good enough for now, and will get us through the next release. - * - * (functionally nothing wrong with this, theoretically, I can think of - * better designs than this abuse.) - */ - -extern gulm_cm_t gulm_cm; - -struct sig_watcher { - struct list_head sw_list; - uint8_t *name; - uint8_t len; - void(*func)(void *misc); - void *misc; -}; -struct list_head sig_watchers_list; -spinlock_t sig_watchers_lock; - -/****************************************************************************/ -/* internal funcs */ -/** - * release_sw - - * @name: - * @len: - * - * - * Returns: void - */ -static void release_sw(uint8_t *name, uint8_t len) -{ - struct list_head *tmp; - struct sig_watcher *sw; - spin_lock(&sig_watchers_lock); - list_for_each(tmp, &sig_watchers_list) { - sw = list_entry (tmp, struct sig_watcher, sw_list); - if( memcmp(name, sw->name, len) == 0 ) { - list_del(tmp); - kfree(sw->name); - kfree(sw); - break; - } - } - spin_unlock(&sig_watchers_lock); -} -/** - * add_sw - - * @name: - * @len: - * @func: - * @misc: - * - * - * Returns: int - */ -static int add_sw(uint8_t *name, uint8_t len, - void(*func)(void *misc), void *misc) -{ - struct sig_watcher *sw; - - sw = kmalloc(sizeof(struct sig_watcher), GFP_KERNEL); - if( sw == NULL ) return -ENOMEM; - sw->name = kmalloc(len, GFP_KERNEL); - if( sw->name == NULL ) { - kfree(sw); - return -ENOMEM; - } - memcpy(sw->name, name, len); - sw->len = len; - sw->func = func; - sw->misc = misc; - INIT_LIST_HEAD (&sw->sw_list); - spin_lock(&sig_watchers_lock); - list_add(&sw->sw_list, &sig_watchers_list); - spin_unlock(&sig_watchers_lock); - return 0; -} - -/** - * gulm_sw_finish - - * @item: - * - * - * Returns: void - */ -void gulm_sw_finish (struct glck_req *item) -{ - struct completion *sleep = (struct completion *)item->misc; - complete (sleep); -} - -/** - * hold_watch_lock - - * @name: - * @len: - * - * - * Returns: void - */ -void hold_watch_lock(gulm_fs_t *fs, uint8_t *name, uint8_t len) -{ - uint8_t key[GIO_KEY_SIZE]; - uint16_t keylen = GIO_KEY_SIZE; - struct completion sleep; - glckr_t *item; - - item = glq_get_new_req(); - if (item == NULL) { - return; - } - - item->keylen = pack_lock_key(key, keylen, 'S', fs->fs_name, name, len); - item->key = key; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Shared; - item->flags = lg_lock_flag_IgnoreExp; - item->error = 0; - item->lvb = NULL; - item->lvblen = 0; - - init_completion (&sleep); - - item->misc = &sleep; - item->finish = gulm_sw_finish; - - glq_queue (item); - wait_for_completion (&sleep); -} -/** - * release_watch_lock - - * @name: - * @len: - * - * - * Returns: void - */ -void release_watch_lock(gulm_fs_t *fs, uint8_t *name, uint8_t len) -{ - uint8_t key[GIO_KEY_SIZE]; - uint16_t keylen = GIO_KEY_SIZE; - struct completion sleep; - glckr_t *item; - - item = glq_get_new_req(); - if (item == NULL) { - return; - } - - item->keylen = pack_lock_key(key, keylen, 'S', fs->fs_name, name, len); - item->key = key; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Unlock; - item->flags = 0; - item->error = 0; - item->lvb = NULL; - item->lvblen = 0; - - init_completion (&sleep); - - item->misc = &sleep; - item->finish = gulm_sw_finish; - - glq_queue (item); - wait_for_completion (&sleep); -} -/** - * signal_watch_lock - - * @name: - * @len: - * - * - * Returns: void - */ -void signal_watch_lock(gulm_fs_t *fs, uint8_t *name, uint8_t len) -{ - uint8_t key[GIO_KEY_SIZE]; - uint16_t keylen = GIO_KEY_SIZE; - struct completion sleep; - glckr_t *item; - - item = glq_get_new_req(); - if (item == NULL) { - return; - } - - item->keylen = pack_lock_key(key, keylen, 'S', fs->fs_name, name, len); - item->key = key; - item->subid = 0; - item->start = 0; - item->stop = ~((uint64_t)0); - item->type = glq_req_type_state; - item->state = lg_lock_state_Exclusive; - item->flags = lg_lock_flag_Try|lg_lock_flag_DoCB|lg_lock_flag_IgnoreExp; - item->error = 0; - item->lvb = NULL; - item->lvblen = 0; - - init_completion (&sleep); - - item->misc = &sleep; - item->finish = gulm_sw_finish; - - glq_queue (item); - wait_for_completion (&sleep); -} - -/** - * sig_watcher_lock_drop - - * @key: - * @keylen: - * - * - * Returns: void - */ -void sig_watcher_lock_drop(uint8_t * key, uint16_t keylen) -{ - struct list_head *tmp; - struct sig_watcher *sw = NULL; - int found = FALSE; - uint8_t *fsname, len, *name, nlen; - if( key[0] != 'S' ) return; /* not a Signal lock */ - len = key[1]; - fsname = &key[2]; - nlen = key[3 + len]; - name = &key[4 + len]; - spin_lock(&sig_watchers_lock); - list_for_each(tmp, &sig_watchers_list) { - sw = list_entry (tmp, struct sig_watcher, sw_list); - if( memcmp(name, sw->name, MIN(nlen, sw->len)) == 0 ) { - found = TRUE; - break; - } - } - spin_unlock(&sig_watchers_lock); - if(found) { - sw->func(sw->misc); - } -} - -/****************************************************************************/ - -/** - * sig_water_init - - * @oid: - * - * - * Returns: void - */ -void sig_watcher_init(void) -{ - INIT_LIST_HEAD (&sig_watchers_list); - spin_lock_init(&sig_watchers_lock); -} - - -/** - * watch_sig - - * @name: - * @len: - * @misc: - * @misc: - * - * Returns: int - */ -int watch_sig(gulm_fs_t *fs, uint8_t *name, uint8_t len, void(*func)(void *misc), void *misc) -{ - if( func == NULL ) { - /* unlock signal lock */ - release_watch_lock(fs, name, len); - release_sw(name, len); - }else{ - /* hold signal lock shared. */ - if(add_sw(name, len, func, misc) == 0 ) { - hold_watch_lock(fs, name, len); - }else{ - return -ENOMEM; - } - } - return 0; -} - -/** - * tap_sig - - * @name: - * @len: - * - * - * Returns: int - */ -void tap_sig(gulm_fs_t *fs, uint8_t *name, uint8_t len) -{ - signal_watch_lock(fs, name, len); -#if 0 - /* Make sure it is still Shr. (very lazy way to do this. but it - * should be low traffic enough not to bother.) - * */ - hold_watch_lock(fs, name, len); -#endif -} - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/handler.c b/gfs-kernel/src/gulm/handler.c deleted file mode 100644 index e6a5259..0000000 --- a/gfs-kernel/src/gulm/handler.c +++ /dev/null @@ -1,343 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gulm.h" - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/fs.h> -#include <linux/smp_lock.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> - -#include "handler.h" - -/* things about myself - * mostly just for verbosity here. - * */ -extern gulm_cm_t gulm_cm; - -/* the task struct */ -typedef struct runtask_s { - struct list_head rt_list; - - gulm_fn fn; - lm_callback_t cb; - lm_fsdata_t *fsdata; - int type; - uint64_t lmnum; - unsigned int lmtype; - int result; - -} runtask_t; -/* ooo crufty. */ -#define LM_CB_GULM_FN 169 -#if LM_CB_GULM_FN == LM_CB_NEED_E || \ - LM_CB_GULM_FN == LM_CB_NEED_D || \ - LM_CB_GULM_FN == LM_CB_NEED_S || \ - LM_CB_GULM_FN == LM_CB_NEED_RECOVERY || \ - LM_CB_GULM_FN == LM_CB_DROPLOCKS || \ - LM_CB_GULM_FN == LM_CB_ASYNC -#error "LM_CB_GULM_FN collision with other LM_CB_*" -#endif - -static __inline__ int -queue_empty (callback_qu_t * cq) -{ - int ret; - spin_lock (&cq->list_lock); - ret = list_empty (&cq->run_tasks); - spin_unlock (&cq->list_lock); - return ret; -} - -/** - * handler - - * @d: - * - * - * Returns: int - */ -int -handler (void *d) -{ - callback_qu_t *cq = (callback_qu_t *) d; - runtask_t *rt; - struct list_head *tmp; - struct lm_lockname lockname; - struct lm_async_cb acb; - - daemonize ("gulm_Cb_Handler"); - atomic_inc (&cq->num_threads); - complete (&cq->startup); - - while (cq->running) { - do { - DECLARE_WAITQUEUE (__wait_chan, current); - current->state = TASK_INTERRUPTIBLE; - add_wait_queue (&cq->waiter, &__wait_chan); - if (queue_empty (cq)) - schedule (); - remove_wait_queue (&cq->waiter, &__wait_chan); - current->state = TASK_RUNNING; - } while (0); - - if (!cq->running) - break; - /* remove item from list */ - spin_lock (&cq->list_lock); - if (list_empty (&cq->run_tasks)) { - spin_unlock (&cq->list_lock); - continue; /* nothing here. move on */ - } - /* take items off the end of the list, since we add them to the - * beginning. - */ - tmp = (&cq->run_tasks)->prev; - list_del (tmp); - cq->task_count--; - spin_unlock (&cq->list_lock); - - rt = list_entry (tmp, runtask_t, rt_list); - - if (rt->type == LM_CB_ASYNC) { - acb.lc_name.ln_number = rt->lmnum; - acb.lc_name.ln_type = rt->lmtype; - acb.lc_ret = rt->result; - rt->cb (rt->fsdata, rt->type, &acb); - } else if (rt->type == LM_CB_GULM_FN) { - rt->fn (rt->fsdata); - } else { - lockname.ln_number = rt->lmnum; - lockname.ln_type = rt->lmtype; - rt->cb (rt->fsdata, rt->type, &lockname); - } - - kfree (rt); - - } /*while(running) */ - - atomic_dec (&cq->num_threads); - complete (&cq->startup); - return 0; -} - -/** - * display_handler_queue - - * @cq: - * - * remember, items are added to the head, and removed from the tail. - * So the last item listed, is the next item to be handled. - * - */ -void -display_handler_queue (callback_qu_t * cq) -{ - struct list_head *lltmp; - runtask_t *rt; - int i = 0; - log_msg (lgm_Always, "Dumping Handler queue with %d items, max %d\n", - cq->task_count, cq->task_max); - spin_lock (&cq->list_lock); - list_for_each (lltmp, &cq->run_tasks) { - rt = list_entry (lltmp, runtask_t, rt_list); - if (rt->type == LM_CB_ASYNC) { - log_msg (lgm_Always, - "%4d ASYNC (%" PRIu64 ", %u) result:%#x\n", - i, rt->lmnum, rt->lmtype, rt->result); - } else if (rt->type == LM_CB_GULM_FN) { - log_msg (lgm_Always, "%4d GULM FN func:%p data:%p\n", - i, rt->fn, rt->fsdata); - } else { /* callback. */ - log_msg (lgm_Always, - "%4d CALLBACK req:%u (%" PRIu64 ", %u)\n", i, - rt->type, rt->lmnum, rt->lmtype); - } - i++; - } - spin_unlock (&cq->list_lock); -} - -/** - * alloc_runtask - - * Returns: runtask_t - */ -runtask_t * -alloc_runtask (void) -{ - runtask_t *rt; - rt = kmalloc (sizeof (runtask_t), GFP_KERNEL); - return rt; -} - -/** - * qu_function_call - - * @cq: - * @fn: - * @data: - * - * Generic function execing on the handler thread. Mostly so I can add - * single things quick without having to build all the details into the - * handler queues. - * - * Returns: int - */ -int -qu_function_call (callback_qu_t * cq, gulm_fn fn, void *data) -{ - runtask_t *rt; - rt = alloc_runtask (); - if (rt == NULL) - return -ENOMEM; - rt->cb = NULL; - rt->fn = fn; - rt->fsdata = data; - rt->type = LM_CB_GULM_FN; - rt->lmtype = 0; - rt->lmnum = 0; - rt->result = 0; - INIT_LIST_HEAD (&rt->rt_list); - spin_lock (&cq->list_lock); - list_add (&rt->rt_list, &cq->run_tasks); - cq->task_count++; - if (cq->task_count > cq->task_max) - cq->task_max = cq->task_count; - spin_unlock (&cq->list_lock); - wake_up (&cq->waiter); - return 0; -} - -/** - * qu_async_rpl - - * @cq: - * @cb: - * @fsdata: - * @lockname: - * @result: - * - * - * Returns: int - */ -int -qu_async_rpl (callback_qu_t * cq, lm_callback_t cb, lm_fsdata_t * fsdata, - struct lm_lockname *lockname, int result) -{ - runtask_t *rt; - rt = alloc_runtask (); - if (rt == NULL) - return -ENOMEM; - rt->cb = cb; - rt->fsdata = fsdata; - rt->type = LM_CB_ASYNC; - rt->lmtype = lockname->ln_type; - rt->lmnum = lockname->ln_number; - rt->result = result; - INIT_LIST_HEAD (&rt->rt_list); - spin_lock (&cq->list_lock); - list_add (&rt->rt_list, &cq->run_tasks); - cq->task_count++; - if (cq->task_count > cq->task_max) - cq->task_max = cq->task_count; - spin_unlock (&cq->list_lock); - wake_up (&cq->waiter); - return 0; -} - -/** - * qu_drop_req - - * - * Returns: <0:Error; =0:Ok - */ -int -qu_drop_req (callback_qu_t * cq, lm_callback_t cb, lm_fsdata_t * fsdata, - int type, uint8_t lmtype, uint64_t lmnum) -{ - runtask_t *rt; - rt = alloc_runtask (); - if (rt == NULL) - return -ENOMEM; - rt->cb = cb; - rt->fsdata = fsdata; - rt->type = type; - rt->lmtype = lmtype; - rt->lmnum = lmnum; - rt->result = 0; - INIT_LIST_HEAD (&rt->rt_list); - spin_lock (&cq->list_lock); - list_add (&rt->rt_list, &cq->run_tasks); - cq->task_count++; - if (cq->task_count > cq->task_max) - cq->task_max = cq->task_count; - spin_unlock (&cq->list_lock); - wake_up (&cq->waiter); - return 0; -} - -/** - * stop_callback_qu - stop the handler thread - */ -void -stop_callback_qu (callback_qu_t * cq) -{ - struct list_head *lltmp, *tmp; - runtask_t *rt; - - if (cq->running) { - cq->running = FALSE; - /* make sure all thread stop. - * */ - while (atomic_read (&cq->num_threads) > 0) { - wake_up (&cq->waiter); - wait_for_completion (&cq->startup); - } - /* clear out any left overs. */ - list_for_each_safe (tmp, lltmp, &cq->run_tasks) { - rt = list_entry (tmp, runtask_t, rt_list); - list_del (tmp); - kfree (rt); - } - } -} - -/** - * start_callback_qu - - * - * Returns: <0:Error, >=0:Ok - */ -int -start_callback_qu (callback_qu_t * cq, int cnt) -{ - int err; - INIT_LIST_HEAD (&cq->run_tasks); - spin_lock_init (&cq->list_lock); - init_completion (&cq->startup); - init_waitqueue_head (&cq->waiter); - atomic_set (&cq->num_threads, 0); - cq->running = TRUE; - cq->task_count = 0; - cq->task_max = 0; - if (cnt <= 0) - cnt = 2; - for (; cnt > 0; cnt--) { - err = kernel_thread (handler, cq, 0); - if (err < 0) { - stop_callback_qu (cq); - /* calling stop here might not behave correctly in all error - * cases. - */ - return err; - } - wait_for_completion (&cq->startup); - } - return 0; -} diff --git a/gfs-kernel/src/gulm/handler.h b/gfs-kernel/src/gulm/handler.h deleted file mode 100644 index 9a9bc7c..0000000 --- a/gfs-kernel/src/gulm/handler.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __handler_c__ -#define __handler_c__ -#include <linux/lm_interface.h> - -struct callback_qu_s { - struct completion startup; - int running; - int task_count; - int task_max; - struct list_head run_tasks; - spinlock_t list_lock; - wait_queue_head_t waiter; - atomic_t num_threads; -}; -typedef struct callback_qu_s callback_qu_t; - -/* kinda an excess overloading */ -typedef void (*gulm_fn) (void *); -int qu_function_call (callback_qu_t * cq, gulm_fn fn, void *data); - -int qu_async_rpl (callback_qu_t * cq, lm_callback_t cb, lm_fsdata_t * fsdata, - struct lm_lockname *lockname, int result); -int qu_drop_req (callback_qu_t * cq, lm_callback_t cb, lm_fsdata_t * fsdata, - int type, uint8_t lmtype, uint64_t lmnum); -int start_callback_qu (callback_qu_t * cq, int cnt); -void stop_callback_qu (callback_qu_t * cq); -void display_handler_queue (callback_qu_t * cq); - -#endif /*__handler_c__*/ diff --git a/gfs-kernel/src/gulm/lg_core.c b/gfs-kernel/src/gulm/lg_core.c deleted file mode 100644 index 19ab5fd..0000000 --- a/gfs-kernel/src/gulm/lg_core.c +++ /dev/null @@ -1,669 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* All of the core related functions for services are here. */ - -#include "lg_priv.h" - -/** - * lg_core_selector - - * @ulm_interface_p: - * - * - * Returns: int - */ -xdr_socket -lg_core_selector (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - /* make sure it is a gulm_interface_p. */ - if (lg == NULL || lg->first_magic != LGMAGIC - || lg->last_magic != LGMAGIC) -#ifdef __KERNEL__ - return NULL; -#else - return -EINVAL; -#endif - - return lg->core_fd; -} - -/** - * lg_core_handle_messages - - * @ulm_interface_p: - * @lg_core_callbacks_t: - * - * - * Returns: int - */ -int -lg_core_handle_messages (gulm_interface_p lgp, lg_core_callbacks_t * ccbp, - void *misc) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_dec_t *dec; - int err = 0; - uint64_t x_gen; - uint32_t x_code, x_error, x_rank; - struct in6_addr x_ip; - uint8_t x_state, x_mode; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_enc == NULL || lg->core_dec == NULL) - return -EBADR; - - down (&lg->core_recver); - if (lg->in_core_hm) - return -EDEADLK; - lg->in_core_hm = TRUE; - up (&lg->core_recver); - - dec = lg->core_dec; - - err = xdr_dec_uint32 (dec, &x_code); - if (err != 0) - goto exit; - - if (gulm_core_login_rpl == x_code) { - do { - if ((err = xdr_dec_uint64 (dec, &x_gen)) < 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_error)) < 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_rank)) < 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) < 0) - break; - } while (0); - if (err != 0) - goto exit; - if (ccbp->login_reply == NULL) { - err = 0; - goto exit; - } - err = ccbp->login_reply (misc, x_gen, x_error, x_rank, x_state); - goto exit; - } else if (gulm_core_logout_rpl == x_code) { - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - goto exit; - if (ccbp->logout_reply != NULL) { - err = ccbp->logout_reply (misc); - } - - xdr_close (&lg->core_fd); - xdr_enc_release (lg->core_enc); - lg->core_enc = NULL; - xdr_dec_release (lg->core_dec); - lg->core_dec = NULL; - - goto exit; - } else if (gulm_core_mbr_lstrpl == x_code) { - if (ccbp->nodelist != NULL) { - err = ccbp->nodelist (misc, lglcb_start, NULL, 0, 0); - if (err != 0) - goto exit; - } - do { - if ((err = xdr_dec_list_start (dec)) != 0) - break; - while (xdr_dec_list_stop (dec) != 0) { - if ((err = - xdr_dec_string_ag (dec, &lg->cfba, - &lg->cfba_len)) != 0) - break; - if ((err = xdr_dec_ipv6 (dec, &x_ip)) != 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_mode)) != 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_mode)) != 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_rank)) != 0) - break; - if ((err = xdr_dec_uint64 (dec, &x_gen)) != 0) - break; - if ((err = xdr_dec_uint64 (dec, &x_gen)) != 0) - break; - if ((err = xdr_dec_uint64 (dec, &x_gen)) != 0) - break; - - if (ccbp->nodelist != NULL) { - err = - ccbp->nodelist (misc, lglcb_item, - lg->cfba, &x_ip, - x_state); - if (err != 0) - goto exit; - } - - } - } while (0); - if (err != 0) { - goto exit; - } - if (ccbp->nodelist == NULL) { - err = 0; - goto exit; - } - err = ccbp->nodelist (misc, lglcb_stop, NULL, 0, 0); - goto exit; - } else if (gulm_core_state_chgs == x_code) { - do { - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_mode)) != 0) - break; - if (x_state == gio_Mbr_ama_Slave) { - if ((err = xdr_dec_ipv6 (dec, &x_ip)) != 0) - break; - if ((err = - xdr_dec_string_ag (dec, &lg->cfba, - &lg->cfba_len)) != 0) - break; - } - } while (0); - if (err != 0) { - goto exit; - } - if (ccbp->statechange == NULL) { - err = 0; - goto exit; - } - err = ccbp->statechange (misc, x_state, x_mode, &x_ip, lg->cfba); - goto exit; - } else if (gulm_core_mbr_updt == x_code) { - do { - if ((err = - xdr_dec_string_ag (dec, &lg->cfba, - &lg->cfba_len)) != 0) - break; - if ((err = xdr_dec_ipv6 (dec, &x_ip)) != 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - } while (0); - if (err != 0) { - goto exit; - } - if (ccbp->nodechange == NULL) { - err = 0; - goto exit; - } - err = ccbp->nodechange (misc, lg->cfba, &x_ip, x_state); - goto exit; - } else if (gulm_core_res_list == x_code) { - if (ccbp->service_list != NULL) { - if ((err = - ccbp->service_list (misc, lglcb_start, NULL)) != 0) - goto exit; - } - do { - if ((err = xdr_dec_list_start (dec)) != 0) - break; - while (xdr_dec_list_stop (dec)) { - if ((err = - xdr_dec_string_ag (dec, &lg->cfba, - &lg->cfba_len)) != 0) - break; - if (ccbp->service_list != NULL) { - if ((err = - ccbp->service_list (misc, - lglcb_item, - lg->cfba)) != - 0) { - goto exit; - } - } - } - } while (0); - if (err != 0) { - goto exit; - } - if (ccbp->service_list == NULL) { - err = 0; - goto exit; - } - err = ccbp->service_list (misc, lglcb_stop, NULL); - goto exit; - } else if (gulm_info_stats_rpl == x_code) { - do { - if ((err = xdr_dec_list_start (dec)) != 0) - break; - while (xdr_dec_list_stop (dec) != 0) { - if ((err = - xdr_dec_string_ag (dec, &lg->cfba, - &lg->cfba_len)) != 0) - break; - if ((err = - xdr_dec_string_ag (dec, &lg->cfbb, - &lg->cfbb_len)) != 0) - break; - } - } while (0); - goto exit; - } else if (gulm_err_reply == x_code) { - if ((err = xdr_dec_uint32 (dec, &x_code)) != 0) - goto exit; - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - goto exit; - if (ccbp->error == NULL) { - err = 0; - goto exit; - } - err = ccbp->error (misc, x_error); - goto exit; - } else { - /* unknown code. what to do? */ - err = -EPROTO; - goto exit; - } - - exit: - lg->in_core_hm = FALSE; - return err; -} - -/** - * lg_core_login - - * @lgp: - * @important: - * - * On any error, things are closed and released to the state of things - * before you called login. - * - * Returns: int - */ -int -lg_core_login (gulm_interface_p lgp, int important) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct sockaddr_in6 adr; - int err; - xdr_socket cfd; - xdr_enc_t *enc; - xdr_dec_t *dec; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - adr.sin6_family = AF_INET6; - adr.sin6_addr = lg_in6addr_loopback; - adr.sin6_port = htons (lg->core_port); - - if ((err = xdr_open (&cfd)) < 0) { - return err; - } - - if ((err = xdr_connect (&adr, cfd)) < 0) { - xdr_close (&cfd); - return err; - } - - enc = xdr_enc_init (cfd, 128); - if (enc == NULL) { - xdr_close (&cfd); - return -ENOMEM; - } - - dec = xdr_dec_init (cfd, 128); - if (enc == NULL) { - xdr_enc_release (enc); - xdr_close (&cfd); - return -ENOMEM; - } - - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_reslgn_req)) < 0) - break; - if ((err = xdr_enc_uint32 (enc, GIO_WIREPROT_VERS)) < 0) - break; - if ((err = xdr_enc_string (enc, lg->clusterID)) < 0) - break; - if ((err = xdr_enc_string (enc, lg->service_name)) < 0) - break; - if ((err = xdr_enc_uint32 (enc, gulm_svc_opt_locked | - gulm_svc_opt_important)) != 0) - break; - if ((err = xdr_enc_flush (enc)) < 0) - break; - } while (0); - if (err != 0) { - xdr_dec_release (dec); - xdr_enc_release (enc); - xdr_close (&cfd); - return err; - } - - down (&lg->core_sender); - lg->core_fd = cfd; - lg->core_enc = enc; - lg->core_dec = dec; - up (&lg->core_sender); - - return 0; -} - -/** - * lg_core_logout - - * @lgp: - * - * - * Returns: int - */ -int -lg_core_logout (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_logout_req)) != 0) - break; - if ((err = xdr_enc_string (enc, lg->service_name)) != 0) - break; - if ((err = xdr_enc_uint8 (enc, gio_Mbr_ama_Resource)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_nodeinfo - - * @lgp: - * @nodename: - * - * - * Returns: int - */ -int -lg_core_nodeinfo (gulm_interface_p lgp, char *nodename) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - if (nodename == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_mbr_req)) != 0) - break; - if ((err = xdr_enc_string (enc, nodename)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_nodelist - - * @lgp: - * - * - * Returns: int - */ -int -lg_core_nodelist (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_mbr_lstreq)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_servicelist - - * @lgp: - * - * - * Returns: int - */ -int -lg_core_servicelist (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_res_req)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_corestate - - * @lgp: - * - * - * Returns: int - */ -int -lg_core_corestate (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_state_req)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_shutdown - - * @lgp: - * - * - * Returns: int - */ -int -lg_core_shutdown (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_shutdown)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_forceexpire - - * @lgp: - * @node_name: - * - * - * Returns: int - */ -int -lg_core_forceexpire (gulm_interface_p lgp, char *nodename) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - if (nodename == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_mbr_force)) != 0) - break; - if ((err = xdr_enc_string (enc, nodename)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/** - * lg_core_forcepending - - * @lgp: - * - * - * Returns: int - */ -int -lg_core_forcepending (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - down (&lg->core_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_core_forcepend)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->core_sender); - return err; -} - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/lg_lock.c b/gfs-kernel/src/gulm/lg_lock.c deleted file mode 100644 index fc80846..0000000 --- a/gfs-kernel/src/gulm/lg_lock.c +++ /dev/null @@ -1,785 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* all of the lock related fucntion are here. */ -#include "lg_priv.h" - -/** - * lg_lock_selector - - * @ulm_interface_p: - * - * - * Returns: int - */ -xdr_socket -lg_lock_selector (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - /* make sure it is a gulm_interface_p. */ - if (lg == NULL || lg->first_magic != LGMAGIC - || lg->last_magic != LGMAGIC) -#ifdef __KERNEL__ - return NULL; -#else - return -EINVAL; -#endif - - return lg->lock_fd; -} - -/** - * lg_lock_handle_messages - - * @ulm_interface_p: - * @lg_lockspace_callbacks_t: - * - * Returns: int - */ -int -lg_lock_handle_messages (gulm_interface_p lgp, lg_lockspace_callbacks_t * cbp, - void *misc) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_dec_t *dec; - int err = 0; - uint64_t x_subid, x_start, x_stop; - uint32_t x_code, x_error, x_flags; - uint16_t x_keylen, x_lvblen = 0; - uint8_t x_state; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->core_enc == NULL || lg->core_dec == NULL) - return -EBADR; - - down (&lg->lock_recver); - if (lg->in_lock_hm) - return -EDEADLK; - lg->in_lock_hm = TRUE; - up (&lg->lock_recver); - - dec = lg->lock_dec; - - err = xdr_dec_uint32 (dec, &x_code); - if (err != 0) - goto exit; - - if (gulm_lock_login_rpl == x_code) { - do { - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - } while (0); - if (err != 0) - goto exit; - if (cbp->login_reply == NULL) { - err = 0; - goto exit; - } - err = cbp->login_reply (misc, x_error, x_state); - goto exit; - } else if (gulm_lock_logout_rpl == x_code) { - if (cbp->logout_reply != NULL) { - err = cbp->logout_reply (misc); - } - - xdr_close (&lg->lock_fd); - xdr_enc_release (lg->lock_enc); - lg->lock_enc = NULL; - xdr_dec_release (lg->lock_dec); - lg->lock_dec = NULL; - - goto exit; - } else if (gulm_lock_state_rpl == x_code) { - do { - if ((err = - xdr_dec_raw_ag (dec, (void **) &lg->lfba, - &lg->lfba_len, &x_keylen)) != 0) - break; - if ((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) - break; - if ((err = xdr_dec_uint64(dec, &x_start)) != 0 ) - break; - if ((err = xdr_dec_uint64(dec, &x_stop)) != 0 ) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_flags)) != 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - break; - if (x_flags & gio_lck_fg_hasLVB) { - if ((err = - xdr_dec_raw_ag (dec, (void **) &lg->lfbb, - &lg->lfbb_len, - &x_lvblen)) != 0) - break; - } - } while (0); - if (err != 0) { - goto exit; - } - if (x_keylen <= 4) { - err = -EPROTO; /* or something */ - goto exit; - } - if (cbp->lock_state == NULL) { - err = 0; - goto exit; - } - err = cbp->lock_state (misc, &lg->lfba[4], x_keylen - 4, - x_subid, x_start, x_stop, - x_state, x_flags, x_error, - lg->lfbb, x_lvblen); - goto exit; - } else if (gulm_lock_action_rpl == x_code) { - do { - if ((err = - xdr_dec_raw_ag (dec, (void **) &lg->lfba, - &lg->lfba_len, &x_keylen)) != 0) - break; - if ((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - break; - } while (0); - if (err != 0) { - goto exit; - } - if (x_keylen <= 4) { - err = -EPROTO; /* or something */ - goto exit; - } - if (cbp->lock_action == NULL) { - err = 0; - goto exit; - } - err = - cbp->lock_action (misc, &lg->lfba[4], x_keylen - 4, - x_subid, x_state, x_error); - goto exit; - } else if (gulm_lock_query_rpl == x_code) { - uint64_t x_c_subid=0, x_c_start=0, x_c_stop=0; - uint8_t x_c_state=0; - do { - if ((err = - xdr_dec_raw_ag (dec, (void **) &lg->lfba, - &lg->lfba_len, &x_keylen)) != 0) - break; - if ((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) - break; - if ((err = xdr_dec_uint64(dec, &x_start)) != 0 ) - break; - if ((err = xdr_dec_uint64(dec, &x_stop)) != 0 ) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - break; - /* i realize that I'm pretty much ignoring the fact that - * this is can be a list of items. As of current, there - * is never more than one item on this list. - * I think I made it a list so it could be in the future, - * even though I cannot think of why. - */ - if ((err = xdr_dec_list_start(dec)) != 0) - break; - while (xdr_dec_list_stop(dec) != 0) { - if((err = xdr_dec_string_ag(dec, &lg->lfbb, &lg->lfbb_len)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_c_subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &x_c_start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &x_c_stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_c_state)) != 0) break; - } - } while (0); - if (err != 0) { - goto exit; - } - if (x_keylen <= 4) { - err = -EPROTO; /* or something */ - goto exit; - } - if (cbp->lock_query == NULL) { - err = 0; - goto exit; - } - err = cbp->lock_query (misc, &lg->lfba[4], x_keylen - 4, - x_subid, x_start, x_stop, x_state, - x_error, lg->lfbb, x_c_subid, - x_c_start, x_c_stop, x_c_state); - goto exit; - } else if (gulm_lock_cb_state == x_code) { - do { - if ((err = - xdr_dec_raw_ag (dec, (void **) &lg->lfba, - &lg->lfba_len, &x_keylen)) != 0) - break; - if ((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) - break; - if ((err = xdr_dec_uint8 (dec, &x_state)) != 0) - break; - } while (0); - if (err != 0) { - goto exit; - } - if (cbp->drop_lock_req == NULL) { - err = 0; - goto exit; - } - err = - cbp->drop_lock_req (misc, &lg->lfba[4], x_keylen - 4, - x_subid, x_state); - goto exit; - } else if (gulm_lock_cb_dropall == x_code) { - if (cbp->drop_all == NULL) { - err = 0; - goto exit; - } - err = cbp->drop_all (misc); - goto exit; - } else if (gulm_info_stats_rpl == x_code) { - do { - if ((err = xdr_dec_list_start (dec)) != 0) - break; - while (xdr_dec_list_stop (dec) != 0) { - if ((err = - xdr_dec_string_ag (dec, &lg->lfba, - &lg->lfba_len)) != 0) - break; - if ((err = - xdr_dec_string_ag (dec, &lg->lfbb, - &lg->lfbb_len)) != 0) - break; - } - } while (0); - goto exit; - } else if (gulm_err_reply == x_code) { - do { - if ((err = xdr_dec_uint32 (dec, &x_code)) != 0) - break; - if ((err = xdr_dec_uint32 (dec, &x_error)) != 0) - break; - } while (0); - if (err != 0) - goto exit; - if (cbp->error == NULL) { - err = 0; - goto exit; - } - err = cbp->error (misc, x_error); - goto exit; - } else { - err = -EPROTO; - goto exit; - } - - exit: - lg->in_lock_hm = FALSE; - return err; -} - -/** - * lg_lock_login - - * @ulm_interface_p: - * @4: - * - * - * Returns: int - */ -int -lg_lock_login (gulm_interface_p lgp, uint8_t lockspace[4]) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct sockaddr_in6 adr; - int err; - xdr_socket cfd; - xdr_enc_t *enc; - xdr_dec_t *dec; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - adr.sin6_family = AF_INET6; - adr.sin6_addr = lg_in6addr_loopback; - adr.sin6_port = htons (lg->lock_port); - - if ((err = xdr_open (&cfd)) < 0) { - return err; - } - - if ((err = xdr_connect (&adr, cfd)) < 0) { - xdr_close (&cfd); - return err; - } - - enc = xdr_enc_init (cfd, 512); - if (enc == NULL) { - xdr_close (&cfd); - return -ENOMEM; - } - - dec = xdr_dec_init (cfd, 512); - if (enc == NULL) { - xdr_enc_release (enc); - xdr_close (&cfd); - return -ENOMEM; - } - - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_login_req)) < 0) - break; - if ((err = xdr_enc_uint32 (enc, GIO_WIREPROT_VERS)) < 0) - break; - if ((err = xdr_enc_string (enc, lg->service_name)) < 0) - break; - if ((err = xdr_enc_uint8 (enc, gio_lck_st_Client)) < 0) - break; - if ((err = xdr_enc_flush (enc)) < 0) - break; - - if ((err = xdr_enc_uint32 (enc, gulm_lock_sel_lckspc)) < 0) - break; - if ((err = xdr_enc_raw (enc, lockspace, 4)) < 0) - break; - /* don't flush here. - * dumb programmer stunt. This way, the lockspace selection won't - * happen until the next thing the user of this lib sends. Which - * means it will be after we have received the login reply. - * - * Is there really a good reason not to flush here? - */ - } while (0); - if (err != 0) { - xdr_dec_release (dec); - xdr_enc_release (enc); - xdr_close (&cfd); - return err; - } - - down (&lg->lock_sender); - lg->lock_fd = cfd; - lg->lock_enc = enc; - lg->lock_dec = dec; - - memcpy (lg->lockspace, lockspace, 4); - up (&lg->lock_sender); - - return 0; -} - -/** - * lg_lock_logout - - * @ulm_interface_p: - * - * - * Returns: int - */ -int -lg_lock_logout (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - down (&lg->lock_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_logout_req)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->lock_sender); - return err; -} - -/** - * lg_lock_state_req - - * @lgp: - * @key: - * @keylen: - * @state: - * @flags: - * @LVB: - * @LVBlen: - * - * - * Returns: int - */ -int -lg_lock_state_req (gulm_interface_p lgp, uint8_t * key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint8_t * LVB, - uint16_t LVBlen) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - uint32_t iflgs = 0; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - if (state != lg_lock_state_Unlock && - state != lg_lock_state_Exclusive && - state != lg_lock_state_Deferred && state != lg_lock_state_Shared) - return -EINVAL; - - /* make sure only the accepted flags get passed through. */ - if ((flags & lg_lock_flag_DoCB) == lg_lock_flag_DoCB) - iflgs |= lg_lock_flag_DoCB; - if ((flags & lg_lock_flag_Try) == lg_lock_flag_Try) - iflgs |= lg_lock_flag_Try; - if ((flags & lg_lock_flag_Any) == lg_lock_flag_Any) - iflgs |= lg_lock_flag_Any; - if ((flags & lg_lock_flag_IgnoreExp) == lg_lock_flag_IgnoreExp) - iflgs |= lg_lock_flag_IgnoreExp; - if ((flags & lg_lock_flag_Piority) == lg_lock_flag_Piority) - iflgs |= lg_lock_flag_Piority; - - enc = lg->lock_enc; - - if (LVB != NULL && LVBlen > 0) - iflgs |= gio_lck_fg_hasLVB; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - down (&lg->lock_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_state_req)) != 0) - break; - if ((err = xdr_enc_raw_iov (enc, 2, iov)) != 0) - break; - if ((err = xdr_enc_uint64 (enc, subid)) != 0) - break; - if ((err = xdr_enc_uint64 (enc, start)) != 0) - break; - if ((err = xdr_enc_uint64 (enc, stop)) != 0) - break; - if ((err = xdr_enc_uint8 (enc, state)) != 0) - break; - if ((err = xdr_enc_uint32 (enc, iflgs)) != 0) - break; - if (iflgs & gio_lck_fg_hasLVB) - if ((err = xdr_enc_raw (enc, LVB, LVBlen)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->lock_sender); - return err; -} - -/** - * lg_lock_cancel_req - - * @lgp: - * @key: - * @keylen: - * - * - * Returns: int - */ -int -lg_lock_cancel_req (gulm_interface_p lgp, uint8_t * key, uint16_t keylen, - uint64_t subid) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - down (&lg->lock_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_action_req)) != 0) - break; - if ((err = xdr_enc_raw_iov (enc, 2, iov)) != 0) - break; - if ((err = xdr_enc_uint64 (enc, subid)) != 0) - break; - if ((err = xdr_enc_uint8 (enc, gio_lck_st_Cancel)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->lock_sender); - return err; -} - -/** - * lg_lock_action_req - - * @lgp: - * @key: - * @keylen: - * @action: - * @LVB: - * @LVBlen: - * - * XXX - * I wonder if I should actually break this into three seperate calls for - * the lvb stuff. Does it really matter? - * - * Returns: int - */ -int -lg_lock_action_req (gulm_interface_p lgp, uint8_t * key, uint16_t keylen, - uint64_t subid, uint8_t action, uint8_t * LVB, - uint16_t LVBlen) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - if (action != lg_lock_act_HoldLVB && - action != lg_lock_act_UnHoldLVB && action != lg_lock_act_SyncLVB) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - down (&lg->lock_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_action_req)) != 0) - break; - if ((err = xdr_enc_raw_iov (enc, 2, iov)) != 0) - break; - if ((err = xdr_enc_uint64 (enc, subid)) != 0) - break; - if ((err = xdr_enc_uint8 (enc, action)) != 0) - break; - if (action == gio_lck_st_SyncLVB) - if ((err = xdr_enc_raw (enc, LVB, LVBlen)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->lock_sender); - return err; -} - -/** - * lg_lock_query_req - - * @lgp: - * @key: - * @keylen: - * @subid: - * @start: - * @stop: - * @state: - * - * - * Returns: int - */ -int lg_lock_query_req(gulm_interface_p lgp, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, uint8_t state) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - if( state != lg_lock_state_Unlock && - state != lg_lock_state_Exclusive && - state != lg_lock_state_Deferred && - state != lg_lock_state_Shared ) - return -EINVAL; - - if( stop < start ) return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - down (&lg->lock_sender); - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_query_req)) != 0 ) break; - if((err = xdr_enc_raw_iov(enc, 2, iov)) != 0 ) break; - if((err = xdr_enc_uint64(enc, subid)) != 0) break; - if((err = xdr_enc_uint64(enc, start)) != 0) break; - if((err = xdr_enc_uint64(enc, stop)) != 0) break; - if((err = xdr_enc_uint8(enc, state)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - up (&lg->lock_sender); - return err; -} - -/** - * lg_lock_drop_exp - - * @ulm_interface_p: - * @holder: - * @keymask: - * @kmlen: - * - * holder is the node name of the expired holder that you want to clear. - * Only locks matching the keymask will be looked at. (most of the time you - * will just set key to a bunch of 0xff to match all) The keymask lets you - * basically subdivide your lockspace into smaller seperate parts. - * (example, there is one gfs lockspace, but each filesystem gets its own - * subpart of that larger space) - * - * If holder is NULL, all expired holders in your lockspace will get - * dropped. - * - * Returns: int - */ -int -lg_lock_drop_exp (gulm_interface_p lgp, uint8_t * holder, uint8_t * key, - uint16_t keylen) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = (key != NULL) ? keylen : 0; - - down (&lg->lock_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_drop_exp)) != 0) - break; - if ((err = xdr_enc_string (enc, holder)) != 0) - break; - if ((err = xdr_enc_raw_iov (enc, 2, iov)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->lock_sender); - return err; -} - -int -lg_lock_expire (gulm_interface_p lgp, uint8_t * holder, uint8_t * key, - uint16_t keylen) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if (lg == NULL) - return -EINVAL; - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - if (lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = (key != NULL) ? keylen : 0; - - down (&lg->lock_sender); - do { - if ((err = xdr_enc_uint32 (enc, gulm_lock_expire)) != 0) - break; - if ((err = xdr_enc_string (enc, holder)) != 0) - break; - if ((err = xdr_enc_raw_iov (enc, 2, iov)) != 0) - break; - if ((err = xdr_enc_flush (enc)) != 0) - break; - } while (0); - up (&lg->lock_sender); - return err; -} - -/* vim: set ai cin noet sw=8 ts=8 : */ - diff --git a/gfs-kernel/src/gulm/lg_main.c b/gfs-kernel/src/gulm/lg_main.c deleted file mode 100644 index ff9b566..0000000 --- a/gfs-kernel/src/gulm/lg_main.c +++ /dev/null @@ -1,211 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* This is where all of the library specific functions exist. - * Not many, but keeps things clean. - */ - -#include "lg_priv.h" -#include "gulm.h" -extern gulm_cm_t gulm_cm; - -const struct in6_addr lg_in6addr_loopback = IN6ADDR_LOOPBACK_INIT; - -/** - * lg_initialize - - * @gulm_interface_p: - * @cluster_name: - * @service_name: - * - * if returning an error, nothing was done to the value of gulm_interface_p - * - * Returns: gulm_interface_p - */ -int -lg_initialize (gulm_interface_p * ret, char *cluster_name, char *service_name) -{ - gulm_interface_t *lg; - int err, len; - - lg = kmalloc (sizeof (gulm_interface_t), GFP_KERNEL); - if (lg == NULL) - return -ENOMEM; - - memset (lg, 0, sizeof (gulm_interface_t)); - lg->first_magic = LGMAGIC; - lg->last_magic = LGMAGIC; - - if (cluster_name == NULL) - cluster_name = "cluster"; - len = strlen (cluster_name) + 1; - lg->clusterID = kmalloc (len, GFP_KERNEL); - if (lg->clusterID == NULL) { - err = -ENOMEM; - goto fail_nomem; - } - memcpy (lg->clusterID, cluster_name, len); - - len = strlen (service_name) + 1; - lg->service_name = kmalloc (len, GFP_KERNEL); - if (lg->service_name == NULL) { - err = -ENOMEM; - goto fail_nomem; - } - memcpy (lg->service_name, service_name, len); - - /* set up flutter bufs. */ - lg->cfba_len = 64; - lg->cfba = kmalloc (lg->cfba_len, GFP_KERNEL); - if (lg->cfba == NULL) { - err = -ENOMEM; - goto fail_nomem; - } - - lg->cfbb_len = 64; - lg->cfbb = kmalloc (lg->cfbb_len, GFP_KERNEL); - if (lg->cfbb == NULL) { - err = -ENOMEM; - goto fail_nomem; - } - - lg->lfba_len = 128; - lg->lfba = kmalloc (lg->lfba_len, GFP_KERNEL); - if (lg->lfba == NULL) { - err = -ENOMEM; - goto fail_nomem; - } - - lg->lfbb_len = 128; - lg->lfbb = kmalloc (lg->lfbb_len, GFP_KERNEL); - if (lg->lfbb == NULL) { - err = -ENOMEM; - goto fail_nomem; - } - - /* setup mutexes */ - init_MUTEX (&lg->core_sender); - init_MUTEX (&lg->core_recver); - init_MUTEX (&lg->lock_sender); - init_MUTEX (&lg->lock_recver); - - lg->core_port = 40040; - lg->lock_port = 40042; - - *ret = lg; - return 0; - fail_nomem: - if (lg->clusterID != NULL) - kfree (lg->clusterID); - if (lg->service_name != NULL) - kfree (lg->service_name); - if (lg->cfba != NULL) - kfree (lg->cfba); - if (lg->cfbb != NULL) - kfree (lg->cfbb); - if (lg->lfba != NULL) - kfree (lg->lfba); - if (lg->lfbb != NULL) - kfree (lg->lfbb); - kfree (lg); - return err; -} - -/** - * lg_release - - * @lg: - * - */ -void -lg_release (gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - if (lgp == NULL) - return; - /* make sure it is a gulm_interface_p. */ - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return; - - if (lg->service_name != NULL) - kfree (lg->service_name); - if (lg->clusterID != NULL) - kfree (lg->clusterID); - - /* wonder if I should send a logout packet? */ - if (lg->core_enc != NULL) - xdr_enc_release (lg->core_enc); - if (lg->core_dec != NULL) - xdr_dec_release (lg->core_dec); - xdr_close (&lg->core_fd); - - if (lg->lock_enc != NULL) - xdr_enc_release (lg->lock_enc); - if (lg->lock_dec != NULL) - xdr_dec_release (lg->lock_dec); - xdr_close (&lg->lock_fd); - - if (lg->cfba != NULL) - kfree (lg->cfba); - if (lg->cfbb != NULL) - kfree (lg->cfbb); - if (lg->lfba != NULL) - kfree (lg->lfba); - if (lg->lfbb != NULL) - kfree (lg->lfbb); - - kfree (lg); -} - -/** - * lg_set_core_port - - * @lgp: - * @new: - * - * - * Returns: int - */ -int -lg_set_core_port (gulm_interface_p lgp, uint16_t new) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - if (lgp == NULL) - return -EINVAL; - /* make sure it is a gulm_interface_p. */ - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - lg->core_port = new; - return 0; -} - -/** - * lg_set_ltpx_port - - * @lgp: - * @new: - * - * - * Returns: int - */ -int -lg_set_lock_port (gulm_interface_p lgp, uint16_t new) -{ - gulm_interface_t *lg = (gulm_interface_t *) lgp; - if (lgp == NULL) - return -EINVAL; - /* make sure it is a gulm_interface_p. */ - if (lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC) - return -EINVAL; - - lg->lock_port = new; - - return 0; -} diff --git a/gfs-kernel/src/gulm/lg_priv.h b/gfs-kernel/src/gulm/lg_priv.h deleted file mode 100644 index ee10f62..0000000 --- a/gfs-kernel/src/gulm/lg_priv.h +++ /dev/null @@ -1,88 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __lg_priv_h__ -#define __lg_priv_h__ -/* private details that we don't want to give the users of this lib access - * to go here. - */ - -#ifdef __linux__ -#include <linux/kernel.h> -#include <linux/sched.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> -#endif /*__linux__*/ - -#include "xdr.h" -#include "gio_wiretypes.h" -#include "libgulm.h" - -#define LGMAGIC (0x474d4354) - -struct gulm_interface_s { - /* since we've masked this to a void* to the users, it is a nice safty - * net to put a little magic in here so we know things stay good. - */ - uint32_t first_magic; - - /* WHAT IS YOUR NAME?!? */ - char *service_name; - - char *clusterID; - - uint16_t core_port; - xdr_socket core_fd; - xdr_enc_t *core_enc; - xdr_dec_t *core_dec; - struct semaphore core_sender; - struct semaphore core_recver; - int in_core_hm; - - uint16_t lock_port; - xdr_socket lock_fd; - xdr_enc_t *lock_enc; - xdr_dec_t *lock_dec; - struct semaphore lock_sender; - struct semaphore lock_recver; - int in_lock_hm; - uint8_t lockspace[4]; - - /* in the message recver func, we read data into these buffers and pass - * them to the callback function. This way we avoid doinf mallocs and - * frees on every callback. - */ - uint16_t cfba_len; - uint8_t *cfba; - uint16_t cfbb_len; - uint8_t *cfbb; - uint16_t lfba_len; - uint8_t *lfba; - uint16_t lfbb_len; - uint8_t *lfbb; - - uint32_t last_magic; -}; -typedef struct gulm_interface_s gulm_interface_t; - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -extern const struct in6_addr lg_in6addr_loopback; - -#endif /*__lg_priv_h__*/ diff --git a/gfs-kernel/src/gulm/libgulm.h b/gfs-kernel/src/gulm/libgulm.h deleted file mode 100644 index 8996e72..0000000 --- a/gfs-kernel/src/gulm/libgulm.h +++ /dev/null @@ -1,199 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __libgulm_h__ -#define __libgulm_h__ - -/* bit messy, but we need this to be rather seemless in both kernel and - * userspace. and this seems the easiest way to do it. - */ - -#ifdef __linux__ -#include <linux/in6.h> -typedef struct socket *lg_socket; -#endif /*__linux__*/ - -typedef void *gulm_interface_p; - -/* mallocs the interface structure. - */ -int lg_initialize (gulm_interface_p *, char *cluster_name, char *service_name); -/* frees struct. - */ -void lg_release (gulm_interface_p); - -/* Determins where we are with a itemlist callback */ -typedef enum { lglcb_start, lglcb_item, lglcb_stop } lglcb_t; - -/****** Core specifics ******/ - -/* leaving a callback pointer as NULL, will cause that message type to - * be ignored. */ -typedef struct lg_core_callbacks_s { - int (*login_reply) (void *misc, uint64_t gen, uint32_t error, - uint32_t rank, uint8_t corestate); - int (*logout_reply) (void *misc); - int (*nodelist) (void *misc, lglcb_t type, char *name, - struct in6_addr * ip, uint8_t state); - int (*statechange) (void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr * masterip, char *mastername); - int (*nodechange) (void *misc, char *nodename, - struct in6_addr * nodeip, uint8_t nodestate); - int (*service_list) (void *misc, lglcb_t type, char *service); - int (*error) (void *misc, uint32_t err); -} lg_core_callbacks_t; - -/* this will trigger a callback from gulm_core_callbacks_t - * handles one message! Either stick this inside of a thread, - * or in a poll()/select() loop using the function below. - * This will block until there is a message sent from core. - */ -int lg_core_handle_messages (gulm_interface_p, lg_core_callbacks_t *, - void *misc); - -/* this returns the filedescriptor that the library is using to - * communicate with the core. This is only for using in a poll() - * or select() call to avoid having the gulm_core_handle_messages() - * call block. - */ -lg_socket lg_core_selector (gulm_interface_p); - -/* Queue requests. */ -int lg_core_login (gulm_interface_p, int important); -int lg_core_logout (gulm_interface_p); -int lg_core_nodeinfo (gulm_interface_p, char *nodename); -int lg_core_nodelist (gulm_interface_p); -int lg_core_servicelist (gulm_interface_p); -int lg_core_corestate (gulm_interface_p); - -/* for completeness mostly. */ -int lg_core_shutdown (gulm_interface_p); -int lg_core_forceexpire (gulm_interface_p, char *node_name); -int lg_core_forcepending (gulm_interface_p); - -/* Node states - * First three are actual states, as well as changes. Last is only a node - * change message. - * */ -#define lg_core_Logged_in (0x05) -#define lg_core_Logged_out (0x06) -#define lg_core_Expired (0x07) -#define lg_core_Fenced (0x08) -/* Core states */ -#define lg_core_Slave (0x01) -#define lg_core_Master (0x02) -#define lg_core_Pending (0x03) -#define lg_core_Arbitrating (0x04) -#define lg_core_Client (0x06) - -/****** lock space specifics *****/ -/* note that this library masks out the lock table seperation. - */ - -typedef struct lg_lockspace_callbacks_s { - int (*login_reply) (void *misc, uint32_t error, uint8_t which); - int (*logout_reply) (void *misc); - int (*lock_state) (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint32_t error, - uint8_t * LVB, uint16_t LVBlen); - int (*lock_action) (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint8_t action, uint32_t error); - int (*drop_lock_req) (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint8_t state); - int (*lock_query) (void *misc, uint8_t * key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t error, uint8_t * cnode, - uint64_t csubid, uint64_t cstart, uint64_t cstop, - uint8_t cstate); - int (*drop_all) (void *misc); - int (*error) (void *misc, uint32_t err); -} lg_lockspace_callbacks_t; - -/* Like the core handle messages function, but for the lockspace. - * Handles one message, blocks. - */ - -int lg_lock_handle_messages (gulm_interface_p, lg_lockspace_callbacks_t *, - void *misc); - -/* this returns the filedescriptor that the library is using to - * communicate with the ltpx. This is only for using in a poll() - * or select() call to avoid having the gulm_lock_handle_messages() - * call block. - */ -lg_socket lg_lock_selector (gulm_interface_p); - -/* Lockspace request calls */ -int lg_lock_login (gulm_interface_p, uint8_t lockspace[4]); -int lg_lock_logout (gulm_interface_p); -int lg_lock_state_req (gulm_interface_p, uint8_t * key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint8_t * LVB, - uint16_t LVBlen); -int lg_lock_cancel_req (gulm_interface_p, uint8_t * key, uint16_t keylen, - uint64_t subid); -int lg_lock_action_req (gulm_interface_p, uint8_t * key, uint16_t keylen, - uint64_t subid, uint8_t action, - uint8_t * LVB, uint16_t LVBlen); -int lg_lock_query_req(gulm_interface_p lgp, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, uint8_t state); -int lg_lock_drop_exp (gulm_interface_p, uint8_t * holder, - uint8_t * keymask, uint16_t kmlen); -int lg_lock_expire (gulm_interface_p lgp, uint8_t * holder, uint8_t * key, - uint16_t keylen); - -/* state requests */ -#define lg_lock_state_Unlock (0x00) -#define lg_lock_state_Exclusive (0x01) -#define lg_lock_state_Deferred (0x02) -#define lg_lock_state_Shared (0x03) - -/* actions */ -#define lg_lock_act_HoldLVB (0x0b) -#define lg_lock_act_UnHoldLVB (0x0c) -#define lg_lock_act_SyncLVB (0x0d) - -/* flags */ -#define lg_lock_flag_DoCB (0x00000001) -#define lg_lock_flag_Try (0x00000002) -#define lg_lock_flag_Any (0x00000004) -#define lg_lock_flag_IgnoreExp (0x00000008) -#define lg_lock_flag_Cachable (0x00000020) -#define lg_lock_flag_Piority (0x00000040) -#define lg_lock_flag_NoCallBacks (0x00000100) - -/* These are the possible values that can be in the error fields. */ -#define lg_err_Ok (0) -#define lg_err_BadLogin (1001) -#define lg_err_BadCluster (1003) -#define lg_err_BadConfig (1004) -#define lg_err_BadGeneration (1005) -#define lg_err_BadWireProto (1019) - -#define lg_err_NotAllowed (1006) -#define lg_err_Unknown_Cs (1007) -#define lg_err_BadStateChg (1008) -#define lg_err_MemoryIssues (1009) - -#define lg_err_TryFailed (1011) -#define lg_err_AlreadyPend (1013) -#define lg_err_Canceled (1015) - -#define lg_err_NoSuchFS (1016) -#define lg_err_NoSuchJID (1017) -#define lg_err_NoSuchName (1018) - -#endif /*__libgulm_h__*/ - -/* vim: set ai cin noet sw=8 ts=8 : */ diff --git a/gfs-kernel/src/gulm/utils_tostr.c b/gfs-kernel/src/gulm/utils_tostr.c deleted file mode 100644 index 1155dd3..0000000 --- a/gfs-kernel/src/gulm/utils_tostr.c +++ /dev/null @@ -1,66 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "gio_wiretypes.h" - -char * -gio_Err_to_str (int x) -{ - char *t = "Unknown GULM Err"; - switch (x) { - case gio_Err_Ok: - t = "Ok"; - break; - - case gio_Err_BadLogin: - t = "Bad Login"; - break; - case gio_Err_BadCluster: - t = "Bad Cluster ID"; - break; - case gio_Err_BadConfig: - t = "Incompatible configurations"; - break; - case gio_Err_BadGeneration: - t = "Bad Generation ID"; - break; - case gio_Err_BadWireProto: - t = "Bad Wire Protocol Version"; - break; - - case gio_Err_NotAllowed: - t = "Not Allowed"; - break; - case gio_Err_Unknown_Cs: - t = "Uknown Client"; - break; - case gio_Err_BadStateChg: - t = "Bad State Change"; - break; - case gio_Err_MemoryIssues: - t = "Memory Problems"; - break; - - case gio_Err_TryFailed: - t = "Try Failed"; - break; - case gio_Err_AlreadyPend: - t = "Request Already Pending"; - break; - case gio_Err_Canceled: - t = "Request Canceled"; - break; - } - return t; -} - diff --git a/gfs-kernel/src/gulm/utils_tostr.h b/gfs-kernel/src/gulm/utils_tostr.h deleted file mode 100644 index 1731edd..0000000 --- a/gfs-kernel/src/gulm/utils_tostr.h +++ /dev/null @@ -1,17 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __utils_tostr_h__ -#define __utils_tostr_h__ -char *gio_Err_to_str (int x); -#endif /*__utils_tostr_h__*/ diff --git a/gfs-kernel/src/gulm/xdr.h b/gfs-kernel/src/gulm/xdr.h deleted file mode 100644 index b3d0189..0000000 --- a/gfs-kernel/src/gulm/xdr.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gulm_xdr_h__ -#define __gulm_xdr_h__ -typedef struct xdr_enc_s xdr_enc_t; -typedef struct xdr_dec_s xdr_dec_t; - -/* sockets in kernel space are done a bit different than socket in - * userspace. But we need to have them appear to be the same. - */ -#ifdef __KERNEL__ - -#ifdef __linux__ -#include <linux/net.h> -#include <linux/in.h> -#include <linux/in6.h> -#include <linux/socket.h> -#include <net/sock.h> - -typedef struct socket *xdr_socket; -#endif /*__linux__*/ -#else /*__KERNEL__*/ -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <unistd.h> -#include <errno.h> -typedef int xdr_socket; -#endif /*__KERNEL__*/ - -/* start things up */ -int xdr_open (xdr_socket * sk); -int xdr_connect (struct sockaddr_in6 *adr, xdr_socket sk); -void xdr_close (xdr_socket * sk); - -/* deep, basic io */ -#ifdef __KERNEL__ -#ifdef __linux__ -size_t xdr_send (struct socket *sock, void *buf, size_t size); -size_t xdr_recv (struct socket *sock, void *buf, size_t size); -#endif /*__linux__*/ -#else /*__KERNEL__*/ -ssize_t xdr_recv (int fd, void *buf, size_t len); -ssize_t xdr_send (int fd, void *buf, size_t len); -#endif /*__KERNEL__*/ - -xdr_enc_t *xdr_enc_init (xdr_socket sk, int buffer_size); -xdr_dec_t *xdr_dec_init (xdr_socket sk, int buffer_size); -int xdr_enc_flush (xdr_enc_t * xdr); -int xdr_enc_release (xdr_enc_t * xdr); /* calls xdr_enc_flush() */ -void xdr_enc_force_release (xdr_enc_t * xdr); /* doesn't call xdr_enc_flush() */ -void xdr_dec_release (xdr_dec_t * xdr); -/* xdr_enc_force_release() is for when you get and error sending and you - * want to free that stuff up right away. If you use the regular release - * for enc, it will fail if it cannot send data over the filedesciptor. - */ - -/* encoders add to a stream */ -int xdr_enc_uint64 (xdr_enc_t * xdr, uint64_t i); -int xdr_enc_uint32 (xdr_enc_t * xdr, uint32_t i); -int xdr_enc_uint16 (xdr_enc_t * xdr, uint16_t i); -int xdr_enc_uint8 (xdr_enc_t * xdr, uint8_t i); -int xdr_enc_ipv6 (xdr_enc_t * enc, struct in6_addr *ip); -int xdr_enc_raw (xdr_enc_t * xdr, void *pointer, uint16_t len); -int xdr_enc_raw_iov (xdr_enc_t * xdr, int count, struct iovec *iov); -int xdr_enc_string (xdr_enc_t * xdr, uint8_t * s); -int xdr_enc_list_start (xdr_enc_t * xdr); -int xdr_enc_list_stop (xdr_enc_t * xdr); - -/* decoders remove from stream */ -int xdr_dec_uint64 (xdr_dec_t * xdr, uint64_t * i); -int xdr_dec_uint32 (xdr_dec_t * xdr, uint32_t * i); -int xdr_dec_uint16 (xdr_dec_t * xdr, uint16_t * i); -int xdr_dec_uint8 (xdr_dec_t * xdr, uint8_t * i); -int xdr_dec_ipv6 (xdr_dec_t * xdr, struct in6_addr *ip); -int xdr_dec_raw (xdr_dec_t * xdr, void *p, uint16_t * l); /* no malloc */ -int xdr_dec_raw_m (xdr_dec_t * xdr, void **p, uint16_t * l); /* mallocs p */ -int xdr_dec_raw_ag (xdr_dec_t * xdr, void **p, uint16_t * bl, uint16_t * rl); -int xdr_dec_string (xdr_dec_t * xdr, uint8_t ** strp); /* mallocs s */ -int xdr_dec_string_nm (xdr_dec_t * xdr, uint8_t * strp, size_t l); /* no malloc */ -int xdr_dec_string_ag (xdr_dec_t * xdr, uint8_t ** s, uint16_t * bl); -int xdr_dec_list_start (xdr_dec_t * xdr); -int xdr_dec_list_stop (xdr_dec_t * xdr); - -#endif /*__gulm_xdr_h__*/ diff --git a/gfs-kernel/src/gulm/xdr_base.c b/gfs-kernel/src/gulm/xdr_base.c deleted file mode 100644 index dd12b29..0000000 --- a/gfs-kernel/src/gulm/xdr_base.c +++ /dev/null @@ -1,907 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * This is a bit of an abstraction layer to get this working in both kernel - * and userspace. - */ -#define TRUE (1) -#define FALSE (0) -#define MIN(a,b) ((a<b)?a:b) - -#ifdef __linux__ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> -#endif /*__linux__*/ - -#include "xdr.h" - -/** - * xdr_realloc - a realloc for kernel space. - * @a: < pointer to realloc - * @nl: < desired new size - * @ol: < current old size - * - * Not as good as the real realloc, since it always moves memory. But good - * enough for as little as it will get used here. - * - * XXX this is broken. - * - * Returns: void* - */ -static void * -xdr_realloc (void *a, size_t nl, size_t ol) -{ - if (nl == ol) { - return a; - } else if (nl == 0) { - kfree (a); - return NULL; - } else if (a == NULL && nl > 0) { - return kmalloc (nl, GFP_KERNEL); - } else { - void *tmp; - tmp = kmalloc (nl, GFP_KERNEL); - if (tmp == NULL) - return NULL; - memcpy (tmp, a, MIN (nl, ol)); - kfree (a); - return tmp; - } -} - -typedef enum { xdr_enc, xdr_dec } xdr_type; - -/* encoders have this sorta non-blocking, growing buffering stunt. - * makes them a bit different from the decoders now. - */ -struct xdr_enc_s { - size_t default_buf_size; - xdr_socket fd; - xdr_type type; - size_t length; - size_t curloc; - uint8_t *stream; -}; - -/* decoders only pull a single item off of the socket at a time. - * so this is all they need. - */ -struct xdr_dec_s { - size_t length; /* total byte length of the stream */ - size_t curloc; /* current byte offset from start */ - uint8_t *stream; /* start of the encoded stream. */ - xdr_socket fd; - xdr_type type; -}; - -/* the types of data we support. */ - -#define XDR_NULL 0x00 /* NOT A VALID TAG!!! used in dec code. */ -#define XDR_LIST_START 0x01 -#define XDR_LIST_STOP 0x02 -/* list is a variable length device. It is a start tag, some number of - * xdr_enc_*, then an stop tag. It's main purpose is to provide a method - * of encasing data. - * */ -#define XDR_STRING 0x04 -/* string tag is followed by a uint16 which is the byte length */ -#define XDR_RAW 0x05 -/* raw tag is followed by a uint16 which is the byte length - * if 65535 bytes isn't enough, split your data and put multiples of these - * back to back. (idea of xdr is to avoid this twit.) - * */ - -/* note, if the size of these should variate, I'm screwed. Should consider - * changing this all to the bit shift and array access to be more concrete. - * later. - */ -#define XDR_UINT64 0x06 -#define XDR_UINT32 0x07 -#define XDR_UINT16 0x08 -#define XDR_UINT8 0x09 -/* should add signed ints */ - -#define XDR_IPv6 0x0a /* 16 bytes, IPv6 address */ - -/* any other base types? - */ - -#define XDR_DEFAULT_BUFFER_SIZE 4096 -/*****************************************************************************/ - -/** - * xdr_enc_init - - * @fd: - * @buffer_size: - * - * - * Returns: xdr_enc_t* - */ -xdr_enc_t * -xdr_enc_init (xdr_socket fd, int buffer_size) -{ - xdr_enc_t *xdr; - - if (buffer_size <= 0) - buffer_size = XDR_DEFAULT_BUFFER_SIZE; - - xdr = kmalloc (sizeof (xdr_enc_t), GFP_KERNEL); - if (xdr == NULL) - return NULL; - xdr->stream = kmalloc (buffer_size, GFP_KERNEL); - if (xdr->stream == NULL) { - kfree (xdr); - return NULL; - } - xdr->fd = fd; - xdr->type = xdr_enc; - xdr->default_buf_size = buffer_size; - xdr->length = buffer_size; - xdr->curloc = 0; - - return xdr; -} - -/** - * xdr_dec_init - - * @fd: - * @buffer_size: - * - * - * Returns: xdr_dec_t* - */ -xdr_dec_t * -xdr_dec_init (xdr_socket fd, int buffer_size) -{ - xdr_dec_t *xdr; - - if (buffer_size <= 0) - buffer_size = XDR_DEFAULT_BUFFER_SIZE; - - xdr = kmalloc (sizeof (xdr_dec_t), GFP_KERNEL); - if (xdr == NULL) - return NULL; - xdr->length = buffer_size; - xdr->curloc = 0; - xdr->stream = kmalloc (buffer_size, GFP_KERNEL); - xdr->fd = fd; - xdr->type = xdr_dec; - if (xdr->stream == NULL) { - kfree (xdr); - return NULL; - } - *(xdr->stream) = XDR_NULL; /* so the first dec_call will call get_next */ - return xdr; -} - -/*****************************************************************************/ -/** - * xdr_enc_flush - - * @xdr: - * - * Returns: int - */ -int -xdr_enc_flush (xdr_enc_t * xdr) -{ - int err; - if (xdr == NULL) - return -EINVAL; - if (xdr->type != xdr_enc) - return -EINVAL; - if (xdr->curloc == 0) - return 0; - - err = xdr_send (xdr->fd, xdr->stream, xdr->curloc); - if (err < 0) - return err; - if (err == 0) - return -EPROTO; /* why? */ - xdr->curloc = 0; - - return 0; -} - -/** - * xdr_release - - * @xdr: - * - * Free the memory, losing whatever may be there. - */ -void -xdr_dec_release (xdr_dec_t * xdr) -{ - if (xdr == NULL) - return; - kfree (xdr->stream); - kfree (xdr); -} - -/** - * xdr_enc_force_release - - * @xdr: - * - * Free the memory, losing whatever may be there. - */ -void -xdr_enc_force_release (xdr_enc_t * xdr) -{ - if (xdr == NULL) - return; - if (xdr->stream != NULL) - kfree (xdr->stream); - kfree (xdr); -} - -/** - * xdr_enc_release - - * @xdr: - * - * Free things up, trying to send any possible leftover data first. - * - * Returns: int - */ -int -xdr_enc_release (xdr_enc_t * xdr) -{ - int e; - if (xdr == NULL) - return -EINVAL; - if ((e = xdr_enc_flush (xdr)) != 0) - return e; - xdr_enc_force_release (xdr); - return 0; -} - -/*****************************************************************************/ -/** - * grow_stream - - * @xdr: - * @len: - * - * each single encoded call needs to fit within a buffer. So we make sure - * the buffer is big enough. - * - * If the buffer is big enough, but just doesn't have room, we send the - * data in the buffer, emptying it, first. - * - * Returns: int - */ -static int -grow_stream (xdr_enc_t * enc, size_t len) -{ - int err; - uint8_t *c; - - /* buffer must be big enough for one type entry. */ - if (len > enc->length) { - c = xdr_realloc (enc->stream, len, enc->length); - if (c == NULL) - return -ENOMEM; - enc->stream = c; - enc->length = len; - } - - /* if there isn't room on the end of this chunk, - * try sending what we've got. - */ - if (enc->curloc + len > enc->length) { - err = xdr_enc_flush (enc); - if (err != 0) { - /* error, better pass this up. */ - return err; - } - } - - return 0; -} - -/** - * append_bytes - - * @xdr: - * @xdr_type: - * @bytes: - * @len: - * - * - * Returns: int - */ -static int -append_bytes (xdr_enc_t * xdr, uint8_t xdr_type, void *bytes, size_t len) -{ - int e; - if (xdr == NULL) - return -EINVAL; - if (xdr->type != xdr_enc) - return -EINVAL; - - /* len + 1; need the one byte for the type code. */ - if ((e = grow_stream (xdr, len + 1)) != 0) - return e; - *(xdr->stream + xdr->curloc) = xdr_type; - xdr->curloc += 1; - memcpy ((xdr->stream + xdr->curloc), bytes, len); - xdr->curloc += len; - - return 0; -} - -int -xdr_enc_uint64 (xdr_enc_t * xdr, uint64_t i) -{ - uint64_t b = cpu_to_be64 (i); - return append_bytes (xdr, XDR_UINT64, &b, sizeof (uint64_t)); -} - -int -xdr_enc_uint32 (xdr_enc_t * xdr, uint32_t i) -{ - uint32_t b = cpu_to_be32 (i); - return append_bytes (xdr, XDR_UINT32, &b, sizeof (uint32_t)); -} - -int -xdr_enc_uint16 (xdr_enc_t * xdr, uint16_t i) -{ - uint16_t b = cpu_to_be16 (i); - return append_bytes (xdr, XDR_UINT16, &b, sizeof (uint16_t)); -} - -int -xdr_enc_uint8 (xdr_enc_t * xdr, uint8_t i) -{ - return append_bytes (xdr, XDR_UINT8, &i, sizeof (uint8_t)); -} - -int -xdr_enc_ipv6 (xdr_enc_t * xdr, struct in6_addr *ip) -{ /* bytes should already be in the right order. */ - return append_bytes (xdr, XDR_IPv6, ip->s6_addr, 16); -} - -int -xdr_enc_raw (xdr_enc_t * xdr, void *p, uint16_t len) -{ - int e; - uint16_t temp; - if (xdr == NULL) - return -EINVAL; - if ((e = grow_stream (xdr, len + 3)) != 0) - return e; - *(xdr->stream + xdr->curloc) = XDR_RAW; - xdr->curloc += 1; - temp = cpu_to_be16(len); - memcpy((xdr->stream + xdr->curloc), &temp, 2); - xdr->curloc += 2; - memcpy ((xdr->stream + xdr->curloc), p, len); - xdr->curloc += len; - return 0; -} - -int -xdr_enc_raw_iov (xdr_enc_t * xdr, int count, struct iovec *iov) -{ - size_t total = 0; - int i, err; - uint16_t temp; - if (xdr == NULL || count < 1 || iov == NULL) - return -EINVAL; - for (i = 0; i < count; i++) - total += iov[i].iov_len; - /* make sure it fits in a uint16_t */ - if (total > 0xffff) - return -EFBIG; - /* grow to fit */ - if ((err = grow_stream (xdr, total + 3)) != 0) - return err; - /* copy in header and size */ - *(xdr->stream + xdr->curloc) = XDR_RAW; - xdr->curloc += 1; - temp = cpu_to_be16(total); - memcpy((xdr->stream + xdr->curloc), &temp, 2); - xdr->curloc += 2; - /* copy in all iovbufs */ - for (i = 0; i < count; i++) { - if (iov[i].iov_base == NULL) - continue; - memcpy ((xdr->stream + xdr->curloc), iov[i].iov_base, - iov[i].iov_len); - xdr->curloc += iov[i].iov_len; - } - return 0; -} - -int -xdr_enc_string (xdr_enc_t * xdr, uint8_t * s) -{ - int len, e; - uint16_t temp; - if (xdr == NULL) - return -EINVAL; - if (s == NULL) - len = 0; - else - len = strlen (s); - if ((e = grow_stream (xdr, len + 3)) != 0) - return e; - *(xdr->stream + xdr->curloc) = XDR_STRING; - xdr->curloc += 1; - temp = cpu_to_be16(len); - memcpy((xdr->stream + xdr->curloc), &temp, 2); - xdr->curloc += 2; - if (len > 0) { - memcpy ((xdr->stream + xdr->curloc), s, len); - xdr->curloc += len; - } - return 0; -} - -int -xdr_enc_list_start (xdr_enc_t * xdr) -{ - int e; - if (xdr == NULL) - return -EINVAL; - if ((e = grow_stream (xdr, 1)) != 0) - return e; - *(xdr->stream + xdr->curloc) = XDR_LIST_START; - xdr->curloc += 1; - return 0; -} - -int -xdr_enc_list_stop (xdr_enc_t * xdr) -{ - int e; - if (xdr == NULL) - return -EINVAL; - if ((e = grow_stream (xdr, 1)) != 0) - return e; - *(xdr->stream + xdr->curloc) = XDR_LIST_STOP; - xdr->curloc += 1; - return 0; -} - -/*****************************************************************************/ - -/** - * get_next - - * @xdr: - * - * get what ever may be next, and put it into the buffer. - * - * Returns: int - */ -static int -get_next (xdr_dec_t * xdr) -{ - int err; - uint16_t len; - if ((err = xdr_recv (xdr->fd, xdr->stream, 1)) < 0) - return err; - if (err == 0) - return -EPROTO; - xdr->curloc = 1; - if (*(xdr->stream) == XDR_UINT64) { - len = sizeof (uint64_t); - } else if (*(xdr->stream) == XDR_UINT32) { - len = sizeof (uint32_t); - } else if (*(xdr->stream) == XDR_UINT16) { - len = sizeof (uint16_t); - } else if (*(xdr->stream) == XDR_UINT8) { - len = sizeof (uint8_t); - } else if (*(xdr->stream) == XDR_IPv6) { - len = 16; - } else if (*(xdr->stream) == XDR_STRING) { - if ((err = xdr_recv (xdr->fd, (xdr->stream + 1), 2)) < 0) - return err; - if (err == 0) - return -EPROTO; - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - } else if (*(xdr->stream) == XDR_RAW) { - if ((err = xdr_recv (xdr->fd, (xdr->stream + 1), 2)) < 0) - return err; - if (err == 0) - return -EPROTO; - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - } else if (*(xdr->stream) == XDR_LIST_START) { - xdr->curloc = 0; - return 0; - } else if (*(xdr->stream) == XDR_LIST_STOP) { - xdr->curloc = 0; - return 0; - } else { - return -1; - } - - /* grow buffer if need be. */ - if (xdr->curloc + len > xdr->length) { - uint8_t *c; - c = xdr_realloc (xdr->stream, xdr->curloc + len, xdr->length); - if (c == NULL) - return -ENOMEM; - xdr->stream = c; - xdr->length = xdr->curloc + len; - } - - if (len > 0) { - if ((err = - xdr_recv (xdr->fd, (xdr->stream + xdr->curloc), len)) < 0) - return err; - if (err == 0) - return -EPROTO; - } - xdr->curloc = 0; - return 0; -} - -int -xdr_dec_uint64 (xdr_dec_t * xdr, uint64_t * i) -{ - int err; - if (xdr == NULL || i == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_UINT64) - return -ENOMSG; - *i = be64_to_cpu (*((uint64_t *) (xdr->stream + 1))); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_uint32 (xdr_dec_t * xdr, uint32_t * i) -{ - int err; - if (xdr == NULL || i == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_UINT32) - return -ENOMSG; - *i = be32_to_cpu (*((uint32_t *) (xdr->stream + 1))); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_uint16 (xdr_dec_t * xdr, uint16_t * i) -{ - int err; - if (xdr == NULL || i == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_UINT16) - return -ENOMSG; - *i = be16_to_cpu (*((uint16_t *) (xdr->stream + 1))); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_uint8 (xdr_dec_t * xdr, uint8_t * i) -{ - int err; - if (xdr == NULL || i == NULL) - return -EINVAL; - - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_UINT8) - return -ENOMSG; - *i = *((uint8_t *) (xdr->stream + 1)); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_ipv6 (xdr_dec_t * xdr, struct in6_addr *ip) -{ - int err; - if (xdr == NULL || ip == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_IPv6) - return -ENOMSG; - memcpy (ip, xdr->stream + 1, 16); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* mallocing version */ -int -xdr_dec_raw_m (xdr_dec_t * xdr, void **p, uint16_t * l) -{ - int len; - void *str; - int err; - - if (xdr == NULL || p == NULL || l == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_RAW) - return -ENOMSG; - xdr->curloc = 1; - - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - - str = kmalloc (len, GFP_KERNEL); - if (str == NULL) - return -ENOMEM; - memcpy (str, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *p = str; - *l = len; - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* non-mallocing version */ -int -xdr_dec_raw (xdr_dec_t * xdr, void *p, uint16_t * l) -{ - int len; - int err; - - if (xdr == NULL || p == NULL || l == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_RAW) - return -ENOMSG; - xdr->curloc = 1; - - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - - if (len > *l) - return -1; - - memcpy (p, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *l = len; - - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/** - * xdr_dec_raw_ag - auto-growing version - * @xdr: - * @p: <> pointer to buffer - * @bl: <> size of the buffer - * @rl: > size of data read from stream - * - * This form of xdr_dec_raw will increase the size of a pre-malloced buffer - * to fit the data it is reading. It is kind of a merger of the - * non-mallocing and mallocing versions. - * - * Returns: int - */ -int -xdr_dec_raw_ag (xdr_dec_t * xdr, void **p, uint16_t * bl, uint16_t * rl) -{ - int len; - int err; - - if (xdr == NULL || p == NULL || bl == NULL || rl == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_RAW) - return -ENOMSG; - xdr->curloc = 1; - - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - - if (len > *bl) { /* grow p */ - void *temp; - temp = xdr_realloc (*p, len, *bl); - if (temp == NULL) - return -ENOMEM; - *bl = len; - *p = temp; - } - - memcpy (*p, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *rl = len; - - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* mallocing version */ -int -xdr_dec_string (xdr_dec_t * xdr, uint8_t ** strp) -{ - int len; - char *str; - int err; - if (xdr == NULL || strp == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_STRING) - return -ENOMSG; - xdr->curloc = 1; - - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - - if (len > 0) { - str = kmalloc (len + 1, GFP_KERNEL); - if (str == NULL) - return -ENOMEM; - str[len] = '\0'; - memcpy (str, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *strp = str; - } else { - *strp = NULL; - } - - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* non-mallocing version */ -int -xdr_dec_string_nm (xdr_dec_t * xdr, uint8_t * string, size_t l) -{ - int len; - int err; - if (xdr == NULL || string == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_STRING) - return -ENOMSG; - xdr->curloc = 1; - - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - - if (len > 0) { - memcpy (string, (xdr->stream + xdr->curloc), MIN (len, l)); - if (l > len) { - string[len] = '\0'; - } - string[l - 1] = '\0'; - } else { - string[0] = '\0'; - } - - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_string_ag (xdr_dec_t * xdr, uint8_t ** s, uint16_t * bl) -{ - int len; - int err; - if (xdr == NULL || s == NULL || bl == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_STRING) - return -ENOMSG; - xdr->curloc = 1; - - len = be16_to_cpu (*((uint16_t *) (xdr->stream + xdr->curloc))); - xdr->curloc += 2; - - if (len == 0) { /* empty string */ - **s = '\0'; - *(xdr->stream) = XDR_NULL; - return 0; - } - - if (len >= *bl) { /* grow s */ - void *temp; - temp = xdr_realloc (*s, len + 1, *bl); - if (temp == NULL) - return -ENOMEM; - *bl = len + 1; - *s = temp; - } - - memcpy (*s, (xdr->stream + xdr->curloc), len); - (*s)[len] = '\0'; - - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_list_start (xdr_dec_t * xdr) -{ - int err; - if (xdr == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_LIST_START) - return -ENOMSG; - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int -xdr_dec_list_stop (xdr_dec_t * xdr) -{ - int err; - if (xdr == NULL) - return -EINVAL; - if (*(xdr->stream) == XDR_NULL) { - if ((err = get_next (xdr)) != 0) - return err; - } - if (*(xdr->stream) != XDR_LIST_STOP) - return -ENOMSG; - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} diff --git a/gfs-kernel/src/gulm/xdr_io.c b/gfs-kernel/src/gulm/xdr_io.c deleted file mode 100644 index b61e815..0000000 --- a/gfs-kernel/src/gulm/xdr_io.c +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * does the lowest level of reads and writes. - * In kernel and/or userspace. - */ - -#include "xdr.h" - -#ifdef __KERNEL__ -#ifdef __linux__ -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <net/sock.h> -#include "asm/uaccess.h" - -/** - * do_tfer - transfers data over a socket - * @sock: < socket - * @iov: <> iovec of buffers - * @n: < how many iovecs - * @size: < total data size to send/recv - * @dir: < send or recv - * @timeout: < how many sec to wait. 0 == forever. - * - * Returns: <0: Error - * >=0: Bytes transfered - */ -static int -do_tfer (struct socket *sock, struct iovec *iov, int n, int size, int dir) -{ - unsigned long flags; - sigset_t oldset; - struct msghdr m; - mm_segment_t fs; - int rv, moved = 0; - - fs = get_fs (); - set_fs (get_ds ()); - - /* XXX do I still want the signal stuff? */ - spin_lock_irqsave (¤t->sighand->siglock, flags); - oldset = current->blocked; - siginitsetinv (¤t->blocked, - sigmask (SIGKILL) | sigmask (SIGTERM)); - recalc_sigpending (); - spin_unlock_irqrestore (¤t->sighand->siglock, flags); - - memset (&m, 0, sizeof (struct msghdr)); - for (;;) { - m.msg_iov = iov; - m.msg_iovlen = n; - m.msg_flags = MSG_NOSIGNAL; - - if (dir) - rv = sock_sendmsg (sock, &m, size - moved); - else - rv = sock_recvmsg (sock, &m, size - moved, 0); - - if (rv <= 0) - goto out_err; - moved += rv; - - if (moved >= size) - break; - - /* adjust iov's for next transfer */ - while (iov->iov_len == 0) { - iov++; - n--; - } - - } - rv = moved; - out_err: - spin_lock_irqsave (¤t->sighand->siglock, flags); - current->blocked = oldset; - recalc_sigpending (); - spin_unlock_irqrestore (¤t->sighand->siglock, flags); - - set_fs (fs); - - return rv; -} - -size_t -xdr_send (struct socket * sock, void *buf, size_t size) -{ - struct iovec iov; - int res; - - iov.iov_base = buf; - iov.iov_len = size; - - res = do_tfer (sock, &iov, 1, size, 1); - - return res; -} - -size_t -xdr_recv (struct socket * sock, void *buf, size_t size) -{ - struct iovec iov; - int res; - - iov.iov_base = buf; - iov.iov_len = size; - - res = do_tfer (sock, &iov, 1, size, 0); - - return res; -} - -#endif /*__linux__*/ -#else /*__KERNEL__*/ - -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> - -ssize_t -xdr_recv (int fd, void *buf, size_t len) -{ - ssize_t cnt = 0; - size_t ttl = 0; - while (len > 0) { - cnt = recv (fd, buf, len, 0); - if (cnt == 0) - return 0; - if (cnt < 0) - return -errno; - len -= cnt; - buf += cnt; - ttl += cnt; - } - return ttl; -} - -ssize_t -xdr_send (int fd, void *buf, size_t len) -{ - ssize_t cnt = 0; - size_t ttl = 0; - while (len > 0) { - cnt = send (fd, buf, len, 0); - if (cnt == 0) - return 0; - if (cnt < 0) - return -errno; - len -= cnt; - buf += cnt; - ttl += cnt; - } - return ttl; -} - -#endif /*__KERNEL__*/ diff --git a/gfs-kernel/src/gulm/xdr_socket.c b/gfs-kernel/src/gulm/xdr_socket.c deleted file mode 100644 index ae85549..0000000 --- a/gfs-kernel/src/gulm/xdr_socket.c +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * This file opens and closes a socket. - * In kernel and/or userspace. - */ - -#include "xdr.h" - -#ifdef __KERNEL__ -#ifdef __linux__ - -int -xdr_open (xdr_socket * xsk) -{ - return sock_create (AF_INET6, SOCK_STREAM, 0, xsk); -} - -int -xdr_connect (struct sockaddr_in6 *adr, xdr_socket xsk) -{ - return xsk->ops->connect (xsk, - (struct sockaddr *) adr, - sizeof (struct sockaddr_in6), 0); -} - -void -xdr_close (xdr_socket * xsk) -{ - if (*xsk == NULL) - return; - sock_release (*xsk); - *xsk = NULL; -} - -#endif /*__linux__*/ -#else /*__KERNEL__*/ - -int -xdr_open (xdr_socket * xsk) -{ - int sk; - sk = socket (AF_INET6, SOCK_STREAM, 0); - if (sk < 0) - return -errno; - *xsk = sk; - return 0; -} - -int -xdr_connect (struct sockaddr_in6 *adr, xdr_socket xsk) -{ - int err; - err = - connect (xsk, (struct sockaddr *) adr, - sizeof (struct sockaddr_in6)); - if (err < 0) - return -errno; - return 0; -} - -void -xdr_close (xdr_socket * xsk) -{ - if (*xsk < 0) - return; - close (*xsk); - *xsk = -1; -} - -#endif /*__KERNEL__*/ diff --git a/gfs-kernel/src/harness/Makefile b/gfs-kernel/src/harness/Makefile deleted file mode 100644 index e81c206..0000000 --- a/gfs-kernel/src/harness/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir = ../.. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/src/linux-orig -linux_patched = ${top_srcdir}/src/linux-patched - - -TARGET = lock_harness.patch - -PWD := $(shell pwd) - -DLMSYMVERFILE := ${KERNEL_SRC}/../kernel/cluster/dlm.symvers - -obj-m := lock_harness.o -lock_harness-objs := main.o - -EXTRA_CFLAGS += -I$(obj) - -all: - rm -f linux - ln -s . linux - ${MAKE} -C ${KERNEL_SRC} M=${PWD} symverfile=${DLMSYMVERFILE} modules USING_KBUILD=yes - ${KERNEL_SRC}/scripts/mod/modpost -m -i ${DLMSYMVERFILE} ../harness/lock_harness.o -o lock_harness.symvers - -install: all - install -d ${incdir}/linux - install lm_interface.h ${incdir}/linux - install -d ${module_dir}/fs/gfs_locking/lock_harness - install lock_harness.ko ${module_dir}/fs/gfs_locking/lock_harness - -uninstall: - ${UNINSTALL} lm_interface.h ${incdir}/linux - ${UNINSTALL} lock_harness.ko ${module_dir}/fs/gfs_locking/lock_harness - -clean: - rm -rf linux *o .*.o.cmd lock_harness.mod.c .lock_harness.ko.cmd .tmp_versions *~ - - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir}/src ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/fs/gfs_locking/lock_harness - cp *.[ch] ${linux_patched}/fs/gfs_locking/lock_harness - mv ${linux_patched}/fs/gfs_locking/lock_harness/lm_interface.h ${linux_patched}/include/linux diff --git a/gfs-kernel/src/harness/lm_interface.h b/gfs-kernel/src/harness/lm_interface.h deleted file mode 100644 index 04933cd..0000000 --- a/gfs-kernel/src/harness/lm_interface.h +++ /dev/null @@ -1,247 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - - Sooner or later, I need to put all the documentation back into this file. - In the mean time, here are some notes. - - - The lock module is now responsible for STOMITHing the an expired - client before calling the callback with type LM_CB_NEED_RECOVERY. - - - If mount() operation returns first == TRUE, GFS will check all the - journals. GFS itself can't/shouldn't stomith the machines, so the lock module - needs to make sure that there are no zombie machines on any of the - journals. (i.e. this should probably be on the first mount of the lock - space where all mounts by other machines are blocked.) GFS will call - others_may_mount() when the filesystem is in a consistent state. - - - GFS can issue multiple simultaneous get_lock()s for the same lockname. - The lock module needs to deal with it, either by 1) building a hash table - to lookup the structures and keeping a reference count so there is only - on lm_lock_t for a given lockname. or 2) just dealing with multiple - lm_lock_t structures for a given lockname. - -*/ - -#ifndef __LM_INTERFACE_DOT_H__ -#define __LM_INTERFACE_DOT_H__ - -/* - * Lock-module- or filesystem-specific opaque handles for various things. - * Lock module gives lockspace and lock handles to GFS, which uses them - * to identify LM instance and lock when calling LM functions. - * GFS gives fsdata to lock module, so LM can identify filesystem instance - * when doing callbacks to GFS. - */ -typedef void lm_lockspace_t; /* lockspace; lock module instance structure */ -typedef void lm_lock_t; /* lock module's internal lock structure */ -typedef void lm_fsdata_t; /* filesystem; GFS instance (superblock struct) */ - -typedef void (*lm_callback_t) (lm_fsdata_t *fsdata, unsigned int type, - void *data); - -/* - * Flags for the struct lm_lockstruct->ls_flags field. - * The nolock module is useful for single-node mounting of GFS; it sets the - * LOCAL flag to allow GFS to perform caching and other optimizations that - * it cannot do when in a cluster. - */ - -#define LM_LSFLAG_LOCAL (0x00000001) /* Local filesystem (no locks) */ - -/* Lock types */ - -#define LM_TYPE_RESERVED (0x00) -#define LM_TYPE_NONDISK (0x01) /* Non-disk cluster-wide, e.g. TRANS */ -#define LM_TYPE_INODE (0x02) /* Inode, e.g. files */ -#define LM_TYPE_RGRP (0x03) /* Resource Group (block allocation) */ -#define LM_TYPE_META (0x04) /* Metadata, e.g. superblock, journals */ -#define LM_TYPE_IOPEN (0x05) -#define LM_TYPE_FLOCK (0x06) /* Linux file lock */ -#define LM_TYPE_PLOCK (0x07) /* POSIX file lock */ -#define LM_TYPE_QUOTA (0x08) /* User or group block usage quota */ - -/* States passed to lock() */ - -#define LM_ST_UNLOCKED (0) /* Not locked */ -#define LM_ST_EXCLUSIVE (1) /* Allow writes */ -#define LM_ST_DEFERRED (2) /* Locking deferred to application level */ -#define LM_ST_SHARED (3) /* Allow reads, protected from writes */ - -/* Flags passed to lock() */ - -#define LM_FLAG_TRY (0x00000001) /* Don't block if not immediately - * grantable */ -#define LM_FLAG_TRY_1CB (0x00000002) /* Don't block if not grantable - * after request to other node */ -#define LM_FLAG_NOEXP (0x00000004) /* Don't grant if held by expired - * (crashed/dead) node */ -#define LM_FLAG_ANY (0x00000008) /* Grant if lock state is any - * other than LM_ST_UNLOCKED */ -#define LM_FLAG_PRIORITY (0x00000010) /* High priority lock request, - * put at top of wait queue */ - -/* Flags returned by lock() */ - -#define LM_OUT_ST_MASK (0x00000003) /* 4-state LM_ST_XX mask */ -#define LM_OUT_CACHEABLE (0x00000004) -#define LM_OUT_CANCELED (0x00000008) /* Lock request was cancelled */ -#define LM_OUT_ASYNC (0x00000080) - -/* Callback types */ - -#define LM_CB_NEED_E (257) /* Other node needs EXCLUSIVE lock */ -#define LM_CB_NEED_D (258) /* Other node needs DEFERRED lock */ -#define LM_CB_NEED_S (259) /* Other node needs SHARED lock */ -#define LM_CB_NEED_RECOVERY (260) /* A node crashed, needs jrnl recovery */ -#define LM_CB_DROPLOCKS (261) /* Locking system running out of space */ -#define LM_CB_ASYNC (262) /* Asynchronous lock request results */ - -/* Reset_exp messages */ - -#define LM_RD_GAVEUP (308) -#define LM_RD_SUCCESS (309) - -struct lm_lockname { - uint64_t ln_number; /* Lock number */ - unsigned int ln_type; /* LM_TYPE_XXX lock type */ -}; - -#define lm_name_equal(name1, name2) \ -(((name1)->ln_number == (name2)->ln_number) && \ - ((name1)->ln_type == (name2)->ln_type)) \ - -struct lm_async_cb { - struct lm_lockname lc_name; - int lc_ret; -}; - -struct lm_lockstruct; - -/* - * Operations that form the interface between GFS' glock layer - * and the lock plug-in module that supports inter-node locks. - */ -struct lm_lockops { - char lm_proto_name[256]; - - /* - * Mount/Unmount - */ - - /* Mount the lock module on lock harness, so GFS can use it */ - int (*lm_mount) (char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t *fsdata, - unsigned int min_lvb_size, - struct lm_lockstruct *lockstruct); - - /* We've completed mount operations for this GFS filesystem/lockspace, - other nodes may now mount it */ - void (*lm_others_may_mount) (lm_lockspace_t *lockspace); - - /* Unmount the lock module */ - void (*lm_unmount) (lm_lockspace_t *lockspace); - - /* Abnormal unmount */ - void (*lm_withdraw) (lm_lockspace_t *lockspace); - - /* - * Lock oriented operations - */ - - /* Find or create structures, etc. for lock (but don't lock it yet) */ - int (*lm_get_lock) (lm_lockspace_t *lockspace, - struct lm_lockname *name, lm_lock_t **lockp); - - /* Done with structure */ - void (*lm_put_lock) (lm_lock_t *lock); - - /* Lock inter-node lock in requested state */ - unsigned int (*lm_lock) (lm_lock_t *lock, unsigned int cur_state, - unsigned int req_state, unsigned int flags); - - /* Unlock inter-node lock */ - unsigned int (*lm_unlock) (lm_lock_t *lock, unsigned int cur_state); - - /* Cancel a lock request */ - void (*lm_cancel) (lm_lock_t *lock); - - /* Lock Value Block operations */ - int (*lm_hold_lvb) (lm_lock_t *lock, char **lvbp); - void (*lm_unhold_lvb) (lm_lock_t *lock, char *lvb); - - /* Make new LVB contents visible to other nodes */ - void (*lm_sync_lvb) (lm_lock_t *lock, char *lvb); - - /* - * Posix Lock oriented operations - */ - - int (*lm_plock_get) (lm_lockspace_t *lockspace, - struct lm_lockname *name, - struct file *file, struct file_lock *fl); - - int (*lm_plock) (lm_lockspace_t *lockspace, - struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl); - - int (*lm_punlock) (lm_lockspace_t *lockspace, - struct lm_lockname *name, - struct file *file, struct file_lock *fl); - - /* - * Client oriented operations - */ - - /* This node has completed journal recovery for a crashed node */ - void (*lm_recovery_done) (lm_lockspace_t *lockspace, unsigned int jid, - unsigned int message); - - struct module *lm_owner; -}; - -/* - * GFS passes this structure to the lock module to fill when mounting. - */ -struct lm_lockstruct { - unsigned int ls_jid; /* Journal ID # for this node */ - unsigned int ls_first; /* This node is first to mount this FS */ - unsigned int ls_lvb_size; /* Size (bytes) of Lock Value Block */ - lm_lockspace_t *ls_lockspace; /* Lock module instance handle */ - struct lm_lockops *ls_ops; /* Pointers to functions in lock module*/ - int ls_flags; /* LM_LSFLAG_XXX, e.g. local filesystem*/ -}; - -/* - * Lock Module Bottom interface. - * Each lock module makes itself known or unknown to the lock harness - * via these functions. - */ - -int lm_register_proto(struct lm_lockops *proto); -void lm_unregister_proto(struct lm_lockops *proto); - -/* - * Lock Module Top interface. - * GFS calls these functions to mount or unmount a particular lock module. - */ - -int lm_mount(char *proto_name, - char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t *fsdata, - unsigned int min_lvb_size, struct lm_lockstruct *lockstruct); -void lm_unmount(struct lm_lockstruct *lockstruct); -void lm_withdraw(struct lm_lockstruct *lockstruct); - -#endif /* __LM_INTERFACE_DOT_H__ */ diff --git a/gfs-kernel/src/harness/main.c b/gfs-kernel/src/harness/main.c deleted file mode 100644 index ab84bcf..0000000 --- a/gfs-kernel/src/harness/main.c +++ /dev/null @@ -1,244 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <linux/kmod.h> -#include <linux/fs.h> -#include <linux/lm_interface.h> - -#define RELEASE_NAME "<CVS>" - -struct lmh_wrapper { - struct list_head lw_list; - struct lm_lockops *lw_ops; -}; - -static struct semaphore lmh_lock; -static struct list_head lmh_list; - -/** - * lm_register_proto - Register a low-level locking protocol - * @proto: the protocol definition - * - * Returns: 0 on success, -EXXX on failure - */ - -int -lm_register_proto(struct lm_lockops *proto) -{ - struct list_head *tmp, *head; - struct lmh_wrapper *lw; - - down(&lmh_lock); - - for (head = &lmh_list, tmp = head->next; tmp != head; tmp = tmp->next) { - lw = list_entry(tmp, struct lmh_wrapper, lw_list); - - if (strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name) == 0) { - up(&lmh_lock); - printk("lock_harness: protocol %s already exists\n", - proto->lm_proto_name); - return -EEXIST; - } - } - - lw = kmalloc(sizeof (struct lmh_wrapper), GFP_KERNEL); - if (!lw) { - up(&lmh_lock); - return -ENOMEM; - } - memset(lw, 0, sizeof (struct lmh_wrapper)); - - lw->lw_ops = proto; - list_add(&lw->lw_list, &lmh_list); - - up(&lmh_lock); - - return 0; -} - -/** - * lm_unregister_proto - Unregister a low-level locking protocol - * @proto: the protocol definition - * - */ - -void -lm_unregister_proto(struct lm_lockops *proto) -{ - struct list_head *tmp, *head; - struct lmh_wrapper *lw = NULL; - - down(&lmh_lock); - - for (head = &lmh_list, tmp = head->next; tmp != head; tmp = tmp->next) { - lw = list_entry(tmp, struct lmh_wrapper, lw_list); - - if (strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name) == 0) { - list_del(&lw->lw_list); - up(&lmh_lock); - kfree(lw); - return; - } - } - - up(&lmh_lock); - - printk("lock_harness: can't unregister lock protocol %s\n", - proto->lm_proto_name); -} - -/** - * lm_mount - Mount a lock protocol - * @proto_name - the name of the protocol - * @table_name - the name of the lock space - * @host_data - data specific to this host - * @cb - the callback to the code using the lock module - * @fsdata - data to pass back with the callback - * @min_lvb_size - the mininum LVB size that the caller can deal with - * @lockstruct - a structure returned describing the mount - * - * Returns: 0 on success, -EXXX on failure - */ - -int -lm_mount(char *proto_name, char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t * fsdata, - unsigned int min_lvb_size, struct lm_lockstruct *lockstruct) -{ - struct list_head *tmp; - struct lmh_wrapper *lw = NULL; - int try = 0; - int error; - - retry: - down(&lmh_lock); - - for (tmp = lmh_list.next; tmp != &lmh_list; tmp = tmp->next) { - lw = list_entry(tmp, struct lmh_wrapper, lw_list); - - if (strcmp(lw->lw_ops->lm_proto_name, proto_name) == 0) - break; - else - lw = NULL; - } - - if (!lw) { - if (!try && capable(CAP_SYS_MODULE)) { - try = 1; - up(&lmh_lock); - request_module(proto_name); - goto retry; - } - printk("lock_harness: can't find protocol %s\n", proto_name); - error = -ENOENT; - goto out; - } - - if (!try_module_get(lw->lw_ops->lm_owner)) { - try = 0; - up(&lmh_lock); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - goto retry; - } - - error = lw->lw_ops->lm_mount(table_name, host_data, - cb, fsdata, min_lvb_size, lockstruct); - if (error) - module_put(lw->lw_ops->lm_owner); - - out: - up(&lmh_lock); - - return error; -} - -/** - * lm_unmount - unmount a lock module - * @lockstruct: the lockstruct passed into mount - * - */ - -void -lm_unmount(struct lm_lockstruct *lockstruct) -{ - down(&lmh_lock); - lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace); - if (lockstruct->ls_ops->lm_owner) - module_put(lockstruct->ls_ops->lm_owner); - up(&lmh_lock); -} - -/** - * lm_withdraw - abnormally unmount a lock module - * @lockstruct: the lockstruct passed into mount - * - */ - -void -lm_withdraw(struct lm_lockstruct *lockstruct) -{ - down(&lmh_lock); - lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace); - if (lockstruct->ls_ops->lm_owner) - module_put(lockstruct->ls_ops->lm_owner); - up(&lmh_lock); -} - -/** - * init_lmh - Initialize the lock module harness - * - * Returns: 0 on success, -EXXX on failure - */ - -int __init -init_lmh(void) -{ - init_MUTEX(&lmh_lock); - INIT_LIST_HEAD(&lmh_list); - - printk("Lock_Harness %s (built %s %s) installed\n", - RELEASE_NAME, __DATE__, __TIME__); - - return 0; -} - -/** - * exit_lmh - cleanup the Lock Module Harness - * - * Returns: 0 on success, -EXXX on failure - */ - -void __exit -exit_lmh(void) -{ -} - -module_init(init_lmh); -module_exit(exit_lmh); - -MODULE_DESCRIPTION("GFS Lock Module Harness " RELEASE_NAME); -MODULE_AUTHOR("Red Hat, Inc."); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL_GPL(lm_register_proto); -EXPORT_SYMBOL_GPL(lm_unregister_proto); -EXPORT_SYMBOL_GPL(lm_mount); -EXPORT_SYMBOL_GPL(lm_unmount); -EXPORT_SYMBOL_GPL(lm_withdraw); diff --git a/gfs-kernel/src/nolock/Makefile b/gfs-kernel/src/nolock/Makefile deleted file mode 100644 index afe1982..0000000 --- a/gfs-kernel/src/nolock/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = ../.. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/src/linux-orig -linux_patched = ${top_srcdir}/src/linux-patched - -PWD := $(shell pwd) - -TARGET = lock_nolock.patch -SYMVERFILE := ${PWD}/../harness/lock_harness.symvers - - -obj-m := lock_nolock.o -lock_nolock-objs := main.o - -EXTRA_CFLAGS += -I$(obj) - -all: - echo ${DESTDIR} - rm -f linux lm_interface.h - ln -s . linux - ln -s ${top_srcdir}/src/harness/lm_interface.h . - ${MAKE} -C ${KERNEL_SRC} M=${PWD} symverfile=${SYMVERFILE} modules USING_KBUILD=yes - -install: all - install -d ${module_dir}/fs/gfs_locking/lock_nolock - install lock_nolock.ko ${module_dir}/fs/gfs_locking/lock_nolock - -uninstall: - ${UNINSTALL} lock_nolock.ko ${module_dir}/fs/gfs_locking/lock_nolock - -clean: - rm -rf linux lm_interface.h *.mod.c .lock_nolock.ko.cmd \ - .tmp_versions *o .*.o.cmd *~ - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir}/src ; diff -urN linux-orig linux-patched > ${TARGET} ; exit 0 ) - -add: - mkdir -p ${linux_patched}/fs/gfs_locking/lock_nolock - cp *.[ch] ${linux_patched}/fs/gfs_locking/lock_nolock diff --git a/gfs-kernel/src/nolock/main.c b/gfs-kernel/src/nolock/main.c deleted file mode 100644 index 7e23eb9..0000000 --- a/gfs-kernel/src/nolock/main.c +++ /dev/null @@ -1,358 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/fs.h> -#include <linux/lm_interface.h> - -#define RELEASE_NAME "<CVS>" - -struct nolock_lockspace { - unsigned int nl_lvb_size; -}; - -struct lm_lockops nolock_ops; - -/** - * nolock_mount - mount a nolock lockspace - * @table_name: the name of the space to mount - * @host_data: host specific data - * @cb: the callback - * @lockstruct: the structure of crap to fill in - * - * Returns: 0 on success, -EXXX on failure - */ - -static int -nolock_mount(char *table_name, char *host_data, - lm_callback_t cb, lm_fsdata_t *fsdata, - unsigned int min_lvb_size, struct lm_lockstruct *lockstruct) -{ - char *c; - unsigned int jid; - struct nolock_lockspace *nl; - - /* If there is a "jid=" in the hostdata, return that jid. - Otherwise, return zero. */ - - c = strstr(host_data, "jid="); - if (!c) - jid = 0; - else { - c += 4; - sscanf(c, "%u", &jid); - } - - nl = kmalloc(sizeof(struct nolock_lockspace), GFP_KERNEL); - if (!nl) - return -ENOMEM; - - memset(nl, 0, sizeof(struct nolock_lockspace)); - nl->nl_lvb_size = min_lvb_size; - - lockstruct->ls_jid = jid; - lockstruct->ls_first = 1; - lockstruct->ls_lvb_size = min_lvb_size; - lockstruct->ls_lockspace = (lm_lockspace_t *)nl; - lockstruct->ls_ops = &nolock_ops; - lockstruct->ls_flags = LM_LSFLAG_LOCAL; - - return 0; -} - -/** - * nolock_others_may_mount - unmount a lock space - * @lockspace: the lockspace to unmount - * - */ - -static void -nolock_others_may_mount(lm_lockspace_t *lockspace) -{ -} - -/** - * nolock_unmount - unmount a lock space - * @lockspace: the lockspace to unmount - * - */ - -static void -nolock_unmount(lm_lockspace_t *lockspace) -{ - struct nolock_lockspace *nl = (struct nolock_lockspace *)lockspace; - kfree(nl); -} - -/** - * nolock_withdraw - withdraw from a lock space - * @lockspace: the lockspace - * - */ - -static void -nolock_withdraw(lm_lockspace_t *lockspace) -{ -} - -/** - * nolock_get_lock - get a lm_lock_t given a descripton of the lock - * @lockspace: the lockspace the lock lives in - * @name: the name of the lock - * @lockp: return the lm_lock_t here - * - * Returns: 0 on success, -EXXX on failure - */ - -static int -nolock_get_lock(lm_lockspace_t *lockspace, struct lm_lockname *name, - lm_lock_t ** lockp) -{ - *lockp = (lm_lock_t *)lockspace; - return 0; -} - -/** - * nolock_put_lock - get rid of a lock structure - * @lock: the lock to throw away - * - */ - -static void -nolock_put_lock(lm_lock_t *lock) -{ -} - -/** - * nolock_lock - acquire a lock - * @lock: the lock to manipulate - * @cur_state: the current state - * @req_state: the requested state - * @flags: modifier flags - * - * Returns: A bitmap of LM_OUT_* - */ - -static unsigned int -nolock_lock(lm_lock_t *lock, unsigned int cur_state, unsigned int req_state, - unsigned int flags) -{ - return req_state | LM_OUT_CACHEABLE; -} - -/** - * nolock_unlock - unlock a lock - * @lock: the lock to manipulate - * @cur_state: the current state - * - * Returns: 0 - */ - -static unsigned int -nolock_unlock(lm_lock_t *lock, unsigned int cur_state) -{ - return 0; -} - -/** - * nolock_cancel - cancel a request on a lock - * @lock: the lock to cancel request for - * - */ - -static void -nolock_cancel(lm_lock_t *lock) -{ -} - -/** - * nolock_hold_lvb - hold on to a lock value block - * @lock: the lock the LVB is associated with - * @lvbp: return the lm_lvb_t here - * - * Returns: 0 on success, -EXXX on failure - */ - -static int -nolock_hold_lvb(lm_lock_t *lock, char **lvbp) -{ - struct nolock_lockspace *nl = (struct nolock_lockspace *)lock; - int error = 0; - - *lvbp = kmalloc(nl->nl_lvb_size, GFP_KERNEL); - if (*lvbp) - memset(*lvbp, 0, nl->nl_lvb_size); - else - error = -ENOMEM; - - return error; -} - -/** - * nolock_unhold_lvb - release a LVB - * @lock: the lock the LVB is associated with - * @lvb: the lock value block - * - */ - -static void -nolock_unhold_lvb(lm_lock_t *lock, char *lvb) -{ - kfree(lvb); -} - -/** - * nolock_sync_lvb - sync out the value of a lvb - * @lock: the lock the LVB is associated with - * @lvb: the lock value block - * - */ - -static void -nolock_sync_lvb(lm_lock_t *lock, char *lvb) -{ -} - -/** - * nolock_plock_get - - * @lockspace: the lockspace - * @name: - * @file: - * @fl: - * - * Returns: errno - */ - -static int -nolock_plock_get(lm_lockspace_t *lockspace, - struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - return LOCK_USE_CLNT; -} - -/** - * nolock_plock - - * @lockspace: the lockspace - * @name: - * @file: - * @cmd: - * @fl: - * - * Returns: errno - */ - -static int -nolock_plock(lm_lockspace_t *lockspace, - struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl) -{ - return posix_lock_file_wait(file, fl); -} - -/** - * nolock_punlock - - * @lockspace: the lockspace - * @name: - * @file: - * @fl: - * - * Returns: errno - */ - -static int -nolock_punlock(lm_lockspace_t *lockspace, - struct lm_lockname *name, - struct file *file, struct file_lock *fl) -{ - return posix_lock_file_wait(file, fl); -} - -/** - * nolock_recovery_done - reset the expired locks for a given jid - * @lockspace: the lockspace - * @jid: the jid - * - */ - -static void -nolock_recovery_done(lm_lockspace_t *lockspace, unsigned int jid, - unsigned int message) -{ -} - -struct lm_lockops nolock_ops = { - .lm_proto_name = "lock_nolock", - .lm_mount = nolock_mount, - .lm_others_may_mount = nolock_others_may_mount, - .lm_unmount = nolock_unmount, - .lm_withdraw = nolock_withdraw, - .lm_get_lock = nolock_get_lock, - .lm_put_lock = nolock_put_lock, - .lm_lock = nolock_lock, - .lm_unlock = nolock_unlock, - .lm_cancel = nolock_cancel, - .lm_hold_lvb = nolock_hold_lvb, - .lm_unhold_lvb = nolock_unhold_lvb, - .lm_sync_lvb = nolock_sync_lvb, - .lm_plock_get = nolock_plock_get, - .lm_plock = nolock_plock, - .lm_punlock = nolock_punlock, - .lm_recovery_done = nolock_recovery_done, - .lm_owner = THIS_MODULE, -}; - -/** - * init_nolock - Initialize the nolock module - * - * Returns: 0 on success, -EXXX on failure - */ - -int __init -init_nolock(void) -{ - int error; - - error = lm_register_proto(&nolock_ops); - if (error) { - printk("lock_nolock: can't register protocol: %d\n", error); - return error; - } - - printk("Lock_Nolock %s (built %s %s) installed\n", - RELEASE_NAME, __DATE__, __TIME__); - - return 0; -} - -/** - * exit_nolock - cleanup the nolock module - * - */ - -void __exit -exit_nolock(void) -{ - lm_unregister_proto(&nolock_ops); -} - -module_init(init_nolock); -module_exit(exit_nolock); - -MODULE_DESCRIPTION("GFS Nolock Locking Module " RELEASE_NAME); -MODULE_AUTHOR("Red Hat, Inc."); -MODULE_LICENSE("GPL"); diff --git a/gfs/Makefile b/gfs/Makefile deleted file mode 100644 index 0e842a4..0000000 --- a/gfs/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd gfs_edit && ${MAKE} all - cd gfs_fsck && ${MAKE} all - cd gfs_grow && ${MAKE} all - cd gfs_jadd && ${MAKE} all - cd gfs_mkfs && ${MAKE} all - cd gfs_quota && ${MAKE} all - cd gfs_tool && ${MAKE} all - -copytobin: - cd gfs_edit && ${MAKE} copytobin - cd gfs_fsck && ${MAKE} copytobin - cd gfs_grow && ${MAKE} copytobin - cd gfs_jadd && ${MAKE} copytobin - cd gfs_mkfs && ${MAKE} copytobin - cd gfs_quota && ${MAKE} copytobin - cd gfs_tool && ${MAKE} copytobin - -clean: - cd bin && ${MAKE} clean - cd gfs_edit && ${MAKE} clean - cd gfs_fsck && ${MAKE} clean - cd gfs_grow && ${MAKE} clean - cd gfs_jadd && ${MAKE} clean - cd gfs_mkfs && ${MAKE} clean - cd gfs_quota && ${MAKE} clean - cd gfs_tool && ${MAKE} clean - -distclean: clean - rm -f make/defines.mk - -install: - cd bin && ${MAKE} install - cd man && ${MAKE} install - cd init.d && ${MAKE} install - -deinstall uninstall: - cd bin && ${MAKE} uninstall - cd man && ${MAKE} uninstall - cd init.d && ${MAKE} uninstall - diff --git a/gfs/bin/Makefile b/gfs/bin/Makefile deleted file mode 100644 index 0ac0089..0000000 --- a/gfs/bin/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = .. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -SBINPROGS= \ - gfs_fsck \ - gfs_grow \ - gfs_jadd \ - gfs_mkfs \ - gfs_quota \ - gfs_tool - -include ${top_srcdir}/make/defines.mk - -all: - cd ..; ${MAKE} copytobin - -clean: - @echo -n Removing all copied files... - @for f in `ls . | grep -v -i "makefile|cvs"`; do rm -f $$f; done - @echo done. - -install: all - if [ ! -d ${sbindir} ]; then \ - install -d ${sbindir}; \ - fi - for v in ${SBINPROGS}; do \ - install -m755 $${v} ${sbindir}; \ - done - # Make the hardlink to mkfs_gfs instead of copying a separate version - (cd ${sbindir}; ln -f gfs_fsck fsck.gfs) - # Make the hardlink to mkfs_gfs instead of copying a separate version - (cd ${sbindir}; ln -f gfs_mkfs mkfs.gfs) - -uninstall: - #uninstall the hardlinked program as well - ${UNINSTALL} ${SBINPROGS} fsck.gfs mkfs.gfs ${sbindir} - - diff --git a/gfs/config/copyright.cf b/gfs/config/copyright.cf deleted file mode 100644 index e736adb..0000000 --- a/gfs/config/copyright.cf +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) Red Hat, Inc. 2004-2005 All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __COPYRIGHT_DOT_CF__ -#define __COPYRIGHT_DOT_CF__ - -#define REDHAT_COPYRIGHT ("Copyright (C) Red Hat, Inc. 2004-2005 All rights reserved.") - -#endif /* __COPYRIGHT_DOT_CF__ */ - - - diff --git a/gfs/configure b/gfs/configure deleted file mode 100755 index dd4d532..0000000 --- a/gfs/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/gfs/gfs_debug/Makefile b/gfs/gfs_debug/Makefile deleted file mode 100644 index bc631a6..0000000 --- a/gfs/gfs_debug/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -TARGET= gfs_debug - -SOURCE= \ - block_device.c \ - basic.c \ - main.c \ - ondisk.c \ - readfile.c \ - util.c - -CFLAGS+= -O2 -Wall -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config \ - -I${incdir} - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -all: ${TARGET} - -gfs_debug: ${SOURCE} - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} - - diff --git a/gfs/gfs_debug/basic.c b/gfs/gfs_debug/basic.c deleted file mode 100644 index 11999e2..0000000 --- a/gfs/gfs_debug/basic.c +++ /dev/null @@ -1,449 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> -#include "linux_endian.h" - -#include "gfs_debug.h" -#include "basic.h" -#include "block_device.h" - -/** - * verify_block_size - - * @bsize: - * - */ - -static int -verify_block_size(unsigned int bsize) -{ - unsigned int x = 512; - - for (;;) { - if (!x) - return -1; - if (x == bsize) - return 0; - x <<= 1; - } -} - -/** - * verify_gfs - - * - */ - -void -verify_gfs(void) -{ - char buf[GFS_BASIC_BLOCK]; - struct gfs_sb sb; - - if (device_size < (GFS_SB_ADDR + 1) * GFS_BASIC_BLOCK) - return; - - do_lseek(device_fd, GFS_SB_ADDR * GFS_BASIC_BLOCK); - do_read(device_fd, buf, GFS_BASIC_BLOCK); - - gfs_sb_in(&sb, buf); - - if (sb.sb_header.mh_magic != GFS_MAGIC || - sb.sb_header.mh_type != GFS_METATYPE_SB || - sb.sb_bsize != 1 << sb.sb_bsize_shift || - verify_block_size(sb.sb_bsize)) - return; - - if (!block_size || block_size == sb.sb_bsize) { - unsigned int x; - - is_gfs = TRUE; - block_size = sb.sb_bsize; - block_size_shift = sb.sb_bsize_shift; - - sd_diptrs = (block_size - sizeof(struct gfs_dinode)) / sizeof(uint64_t); - sd_inptrs = (block_size - sizeof(struct gfs_indirect)) / sizeof(uint64_t); - sd_jbsize = block_size - sizeof(struct gfs_meta_header); - sd_hash_bsize = block_size / 2; - sd_hash_ptrs = sd_hash_bsize / sizeof(uint64_t); - - sd_heightsize[0] = block_size - sizeof(struct gfs_dinode); - sd_heightsize[1] = block_size * sd_diptrs; - for (x = 2;; x++) { - uint64_t space = sd_heightsize[x - 1] * sd_inptrs; - uint64_t d = space / sd_inptrs; - uint32_t m = space % sd_inptrs; - - if (d != sd_heightsize[x - 1] || m) - break; - sd_heightsize[x] = space; - } - sd_max_height = x; - - sd_jheightsize[0] = block_size - sizeof(struct gfs_dinode); - sd_jheightsize[1] = sd_jbsize * sd_diptrs; - for (x = 2;; x++) { - uint64_t space = sd_jheightsize[x - 1] * sd_inptrs; - uint64_t d = space / sd_inptrs; - uint32_t m = space % sd_inptrs; - - if (d != sd_jheightsize[x - 1] || m) - break; - sd_jheightsize[x] = space; - } - sd_max_jheight = x; - } -} - -/** - * must_be_gfs - - * - */ - -void -must_be_gfs(void) -{ - if (!is_gfs) - die("not a gfs filesystem\n"); -} - -/** - * scan_device - - * - */ - -void -scan_device(void) -{ - char data[GFS_BASIC_BLOCK]; - uint64_t bb; - struct gfs_meta_header mh; - - for (bb = 0; (bb + 1) * GFS_BASIC_BLOCK <= device_size; bb++) { - do_lseek(device_fd, bb * GFS_BASIC_BLOCK); - do_read(device_fd, data, GFS_BASIC_BLOCK); - gfs_meta_header_in(&mh, data); - - if (mh.mh_magic == GFS_MAGIC && - mh.mh_type && mh.mh_type <= GFS_METATYPE_EA) - printf("sector %"PRIu64": type %u\n", - bb, mh.mh_type); - } -} - -/** - * print_superblock - - * - */ - -void -print_superblock(void) -{ - char *data; - struct gfs_sb sb; - - must_be_gfs(); - - data = get_block(GFS_SB_ADDR * GFS_BASIC_BLOCK / block_size, TRUE); - gfs_sb_in(&sb, data); - free(data); - - gfs_sb_print(&sb); -} - -/** - * print_bitmaps - - * @data: - * @offset: - * - */ - -static void -print_bitmaps(char *data, unsigned int offset) -{ - unsigned int bn = 0; - unsigned int bit; - unsigned char value; - char *type; - - printf("\n"); - - for (; offset < block_size; offset++) { - for (bit = 0; bit < GFS_NBBY; bit++) { - value = data[offset]; - value = (value >> (bit * GFS_BIT_SIZE)) & GFS_BIT_MASK; - switch (value) { - case GFS_BLKST_FREE: - type = "free"; - break; - case GFS_BLKST_USED: - type = "used data"; - break; - case GFS_BLKST_FREEMETA: - type = "free meta"; - break; - case GFS_BLKST_USEDMETA: - type = "used meta"; - break; - default: - ASSERT(FALSE,); - } - printf(" block %u: %s\n", bn, type); - bn++; - } - } -} - -/** - * print_stuffed_hash - - * @data: - * - */ - -static void -print_stuffed_hash(char *data) -{ - uint64_t *p = (uint64_t *)(data + sizeof(struct gfs_dinode)); - uint64_t *end = (uint64_t *)(((char *)p) + block_size / 2); - uint64_t this, last = 0; - unsigned int run = 0; - int first = TRUE; - - printf("\n"); - - for (; p < end; p++) { - this = gfs64_to_cpu(*p); - - if (first) { - first = FALSE; - run = 1; - } else { - if (this == last) - run++; - else { - printf(" pointer: %"PRIu64" (%u)\n", - last, run); - run = 1; - } - } - - last = this; - } - - printf(" pointer: %"PRIu64" (%u)\n", - last, run); -} - -/** - * print_dirents - - * @data: - * @offset: - * - * Make this more robust - * - */ - -void -print_dirents(char *data, unsigned int offset) -{ - struct gfs_dirent de; - - for (; offset < block_size; offset += de.de_rec_len) { - printf("\n"); - gfs_dirent_in(&de, data + offset); - - if (sizeof(struct gfs_dirent) + de.de_name_len > de.de_rec_len) - continue; - if (offset + sizeof(struct gfs_dirent) + de.de_name_len > block_size) - break; - if (de.de_inum.no_formal_ino) - gfs_dirent_print(&de, data + offset + sizeof(struct gfs_dirent)); - } -} - -/** - * print_pointers - - * @data: - * @offset: - * - */ - -static void -print_pointers(char *data, unsigned int offset) -{ - uint64_t *p = (uint64_t *)(data + offset); - uint64_t *end = (uint64_t *)(data + block_size); - unsigned int x = 0; - - printf("\n"); - - for (; p < end; p++, x++) - if (*p) - printf(" pointer #%u: %"PRIu64"\n", - x, gfs64_to_cpu(*p)); -} - -/** - * identify_block - - * - */ - -void -identify_block(void) -{ - char *data; - struct gfs_meta_header mh; - - must_be_gfs(); - - data = get_block(block_number, TRUE); - gfs_meta_header_in(&mh, data); - - if (mh.mh_magic != GFS_MAGIC) { - printf("Not GFS metadata\n"); - free(data); - return; - } - - switch (mh.mh_type) { - case GFS_METATYPE_NONE: - printf("GFS_METATYPE_NONE\n"); - break; - - case GFS_METATYPE_SB: - printf("Super\n"); - if (verbose) { - struct gfs_sb sb; - gfs_sb_in(&sb, data); - gfs_sb_print(&sb); - } - break; - - case GFS_METATYPE_RG: - printf("Resource Group Header\n"); - if (verbose) { - struct gfs_rgrp rg; - gfs_rgrp_in(&rg, data); - gfs_rgrp_print(&rg); - if (verbose > 1) - print_bitmaps(data, sizeof(struct gfs_rgrp)); - } - break; - - case GFS_METATYPE_RB: - printf("Resource Group Bitmap\n"); - if (verbose) { - gfs_meta_header_print(&mh); - if (verbose > 1) - print_bitmaps(data, sizeof(struct gfs_meta_header)); - } - break; - - case GFS_METATYPE_DI: - printf("Dinode\n"); - if (verbose) { - struct gfs_dinode di; - gfs_dinode_in(&di, data); - gfs_dinode_print(&di); - if (verbose > 1) { - if (di.di_height) - print_pointers(data, sizeof(struct gfs_dinode)); - else { - if (di.di_type == GFS_FILE_REG) - printf("\n stuffed data\n"); - else if (di.di_type == GFS_FILE_DIR && - (di.di_flags & GFS_DIF_EXHASH)) - print_stuffed_hash(data); - else if (di.di_type == GFS_FILE_DIR) - print_dirents(data, sizeof(struct gfs_dinode)); - else if (di.di_type == GFS_FILE_LNK) - printf("\nsymlink to %s\n", - data + sizeof(struct gfs_dinode)); - } - } - } - break; - - case GFS_METATYPE_IN: - printf("Indirect\n"); - if (verbose) { - struct gfs_indirect in; - gfs_indirect_in(&in, data); - gfs_indirect_print(&in); - if (verbose > 1) { - print_pointers(data, sizeof(struct gfs_indirect)); - } - } - break; - - case GFS_METATYPE_LF: - printf("Directory Leaf\n"); - if (verbose) { - struct gfs_leaf lf; - gfs_leaf_in(&lf, data); - gfs_leaf_print(&lf); - if (verbose > 1) - print_dirents(data, sizeof(struct gfs_leaf)); - } - break; - - case GFS_METATYPE_JD: - printf("Journaled Data\n"); - if (verbose) - gfs_meta_header_print(&mh); - break; - - case GFS_METATYPE_LH: - printf("Log Header\n"); - if (verbose) { - struct gfs_log_header lh; - gfs_log_header_in(&lh, data); - gfs_log_header_print(&lh); - } - break; - - case GFS_METATYPE_LD: - printf("Lock Descriptor\n"); - if (verbose) { - struct gfs_log_descriptor ld; - gfs_desc_in(&ld, data); - gfs_desc_print(&ld); - } - break; - - case GFS_METATYPE_EA: - printf("Extended Attribute\n"); - if (verbose) - gfs_meta_header_print(&mh); - break; - - default: - printf("Unknown metadata type\n"); - if (verbose) - gfs_meta_header_print(&mh); - break; - } - - free(data); -} - diff --git a/gfs/gfs_debug/basic.h b/gfs/gfs_debug/basic.h deleted file mode 100644 index 741d59b..0000000 --- a/gfs/gfs_debug/basic.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __BASIC_DOT_H__ -#define __BASIC_DOT_H__ - - -EXTERN unsigned int sd_diptrs INIT(0); -EXTERN unsigned int sd_inptrs INIT(0); -EXTERN unsigned int sd_jbsize INIT(0); -EXTERN unsigned int sd_hash_bsize INIT(0); -EXTERN unsigned int sd_hash_ptrs INIT(0); -EXTERN uint32_t sd_max_height INIT(0); -EXTERN uint64_t sd_heightsize[GFS_MAX_META_HEIGHT]; -EXTERN uint32_t sd_max_jheight INIT(0); -EXTERN uint64_t sd_jheightsize[GFS_MAX_META_HEIGHT]; - - -void verify_gfs(void); -void must_be_gfs(void); -void scan_device(void); -void print_superblock(void); -void identify_block(void); - -void print_dirents(char *data, unsigned int offset); - - -#endif /* __BASIC_DOT_H__ */ - diff --git a/gfs/gfs_debug/block_device.c b/gfs/gfs_debug/block_device.c deleted file mode 100644 index ef608a3..0000000 --- a/gfs/gfs_debug/block_device.c +++ /dev/null @@ -1,130 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include "gfs_debug.h" -#include "block_device.h" - -/** - * find_device_size - - * - */ - -void -find_device_size(void) -{ - device_size = lseek(device_fd, 0, SEEK_END); - if (device_size < 0) - die("can't determine device size: %s\n", - strerror(errno)); -} - -/** - * get_block - - * @bn: - * @fatal: - * - * Returns: the data in the block (needs to be freed) - */ - -char * -get_block(uint64_t bn, int fatal) -{ - char *data; - - if (device_size < (bn + 1) * block_size) { - fprintf(stderr, "%s: block %"PRIu64" is off the end of the device\n", - prog_name, bn); - if (fatal) - exit(EXIT_FAILURE); - } - - data = malloc(block_size); - if (!data) - die("out of memory (%s, %u)\n", - __FILE__, __LINE__); - - do_lseek(device_fd, bn * block_size); - do_read(device_fd, data, block_size); - - return data; -} - -/** - * print_size - - * - */ - -void -print_size(void) -{ - printf("%"PRIu64"\n", device_size); -} - -/** - * print_hexblock - - * - */ - -void -print_hexblock(void) -{ - char *data; - unsigned int x; - - if (!block_size) - die("no block size set\n"); - - data = get_block(block_number, TRUE); - - for (x = 0; x < block_size; x++) { - printf("%.2X", ((unsigned char *)data)[x]); - if (x % 16 == 15) - printf("\n"); - else - printf(" "); - } - - if (x % 16) - printf("\n"); - - free(data); -} - -/** - * print_rawblock - - * - */ - -void -print_rawblock(void) -{ - char *data; - - if (!block_size) - die("no block size set\n"); - - data = get_block(block_number, TRUE); - do_write(STDOUT_FILENO, data, block_size); - free(data); -} diff --git a/gfs/gfs_debug/block_device.h b/gfs/gfs_debug/block_device.h deleted file mode 100644 index a4e0a3c..0000000 --- a/gfs/gfs_debug/block_device.h +++ /dev/null @@ -1,27 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __BLOCK_DEVICE_DOT_H__ -#define __BLOCK_DEVICE_DOT_H__ - - -void find_device_size(void); -char *get_block(uint64_t bn, int fatal); - -void print_size(void); -void print_hexblock(void); -void print_rawblock(void); - - -#endif /* __BLOCK_DEVICE_DOT_H__ */ - diff --git a/gfs/gfs_debug/gfs_debug.h b/gfs/gfs_debug/gfs_debug.h deleted file mode 100644 index 12d5343..0000000 --- a/gfs/gfs_debug/gfs_debug.h +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFS_DEBUG_DOT_H__ -#define __GFS_DEBUG_DOT_H__ - - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef EXTERN -#define EXTERN extern -#define INIT(X) -#else -#undef EXTERN -#define EXTERN -#define INIT(X) =X -#endif - - -#define die(fmt, args...) \ -do { \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} while (0) - -#define ASSERT(x, todo) \ -do { \ - if (!(x)) { \ - {todo} \ - die("assertion failed on line %d of file %s\n", \ - __LINE__, __FILE__); \ - } \ -} while (0) - -EXTERN char *prog_name; - -#define do_lseek(fd, off) \ -do { \ - if (lseek((fd), (off), SEEK_SET) != (off)) \ - die("bad seek on line %d of file %s: %s\n", \ - __LINE__, __FILE__, strerror(errno)); \ -} while (0) - -#define do_read(fd, buff, len) \ -do { \ - if (read((fd), (buff), (len)) != (len)) \ - die("bad read on line %d of file %s: %s\n", \ - __LINE__, __FILE__, strerror(errno)); \ -} while (0) - -#define do_write(fd, buff, len) \ -do { \ - if (write((fd), (buff), (len)) != (len)) \ - die("bad write on line %d of file %s: %s\n", \ - __LINE__, __FILE__, strerror(errno)); \ -} while (0) - -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) - - -/* Command line arguments */ - -EXTERN unsigned int verbose INIT(0); - -EXTERN char *action INIT(NULL); - -EXTERN char *device INIT(NULL); -EXTERN int device_fd INIT(-1); -EXTERN off_t device_size INIT(-1); - -EXTERN int is_gfs INIT(FALSE); -EXTERN unsigned int block_size INIT(0); -EXTERN unsigned int block_size_shift INIT(0); - -EXTERN uint64_t block_number INIT(0); - - -#endif /* __GFS_DEBUG_DOT_H__ */ - diff --git a/gfs/gfs_debug/main.c b/gfs/gfs_debug/main.c deleted file mode 100644 index 97cefeb..0000000 --- a/gfs/gfs_debug/main.c +++ /dev/null @@ -1,192 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> -#include "copyright.cf" - -#define EXTERN -#include "gfs_debug.h" -#include "basic.h" -#include "block_device.h" -#include "readfile.h" - -/** - * print_usage - print out usage information - * - */ - -static void -print_usage(void) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options] <action>\n", prog_name); - printf("\n"); - printf("Actions:\n"); - printf(" size print the device size\n"); - printf(" hexread print a block in hex\n"); - printf(" rawread print a block raw\n"); - printf("\n"); - printf("GFS-specific Actions:\n"); - printf(" scan scan the device looking for GFS blocks\n"); - printf(" identify identify the contents of a block\n"); - printf(" sb print superblock\n"); - printf(" jindex print journal index\n"); - printf(" rindex print resource index\n"); - printf(" quota print quota file\n"); - printf(" root print root directory\n"); - printf(" readfile print the contents of a file\n"); - printf(" readdir print the contents of a directory\n"); - printf("\n"); - printf("Options:\n"); - printf("\n"); - printf(" -B <bytes> Set the block size\n"); - printf(" -b <number> Block number\n"); - printf(" -d <device> Device to look at\n"); - printf(" -h Print this help, then exit\n"); - printf(" -v Verbose\n"); - printf(" -V Print program version information, then exit\n"); -} - -/** - * decode_arguments - - * @argc: - * @argv: - * - */ - -static void -decode_arguments(int argc, char *argv[]) -{ - int cont = TRUE; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, "B:b:d:hVv"); - - switch (optchar) { - case 'B': - sscanf(optarg, "%u", &block_size); - if (!block_size) - die("can't have a zero block size\n"); - break; - - case 'b': - sscanf(optarg, "%"SCNu64, &block_number); - break; - - case 'd': - device = optarg; - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - - case 'V': - printf("gfs_mkfs %s (built %s %s)\n", GFS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - - case 'v': - verbose++; - break; - - case EOF: - cont = FALSE; - break; - - default: - die("unknown option: %c\n", optchar); - }; - } - - if (optind < argc) { - action = argv[optind]; - optind++; - } else - die("no action specified\n"); - - if (optind < argc) - die("Unrecognized option: %s\n", argv[optind]); - - if (!device) - die("no device specified\n"); -} - -/** - * main - - * @argc: - * @argv: - * - * Returns: exit status - */ - -int -main(int argc, char *argv[]) -{ - prog_name = argv[0]; - - decode_arguments(argc, argv); - - device_fd = open(device, O_RDWR); - if (device_fd < 0) - die("can't open device %s: %s\n", - device, strerror(errno)); - - find_device_size(); - verify_gfs(); - - if (!strcmp(action, "size")) - print_size(); - else if (!strcmp(action, "hexread")) - print_hexblock(); - else if (!strcmp(action, "rawread")) - print_rawblock(); - else if (!strcmp(action, "scan")) - scan_device(); - else if (!strcmp(action, "identify")) - identify_block(); - else if (!strcmp(action, "sb")) - print_superblock(); - else if (!strcmp(action, "jindex")) - print_jindex(); - else if (!strcmp(action, "rindex")) - print_rindex(); - else if (!strcmp(action, "quota")) - print_quota(); - else if (!strcmp(action, "root")) - print_root(); - else if (!strcmp(action, "readfile")) - readfile(); - else if (!strcmp(action, "readdir")) - readdir(); - else - die("unknown action %s\n", action); - - close(device_fd); - - exit(EXIT_SUCCESS); -} - diff --git a/gfs/gfs_debug/ondisk.c b/gfs/gfs_debug/ondisk.c deleted file mode 100644 index 082bd7c..0000000 --- a/gfs/gfs_debug/ondisk.c +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> - diff --git a/gfs/gfs_debug/readfile.c b/gfs/gfs_debug/readfile.c deleted file mode 100644 index 651e441..0000000 --- a/gfs/gfs_debug/readfile.c +++ /dev/null @@ -1,249 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> -#include "linux_endian.h" - -#include "gfs_debug.h" -#include "basic.h" -#include "block_device.h" -#include "readfile.h" -#include "util.h" - -void -print_jindex(void) -{ - struct gfs_sb sb; - struct gfs_dinode di; - struct gfs_jindex ji; - char *data; - char buf[sizeof(struct gfs_jindex)]; - uint64_t o; - unsigned int x; - int error; - - must_be_gfs(); - - data = get_block(GFS_SB_ADDR * GFS_BASIC_BLOCK / block_size, TRUE); - gfs_sb_in(&sb, data); - free(data); - - data = get_block(sb.sb_jindex_di.no_addr, TRUE); - gfs_dinode_in(&di, data); - free(data); - - if (di.di_size % sizeof(struct gfs_jindex)) - fprintf(stderr, "%s: strange size for journal index %"PRIu64"\n", - prog_name, di.di_size); - - for (o = 0, x = 0;; o += sizeof(struct gfs_jindex), x++) { - error = gfs_readi(&di, buf, o, sizeof(struct gfs_jindex)); - if (!error) - break; - if (error < sizeof(struct gfs_jindex)) - continue; - gfs_jindex_in(&ji, buf); - printf("Journal %u:\n", x); - gfs_jindex_print(&ji); - printf("\n"); - } -} - -void -print_rindex(void) -{ - struct gfs_sb sb; - struct gfs_dinode di; - struct gfs_rindex ri; - char *data; - char buf[sizeof(struct gfs_rindex)]; - uint64_t o; - unsigned int x; - int error; - - must_be_gfs(); - - data = get_block(GFS_SB_ADDR * GFS_BASIC_BLOCK / block_size, TRUE); - gfs_sb_in(&sb, data); - free(data); - - data = get_block(sb.sb_rindex_di.no_addr, TRUE); - gfs_dinode_in(&di, data); - free(data); - - if (di.di_size % sizeof(struct gfs_rindex)) - fprintf(stderr, "%s: strange size for resource index %"PRIu64"\n", - prog_name, di.di_size); - - for (o = 0, x = 0;; o += sizeof(struct gfs_rindex), x++) { - error = gfs_readi(&di, buf, o, sizeof(struct gfs_rindex)); - if (!error) - break; - if (error < sizeof(struct gfs_rindex)) - continue; - gfs_rindex_in(&ri, buf); - printf("Resource Group %u:\n", x); - gfs_rindex_print(&ri); - printf("\n"); - } -} - -void -print_quota(void) -{ - struct gfs_sb sb; - struct gfs_dinode di; - struct gfs_quota qu; - char *data; - char buf[sizeof(struct gfs_quota)]; - uint64_t o; - unsigned int x; - int error; - - must_be_gfs(); - - data = get_block(GFS_SB_ADDR * GFS_BASIC_BLOCK / block_size, TRUE); - gfs_sb_in(&sb, data); - free(data); - - data = get_block(sb.sb_quota_di.no_addr, TRUE); - gfs_dinode_in(&di, data); - free(data); - - for (o = 0, x = 0;; o += sizeof(struct gfs_quota), x++) { - error = gfs_readi(&di, buf, o, sizeof(struct gfs_quota)); - if (!error) - break; - if (error < 0) - continue; - gfs_quota_in(&qu, buf); - - if (!qu.qu_limit && !qu.qu_warn && !qu.qu_value) - continue; - - printf("Quota (%s, %u):\n", (x % 2) ? "group" : "user", x / 2); - gfs_quota_print(&qu); - printf("\n"); - } -} - -void -print_root(void) -{ - struct gfs_sb sb; - char *data; - - must_be_gfs(); - - data = get_block(GFS_SB_ADDR * GFS_BASIC_BLOCK / block_size, TRUE); - gfs_sb_in(&sb, data); - free(data); - - block_number = sb.sb_root_di.no_addr; - - readdir(); -} - -#define CHUNKSIZE (65536) - -void -readfile(void) -{ - struct gfs_dinode di; - char *data; - char buf[CHUNKSIZE]; - uint64_t o = 0; - int error; - - must_be_gfs(); - - data = get_block(block_number, TRUE); - gfs_dinode_in(&di, data); - free(data); - - if (di.di_header.mh_magic != GFS_MAGIC || - di.di_header.mh_type != GFS_METATYPE_DI) - die("block %"PRIu64" isn't an inode\n", - block_number); - - if (di.di_type != GFS_FILE_REG) - die("block %"PRIu64" isn't a regular file\n", - block_number); - - for (;;) { - error = gfs_readi(&di, buf, o, CHUNKSIZE); - if (error <= 0) - break; - write(STDOUT_FILENO, buf, error); - o += error; - } -} - -static void -do_readdir(struct gfs_dinode *di, char *data, - uint32_t index, uint32_t len, uint64_t leaf_no, - void *opaque) -{ - struct gfs_leaf leaf; - - print_dirents(data, sizeof(struct gfs_leaf)); - gfs_leaf_in(&leaf, data); - - while (leaf.lf_next) { - data = get_block(leaf.lf_next, FALSE); - if (!data) - return; - print_dirents(data, sizeof(struct gfs_leaf)); - gfs_leaf_in(&leaf, data); - free(data); - } -} - -void -readdir(void) -{ - struct gfs_dinode di; - char *data; - - must_be_gfs(); - - data = get_block(block_number, TRUE); - gfs_dinode_in(&di, data); - - if (di.di_header.mh_magic != GFS_MAGIC || - di.di_header.mh_type != GFS_METATYPE_DI) - die("block %"PRIu64" isn't an inode\n", - block_number); - - if (di.di_type != GFS_FILE_DIR) - die("block %"PRIu64" isn't a directory\n", - block_number); - - if (di.di_flags & GFS_DIF_EXHASH) - foreach_leaf(&di, do_readdir, NULL); - else - print_dirents(data, sizeof(struct gfs_dinode)); - - free(data); -} diff --git a/gfs/gfs_debug/readfile.h b/gfs/gfs_debug/readfile.h deleted file mode 100644 index 8d0400e..0000000 --- a/gfs/gfs_debug/readfile.h +++ /dev/null @@ -1,27 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __READFILE_DOT_H__ -#define __READFILE_DOT_H__ - - -void print_jindex(void); -void print_rindex(void); -void print_quota(void); -void print_root(void); -void readfile(void); -void readdir(void); - - -#endif /* __READFILE_DOT_H__ */ - diff --git a/gfs/gfs_debug/util.c b/gfs/gfs_debug/util.c deleted file mode 100644 index b5e8f64..0000000 --- a/gfs/gfs_debug/util.c +++ /dev/null @@ -1,347 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> -#include "linux_endian.h" - -#include "gfs_debug.h" -#include "basic.h" -#include "block_device.h" -#include "util.h" - -int -check_type(char *data, unsigned int type) -{ - struct gfs_meta_header mh; - - gfs_meta_header_in(&mh, data); - if (mh.mh_magic != GFS_MAGIC || - mh.mh_type != type) { - fprintf(stderr, "%s: expected metadata type %u\n", - prog_name, type); - return -1; - } - return 0; -} - -/** - * recursive_scan - call a function for each block pointer in a file - * @di: - * @height: - * @bn: - * @pc: - * @opaque: - * - */ - -void -recursive_scan(struct gfs_dinode *di, - unsigned int height, uint64_t bn, - pointer_call_t pc, void *opaque) -{ - char *data = NULL; - uint64_t *top, *bottom; - uint64_t x; - - if (!height) { - data = get_block(di->di_num.no_addr, TRUE); - - top = (uint64_t *)(data + sizeof(struct gfs_dinode)); - bottom = (uint64_t *)(data + sizeof(struct gfs_dinode)) + sd_diptrs; - } else { - data = get_block(bn, FALSE); - if (!data) - return; - if (check_type(data, GFS_METATYPE_IN)) - return; - - top = (uint64_t *)(data + sizeof(struct gfs_indirect)); - bottom = (uint64_t *)(data + sizeof(struct gfs_indirect)) + sd_inptrs; - } - - for ( ; top < bottom; top++) { - x = gfs64_to_cpu(*top); - - pc(di, height, x, opaque); - - if (x && height < di->di_height - 1) - recursive_scan(di, - height + 1, x, - pc, opaque); - } - - free(data); -} - -void -foreach_leaf(struct gfs_dinode *di, - leaf_call_t lc, void *opaque) -{ - char *data; - struct gfs_leaf leaf; - uint32_t hsize, len; - uint32_t ht_offset, lp_offset, ht_offset_cur = -1; - uint32_t index = 0; - uint64_t lp[sd_hash_ptrs]; - uint64_t leaf_no; - int error; - - hsize = 1 << di->di_depth; - if (hsize * sizeof(uint64_t) != di->di_size) - die("bad hash table size\n"); - - while (index < hsize) { - lp_offset = index % sd_hash_ptrs; - ht_offset = index - lp_offset; - - if (ht_offset_cur != ht_offset) { - error = gfs_readi(di, (char *)lp, ht_offset * sizeof(uint64_t), sd_hash_bsize); - if (error != sd_hash_bsize) - die("FixMe!!!\n"); - ht_offset_cur = ht_offset; - } - - leaf_no = gfs64_to_cpu(lp[lp_offset]); - if (!leaf_no) - die("NULL leaf pointer\n"); - - data = get_block(leaf_no, TRUE); - gfs_leaf_in(&leaf, data); - len = 1 << (di->di_depth - leaf.lf_depth); - - lc(di, data, index, len, leaf_no, opaque); - - free(data); - index += len; - } - - if (index != hsize) - die("screwed up directory\n"); -} - -static unsigned int -calc_tree_height(struct gfs_dinode *di, uint64_t size) -{ - uint64_t *arr; - unsigned int max, height; - - if (di->di_size > size) - size = di->di_size; - - if (di->di_flags & GFS_DIF_JDATA) { - arr = sd_jheightsize; - max = sd_max_jheight; - } else { - arr = sd_heightsize; - max = sd_max_height; - } - - for (height = 0; height < max; height++) - if (arr[height] >= size) - break; - - return height; -} - -struct metapath { - unsigned int mp_list[GFS_MAX_META_HEIGHT]; -}; - -static struct metapath * -find_metapath(struct gfs_dinode *di, uint64_t block) -{ - struct metapath *mp; - uint64_t b = block; - unsigned int i; - - mp = malloc(sizeof(struct metapath)); - if (!mp) - die("out of memory (%s, %u)\n", - __FILE__, __LINE__); - memset(mp, 0, sizeof(struct metapath)); - - for (i = di->di_height; i--;) { - mp->mp_list[i] = b % sd_inptrs; - b /= sd_inptrs; - } - - return mp; -} - -static uint64_t -lookup_block(char *data, unsigned int height, - struct metapath *mp) -{ - unsigned int head_size; - uint64_t block; - - head_size = (height > 0) ? - sizeof(struct gfs_indirect) : sizeof(struct gfs_dinode); - block = *(((uint64_t *)(data + head_size)) + mp->mp_list[height]); - - if (block) - return gfs64_to_cpu(block); - else - return 0; -} - -int -gfs_block_map(struct gfs_dinode *di, - uint64_t lblock, uint64_t *dblock) -{ - unsigned int bsize; - unsigned int height; - struct metapath *mp; - unsigned int end_of_metadata; - char *data; - unsigned int x; - int error = 0; - - *dblock = 0; - - if (!di->di_height) { - if (!lblock) - *dblock = di->di_num.no_addr; - return 0; - } - - bsize = (di->di_flags & GFS_DIF_JDATA) ? sd_jbsize : block_size; - - height = calc_tree_height(di, (lblock + 1) * bsize); - if (di->di_height < height) - return 0; - - mp = find_metapath(di, lblock); - end_of_metadata = di->di_height - 1; - - data = get_block(di->di_num.no_addr, TRUE); - - for (x = 0; x < end_of_metadata; x++) { - *dblock = lookup_block(data, x, mp); - free(data); - if (!*dblock) - goto out; - - data = get_block(*dblock, FALSE); - if (!data) { - error = -1; - goto out; - } - } - - *dblock = lookup_block(data, x, mp); - - free(data); - - out: - free(mp); - - return error; -} - -static int -copy2mem(char *data, void **buf, - unsigned int offset, unsigned int size) -{ - char **p = (char **)buf; - - if (data) - memcpy(*p, data + offset, size); - else - memset(*p, 0, size); - - *p += size; - - return 0; -} - -int -gfs_readi(struct gfs_dinode *di, void *buf, - uint64_t offset, unsigned int size) -{ - int journaled = (di->di_flags & GFS_DIF_JDATA); - uint64_t lblock, dblock; - unsigned int o; - unsigned int amount; - char *data; - int copied = 0; - int error = 0; - - if (offset >= di->di_size) - return 0; - - if ((offset + size) > di->di_size) - size = di->di_size - offset; - - if (!size) - return 0; - - if (journaled) { - lblock = offset / sd_jbsize; - o = offset % sd_jbsize; - } else { - lblock = offset >> block_size_shift; - o = offset & (block_size - 1); - } - - if (!di->di_height) - o += sizeof(struct gfs_dinode); - else if (journaled) - o += sizeof(struct gfs_meta_header); - - while (copied < size) { - amount = size - copied; - if (amount > block_size - o) - amount = block_size - o; - - error = gfs_block_map(di, lblock, &dblock); - if (error) - goto fail; - - if (dblock) { - data = get_block(dblock, FALSE); - if (!data) { - error = -1; - goto fail; - } - } else - data = NULL; - - copy2mem(data, &buf, o, amount); - - if (data) - free(data); - - copied += amount; - lblock++; - - o = (journaled) ? sizeof(struct gfs_meta_header) : 0; - } - - return copied; - - fail: - return (copied) ? copied : error; -} - diff --git a/gfs/gfs_debug/util.h b/gfs/gfs_debug/util.h deleted file mode 100644 index cf5bbbf..0000000 --- a/gfs/gfs_debug/util.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UTIL_DOT_H__ -#define __UTIL_DOT_H__ - - -int check_type(char *data, unsigned int type); - - -typedef void (*pointer_call_t)(struct gfs_dinode *di, - unsigned int height, uint64_t bn, - void *opaque); -void recursive_scan(struct gfs_dinode *di, - unsigned int height, uint64_t bn, - pointer_call_t pc, void *opaque); - -typedef void (*leaf_call_t)(struct gfs_dinode *di, char *data, - uint32_t index, uint32_t len, uint64_t leaf_no, - void *opaque); -void foreach_leaf(struct gfs_dinode *di, - leaf_call_t lc, void *opaque); - - -int gfs_block_map(struct gfs_dinode *di, - uint64_t lblock, uint64_t *dblock); -int gfs_readi(struct gfs_dinode *di, void *buf, - uint64_t offset, unsigned int size); - - -#endif /* __UTIL_DOT_H__ */ - diff --git a/gfs/gfs_edit/Makefile b/gfs/gfs_edit/Makefile deleted file mode 100644 index f38c859..0000000 --- a/gfs/gfs_edit/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= gfs_edit - -SOURCE= \ - gfshex.c \ - hexedit.c - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -all: gfs_edit - -gfs_edit: ${SOURCE} - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -lncurses -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} - - diff --git a/gfs/gfs_edit/gfshex.c b/gfs/gfs_edit/gfshex.c deleted file mode 100644 index f69a209..0000000 --- a/gfs/gfs_edit/gfshex.c +++ /dev/null @@ -1,356 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <curses.h> - -#include "global.h" -#include "hexedit.h" -#include "linux_endian.h" - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> - -#include "gfshex.h" - -extern int line; -extern struct gfs_sb sb; -extern char *buf; -extern struct gfs_dinode di; -extern uint64 bufsize; - -/****************************************************************************** -******************************************************************************* -** -** do_dinode_extended() -** -** Description: -** -** Input(s): -** -** Output(s): -** -** Returns: -** -******************************************************************************* -******************************************************************************/ - -void do_dinode_extended(struct gfs_dinode *di, char *buf) -{ - unsigned int x, y, count; - struct gfs_dirent de; - uint64 p, last; - - indirect_blocks = 0; - memset(indirect_block, 0, sizeof(indirect_block)); - if (di->di_height > 0) { - /* Indirect pointers */ - for (x = sizeof(struct gfs_dinode), y = 0; - x < bufsize; - x += sizeof(uint64), y++) { - p = gfs64_to_cpu(*(uint64 *)(buf + x)); - if (p) - indirect_block[indirect_blocks++] = p; - } - } - else if (di->di_type == GFS_FILE_DIR && - !(di->di_flags & GFS_DIF_EXHASH)) { - /* Directory Entries: */ - for (x = sizeof(struct gfs_dinode); x < bufsize; x += de.de_rec_len) { - gfs_dirent_in(&de, buf + x); - if (de.de_inum.no_formal_ino) - indirect_block[indirect_blocks++] = de.de_inum.no_formal_ino; - } - } - else if (di->di_type == GFS_FILE_DIR && - (di->di_flags & GFS_DIF_EXHASH) && - di->di_height == 0) { - /* Leaf Pointers: */ - - last = gfs64_to_cpu(*(uint64 *)(buf + sizeof(struct gfs_dinode))); - count = 0; - - for (x = sizeof(struct gfs_dinode), y = 0; - y < (1 << di->di_depth); - x += sizeof(uint64), y++) { - p = gfs64_to_cpu(*(uint64 *)(buf + x)); - - if (p != last) { - indirect_block[indirect_blocks++] = last; - /*printf(" %u: %"PRIu64"\n", count, last);*/ - last = p; - count = 1; - } - else - count++; - - if ((y + 1) * sizeof(uint64) == di->di_size) - indirect_block[indirect_blocks++] = last; - ; /*printf(" %u: %"PRIu64"\n", count, last);*/ - } - } -} - - -/****************************************************************************** -******************************************************************************* -** -** do_indirect_extended() -** -** Description: -** -** Input(s): -** -** Output(s): -** -** Returns: -** -******************************************************************************* -******************************************************************************/ - -void do_indirect_extended(char *buf) -{ - unsigned int x, y; - uint64 p; - - printf("\nPointers\n\n"); - - for (x = sizeof(struct gfs_indirect), y = 0; x < bufsize; x += 8, y++) - { - p = gfs64_to_cpu(*(uint64 *)(buf + x)); - - if (p) - printf(" %u -> %"PRIu64"\n", y, p); - } -} - - -/****************************************************************************** -******************************************************************************* -** -** do_leaf_extended() -** -** Description: -** -** Input(s): -** -** Output(s): -** -** Returns: -** -******************************************************************************* -******************************************************************************/ - -void do_leaf_extended(char *buf) -{ - struct gfs_dirent de; - unsigned int x; - - - printf("\nDirectory Entries:\n"); - - for (x = sizeof(struct gfs_leaf); x < bufsize; x += de.de_rec_len) - { - printf("\n"); - gfs_dirent_in(&de, buf + x); - if (de.de_inum.no_formal_ino) - gfs_dirent_print(&de, buf + x + sizeof(struct gfs_dirent)); - } -} - - -/****************************************************************************** -******************************************************************************* -** -** do_eattr_extended() -** -** Description: -** -** Input(s): -** -** Output(s): -** -** Returns: -** -******************************************************************************* -******************************************************************************/ - -void do_eattr_extended(char *buf) -{ - struct gfs_ea_header ea; - unsigned int x; - - - printf("\nEattr Entries:\n"); - - for (x = sizeof(struct gfs_meta_header); x < bufsize; x += ea.ea_rec_len) - { - printf("\n"); - gfs_ea_header_in(&ea, buf + x); - gfs_ea_header_print(&ea, buf + x + sizeof(struct gfs_ea_header)); - } -} - -void gfs_inum_print2(const char *title,struct gfs_inum *no) -{ - move(line,2); - printw(title); - pv2(no, no_formal_ino, "%"PRIX64); - pv2(no, no_addr, "%"PRIX64); -} - -/** - * gfs_sb_print2 - Print out a superblock - * @sb: the cpu-order buffer - */ -void gfs_sb_print2(struct gfs_sb *sb) -{ - gfs_meta_header_print(&sb->sb_header); - - pv(sb, sb_fs_format, "%u"); - pv(sb, sb_multihost_format, "%u"); - pv(sb, sb_flags, "%u"); - - pv(sb, sb_bsize, "%u"); - pv(sb, sb_bsize_shift, "%u"); - pv(sb, sb_seg_size, "%u"); - - gfs_inum_print2("jindex inode",&sb->sb_jindex_di); - gfs_inum_print2("rindex inode",&sb->sb_rindex_di); - gfs_inum_print2("root inode",&sb->sb_root_di); - - pv(sb, sb_lockproto, "%s"); - pv(sb, sb_locktable, "%s"); - - gfs_inum_print2("quota inode",&sb->sb_quota_di); - gfs_inum_print2("license inode",&sb->sb_license_di); - - pa(sb, sb_reserved, 96); -} - -/****************************************************************************** -******************************************************************************* -** -** int display_gfs() -** -** Description: -** This routine... -** -** Input(s): -** *buffer - -** extended - -** -** Returns: -** 0 if OK, 1 on error. -** -******************************************************************************* -******************************************************************************/ -int display_gfs(void) -{ - struct gfs_meta_header mh; - struct gfs_rgrp rg; - struct gfs_leaf lf; - struct gfs_log_header lh; - struct gfs_log_descriptor ld; - - uint32 magic; - - magic = gfs32_to_cpu(*(uint32 *)buf); - - switch (magic) - { - case GFS_MAGIC: - gfs_meta_header_in(&mh, buf); - - switch (mh.mh_type) - { - case GFS_METATYPE_SB: - printw("Superblock:\n\n"); - gfs_sb_in(&sb, buf); - gfs_sb_print2(&sb); - break; - - case GFS_METATYPE_RG: - printw("Resource Group Header:\n\n"); - gfs_rgrp_in(&rg, buf); - gfs_rgrp_print(&rg); - break; - - case GFS_METATYPE_RB: - printw("Resource Group Bitmap:\n\n"); - gfs_meta_header_print(&mh); - break; - - case GFS_METATYPE_DI: - printw("Dinode:\n\n"); - gfs_dinode_print(&di); - break; - - case GFS_METATYPE_LF: - printw("Leaf:\n\n"); - gfs_leaf_in(&lf, buf); - gfs_leaf_print(&lf); - break; - - case GFS_METATYPE_IN: - printw("Indirect Block:\n\n"); - gfs_meta_header_print(&mh); - break; - - case GFS_METATYPE_JD: - printf("Journaled File Block:\n\n"); - gfs_meta_header_print(&mh); - break; - - case GFS_METATYPE_LH: - printw("Log Header:\n\n"); - gfs_log_header_in(&lh, buf); - gfs_log_header_print(&lh); - break; - - - case GFS_METATYPE_LD: - printw("Log Descriptor:\n\n"); - gfs_desc_in(&ld, buf); - gfs_desc_print(&ld); - break; - - case GFS_METATYPE_EA: - printw("Eattr Block:\n\n"); - gfs_meta_header_print(&mh); - break; - - case GFS_METATYPE_ED: - printw("Eattr Data Block:\n\n"); - gfs_meta_header_print(&mh); - break; - - default: - printw("Unknown metadata type\n"); - break; - } - break; - - default: - printw("Unknown block type\n"); - break; - }; - return(0); -} diff --git a/gfs/gfs_edit/gfshex.h b/gfs/gfs_edit/gfshex.h deleted file mode 100644 index db93576..0000000 --- a/gfs/gfs_edit/gfshex.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFSHEX_DOT_H__ -#define __GFSHEX_DOT_H__ - - -int display_gfs(void); -int edit_gfs(void); -void do_dinode_extended(struct gfs_dinode *di, char *buf); - - -#endif /* __GFSHEX_DOT_H__ */ diff --git a/gfs/gfs_edit/hexedit.c b/gfs/gfs_edit/hexedit.c deleted file mode 100644 index 65380e7..0000000 --- a/gfs/gfs_edit/hexedit.c +++ /dev/null @@ -1,827 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <curses.h> -#include <term.h> -#include <signal.h> -#include <sys/ioctl.h> -#include <sys/mount.h> - -#include "global.h" -#include <linux/gfs_ondisk.h> -#include "copyright.cf" - -#define EXTERN -#include "hexedit.h" -#include "gfshex.h" -#include "linux/gfs_ondisk.h" -#include "linux_endian.h" - -#include <syslog.h> - -#define TITLE1 "gfs_edit - Global File System Editor (use with extreme caution)" -#define TITLE2 "Copyright (C) 2006 Red Hat, Inc. - Press H for help" - -int display(void); - -/* ------------------------------------------------------------------------ */ -/* UpdateSize - screen size changed, so update it */ -/* ------------------------------------------------------------------------ */ -void UpdateSize(int sig) -{ - static char term_buffer[2048]; - int rc; - - termlines=30; - termtype=getenv("TERM"); - if (termtype==NULL) - return; - rc=tgetent(term_buffer,termtype); - if (rc>=0) { - termlines=tgetnum("li"); - if (termlines<10) - termlines=30; - } - else - perror("Error: tgetent failed."); - termlines--; /* last line is number of lines -1 */ - display(); - signal(SIGWINCH, UpdateSize); -} - -/* ------------------------------------------------------------------------- */ -/* display_title_lines */ -/* ------------------------------------------------------------------------- */ -void display_title_lines(void) -{ - clear(); - attrset(COLOR_PAIR(1)); - move(0, 0); - printw("%-80s",TITLE1); - move(termlines, 0); - printw("%-79s",TITLE2); - attrset(COLOR_PAIR(2)); -} - -/* ------------------------------------------------------------------------- */ -/* bobgets - get a string */ -/* returns: 1 if user exited by hitting enter */ -/* 0 if user exited by hitting escape */ -/* ------------------------------------------------------------------------- */ -int bobgets(char string[],int x,int y,int sz) -{ - int done,ch,runningy,rc; - - move(x,y); - done=FALSE; - attrset(COLOR_PAIR(3)); - move(x,y); - addstr(string); - move(x,y); - curs_set(2); - refresh(); - runningy=y; - rc=0; - while (!done) { - ch=getch(); - - if(ch < 0x0100 && isprint(ch)) { - char *p=string+strlen(string); // end of the string - *(p+1)='\0'; - while (insert && p > &string[runningy-y]) { - *p=*(p-1); - p--; - } - string[runningy-y]=ch; - runningy++; - move(x,y); - addstr(string); - } - else { - // special character, is it one we recognize? - switch(ch) - { - case(KEY_ENTER): - case('\n'): - case('\r'): - rc=1; - done=TRUE; - break; - case(KEY_CANCEL): - case(0x01B): - rc=0; - done=TRUE; - break; - case(KEY_LEFT): - if (runningy>y) - runningy--; - break; - case(KEY_RIGHT): - runningy++; - break; - case(KEY_DC): - case(0x07F): - if (runningy>=y) { - char *p=&string[runningy-y]; - while (*p) - *p++=*(p+1); - *p='\0'; - runningy--; - // remove the character from the string - move(x,y); - addstr(string); - attrset(COLOR_PAIR(2)); - addstr(" "); - attrset(COLOR_PAIR(3)); - runningy++; - } - break; - case(KEY_BACKSPACE): - if (runningy>y) { - char *p=&string[runningy-y-1]; - while (*p) - *p++=*(p+1); - *p='\0'; - runningy--; - // remove the character from the string - move(x,y); - addstr(string); - attrset(COLOR_PAIR(2)); - addstr(" "); - attrset(COLOR_PAIR(3)); - } - break; - case KEY_DOWN: // Down - rc=0x5000U; - done=TRUE; - break; - case KEY_UP: // Up - rc=0x4800U; - done=TRUE; - break; - case 0x014b: - insert=!insert; - move(0,68); - if (insert) - printw("insert "); - else - printw("replace"); - break; - default: - move(0,70); - printw("%08X",ch); - // ignore all other characters - break; - } // end switch on non-printable character - } // end non-printable character - move(x,runningy); - refresh(); - } // while !done - if (sz>0) - string[sz]='\0'; - attrset(COLOR_PAIR(2)); - return rc; -}/* bobgets */ - -/****************************************************************************** -******************************************************************************* -** -** void print_usage() -** -** Description: -** This routine prints out the appropriate commands for this application. -** -******************************************************************************* -******************************************************************************/ - -void print_usage(void) -{ - int ch; - - line = 2; - clear(); - display_title_lines(); - move(line++,0); - printw("Supported commands: (roughly conforming to the rules of 'less')"); - line++; - move(line++,0); - printw(" b - Backward one 4K block"); - move(line++,0); - printw(" f - Forward one 4K block"); - move(line++,0); - printw(" g - Goto a given block in hex"); - move(line++,0); - printw(" h - This Help display"); - move(line++,0); - printw(" j - Jump to the highlighted 64-bit block number."); - move(line++,0); - printw(" m - Switch display mode: hex -> GFS structure -> Extended"); - move(line++,0); - printw(" q - Quit (same as hitting <escape> key)"); - move(line++,0); - printw("<space> - Forward one 4K block (same as 'f')"); - move(line++,0); - printw("<pg up>/<down> - move up or down one screen full"); - move(line++,0); - printw("<up>/<down> - move up or down one line"); - move(line++,0); - printw("<left>/<right> - move left or right one byte"); - move(line++,0); - printw("<home> - return to the superblock."); - move(line++,0); - printw("<enter> - edit a value (enter to save, esc to discard)"); - move(line++,0); - printw("<backspace> - return to previous block"); - move(line++,0); - printw("<escape> - Quit the program"); - move(line++,0); - move(line++,0); - printw("Notes: Areas shown in red are outside the bounds of the struct."); - move(line++,0); - printw(" Fields shown in green are selected for edit on <enter>."); - move(line++,0); - move(line++,0); - printw("Press any key to return."); - refresh(); - while ((ch=getch()) == 0); // wait for input - clear(); -} - -/* ------------------------------------------------------------------------ */ -/* display_block_type */ -/* returns: metatype if block is a GFS structure block type */ -/* 0 if block is not a GFS structure */ -/* ------------------------------------------------------------------------ */ -int display_block_type(const unsigned char *lpBuffer) -{ - int ret_type = 0; /* return type */ - - /* first, print out the kind of GFS block this is */ - line = 1; - move(line, 0); - printw("Block #"); - if (edit_row[display_mode] == -1) - attrset(COLOR_PAIR(5));; - printw("%"PRIX64,block); - if (edit_row[display_mode] == -1) - attrset(COLOR_PAIR(2)); - move(line,25); - printw("of %"PRIX64,max_block); - move(line, 45); - - if (*(lpBuffer+0)==0x01 && *(lpBuffer+1)==0x16 && *(lpBuffer+2)==0x19 && - *(lpBuffer+3)==0x70 && *(lpBuffer+4)==0x00 && *(lpBuffer+5)==0x00 && - *(lpBuffer+6)==0x00) { /* If magic number appears at the start */ - ret_type = *(lpBuffer+7); - switch (*(lpBuffer+7)) { - case GFS_METATYPE_SB: /* 1 */ - printw("(superblock)"); - struct_len = sizeof(struct gfs_sb); - break; - case GFS_METATYPE_RG: /* 2 */ - printw("(rsrc grp hdr)"); - struct_len = sizeof(struct gfs_rgrp); - break; - case GFS_METATYPE_RB: /* 3 */ - printw("(rsrc grp bitblk)"); - struct_len = 512; - break; - case GFS_METATYPE_DI: /* 4 */ - printw("(disk inode)"); - struct_len = sizeof(struct gfs_dinode); - break; - case GFS_METATYPE_IN: /* 5 */ - printw("(indir inode blklst)"); - struct_len = sizeof(struct gfs_indirect); - break; - case GFS_METATYPE_LF: /* 6 */ - printw("(leaf dinode blklst)"); - struct_len = sizeof(struct gfs_leaf); - break; - case GFS_METATYPE_JD: - printw("(journal data)"); - struct_len = sizeof(struct gfs_meta_header); - break; - case GFS_METATYPE_LH: - printw("(log header)"); - struct_len = sizeof(struct gfs_log_header); - break; - case GFS_METATYPE_LD: - printw("(log descriptor)"); - struct_len = sizeof(struct gfs_log_descriptor); - break; - case GFS_METATYPE_EA: - printw("(extended attr hdr)"); - struct_len = sizeof(struct gfs_ea_header); - break; - case GFS_METATYPE_ED: - printw("(extended attr data)"); - struct_len = 512; - break; - default: - printw("(wtf?)"); - struct_len = 512; - break; - } - } - else - struct_len = 512; - line++; - move(line, 0); - if (display_mode == HEX_MODE) { - /* calculate how much of the buffer we can fit on screen */ - screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8; - if (!screen_chunk_size) - screen_chunk_size = 256; - printw("(%d of %d)", (offset / screen_chunk_size) + 1, - (bufsize % screen_chunk_size) > 0 ? - bufsize / screen_chunk_size + 1 : bufsize / screen_chunk_size); - } - move(line, 9); - if (block == sb.sb_jindex_di.no_addr) - printw("----------------- Journal Index file -----------------"); - else if (block == sb.sb_rindex_di.no_addr) - printw("-------------- Resource Group Index file -------------"); - else if (block == sb.sb_quota_di.no_addr) - printw("---------------------- Quota file --------------------"); - else if (block == sb.sb_root_di.no_addr) - printw("-------------------- Root direcory -------------------"); - else if (block == sb.sb_license_di.no_addr) - printw("--------------------- License file -------------------"); - line++; - return ret_type; -} - -/* ------------------------------------------------------------------------ */ -/* hexdump - hex dump the filesystem block to the screen */ -/* ------------------------------------------------------------------------ */ -int hexdump(uint64 startaddr, const unsigned char *lpBuffer, int len) -{ - const unsigned char *pointer,*ptr2; - int i; - uint64 l; - - strcpy(edit_fmt,"%02X"); - pointer = (unsigned char *)lpBuffer + offset; - ptr2 = (unsigned char *)lpBuffer + offset; - l = offset; - while (line < termlines && - line <= ((screen_chunk_size / 16) + 2) && - l < bufsize) { - move(line, 0); - attrset(COLOR_PAIR(6)); /* yellow for offsets */ - if (startaddr < 0xffffffff) - printw("%.8"PRIX64,startaddr + l); - else - printw("%.16"PRIX64,startaddr + l); - if (l < struct_len) - attrset(COLOR_PAIR(2)); /* normal part of the structure */ - else - attrset(COLOR_PAIR(4)); /* beyond the end of the structure */ - for (i=0; i<16; i++) { /* first print it in hex */ - if (l+i < struct_len) - attrset(COLOR_PAIR(2)); /* normal part of the structure */ - else - attrset(COLOR_PAIR(4)); /* beyond the end of the structure */ - if (i%4 == 0) - printw(" "); - if (line == edit_row[display_mode] + 3 && - i == edit_col[display_mode]) { - attrset(COLOR_PAIR(5)); /* normal part of the structure */ - memset(edit_string,0,3); - sprintf(edit_string,"%02X",*pointer); - } - printw("%02X",*pointer); - if (line == edit_row[display_mode] + 3 && - i == edit_col[display_mode]) { - if (l < struct_len + offset) - attrset(COLOR_PAIR(2)); /* normal part of the structure */ - else - attrset(COLOR_PAIR(4)); /* beyond end of the structure */ - } - pointer++; - } - printw(" ["); - for (i=0; i<16; i++) { /* now print it in character format */ - if ((*ptr2 >=' ') && (*ptr2 <= '~')) - printw("%c",*ptr2); - else - printw("."); - ptr2++; - } - printw("] "); - if (line - 3 > edit_last[display_mode]) - edit_last[display_mode] = line - 3; - line++; - l+=16; - } - return (offset+len); -} - -/* ------------------------------------------------------------------------ */ -/* display_extended */ -/* ------------------------------------------------------------------------ */ -int display_extended(void) -{ - int e; - - edit_last[display_mode] = 0; - move(line++, 0); - if (indirect_blocks) { - printw("This inode contains %d indirect blocks", indirect_blocks); - line++; - move(line++, 0); - printw("Indirect blocks for this inode:"); - for (e = 0; e < termlines && e < indirect_blocks; e++) { - if (line - 6 == edit_row[display_mode]) - attrset(COLOR_PAIR(5)); - move(line, 5); - printw("%d => %"PRIX64, e + 1, indirect_block[e]); - if (line - 6 == edit_row[display_mode]) { - sprintf(edit_string, "%"PRIX64, indirect_block[e]); - strcpy(edit_fmt, "%"PRIX64); - edit_size[display_mode] = strlen(edit_string); - attrset(COLOR_PAIR(2)); - } - line++; - } - if (line >= 7) /* 7 because it was bumped at the end */ - edit_last[display_mode] = line - 7; - } - else - printw("This block does not have indirect blocks."); - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* display */ -/* ------------------------------------------------------------------------ */ -int display(void) -{ - display_title_lines(); - move(2,0); - if (block_in_mem != block) { /* If we changed blocks from the last read */ - dev_offset = block * bufsize; - ioctl(fd, BLKFLSBUF, 0); - do_lseek(fd, dev_offset); - do_read(fd, buf, bufsize); /* read in the desired block */ - block_in_mem = block; /* remember which block is in memory */ - } - line = 1; - gfs_struct_type = display_block_type(buf); - indirect_blocks = 0; - if (gfs_struct_type == GFS_METATYPE_SB || block == 0x10) - gfs_sb_in(&sb, buf); /* parse it out into the sb structure */ - else if (gfs_struct_type == GFS_METATYPE_DI) { - gfs_dinode_in(&di, buf); /* parse disk inode into structure */ - do_dinode_extended(&di, buf); /* get extended data, if any */ - } - edit_last[display_mode] = 0; - if (display_mode == HEX_MODE) /* if hex display mode */ - hexdump(dev_offset, buf, 256); /* show the block in hex */ - else if (display_mode == GFS_MODE) /* if structure display */ - display_gfs(); /* display the gfs structure */ - else /* otherwise */ - display_extended(); /* display extended blocks */ - refresh(); - return(0); -} - - -/****************************************************************************** -******************************************************************************* -** -** main() -** -** Description: -** Do everything -** -******************************************************************************* -******************************************************************************/ -int main(int argc, char *argv[]) -{ - char device[STRLEN]; - char string[256]; - int i,ch, left_off; - int64 temp_blk; - - prog_name = argv[0]; - - if (argc < 2) - die("no device specified\n"); - - memset(edit_row, 0, sizeof(edit_row)); - memset(edit_col, 0, sizeof(edit_col)); - memset(edit_size, 0, sizeof(edit_size)); - memset(edit_last, 0, sizeof(edit_last)); - display_mode = HEX_MODE; - type_alloc(buf, char, bufsize); /* allocate/malloc a new 4K buffer */ - block = 0x10; - for (i = 1; i < argc; i++) { - if (!strcasecmp(argv[i], "-verbose")) - verbose = TRUE; - else if (!strcasecmp(argv[i], "-V")) { - printf("%s %s (built %s %s)\n", prog_name, GFS_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - } - else { - strcpy(device,argv[i]); - } - } - fd = open(device, O_RDWR); - if (fd < 0) - die("can't open %s: %s\n", argv[1], strerror(errno)); - max_block = lseek(fd, 0, SEEK_END) / bufsize; - - if (initscr() == NULL) { - fprintf(stderr, "Error: unable to initialize screen.\n"); - exit(-1); - } - - signal(SIGWINCH, UpdateSize); /* handle the terminal resize signal */ - UpdateSize(0); /* update screen size based on terminal settings */ - clear(); - start_color(); - noecho(); - keypad(stdscr, TRUE); - raw(); - curs_set(0); - init_pair(1, COLOR_BLACK, COLOR_CYAN); /* title lines */ - init_pair(2, COLOR_WHITE, COLOR_BLACK); /* normal text */ - init_pair(3, COLOR_BLACK, COLOR_WHITE); /* inverse text */ - init_pair(4, COLOR_RED, COLOR_BLACK); /* special text */ - init_pair(5, COLOR_GREEN, COLOR_BLACK); /* highlighted text */ - init_pair(6, COLOR_CYAN, COLOR_BLACK); /* offsets */ - - while (!Quit) { - display(); - while ((ch=getch()) == 0); // wait for input - switch (ch) - { - /* -------------------------------------------------------------- */ - /* escape or 'q' */ - /* -------------------------------------------------------------- */ - case 0x1b: - case 0x03: - case 'q': - Quit=TRUE; - break; - /* -------------------------------------------------------------- */ - /* home - return to the superblock */ - /* -------------------------------------------------------------- */ - case KEY_HOME: - previous_block = block; - block = 0x10; - offset = 0; - break; - /* -------------------------------------------------------------- */ - /* backspace - return to the previous block */ - /* -------------------------------------------------------------- */ - case KEY_BACKSPACE: - case 0x7f: - temp_blk = block; - block = previous_block; - previous_block = temp_blk; - offset = 0; - break; - /* -------------------------------------------------------------- */ - /* arrow up */ - /* -------------------------------------------------------------- */ - case KEY_UP: - if (edit_row[display_mode] >= 0) /* -1 means change block number */ - edit_row[display_mode]--; - break; - /* -------------------------------------------------------------- */ - /* arrow down */ - /* -------------------------------------------------------------- */ - case KEY_DOWN: - if (edit_row[display_mode] < edit_last[display_mode]) - edit_row[display_mode]++; - break; - /* -------------------------------------------------------------- */ - /* arrow left */ - /* -------------------------------------------------------------- */ - case KEY_LEFT: - if (display_mode == HEX_MODE) { - if (edit_col[display_mode] > 0) - edit_col[display_mode]--; - else - edit_col[display_mode] = 15; - } - break; - /* -------------------------------------------------------------- */ - /* arrow right */ - /* -------------------------------------------------------------- */ - case KEY_RIGHT: - if (display_mode == HEX_MODE) { - if (edit_col[display_mode] < 15) - edit_col[display_mode]++; - else - edit_col[display_mode] = 0; - } - break; - /* -------------------------------------------------------------- */ - /* m - change display mode key */ - /* -------------------------------------------------------------- */ - case 'm': - display_mode = ((display_mode + 1) % DISPLAY_MODES); - break; - /* -------------------------------------------------------------- */ - /* J - Jump to highlighted block number */ - /* -------------------------------------------------------------- */ - case 'j': - if (display_mode == HEX_MODE) { - unsigned int col2; - uint64 *b; - - col2 = edit_col[display_mode] & 0x08;/* thus 0-7->0, 8-15->8 */ - b = (uint64 *)&buf[edit_row[display_mode]*16 + offset + col2]; - temp_blk=gfs64_to_cpu(*b); - } - else - sscanf(edit_string, "%"SCNx64, &temp_blk);/* retrieve in hex */ - if (temp_blk < max_block) { /* if the block number is valid */ - offset = 0; - display_mode = HEX_MODE; - previous_block = block; - block = temp_blk; - } - break; - /* -------------------------------------------------------------- */ - /* g - goto block */ - /* -------------------------------------------------------------- */ - case 'g': - memset(string, 0, sizeof(string)); - sprintf(string,"%"PRIX64, block); - if (bobgets(string, 1, 7, 16)) - sscanf(string, "%"SCNx64, &temp_blk); /* retrieve in hex */ - if (temp_blk < max_block) { - offset = 0; - previous_block = block; - block = temp_blk; - } - break; - /* -------------------------------------------------------------- */ - /* h - help key */ - /* -------------------------------------------------------------- */ - case 'h': - print_usage(); - break; - /* -------------------------------------------------------------- */ - /* b - Back one 4K block */ - /* -------------------------------------------------------------- */ - case 'b': - edit_row[display_mode] = 0; - if (block > 0) { - previous_block = block; - block--; - } - offset = 0; - break; - /* -------------------------------------------------------------- */ - /* page up key */ - /* -------------------------------------------------------------- */ - case 0x19: // ctrl-y for vt100 - case KEY_PPAGE: // PgUp - case 0x15: // ctrl-u for vi compat. - case 0x02: // ctrl-b for less compat. - edit_row[display_mode] = 0; - if (display_mode == GFS_MODE || offset==0) { - previous_block = block; - block--; - if (display_mode == HEX_MODE) - offset = (bufsize % screen_chunk_size) > 0 ? - screen_chunk_size * (bufsize / screen_chunk_size) : - bufsize - screen_chunk_size; - else - offset = 0; - } - else - offset -= screen_chunk_size; - break; - /* -------------------------------------------------------------- */ - /* f - Forward one 4K block */ - /* -------------------------------------------------------------- */ - case 'f': - case ' ': /* space for less/more compat. */ - previous_block = block; - edit_row[display_mode] = 0; - block++; - offset = 0; - break; - /* -------------------------------------------------------------- */ - /* page down key */ - /* -------------------------------------------------------------- */ - case 0x16: // ctrl-v for vt100 - case KEY_NPAGE: // PgDown - case 0x04: // ctrl-d for vi compat. - edit_row[display_mode] = 0; - if (display_mode == GFS_MODE || - offset + screen_chunk_size >= bufsize) { - previous_block = block; - block++; - offset = 0; - } - else - offset += screen_chunk_size; - break; - /* -------------------------------------------------------------- */ - /* enter key - change a value */ - /* -------------------------------------------------------------- */ - case(KEY_ENTER): - case('\n'): - case('\r'): - if (edit_row[display_mode] == -1) { - memset(string, 0, sizeof(string)); - sprintf(string,"%"PRIX64, block); - if (bobgets(string, 1, 7, 16)) - sscanf(string, "%"SCNx64, &temp_blk); /* retrieve in hex */ - if (temp_blk < max_block) { - offset = 0; - previous_block = block; - block = temp_blk; - } - } - else { - if (display_mode == HEX_MODE) { - left_off = ((block * bufsize) < 0xffffffff) ? 9 : 17; - /* 8 and 16 char addresses on screen */ - - if (bobgets(edit_string, edit_row[display_mode] + 3, - (edit_col[display_mode] * 2) + - (edit_col[display_mode] / 4) + left_off, 2)) { - if (strstr(edit_fmt,"X") || strstr(edit_fmt,"x")) { - int hexoffset; - unsigned char ch; - - hexoffset = (edit_row[display_mode] * 16) + - edit_col[display_mode]; - ch = 0x00; - if (isdigit(edit_string[0])) - ch = (edit_string[0] - '0') * 0x10; - else if (edit_string[0] >= 'a' && - edit_string[0] <= 'f') - ch = (edit_string[0] - 'a' + 0x0a) * 0x10; - else if (edit_string[0] >= 'A' && - edit_string[0] <= 'F') - ch = (edit_string[0] - 'A' + 0x0a) * 0x10; - if (isdigit(edit_string[1])) - ch += (edit_string[1] - '0'); - else if (edit_string[1] >= 'a' && - edit_string[1] <= 'f') - ch += (edit_string[1] - 'a' + 0x0a); - else if (edit_string[1] >= 'A' && - edit_string[1] <= 'F') - ch += (edit_string[1] - 'A' + 0x0a); - buf[offset + hexoffset] = ch; - do_lseek(fd, dev_offset); - do_write(fd, buf, bufsize); - fsync(fd); - } - } - } - else if (display_mode == GFS_MODE) - bobgets(edit_string, edit_row[display_mode] + 3, 24, - edit_size[display_mode]); - else - bobgets(edit_string, edit_row[display_mode] + 6, 24, - edit_size[display_mode]); - } - break; - default: - move(termlines - 1, 0); - printw("Keystroke not understood: %02X",ch); - refresh(); - sleep(2); - break; - } /* switch */ - } /* while !Quit */ - clear(); - refresh(); - endwin(); - close(fd); - if (buf) - free(buf); - exit(EXIT_SUCCESS); -} diff --git a/gfs/gfs_edit/hexedit.h b/gfs/gfs_edit/hexedit.h deleted file mode 100644 index e52abd2..0000000 --- a/gfs/gfs_edit/hexedit.h +++ /dev/null @@ -1,193 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __HEXVIEW_DOT_H__ -#define __HEXVIEW_DOT_H__ - - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* Extern Macro */ - -#ifndef EXTERN -#define EXTERN extern -#define INIT(X) -#else -#undef EXTERN -#define EXTERN -#define INIT(X) =X -#endif - -#define DISPLAY_MODES 3 -enum dsp_mode { HEX_MODE = 0, GFS_MODE = 1, EXTENDED_MODE = 2 }; - -EXTERN char *prog_name; -EXTERN int fd; -EXTERN int64 block INIT(0); -EXTERN int64 previous_block INIT(0); -EXTERN int64 block_in_mem INIT(-1); -EXTERN int edit_mode INIT(0); -EXTERN int line, termlines; -EXTERN char edit_fmt[80]; -EXTERN char edit_string[1024]; -EXTERN int verbose INIT(FALSE); -EXTERN uint64 dev_offset INIT(0); -EXTERN uint64 max_block INIT(0); -EXTERN char *buf INIT(NULL); -EXTERN uint64 bufsize INIT(4096); -EXTERN int Quit INIT(FALSE); -EXTERN int termlines INIT(30); -EXTERN int insert INIT(0); -EXTERN const char *termtype; -EXTERN int line INIT(1); -EXTERN int struct_len INIT(0); -EXTERN unsigned int offset; -EXTERN int edit_row[DISPLAY_MODES], edit_col[DISPLAY_MODES]; -EXTERN int edit_size[DISPLAY_MODES], edit_last[DISPLAY_MODES]; -EXTERN char edit_string[1024], edit_fmt[80]; -EXTERN struct gfs_sb sb; -EXTERN struct gfs_dinode di; -EXTERN int screen_chunk_size INIT(512); /* how much of the 4K can fit on screen */ -EXTERN int gfs_struct_type; -EXTERN uint64 indirect_block[512]; /* more than the most indirect ptrs possible - for any given 4K block */ -EXTERN int indirect_blocks INIT(0); /* count of indirect blocks */ -EXTERN enum dsp_mode display_mode INIT(HEX_MODE); - -#define STRLEN (256) -#define SCREEN_HEIGHT (16) -#define SCREEN_WIDTH (16) - -#define die(fmt, args...) \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ## args); \ - exit(EXIT_FAILURE); \ -} - -/* I/O macros */ - -#define do_lseek(fd, off) \ -{ \ - if (lseek((fd), (off), SEEK_SET) != (off)) \ - die("bad seek: %s on line %d of file %s\n", \ - strerror(errno),__LINE__, __FILE__); \ -} - -#define do_read(fd, buff, len) \ -{ \ - if (read((fd), (buff), (len)) != (len)) \ - die("bad read: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} - -#define do_write(fd, buff, len) \ -{ \ - if (write((fd), (buff), (len)) != (len)) \ - die("bad write: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} - - - -/* Memory macros */ - -#define type_zalloc(ptr, type, count) \ -{ \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if ((ptr)) \ - memset((char *)(ptr), 0, sizeof(type) * (count)); \ - else \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} - -#define type_alloc(ptr, type, count) \ -{ \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if (!(ptr)) \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} - -#define pa(struct, member, count) print_array(#member, struct->member, count); -#define printk printw -#define pv(struct, member, fmt) do { \ - if (line < termlines) { \ - if (line == edit_row[display_mode] + 3) { \ - attrset(COLOR_PAIR(5)); \ - } \ - move(line,0); \ - printw(" "#member":"); \ - move(line,24); \ - printw(fmt, struct->member); \ - move(line, 50); \ - if (strstr(fmt,"X") || strstr(fmt,"x")) \ - printw("(hex)"); \ - else if (strstr(fmt,"s")) \ - printw("(string)"); \ - else \ - printw("(decimal)"); \ - refresh(); \ - if (line == edit_row[display_mode] + 3) { \ - sprintf(edit_string, fmt, struct->member); \ - strcpy(edit_fmt, fmt); \ - edit_size[display_mode] = strlen(edit_string); \ - attrset(COLOR_PAIR(2)); \ - } \ - if (line - 3 > edit_last[display_mode]) \ - edit_last[display_mode] = line - 3; \ - line++; \ - move(line,0); /* this seemingly redundant move needed */ \ - } \ - } while (FALSE); - -#define pv2(struct, member, fmt) do { \ - if (line < termlines) { \ - if (line == edit_row[display_mode] + 3) { \ - attrset(COLOR_PAIR(5)); \ - } \ - move(line,24); \ - printw(fmt, struct->member); \ - move(line, 50); \ - if (strstr(fmt,"X") || strstr(fmt,"x")) \ - printw("(hex)"); \ - else if (strstr(fmt,"s")) \ - printw("(string)"); \ - else \ - printw("(decimal)"); \ - refresh(); \ - if (line == edit_row[display_mode] + 3) { \ - sprintf(edit_string, fmt, struct->member); \ - strcpy(edit_fmt, fmt); \ - edit_size[display_mode] = strlen(edit_string); \ - attrset(COLOR_PAIR(2)); \ - } \ - if (line - 3 > edit_last[display_mode]) \ - edit_last[display_mode] = line - 3; \ - line++; \ - move(line,0); /* this seemingly redundant move needed */ \ - } \ - } while (FALSE); - - -/* Divide x by y. Round up if there is a remainder. */ -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) - - -#endif /* __HEXVIEW_DOT_H__ */ diff --git a/gfs/gfs_edit/ondisk.c b/gfs/gfs_edit/ondisk.c deleted file mode 100644 index 41c5723..0000000 --- a/gfs/gfs_edit/ondisk.c +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "global.h" -#include "linux_endian.h" - -#include <linux/gfs_ondisk.h> - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> - diff --git a/gfs/gfs_fsck/FEATURES b/gfs/gfs_fsck/FEATURES deleted file mode 100644 index 8a63591..0000000 --- a/gfs/gfs_fsck/FEATURES +++ /dev/null @@ -1,25 +0,0 @@ -This is a completely rewritten filesystem checker for GFS. Performance -characteristics are significantly improved. The design follows the 5-pass -fsck design found in "Fsck - The UNIX File System Check Program" -by McKusick & Kowalkski (1994) - - http://citeseer.ist.psu.edu/mckusick94fsck.html - - -Line item list of supported features: - -1. Detects and replaces missing/bad root inode -2. Detects and relinks unlinked inodes to l+f - o If a file is zero length, it is not relinked to l+f - unless it - has an extended attribute attached to it. -3. Detects duplicate blocks and removes inodes containing them -4. Detects bad blocks (block number out of range) and removes inodes - containing them - Currently EAs that have blocks are removed but - the inode containing them is left. -5. Detects bad metadata headers and clears the structure -6. Fixes bad resource group bitmaps -7. Fixes incorrect resource group counts -8. Creates l+f directory if missing -9. Detects and removes duplicate '.' and '..' entries -10. Creates '.' if missing -11. Beginning of support for internationalization -12. Checks extended attributes diff --git a/gfs/gfs_fsck/Makefile b/gfs/gfs_fsck/Makefile deleted file mode 100644 index 76a8650..0000000 --- a/gfs/gfs_fsck/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2005 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir= .. - -include ${top_srcdir}/make/defines.mk - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - -.PHONY: all clean - -sources = main.c initialize.c pass1.c pass1b.c pass1c.c \ - pass2.c pass3.c pass4.c pass5.c \ - block_list.c super.c bio.c ondisk.c file.c rgrp.c fs_bits.c util.c \ - fs_bmap.c fs_inode.c fs_dir.c fs_recovery.c log.c hash.c \ - inode_hash.c bitmap.c lost_n_found.c inode.c link.c metawalk.c \ - eattr.c - -CFLAGS+=-D_FILE_OFFSET_BITS=64 -DHELPER_PROGRAM -DGFS_RELEASE_NAME="${RELEASE}" -Wall -O2 - -all: gfs_fsck - -gfs_fsck: $(sources:.c=.o) - $(CC) $(CFLAGS) $^ -o $@ - -%.o: %.c - $(CC) -MMD -c $(INCLUDES) $(CFLAGS) $< -o $@ - - -test_block_list: block_list.o bitmap.o log.o test_block_list.o - $(CC) $(CFLAGS) $^ -o $@ - -test_bitmap: bitmap.o test_bitmap.o log.o - $(CC) $(CFLAGS) $^ -o $@ -clean: - @rm -f *.o *~ - -copytobin: gfs_fsck - cp gfs_fsck ${top_srcdir}/bin - -distclean: clean - @rm -f *.d cscope.* gfs_fsck test_inode_list *.orig *.rej test_block_list test_bitmap - - -gfs_fsck.pot: $(sources) - @xgettext -C -F --keyword=print_log --keyword=log_debug --keyword=log_info --keyword=_ \ - --keyword=log_notice --keyword=log_warn --keyword=log_err --keyword=log_crit \ - --keyword=log_debug --keyword=log_err --keyword=log_print -d - $(sources) > gfs_fsck.pot - - --include $(sources:.c=.d) diff --git a/gfs/gfs_fsck/TODO b/gfs/gfs_fsck/TODO deleted file mode 100644 index 2b2e762..0000000 --- a/gfs/gfs_fsck/TODO +++ /dev/null @@ -1,49 +0,0 @@ - -TODO: - -Current - x fs_mkdir appears to be grabbing blocks that are in use - need to - figure out why - had to fix fs_blkalloc_internal in fs_bits.c to - use the incore bitmaps instead of ondisk. - o Make sure that all blocks in an inode get marked cleared when an - inode is cleared. - x If a directory is unlinked from pass2 on, make sure that any - directories that have it as a parent have their - dir_info->treewalk_parent entries cleared - handled by pass3 - checking if parents inodes are valid in the bitmap - o If an directory is unlinked from pass2 on, make sure that inodes - have their link count decremented (this may be difficult - i'll - have to reread the dirents and decrement the counts for all dirents - up to the error...). - x 'Add in UI for interactive mode - o Check hash of directory name against name given (Would be nice - - not in old fsck, but can cause problems if it is not verified.) - x Unstuffed EA blocks have type GFS_METATYPE_ED in 6.1, but - GFS_METATYPE_EA in 6.0 - handle this. - ---- - -Future - o internationalization - o Check GFS special files (quota, resource group index inode, journal - index inode, license inode?) - o convert dir_info list to a hash table like the inode_info hash - o Fix up the bitmap enums and #defines in block_list.[ch] - o Go through all fxns that have NEEDS_CHECKING in them and verify - them (and remove NEEDS_CHECKING) - o Add 'preen' option? - o Add disk-based bitmaps option in case system doesn't have enough - memory to handle all the bitmaps - o currently rgrp bitmaps are loaded into memory on initialization - - need to see if this is necessary or not - we're using them in pass1 - and again in pass5 - if memory is tight we might be able to free - them in between - o Offer exhaustive search capability if superblock or rgs are missing - or broken that checks block by block for fs info. - o If we encounter a directory entry in pass2 that points to a block - marked free, shove it into a queue, and then at the end of pass2, - clear all results, then rerun from pass1 including the blocks in - the queue as well as those marked in the RG bitmaps. With this, we - can rebuild the entire fs with a valid root inode, it'll just take - several iterations. - diff --git a/gfs/gfs_fsck/bio.c b/gfs/gfs_fsck/bio.c deleted file mode 100644 index cfa5cc5..0000000 --- a/gfs/gfs_fsck/bio.c +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "util.h" -#include "fsck.h" -#include "bio.h" - -/* - * get_buf - get a buffer - * @sdp: the super block - * @blkno: blk # that this buffer will be associated with - * @bhp: the location where the buffer is returned - * - * This function allocates space for a buffer head structure - * and the corresponding data. It does not fill in the - * actual data - that is done by read_buf. - * - * Returns: 0 on success, -1 on error - */ -int get_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp){ - osi_buf_t *bh = NULL; - - *bhp = NULL; - bh = (osi_buf_t *)malloc(sizeof(osi_buf_t)); - if(!bh){ - log_err("Unable to allocate memory for new buffer head.\n"); - return -1; - } - if(!memset(bh, 0, sizeof(osi_buf_t))) { - log_err("Unable to zero buffer head\n"); - return -1; - } - - /* FIXME: Not sure how this will work on all - * architectures without the casts */ - bh->b_blocknr = blkno; - bh->b_size = sdp->sb.sb_bsize; - bh->b_state = 0; - if(!(bh->b_data = malloc(BH_SIZE(bh)))) { - free(bh); - log_err("Unable to allocate memory for new buffer " - "blkno = %"PRIu64", size = %u\n", blkno, BH_SIZE(bh)); - return -1; - } - if(!memset(BH_DATA(bh), 0, BH_SIZE(bh))) { - free(bh); - log_err("Unable to zero memory for new buffer " - "blkno = %"PRIu64", size = %u\n", blkno, BH_SIZE(bh)); - } - - *bhp = bh; - - return 0; -} - - -/* - * relse_buf - release a buffer - * @sdp: the super block - * @bh: the buffer to release - * - * This function will release the memory of the buffer - * and associated buffer head. - * - * Returns: nothing - */ -void relse_buf(struct fsck_sb *sdp, osi_buf_t *bh){ - if(bh){ - if(BH_DATA(bh)) { - free(BH_DATA(bh)); - bh->b_data = NULL; - } - free(bh); - bh = NULL; - } -} - - -/* - * read_buf - read a buffer - * @sdp: the super block - * @blkno: block number - * @bhp: place where buffer is returned - * @flags: - * - * Returns 0 on success, -1 on error - */ -int read_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags){ - int disk_fd = sdp->diskfd; - - if(do_lseek(disk_fd, (uint64)(BH_BLKNO(bh)*BH_SIZE(bh)))){ - log_err("Unable to seek to position %"PRIu64" " - "(%"PRIu64" * %u) on storage device.\n", - (uint64)(BH_BLKNO(bh) * BH_SIZE(bh)), - BH_BLKNO(bh), BH_SIZE(bh)); - return -1; - } - - if(do_read(disk_fd, BH_DATA(bh), BH_SIZE(bh))){ - log_err("Unable to read %u bytes from position %"PRIu64"\n", - BH_SIZE(bh), (uint64)(BH_BLKNO(bh) * BH_SIZE(bh))); - return -1; - } - - return 0; -} - - -/* - * write_buf - write a buffer - * @sdp: the super block - * @bh: buffer head that describes buffer to write - * @flags: flags that determine usage - * - * Returns: 0 on success, -1 on failure - */ -int write_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags){ - int disk_fd = sdp->diskfd; - - if(do_lseek(disk_fd, (uint64)(BH_BLKNO(bh) * BH_SIZE(bh)))) { - log_err("Unable to seek to position %"PRIu64 - "(%"PRIu64" * %u) on storage device.\n", - (uint64)(BH_BLKNO(bh) * BH_SIZE(bh)), - BH_BLKNO(bh), BH_SIZE(bh)); - return -1; - } - - log_debug("Writing to %"PRIu64" - %"PRIu64" %u\n", - (uint64)(BH_BLKNO(bh) * BH_SIZE(bh)), - BH_BLKNO(bh), BH_SIZE(bh)); - if(do_write(disk_fd, BH_DATA(bh), BH_SIZE(bh))) { - log_err("Unable to write %u bytes to position %"PRIu64"\n", - BH_SIZE(bh), (uint64)(BH_BLKNO(bh) * BH_SIZE(bh))); - return -1; - } - - if(flags & BW_WAIT){ - fsync(disk_fd); - } - - return 0; -} - - -/* - * get_and_read_buf - combines get_buf and read_buf functions - * @sdp - * @blkno - * @bhp - * @flags - * - * Returns: 0 on success, -1 on error - */ -int get_and_read_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp, - int flags) -{ - if(get_buf(sdp, blkno, bhp)) { - stack; - return -1; - } - - if(read_buf(sdp, *bhp, flags)){ - stack; - relse_buf(sdp, *bhp); - *bhp = NULL; /* guarantee that ptr is NULL in failure cases */ - return -1; - } - - return 0; -} - diff --git a/gfs/gfs_fsck/bio.h b/gfs/gfs_fsck/bio.h deleted file mode 100644 index 0f4ef62..0000000 --- a/gfs/gfs_fsck/bio.h +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __BIO_H -#define __BIO_H - -#include "osi_user.h" -#include "fsck_incore.h" -/* buf_write flags */ -#define BW_WAIT 1 - - -#define BH_DATA(bh) ((char *)(bh)->b_data) -#define BH_BLKNO(bh) ((uint64)(bh)->b_blocknr) -#define BH_SIZE(bh) ((uint32)(bh)->b_size) -#define BH_STATE(bh) ((uint32)(bh)->b_state) - -int get_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp); -void relse_buf(struct fsck_sb *sdp, osi_buf_t *bh); -int read_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags); -int write_buf(struct fsck_sb *sdp, osi_buf_t *bh, int flags); -int get_and_read_buf(struct fsck_sb *sdp, uint64 blkno, osi_buf_t **bhp, int flags); - -#endif /* __BIO_H */ - - diff --git a/gfs/gfs_fsck/bitmap.c b/gfs/gfs_fsck/bitmap.c deleted file mode 100644 index 507dcc8..0000000 --- a/gfs/gfs_fsck/bitmap.c +++ /dev/null @@ -1,130 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* Basic bitmap manipulation */ -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include "osi_user.h" -#include "bitmap.h" -#include "block_list.h" -#include "fsck_incore.h" -#include "log.h" - - -#define BITMAP_SIZE(size, cpb) (size / cpb) - -#define BITMAP_BYTE_OFFSET(x, map) ((x % map->chunks_per_byte) \ - * map->chunksize ) - -#define BITMAP_MASK(chunksize) ((2 << (chunksize - 1)) - 1) - -uint64_t bitmap_size(struct bmap *bmap) { - return bmap->size; -} - -int bitmap_create(struct bmap *bmap, uint64_t size, uint8_t chunksize) -{ - if((((chunksize >> 1) << 1) != chunksize) && chunksize != 1) { - log_err("chunksize must be a power of 2\n"); - return -1; - } - if(chunksize > 8) { - log_err("chunksize must be <= 8\n"); - return -1; - } - bmap->chunksize = chunksize; - bmap->chunks_per_byte = 8 / chunksize; - - bmap->size = size; - - /* Have to add 1 to BITMAP_SIZE since it's 0-based and mallocs - * must be 1-based */ - bmap->mapsize = BITMAP_SIZE(size, bmap->chunks_per_byte)+1; - - if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize))) { - log_err("Unable to allocate bitmap of size %"PRIu64"\n", - bmap->mapsize); - return -ENOMEM; - } - if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) { - log_err("Unable to zero bitmap of size %"PRIu64"\n", - bmap->mapsize); - free(bmap->map); - bmap->map = NULL; - return -ENOMEM; - } - log_debug("Allocated bitmap of size %"PRIu64 - " with %d chunks per byte\n", - bmap->mapsize, bmap->chunks_per_byte); - return 0; -} - -int bitmap_set(struct bmap *bmap, uint64_t offset, uint8_t val) -{ - char *byte = NULL; - uint64_t b = offset; - - if(offset < bmap->size) { - byte = bmap->map + BITMAP_SIZE(offset, bmap->chunks_per_byte); - b = BITMAP_BYTE_OFFSET(offset, bmap); - - *byte |= (val & BITMAP_MASK(bmap->chunksize)) << b; - return 0; - } - log_debug("offset %d out of bounds\n", offset); - return -1; -} - -int bitmap_get(struct bmap *bmap, uint64_t bit, uint8_t *val) -{ - char *byte = NULL; - uint64_t b = bit; - - if(bit < bmap->size) { - byte = bmap->map + BITMAP_SIZE(bit, bmap->chunks_per_byte); - b = BITMAP_BYTE_OFFSET(bit, bmap); - - *val = (*byte & (BITMAP_MASK(bmap->chunksize) << b )) >> b; - return 0; - } - log_debug("offset %d out of bounds\n", bit); - return -1; -} - - -int bitmap_clear(struct bmap *bmap, uint64_t offset) -{ - char *byte = NULL; - uint64_t b = offset; - - if(offset < bmap->size) { - byte = bmap->map + BITMAP_SIZE(offset, bmap->chunks_per_byte); - b = BITMAP_BYTE_OFFSET(offset, bmap); - - *byte &= ~(BITMAP_MASK(bmap->chunksize) << b); - return 0; - } - log_debug("offset %d out of bounds\n", offset); - return -1; - -} - -void bitmap_destroy(struct bmap *bmap) -{ - if(bmap->map) - free(bmap->map); - bmap->size = 0; - bmap->mapsize = 0; - bmap->chunksize = 0; - bmap->chunks_per_byte = 0; -} diff --git a/gfs/gfs_fsck/bitmap.h b/gfs/gfs_fsck/bitmap.h deleted file mode 100644 index a1d48c7..0000000 --- a/gfs/gfs_fsck/bitmap.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - -#ifndef _BITMAP_H -#define _BITMAP_H - -struct bmap { - uint64_t size; - uint64_t mapsize; - int chunksize; - int chunks_per_byte; - char *map; -}; - -int bitmap_create(struct bmap *bmap, uint64_t size, uint8_t bitsize); -int bitmap_set(struct bmap *bmap, uint64_t offset, uint8_t val); -int bitmap_get(struct bmap *bmap, uint64_t bit, uint8_t *val); -int bitmap_clear(struct bmap *bmap, uint64_t offset); -void bitmap_destroy(struct bmap *bmap); -uint64_t bitmap_size(struct bmap *bmap); - - -#endif /* _BITMAP_H */ diff --git a/gfs/gfs_fsck/block_list.c b/gfs/gfs_fsck/block_list.c deleted file mode 100644 index be74992..0000000 --- a/gfs/gfs_fsck/block_list.c +++ /dev/null @@ -1,301 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include "bitmap.h" -#include "block_list.h" -#include "fsck.h" - -#define FREE (0x0) /* 0000 */ -#define BLOCK_IN_USE (0x1) /* 0001 */ - -#define DIR_INDIR_BLK (0x2) /* 0010 */ -#define DIR_INODE (0x3) /* 0011 */ -#define FILE_INODE (0x4) /* 0100 */ -#define LNK_INODE (0x5) -#define BLK_INODE (0x6) -#define CHR_INODE (0x7) -#define FIFO_INODE (0x8) -#define SOCK_INODE (0x9) -#define DIR_LEAF_INODE (0xA) /* 1010 */ -#define JOURNAL_BLK (0xB) /* 1011 */ -#define OTHER_META (0xC) /* 1100 */ -#define FREE_META (0xD) /* 1101 */ -#define EATTR_META (0xE) /* 1110 */ - -#define INVALID_META (0xF) /* 1111 */ - - -/* Must be kept in sync with mark_block enum in block_list.h */ -/* FIXME: Fragile */ -static int mark_to_gbmap[16] = { - FREE, BLOCK_IN_USE, DIR_INDIR_BLK, DIR_INODE, FILE_INODE, - LNK_INODE, BLK_INODE, CHR_INODE, FIFO_INODE, SOCK_INODE, - DIR_LEAF_INODE, JOURNAL_BLK, OTHER_META, FREE_META, - EATTR_META, INVALID_META -}; - -struct block_list *block_list_create(uint64_t size, enum block_list_type type) -{ - struct block_list *il; - uint64_t addl_mem_needed = 0L; - log_info("Creating a block list of size %"PRIu64"...\n", size); - - if ((il = malloc(sizeof(*il)))) { - if(!memset(il, 0, sizeof(*il))) { - log_err("Cannot set block list to zero\n"); - return NULL; - } - il->type = type; - - switch(type) { - case gbmap: - if(bitmap_create(&il->list.gbmap.group_map, size, 4)) { - /* Note on addl_mem_needed: We've tried to allocate ram */ - /* for our bitmaps, but we failed. The fs is too big. */ - /* We should tell them how much to allocate. This first */ - /* bitmap is the biggest, but we need three more smaller */ - /* for the code that immediately follows. I'm rounding */ - /* up to twice the memory for this bitmap, even though */ - /* it's actually 1 + 3/4. That will allow for future */ - /* mallocs that happen after this point in the code. */ - /* For the bad_map, we have two more to go (total of 3) */ - /* but again I'm rounding it up to 4 smaller ones. */ - /* For the dup_map, I'm rounding from 2 to 3, and for */ - /* eattr_map, I'm rounding up from 1 to 2. */ - addl_mem_needed = il->list.gbmap.group_map.mapsize * 2; - stack; - free(il); - il = NULL; - } - else if(bitmap_create(&il->list.gbmap.bad_map, size, 1)) { - addl_mem_needed = il->list.gbmap.group_map.mapsize * 4; - stack; - free(il); - il = NULL; - } - else if(bitmap_create(&il->list.gbmap.dup_map, size, 1)) { - addl_mem_needed = il->list.gbmap.group_map.mapsize * 3; - stack; - free(il); - il = NULL; - } - else if(bitmap_create(&il->list.gbmap.eattr_map, size, 1)) { - addl_mem_needed = il->list.gbmap.group_map.mapsize * 2; - stack; - free(il); - il = NULL; - } - if (addl_mem_needed) { - log_err("This system doesn't have enough memory + swap space to fsck this file system.\n"); - log_err("Additional memory needed is approximately: %ldMB\n", addl_mem_needed / 1048576); - log_err("Please increase your swap space by that amount and run gfs_fsck again.\n"); - } - break; - default: - log_crit("Block list type %d not implemented\n", - type); - break; - } - } - - return il; -} - -int block_mark(struct block_list *il, uint64_t block, enum mark_block mark) -{ - int err = 0; - - switch(il->type) { - case gbmap: - if(mark == bad_block) { - err = bitmap_set(&il->list.gbmap.bad_map, block, 1); - } - else if(mark == dup_block) { - err = bitmap_set(&il->list.gbmap.dup_map, block, 1); - } - else if(mark == eattr_block) { - err = bitmap_set(&il->list.gbmap.eattr_map, block, 1); - } - else { - err = bitmap_set(&il->list.gbmap.group_map, block, - mark_to_gbmap[mark]); - } - - break; - default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; - break; - } - return err; -} - -int block_set(struct block_list *il, uint64_t block, enum mark_block mark) -{ - int err = 0; - err = block_clear(il, block, mark); - if(!err) - err = block_mark(il, block, mark); - return err; -} - -int block_clear(struct block_list *il, uint64_t block, enum mark_block m) -{ - int err = 0; - - switch(il->type) { - case gbmap: - switch (m) { - case dup_block: - err = bitmap_clear(&il->list.gbmap.dup_map, block); - break; - case bad_block: - err = bitmap_clear(&il->list.gbmap.bad_map, block); - break; - case eattr_block: - err = bitmap_clear(&il->list.gbmap.eattr_map, block); - break; - default: - /* FIXME: check types */ - err = bitmap_clear(&il->list.gbmap.group_map, block); - break; - } - - break; - default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; - break; - } - return err; -} - -int block_check(struct block_list *il, uint64_t block, struct block_query *val) -{ - int err = 0; - val->block_type = 0; - val->bad_block = 0; - val->dup_block = 0; - switch(il->type) { - case gbmap: - if((err = bitmap_get(&il->list.gbmap.group_map, block, - &val->block_type))) { - log_err("Unable to get block type for block %" - PRIu64"\n", block); - break; - } - if((err = bitmap_get(&il->list.gbmap.bad_map, block, - &val->bad_block))) { - log_err("Unable to get bad block status for block %" - PRIu64"\n", block); - break; - } - if((err = bitmap_get(&il->list.gbmap.dup_map, block, - &val->dup_block))) { - log_err("Unable to get duplicate status for block %" - PRIu64"\n", block); - break; - } - if((err = bitmap_get(&il->list.gbmap.eattr_map, block, - &val->eattr_block))) { - log_err("Unable to get eattr status for block %" - PRIu64"\n", block); - break; - } - break; - default: - log_err("block list type %d not implemented\n", - il->type); - err = -1; - break; - } - - return err; -} - -void *block_list_destroy(struct block_list *il) -{ - if(il) { - switch(il->type) { - case gbmap: - bitmap_destroy(&il->list.gbmap.group_map); - bitmap_destroy(&il->list.gbmap.bad_map); - bitmap_destroy(&il->list.gbmap.dup_map); - bitmap_destroy(&il->list.gbmap.eattr_map); - break; - default: - break; - } - free(il); - il = NULL; - } - return il; -} - - -int find_next_block_type(struct block_list *il, enum mark_block m, uint64_t *b) -{ - uint64_t i; - uint8_t val; - int found = 0; - for(i = *b; ; i++) { - switch(il->type) { - case gbmap: - if(i >= bitmap_size(&il->list.gbmap.dup_map)) - return -1; - - switch(m) { - case dup_block: - if(bitmap_get(&il->list.gbmap.dup_map, i, - &val)) { - stack; - return -1; - } - - if(val) - found = 1; - break; - case eattr_block: - if(bitmap_get(&il->list.gbmap.eattr_map, i, - &val)) { - stack; - return -1; - } - - if(val) - found = 1; - break; - default: - /* FIXME: add support for getting - * other types */ - log_err("Unhandled block type\n"); - } - break; - default: - log_err("Unhandled block list type\n"); - break; - } - if(found) { - *b = i; - return 0; - } - } - return -1; -} diff --git a/gfs/gfs_fsck/block_list.h b/gfs/gfs_fsck/block_list.h deleted file mode 100644 index 67a4d5a..0000000 --- a/gfs/gfs_fsck/block_list.h +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _BLOCK_LIST_H -#define _BLOCK_LIST_H - -#include "bitmap.h" - -#define BMAP_COUNT 13 - -enum block_list_type { - gbmap = 0, /* Grouped bitmap */ - dbmap, /* Ondisk bitmap - like grouped bitmap, but mmaps - * the bitmaps onto file(s) ondisk - not implemented */ -}; - -/* Must be kept in sync with mark_to_bitmap array in block_list.c */ -enum mark_block { - block_free = 0, - block_used, - indir_blk, - inode_dir, - inode_file, - inode_lnk, - inode_blk, - inode_chr, - inode_fifo, - inode_sock, - leaf_blk, - journal_blk, - meta_other, - meta_free, - meta_eattr, - meta_inval = 15, - bad_block, /* Contains at least one bad block */ - dup_block, /* Contains at least one duplicate block */ - eattr_block, /* Contains an eattr */ -}; - -struct block_query { - uint8_t block_type; - uint8_t bad_block; - uint8_t dup_block; - uint8_t eattr_block; -}; - -struct gbmap { - struct bmap group_map; - struct bmap bad_map; - struct bmap dup_map; - struct bmap eattr_map; -}; - -struct dbmap { - struct bmap group_map; - char *group_file; - struct bmap bad_map; - char *bad_file; - struct bmap dup_map; - char *dup_file; - struct bmap eattr_map; - char *eattr_file; -}; - -union block_lists { - struct gbmap gbmap; - struct dbmap dbmap; -}; - - -/* bitmap implementation */ -struct block_list { - enum block_list_type type; - /* Union of bitmap, rle */ - union block_lists list; -}; - - -struct block_list *block_list_create(uint64_t size, enum block_list_type type); -int block_mark(struct block_list *il, uint64_t block, enum mark_block mark); -int block_set(struct block_list *il, uint64_t block, enum mark_block mark); -int block_clear(struct block_list *il, uint64_t block, enum mark_block m); -int block_check(struct block_list *il, uint64_t block, - struct block_query *val); -int block_check_for_mark(struct block_list *il, uint64_t block, - enum mark_block mark); -void *block_list_destroy(struct block_list *il); -int find_next_block_type(struct block_list *il, enum mark_block m, uint64_t *b); - -#endif /* _BLOCK_LIST_H */ diff --git a/gfs/gfs_fsck/eattr.c b/gfs/gfs_fsck/eattr.c deleted file mode 100644 index 5b159ac..0000000 --- a/gfs/gfs_fsck/eattr.c +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdint.h> - -#include "fsck_incore.h" - - -static int clear_blk_nodup(struct fsck_sb *sbp, uint64_t block) -{ - struct block_query q; - - if(block_check(sbp->bl, block, &q)) { - stack; - return -1; - } - - if(q.dup_block) { - log_debug("Not clearing block with marked as a duplicate\n"); - return 1; - } - - block_set(sbp->bl, block, block_free); - - return 0; - -} - -int clear_eattr_indir(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private) -{ - return clear_blk_nodup(ip->i_sbd, block); -} - - -int clear_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private) -{ - - return clear_blk_nodup(ip->i_sbd, block); - -} - - -int clear_eattr_entry (struct fsck_inode *ip, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - char ea_name[256]; - - if(!ea_hdr->ea_name_len){ - /* Skip this entry for now */ - return 1; - } - - memset(ea_name, 0, sizeof(ea_name)); - strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs_ea_header), - ea_hdr->ea_name_len); - - if(!GFS_EATYPE_VALID(ea_hdr->ea_type) && - ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){ - /* Skip invalid entry */ - return 1; - } - - if(ea_hdr->ea_num_ptrs){ - uint32 avail_size; - int max_ptrs; - - avail_size = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header); - max_ptrs = (gfs32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size; - - if(max_ptrs > ea_hdr->ea_num_ptrs) { - return 1; - } else { - log_debug(" Pointers Required: %d\n" - " Pointers Reported: %d\n", - max_ptrs, - ea_hdr->ea_num_ptrs); - } - - - } - return 0; -} - -int clear_eattr_extentry(struct fsck_inode *ip, uint64_t *ea_data_ptr, - osi_buf_t *leaf_bh, struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, void *private) -{ - uint64_t block = gfs64_to_cpu(*ea_data_ptr); - - return clear_blk_nodup(ip->i_sbd, block); - -} - - - diff --git a/gfs/gfs_fsck/eattr.h b/gfs/gfs_fsck/eattr.h deleted file mode 100644 index ac05e9c..0000000 --- a/gfs/gfs_fsck/eattr.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _EATTR_H -#define _EATTR_H - -int clear_eattr_indir(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private); -int clear_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private); -int clear_eattr_entry (struct fsck_inode *ip, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private); -int clear_eattr_extentry(struct fsck_inode *ip, uint64_t *ea_data_ptr, - osi_buf_t *leaf_bh, struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, void *private); - - - -#endif /* _EATTR_H */ diff --git a/gfs/gfs_fsck/file.c b/gfs/gfs_fsck/file.c deleted file mode 100644 index e274894..0000000 --- a/gfs/gfs_fsck/file.c +++ /dev/null @@ -1,242 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "util.h" -#include "bio.h" -#include "fs_bmap.h" -#include "fs_inode.h" -#include "fsck.h" -#include "file.h" - -/** - * readi - Read a file - * @ip: The GFS Inode - * @buf: The buffer to place result into - * @offset: File offset to begin reading from - * @size: Amount of data to transfer - * - * Returns: The amount of data actually copied or the error - */ -int readi(struct fsck_inode *ip, void *buf, uint64 offset, unsigned int size) -{ - struct fsck_sb *sdp = ip->i_sbd; - osi_buf_t *bh; - uint64_t lblock, dblock=0; - uint32_t extlen = 0; - unsigned int amount; - int not_new = 0; - int journaled = fs_is_jdata(ip); - int copied = 0; - int error = 0; - - if (offset >= ip->i_di.di_size){ - log_debug("readi: Offset (%"PRIu64") is >= " - "the file size (%"PRIu64").\n", - offset, ip->i_di.di_size); - goto out; - } - - if ((offset + size) > ip->i_di.di_size) - size = ip->i_di.di_size - offset; - - if (!size){ - log_err("readi: Nothing to be read.\n"); - goto out; - } - - if (journaled){ - lblock = offset / sdp->jbsize; - offset %= sdp->jbsize; - } - else{ - lblock = offset >> sdp->sb.sb_bsize_shift; - offset &= sdp->sb.sb_bsize - 1; - } - - if (fs_is_stuffed(ip)) - offset += sizeof(struct gfs_dinode); - else if (journaled) - offset += sizeof(struct gfs_meta_header); - - - while (copied < size){ - amount = size - copied; - if (amount > sdp->sb.sb_bsize - offset) - amount = sdp->sb.sb_bsize - offset; - - if (!extlen){ - error = fs_block_map(ip, lblock, ¬_new, &dblock, &extlen); - if (error){ - log_err("readi: The call to fs_block_map() failed.\n"); - goto out; - } - } - - if (dblock){ - error = get_and_read_buf(ip->i_sbd, dblock, &bh, 0); - if (error){ - log_err("readi: Unable to perform get_and_read_buf()\n"); - goto out; - } - - dblock++; - extlen--; - } - else - bh = NULL; - - if (bh){ - memcpy(buf+copied, BH_DATA(bh)+offset, amount); - relse_buf(ip->i_sbd, bh); - } else { - memset(buf+copied, 0, amount); - } - copied += amount; - lblock++; - - offset = (journaled) ? sizeof(struct gfs_meta_header) : 0; - } - - out: - - return (error < 0) ? error : copied; -} - - - -/** - * writei - Write bytes to a file - * @ip: The GFS inode - * @buf: The buffer containing information to be written - * @offset: The file offset to start writing at - * @size: The amount of data to write - * - * Returns: The number of bytes correctly written or error code - */ -int writei(struct fsck_inode *ip, void *buf, uint64_t offset, unsigned int size) -{ - struct fsck_sb *sdp = ip->i_sbd; - osi_buf_t *dibh, *bh; - uint64_t lblock, dblock; - uint32_t extlen = 0; - unsigned int amount; - int new; - int journaled = fs_is_jdata(ip); - const uint64_t start = offset; - int copied = 0; - int error = 0; - - /* Bomb out on writing nothing. - Posix says we can't change the time here. */ - - if (!size) - goto fail; /* Not really an error */ - - - if (fs_is_stuffed(ip) && - ((start + size) > (sdp->sb.sb_bsize - sizeof(struct gfs_dinode)))){ - error = fs_unstuff_dinode(ip); - if (error) - goto fail; - } - - - if (journaled){ - lblock = offset / sdp->jbsize; - offset %= sdp->jbsize; - } - else{ - lblock = offset >> sdp->sb.sb_bsize_shift; - offset &= sdp->sb.sb_bsize - 1; - } - - if (fs_is_stuffed(ip)) - offset += sizeof(struct gfs_dinode); - else if (journaled) - offset += sizeof(struct gfs_meta_header); - - - while (copied < size){ - amount = size - copied; - if (amount > sdp->sb.sb_bsize - offset) - amount = sdp->sb.sb_bsize - offset; - - if (!extlen){ - new = TRUE; - error = fs_block_map(ip, lblock, &new, &dblock, &extlen); - if (error) - goto fail; - if(!dblock){ - log_crit("fs_writei: " - "Unable to map logical block to real block.\n"); - log_crit("Uncircumventable error.\n"); - exit(EXIT_FAILURE); - } - } - - error = get_and_read_buf(ip->i_sbd, dblock, &bh, 0); - if (error) - goto fail; - - if(journaled && dblock != ip->i_di.di_num.no_addr ) { - set_meta(bh, GFS_METATYPE_JD, GFS_FORMAT_JD); - } - - memcpy(BH_DATA(bh)+offset, buf+copied, amount); - write_buf(ip->i_sbd, bh, 0); - relse_buf(ip->i_sbd, bh); - - copied += amount; - lblock++; - dblock++; - extlen--; - - offset = (journaled) ? sizeof(struct gfs_meta_header) : 0; - } - - - out: - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); - if (error){ - log_err("fs_writei: " - "Unable to get inode buffer.\n"); - return -1; - } - - error = check_meta(dibh, GFS_METATYPE_DI); - if(error){ - log_err("fs_writei: " - "Buffer is not a valid inode.\n"); - relse_buf(ip->i_sbd, dibh); - return -1; - } - - if (ip->i_di.di_size < start + copied) - ip->i_di.di_size = start + copied; - ip->i_di.di_mtime = ip->i_di.di_ctime = osi_current_time(); - - gfs_dinode_out(&ip->i_di, BH_DATA(dibh)); - write_buf(ip->i_sbd, dibh, 0); - relse_buf(ip->i_sbd, dibh); - - return copied; - - - - fail: - if (copied) - goto out; - - return error; -} - diff --git a/gfs/gfs_fsck/file.h b/gfs/gfs_fsck/file.h deleted file mode 100644 index 5f14358..0000000 --- a/gfs/gfs_fsck/file.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _FILE_H -#define _FILE_H - -#include <stdint.h> -#include "fsck_incore.h" - -int readi(struct fsck_inode *ip, void *buf, uint64_t offset, unsigned int size); -int writei(struct fsck_inode *ip, void *buf, uint64_t offset, unsigned int size); - -#endif /* _FILE_H */ diff --git a/gfs/gfs_fsck/fs_bits.c b/gfs/gfs_fsck/fs_bits.c deleted file mode 100644 index 8162e5e..0000000 --- a/gfs/gfs_fsck/fs_bits.c +++ /dev/null @@ -1,362 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "util.h" -#include "bio.h" -#include "rgrp.h" - -#include "fsck_incore.h" -#include "fs_bits.h" -/** - * fs_setbit - Set a bit in the bitmaps - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @block: the block to set - * @new_state: the new state of the block - * - */ -static void fs_setbit(unsigned char *buffer, unsigned int buflen, - uint32_t block, unsigned char new_state) -{ - unsigned char *byte, *end, cur_state; - unsigned int bit; - - byte = buffer + (block / GFS_NBBY); - bit = (block % GFS_NBBY) * GFS_BIT_SIZE; - end = buffer + buflen; - - if(byte >= end){ - log_err("fs_setbit: byte >= end\n"); - exit(1); - } - cur_state = (*byte >> bit) & GFS_BIT_MASK; - - *byte ^= cur_state << bit; - *byte |= new_state << bit; -} - -uint32_t fs_bitfit_core(struct fsck_sb *sbp, uint64_t goal, uint64_t start, uint64_t len, - unsigned char old_state) -{ - uint64_t block; - struct block_query q; - - log_debug("Goal: %"PRIu64", Start: %"PRIu64" len: %"PRIu64"\n", - goal, start, len); - for(block = start+goal; block < start+len; block++) { - block_check(sbp->bl, block, &q); - switch(old_state) { - case GFS_BLKST_FREE: - switch(q.block_type) { - case block_free: - return block - start; - } - break; - case GFS_BLKST_FREEMETA: - switch(q.block_type) { - case meta_free: - return block - start; - } - break; - case GFS_BLKST_USEDMETA: - switch(q.block_type) { - case inode_dir: - case inode_file: - case inode_lnk: - case inode_blk: - case inode_chr: - case inode_fifo: - case inode_sock: - case indir_blk: - case leaf_blk: - case journal_blk: - case meta_other: - case meta_eattr: - return block - start; - } - break; - case GFS_BLKST_USED: - switch(q.block_type) { - case block_used: - return block - start; - } - break; - default: - log_err("Invalid type"); - break; - } - } - return BFITNOENT; -} -/** - * fs_bitfit - Find a free block in the bitmaps - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @goal: the block to try to allocate - * @old_state: the state of the block we're looking for - * - * Return: the block number that was allocated - */ -uint32_t fs_bitfit(unsigned char *buffer, unsigned int buflen, - uint32_t goal, unsigned char old_state) -{ - unsigned char *byte, *end, alloc; - uint32_t blk = goal; - unsigned int bit; - - - byte = buffer + (goal / GFS_NBBY); - bit = (goal % GFS_NBBY) * GFS_BIT_SIZE; - end = buffer + buflen; - alloc = (old_state & 1) ? 0 : 0x55; - - while (byte < end){ - if ((*byte & 0x55) == alloc){ - blk += (8 - bit) >> 1; - - bit = 0; - byte++; - - continue; - } - - if (((*byte >> bit) & GFS_BIT_MASK) == old_state){ - return blk; - } - - bit += GFS_BIT_SIZE; - if (bit >= 8){ - bit = 0; - byte++; - } - - blk++; - } - return BFITNOENT; -} - -/** - * fs_bitcount - count the number of bits in a certain state - * @buffer: the buffer that holds the bitmaps - * @buflen: the length (in bytes) of the buffer - * @state: the state of the block we're looking for - * - * Returns: The number of bits - */ -uint32_t fs_bitcount(unsigned char *buffer, unsigned int buflen, - unsigned char state) -{ - unsigned char *byte, *end; - unsigned int bit; - uint32_t count = 0; - - byte = buffer; - bit = 0; - end = buffer + buflen; - - while (byte < end){ - if (((*byte >> bit) & GFS_BIT_MASK) == state) - count++; - - bit += GFS_BIT_SIZE; - if (bit >= 8){ - bit = 0; - byte++; - } - } - return count; -} - - -/** - * fs_blkalloc_internal - allocate a single block - * @rgd: the resource group descriptor - * @goal: the goal block in the RG - * @old_state: the type of block to find - * @new_state: the resulting block type - * @do_it: if FALSE, we just find the block we would allocate - * - * - * Returns: returns the block allocated, or BFITNOENT on failure - */ -uint32_t fs_blkalloc_internal(struct fsck_rgrp *rgd, uint32_t goal, - unsigned char old_state, - unsigned char new_state, int do_it) -{ - struct fsck_sb *sdp = rgd->rd_sbd; - uint32_t block = 0; - log_debug("fs_blkalloc_internal got %u as goal\n", goal); - goal = ((int)(goal - rgd->rd_ri.ri_data1) < 0) - ? 0 - : goal - rgd->rd_ri.ri_data1; - - - block = fs_bitfit_core(sdp, goal, rgd->rd_ri.ri_data1, - rgd->rd_ri.ri_data, old_state); - - - if(block == BFITNOENT) { - log_debug("No bits left in old_state?\n" - "\told_state = %u\n" - "\tnew_state = %u\n" - "\trg_free = %u\n" - "\trg_freemeta = %u\n", - old_state, new_state, - rgd->rd_rg.rg_free, - rgd->rd_rg.rg_freemeta); - return BFITNOENT; - } - - log_debug("fs_blkalloc_internal found block %u\n", block); - switch(new_state) { - case GFS_BLKST_FREE: - block_set(sdp->bl, block + rgd->rd_ri.ri_data1, block_free); - break; - case GFS_BLKST_USED: - block_set(sdp->bl, block + rgd->rd_ri.ri_data1, block_used); - break; - case GFS_BLKST_USEDMETA: - block_set(sdp->bl, block + rgd->rd_ri.ri_data1, meta_other); - break; - case GFS_BLKST_FREEMETA: - block_set(sdp->bl, block + rgd->rd_ri.ri_data1, meta_free); - break; - } - return block; -} - - -/* - * fs_get_bitmap - get value of FS bitmap - * @sdp: super block - * @blkno: block number relative to file system - * - * This function gets the value of a bit of the - * file system bitmap. - * Possible state values for a block in the bitmap are: - * GFS_BLKST_FREE (0) - * GFS_BLKST_USED (1) - * GFS_BLKST_FREEMETA (2) - * GFS_BLKST_USEDMETA (3) - * - * Returns: state on success, -1 on error - */ -int fs_get_bitmap(struct fsck_sb *sdp, uint64 blkno, struct fsck_rgrp *rgd){ - int buf, val; - uint32_t rgrp_block; -/* struct fsck_rgrp *rgd;*/ - fs_bitmap_t *bits = NULL; - unsigned int bit; - unsigned char *byte; - int local_rgd = 0; - - if(check_range(sdp, blkno)){ - log_warn("Block #%"PRIu64" is out of range.\n", blkno); - return -1; - } - if(rgd == NULL) { - local_rgd = 1; - rgd = fs_blk2rgrpd(sdp, blkno); - } - if(rgd == NULL){ - log_err( "Unable to get rgrp for block #%"PRIu64"\n", blkno); - return -1; - } - if(fs_rgrp_read(rgd, FALSE)){ /* FALSE:don't try to fix (done elsewhere) */ - log_err( "Unable to read rgrp.\n"); - return -1; - } - - rgrp_block = (uint32_t)(blkno - rgd->rd_ri.ri_data1); - - for(buf= 0; buf < rgd->rd_ri.ri_length; buf++){ - bits = &(rgd->rd_bits[buf]); - if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS_NBBY)){ - break; - } - } - - if(buf >= rgd->rd_ri.ri_length){ - log_err( "Unable to locate bitmap entry for block #%"PRIu64"\n", - blkno); - fs_rgrp_relse(rgd); - return -1; - } - - byte = (BH_DATA(rgd->rd_bh[buf]) + bits->bi_offset) + - (rgrp_block/GFS_NBBY - bits->bi_start); - bit = (rgrp_block % GFS_NBBY) * GFS_BIT_SIZE; - - val = ((*byte >> bit) & GFS_BIT_MASK); - if(local_rgd) { - fs_rgrp_relse(rgd); - } - - return val; -} - - -/* - * fs_set_bitmap - * @sdp: super block - * @blkno: block number relative to file system - * @state: one of 4 possible states - * - * This function sets the value of a bit of the - * file system bitmap. - * - * Returns: 0 on success, -1 on error - */ -int fs_set_bitmap(struct fsck_sb *sdp, uint64 blkno, int state){ - int buf; - uint32_t rgrp_block; - fs_bitmap_t *bits = NULL; - struct fsck_rgrp *rgd; - - if((state != GFS_BLKST_FREE) && (state != GFS_BLKST_USED) && - (state != GFS_BLKST_FREEMETA) && (state != GFS_BLKST_USEDMETA)){ - return -1; - } - - rgd = fs_blk2rgrpd(sdp, blkno); - - if(!rgd) { - log_err("Unable to get resource group for blkno %"PRIu64"\n", - blkno); - return -1; - } - - if(fs_rgrp_read(rgd, FALSE)) { - stack; - return -1; - } - rgrp_block = (uint32_t)(blkno - rgd->rd_ri.ri_data1); - for(buf= 0; buf < rgd->rd_ri.ri_length; buf++){ - bits = &(rgd->rd_bits[buf]); - if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS_NBBY)){ - break; - } - } - if (buf < rgd->rd_ri.ri_length) { - fs_setbit(BH_DATA(rgd->rd_bh[buf]) + bits->bi_offset, - bits->bi_len, - (rgrp_block - (bits->bi_start*GFS_NBBY)), - state); - if(write_buf(sdp, rgd->rd_bh[buf], 0)){ - fs_rgrp_relse(rgd); - return -1; - } - } - fs_rgrp_relse(rgd); - return 0; -} diff --git a/gfs/gfs_fsck/fs_bits.h b/gfs/gfs_fsck/fs_bits.h deleted file mode 100644 index 43efe52..0000000 --- a/gfs/gfs_fsck/fs_bits.h +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FS_BITS_H__ -#define __FS_BITS_H__ - -#include "global.h" -#include "rgrp.h" -#include "fsck_incore.h" -#include "fsck.h" - -#define BFITNOENT (0xFFFFFFFF) - -struct fs_bitmap -{ - uint32 bi_offset; /* The offset in the buffer of the first byte */ - uint32 bi_start; /* The position of the first byte in this block */ - uint32 bi_len; /* The number of bytes in this block */ -}; -typedef struct fs_bitmap fs_bitmap_t; - -/* functions with blk #'s that are buffer relative */ -uint32_t fs_bitcount(unsigned char *buffer, unsigned int buflen, - unsigned char state); -uint32_t fs_bitfit(unsigned char *buffer, unsigned int buflen, - uint32_t goal, unsigned char old_state); - -/* functions with blk #'s that are rgrp relative */ -uint32_t fs_blkalloc_internal(struct fsck_rgrp *rgd, uint32_t goal, - unsigned char old_state, - unsigned char new_state, int do_it); - -/* functions with blk #'s that are file system relative */ -int fs_get_bitmap(struct fsck_sb *sdp, uint64_t blkno, struct fsck_rgrp *rgd); -int fs_set_bitmap(struct fsck_sb *sdp, uint64_t blkno, int state); - -#endif /* __FS_BITS_H__ */ diff --git a/gfs/gfs_fsck/fs_bmap.c b/gfs/gfs_fsck/fs_bmap.c deleted file mode 100644 index e7d1fc9..0000000 --- a/gfs/gfs_fsck/fs_bmap.c +++ /dev/null @@ -1,542 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "util.h" -#include "rgrp.h" -#include "fs_inode.h" -#include "bio.h" - -#include "fs_bmap.h" - -typedef struct metapath -{ - uint64 mp_list[GFS_MAX_META_HEIGHT]; -}metapath_t; - - -/** - * fs_unstuff_dinode - Unstuff a dinode when the data has grown too big - * @ip: The GFS inode to unstuff - * * This routine unstuffs a dinode and returns it to a "normal" state such - * that the height can be grown in the traditional way. - * - * Returns: 0 on success, -EXXXX on failure - */ -int fs_unstuff_dinode(struct fsck_inode *ip) -{ - struct fsck_sb *sdp = ip->i_sbd; - osi_buf_t *bh = NULL; - osi_buf_t *dibh = NULL; - int journaled = fs_is_jdata(ip); - uint64 block = 0; - int error; - - log_debug("Unstuffing inode %"PRIu64" - %u\n", ip->i_di.di_num.no_addr, - journaled); - - if(!fs_is_stuffed(ip)){ - log_err("Trying to unstuff a dinode that is already unstuffed.\n"); - return -1; - } - - - error = get_and_read_buf(sdp, ip->i_num.no_addr, &dibh, 0); - if (error) { - stack; - goto fail; - } - - error = check_meta(dibh, GFS_METATYPE_DI); - if(error) { - stack; - goto fail; - } - - if (ip->i_di.di_size){ - log_err("Allocating new block for unstuffed dinode\n"); - if(journaled){ - error = fs_metaalloc(ip, &block); - if (error) { - stack; - goto fail; - } - log_err("Got block %"PRIu64"\n", block); - error = get_buf(sdp, block, &bh); - if (error) { - stack; - goto fail; - } - - set_meta(bh, GFS_METATYPE_JD, GFS_FORMAT_JD); - - memcpy(BH_DATA(bh)+sizeof(struct gfs_meta_header), - BH_DATA(dibh)+sizeof(struct gfs_dinode), - BH_SIZE(dibh)-sizeof(struct gfs_dinode)); - - error = write_buf(sdp, bh, 0); - if(error) { - stack; - goto fail; - } - relse_buf(sdp, bh); - block_set(sdp->bl, block, journal_blk); - } - else{ - error = fs_blkalloc(ip, &block); - - if(error) { - stack; - goto fail; - } - - error = get_buf(sdp, block, &bh); - if (error) { - stack; - goto fail; - } - - memcpy(BH_DATA(bh)+sizeof(struct gfs_meta_header), - BH_DATA(dibh)+sizeof(struct gfs_dinode), - BH_SIZE(dibh)-sizeof(struct gfs_dinode)); - - error = write_buf(sdp, bh, 0); - if(error) { - stack; - goto fail; - } - relse_buf(sdp, bh); - block_set(sdp->bl, block, block_used); - } - } - - bh = NULL; - /* Set up the pointer to the new block */ - - memset(BH_DATA(dibh)+sizeof(struct gfs_dinode), 0, - BH_SIZE(dibh)-sizeof(struct gfs_dinode)); - - if (ip->i_di.di_size){ - ((uint64 *)(BH_DATA(dibh) + sizeof(struct gfs_dinode)))[0] = cpu_to_gfs64(block); - ip->i_di.di_blocks++; - } - - ip->i_di.di_height = 1; - - gfs_dinode_out(&ip->i_di, BH_DATA(dibh)); - if(write_buf(sdp, dibh, 0)){ - log_err("Dinode unstuffed, but unable to write back dinode.\n"); - goto fail; - } - relse_buf(sdp, dibh); - - return 0; - - - - fail: - if(bh) relse_buf(sdp, bh); - if(dibh) relse_buf(sdp, dibh); - - return error; -} - - -/** - * calc_tree_height - Calculate the height of a metadata tree - * @ip: The GFS inode - * @size: The proposed size of the file - * - * Work out how tall a metadata tree needs to be in order to accommodate a - * file of a particular size. If size is less than the current size of - * the inode, then the current size of the inode is used instead of the - * supplied one. - * - * Returns: the height the tree should be - */ - -static unsigned int calc_tree_height(struct fsck_inode *ip, uint64 size) -{ - struct fsck_sb *sdp = ip->i_sbd; - uint64 *arr; - unsigned int max, height; - - if (ip->i_di.di_size > size) - size = ip->i_di.di_size; - - if (fs_is_jdata(ip)){ - arr = sdp->jheightsize; - max = sdp->max_jheight; - } - else{ - arr = sdp->heightsize; - max = sdp->max_height; - } - for (height = 0; height < max; height++) - if (arr[height] >= size) - break; - - return height; -} - - -/** - * build_height - Build a metadata tree of the requested height - * @ip: The GFS inode - * @height: The height to build to - * - * - * Returns: 0 on success, -EXXXX on failure - */ -static int build_height(struct fsck_inode *ip, int height) -{ - struct fsck_sb *sdp = ip->i_sbd; - osi_buf_t *bh, *dibh; - uint64 block, *bp; - unsigned int x; - int new_block; - int error; - - while (ip->i_di.di_height < height){ - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); - if (error) - goto fail; - - new_block = FALSE; - bp = (uint64 *)(BH_DATA(dibh) + sizeof(struct gfs_dinode)); - for (x = 0; x < sdp->diptrs; x++, bp++) - if (*bp){ - new_block = TRUE; - break; - } - - - if (new_block){ - /* Get a new block, fill it with the old direct pointers and write it out */ - error = fs_metaalloc(ip, &block); - if (error) - goto fail_drelse; - - error = get_and_read_buf(sdp, block, &bh, 0); - if (error) - goto fail_drelse; - - set_meta(bh, GFS_METATYPE_IN, GFS_FORMAT_IN); - /* - gfs_buffer_copy_tail(bh, sizeof(struct gfs_indirect), - dibh, sizeof(struct gfs_dinode)); - */ - log_err("ATTENTION -- Not doing copy_tail...\n"); - exit(1); - error = -1; - goto fail_drelse; - if((error = write_buf(sdp, bh, 0))){ - log_err( "Unable to write new buffer #%"PRIu64".\n", - BH_BLKNO(bh)); - goto fail_drelse; - } - relse_buf(sdp, bh); - } - - - /* Set up the new direct pointer and write it out to disk */ - - memset(BH_DATA(dibh)+sizeof(struct gfs_dinode), 0, - BH_SIZE(dibh)-sizeof(struct gfs_dinode)); - - if (new_block){ - ((uint64 *)(BH_DATA(dibh) + sizeof(struct gfs_dinode)))[0] = cpu_to_gfs64(block); - ip->i_di.di_blocks++; - } - - ip->i_di.di_height++; - - gfs_dinode_out(&ip->i_di, BH_DATA(dibh)); - write_buf(sdp, dibh, 0); - relse_buf(sdp, dibh); - } - - return 0; - - - - fail_drelse: - relse_buf(sdp, dibh); - - fail: - return error; -} - - -static void find_metapath(struct fsck_inode *ip, metapath_t *mp, uint64 block) -{ - struct fsck_sb *sdp = ip->i_sbd; - unsigned int i; - - for (i = ip->i_di.di_height; i--; ){ - mp->mp_list[i] = block % sdp->inptrs; - block /= sdp->inptrs; - } -} - - -/** - * metapointer - Return pointer to start of metadata in a buffer - * @bh: The buffer - * @level: The metadata level (0 = dinode) - * @mp: The metapath - * - * Return a pointer to the block number of the next level of the metadata - * tree given a buffer containing the pointer to the current level of the - * metadata tree. - */ - -static uint64 *metapointer(osi_buf_t *bh, unsigned int level, metapath_t *mp) -{ - int head_size = (level > 0) ? sizeof(struct gfs_indirect) : sizeof(struct gfs_dinode); - return ((uint64 *)(BH_DATA(bh) + head_size)) + mp->mp_list[level]; -} - - -/** - * get_metablock - Get the next metadata block in metadata tree - * @ip: The GFS inode - * @bh: Buffer containing the pointers to metadata blocks - * @level: The level of the tree (0 = dinode) - * @mp: The metapath - * @create: Non-zero if we may create a new meatdata block - * @new: Used to indicate if we did create a new metadata block - * @block: the returned disk block number - * - * Given a metatree, complete to a particular level, checks to see if the next - * level of the tree exists. If not the next level of the tree is created. - * The block number of the next level of the metadata tree is returned. - * - * Returns: 0 on success, -EXXX on failure - */ - -static int get_metablock(struct fsck_inode *ip, - osi_buf_t *bh, unsigned int level, metapath_t *mp, - int create, int *new, uint64 *block) -{ - uint64 *ptr = metapointer(bh, level, mp); - int error = 0; - - *new = 0; - *block = 0; - - if (*ptr){ - *block = gfs64_to_cpu(*ptr); - goto out; - } - - if (!create) - goto out; - - error = fs_metaalloc(ip, block); - if (error) - goto out; - - *ptr = cpu_to_gfs64(*block); - ip->i_di.di_blocks++; - write_buf(ip->i_sbd, bh, 0); - - *new = 1; - - out: - return error; -} - - -/** - * get_datablock - Get datablock number from metadata block - * @rgd: rgrp to allocate from if necessary - * @ip: The GFS inode - * @bh: The buffer containing pointers to datablocks - * @mp: The metapath - * @create: Non-zero if we may create a new data block - * @new: Used to indicate if we created a new data block - * @block: the returned disk block number - * - * Given a fully built metadata tree, checks to see if a particular data - * block exists. It is created if it does not exist and the block number - * on disk is returned. - * - * Returns: 0 on success, -EXXX on failure - */ - -static int get_datablock(struct fsck_inode *ip, - osi_buf_t *bh, metapath_t *mp, - int create, int *new, uint64 *block) -{ - uint64 *ptr = metapointer(bh, ip->i_di.di_height - 1, mp); - int error = 0; - - *new = 0; - *block = 0; - - - if (*ptr){ - *block = gfs64_to_cpu(*ptr); - goto out; - } - - if (!create) - goto out; - - if (fs_is_jdata(ip)){ - error = fs_metaalloc(ip, block); - if (error) - goto out; - } - else { - error = fs_blkalloc(ip, block); - if (error) - goto out; - } - - *ptr = cpu_to_gfs64(*block); - ip->i_di.di_blocks++; - write_buf(ip->i_sbd, bh, 0); - - *new = 1; - - out: - return error; -} - - -/** - * fs_block_map - Map a block from an inode to a disk block - * @ip: The GFS inode - * @lblock: The logical block number - * @new: Value/Result argument (1 = may create/did create new blocks) - * @dblock: the disk block number of the start of an extent - * @extlen: the size of the extent - * - * Find the block number on the current device which corresponds to an - * inode's block. If the block had to be created, "new" will be set. - * - * Returns: 0 on success, -EXXX on failure - */ -int fs_block_map(struct fsck_inode *ip, uint64 lblock, int *new, - uint64 *dblock, uint32 *extlen) -{ - struct fsck_sb *sdp = ip->i_sbd; - osi_buf_t *bh = NULL; - metapath_t mp; - int create = *new; - unsigned int bsize; - unsigned int height; - unsigned int x, end_of_metadata; - unsigned int nptrs; - uint64 tmp_dblock; - int tmp_new; - int error = 0; - - *new = 0; - *dblock = 0; - if (extlen) - *extlen = 0; - - if (fs_is_stuffed(ip)){ - *dblock = ip->i_num.no_addr; - if (extlen) - *extlen = 1; - goto out; - } - bsize = (fs_is_jdata(ip)) ? sdp->jbsize : sdp->sb.sb_bsize; - - height = calc_tree_height(ip, (lblock + 1) * bsize); - if (ip->i_di.di_height < height){ - if (!create){ - error = 0; - goto fail; - } - - error = build_height(ip, height); - if (error) - goto fail; - } - - - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &bh, 0); - if (error) - goto fail; - - - find_metapath(ip, &mp, lblock); - end_of_metadata = ip->i_di.di_height - 1; - - for (x = 0; x < end_of_metadata; x++){ - error = get_metablock(ip, bh, x, &mp, create, new, dblock); - relse_buf(ip->i_sbd, bh); bh = NULL; - if (error) - goto fail; - if (!*dblock) - goto out; - - error = get_and_read_buf(ip->i_sbd, *dblock, &bh, 0); - if (error) - goto fail; - } - - - error = get_datablock(ip, bh, &mp, create, new, dblock); - if (error) - goto fail_drelse; - - if (extlen && *dblock){ - *extlen = 1; - - if (!*new){ - nptrs = (end_of_metadata) ? sdp->inptrs : sdp->diptrs; - while (++mp.mp_list[end_of_metadata] < nptrs){ - error = get_datablock(ip, bh, &mp, 0, &tmp_new, - &tmp_dblock); - if(error){ - log_err( "Unable to perform get_datablock.\n"); - goto fail; - } - - if (*dblock + *extlen != tmp_dblock) - break; - - (*extlen)++; - } - } - } - - - relse_buf(sdp, bh); - - - out: - if (*new){ - error = get_and_read_buf(sdp, ip->i_num.no_addr, &bh, 0); - if (error) - goto fail; - gfs_dinode_out(&ip->i_di, BH_DATA(bh)); - write_buf(sdp, bh, 0); - relse_buf(sdp, bh); - } - return 0; - - - - fail_drelse: - if(bh) - relse_buf(sdp, bh); - - fail: - return error; -} diff --git a/gfs/gfs_fsck/fs_bmap.h b/gfs/gfs_fsck/fs_bmap.h deleted file mode 100644 index 65cbf3f..0000000 --- a/gfs/gfs_fsck/fs_bmap.h +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FS_BMAP_H__ -#define __FS_BMAP_H__ - -#include "fsck_incore.h" - -int fs_unstuff_dinode(struct fsck_inode *ip); -int fs_block_map(struct fsck_inode *ip, uint64 lblock, int *new, - uint64 *dblock, uint32 *extlen); - -#endif /* __FS_BMAP_H__ */ diff --git a/gfs/gfs_fsck/fs_dir.c b/gfs/gfs_fsck/fs_dir.c deleted file mode 100644 index 335da33..0000000 --- a/gfs/gfs_fsck/fs_dir.c +++ /dev/null @@ -1,1687 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "util.h" -#include "file.h" -#include "rgrp.h" -#include "fsck_incore.h" -#include "fs_inode.h" -#include "bio.h" -#include "link.h" - -#include "fs_dir.h" - -#define IS_LEAF (1) -#define IS_DINODE (2) - -#define dir_hash(qstr) (gfs_dir_hash((qstr)->name, (qstr)->len)) - -/* Detect directory is a stuffed inode */ -int fsck_inode_is_stuffed(struct fsck_inode *ip) -{ - return !ip->i_di.di_height; -} - -/** - * dirent_first - Return the first dirent - * @bh: The buffer - * @dent: Pointer to list of dirents - * - * return first dirent whether bh points to leaf or stuffed dinode - * - * Returns: IS_LEAF or IS_DINODE - */ -int dirent_first(osi_buf_t *bh, struct gfs_dirent **dent) -{ - struct gfs_leaf *leaf; - struct gfs_dinode *dinode; - - leaf = (struct gfs_leaf *)BH_DATA(bh); - - if (gfs32_to_cpu(leaf->lf_header.mh_type) == GFS_METATYPE_LF) - { - *dent = (struct gfs_dirent *)(BH_DATA(bh) + sizeof(struct gfs_leaf)); - - return IS_LEAF; - } - else - { - dinode = (struct gfs_dinode *)BH_DATA(bh); - if(gfs32_to_cpu(dinode->di_header.mh_type) != GFS_METATYPE_DI){ - log_err("buffer is not GFS_METATYPE_[DI | LF]\n"); - return -1; - } - - *dent = (struct gfs_dirent *)(BH_DATA(bh) + sizeof(struct gfs_dinode)); - - return IS_DINODE; - } -} - - -/** - * dirent_next - Next dirent - * @bh: The buffer - * @dent: Pointer to list of dirents - * - * Returns: 0 on success, error code otherwise - */ -int dirent_next(osi_buf_t *bh, struct gfs_dirent **dent) -{ - struct gfs_dirent *tmp, *cur; - char *bh_end; - uint32 cur_rec_len; - - cur = *dent; - bh_end = BH_DATA(bh) + BH_SIZE(bh); - - cur_rec_len = gfs16_to_cpu(cur->de_rec_len); - - if ((char *)cur + cur_rec_len >= bh_end){ - if((char *)cur + cur_rec_len != bh_end){ - log_err("Bad record length causing failure in dirent_next()\n"); - return -1; - } - return -ENOENT; - } - - tmp = (struct gfs_dirent *)((char *)cur + cur_rec_len); - - if((char *)tmp + gfs16_to_cpu(tmp->de_rec_len) > bh_end){ - log_err("Bad record length causing failure in dirent_next\n"); - return -1; - } - - /* only the first dent could ever have de_ino == 0 */ - if(!tmp->de_inum.no_formal_ino){ - char tmp_name[256]; - - memcpy(tmp_name, cur+sizeof(struct gfs_dirent), gfs16_to_cpu(cur->de_name_len)); - tmp_name[gfs16_to_cpu(cur->de_name_len)] = '\0'; - log_err("dirent_next: " - "A non-first dir entry has zero formal inode.\n"); - log_err("\tFaulty dirent after (%s) in block #%"PRIu64".\n", - tmp_name, BH_BLKNO(bh)); - - return -1; - } - - *dent = tmp; - - return 0; -} - - -/** - * dirent_del - Delete a dirent - * @dip: The GFS inode - * @bh: The buffer - * @prev: The previous dirent - * @cur: The current dirent - * - * Returns: 0 on success, error code otherwise - */ - -int dirent_del(struct fsck_inode *dip, osi_buf_t *bh, - struct gfs_dirent *prev, struct gfs_dirent *cur){ - uint32 cur_rec_len, prev_rec_len; - - dip->i_di.di_entries--; - if(!cur->de_inum.no_formal_ino){ - log_err("dirent_del: " - "Can not delete dirent with !no_formal_ino.\n"); - return -1; - } - - /* If there is no prev entry, this is the first entry in the block. - The de_rec_len is already as big as it needs to be. Just zero - out the inode number and return. */ - - if (!prev){ - cur->de_inum.no_formal_ino = 0; /* No endianess worries */ - if(write_buf(dip->i_sbd, bh, 0)){ - log_err("dirent_del: Bad write_buf.\n"); - return -EIO; - } - return 0; - } - - /* Combine this dentry with the previous one. */ - - prev_rec_len = gfs16_to_cpu(prev->de_rec_len); - cur_rec_len = gfs16_to_cpu(cur->de_rec_len); - - if((char *)prev + prev_rec_len != (char *)cur){ - log_err("dirent_del: Bad bounds for directory entries.\n"); - return -1; - } - - if((char *)cur + cur_rec_len > BH_DATA(bh) + BH_SIZE(bh)){ - log_err("dirent_del: Directory entry has record length" - " longer than buffer.\n"); - return -1; - } - - log_debug("Updating previous record from %u to %u\n", - prev_rec_len, prev_rec_len+cur_rec_len); - prev_rec_len += cur_rec_len; - prev->de_rec_len = cpu_to_gfs16(prev_rec_len); - - if(write_buf(dip->i_sbd, bh, 0)){ - log_err("dirent_del: Bad write_buf.\n"); - return -EIO; - } - - return 0; -} - - -/** - * get_leaf - Get leaf - * @dip: - * @leaf_no: - * @bh_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int get_leaf(struct fsck_inode *dip, uint64 leaf_no, osi_buf_t **bhp) -{ - int error; - - error = get_and_read_buf(dip->i_sbd, leaf_no, bhp, 0); - - if (error) { - log_err("Unable to read leaf buffer #%"PRIu64"\n", leaf_no); - return error; - } - - error = check_meta(*bhp, GFS_METATYPE_LF); - - if(error) { - log_err("Metatype for block #%"PRIu64" is not type 'leaf'\n", - leaf_no); - relse_buf(dip->i_sbd, *bhp); - } - return error; -} - - -/** - * get_first_leaf - Get first leaf - * @dip: The GFS inode - * @index: - * @bh_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int get_first_leaf(struct fsck_inode *dip, uint32 index, osi_buf_t **bh_out) -{ - uint64 leaf_no; - int error; - - error = get_leaf_nr(dip, index, &leaf_no); - if (!error) - error = get_leaf(dip, leaf_no, bh_out); - - return error; -} - - -/** - * get_next_leaf - Get next leaf - * @dip: The GFS inode - * @bh_in: The buffer - * @bh_out: - * - * Returns: 0 on success, error code otherwise - */ - -static int get_next_leaf(struct fsck_inode *dip,osi_buf_t *bh_in,osi_buf_t **bh_out) -{ - struct gfs_leaf *leaf; - int error; - - leaf = (struct gfs_leaf *)BH_DATA(bh_in); - - if (!leaf->lf_next) - error = -ENOENT; - else - error = get_leaf(dip, gfs64_to_cpu(leaf->lf_next), bh_out); - return error; -} - -/** - * leaf_search - * @bh: - * @id: - * @dent_out: - * @dent_prev: - * - * Returns: - */ -static int leaf_search(osi_buf_t *bh, identifier_t *id, - struct gfs_dirent **dent_out, - struct gfs_dirent **dent_prev) -{ - uint32 hash; - struct gfs_dirent *dent, *prev = NULL; - unsigned int entries = 0, x = 0; - int type; - - type = dirent_first(bh, &dent); - - if (type == IS_LEAF){ - struct gfs_leaf *leaf = (struct gfs_leaf *)BH_DATA(bh); - entries = gfs16_to_cpu(leaf->lf_entries); - } else if (type == IS_DINODE) { - struct gfs_dinode *dinode = (struct gfs_dinode *)(BH_DATA(bh)); - entries = gfs32_to_cpu(dinode->di_entries); - } else { - log_err("type != IS_LEAF && type != IS_DINODE\n"); - return -1; - } - - if(id->type == ID_FILENAME){ - hash = dir_hash(id->filename); - - do{ - if (!dent->de_inum.no_formal_ino){ - prev = dent; - continue; - } - - if (gfs32_to_cpu(dent->de_hash) == hash && - fs_filecmp(id->filename, (char *)(dent + 1), - gfs16_to_cpu(dent->de_name_len))){ - *dent_out = dent; - if (dent_prev) - *dent_prev = prev; - return 0; - } - - if(x >= entries){ - log_err("x >= entries (%u >= %u)\n", x, entries); - return -1; - } - x++; - prev = dent; - } while (dirent_next(bh, &dent) == 0); - } else if(id->type == ID_INUM){ - struct gfs_inum inum; - - do{ - if (!dent->de_inum.no_formal_ino){ - prev = dent; - continue; - } - - gfs_inum_in(&inum, (char *)&dent->de_inum); - - if(inum.no_addr == id->inum->no_addr){ - *dent_out = dent; - if(dent_prev) - *dent_prev = prev; - return 0; - } - - if(x >= entries){ - log_err("x >= entries (%u >= %u)\n", x, entries); - return -1; - } - x++; - prev = dent; - } while (dirent_next(bh, &dent) == 0); - } else { - log_err("leaf_search: Invalid type for identifier.\n"); - exit(1); - } - - return -ENOENT; -} - - -/** - * linked_leaf_search - Linked leaf search - * @dip: The GFS inode - * @id: - * @dent_out: - * @dent_prev: - * @bh_out: - * - * Returns: 0 on sucess, error code otherwise - */ - -static int linked_leaf_search(struct fsck_inode *dip, identifier_t *id, - struct gfs_dirent **dent_out, - struct gfs_dirent **dent_prev, osi_buf_t **bh_out) -{ - osi_buf_t *bh = NULL, *bh_next; - uint32 hsize, index; - uint32 hash; - int error = 0; - - hsize = 1 << dip->i_di.di_depth; - if(hsize * sizeof(uint64) != dip->i_di.di_size){ - log_err("hsize * sizeof(uint64) != dip->i_di.di_size\n"); - return -1; - } - - /* Figure out the address of the leaf node. */ - - if(id->type == ID_FILENAME){ - hash = dir_hash(id->filename); - index = hash >> (32 - dip->i_di.di_depth); - - error = get_first_leaf(dip, index, &bh_next); - if (error){ - return error; - } - - /* Find the entry */ - do{ - if (bh) - relse_buf(dip->i_sbd, bh); - - bh = bh_next; - - error = leaf_search(bh, id, dent_out, dent_prev); - switch (error){ - case 0: - *bh_out = bh; - return 0; - - case -ENOENT: - break; - - default: - relse_buf(dip->i_sbd, bh); - return error; - } - - error = get_next_leaf(dip, bh, &bh_next); - }while (!error); - - relse_buf(dip->i_sbd, bh); - } else if(id->type == ID_INUM){ - for(index=0; index < (1 << dip->i_di.di_depth); index++){ - error = get_first_leaf(dip, index, &bh_next); - if (error){ - return error; - } - - /* Find the entry */ - do{ - if (bh) - relse_buf(dip->i_sbd, bh); - - bh = bh_next; - - error = leaf_search(bh, id, dent_out, dent_prev); - switch (error){ - case 0: - *bh_out = bh; - return 0; - - case -ENOENT: - break; - - default: - relse_buf(dip->i_sbd, bh); - return error; - } - - error = get_next_leaf(dip, bh, &bh_next); - }while (!error); - } - } else { - log_err("linked_leaf_search: Invalid type for identifier.\n"); - exit(1); - } - return error; -} - - -/** - * dir_e_search - - * @dip: The GFS inode - * @id: - * @inode: - * - * Returns: - */ -static int dir_e_search(struct fsck_inode *dip, identifier_t *id, unsigned int *type) -{ - osi_buf_t *bh; - struct gfs_dirent *dent; - int error; - - error = linked_leaf_search(dip, id, &dent, NULL, &bh); - if (error){ - return error; - } - - if(id->type == ID_FILENAME){ - if(id->inum){ - log_err("dir_e_search: Illegal parameter. inum must be NULL.\n"); - exit(1); - } - if(!(id->inum = (struct gfs_inum *)malloc(sizeof(struct gfs_inum)))) { - log_err("Unable to allocate inum structure\n"); - return -1; - } - if(!memset(id->inum, 0, sizeof(struct gfs_inum))) { - log_err("Unable to zero inum structure\n"); - return -1; - } - - gfs_inum_in(id->inum, (char *)&dent->de_inum); - } else { - if(id->filename){ - log_err("dir_e_search: Illegal parameter. name must be NULL.\n"); - exit(1); - } - if(!(id->filename = (osi_filename_t *)malloc(sizeof(osi_filename_t)))) { - log_err("Unable to allocate osi_filename structure\n"); - return -1; - } - if(!(memset(id->filename, 0, sizeof(osi_filename_t)))) { - log_err("Unable to zero osi_filename structure\n"); - return -1; - } - - id->filename->len = gfs16_to_cpu(dent->de_name_len); - if(!(id->filename->name = malloc(id->filename->len))) { - log_err("Unable to allocate name in osi_filename structure\n"); - free(id->filename); - return -1; - } - if(!(memset(id->filename->name, 0, id->filename->len))) { - log_err("Unable to zero name in osi_filename structure\n"); - free(id->inum); - free(id->filename); - return -1; - } - - memcpy(id->filename->name, (char *)dent+sizeof(struct gfs_dirent), - id->filename->len); - } - if (type) - *type = gfs16_to_cpu(dent->de_type); - - relse_buf(dip->i_sbd, bh); - - return 0; -} - - -/** - * dir_l_search - - * @dip: The GFS inode - * @id: - * @inode: - * - * Returns: - */ -static int dir_l_search(struct fsck_inode *dip, identifier_t *id, unsigned int *type) -{ - osi_buf_t *dibh; - struct gfs_dirent *dent; - int error; - - if(!fs_is_stuffed(dip)){ - log_err("A linear search was attempted on a directory " - "that is not stuffed.\n"); - return -1; - } - - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); - if (error) - goto out; - - - error = leaf_search(dibh, id, &dent, NULL); - if (error) - goto out_drelse; - - if(id->type == ID_FILENAME){ - if(id->inum){ - log_err("dir_l_search: Illegal parameter. inum must be NULL.\n"); - exit(1); - } - id->inum = (struct gfs_inum *)malloc(sizeof(struct gfs_inum)); - memset(id->inum, 0, sizeof(struct gfs_inum)); - - gfs_inum_in(id->inum, (char *)&dent->de_inum); - } else { - if(id->filename){ - log_err("dir_l_search: Illegal parameter. name must be NULL.\n"); - exit(1); - } - id->filename = (osi_filename_t *)malloc(sizeof(osi_filename_t)); - memset(id->filename, 0, sizeof(osi_filename_t)); - - id->filename->len = gfs16_to_cpu(dent->de_name_len); - id->filename->name = malloc(id->filename->len); - memset(id->filename->name, 0, id->filename->len); - - memcpy(id->filename->name, (char *)dent+sizeof(struct gfs_dirent), - id->filename->len); - } - if(type) - *type = gfs16_to_cpu(dent->de_type); - - - out_drelse: - relse_buf(dip->i_sbd, dibh); - - out: - return error; -} - - -/** - * dir_make_exhash - Convet a stuffed directory into an ExHash directory - * @dip: The GFS inode - * - * Returns: 0 on success, error code otherwise - */ - -static int dir_make_exhash(struct fsck_inode *dip) -{ - struct fsck_sb *sdp = dip->i_sbd; - struct gfs_dirent *dent; - osi_buf_t *bh = NULL, *dibh = NULL; - struct gfs_leaf *leaf; - int y; - uint32 x; - uint64 *lp, bn; - int error; - - /* Sanity checks */ - - if(sizeof(struct gfs_leaf) > sizeof(struct gfs_dinode)){ - log_err( - "dir_make_exhash: on-disk leaf is larger than on-disk dinode.\n" - " Unable to expand directory.\n"); - return -1; - } - - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); - if (error) - goto fail; - - - error = fs_metaalloc(dip, &bn); - - if (error) - goto fail_drelse; - - - /* Turn over a new leaf */ - - error = get_and_read_buf(sdp, bn, &bh, 0); - if (error) - goto fail_drelse; - - if(check_meta(bh, 0)){ - log_err("dir_make_exhash: Buffer has bad meta header.\n"); - goto fail_drelse; - } - - set_meta(bh, GFS_METATYPE_LF, GFS_FORMAT_LF); - memset(BH_DATA(bh) + sizeof(struct gfs_meta_header), 0, - BH_SIZE(bh) - sizeof(struct gfs_meta_header)); - - /* Fill in the leaf structure */ - - leaf = (struct gfs_leaf *)BH_DATA(bh); - - if(dip->i_di.di_entries >= (1 << 16)){ - log_err( - "dir_make_exhash: Too many directory entries.\n" - " Unable to expand directory.\n"); - goto fail_drelse; - } - leaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); - leaf->lf_entries = cpu_to_gfs16(dip->i_di.di_entries); - - - /* Copy dirents */ - memset(BH_DATA(bh)+sizeof(struct gfs_leaf), 0, BH_SIZE(bh)-sizeof(struct gfs_leaf)); - memcpy(BH_DATA(bh)+sizeof(struct gfs_leaf), - BH_DATA(dibh)+sizeof(struct gfs_dinode), - BH_SIZE(dibh)-sizeof(struct gfs_dinode)); - - /* Find last entry */ - - x = 0; - dirent_first(bh, &dent); - - do - { - if (!dent->de_inum.no_formal_ino) - continue; - - if (++x == dip->i_di.di_entries) - break; - } - while (dirent_next(bh, &dent) == 0); - - - /* Adjust the last dirent's record length - (Remember that dent still points to the last entry.) */ - - dent->de_rec_len = gfs16_to_cpu(dent->de_rec_len) + - sizeof(struct gfs_dinode) - sizeof(struct gfs_leaf); - dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); - - if(write_buf(dip->i_sbd, bh, 0)){ - log_err("dir_make_exhash: bad write_buf()\n"); - goto fail_drelse; - } - relse_buf(dip->i_sbd, bh); bh=NULL; - - log_debug("Created a new leaf block at %"PRIu64"\n", bn); - - block_set(dip->i_sbd->bl, bn, leaf_blk); - /* We're done with the new leaf block, now setup the new - hash table. */ - - memset(BH_DATA(dibh) + sizeof(struct gfs_dinode), 0, - BH_SIZE(dibh) - sizeof(struct gfs_dinode)); - - lp = (uint64 *)(BH_DATA(dibh) + sizeof(struct gfs_dinode)); - - for (x = sdp->hash_ptrs; x--; lp++) - *lp = cpu_to_gfs64(bn); - - dip->i_di.di_size = sdp->sb.sb_bsize / 2; - dip->i_di.di_blocks++; - dip->i_di.di_flags |= GFS_DIF_EXHASH; - dip->i_di.di_payload_format = 0; - - for (x = sdp->hash_ptrs, y = -1; x; x >>= 1, y++) ; - dip->i_di.di_depth = y; - - gfs_dinode_out(&dip->i_di, BH_DATA(dibh)); - - if(write_buf(dip->i_sbd, dibh, 0)){ - log_err("dir_make_exhash: bad write_buf()\n"); - goto fail_drelse; - } - relse_buf(dip->i_sbd, dibh); dibh = NULL; - - return 0; - - - - fail_drelse: - if(bh) - relse_buf(dip->i_sbd, bh); - if(dibh) - relse_buf(dip->i_sbd, dibh); - - fail: - return error; -} - - -/** - * dir_split_leaf - Split a leaf block into two - * @dip: The GFS inode - * @index: - * @leaf_no: - * - * Returns: 0 on success, error code on failure - */ -static int dir_split_leaf(struct fsck_inode *dip, uint32 index, uint64 leaf_no) -{ - struct fsck_sb *sdp = dip->i_sbd; - osi_buf_t *nbh, *obh, *dibh; - struct gfs_leaf *nleaf, *oleaf; - struct gfs_dirent *dent, *prev = NULL, *next = NULL, *new; - uint32 start, len, half_len, divider; - uint64 bn, *lp; - uint32 name_len; - int x, moved = FALSE; - int error; - - /* Allocate the new leaf block */ - - error = fs_metaalloc(dip, &bn); - if (error) - goto fail; - - - /* Get the new leaf block */ - error = get_and_read_buf(sdp, bn, &nbh, 0); - if (error) - goto fail; - - if(check_meta(nbh, 0)){ - log_err("dir_split_leaf: Buffer is not a meta buffer.\n"); - relse_buf(sdp, nbh); - return -1; - } - - set_meta(nbh, GFS_METATYPE_LF, GFS_FORMAT_LF); - - memset(BH_DATA(nbh)+sizeof(struct gfs_meta_header), 0, - BH_SIZE(nbh)-sizeof(struct gfs_meta_header)); - - nleaf = (struct gfs_leaf *)BH_DATA(nbh); - - nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); - - - /* Get the old leaf block */ - - error = get_leaf(dip, leaf_no, &obh); - if (error) - goto fail_nrelse; - - oleaf = (struct gfs_leaf *)BH_DATA(obh); - - - /* Compute the start and len of leaf pointers in the hash table. */ - - len = 1 << (dip->i_di.di_depth - gfs16_to_cpu(oleaf->lf_depth)); - if(len == 1){ - log_err("dir_split_leaf: Corrupted leaf block encountered.\n"); - goto fail_orelse; - } - half_len = len >> 1; - - start = (index & ~(len - 1)); - - log_debug("Splitting leaf: len = %u, half_len = %u\n", len, half_len); - - /* Change the pointers. - Don't bother distinguishing stuffed from non-stuffed. - This code is complicated enough already. */ - - lp = (uint64 *)malloc(half_len * sizeof(uint64)); - memset(lp, 0, half_len * sizeof(uint64)); - - error = readi(dip, (char *)lp, start * sizeof(uint64), - half_len * sizeof(uint64)); - if (error != half_len * sizeof(uint64)){ - if (error >= 0) - error = -EIO; - goto fail_lpfree; - } - - /* Change the pointers */ - - for (x = 0; x < half_len; x++) - lp[x] = cpu_to_gfs64(bn); - - error = writei(dip, (char *)lp, start * sizeof(uint64), - half_len * sizeof(uint64)); - - if (error != half_len * sizeof(uint64)){ - if (error >= 0) - error = -EIO; - goto fail_lpfree; - } - - free(lp); lp = NULL; /* need to set lp for failure cases */ - - - /* Compute the divider */ - - divider = (start + half_len) << (32 - dip->i_di.di_depth); - - /* Copy the entries */ - - dirent_first(obh, &dent); - - do{ - next = dent; - if (dirent_next(obh, &next)) - next = NULL; - - if (dent->de_inum.no_formal_ino && - (gfs32_to_cpu(dent->de_hash) < divider)){ - name_len = gfs16_to_cpu(dent->de_name_len); - - error = fs_dirent_alloc(dip, nbh, name_len, &new); - if(error){ - log_err("dir_split_leaf: fs_dirent_alloc failed.\n"); - goto fail_orelse; - } - - new->de_inum = dent->de_inum; /* No endianness worries */ - new->de_hash = dent->de_hash; /* No endianness worries */ - new->de_type = dent->de_type; /* No endianness worries */ - memcpy((char *)(new + 1), (char *)(dent + 1), name_len); - - nleaf->lf_entries = gfs16_to_cpu(nleaf->lf_entries) + 1; - nleaf->lf_entries = cpu_to_gfs16(nleaf->lf_entries); - - dirent_del(dip, obh, prev, dent); - /* Dirent del decrements entries, but we're - * just shifting entries around, so increment - * it again */ - dip->i_di.di_entries++; - - if(!gfs16_to_cpu(oleaf->lf_entries)){ - log_err("dir_split_leaf: old leaf contains no entries.\n"); - goto fail_orelse; - } - oleaf->lf_entries = gfs16_to_cpu(oleaf->lf_entries) - 1; - oleaf->lf_entries = cpu_to_gfs16(oleaf->lf_entries); - - if (!prev) - prev = dent; - - moved = TRUE; - } - else - prev = dent; - - dent = next; - } - while (dent); - - - /* If none of the entries got moved into the new leaf, - artificially fill in the first entry. */ - - if (!moved){ - error = fs_dirent_alloc(dip, nbh, 0, &new); - if(error){ - log_err("dir_split_leaf: fs_dirent_alloc failed..\n"); - goto fail_orelse; - } - new->de_inum.no_formal_ino = 0; - } - - - oleaf->lf_depth = gfs16_to_cpu(oleaf->lf_depth) + 1; - oleaf->lf_depth = cpu_to_gfs16(oleaf->lf_depth); - nleaf->lf_depth = oleaf->lf_depth; - - - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); - if(error){ - log_err("dir_split_leaf: Unable to get inode buffer.\n"); - goto fail_orelse; - } - - error = check_meta(dibh, GFS_METATYPE_DI); - if(error){ - log_err("dir_split_leaf: Buffer #%"PRIu64" is not a directory " - "inode.\n", BH_BLKNO(dibh)); - goto fail_drelse; - } - - dip->i_di.di_blocks++; - - gfs_dinode_out(&dip->i_di, BH_DATA(dibh)); - if(write_buf(sdp, dibh, 0)){ - log_err("dir_split_leaf: Failed to write new directory inode.\n"); - goto fail_drelse; - } - relse_buf(sdp, dibh); - - - if(write_buf(sdp, obh, 0)){ - log_err("dir_split_leaf: Failed to write back old leaf block.\n"); - goto fail_orelse; - } - relse_buf(sdp, obh); - if(write_buf(sdp, nbh, 0)){ - log_err("dir_split_leaf: Failed to write new leaf block.\n"); - goto fail_nrelse; - } - - log_debug("Created a new leaf block at %"PRIu64"\n", BH_BLKNO(nbh)); - - block_set(dip->i_sbd->bl, BH_BLKNO(nbh), leaf_blk); - - relse_buf(sdp, nbh); - - return 0; - - - - fail_drelse: - relse_buf(sdp, dibh); - - fail_lpfree: - if(lp) free(lp); - - fail_orelse: - relse_buf(sdp, obh); - - fail_nrelse: - relse_buf(sdp, nbh); - - fail: - return -1; -} - - -/** - * dir_double_exhash - Double size of ExHash table - * @dip: The GFS dinode - * - * Returns: 0 on success, -1 on failure - */ -static int dir_double_exhash(struct fsck_inode *dip) -{ - struct fsck_sb *sdp = dip->i_sbd; - osi_buf_t *dibh; - uint32 hsize; - uint64 *buf; - uint64 *from, *to; - uint64 block; - int x; - int error = 0; - - /* Sanity Checks */ - - hsize = 1 << dip->i_di.di_depth; - if(hsize * sizeof(uint64) != dip->i_di.di_size){ - log_err("dir_double_exhash: " - "hash size does not correspond to di_size.\n"); - return -1; - } - - - /* Allocate both the "from" and "to" buffers in one big chunk */ - - buf = (uint64 *)malloc(3 * sdp->hash_bsize); - if(!buf){ - log_err("dir_double_exhash: " - "Unable to allocate memory for blk ptr list.\n"); - return -1; - } - memset(buf, 0, 3 * sdp->hash_bsize); - - for (block = dip->i_di.di_size / sdp->hash_bsize; block--;){ - error = readi(dip, (char *)buf, block * sdp->hash_bsize, - sdp->hash_bsize); - if (error != sdp->hash_bsize){ - if (error >= 0) - error = -EIO; - goto out; - } - - from = buf; - to = (uint64 *)((char *)buf + sdp->hash_bsize); - - for (x = sdp->hash_ptrs; x--; from++){ - *to++ = *from; /* No endianess worries */ - *to++ = *from; - } - - error = writei(dip, (char *)buf + sdp->hash_bsize, - block * sdp->sb.sb_bsize, sdp->sb.sb_bsize); - if (error != sdp->sb.sb_bsize){ - if (error >= 0) - error = -EIO; - goto out; - } - } - - free(buf); buf=NULL; - - - error = get_and_read_buf(sdp, dip->i_num.no_addr, &dibh, 0); - if(error){ - log_err("dir_double_exhash: " - "Unable to get inode buffer.\n"); - return -1; - } - - error = check_meta(dibh, GFS_METATYPE_DI); - if(error){ - log_err("dir_double_exhash: " - "Buffer does not contain directory inode.\n"); - relse_buf(sdp, dibh); - return -1; - } - - dip->i_di.di_depth++; - - gfs_dinode_out(&dip->i_di, BH_DATA(dibh)); - if(write_buf(sdp, dibh, 0)){ - log_err("dir_double_exhash: " - "Unable to write out directory inode.\n"); - relse_buf(sdp, dibh); - return -1; - } - - relse_buf(sdp, dibh); - - return 0; - - - out: - if(buf) free(buf); - - return error; -} - - -static int dir_e_del(struct fsck_inode *dip, osi_filename_t *filename){ - int index; - int error; - int found = 0; - uint64 leaf_no; - osi_buf_t *bh; - identifier_t id; - struct gfs_dirent *cur, *prev; - - id.type = ID_FILENAME; - id.filename = filename; - id.inum = NULL; - - index = (1 << (dip->i_di.di_depth))-1; - - for(; (index >= 0) && !found; index--){ - error = get_leaf_nr(dip, index, &leaf_no); - if (error){ - log_err("dir_e_del: Unable to get leaf number.\n"); - return error; - } - - while(leaf_no && !found){ - if(get_leaf(dip, leaf_no, &bh)){ - stack; - return -1; - } - - error = leaf_search(bh, &id, &cur, &prev); - if(id.inum) free(id.inum); - - if(error){ - if(error != -ENOENT){ - log_err("dir_e_del: leaf_search failed.\n"); - relse_buf(dip->i_sbd, bh); - return -1; - } - leaf_no = gfs64_to_cpu(((struct gfs_leaf *)BH_DATA(bh))->lf_next); - relse_buf(dip->i_sbd, bh); - } else { - found = 1; - } - } - } - - if(!found) - return 1; - - if(dirent_del(dip, bh, prev, cur)){ - log_err("dir_e_del: dirent_del failed.\n"); - relse_buf(dip->i_sbd, bh); - return -1; - } - - relse_buf(dip->i_sbd, bh); - return 0; -} - - -static int dir_l_del(struct fsck_inode *dip, osi_buf_t *dibh, - osi_filename_t *filename){ - int error=0; - int got_buf = 0; - struct gfs_dirent *cur, *prev; - identifier_t id; - - id.type = ID_FILENAME; - id.filename = filename; - id.inum = NULL; - - if(!fs_is_stuffed(dip)){ - log_crit("dir_l_del: Attempting linear delete on unstuffed" - " dinode.\n"); - return -1; - } - - if(!dibh) { - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, - &dibh, 0); - if (error){ - log_err("dir_l_del: Failed to read in dinode buffer.\n"); - return -1; - } - got_buf = 1; - } - - error = leaf_search(dibh, &id, &cur, &prev); - if(id.inum) free(id.inum); - - if(error){ - if(error == -ENOENT){ - log_debug("dir_l_del found no entry\n"); - if(got_buf) - relse_buf(dip->i_sbd, dibh); - return 1; - } else { - log_err("dir_l_del: leaf_search failed.\n"); - if(got_buf) - relse_buf(dip->i_sbd, dibh); - return -1; - } - } - - if(dirent_del(dip, dibh, prev, cur)){ - stack; - if(got_buf) - relse_buf(dip->i_sbd, dibh); - return -1; - } - - if(got_buf) - relse_buf(dip->i_sbd, dibh); - return 0; -} - - -/* - * fs_dirent_del - * @dip - * filename - * - * Delete a directory entry from a directory. This _only_ - * removes the directory entry - leaving the dinode in - * place. (Likely without a link.) - * - * Returns: 0 on success (or if it doesn't already exist), -1 on failure - */ -int fs_dirent_del(struct fsck_inode *dip, osi_buf_t *bh, osi_filename_t *filename){ - int error; - - if(dip->i_di.di_type != GFS_FILE_DIR){ - log_err("fs_dirent_del: parent inode is not a directory.\n"); - return -1; - } - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_del(dip, filename); - else - error = dir_l_del(dip, bh, filename); - - return error; - -} - - -/** - * dir_e_add - - * @dip: The GFS inode - * @filename: - * @inode: - * @type: - * - */ -static int dir_e_add(struct fsck_inode *dip, osi_filename_t *filename, - struct gfs_inum *inum, unsigned int type) -{ - struct fsck_sb *sdp = dip->i_sbd; - osi_buf_t *bh, *nbh, *dibh; - struct gfs_leaf *leaf, *nleaf; - struct gfs_dirent *dent; - uint32 hsize, index; - uint32 hash; - uint64 leaf_no, bn; - int error; - - restart: - - /* Sanity Checks */ - - hsize = 1 << dip->i_di.di_depth; - if(hsize * sizeof(uint64) != dip->i_di.di_size){ - log_err("dir_e_add: hash size and di_size do not correspond.\n"); - return -1; - } - - /* Figure out the address of the leaf node. */ - - hash = dir_hash(filename); - index = hash >> (32 - dip->i_di.di_depth); - - - error = get_leaf_nr(dip, index, &leaf_no); - if (error){ - log_err("dir_e_add: Unable to get leaf number.\n"); - return error; - } - - - /* Add entry to the leaf */ - - while (TRUE){ - error = get_leaf(dip, leaf_no, &bh); - if (error){ - log_err("dir_e_add: Unable to get leaf #%"PRIu64"\n", leaf_no); - return error; - } - - leaf = (struct gfs_leaf *)BH_DATA(bh); - - - if (fs_dirent_alloc(dip, bh, filename->len, &dent)){ - if (gfs16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth){ - /* Can we split the leaf? */ - relse_buf(sdp, bh); - - error = dir_split_leaf(dip, index, leaf_no); - if (error){ - log_err("dir_e_add: Unable to split leaf.\n"); - return error; - } - - goto restart; - } - else if (dip->i_di.di_depth < GFS_DIR_MAX_DEPTH){ - /* Can we double the hash table? */ - relse_buf(sdp, bh); - - error = dir_double_exhash(dip); - if (error){ - log_err("dir_e_add: Unable to double exhash.\n"); - return error; - } - - goto restart; - } - else if (leaf->lf_next){ - /* Can we try the next leaf in the list? */ - leaf_no = gfs64_to_cpu(leaf->lf_next); - relse_buf(sdp, bh); - continue; - } - else { - /* Create a new leaf and add it to the list. */ - error = fs_metaalloc(dip, &bn); - if (error){ - relse_buf(sdp, bh); - log_err("dir_e_add: " - "Unable to allocate space for meta block.\n"); - return error; - } - - error = get_and_read_buf(sdp, bn, &nbh, 0); - if (error){ - relse_buf(sdp, bh); - return error; - } - - /*gfs_trans_add_bh(sdp, dip->i_gl, nbh);*/ - if(check_meta(nbh, 0)){ - log_err("dir_e_add: Buffer is not a meta buffer.\n"); - relse_buf(sdp, bh); - relse_buf(sdp, nbh); - return -1; - } - set_meta(nbh, GFS_METATYPE_LF, GFS_FORMAT_LF); - /* Make sure the bitmap is updated */ - log_debug("Setting leaf block at %"PRIu64"\n", - bn); - block_set(dip->i_sbd->bl, bn, leaf_blk); - memset(BH_DATA(nbh)+sizeof(struct gfs_meta_header), 0, - BH_SIZE(nbh)-sizeof(struct gfs_meta_header)); - - /*gfs_trans_add_bh(sdp, dip->i_gl, bh);*/ - leaf->lf_next = cpu_to_gfs64(bn); - - nleaf = (struct gfs_leaf *)BH_DATA(nbh); - nleaf->lf_depth = leaf->lf_depth; - nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); - - if (fs_dirent_alloc(dip, nbh, filename->len, &dent)){ - log_err("dir_e_add: Uncircumventible error!\n"); - exit(EXIT_FAILURE); - } - - dip->i_di.di_blocks++; - - /* ATTENTION -- check for errors */ - write_buf(sdp, nbh, BW_WAIT); - write_buf(sdp, bh, 0); - relse_buf(sdp, bh); - - bh = nbh; - leaf = nleaf; - } - } - - - gfs_inum_out(inum, (char *)&dent->de_inum); - dent->de_hash = cpu_to_gfs32(hash); - dent->de_type = cpu_to_gfs16(type); - memcpy((char *)(dent + 1), filename->name, filename->len); - - leaf->lf_entries = gfs16_to_cpu(leaf->lf_entries) + 1; - leaf->lf_entries = cpu_to_gfs16(leaf->lf_entries); - - write_buf(sdp, bh, 0); - relse_buf(sdp, bh); - - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); - if(error){ - log_err("dir_e_add: Unable to get inode buffer.\n"); - return error; - } - - error = check_meta(dibh, GFS_METATYPE_DI); - if(error){ - log_err("dir_e_add: Buffer #%"PRIu64" is not a directory " - "inode.\n", BH_BLKNO(dibh)); - relse_buf(sdp, dibh); - return error; - } - - dip->i_di.di_entries++; - dip->i_di.di_mtime = dip->i_di.di_ctime = osi_current_time(); - log_debug("Entries for %"PRIu64" is %u\n", dip->i_di.di_num.no_addr, - dip->i_di.di_entries); - - gfs_dinode_out(&dip->i_di, BH_DATA(dibh)); - write_buf(sdp, dibh, 0); - relse_buf(sdp, dibh); - - return 0; - } - - return -ENOENT; -} - - -/** - * dir_l_add - - * @dip: The GFS inode - * @filename: - * @inode: - * @type: - * - * Returns: - */ - -static int dir_l_add(struct fsck_inode *dip, osi_filename_t *filename, - struct gfs_inum *inum, unsigned int type) -{ - osi_buf_t *dibh; - struct gfs_dirent *dent; - int error; - - /* Sanity checks */ - - if(!fs_is_stuffed(dip)){ - log_err("dir_l_add: Attempting linear add on unstuffed dinode.\n"); - return -1; - } - - error = get_and_read_buf(dip->i_sbd, dip->i_num.no_addr, &dibh, 0); - if (error) - goto out; - - - if (fs_dirent_alloc(dip, dibh, filename->len, &dent)) - { - /* no need to write buffer, it hasn't changed. */ - relse_buf(dip->i_sbd, dibh); - - error = dir_make_exhash(dip); - /* DEBUG */ - log_debug("Changing Linear dir to Exhash dir - %s\n", - (error)? "UNSUCCESSFUL": "SUCCESSFUL"); - if (!error) - error = dir_e_add(dip, filename, inum, type); - - goto out; - } - - - gfs_inum_out(inum, (char *)&dent->de_inum); - dent->de_hash = dir_hash(filename); - dent->de_hash = cpu_to_gfs32(dent->de_hash); - dent->de_type = cpu_to_gfs16(type); - memcpy((char *)(dent + 1), filename->name, filename->len); - - - dip->i_di.di_entries++; - dip->i_di.di_mtime = dip->i_di.di_ctime = osi_current_time(); - log_debug("Entries for %"PRIu64" is %u\n", dip->i_di.di_num.no_addr, - dip->i_di.di_entries); - gfs_dinode_out(&dip->i_di, BH_DATA(dibh)); - if(write_buf(dip->i_sbd, dibh, 0)){ - log_err("dir_l_add: bad write_buf()\n"); - error = -EIO; - } - - relse_buf(dip->i_sbd, dibh); - - out: - if(error){ - char tmp_name[256]; - memset(tmp_name, 0, sizeof(tmp_name)); - memcpy(tmp_name, filename->name, filename->len); - log_err("Unable to add "%s" to directory #%"PRIu64"\n", - tmp_name, dip->i_num.no_addr); - } - return error; -} - - - -/** - * fs_dir_add - Add new filename into directory - * @dip: The GFS inode - * @filename: The new name - * @inode: The inode number of the entry - * @type: The type of the entry - * - * Returns: 0 on success, error code on failure - */ -int fs_dir_add(struct fsck_inode *dip, osi_filename_t *filename, - struct gfs_inum *inum, unsigned int type) -{ - int error; - - if(dip->i_di.di_type != GFS_FILE_DIR){ - log_err("fs_dir_add: parent inode is not a directory.\n"); - return -1; - } - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_add(dip, filename, inum, type); - else - error = dir_l_add(dip, filename, inum, type); - - return error; -} - - -/** - * fs_dirent_alloc - Allocate a directory entry - * @dip: The GFS inode - * @bh: The buffer - * @name_len: The length of the name - * @dent_out: Pointer to list of dirents - * - * Returns: 0 on success, error code otherwise - */ -int fs_dirent_alloc(struct fsck_inode *dip, osi_buf_t *bh, - int name_len, struct gfs_dirent **dent_out) -{ - struct fsck_sb *sdp = dip->i_sbd; - struct gfs_dirent *dent, *new; - struct gfs_leaf *leaf; - struct gfs_dinode *dinode; - unsigned int rec_len = GFS_DIRENT_SIZE(name_len); - unsigned int entries = 0, offset = 0, x = 0; - int type; - - type = dirent_first(bh, &dent); - - if (type == IS_LEAF){ - leaf = (struct gfs_leaf *)BH_DATA(bh); - entries = gfs16_to_cpu(leaf->lf_entries); - offset = sizeof(struct gfs_leaf); - } - else if (type == IS_DINODE) { - dinode = (struct gfs_dinode *)BH_DATA(bh); - entries = gfs32_to_cpu(dinode->di_entries); - offset = sizeof(struct gfs_dinode); - } else { - log_err("fs_dirent_alloc: Buffer has bad metatype.\n"); - return -1; - } - - if (!entries){ - dent->de_rec_len = BH_SIZE(bh) - offset; - dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); - dent->de_name_len = cpu_to_gfs16(name_len); - - *dent_out = dent; - write_buf(sdp, bh, 0); - goto success; - } - - - do{ - uint32 cur_rec_len, cur_name_len; - - cur_rec_len = gfs16_to_cpu(dent->de_rec_len); - cur_name_len = gfs16_to_cpu(dent->de_name_len); - - if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || - (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)){ - if (dent->de_inum.no_formal_ino){ - new = (struct gfs_dirent *)((char *)dent + GFS_DIRENT_SIZE(cur_name_len)); - memset(new, 0, sizeof(struct gfs_dirent)); - - new->de_rec_len = cpu_to_gfs16(cur_rec_len - GFS_DIRENT_SIZE(cur_name_len)); - new->de_name_len = cpu_to_gfs16(name_len); - - dent->de_rec_len = cur_rec_len - gfs16_to_cpu(new->de_rec_len); - dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); - - *dent_out = new; - write_buf(sdp, bh, 0); - goto success; - } - - dent->de_name_len = cpu_to_gfs16(name_len); - - *dent_out = dent; - write_buf(sdp, bh, 0); - goto success; - } - - if(x >= entries){ - log_err("fs_dirent_alloc: dirents contain bad length information.\n"); - return -1; - } - - if (dent->de_inum.no_formal_ino) - x++; - } - while(dirent_next(bh, &dent) == 0); - - return -ENOSPC; - - success: - return 0; -} - - -/** - * get_leaf_nr - Get a leaf number associated with the index - * @dip: The GFS inode - * @index: - * @leaf_out: - * - * Returns: 0 on success, error code otherwise - */ - -int get_leaf_nr(struct fsck_inode *dip, uint32 index, uint64 *leaf_out) -{ - uint64 leaf_no; - int error = -1; - error = readi(dip, (char *)&leaf_no, - index * sizeof(uint64), sizeof(uint64)); - if (error != sizeof(uint64)){ - log_debug("get_leaf_nr: Bad internal read. (rtn = %d)\n", - error); - return (error < 0) ? error : -EIO; - } - - *leaf_out = gfs64_to_cpu(leaf_no); - - return 0; -} - - -/** - * fs_filecmp - Compare two filenames - * @file1: The first filename - * @file2: The second filename - * @len_of_file2: The length of the second file - * - * This routine compares two filenames and returns TRUE if they are equal. - * - * Returns: TRUE (!=0) if the files are the same, otherwise FALSE (0). - */ -int fs_filecmp(osi_filename_t *file1, char *file2, int len_of_file2) -{ - if (file1->len != len_of_file2){ - return FALSE; - } - - if (osi_memcmp(file1->name, file2, file1->len)){ - return FALSE; - } - return TRUE; -} - - -/** - * fs_dir_search - Search a directory - * @dip: The GFS inode - * @id - * @type: - * - * This routine searches a directory for a file or another directory - * given its identifier. The component of the identifier that is - * not being used to search will be filled in and must be freed by - * the caller. - * - * Returns: 0 if found, -1 on failure, -ENOENT if not found. - */ -int fs_dir_search(struct fsck_inode *dip, identifier_t *id, unsigned int *type) -{ - int error; - - if(dip->i_di.di_type != GFS_FILE_DIR){ - log_err("An attempt was made to search an inode " - "that is not a directory.\n"); - return -1; - } - - if (dip->i_di.di_flags & GFS_DIF_EXHASH) - error = dir_e_search(dip, id, type); - else - error = dir_l_search(dip, id, type); - - return error; -} diff --git a/gfs/gfs_fsck/fs_dir.h b/gfs/gfs_fsck/fs_dir.h deleted file mode 100644 index 7588358..0000000 --- a/gfs/gfs_fsck/fs_dir.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FS_DIR_H__ -#define __FS_DIR_H__ - -#include "osi_user.h" -#include "fsck_incore.h" - -#define ID_FILENAME 0 -#define ID_INUM 1 -typedef struct identifier_s { - int type; - - osi_filename_t *filename; - struct gfs_inum *inum; -} identifier_t; - -int dirent_del(struct fsck_inode *dip, osi_buf_t *bh, - struct gfs_dirent *prev, struct gfs_dirent *cur); -int fsck_inode_is_stuffed(struct fsck_inode *ip); -int dirent_first(osi_buf_t *bh, struct gfs_dirent **dent); -int get_leaf_nr(struct fsck_inode *dip, uint32 index, uint64 *leaf_out); -int fs_filecmp(osi_filename_t *file1, char *file2, int len_of_file2); -int fs_dirent_del(struct fsck_inode *dip, osi_buf_t *bh, osi_filename_t *filename); -int fs_dir_add(struct fsck_inode *dip, osi_filename_t *filename, - struct gfs_inum *inum, unsigned int type); -int fs_dirent_alloc(struct fsck_inode *dip, osi_buf_t *bh, - int name_len, struct gfs_dirent **dent_out); - -int fs_dir_search(struct fsck_inode *dip, identifier_t *id, unsigned int *type); - -#endif /* __FS_DIR_H__ */ diff --git a/gfs/gfs_fsck/fs_inode.c b/gfs/gfs_fsck/fs_inode.c deleted file mode 100644 index 7d97c11..0000000 --- a/gfs/gfs_fsck/fs_inode.c +++ /dev/null @@ -1,613 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "util.h" -#include "bio.h" -#include "fs_bits.h" -#include "fs_dir.h" -#include "rgrp.h" -#include "log.h" - -#include "fs_inode.h" - -#define ST_CREATE 1 - -/** - * fs_get_istruct - Get an inode given its number - * @sdp: The GFS superblock - * @inum: The inode number - * @create: Flag to say if we are allowed to create a new struct fsck_inode - * @ipp: pointer to put the returned inode in - * - * Returns: 0 on success, -1 on error - */ -static int fs_get_istruct(struct fsck_sb *sdp, struct gfs_inum *inum, - int create, struct fsck_inode **ipp) -{ - struct fsck_inode *ip = NULL; - int error = 0; - - if (!create){ - /* we are not currently tracking which inodes we already have */ - error = -1; - goto out; - } - - if(!(ip = (struct fsck_inode *)malloc(sizeof(struct fsck_inode)))) { - log_err("Unable to allocate fsck_inode structure\n"); - error = -1; - goto out; - } - if(!memset(ip, 0, sizeof(struct fsck_inode))) { - log_err("Unable to zero fsck_inode structure\n"); - error = -1; - goto out; - } - - ip->i_num = *inum; - - ip->i_sbd = sdp; - - error = fs_copyin_dinode(ip, NULL); - if (error){ - free(ip); - ip = NULL; - goto out; - } - - out: - *ipp = ip; - - return error; -} - - -/* - * fs_copyin_dinode - read dinode from disk and store in inode - * @ip: inode, sdp and inum must be set - * - * Returns: 0 on success, -1 on error - */ -int fs_copyin_dinode(struct fsck_inode *ip, osi_buf_t *dibh) -{ -/* osi_buf_t *dibh;*/ - int do_relse = 0; - int error = 0; - - if(!dibh) { - error = get_and_read_buf(ip->i_sbd, - ip->i_num.no_addr, &dibh, 0); - if (error) { - stack; - goto out; - } - - if(check_meta(dibh, GFS_METATYPE_DI)){ - log_err("Block #%"PRIu64" is not a dinode.\n", - ip->i_num.no_addr); - relse_buf(ip->i_sbd, dibh); - return -1; - } - do_relse = 1; - } - gfs_dinode_in(&ip->i_di, BH_DATA(dibh)); - - if(do_relse) - relse_buf(ip->i_sbd, dibh); - - - - out: - return error; -} - - -/* - * fs_copyout_dinode - given an inode, copy its dinode data to disk - * @ip: the inode - * - * Returns: 0 on success, -1 on error - */ -int fs_copyout_dinode(struct fsck_inode *ip){ - osi_buf_t *dibh; - int error; - - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); - if(error){ - log_err( "Unable to get a buffer to write dinode to disk.\n"); - return -1; - } - - gfs_dinode_out(&ip->i_di, BH_DATA(dibh)); - - if(write_buf(ip->i_sbd, dibh, 0)){ - log_err( "Unable to commit dinode buffer to disk.\n"); - relse_buf(ip->i_sbd, dibh); - return -1; - } - - relse_buf(ip->i_sbd, dibh); - return 0; -} - -/** - * make_dinode - Fill in a new dinode structure - * @dip: the directory this inode is being created in - * @inum: the inode number - * @type: the file type - * @mode: the file permissions - * @cred: a credentials structure - * - */ - -static int make_dinode(struct fsck_inode *dip, struct gfs_inum *inum, - unsigned int type, unsigned int mode, osi_cred_t *cred) -{ - struct fsck_sb *sdp = dip->i_sbd; - struct gfs_dinode di; - osi_buf_t *dibh; - struct fsck_rgrp *rgd; - int error; - - error = get_and_read_buf(sdp, inum->no_addr, &dibh, 0); - if (error) - goto out; - - if(check_meta(dibh, 0)){ - log_err("make_dinode: Buffer #%"PRIu64" has no meta header.\n", - BH_BLKNO(dibh)); - if(query(dip->i_sbd, "Add header? (y/n) ")){ - struct gfs_meta_header mh; - memset(&mh, 0, sizeof(struct gfs_meta_header)); - mh.mh_magic = GFS_MAGIC; - mh.mh_type = GFS_METATYPE_NONE; - gfs_meta_header_out(&mh, BH_DATA(dibh)); - log_warn("meta header added.\n"); - } else { - log_err("meta header not added. Failing make_dinode.\n"); - relse_buf(sdp, dibh); - return -1; - } - } - - ((struct gfs_meta_header *)BH_DATA(dibh))->mh_type = - cpu_to_gfs32(GFS_METATYPE_DI); - ((struct gfs_meta_header *)BH_DATA(dibh))->mh_format = - cpu_to_gfs32(GFS_FORMAT_DI); - - memset(BH_DATA(dibh) + sizeof(struct gfs_dinode), 0, - BH_SIZE(dibh) - sizeof(struct gfs_dinode)); - - memset(&di, 0, sizeof(struct gfs_dinode)); - - gfs_meta_header_in(&di.di_header, BH_DATA(dibh)); - - di.di_num = *inum; - - if (dip->i_di.di_mode & 02000) - { - di.di_mode = mode | ((type == GFS_FILE_DIR) ? 02000 : 0); - di.di_gid = dip->i_di.di_gid; - } - else - { - di.di_mode = mode; - di.di_gid = osi_cred_to_gid(cred); - } - - di.di_uid = osi_cred_to_uid(cred); - di.di_nlink = 1; - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = osi_current_time(); - - rgd = fs_blk2rgrpd(sdp, inum->no_addr); - if(!rgd){ - log_err( "Unable to map block #%"PRIu64" to rgrp\n", inum->no_addr); - exit(1); - } - - di.di_rgrp = rgd->rd_ri.ri_addr; - di.di_goal_rgrp = di.di_rgrp; - di.di_goal_dblk = di.di_goal_mblk = inum->no_addr - rgd->rd_ri.ri_data1; - - di.di_type = type; - - gfs_dinode_out(&di, BH_DATA(dibh)); - if(write_buf(dip->i_sbd, dibh, 0)){ - log_err( "make_dinode: bad write_buf()\n"); - error = -EIO; - } - - relse_buf(dip->i_sbd, dibh); - - - out: - - return error; -} - -#if 0 -/** - * fs_change_nlink - Change nlink count on inode - * @ip: The GFS inode - * @diff: The change in the nlink count required - * - * Returns: 0 on success, -EXXXX on failure. - */ -static int fs_change_nlink(struct fsck_inode *ip, int diff) -{ - osi_buf_t *dibh; - uint32 nlink; - int error=0; - - nlink = ip->i_di.di_nlink + diff; - - if (diff < 0) - if(nlink >= ip->i_di.di_nlink) - log_err( "fs_change_nlink: Bad link count detected in dinode.\n"); - - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); - if (error) - goto out; - - ip->i_di.di_nlink = nlink; - ip->i_di.di_ctime = osi_current_time(); - - gfs_dinode_out(&ip->i_di, BH_DATA(dibh)); - write_buf(ip->i_sbd, dibh, 0); - relse_buf(ip->i_sbd,dibh); - - out: - return error; -} -#endif -/** - * fs_lookupi - Look up a filename in a directory and return its inode - * @dip: The directory to search - * @name: The name of the inode to look for - * @cred: The caller's credentials - * @ipp: Used to return the found inode if any - * - * Returns: 0 on success, -EXXXX on failure - */ -static int fs_lookupi(struct fsck_inode *dip, osi_filename_t *name, - osi_cred_t *cred, struct fsck_inode **ipp) -{ - struct fsck_sb *sdp = dip->i_sbd; - int error = 0; - identifier_t id; - - memset(&id, 0, sizeof(identifier_t)); - id.filename = name; - id.type = ID_FILENAME; - - *ipp = NULL; - - if (!name->len || name->len > GFS_FNAMESIZE) - { - error = -ENAMETOOLONG; - goto out; - } - - if (fs_filecmp(name, (char *)".", 1)) - { - *ipp = dip; - goto out; - } - - error = fs_dir_search(dip, &id, NULL); - if (error){ - if (error == -ENOENT) - error = 0; - goto out; - } - - error = fs_get_istruct(sdp, id.inum, ST_CREATE, ipp); - - out: - - if(id.inum) free(id.inum); - return error; -} - -int fs_createi(struct fsck_inode *dip, osi_filename_t *name, - unsigned int type, unsigned int mode, osi_cred_t *cred, - int *new, struct fsck_inode **ipp) -{ - osi_list_t *tmp=NULL; - struct fsck_sb *sdp = dip->i_sbd; - struct gfs_inum inum; - int error; - int allocate=0; - identifier_t id; - - memset(&id, 0, sizeof(identifier_t)); - - if (!name->len || name->len > GFS_FNAMESIZE){ - error = -ENAMETOOLONG; - goto fail; - } - - restart: - - /* Don't create entries in an unlinked directory */ - if (!dip->i_di.di_nlink){ - error = -EPERM; - goto fail; - } - - id.filename = name; - id.type = ID_FILENAME; - - error = fs_dir_search(dip, &id, NULL); - if(id.inum) free(id.inum); - switch (error) - { - case -ENOENT: - break; - - case 0: - if (!new){ - error = -EEXIST; - goto fail; - } else { - error = fs_lookupi(dip, name, cred, ipp); - if (error) - goto fail; - - if (*ipp){ - *new = FALSE; - return 0; - } else - goto restart; - } - break; - - default: - goto fail; - } - - if (dip->i_di.di_entries == (uint32)-1){ - error = -EFBIG; - goto fail; - } - if (type == GFS_FILE_DIR && dip->i_di.di_nlink == (uint32)-1){ - error = -EMLINK; - goto fail; - } - - retry: - inum.no_addr = inum.no_formal_ino = 0; - for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){ - uint64 block; - struct fsck_rgrp *rgd; - - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - if(fs_rgrp_read(rgd, FALSE)) - return -1; - if(rgd->rd_rg.rg_freemeta){ - block = fs_blkalloc_internal(rgd, dip->i_num.no_addr, - GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, 1); - log_debug("Got block %"PRIu64"\n", block); - if(block == BFITNOENT) { - fs_rgrp_relse(rgd); - continue; - } - block += rgd->rd_ri.ri_data1; - log_debug("Got block #%"PRIu64"\n", block); - inum.no_addr = inum.no_formal_ino = block; - rgd->rd_rg.rg_freemeta--; - rgd->rd_rg.rg_useddi++; - - if(fs_rgrp_recount(rgd)){ - log_err( "fs_createi: Unable to recount rgrp blocks.\n"); - fs_rgrp_relse(rgd); - error = -EIO; - goto fail; - } - - /* write out the rgrp */ - gfs_rgrp_out(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - write_buf(sdp, rgd->rd_bh[0], 0); - fs_rgrp_relse(rgd); - break; - } else { - if(allocate){ - if(!clump_alloc(rgd, 0)){ - block = fs_blkalloc_internal(rgd, dip->i_num.no_addr, - GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, 1); - log_debug("Got block %"PRIu64"\n", - block); - if(block == BFITNOENT) { - fs_rgrp_relse(rgd); - continue; - } - block += rgd->rd_ri.ri_data1; - - inum.no_addr = inum.no_formal_ino = block; - rgd->rd_rg.rg_freemeta--; - rgd->rd_rg.rg_useddi++; - - if(fs_rgrp_recount(rgd)){ - log_err( "fs_createi: Unable to recount rgrp blocks.\n"); - fs_rgrp_relse(rgd); - error = -EIO; - goto fail; - } - - /* write out the rgrp */ - gfs_rgrp_out(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - write_buf(sdp, rgd->rd_bh[0], 0); - fs_rgrp_relse(rgd); - break; - } - } - fs_rgrp_relse(rgd); - } - } - - if(!inum.no_addr){ - if(allocate){ - log_err( "No space available for new file or directory.\n"); - return -1; - } else { - allocate = 1; - goto retry; - } - } - - error = fs_dir_add(dip, name, &inum, type); - if (error) - goto fail; - - error = make_dinode(dip, &inum, type, mode, cred); - if (error) - goto fail; - - - error = fs_get_istruct(sdp, &inum, ST_CREATE, ipp); - if (error) - goto fail; - - if (new) - *new = TRUE; - - return 0; - - fail: - return error; -} - - -/* - * fs_mkdir - make a directory - * @dip - dir inode that is the parent of the new dir - * @new_dir - name of the new dir - * @mode - mode of new dir - * @nip - returned inode ptr to the new directory - * - * This function has one main difference from the way a normal mkdir - * works. It will not return an error if the directory already - * exists. Instead it will return success and nip will point to the - * inode that exists with the same name as new_dir. - * - * Returns: 0 on success, -1 on failure. - */ -int fs_mkdir(struct fsck_inode *dip, char *new_dir, int mode, struct fsck_inode **nip){ - int error; - osi_cred_t creds; - osi_buf_t *dibh; - struct gfs_dinode *di; - struct gfs_dirent *dent; - struct fsck_inode *ip= NULL; - struct fsck_sb *sdp = dip->i_sbd; - osi_filename_t name; - int new; - - name.name = new_dir; - name.len = strlen(new_dir); - creds.cr_uid = getuid(); - creds.cr_gid = getgid(); - - error = fs_createi(dip, &name, GFS_FILE_DIR, mode, &creds, &new, &ip); - - if (error) - goto fail; - - if(!new){ - goto out; - } - - if(!ip){ - log_err( "fs_mkdir: fs_createi() failed.\n"); - error = -1; - goto fail; - } - - ip->i_di.di_nlink = 2; - ip->i_di.di_size = sdp->sb.sb_bsize - sizeof(struct gfs_dinode); - ip->i_di.di_flags |= GFS_DIF_JDATA; - ip->i_di.di_payload_format = GFS_FORMAT_DE; - ip->i_di.di_entries = 2; - - error = get_and_read_buf(ip->i_sbd, ip->i_num.no_addr, &dibh, 0); - if(error){ - log_err( "fs_mkdir: Unable to aquire directory buffer.\n"); - goto fail; - } - - di = (struct gfs_dinode *)BH_DATA(dibh); - - error = fs_dirent_alloc(ip, dibh, 1, &dent); - if(error){ /* This should never fail */ - log_err( "fs_mkdir: fs_dirent_alloc() failed for "." entry.\n"); - goto fail; - } - - dent->de_inum = di->di_num; /* already GFS endian */ - dent->de_hash = gfs_dir_hash(".", 1); - dent->de_hash = cpu_to_gfs32(dent->de_hash); - dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); - memcpy((char *)(dent + 1), ".", 1); - di->di_entries = cpu_to_gfs32(1); - - error = fs_dirent_alloc(ip, dibh, 2, &dent); - if(error){ /* This should never fail */ - log_err( "fs_mkdir: fs_dirent_alloc() failed for ".." entry.\n"); - goto fail; - } - gfs_inum_out(&dip->i_num, (char *)&dent->de_inum); - dent->de_hash = gfs_dir_hash("..", 2); - dent->de_hash = cpu_to_gfs32(dent->de_hash); - dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); - memcpy((char *)(dent + 1), "..", 2); - - gfs_dinode_out(&ip->i_di, (char *)di); - if(write_buf(ip->i_sbd, dibh, 0)){ - log_err( "fs_mkdir: Bad write_buf()\n"); - error = -EIO; - goto fail; - } - - relse_buf(ip->i_sbd, dibh); - - - /* FIXME: this may break stuff elsewhere, but since I'm - * keeping track of the linkcount in-core, we shouldn't need - * to do this... - - error = fs_change_nlink(dip, +1); - if(error){ - log_err( "fs_mkdir: fs_change_nlink() failed.\n"); - goto fail; - } */ - - out: - error=0; - if(nip) { - *nip = ip; - } - else if(ip) { - free(ip); - ip = NULL; - } - return 0; - fail: - if(ip) - free(ip); - return error; -} - - diff --git a/gfs/gfs_fsck/fs_inode.h b/gfs/gfs_fsck/fs_inode.h deleted file mode 100644 index d727c49..0000000 --- a/gfs/gfs_fsck/fs_inode.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FS_INODE_H__ -#define __FS_INODE_H__ - -#include "fsck_incore.h" - -int fs_copyin_dinode(struct fsck_inode *ip, osi_buf_t *bh); -int fs_copyout_dinode(struct fsck_inode *ip); -int fs_mkdir(struct fsck_inode *dip, char *new_dir, int mode, struct fsck_inode **nip); -int fs_remove(struct fsck_inode *ip); - -static __inline__ int fs_is_stuffed(struct fsck_inode *ip) -{ - return !ip->i_di.di_height; -} - -static __inline__ int fs_is_jdata(struct fsck_inode *ip) -{ - return ip->i_di.di_flags & GFS_DIF_JDATA; -} - - -#endif /* __FS_INODE_H__ */ diff --git a/gfs/gfs_fsck/fs_recovery.c b/gfs/gfs_fsck/fs_recovery.c deleted file mode 100644 index fba7e53..0000000 --- a/gfs/gfs_fsck/fs_recovery.c +++ /dev/null @@ -1,89 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - -#include "util.h" -#include "bio.h" - -#include "fs_recovery.h" - -/* - * reconstruct_single_journal - write a fresh journal - * @sdp: superblock - * @jnum: journal number - * - * This function will write a fresh journal over the top of - * the previous journal. All journal information is lost. This - * process is basically stolen from write_journals() in the mkfs code. - * - * Returns: -1 on error, 0 otherwise - */ -static int reconstruct_single_journal(struct fsck_sb *sdp, int jnum){ - struct gfs_log_header lh; - struct gfs_jindex *jdesc = &(sdp->jindex[jnum]); - uint32 seg, sequence; - char buf[sdp->sb.sb_bsize]; - - srandom(time(NULL)); - sequence = jdesc->ji_nsegment / (RAND_MAX + 1.0) * random(); - - log_info("Clearing journal %d\n", jnum); - - for (seg = 0; seg < jdesc->ji_nsegment; seg++){ - memset(buf, 0, sdp->sb.sb_bsize); - memset(&lh, 0, sizeof(struct gfs_log_header)); - - lh.lh_header.mh_magic = GFS_MAGIC; - lh.lh_header.mh_type = GFS_METATYPE_LH; - lh.lh_header.mh_format = GFS_FORMAT_LH; - lh.lh_header.mh_generation = 0x101674; - lh.lh_flags = GFS_LOG_HEAD_UNMOUNT; - lh.lh_first = jdesc->ji_addr + seg * sdp->sb.sb_seg_size; - lh.lh_sequence = sequence; - - gfs_log_header_out(&lh, buf); - gfs_log_header_out(&lh, - buf + GFS_BASIC_BLOCK - sizeof(struct gfs_log_header)); - - if(do_lseek(sdp->diskfd, lh.lh_first * sdp->sb.sb_bsize) || - do_write(sdp->diskfd, buf, sdp->sb.sb_bsize)){ - log_err("Unable to reconstruct journal %d.\n", jnum); - return -1; - } - - if (++sequence == jdesc->ji_nsegment) - sequence = 0; - } - return 0; -} - - -/* - * reconstruct_journals - write fresh journals - * sdp: the super block - * - * Returns: 0 on success, -1 on failure - */ -int reconstruct_journals(struct fsck_sb *sdp){ - int i; - - log_notice("Clearing journals (this may take a while)"); - for(i=0; i < sdp->journals; i++) { - if((i % 2) == 0) - log_at_notice("."); - if(reconstruct_single_journal(sdp, i)) - return -1; - } - log_notice("\nJournals cleared.\n"); - return 0; -} diff --git a/gfs/gfs_fsck/fs_recovery.h b/gfs/gfs_fsck/fs_recovery.h deleted file mode 100644 index e6d18e9..0000000 --- a/gfs/gfs_fsck/fs_recovery.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FS_RECOVERY_H__ -#define __FS_RECOVERY_H__ - -#include "fsck_incore.h" - -int reconstruct_journals(struct fsck_sb *sdp); - -#endif /* __FS_RECOVERY_H__ */ - diff --git a/gfs/gfs_fsck/fsck.h b/gfs/gfs_fsck/fsck.h deleted file mode 100644 index f1dbbe5..0000000 --- a/gfs/gfs_fsck/fsck.h +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _FSCK_H -#define _FSCK_H - - -#include "fsck_incore.h" -#include "log.h" - -struct gfs_sb; -struct fsck_sb; - -struct options { - char *device; - int yes:1; - int no:1; -}; - -extern uint64_t last_fs_block, last_reported_block; -extern int skip_this_pass, fsck_abort, fsck_query; - -int initialize(struct fsck_sb *sbp); -void destroy(struct fsck_sb *sbp); -int block_mounters(struct fsck_sb *sbp, int block_em); -int pass1(struct fsck_sb *sbp); -int pass1b(struct fsck_sb *sbp); -int pass1c(struct fsck_sb *sbp); -int pass2(struct fsck_sb *sbp, struct options *opts); -int pass3(struct fsck_sb *sbp, struct options *opts); -int pass4(struct fsck_sb *sbp, struct options *opts); -int pass5(struct fsck_sb *sbp, struct options *opts); - -/* FIXME: Hack to get this going for pass2 - this should be pulled out - * of pass1 and put somewhere else... */ -int add_to_dir_list(struct fsck_sb *sbp, uint64_t block); - -#endif /* _FSCK_H */ diff --git a/gfs/gfs_fsck/fsck_incore.h b/gfs/gfs_fsck/fsck_incore.h deleted file mode 100644 index bf51e74..0000000 --- a/gfs/gfs_fsck/fsck_incore.h +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - - -#ifndef _FSCK_INCORE_H -#define _FSCK_INCORE_H - -#include <stdint.h> -#include "ondisk.h" -#include "osi_list.h" -#include "osi_user.h" -#include "fs_bits.h" -#include "block_list.h" - -#define SBF_RECONSTRUCT_JOURNALS (1) - -#define FSCK_HASH_SHIFT (13) -#define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT) -#define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1) - -struct fsck_sb; - -struct inode_info -{ - osi_list_t list; - uint64_t inode; - uint32_t link_count; /* the number of links the inode - * thinks it has */ - uint32_t counted_links; /* the number of links we've found */ -}; - -struct dir_info -{ - osi_list_t list; - uint64_t dinode; - uint64_t treewalk_parent; - uint64_t dotdot_parent; - uint8_t checked:1; - -}; - -/* Use to manage in core bitmaps */ - -struct bitmap_list -{ - osi_list_t list; - char *bm; - struct fsck_rgrp *rgd; -}; - -/* - * Incore inode structure - */ - -struct fsck_inode -{ - struct fsck_sb *i_sbd; /* GFS superblock pointer */ - struct gfs_inum i_num; - struct gfs_dinode i_di; /* Dinode Structure */ -}; - -struct fsck_rgrp -{ - struct fsck_sb *rd_sbd; /* ptr to in-core super block */ - osi_list_t rd_list; /* Link with superblock */ - - struct gfs_rindex rd_ri; /* Resource Index structure */ - struct gfs_rgrp rd_rg; /* Resource Group structure */ - - int32_t rd_open_count; /* # of open references on this rgrpd */ - - fs_bitmap_t *rd_bits; - osi_buf_t **rd_bh; -}; - - - -struct fsck_sb { - struct gfs_sb sb; /* Super Block */ - int diskfd; - uint32_t flags; - char fsname[256]; - - /* Special inodes */ - struct fsck_inode *lf_dip; /* lost-n-found dir inode */ - struct fsck_inode *jiinode; - struct fsck_inode *riinode; - struct fsck_inode *rooti; - - /* rgrp stuff */ - osi_list_t rglist; /* List of resource groups */ - unsigned int rgcount; /* Count of resource groups */ - - /* journal stuff */ - unsigned int journals; /* Number of journals in the FS */ - struct gfs_jindex *jindex; /* Array of Jindex structs for - * this FS's journals */ - struct gfs_jindex jdesc; /* Jindex struct for this - * machine's journal */ - - /* Constants computed on mount */ - uint32_t fsb2bb_shift; /* Shift FS Block numbers to the left by - this to get buffer cache blocks */ - uint32_t diptrs; /* Number of pointers in a dinode */ - uint32_t inptrs; /* Number of pointers in a indirect block */ - uint32_t jbsize; /* Size of a journaled data block */ - uint32_t hash_bsize; /* sizeof(exhash block) */ - uint32_t hash_ptrs; /* Number of points in a hash block */ - uint32_t max_height; /* Maximum height of a file's metadata tree */ - uint64_t heightsize[GFS_MAX_META_HEIGHT]; - uint32_t max_jheight; /* Max height of a journaled file's metadata tree */ - uint64_t jheightsize[GFS_MAX_META_HEIGHT]; - - uint64_t last_fs_block; - uint64_t last_data_block; - uint64_t first_data_block; - - /* dir_list is used to keep track of directory inodes and - * their parents */ - osi_list_t dir_hash[FSCK_HASH_SIZE]; - - /* inode_list is used to keep track of the link count of - * inodes */ - osi_list_t inode_hash[FSCK_HASH_SIZE]; - - /* contains list of data and metadata blocks and various info - * about each */ - struct block_list *bl; - - osi_list_t dup_list; - - /* fsck_opts is used to pass command line params around */ - struct options *opts; - -}; - - - - -#endif /* _FSCK_INCORE_H */ diff --git a/gfs/gfs_fsck/hash.c b/gfs/gfs_fsck/hash.c deleted file mode 100644 index 76baeb0..0000000 --- a/gfs/gfs_fsck/hash.c +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* This is the same hash algorithm used by the glocks in gfs */ - -#include <stdint.h> -#include <unistd.h> -#include "fsck_incore.h" -#include "hash.h" -#include "osi_list.h" - -/** - * hash_more_internal - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * @hash: the hash from a previous call - * - * Take some data and convert it to a 32-bit hash. - * - * This is the 32-bit FNV-1a hash from: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * Hash guts - * - * Returns: the hash - */ - -static __inline__ uint32_t -hash_more_internal(const void *data, unsigned int len, uint32_t hash) -{ - unsigned char *p = (unsigned char *) data; - unsigned char *e = p + len; - uint32_t h = hash; - - while (p < e) { - h ^= (uint32_t) (*p++); - h *= 0x01000193; - } - - return h; -} - -/** - * fsck_hash - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * Take some data and convert it to a 32-bit hash. - * - * This is the 32-bit FNV-1a hash from: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * Returns: the hash - */ - -uint32_t -fsck_hash(const void *data, unsigned int len) -{ - uint32_t h = 0x811C9DC5; - h = hash_more_internal(data, len, h); - return h; -} - -/** - * fsck_hash_more - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * @hash: the hash from a previous call - * - * Take some data and convert it to a 32-bit hash. - * - * This is the 32-bit FNV-1a hash from: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * This version let's you hash together discontinuous regions. - * For example, to compute the combined hash of the memory in - * (data1, len1), (data2, len2), and (data3, len3) you: - * - * h = fsck_hash(data1, len1); - * h = fsck_hash_more(data2, len2, h); - * h = fsck_hash_more(data3, len3, h); - * - * Returns: the hash - */ - -uint32_t -fsck_hash_more(const void *data, unsigned int len, uint32_t hash) -{ - uint32_t h; - h = hash_more_internal(data, len, hash); - return h; -} - - diff --git a/gfs/gfs_fsck/hash.h b/gfs/gfs_fsck/hash.h deleted file mode 100644 index ba5856a..0000000 --- a/gfs/gfs_fsck/hash.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _HASH_H -#define _HASH_H - -uint32_t fsck_hash(const void *data, unsigned int len); -uint32_t fsck_hash_more(const void *data, unsigned int len, uint32_t hash); - -#endif /* _HASH_H */ diff --git a/gfs/gfs_fsck/initialize.c b/gfs/gfs_fsck/initialize.c deleted file mode 100644 index 316a485..0000000 --- a/gfs/gfs_fsck/initialize.c +++ /dev/null @@ -1,441 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdint.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "fsck_incore.h" -#include "fsck.h" -#include "util.h" -#include "super.h" -#include "fs_inode.h" -#include "fs_recovery.h" -#include "inode.h" -#include "bio.h" - -/** - * init_journals - * - * Go through journals and replay them - then clear them - */ -int init_journals(struct fsck_sb *sbp) -{ - - if(!sbp->opts->no) { - /* Next, Replay the journals */ - if(sbp->flags & SBF_RECONSTRUCT_JOURNALS){ - if(reconstruct_journals(sbp)){ - stack; - return 1; - } - } else { - /* ATTENTION -- Journal replay is not supported */ - if(reconstruct_journals(sbp)){ - stack; - return 1; - } - } - } - return 0; -} - -/** - * block_mounters - * - * Change the lock protocol so nobody can mount the fs - * - */ -int block_mounters(struct fsck_sb *sbp, int block_em) -{ - if(block_em) { - /* verify it starts with lock_ */ - if(!strncmp(sbp->sb.sb_lockproto, "lock_", 5)) { - /* Change lock_ to fsck_ */ - memcpy(sbp->sb.sb_lockproto, "fsck_", 5); - } - /* FIXME: Need to do other verification in the else - * case */ - } else { - /* verify it starts with fsck_ */ - /* verify it starts with lock_ */ - if(!strncmp(sbp->sb.sb_lockproto, "fsck_", 5)) { - /* Change fsck_ to lock_ */ - memcpy(sbp->sb.sb_lockproto, "lock_", 5); - } - } - - if(write_sb(sbp)) { - stack; - return -1; - } - return 0; -} - - -/* - * empty_super_block - free all structures in the super block - * sdp: the in-core super block - * - * This function frees all allocated structures within the - * super block. It does not free the super block itself. - * - * Returns: Nothing - */ -static void empty_super_block(struct fsck_sb *sdp) -{ - uint32_t i; - - log_info("Freeing buffers.\n"); - if(sdp->riinode){ - free(sdp->riinode); - sdp->riinode = NULL; - } - if(sdp->jiinode){ - free(sdp->jiinode); - sdp->jiinode = NULL; - } - if(sdp->rooti){ - free(sdp->rooti); - sdp->rooti = NULL; - } - - if(sdp->jindex){ - free(sdp->jindex); - sdp->jindex = NULL; - } - if(sdp->lf_dip) { - free(sdp->lf_dip); - sdp->lf_dip = NULL; - } - while(!osi_list_empty(&sdp->rglist)){ - struct fsck_rgrp *rgd; - unsigned int x; - rgd = osi_list_entry(sdp->rglist.next, - struct fsck_rgrp, rd_list); - osi_list_del(&rgd->rd_list); - if(rgd->rd_bits) - free(rgd->rd_bits); - if(rgd->rd_bh) { - for(x = 0; x < rgd->rd_ri.ri_length; x++) { - if(rgd->rd_bh[x]) { - if(BH_DATA(rgd->rd_bh[x])) { - free(BH_DATA(rgd->rd_bh[x])); - } - free(rgd->rd_bh[x]); - } - } - free(rgd->rd_bh); - } - free(rgd); - } - - for(i = 0; i < FSCK_HASH_SIZE; i++) { - while(!osi_list_empty(&sdp->inode_hash[i])) { - struct inode_info *ii; - ii = osi_list_entry(sdp->inode_hash[i].next, - struct inode_info, list); - osi_list_del(&ii->list); - free(ii); - } - while(!osi_list_empty(&sdp->dir_hash[i])) { - struct dir_info *di; - di = osi_list_entry(sdp->dir_hash[i].next, - struct dir_info, list); - osi_list_del(&di->list); - free(di); - } - } - - block_list_destroy(sdp->bl); -} - - -/** - * set_block_ranges - * @sdp: superblock - * - * Uses info in rgrps and jindex to determine boundaries of the - * file system. - * - * Returns: 0 on success, -1 on failure - */ -static int set_block_ranges(struct fsck_sb *sdp) -{ - struct gfs_jindex *jdesc; - struct fsck_rgrp *rgd; - struct gfs_rindex *ri; - osi_list_t *tmp; - char buf[sdp->sb.sb_bsize]; - uint64 rmax = 0; - uint64 jmax = 0; - uint64 rmin = 0; - uint64 i; - int error; - - log_info("Setting block ranges...\n"); - - for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) - { - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - ri = &rgd->rd_ri; - if (ri->ri_data1 + ri->ri_data - 1 > rmax) - rmax = ri->ri_data1 + ri->ri_data - 1; - if (!rmin || ri->ri_data1 < rmin) - rmin = ri->ri_data1; - } - - last_fs_block = rmax; - - for (i = 0; i < sdp->journals; i++) - { - jdesc = &sdp->jindex[i]; - - if ((jdesc->ji_addr+jdesc->ji_nsegment*sdp->sb.sb_seg_size-1) - > jmax) - jmax = jdesc->ji_addr + jdesc->ji_nsegment - * sdp->sb.sb_seg_size - 1; - } - - sdp->last_fs_block = (jmax > rmax) ? jmax : rmax; - if (sdp->last_fs_block > 0xffffffff && sizeof(unsigned long) <= 4) { - log_crit("This file system is too big for this computer to handle.\n"); - log_crit("Last fs block = 0x%llx, but sizeof(unsigned long) is %d bytes.\n", - sdp->last_fs_block, sizeof(unsigned long)); - goto fail; - } - - sdp->last_data_block = rmax; - sdp->first_data_block = rmin; - - if(do_lseek(sdp->diskfd, (sdp->last_fs_block * sdp->sb.sb_bsize))){ - log_crit("Can't seek to last block in file system: %" - PRIu64"\n", sdp->last_fs_block); - goto fail; - } - - memset(buf, 0, sdp->sb.sb_bsize); - error = read(sdp->diskfd, buf, sdp->sb.sb_bsize); - if (error != sdp->sb.sb_bsize){ - log_crit("Can't read last block in file system (%u), " - "last_fs_block: %"PRIu64"\n", - error, sdp->last_fs_block); - goto fail; - } - - return 0; - - fail: - return -1; -} - - -/** - * read_super_block - * @sdp: - * - * Returns: 0 on success, -1 on failure - */ -static int read_super_block(struct fsck_sb *sdp) -{ - uint32_t i; - - sync(); - - /******************************************************************** - ***************** First, initialize all lists ********************** - ********************************************************************/ - log_info("Initializing lists...\n"); - osi_list_init(&sdp->rglist); - for(i = 0; i < FSCK_HASH_SIZE; i++) { - osi_list_init(&sdp->dir_hash[i]); - osi_list_init(&sdp->inode_hash[i]); - } - - /******************************************************************** - ************ next, read in on-disk SB and set constants ********** - ********************************************************************/ - sdp->sb.sb_bsize = 512; - if (sdp->sb.sb_bsize < GFS_BASIC_BLOCK) - sdp->sb.sb_bsize = GFS_BASIC_BLOCK; - - if(sizeof(struct gfs_sb) > sdp->sb.sb_bsize){ - log_crit("GFS superblock is larger than the blocksize!\n"); - log_debug("sizeof(struct gfs_sb) > sdp->sb.sb_bsize\n"); - return -1; - } - - if(read_sb(sdp) < 0){ - return -1; - } - - return 0; -} - -/** - * fill_super_block - * @sdp: - * - * Returns: 0 on success, -1 on failure - */ -static int fill_super_block(struct fsck_sb *sdp) -{ - struct fsck_inode *ip = NULL; - /******************************************************************* - ****************** Initialize important inodes ****************** - *******************************************************************/ - - log_info("Initializing special inodes...\n"); - /* get ri inode */ - if(load_inode(sdp, sdp->sb.sb_rindex_di.no_addr, &ip)) { - stack; - return -1; - } - sdp->riinode = ip; - - /* get ji inode */ - if(load_inode(sdp, sdp->sb.sb_jindex_di.no_addr, &ip)) { - stack; - return -1; - } - sdp->jiinode = ip; - - /* get root dinode */ - if(!load_inode(sdp, sdp->sb.sb_root_di.no_addr, &ip)) { - if(!check_inode(ip)) { - sdp->rooti = ip; - } - else { - free(ip); - } - } else { - log_warn("Unable to load root inode\n"); - } - - /******************************************************************* - ******* Fill in rgrp and journal indexes and related fields ***** - *******************************************************************/ - - /* read in the ji data */ - if (ji_update(sdp)){ - log_err("Unable to read in ji inode.\n"); - return -1; - } - - if(ri_update(sdp)){ - log_err("Unable to fill in resource group information.\n"); - goto fail; - } - - /******************************************************************* - ******* Now, set boundary fields in the super block ************* - *******************************************************************/ - if(set_block_ranges(sdp)){ - log_err("Unable to determine the boundaries of the" - " file system.\n"); - goto fail; - } - - sdp->bl = block_list_create(sdp->last_fs_block+1, gbmap); - if (!sdp->bl) - goto fail; - - return 0; - - fail: - empty_super_block(sdp); - - return -1; -} - -/** - * init_sbp - initialize superblock pointer - * - */ -static int init_sbp(struct fsck_sb *sbp) -{ - if(sbp->opts->no) { - if ((sbp->diskfd = open(sbp->opts->device, O_RDONLY)) < 0) { - log_crit("Unable to open device: %s\n", sbp->opts->device); - return -1; - } - } else { - /* read in sb from disk */ - if ((sbp->diskfd = open(sbp->opts->device, O_RDWR)) < 0){ - log_crit("Unable to open device: %s\n", sbp->opts->device); - return -1; - } - } - - /* initialize lists and read in the sb */ - if(read_super_block(sbp)) { - stack; - return -1; - } - - /* Change lock protocol to be fsck_* instead of lock_* */ - if(!sbp->opts->no) { - if(block_mounters(sbp, 1)) { - log_err("Unable to block other mounters\n"); - return -1; - } - } - - /* initialize important inodes, fill the rgrp and journal indexes, etc */ - if(fill_super_block(sbp)) { - if(!sbp->opts->no) - block_mounters(sbp, 0); - stack; - return -1; - } - - /* verify various things */ - - if(init_journals(sbp)) { - if(!sbp->opts->no) - block_mounters(sbp, 0); - stack; - return -1; - } - - return 0; -} - -static void destroy_sbp(struct fsck_sb *sbp) -{ - if(!sbp->opts->no) { - if(block_mounters(sbp, 0)) { - log_warn("Unable to unblock other mounters - manual intevention required\n"); - log_warn("Use 'gfs_tool sb <device> proto' to fix\n"); - } - log_info("Syncing the device.\n"); - fsync(sbp->diskfd); - } - empty_super_block(sbp); - close(sbp->diskfd); -} - -int initialize(struct fsck_sb *sbp) -{ - - return init_sbp(sbp); - -} - -void destroy(struct fsck_sb *sbp) -{ - destroy_sbp(sbp); - -} diff --git a/gfs/gfs_fsck/inode.c b/gfs/gfs_fsck/inode.c deleted file mode 100644 index f4ca0f1..0000000 --- a/gfs/gfs_fsck/inode.c +++ /dev/null @@ -1,343 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fsck_incore.h" -#include "fsck.h" -#include "osi_user.h" -#include "bio.h" -#include "fs_inode.h" -#include "inode.h" -#include "rgrp.h" -#include "util.h" -#include "fs_dir.h" - -/* FIXME: Not crazy about this name vs. load_inode, but I'm not very - * creative ATM */ -/* replaces fs_copyin_dinode */ -int copyin_inode(struct fsck_sb *sbp, osi_buf_t *bh, struct fsck_inode **inode) -{ - struct fsck_inode *ip; - - if(!(ip = (struct fsck_inode *)malloc(sizeof(struct fsck_inode)))) { - log_err("Unable to allocate memory for inode\n"); - return -1; - } - if(!memset(ip, 0, sizeof(struct fsck_inode))) { - log_err("Unable to zero inode memory\n"); - return -1; - } - ip->i_sbd = sbp; - - ip->i_num.no_addr = ip->i_num.no_formal_ino = BH_BLKNO(bh); - memset(&ip->i_di, 0, sizeof(struct gfs_dinode)); - - gfs_dinode_in(&ip->i_di, BH_DATA(bh)); - - *inode = ip; - - return 0; -} - -int load_inode(struct fsck_sb *sbp, uint64_t block, struct fsck_inode **inode) -{ - osi_buf_t *bh; - - if(get_and_read_buf(sbp, block, &bh, 0)){ - stack; - log_err("Unable to retrieve block %"PRIu64"\n", - block); - return -1; - } - - if(copyin_inode(sbp, bh, inode)) { - stack; - relse_buf(sbp, bh); - return -1; - } - - relse_buf(sbp, bh); - return 0; -} - - -void free_inode(struct fsck_inode **inode) -{ - free(*inode); - inode = NULL; -} - - -int check_inode(struct fsck_inode *ip) -{ - int error = 0; - if(ip->i_di.di_header.mh_type != GFS_METATYPE_DI) { - return -1; - } - - if(ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino){ - log_err( - "In-core and on-disk formal inode" - "numbers do not match. %"PRIu64" %"PRIu64"\n", - ip->i_num.no_formal_ino, - ip->i_di.di_num.no_formal_ino); - error = -1; - } - - /* Handle a moved inode */ - - if (ip->i_num.no_addr != ip->i_di.di_num.no_addr){ - log_err("\tBlock # used to read disk inode: %"PRIu64"\n" - "\tBlock # recorded in disk inode : %"PRIu64"\n", - ip->i_num.no_addr, ip->i_di.di_num.no_addr); - error = -1; - } - - return error; - -} - - - -/*int remove_inode(struct fsck_sb *sbp, uint64_t block) -{ - struct fsck_inode *ip; - load_inode(sbp, block, &ip); - check_metatree(ip, &fxns); - free_inode(&ip); - return 0; -}*/ - -/** - * fs_get_istruct - Get an inode given its number - * @sdp: The GFS superblock - * @inum: The inode number - * @create: Flag to say if we are allowed to create a new struct fsck_inode - * @ipp: pointer to put the returned inode in - * - * Returns: 0 on success, -1 on error - */ -static int fs_get_istruct(struct fsck_sb *sdp, struct gfs_inum *inum, - int create, struct fsck_inode **ipp) -{ - struct fsck_inode *ip = NULL; - int error = 0; - - if (!create){ - /* we are not currently tracking which inodes we already have */ - error = -1; - goto out; - } - - ip = (struct fsck_inode *)malloc(sizeof(struct fsck_inode)); - ip->i_num = *inum; - - ip->i_sbd = sdp; - - error = fs_copyin_dinode(ip, NULL); - if (error){ - free(ip); - ip = NULL; - goto out; - } - - out: - *ipp = ip; - - return error; -} - - - -/** - * make_dinode - Fill in a new dinode structure - * @dip: the directory this inode is being created in - * @inum: the inode number - * @type: the file type - * @mode: the file permissions - * @cred: a credentials structure - * - */ - -static int make_dinode(struct fsck_inode *dip, struct fsck_sb *sdp, - struct gfs_inum *inum, - unsigned int type, unsigned int mode, osi_cred_t *cred) -{ - struct gfs_dinode di; - osi_buf_t *dibh; - struct fsck_rgrp *rgd; - int error; - - error = get_and_read_buf(sdp, inum->no_addr, &dibh, 0); - if (error) - goto out; - - if(check_meta(dibh, 0)){ - struct gfs_meta_header mh; - log_debug("Buffer #%"PRIu64" has no meta header.\n", - BH_BLKNO(dibh)); - memset(&mh, 0, sizeof(struct gfs_meta_header)); - mh.mh_magic = GFS_MAGIC; - mh.mh_type = GFS_METATYPE_NONE; - gfs_meta_header_out(&mh, BH_DATA(dibh)); - log_debug("meta header added.\n"); - } - - ((struct gfs_meta_header *)BH_DATA(dibh))->mh_type = - cpu_to_gfs32(GFS_METATYPE_DI); - ((struct gfs_meta_header *)BH_DATA(dibh))->mh_format = - cpu_to_gfs32(GFS_FORMAT_DI); - - memset(BH_DATA(dibh) + sizeof(struct gfs_dinode), 0, - BH_SIZE(dibh) - sizeof(struct gfs_dinode)); - - memset(&di, 0, sizeof(struct gfs_dinode)); - - gfs_meta_header_in(&di.di_header, BH_DATA(dibh)); - - di.di_num = *inum; - - if (dip && (dip->i_di.di_mode & 02000)) - { - di.di_mode = mode | ((type == GFS_FILE_DIR) ? 02000 : 0); - di.di_gid = dip->i_di.di_gid; - } - else - { - di.di_mode = mode; - di.di_gid = osi_cred_to_gid(cred); - } - - di.di_uid = osi_cred_to_uid(cred); - di.di_nlink = 1; - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = osi_current_time(); - - rgd = fs_blk2rgrpd(sdp, inum->no_addr); - if(!rgd){ - log_crit("Unable to map block #%"PRIu64" to rgrp\n", inum->no_addr); - exit(1); - } - - di.di_rgrp = rgd->rd_ri.ri_addr; - di.di_goal_rgrp = di.di_rgrp; - di.di_goal_dblk = di.di_goal_mblk = inum->no_addr - rgd->rd_ri.ri_data1; - - di.di_type = type; - - gfs_dinode_out(&di, BH_DATA(dibh)); - if(write_buf(sdp, dibh, 0)){ - log_err("make_dinode: bad write_buf()\n"); - error = -EIO; - } - - relse_buf(sdp, dibh); - - - out: - - return error; -} - - -int create_inode(struct fsck_sb *sbp, unsigned int type, struct fsck_inode **ip) -{ - uint64_t block; - struct fsck_rgrp *rgd; - osi_list_t *tmp; - struct gfs_inum inum; - int allocate=0; - unsigned int mode = 0755; - osi_cred_t cred; - cred.cr_uid = getuid(); - cred.cr_gid = getgid(); - retry: - inum.no_addr = inum.no_formal_ino = 0; - /* Search for a resource group that has free space */ - osi_list_foreach(tmp, &sbp->rglist) { - /* Create a new inode in that rgd */ - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - if(fs_rgrp_read(rgd, FALSE)) { - stack; - return -1; - } - if(rgd->rd_rg.rg_freemeta){ - block = fs_blkalloc_internal(rgd, 0, - GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA, 1); - log_debug("Got block %"PRIu64"\n", block); - if(block == BFITNOENT) { - fs_rgrp_relse(rgd); - continue; - } - block += rgd->rd_ri.ri_data1; - - inum.no_addr = inum.no_formal_ino = block; - /* FIXME: type isn't right */ - block_set(sbp->bl, block, type); - /* write out the rgrp */ - gfs_rgrp_out(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - write_buf(sbp, rgd->rd_bh[0], 0); - fs_rgrp_relse(rgd); - break; - } - else { - if(allocate && !clump_alloc(rgd, 0)){ - block = fs_blkalloc_internal(rgd, 0, - GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, 1); - log_debug("Got block %"PRIu64"\n", block); - - if(block == BFITNOENT) { - fs_rgrp_relse(rgd); - continue; - } - block += rgd->rd_ri.ri_data1; - - inum.no_addr = inum.no_formal_ino = block; - - /* FIXME: type isn't right */ - block_set(sbp->bl, block, type); - - /* write out the rgrp */ - gfs_rgrp_out(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - write_buf(sbp, rgd->rd_bh[0], 0); - fs_rgrp_relse(rgd); - break; - } - fs_rgrp_relse(rgd); - } - } - - if(!inum.no_addr){ - if(allocate){ - log_err("No space available for new file or directory.\n"); - return -1; - } else { - allocate = 1; - goto retry; - } - } - - /* We need to setup the inode without attaching it to a directory */ - if(make_dinode(NULL, sbp, &inum, type, mode, &cred)) { - stack; - return -1; - } - if(fs_get_istruct(sbp, &inum, 1, ip)) { - stack; - return -1; - } - - return 0; - - -} - diff --git a/gfs/gfs_fsck/inode.h b/gfs/gfs_fsck/inode.h deleted file mode 100644 index 32fee3e..0000000 --- a/gfs/gfs_fsck/inode.h +++ /dev/null @@ -1,25 +0,0 @@ -/***************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _INODE_H -#define _INODE_H - - -int copyin_inode(struct fsck_sb *sbp, osi_buf_t *bh, struct fsck_inode **ip); -int load_inode(struct fsck_sb *sbp, uint64_t block, struct fsck_inode **ip); -void free_inode(struct fsck_inode **inode); -int check_inode(struct fsck_inode *ip); -int create_inode(struct fsck_sb *sbp, unsigned int type, - struct fsck_inode **ip); - - -#endif /* _INODE_H */ diff --git a/gfs/gfs_fsck/inode_hash.c b/gfs/gfs_fsck/inode_hash.c deleted file mode 100644 index a88cf0b..0000000 --- a/gfs/gfs_fsck/inode_hash.c +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdint.h> -#include "osi_list.h" -#include "fsck_incore.h" -#include "hash.h" -#include "inode_hash.h" - -static uint32_t inode_hash(uint64_t block_no) -{ - unsigned int h; - - h = fsck_hash(&block_no, sizeof (uint64_t)); - h &= FSCK_HASH_MASK; - - return h; -} - -struct inode_info *inode_hash_search(osi_list_t *buckets, uint64_t key) -{ - struct inode_info *ii; - osi_list_t *tmp; - osi_list_t *bucket = &buckets[inode_hash(key)]; - - osi_list_foreach(tmp, bucket) { - ii = osi_list_entry(tmp, struct inode_info, list); - if(ii->inode == key) { - return ii; - } - } - return NULL; -} - -int inode_hash_insert(osi_list_t *buckets, uint64_t key, struct inode_info *ii) -{ - osi_list_t *tmp; - osi_list_t *bucket = &buckets[inode_hash(key)]; - struct inode_info *itmp = NULL; - - if(osi_list_empty(bucket)) { - osi_list_add(&ii->list, bucket); - return 0; - } - - osi_list_foreach(tmp, bucket) { - itmp = osi_list_entry(tmp, struct inode_info, list); - if(itmp->inode < key) { - continue; - } else { - osi_list_add_prev(&ii->list, tmp); - return 0; - } - } - osi_list_add_prev(&ii->list, bucket); - return 0; -} - - -int inode_hash_remove(osi_list_t *buckets, uint64_t key) -{ - osi_list_t *tmp; - osi_list_t *bucket = &buckets[inode_hash(key)]; - struct inode_info *itmp = NULL; - - if(osi_list_empty(bucket)) { - return -1; - } - osi_list_foreach(tmp, bucket) { - itmp = osi_list_entry(tmp, struct inode_info, list); - if(itmp->inode == key) { - osi_list_del(tmp); - return 0; - } - } - return -1; -} diff --git a/gfs/gfs_fsck/inode_hash.h b/gfs/gfs_fsck/inode_hash.h deleted file mode 100644 index 1c6c5b0..0000000 --- a/gfs/gfs_fsck/inode_hash.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _INODE_HASH_H -#define _INODE_HASH_H - -struct inode_info *inode_hash_search(osi_list_t *buckets, uint64_t block_no); -int inode_hash_insert(osi_list_t *buckets, uint64_t key, struct inode_info *ii);int inode_hash_remove(osi_list_t *buckets, uint64_t key); - -#endif /* _INODE_HASH_H */ diff --git a/gfs/gfs_fsck/link.c b/gfs/gfs_fsck/link.c deleted file mode 100644 index b1b8611..0000000 --- a/gfs/gfs_fsck/link.c +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdint.h> -#include "fsck_incore.h" -#include "inode_hash.h" -#include "link.h" - -int set_link_count(struct fsck_sb *sbp, uint64_t inode_no, uint32_t count) -{ - struct inode_info *ii = NULL; - log_debug("Setting link count to %u for %"PRIu64"\n", count, inode_no); - /* If the list has entries, look for one that matches - * inode_no */ - ii = inode_hash_search(sbp->inode_hash, inode_no); - if(ii) { - if(ii->link_count) { - log_err("Link count already set for inode #%" - PRIu64"!\n"); - stack; - return -1; - } - else { - ii->link_count = count; - } - } - else { - /* If not match was found, add a new entry and set it's - * link count to count*/ - if(!(ii = (struct inode_info *) malloc(sizeof(*ii)))) { - log_err("Unable to allocate inode_info structure\n"); - stack; - return -1; - } - memset(ii, 0, sizeof(*ii)); - ii->inode = inode_no; - ii->link_count = count; - inode_hash_insert(sbp->inode_hash, inode_no, ii); - } - return 0; - - -} - -int increment_link(struct fsck_sb *sbp, uint64_t inode_no) -{ - struct inode_info *ii = NULL; - - ii = inode_hash_search(sbp->inode_hash, inode_no); - /* If the list has entries, look for one that matches - * inode_no */ - if(ii) { - ii->counted_links++; - log_debug("Incremented counted links to %u for %"PRIu64"\n", - ii->counted_links, inode_no); - return 0; - } - log_debug("No match found when incrementing link for %"PRIu64"!\n", - inode_no); - /* If no match was found, add a new entry and set its - * counted links to 1 */ - if(!(ii = (struct inode_info *) malloc(sizeof(*ii)))) { - log_err("Unable to allocate inode_info structure\n"); - stack; - return -1; - } - if(!memset(ii, 0, sizeof(*ii))) { - log_err("Unable to zero inode_info structure\n"); - stack; - return -1; - } - ii->inode = inode_no; - ii->counted_links = 1; - inode_hash_insert(sbp->inode_hash, inode_no, ii); - - return 0; -} - -int decrement_link(struct fsck_sb *sbp, uint64_t inode_no) -{ - struct inode_info *ii = NULL; - - ii = inode_hash_search(sbp->inode_hash, inode_no); - /* If the list has entries, look for one that matches - * inode_no */ - log_err("Decrementing %"PRIu64"\n", inode_no); - if(ii) { - ii->counted_links--; - return 0; - } - log_debug("No match found when decrementing link for %"PRIu64"!\n", - inode_no); - return -1; - -} - - diff --git a/gfs/gfs_fsck/link.h b/gfs/gfs_fsck/link.h deleted file mode 100644 index 906008a..0000000 --- a/gfs/gfs_fsck/link.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - -#ifndef _LINK_H -#define _LINK_H - -int set_link_count(struct fsck_sb *sbp, uint64_t inode_no, uint32_t count); -int increment_link(struct fsck_sb *sbp, uint64_t inode_no); -int decrement_link(struct fsck_sb *sbp, uint64_t inode_no); - -#endif /* _LINK_H */ diff --git a/gfs/gfs_fsck/log.c b/gfs/gfs_fsck/log.c deleted file mode 100644 index d6b0cad..0000000 --- a/gfs/gfs_fsck/log.c +++ /dev/null @@ -1,155 +0,0 @@ -/***************************************************************************** -****************************************************************************** -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -****************************************************************************** -*****************************************************************************/ - -#include <stdio.h> -#include <stdarg.h> -#include <ctype.h> -#include <libintl.h> - -#include <sys/select.h> -#include <unistd.h> - -#include "fsck_incore.h" -#include "log.h" - -#define _(String) gettext(String) - -struct log_state { - int print_level; -}; -static struct log_state _state = {MSG_NOTICE}; - -void increase_verbosity(void) -{ - _state.print_level++; -} - -void decrease_verbosity(void) -{ - _state.print_level--; -} - -void print_msg(int priority, char *file, int line, const char *format, va_list args) { - - switch (priority) { - - case MSG_DEBUG: - printf("(%s:%d)\t", file, line); - vprintf(format, args); - fflush(stdout); - break; - case MSG_INFO: - case MSG_NOTICE: - case MSG_WARN: - vprintf(format, args); - fflush(stdout); - break; - case MSG_ERROR: - case MSG_CRITICAL: - default: - vfprintf(stderr, format, args); - break; - } - return; -} - - -void print_fsck_log(int iif, int priority, char *file, int line, const char *format, ...) -{ - - va_list args; - const char *transform; - - va_start(args, format); - - transform = _(format); - - if((_state.print_level == priority) || - (!iif && (_state.print_level >= priority))) - print_msg(priority, file, line, transform, args); - - va_end(args); -} - - - -int query(struct fsck_sb *sbp, const char *format, ...) -{ - - va_list args; - const char *transform; - char response; - fd_set rfds; - struct timeval tv; - int err = 0; - int ret = 0; - - va_start(args, format); - - transform = _(format); - - if(sbp->opts->yes) - return 1; - if(sbp->opts->no) - return 0; - - fsck_query = TRUE; - /* Watch stdin (fd 0) to see when it has input. */ - FD_ZERO(&rfds); - FD_SET(STDIN_FILENO, &rfds); - - tv.tv_sec = 0; - tv.tv_usec = 0; - /* Make sure there isn't extraneous input before asking the - * user the question */ - while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) { - if(err < 0) { - log_debug("Error in select() on stdin\n"); - break; - } - read(STDIN_FILENO, &response, sizeof(char)); - - } - query: - vprintf(transform, args); - - /* Make sure query is printed out */ - fflush(NULL); - - rescan: - read(STDIN_FILENO, &response, sizeof(char)); - - if(tolower(response) == 'y') { - ret = 1; - } else if (tolower(response) == 'n') { - ret = 0; - } else if ((response == ' ') || (response == '\t')) { - goto rescan; - } else { - while(response != '\n') - read(STDIN_FILENO, &response, sizeof(char)); - printf("Bad response, please type 'y' or 'n'.\n"); - goto query; - } - - /* Clip the input */ - while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) { - if(err < 0) { - log_debug("Error in select() on stdin\n"); - break; - } - read(STDIN_FILENO, &response, sizeof(char)); - } - - fsck_query = FALSE; - return ret; -} diff --git a/gfs/gfs_fsck/log.h b/gfs/gfs_fsck/log.h deleted file mode 100644 index aa9ab19..0000000 --- a/gfs/gfs_fsck/log.h +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************** -****************************************************************************** -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -****************************************************************************** -*****************************************************************************/ - -#ifndef __LOG_H -#define __LOG_H - -#define MSG_DEBUG 7 -#define MSG_INFO 6 -#define MSG_NOTICE 5 -#define MSG_WARN 4 -#define MSG_ERROR 3 -#define MSG_CRITICAL 2 -#define MSG_NULL 1 - - - -#define print_log(iif, priority, format...) \ -do { \ - print_fsck_log(iif, priority, __FILE__, __LINE__, ## format); \ -} while(0) - -#define log_debug(format...) \ -do { \ - print_log(0, MSG_DEBUG, format); \ -} while(0) - -#define log_info(format...) \ -do { \ - print_log(0, MSG_INFO, format); \ -} while(0) - -#define log_notice(format...) \ -do { \ - print_log(0, MSG_NOTICE, format); \ -} while(0) - -#define log_warn(format...) \ -do { \ - print_log(0, MSG_WARN, format); \ -} while(0) - -#define log_err(format...) \ -do { \ - print_log(0, MSG_ERROR, format); \ -} while(0) - -#define log_crit(format...) \ -do { \ - print_log(0, MSG_CRITICAL, format); \ -} while(0) - -#define stack log_debug("<backtrace> - %s()\n", __func__) - -#define log_at_debug(format...) \ -do { \ - print_log(1, MSG_DEBUG, format); \ -} while(0) - -#define log_at_info(format...) \ -do { \ - print_log(1, MSG_INFO, format); \ -} while(0) - -#define log_at_notice(format...) \ -do { \ - print_log(1, MSG_NOTICE, format); \ -} while(0) - -#define log_at_warn(format...) \ -do { \ - print_log(1, MSG_WARN, format); \ -} while(0) - -#define log_at_err(format...) \ -do { \ - print_log(1, MSG_ERROR, format); \ -} while(0) - -#define log_at_crit(format...) \ -do { \ - print_log(1, MSG_CRITICAL, format); \ -} while(0) - -void increase_verbosity(void); -void decrease_verbosity(void); -void print_fsck_log(int iif, int priority, char *file, int line, const char *format, ...); -int query(struct fsck_sb *sbp, const char *format, ...); - - -#endif /* __LOG_H */ diff --git a/gfs/gfs_fsck/lost_n_found.c b/gfs/gfs_fsck/lost_n_found.c deleted file mode 100644 index b4a1e52..0000000 --- a/gfs/gfs_fsck/lost_n_found.c +++ /dev/null @@ -1,146 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fs_dir.h" - -#include "lost_n_found.h" -#include "link.h" -#include "fs_inode.h" -#include "bio.h" -#include "inode.h" -/* add_inode_to_lf - Add dir entry to lost+found for the inode - * @ip: inode to add to lost + found - * - * This function adds an entry into the lost and found dir - * for the given inode. The name of the entry will be - * "lost_<ip->i_num.no_addr>". - * - * Returns: 0 on success, -1 on failure. - */ -int add_inode_to_lf(struct fsck_inode *ip){ - char tmp_name[256]; - struct fsck_inode *lf_ip, *ri; - osi_filename_t filename; - struct block_query q; - - if(!ip->i_sbd->lf_dip) { - log_info("Locating/Creating lost and found directory\n"); - - load_inode(ip->i_sbd, ip->i_sbd->sb.sb_root_di.no_addr, &ri); - - if(fs_mkdir(ri, "l+f", 00700, &lf_ip)){ - log_err("Unable to create/locate l+f directory.\n"); - } - free_inode(&ri); - if(!lf_ip){ - log_warn("No l+f directory, can not add inode.\n"); - return -1; - } - log_notice("l+f directory at %"PRIu64"\n", lf_ip->i_num.no_addr); - - ip->i_sbd->lf_dip = lf_ip; - if(block_check(ip->i_sbd->bl, lf_ip->i_num.no_addr, &q)) { - stack; - return -1; - } - if(q.block_type != inode_dir) { - /* This is a new l+f directory, so set its - * block type and increment link counts for - * the directories */ - /* FIXME: i'd feel better about this if - * fs_mkdir returned whether it created a new - * directory or just found an old one, and we - * used that instead of the block_type to run - * this */ - block_set(ip->i_sbd->bl, lf_ip->i_num.no_addr, inode_dir); - increment_link(ip->i_sbd, ip->i_sbd->sb.sb_root_di.no_addr); - increment_link(ip->i_sbd, lf_ip->i_num.no_addr); - increment_link(ip->i_sbd, lf_ip->i_num.no_addr); - } - } else { - lf_ip = ip->i_sbd->lf_dip; - } - - if(ip->i_num.no_addr == lf_ip->i_num.no_addr) { - log_err("Trying to add l+f to itself...skipping"); - return 0; - } - switch(ip->i_di.di_type){ - case GFS_FILE_DIR: - log_info("Adding .. entry pointing to l+f for %"PRIu64"\n", - ip->i_num.no_addr); - sprintf(tmp_name, ".."); - filename.len = strlen(tmp_name); /* no trailing NULL */ - if(!(filename.name = malloc(sizeof(char) * filename.len))) { - log_err("Unable to allocate name\n"); - stack; - return -1; - } - if(!memset(filename.name, 0, sizeof(char) * filename.len)) { - log_err("Unable to zero name\n"); - stack; - return -1; - } - memcpy(filename.name, tmp_name, filename.len); - - if(fs_dirent_del(ip, NULL, &filename)){ - log_warn("add_inode_to_lf: " - "Unable to remove ".." directory entry.\n"); - } - - if(fs_dir_add(ip, &filename, &(lf_ip->i_num), - lf_ip->i_di.di_type)){ - log_err("Failed to link ".." entry to l+f directory.\n"); - block_set(ip->i_sbd->bl, ip->i_num.no_addr, meta_inval); - return 0; - } - - free(filename.name); - sprintf(tmp_name, "lost_dir_%"PRIu64, ip->i_num.no_addr); - break; - case GFS_FILE_REG: - sprintf(tmp_name, "lost_file_%"PRIu64, ip->i_num.no_addr); - break; - default: - sprintf(tmp_name, "lost_%"PRIu64, ip->i_num.no_addr); - break; - } - filename.len = strlen(tmp_name); /* no trailing NULL */ - if(!(filename.name = malloc(sizeof(char) * filename.len))) { - log_err("Unable to allocate name\n"); - stack; - return -1; - } - if(!memset(filename.name, 0, sizeof(char) * filename.len)) { - log_err("Unable to zero name\n"); - stack; - return -1; - } - memcpy(filename.name, tmp_name, filename.len); - - if(fs_dir_add(lf_ip, &filename, &(ip->i_num), ip->i_di.di_type)){ - log_err("Failed to add inode #%"PRIu64" to l+f dir.\n", - ip->i_num.no_addr); - /* FIXME: don't return -1 here, just mark the inode bad */ - free(filename.name); - block_set(ip->i_sbd->bl, ip->i_num.no_addr, meta_inval); - return 0; - } - increment_link(ip->i_sbd, ip->i_num.no_addr); - if(ip->i_di.di_type == GFS_FILE_DIR) { - increment_link(ip->i_sbd, lf_ip->i_num.no_addr); - } - free(filename.name); - log_notice("Added inode #%"PRIu64" to l+f dir\n", ip->i_num.no_addr); - return 0; -} diff --git a/gfs/gfs_fsck/lost_n_found.h b/gfs/gfs_fsck/lost_n_found.h deleted file mode 100644 index fb8b286..0000000 --- a/gfs/gfs_fsck/lost_n_found.h +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LOST_N_FOUND_H__ -#define __LOST_N_FOUND_H__ - -#include "fsck_incore.h" - -int add_inode_to_lf(struct fsck_inode *ip); - -#endif /* __LOST_N_FOUND_H__ */ diff --git a/gfs/gfs_fsck/main.c b/gfs/gfs_fsck/main.c deleted file mode 100644 index 58b0c7a..0000000 --- a/gfs/gfs_fsck/main.c +++ /dev/null @@ -1,289 +0,0 @@ -/***************************************************************************** -****************************************************************************** -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -****************************************************************************** -*****************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdint.h> -#include <libgen.h> -#include <ctype.h> -#include <signal.h> - -#include "copyright.cf" -#include "fsck_incore.h" -#include "fsck.h" -#include "log.h" - -uint64_t last_fs_block, last_reported_block = -1; -int skip_this_pass = FALSE, fsck_abort = FALSE, fsck_query = FALSE; -const char *pass = ""; - -void print_map(struct block_list *il, int count) -{ - int i, j; - struct block_query k; - - log_info("Printing map of blocks - 80 blocks per row\n"); - j = 0; - for(i = 0; i < count; i++) { - if(j > 79) { - log_info("\n"); - j = 0; - } - else if(!(j %10) && j != 0) { - log_info(" "); - } - j++; - block_check(il, i, &k); - log_info("%X", k.block_type); - - } - log_info("\n"); -} - -void usage(char *name) -{ - printf("Usage: %s [-hnqvVy] <device> \n", basename(name)); -} - -void version(void) -{ - printf("GFS fsck %s (built %s %s)\n", - GFS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); -} - -int read_cmdline(int argc, char **argv, struct options *opts) -{ - int c; - - while((c = getopt(argc, argv, "hnqvyV")) != -1) { - switch(c) { - - case 'h': - usage(argv[0]); - exit(0); - break; - case 'n': - opts->no = 1; - break; - case 'q': - decrease_verbosity(); - break; - case 'v': - increase_verbosity(); - break; - case 'V': - version(); - exit(0); - break; - case 'y': - opts->yes = 1; - break; - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - break; - default: - fprintf(stderr, "Bad programmer! You forgot to catch" - " the %c flag\n", c); - exit(1); - break; - - } - } - if(argc > optind) { - opts->device = (argv[optind]); - if(!opts->device) { - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - } - } else { - fprintf(stderr, "No device specified. Use '-h' for usage.\n"); - exit(1); - } - return 0; -} - -void interrupt(int sig) -{ - fd_set rfds; - struct timeval tv; - char response; - int err; - - if (fsck_query) /* if we're asking them a question */ - return; /* ignore the interrupt signal */ - FD_ZERO(&rfds); - FD_SET(STDIN_FILENO, &rfds); - - tv.tv_sec = 0; - tv.tv_usec = 0; - /* Make sure there isn't extraneous input before asking the - * user the question */ - while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) { - if(err < 0) { - log_debug("Error in select() on stdin\n"); - break; - } - read(STDIN_FILENO, &response, sizeof(char)); - } - while (TRUE) { - printf("\ngfs_fsck interrupted in %s: ", pass); - if (!last_reported_block || last_reported_block == last_fs_block) - printf("progress unknown.\n"); - else - printf("processing block %" PRIu64 " out of %" PRIu64 "\n", - last_reported_block, last_fs_block); - printf("Do you want to abort gfs_fsck, skip the rest of %s or continue (a/s/c)?", pass); - - /* Make sure query is printed out */ - fflush(stdout); - read(STDIN_FILENO, &response, sizeof(char)); - - if(tolower(response) == 's') { - skip_this_pass = TRUE; - return; - } - else if (tolower(response) == 'a') { - fsck_abort = TRUE; - return; - } - else if (tolower(response) == 'c') - return; - else { - while(response != '\n') - read(STDIN_FILENO, &response, sizeof(char)); - printf("Bad response, please type 'c', 'a' or 's'.\n"); - continue; - } - } -} - -int main(int argc, char **argv) -{ - struct fsck_sb sb; - struct options opts = {0}; - - struct fsck_sb *sbp = &sb; - memset(sbp, 0, sizeof(*sbp)); - - sbp->opts = &opts; - - if(read_cmdline(argc, argv, &opts)) - return 1; - setbuf(stdout, NULL); - log_notice("Initializing fsck\n"); - if (initialize(sbp)) - return 1; - - signal(SIGINT, interrupt); - log_notice("Starting pass1\n"); - pass = "pass 1"; - last_reported_block = 0; - if (pass1(sbp)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass1 interrupted \n"); - } - else - log_notice("Pass1 complete \n"); - - if (!fsck_abort) { - last_reported_block = 0; - pass = "pass 1b"; - log_notice("Starting pass1b\n"); - if(pass1b(sbp)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass1b interrupted \n"); - } - else - log_notice("Pass1b complete \n"); - } - if (!fsck_abort) { - last_reported_block = 0; - pass = "pass 1c"; - log_notice("Starting pass1c\n"); - if(pass1c(sbp)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass1c interrupted \n"); - } - else - log_notice("Pass1c complete \n"); - } - if (!fsck_abort) { - last_reported_block = 0; - pass = "pass 2"; - log_notice("Starting pass2\n"); - if (pass2(sbp, &opts)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass2 interrupted \n"); - } - else - log_notice("Pass2 complete \n"); - } - if (!fsck_abort) { - last_reported_block = 0; - pass = "pass 3"; - log_notice("Starting pass3\n"); - if (pass3(sbp, &opts)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass3 interrupted \n"); - } - else - log_notice("Pass3 complete \n"); - } - if (!fsck_abort) { - last_reported_block = 0; - pass = "pass 4"; - log_notice("Starting pass4\n"); - if (pass4(sbp, &opts)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass4 interrupted \n"); - } - else - log_notice("Pass4 complete \n"); - } - if (!fsck_abort) { - last_reported_block = 0; - pass = "pass 5"; - log_notice("Starting pass5\n"); - if (pass5(sbp, &opts)) - return 1; - if (skip_this_pass || fsck_abort) { - skip_this_pass = FALSE; - log_notice("Pass5 interrupted \n"); - } - else - log_notice("Pass5 complete \n"); - /* print_map(sbp->bl, sbp->last_fs_block); */ - - log_notice("Writing changes to disk\n"); - } - destroy(sbp); - - return 0; -} - - - diff --git a/gfs/gfs_fsck/metawalk.c b/gfs/gfs_fsck/metawalk.c deleted file mode 100644 index 33ad990..0000000 --- a/gfs/gfs_fsck/metawalk.c +++ /dev/null @@ -1,819 +0,0 @@ -/***************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fsck_incore.h" -#include "fsck.h" -#include "bio.h" -#include "fs_dir.h" -#include "inode.h" -#include "util.h" -#include "hash.h" - -#include "metawalk.h" - -int check_entries(struct fsck_inode *ip, osi_buf_t *bh, int index, - int type, int *update, uint16_t *count, - struct metawalk_fxns *pass) -{ - struct gfs_leaf *leaf = NULL; - struct gfs_dirent *dent; - struct gfs_dirent de, *prev; - int error = 0; - char *bh_end; - char *filename; - int first = 1; - - bh_end = BH_DATA(bh) + BH_SIZE(bh); - - if(type == DIR_LINEAR) { - dent = (struct gfs_dirent *)(BH_DATA(bh) - + sizeof(struct gfs_dinode)); - } - else if (type == DIR_EXHASH) { - dent = (struct gfs_dirent *)(BH_DATA(bh) - + sizeof(struct gfs_leaf)); - leaf = (struct gfs_leaf *)BH_DATA(bh); - log_debug("Checking leaf %"PRIu64"\n", BH_BLKNO(bh)); - } - else { - log_err("Invalid directory type %d specified\n", type); - return -1; - } - - prev = NULL; - if(!pass->check_dentry) { - return 0; - } - - while(1) { - memset(&de, 0, sizeof(struct gfs_dirent)); - gfs_dirent_in(&de, (char *)dent); - filename = (char *)dent + sizeof(struct gfs_dirent); - - if (!de.de_inum.no_formal_ino){ - if(first){ - log_debug("First dirent is a sentinel (place holder).\n"); - first = 0; - } else { - /* FIXME: Do something about this */ - log_err("Directory entry with inode number of zero in leaf %"PRIu64" of directory %"PRIu64"!\n", BH_BLKNO(bh), ip->i_di.di_num.no_addr); - return 1; - } - } else { - - error = pass->check_dentry(ip, dent, prev, bh, - filename, update, - count, - pass->private); - if(error < 0) { - stack; - return -1; - } - /*if(error > 0) { - return 1; - }*/ - } - - if (de.de_rec_len < sizeof(struct gfs_dirent)) { - log_err("Entry %"PRIu64" of directory %" - PRIu64" is corrupt, skipping.\n", - BH_BLKNO(bh), ip->i_di.di_num.no_addr); - break; - } - if ((char *)dent + de.de_rec_len >= bh_end){ - log_debug("Last entry processed.\n"); - break; - } - - /* If we didn't clear the dentry, or if we did, but it - * was the first dentry, set prev */ - if(!error || first) { - prev = dent; - } - - first = 0; - - - dent = (struct gfs_dirent *)((char *)dent + de.de_rec_len); - } - return 0; -} - - - -/* Checks exthash directory entries */ -int check_leaf(struct fsck_inode *ip, int *update, struct metawalk_fxns *pass) -{ - int error; - struct gfs_leaf leaf; - uint64_t leaf_no, old_leaf; - osi_buf_t *lbh; - int index; - struct fsck_sb *sbp = ip->i_sbd; - uint16_t count; - int ref_count = 0, exp_count = 0; - - old_leaf = 0; - for(index = 0; index < (1 << ip->i_di.di_depth); index++) { - if(get_leaf_nr(ip, index, &leaf_no)) { - log_err("Unable to get leaf block number in dir %" - PRIu64"\n" - "\tDepth = %u\n" - "\tindex = %u\n", - ip->i_num.no_addr, - ip->i_di.di_depth, - index); - return -1; - } - - /* GFS has multiple indirect pointers to the same leaf - * until those extra pointers are needed, so skip the - * dups */ - if(old_leaf == leaf_no) { - ref_count++; - continue; - } else { - if(ref_count != exp_count){ - log_err("Dir #%"PRIu64" has an incorrect number " - "of pointers to leaf #%"PRIu64"\n" - "\tFound: %u, Expected: %u\n", - ip->i_num.no_addr, - old_leaf, - ref_count, - exp_count); - return 1; - } - ref_count = 1; - } - - count = 0; - do { - /* FIXME: Do other checks (see old - * pass3:dir_exhash_scan() */ - lbh = NULL; - if(pass->check_leaf) { - error = pass->check_leaf(ip, leaf_no, &lbh, - pass->private); - if(error < 0) { - stack; - relse_buf(sbp, lbh); - return -1; - } - if(error > 0) { - relse_buf(sbp, lbh); - lbh = NULL; - return 1; - } - } - - if (!lbh){ - if(get_and_read_buf(sbp, leaf_no, - &lbh, 0)){ - log_err("Unable to read leaf block #%" - PRIu64" for " - "directory #%"PRIu64".\n", - leaf_no, - ip->i_di.di_num.no_addr); - /* FIXME: should i error out - * if this fails? */ - break; - } - } - gfs_leaf_in(&leaf, BH_DATA(lbh)); - - /* Make sure it's really a leaf. */ - if (leaf.lf_header.mh_type != GFS_METATYPE_LF) { - log_err("Inode %" PRIu64 " points to bad leaf " - PRIu64 ".\n", ip->i_di.di_num.no_addr, - leaf_no); - relse_buf(sbp, lbh); - break; - } - exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth)); - log_debug("expected count %u - %u %u\n", exp_count, - ip->i_di.di_depth, leaf.lf_depth); - if(pass->check_dentry && - ip->i_di.di_type == GFS_FILE_DIR) { - error = check_entries(ip, lbh, index, - DIR_EXHASH, update, - &count, - pass); - - /* Since the buffer possibly got - updated directly, release it now, - and grab it again later if we need - it */ - relse_buf(sbp, lbh); - if(error < 0) { - stack; - return -1; - } - - if(error > 0) { - return 1; - } - - if(update && (count != leaf.lf_entries)) { - - if(get_and_read_buf(sbp, leaf_no, - &lbh, 0)){ - log_err("Unable to read leaf block #%" - PRIu64" for " - "directory #%"PRIu64".\n", - leaf_no, - ip->i_di.di_num.no_addr); - return -1; - } - gfs_leaf_in(&leaf, BH_DATA(lbh)); - - log_err("Leaf(%"PRIu64") entry count in directory %"PRIu64" doesn't match number of entries found - is %u, found %u\n", leaf_no, ip->i_num.no_addr, leaf.lf_entries, count); - if(query(sbp, "Update leaf entry count? (y/n) ")) { - leaf.lf_entries = count; - gfs_leaf_out(&leaf, BH_DATA(lbh)); - write_buf(sbp, lbh, 0); - log_warn("Leaf entry count updated\n"); - } else { - log_err("Leaf entry count left in inconsistant state\n"); - } - relse_buf(sbp, lbh); - } - /* FIXME: Need to get entry count and - * compare it against - * leaf->lf_entries */ - - break; - } else { - relse_buf(sbp, lbh); - if(!leaf.lf_next) { - break; - } - leaf_no = leaf.lf_next; - log_debug("Leaf chain detected.\n"); - } - } while(1); - old_leaf = leaf_no; - } - return 0; -} - -static int check_eattr_entries(struct fsck_inode *ip, osi_buf_t *bh, - struct metawalk_fxns *pass) -{ - struct gfs_ea_header *ea_hdr, *ea_hdr_prev = NULL; - uint64_t *ea_data_ptr = NULL; - int i; - int error = 0; - uint32_t offset = (uint32_t)sizeof(struct gfs_meta_header); - - if(!pass->check_eattr_entry) { - return 0; - } - - ea_hdr = (struct gfs_ea_header *)(BH_DATA(bh) + - sizeof(struct gfs_meta_header)); - - while(1){ - error = pass->check_eattr_entry(ip, bh, ea_hdr, ea_hdr_prev, - pass->private); - if(error < 0) { - stack; - return -1; - } - if(error == 0) { - if(pass->check_eattr_extentry && ea_hdr->ea_num_ptrs) { - ea_data_ptr = ((uint64_t *)((char *)ea_hdr + - sizeof(struct gfs_ea_header) + - ((ea_hdr->ea_name_len + 7) & ~7))); - - /* It is possible when a EA is shrunk - ** to have ea_num_ptrs be greater than - ** the number required for ** data. - ** In this case, the EA ** code leaves - ** the blocks ** there for ** - ** reuse........... */ - for(i = 0; i < ea_hdr->ea_num_ptrs; i++){ - if(pass->check_eattr_extentry(ip, - ea_data_ptr, - bh, ea_hdr, - ea_hdr_prev, - pass->private)) { - stack; - return -1; - } - ea_data_ptr++; - } - } - } - offset += gfs32_to_cpu(ea_hdr->ea_rec_len); - if(ea_hdr->ea_flags & GFS_EAFLAG_LAST || - offset >= ip->i_sbd->sb.sb_bsize || ea_hdr->ea_rec_len == 0){ - break; - } - ea_hdr_prev = ea_hdr; - ea_hdr = (struct gfs_ea_header *) - ((char *)(ea_hdr) + - gfs32_to_cpu(ea_hdr->ea_rec_len)); - } - - return 0; -} - -/** - * check_leaf_eattr - * @ip: the inode the eattr comes from - * @block: block number of the leaf - * - * Returns: 0 on success, -1 if removal is needed - */ -static int check_leaf_eattr(struct fsck_inode *ip, uint64_t block, - uint64_t parent, struct metawalk_fxns *pass) -{ - osi_buf_t *bh = NULL; - int error = 0; - log_debug("Checking EA leaf block #%"PRIu64".\n", block); - - if(pass->check_eattr_leaf) { - error = pass->check_eattr_leaf(ip, block, parent, - &bh, pass->private); - if(error < 0) { - stack; - return -1; - } - if(error > 0) { - relse_buf(ip->i_sbd, bh); - return 1; - } - } - - check_eattr_entries(ip, bh, pass); - - relse_buf(ip->i_sbd, bh); - - return 0; -} - - - - - -/** - * check_indirect_eattr - * @ip: the inode the eattr comes from - * @indirect_block - * - * Returns: 0 on success -1 on error - */ -static int check_indirect_eattr(struct fsck_inode *ip, uint64_t indirect, - struct metawalk_fxns *pass){ - int error = 0; - uint64_t *ea_leaf_ptr, *end; - uint64_t block; - osi_buf_t *indirect_buf = NULL; - struct fsck_sb *sdp = ip->i_sbd; - - log_debug("Checking EA indirect block #%"PRIu64".\n", indirect); - - if (!pass->check_eattr_indir || - !pass->check_eattr_indir(ip, indirect, ip->i_di.di_num.no_addr, - &indirect_buf, pass->private)) { - ea_leaf_ptr = (uint64 *)(BH_DATA(indirect_buf) - + sizeof(struct gfs_indirect)); - end = ea_leaf_ptr - + ((sdp->sb.sb_bsize - - sizeof(struct gfs_indirect)) / 8); - - while(*ea_leaf_ptr && (ea_leaf_ptr < end)){ - block = gfs64_to_cpu(*ea_leaf_ptr); - /* FIXME: should I call check_leaf_eattr if we - * find a dup? */ - error = check_leaf_eattr(ip, block, indirect, pass); - ea_leaf_ptr++; - } - } - - relse_buf(sdp, indirect_buf); - return error; -} - - - - -/** - * check_inode_eattr - check the EA's for a single inode - * @ip: the inode whose EA to check - * - * Returns: 0 on success, -1 on error - */ -int check_inode_eattr(struct fsck_inode *ip, struct metawalk_fxns *pass) -{ - int error = 0; - - if(!ip->i_di.di_eattr){ - return 0; - } - - log_debug("Extended attributes exist for inode #%"PRIu64".\n", - ip->i_num.no_formal_ino); - - if(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT){ - if((error = check_indirect_eattr(ip, ip->i_di.di_eattr, pass))) - stack; - } else { - if((error = check_leaf_eattr(ip, ip->i_di.di_eattr, - ip->i_di.di_num.no_addr, pass))) - stack; - } - - return error; -} - -/** - * build_metalist - * @ip: - * @mlp: - * - */ - -static int build_metalist(struct fsck_inode *ip, osi_list_t *mlp, - struct metawalk_fxns *pass) -{ - uint32 height = ip->i_di.di_height; - osi_buf_t *bh, *nbh; - osi_list_t *prev_list, *cur_list, *tmp; - int i, head_size; - uint64 *ptr, block; - int err; - - if(get_and_read_buf(ip->i_sbd, ip->i_di.di_num.no_addr, &bh, 0)) { - stack; - return -1; - } - - osi_list_add(&bh->b_list, &mlp[0]); - - /* if(<there are no indirect blocks to check>) */ - if (height < 2) { - return 0; - } - - for (i = 1; i < height; i++){ - prev_list = &mlp[i - 1]; - cur_list = &mlp[i]; - - for (tmp = prev_list->next; tmp != prev_list; tmp = tmp->next){ - bh = osi_list_entry(tmp, osi_buf_t, b_list); - - head_size = (i > 1 ? - sizeof(struct gfs_indirect) : - sizeof(struct gfs_dinode)); - - for (ptr = (uint64 *)(bh->b_data + head_size); - (char *)ptr < (bh->b_data + bh->b_size); - ptr++) { - nbh = NULL; - - if (!*ptr) - continue; - - block = gfs64_to_cpu(*ptr); - - err = pass->check_metalist(ip, block, &nbh, - pass->private); - if(err < 0) { - stack; - goto fail; - } - if(err > 0) { - log_debug("Skipping block %"PRIu64 - "\n", block); - continue; - } - if(!nbh) { - if(get_and_read_buf(ip->i_sbd, block, - &nbh, 0)) { - stack; - goto fail; - } - } - osi_list_add(&nbh->b_list, cur_list); - } - } - } - return 0; - - fail: - for (i = 0; i < GFS_MAX_META_HEIGHT; i++) - { - osi_list_t *list; - list = &mlp[i]; - while (!osi_list_empty(list)) - { - bh = osi_list_entry(list->next, osi_buf_t, b_list); - osi_list_del(&bh->b_list); - relse_buf(ip->i_sbd, bh); - } - } - return -1; -} - -/** - * check_metatree - * @ip: - * @rgd: - * - */ -int check_metatree(struct fsck_inode *ip, struct metawalk_fxns *pass) -{ - osi_list_t metalist[GFS_MAX_META_HEIGHT]; - osi_list_t *list, *tmp; - osi_buf_t *bh; - uint64_t block, *ptr; - uint32_t height = ip->i_di.di_height; - int i, head_size; - int update = 0; - int error = 0; - - if (!height) - goto end; - - - for (i = 0; i < GFS_MAX_META_HEIGHT; i++) - osi_list_init(&metalist[i]); - - /* create metalist for each level */ - if(build_metalist(ip, &metalist[0], pass)){ - stack; - return -1; - } - - /* We don't need to record directory blocks - they will be - * recorded later...i think... */ - if (ip->i_di.di_type == GFS_FILE_DIR) { - log_debug("Directory with height > 0 at %"PRIu64"\n", - ip->i_di.di_num.no_addr); - - } - - /* check data blocks */ - list = &metalist[height - 1]; - - for (tmp = list->next; tmp != list; tmp = tmp->next) - { - bh = osi_list_entry(tmp, osi_buf_t, b_list); - - head_size = (height != 1 ? sizeof(struct gfs_indirect) : sizeof(struct gfs_dinode)); - ptr = (uint64 *)(bh->b_data + head_size); - - for ( ; (char *)ptr < (bh->b_data + bh->b_size); ptr++) - { - if (!*ptr) - continue; - - block = gfs64_to_cpu(*ptr); - - if(pass->check_data && - (pass->check_data(ip, block, pass->private) < 0)) { - stack; - return -1; - } - } - } - - - /* free metalists */ - for (i = 0; i < GFS_MAX_META_HEIGHT; i++) - { - list = &metalist[i]; - while (!osi_list_empty(list)) - { - bh = osi_list_entry(list->next, osi_buf_t, b_list); - osi_list_del(&bh->b_list); - relse_buf(ip->i_sbd, bh); - } - } - -end: - if (ip->i_di.di_type == GFS_FILE_DIR) { - /* check validity of leaf blocks and leaf chains */ - if (ip->i_di.di_flags & GFS_DIF_EXHASH) { - error = check_leaf(ip, &update, pass); - if(error < 0) - return -1; - if(error > 0) - return 1; - } - } - - return 0; -} - - -/* Checks stuffed inode directories */ -int check_linear_dir(struct fsck_inode *ip, osi_buf_t *bh, int *update, - struct metawalk_fxns *pass) -{ - int error = 0; - uint16_t count = 0; - - error = check_entries(ip, bh, 0, DIR_LINEAR, update, &count, pass); - if(error < 0) { - stack; - return -1; - } - - return error; -} - - -int check_dir(struct fsck_sb *sbp, uint64_t block, struct metawalk_fxns *pass) -{ - osi_buf_t *bh; - struct fsck_inode *ip; - int update = 0; - int error = 0; - - if(get_and_read_buf(sbp, block, &bh, 0)){ - log_err("Unable to retrieve block #%"PRIu64"\n", - block); - block_set(sbp->bl, block, meta_inval); - return -1; - } - - if(copyin_inode(sbp, bh, &ip)) { - stack; - relse_buf(sbp, bh); - return -1; - } - - if(ip->i_di.di_flags & GFS_DIF_EXHASH) { - - error = check_leaf(ip, &update, pass); - if(error < 0) { - stack; - free_inode(&ip); - relse_buf(sbp, bh); - return -1; - } - } - else { - error = check_linear_dir(ip, bh, &update, pass); - if(error < 0) { - stack; - free_inode(&ip); - relse_buf(sbp, bh); - return -1; - } - } - - free_inode(&ip); - relse_buf(sbp, bh); - - return error; - -} - - -static int remove_dentry(struct fsck_inode *ip, struct gfs_dirent *dent, - struct gfs_dirent *prev_de, - osi_buf_t *bh, char *filename, int *update, - uint16_t *count, - void *private) -{ - /* the metawalk_fxn's private field must be set to the dentry - * block we want to clear */ - uint64_t *dentryblock = (uint64_t *) private; - struct gfs_dirent dentry, *de; - - memset(&dentry, 0, sizeof(struct gfs_dirent)); - gfs_dirent_in(&dentry, (char *)dent); - de = &dentry; - - if(de->de_inum.no_addr == *dentryblock) { - *update = 1; - if(dirent_del(ip, bh, prev_de, dent)) { - stack; - return -1; - } - } - else { - (*count)++; - *update = 1; - } - - return 0; - -} - -int remove_dentry_from_dir(struct fsck_sb *sbp, uint64_t dir, - uint64_t dentryblock) -{ - struct metawalk_fxns remove_dentry_fxns = {0}; - struct block_query q; - int error; - - log_debug("Removing dentry %"PRIu64" from directory %"PRIu64"\n", - dentryblock, dir); - if(check_range(sbp, dir)) { - log_err("Parent directory out of range\n"); - return 1; - } - remove_dentry_fxns.private = &dentryblock; - remove_dentry_fxns.check_dentry = remove_dentry; - - if(block_check(sbp->bl, dir, &q)) { - stack; - return -1; - } - if(q.block_type != inode_dir) { - log_info("Parent block is not a directory...ignoring\n"); - return 1; - } - /* Need to run check_dir with a private var of dentryblock, - * and fxns that remove that dentry if found */ - error = check_dir(sbp, dir, &remove_dentry_fxns); - - return error; -} - -/* FIXME: These should be merged with the hash routines in inode_hash.c */ -static uint32_t dinode_hash(uint64_t block_no) -{ - unsigned int h; - - h = fsck_hash(&block_no, sizeof (uint64_t)); - h &= FSCK_HASH_MASK; - - return h; -} - -int find_di(struct fsck_sb *sbp, uint64_t childblock, struct dir_info **dip) -{ - osi_list_t *bucket = &sbp->dir_hash[dinode_hash(childblock)]; - osi_list_t *tmp; - struct dir_info *di = NULL; - - osi_list_foreach(tmp, bucket) { - di = osi_list_entry(tmp, struct dir_info, list); - if(di->dinode == childblock) { - *dip = di; - return 0; - } - } - *dip = NULL; - return -1; - -} - -int dinode_hash_insert(osi_list_t *buckets, uint64_t key, struct dir_info *di) -{ - osi_list_t *tmp; - osi_list_t *bucket = &buckets[dinode_hash(key)]; - struct dir_info *dtmp = NULL; - - if(osi_list_empty(bucket)) { - osi_list_add(&di->list, bucket); - return 0; - } - - osi_list_foreach(tmp, bucket) { - dtmp = osi_list_entry(tmp, struct dir_info, list); - if(dtmp->dinode < key) { - continue; - } - else { - osi_list_add_prev(&di->list, tmp); - return 0; - } - } - osi_list_add_prev(&di->list, bucket); - return 0; -} - - -int dinode_hash_remove(osi_list_t *buckets, uint64_t key) -{ - osi_list_t *tmp; - osi_list_t *bucket = &buckets[dinode_hash(key)]; - struct dir_info *dtmp = NULL; - - if(osi_list_empty(bucket)) { - return -1; - } - osi_list_foreach(tmp, bucket) { - dtmp = osi_list_entry(tmp, struct dir_info, list); - if(dtmp->dinode == key) { - osi_list_del(tmp); - return 0; - } - } - return -1; -} diff --git a/gfs/gfs_fsck/metawalk.h b/gfs/gfs_fsck/metawalk.h deleted file mode 100644 index 7d3855e..0000000 --- a/gfs/gfs_fsck/metawalk.h +++ /dev/null @@ -1,77 +0,0 @@ -/***************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _METAWALK_H -#define _METAWALK_H - -#define DIR_LINEAR 1 -#define DIR_EXHASH 2 - -struct metawalk_fxns; - -int check_inode_eattr(struct fsck_inode *ip, struct metawalk_fxns *pass); -int check_metatree(struct fsck_inode *ip, struct metawalk_fxns *pass); -int check_dir(struct fsck_sb *sbp, uint64_t block, struct metawalk_fxns *pass); -int remove_dentry_from_dir(struct fsck_sb *sbp, uint64_t dir, - uint64_t dentryblock); -int find_di(struct fsck_sb *sbp, uint64_t childblock, struct dir_info **dip); -int dinode_hash_insert(osi_list_t *buckets, uint64_t key, struct dir_info *di); -int dinode_hash_remove(osi_list_t *buckets, uint64_t key); - -/* metawalk_fxns: function pointers to check various parts of the fs - * - * The functions should return -1 on fatal errors, 1 if the block - * should be skipped, and 0 on success - * - * private: Data that should be passed to the fxns - * check_leaf: - * check_metalist: - * check_data: - * check_eattr_indir: - * check_eattr_leaf: - * check_dentry: - * check_eattr_entry: - * check_eattr_extentry: - */ -struct metawalk_fxns { - void *private; - int (*check_leaf) (struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private); - int (*check_metalist) (struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private); - int (*check_data) (struct fsck_inode *ip, uint64_t block, - void *private); - int (*check_eattr_indir) (struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private); - int (*check_eattr_leaf) (struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private); - int (*check_dentry) (struct fsck_inode *ip, struct gfs_dirent *de, - struct gfs_dirent *prev, - osi_buf_t *bh, char *filename, int *update, - uint16_t *count, - void *private); - int (*check_eattr_entry) (struct fsck_inode *ip, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private); - int (*check_eattr_extentry) (struct fsck_inode *ip, - uint64_t *ea_data_ptr, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private); -}; - -#endif /* _METAWALK_H */ diff --git a/gfs/gfs_fsck/ondisk.c b/gfs/gfs_fsck/ondisk.c deleted file mode 100644 index fc8b918..0000000 --- a/gfs/gfs_fsck/ondisk.c +++ /dev/null @@ -1,1355 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef HELPER_PROGRAM - -#include "gfs.h" - -#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); - -#else - -#include <stdio.h> -#include <string.h> - -#include "global.h" -#include "linux_endian.h" -#include "ondisk.h" - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); - -#endif /* !HELPER_PROGRAM */ - -#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} -#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} -#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} -#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} -#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} -#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} -#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} -#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} - -#define pa(struct, member, count) print_array(#member, struct->member, count, console); - -/** - * print_array - Print out an array of bytes - * @title: what to print before the array - * @buf: the array - * @count: the number of bytes - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -static void -print_array(char *title, char *buf, int count, int console) -{ - int x; - - printk(" %s =\n", title); - for (x = 0; x < count; x++) { - printk("%.2X ", (unsigned char) buf[x]); - if (x % 16 == 15) - printk("\n"); - } - if (x % 16) - printk("\n"); - -} - -/** - * gfs_inum_in - Read in an inode number - * @no: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_inum_in(struct gfs_inum *no, char *buf) -{ - struct gfs_inum *str = (struct gfs_inum *) buf; - - CPIN_64(no, str, no_formal_ino); - CPIN_64(no, str, no_addr); - -} - -/** - * gfs_inum_out - Write out an inode number - * @no: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_inum_out(struct gfs_inum *no, char *buf) -{ - struct gfs_inum *str = (struct gfs_inum *) buf; - - CPOUT_64(no, str, no_formal_ino); - CPOUT_64(no, str, no_addr); - -} - -/** - * gfs_inum_print - Print out a inode number - * @no: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_inum_print(struct gfs_inum *no, int console) -{ - - pv(no, no_formal_ino, "%" PRIu64); - pv(no, no_addr, "%" PRIu64); - -} - -/** - * gfs_meta_header_in - Read in a metadata header - * @mh: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_meta_header_in(struct gfs_meta_header *mh, char *buf) -{ - struct gfs_meta_header *str = (struct gfs_meta_header *) buf; - - CPIN_32(mh, str, mh_magic); - CPIN_32(mh, str, mh_type); - CPIN_64(mh, str, mh_generation); - CPIN_32(mh, str, mh_format); - CPIN_32(mh, str, mh_incarn); - -} - -/** - * gfs_meta_header_in - Write out a metadata header - * @mh: the cpu-order structure - * @buf: the disk-order buffer - * - * Don't ever change the generation number in this routine. - * It's done manually in increment_generation(). - */ - -void -gfs_meta_header_out(struct gfs_meta_header *mh, char *buf) -{ - struct gfs_meta_header *str = (struct gfs_meta_header *) buf; - - CPOUT_32(mh, str, mh_magic); - CPOUT_32(mh, str, mh_type); - /*CPOUT_64(mh, str, mh_generation); */ - CPOUT_32(mh, str, mh_format); - CPOUT_32(mh, str, mh_incarn); - -} - -/** - * gfs_meta_header_print - Print out a metadata header - * @mh: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_meta_header_print(struct gfs_meta_header *mh, int console) -{ - - pv(mh, mh_magic, "0x%.8X"); - pv(mh, mh_type, "%u"); - pv(mh, mh_generation, "%" PRIu64); - pv(mh, mh_format, "%u"); - pv(mh, mh_incarn, "%u"); - -} - -/** - * gfs_sb_in - Read in a superblock - * @sb: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_sb_in(struct gfs_sb *sb, char *buf) -{ - struct gfs_sb *str = (struct gfs_sb *) buf; - - gfs_meta_header_in(&sb->sb_header, buf); - - CPIN_32(sb, str, sb_fs_format); - CPIN_32(sb, str, sb_multihost_format); - CPIN_32(sb, str, sb_flags); - - CPIN_32(sb, str, sb_bsize); - CPIN_32(sb, str, sb_bsize_shift); - CPIN_32(sb, str, sb_seg_size); - - gfs_inum_in(&sb->sb_jindex_di, (char *) &str->sb_jindex_di); - gfs_inum_in(&sb->sb_rindex_di, (char *) &str->sb_rindex_di); - gfs_inum_in(&sb->sb_root_di, (char *) &str->sb_root_di); - - CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); - CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); - - gfs_inum_in(&sb->sb_quota_di, (char *) &str->sb_quota_di); - gfs_inum_in(&sb->sb_license_di, (char *) &str->sb_license_di); - - CPIN_08(sb, str, sb_reserved, 96); - -} - -/** - * gfs_sb_out - Write out a superblock - * @sb: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_sb_out(struct gfs_sb *sb, char *buf) -{ - struct gfs_sb *str = (struct gfs_sb *) buf; - - gfs_meta_header_out(&sb->sb_header, buf); - - CPOUT_32(sb, str, sb_fs_format); - CPOUT_32(sb, str, sb_multihost_format); - CPOUT_32(sb, str, sb_flags); - - CPOUT_32(sb, str, sb_bsize); - CPOUT_32(sb, str, sb_bsize_shift); - CPOUT_32(sb, str, sb_seg_size); - - gfs_inum_out(&sb->sb_jindex_di, (char *) &str->sb_jindex_di); - gfs_inum_out(&sb->sb_rindex_di, (char *) &str->sb_rindex_di); - gfs_inum_out(&sb->sb_root_di, (char *) &str->sb_root_di); - - CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); - CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); - - gfs_inum_out(&sb->sb_quota_di, (char *) &str->sb_quota_di); - gfs_inum_out(&sb->sb_license_di, (char *) &str->sb_license_di); - - CPOUT_08(sb, str, sb_reserved, 96); - -} - -/** - * gfs_sb_print - Print out a superblock - * @sb: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_sb_print(struct gfs_sb *sb, int console) -{ - - gfs_meta_header_print(&sb->sb_header, console); - - pv(sb, sb_fs_format, "%u"); - pv(sb, sb_multihost_format, "%u"); - pv(sb, sb_flags, "%u"); - - pv(sb, sb_bsize, "%u"); - pv(sb, sb_bsize_shift, "%u"); - pv(sb, sb_seg_size, "%u"); - - gfs_inum_print(&sb->sb_jindex_di, console); - gfs_inum_print(&sb->sb_rindex_di, console); - gfs_inum_print(&sb->sb_root_di, console); - - pv(sb, sb_lockproto, "%s"); - pv(sb, sb_locktable, "%s"); - - gfs_inum_print(&sb->sb_quota_di, console); - gfs_inum_print(&sb->sb_license_di, console); - - pa(sb, sb_reserved, 96); - -} - -/** - * gfs_jindex_in - Read in a journal index structure - * @jindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_jindex_in(struct gfs_jindex *jindex, char *buf) -{ - struct gfs_jindex *str = (struct gfs_jindex *) buf; - - CPIN_64(jindex, str, ji_addr); - CPIN_32(jindex, str, ji_nsegment); - CPIN_32(jindex, str, ji_pad); - - CPIN_08(jindex, str, ji_reserved, 64); - -} - -/** - * gfs_jindex_out - Write out a journal index structure - * @jindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_jindex_out(struct gfs_jindex *jindex, char *buf) -{ - struct gfs_jindex *str = (struct gfs_jindex *) buf; - - CPOUT_64(jindex, str, ji_addr); - CPOUT_32(jindex, str, ji_nsegment); - CPOUT_32(jindex, str, ji_pad); - - CPOUT_08(jindex, str, ji_reserved, 64); - -} - -/** - * gfs_jindex_print - Print out a journal index structure - * @ji: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_jindex_print(struct gfs_jindex *ji, int console) -{ - - pv(ji, ji_addr, "%" PRIu64); - pv(ji, ji_nsegment, "%u"); - pv(ji, ji_pad, "%u"); - - pa(ji, ji_reserved, 64); - -} - -/** - * gfs_rindex_in - Read in a resource index structure - * @rindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rindex_in(struct gfs_rindex *rindex, char *buf) -{ - struct gfs_rindex *str = (struct gfs_rindex *) buf; - - CPIN_64(rindex, str, ri_addr); - CPIN_32(rindex, str, ri_length); - CPIN_32(rindex, str, ri_pad); - - CPIN_64(rindex, str, ri_data1); - CPIN_32(rindex, str, ri_data); - - CPIN_32(rindex, str, ri_bitbytes); - - CPIN_08(rindex, str, ri_reserved, 64); - -} - -/** - * gfs_rindex_out - Write out a resource index structure - * @rindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rindex_out(struct gfs_rindex *rindex, char *buf) -{ - struct gfs_rindex *str = (struct gfs_rindex *) buf; - - CPOUT_64(rindex, str, ri_addr); - CPOUT_32(rindex, str, ri_length); - CPOUT_32(rindex, str, ri_pad); - - CPOUT_64(rindex, str, ri_data1); - CPOUT_32(rindex, str, ri_data); - - CPOUT_32(rindex, str, ri_bitbytes); - - CPOUT_08(rindex, str, ri_reserved, 64); - -} - -/** - * gfs_rindex_print - Print out a resource index structure - * @ri: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_rindex_print(struct gfs_rindex *ri, int console) -{ - - pv(ri, ri_addr, "%" PRIu64); - pv(ri, ri_length, "%u"); - pv(ri, ri_pad, "%u"); - - pv(ri, ri_data1, "%" PRIu64); - pv(ri, ri_data, "%u"); - - pv(ri, ri_bitbytes, "%u"); - - pa(ri, ri_reserved, 64); - -} - -/** - * gfs_rgrp_in - Read in a resource group header - * @rgrp: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf) -{ - struct gfs_rgrp *str = (struct gfs_rgrp *) buf; - - gfs_meta_header_in(&rgrp->rg_header, buf); - - CPIN_32(rgrp, str, rg_flags); - - CPIN_32(rgrp, str, rg_free); - - CPIN_32(rgrp, str, rg_useddi); - CPIN_32(rgrp, str, rg_freedi); - gfs_inum_in(&rgrp->rg_freedi_list, (char *) &str->rg_freedi_list); - - CPIN_32(rgrp, str, rg_usedmeta); - CPIN_32(rgrp, str, rg_freemeta); - - CPIN_08(rgrp, str, rg_reserved, 64); - -} - -/** - * gfs_rgrp_out - Write out a resource group header - * @rgrp: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf) -{ - struct gfs_rgrp *str = (struct gfs_rgrp *) buf; - - gfs_meta_header_out(&rgrp->rg_header, buf); - - CPOUT_32(rgrp, str, rg_flags); - - CPOUT_32(rgrp, str, rg_free); - - CPOUT_32(rgrp, str, rg_useddi); - CPOUT_32(rgrp, str, rg_freedi); - gfs_inum_out(&rgrp->rg_freedi_list, (char *) &str->rg_freedi_list); - - CPOUT_32(rgrp, str, rg_usedmeta); - CPOUT_32(rgrp, str, rg_freemeta); - - CPOUT_08(rgrp, str, rg_reserved, 64); - -} - -/** - * gfs_rgrp_print - Print out a resource group header - * @rg: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_rgrp_print(struct gfs_rgrp *rg, int console) -{ - - gfs_meta_header_print(&rg->rg_header, console); - - pv(rg, rg_flags, "%u"); - - pv(rg, rg_free, "%u"); - - pv(rg, rg_useddi, "%u"); - pv(rg, rg_freedi, "%u"); - gfs_inum_print(&rg->rg_freedi_list, console); - - pv(rg, rg_usedmeta, "%u"); - pv(rg, rg_freemeta, "%u"); - - pa(rg, rg_reserved, 64); - -} - -/** - * gfs_quota_in - Read in a quota structures - * @quota: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_in(struct gfs_quota *quota, char *buf) -{ - struct gfs_quota *str = (struct gfs_quota *) buf; - - CPIN_64(quota, str, qu_limit); - CPIN_64(quota, str, qu_warn); - CPIN_64(quota, str, qu_value); - - CPIN_08(quota, str, qu_reserved, 64); - -} - -/** - * gfs_quota_out - Write out a quota structure - * @quota: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_out(struct gfs_quota *quota, char *buf) -{ - struct gfs_quota *str = (struct gfs_quota *) buf; - - CPOUT_64(quota, str, qu_limit); - CPOUT_64(quota, str, qu_warn); - CPOUT_64(quota, str, qu_value); - - CPOUT_08(quota, str, qu_reserved, 64); - -} - -/** - * gfs_quota_print - Print out a quota structure - * @quota: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_quota_print(struct gfs_quota *quota, int console) -{ - - pv(quota, qu_limit, "%" PRIu64); - pv(quota, qu_warn, "%" PRIu64); - pv(quota, qu_value, "%" PRId64); - - pa(quota, qu_reserved, 64); - -} - -/** - * gfs_dinode_in - Read in a dinode - * @dinode: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dinode_in(struct gfs_dinode *dinode, char *buf) -{ - struct gfs_dinode *str = (struct gfs_dinode *) buf; - - gfs_meta_header_in(&dinode->di_header, buf); - - gfs_inum_in(&dinode->di_num, (char *) &str->di_num); - - CPIN_32(dinode, str, di_mode); - CPIN_32(dinode, str, di_uid); - CPIN_32(dinode, str, di_gid); - CPIN_32(dinode, str, di_nlink); - CPIN_64(dinode, str, di_size); - CPIN_64(dinode, str, di_blocks); - CPIN_64(dinode, str, di_atime); - CPIN_64(dinode, str, di_mtime); - CPIN_64(dinode, str, di_ctime); - CPIN_32(dinode, str, di_major); - CPIN_32(dinode, str, di_minor); - - CPIN_64(dinode, str, di_rgrp); - CPIN_64(dinode, str, di_goal_rgrp); - CPIN_32(dinode, str, di_goal_dblk); - CPIN_32(dinode, str, di_goal_mblk); - CPIN_32(dinode, str, di_flags); - CPIN_32(dinode, str, di_payload_format); - CPIN_16(dinode, str, di_type); - CPIN_16(dinode, str, di_height); - CPIN_32(dinode, str, di_incarn); - CPIN_16(dinode, str, di_pad); - - CPIN_16(dinode, str, di_depth); - CPIN_32(dinode, str, di_entries); - - gfs_inum_in(&dinode->di_next_unused, (char *) &str->di_next_unused); - - CPIN_64(dinode, str, di_eattr); - - CPIN_08(dinode, str, di_reserved, 56); - -} - -/** - * gfs_dinode_out - Write out a dinode - * @dinode: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dinode_out(struct gfs_dinode *dinode, char *buf) -{ - struct gfs_dinode *str = (struct gfs_dinode *) buf; - - gfs_meta_header_out(&dinode->di_header, buf); - - gfs_inum_out(&dinode->di_num, (char *) &str->di_num); - - CPOUT_32(dinode, str, di_mode); - CPOUT_32(dinode, str, di_uid); - CPOUT_32(dinode, str, di_gid); - CPOUT_32(dinode, str, di_nlink); - CPOUT_64(dinode, str, di_size); - CPOUT_64(dinode, str, di_blocks); - CPOUT_64(dinode, str, di_atime); - CPOUT_64(dinode, str, di_mtime); - CPOUT_64(dinode, str, di_ctime); - CPOUT_32(dinode, str, di_major); - CPOUT_32(dinode, str, di_minor); - - CPOUT_64(dinode, str, di_rgrp); - CPOUT_64(dinode, str, di_goal_rgrp); - CPOUT_32(dinode, str, di_goal_dblk); - CPOUT_32(dinode, str, di_goal_mblk); - CPOUT_32(dinode, str, di_flags); - CPOUT_32(dinode, str, di_payload_format); - CPOUT_16(dinode, str, di_type); - CPOUT_16(dinode, str, di_height); - CPOUT_32(dinode, str, di_incarn); - CPOUT_16(dinode, str, di_pad); - - CPOUT_16(dinode, str, di_depth); - CPOUT_32(dinode, str, di_entries); - - gfs_inum_out(&dinode->di_next_unused, (char *) &str->di_next_unused); - - CPOUT_64(dinode, str, di_eattr); - - CPOUT_08(dinode, str, di_reserved, 56); - -} - -/** - * gfs_dinode_print - Print out a dinode - * @di: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_dinode_print(struct gfs_dinode *di, int console) -{ - - gfs_meta_header_print(&di->di_header, console); - - gfs_inum_print(&di->di_num, console); - - pv(di, di_mode, "0%o"); - pv(di, di_uid, "%u"); - pv(di, di_gid, "%u"); - pv(di, di_nlink, "%u"); - pv(di, di_size, "%" PRIu64); - pv(di, di_blocks, "%" PRIu64); - pv(di, di_atime, "%" PRId64); - pv(di, di_mtime, "%" PRId64); - pv(di, di_ctime, "%" PRId64); - pv(di, di_major, "%u"); - pv(di, di_minor, "%u"); - - pv(di, di_rgrp, "%" PRIu64); - pv(di, di_goal_rgrp, "%" PRIu64); - pv(di, di_goal_dblk, "%u"); - pv(di, di_goal_mblk, "%u"); - pv(di, di_flags, "0x%.8X"); - pv(di, di_payload_format, "%u"); - pv(di, di_type, "%u"); - pv(di, di_height, "%u"); - pv(di, di_incarn, "%u"); - pv(di, di_pad, "%u"); - - pv(di, di_depth, "%u"); - pv(di, di_entries, "%u"); - - gfs_inum_print(&di->di_next_unused, console); - - pv(di, di_eattr, "%" PRIu64); - - pa(di, di_reserved, 56); - -} - -/** - * gfs_indirect_in - copy in the header of an indirect block - * @indirect: the in memory copy - * @buf: the buffer copy - * - */ - -void -gfs_indirect_in(struct gfs_indirect *indirect, char *buf) -{ - struct gfs_indirect *str = (struct gfs_indirect *) buf; - - gfs_meta_header_in(&indirect->in_header, buf); - - CPIN_08(indirect, str, in_reserved, 64); - -} - -/** - * gfs_indirect_out - copy out the header of an indirect block - * @indirect: the in memory copy - * @buf: the buffer copy - * - */ - -void -gfs_indirect_out(struct gfs_indirect *indirect, char *buf) -{ - struct gfs_indirect *str = (struct gfs_indirect *) buf; - - gfs_meta_header_out(&indirect->in_header, buf); - - CPOUT_08(indirect, str, in_reserved, 64); - -} - -/** - * gfs_indirect_print - Print out a indirect block header - * @indirect: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_indirect_print(struct gfs_indirect *indirect, int console) -{ - - gfs_meta_header_print(&indirect->in_header, console); - - pa(indirect, in_reserved, 64); - -} - -/** - * gfs_dirent_in - Read in a directory entry - * @dirent: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dirent_in(struct gfs_dirent *dirent, char *buf) -{ - struct gfs_dirent *str = (struct gfs_dirent *) buf; - - gfs_inum_in(&dirent->de_inum, (char *) &str->de_inum); - CPIN_32(dirent, str, de_hash); - CPIN_16(dirent, str, de_rec_len); - CPIN_16(dirent, str, de_name_len); - CPIN_16(dirent, str, de_type); - - CPIN_08(dirent, str, de_reserved, 14); - -} - -/** - * gfs_dirent_out - Write out a directory entry - * @dirent: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dirent_out(struct gfs_dirent *dirent, char *buf) -{ - struct gfs_dirent *str = (struct gfs_dirent *) buf; - - gfs_inum_out(&dirent->de_inum, (char *) &str->de_inum); - CPOUT_32(dirent, str, de_hash); - CPOUT_16(dirent, str, de_rec_len); - CPOUT_16(dirent, str, de_name_len); - CPOUT_16(dirent, str, de_type); - - CPOUT_08(dirent, str, de_reserved, 14); - -} - -/** - * gfs_dirent_print - Print out a directory entry - * @de: the cpu-order buffer - * @name: the filename - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_dirent_print(struct gfs_dirent *de, char *name, int console) -{ - char buf[GFS_FNAMESIZE + 1]; - - gfs_inum_print(&de->de_inum, console); - pv(de, de_hash, "0x%.8X"); - pv(de, de_rec_len, "%u"); - pv(de, de_name_len, "%u"); - pv(de, de_type, "%u"); - - pa(de, de_reserved, 14); - - memset(buf, 0, GFS_FNAMESIZE + 1); - memcpy(buf, name, de->de_name_len); - printk(" name = %s\n", buf); - -} - -/** - * gfs_leaf_in - Read in a directory leaf header - * @leaf: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_leaf_in(struct gfs_leaf *leaf, char *buf) -{ - struct gfs_leaf *str = (struct gfs_leaf *) buf; - - gfs_meta_header_in(&leaf->lf_header, buf); - - CPIN_16(leaf, str, lf_depth); - CPIN_16(leaf, str, lf_entries); - CPIN_32(leaf, str, lf_dirent_format); - CPIN_64(leaf, str, lf_next); - - CPIN_08(leaf, str, lf_reserved, 64); - -} - -/** - * gfs_leaf_out - Write out a directory leaf header - * @leaf: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_leaf_out(struct gfs_leaf *leaf, char *buf) -{ - struct gfs_leaf *str = (struct gfs_leaf *) buf; - - gfs_meta_header_out(&leaf->lf_header, buf); - - CPOUT_16(leaf, str, lf_depth); - CPOUT_16(leaf, str, lf_entries); - CPOUT_32(leaf, str, lf_dirent_format); - CPOUT_64(leaf, str, lf_next); - - CPOUT_08(leaf, str, lf_reserved, 64); - -} - -/** - * gfs_leaf_print - Print out a directory leaf header - * @lf: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_leaf_print(struct gfs_leaf *lf, int console) -{ - - gfs_meta_header_print(&lf->lf_header, console); - - pv(lf, lf_depth, "%u"); - pv(lf, lf_entries, "%u"); - pv(lf, lf_dirent_format, "%u"); - pv(lf, lf_next, "%" PRIu64); - - pa(lf, lf_reserved, 64); - -} - -/** - * gfs_log_header_in - Read in a log header - * @head: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_log_header_in(struct gfs_log_header *head, char *buf) -{ - struct gfs_log_header *str = (struct gfs_log_header *) buf; - - gfs_meta_header_in(&head->lh_header, buf); - - CPIN_32(head, str, lh_flags); - CPIN_32(head, str, lh_pad); - - CPIN_64(head, str, lh_first); - CPIN_64(head, str, lh_sequence); - - CPIN_64(head, str, lh_tail); - CPIN_64(head, str, lh_last_dump); - - CPIN_08(head, str, lh_reserved, 64); - -} - -/** - * gfs_log_header_out - Write out a log header - * @head: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_log_header_out(struct gfs_log_header *head, char *buf) -{ - struct gfs_log_header *str = (struct gfs_log_header *) buf; - - gfs_meta_header_out(&head->lh_header, buf); - - CPOUT_32(head, str, lh_flags); - CPOUT_32(head, str, lh_pad); - - CPOUT_64(head, str, lh_first); - CPOUT_64(head, str, lh_sequence); - - CPOUT_64(head, str, lh_tail); - CPOUT_64(head, str, lh_last_dump); - - CPOUT_08(head, str, lh_reserved, 64); - -} - -/** - * gfs_log_header_print - Print out a log header - * @head: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_log_header_print(struct gfs_log_header *lh, int console) -{ - - gfs_meta_header_print(&lh->lh_header, console); - - pv(lh, lh_flags, "0x%.8X"); - pv(lh, lh_pad, "%u"); - - pv(lh, lh_first, "%" PRIu64); - pv(lh, lh_sequence, "%" PRIu64); - - pv(lh, lh_tail, "%" PRIu64); - pv(lh, lh_last_dump, "%" PRIu64); - - pa(lh, lh_reserved, 64); - -} - -/** - * gfs_desc_in - Read in a log descriptor - * @desc: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_desc_in(struct gfs_log_descriptor *desc, char *buf) -{ - struct gfs_log_descriptor *str = (struct gfs_log_descriptor *) buf; - - gfs_meta_header_in(&desc->ld_header, buf); - - CPIN_32(desc, str, ld_type); - CPIN_32(desc, str, ld_length); - CPIN_32(desc, str, ld_data1); - CPIN_32(desc, str, ld_data2); - - CPIN_08(desc, str, ld_reserved, 64); - -} - -/** - * gfs_desc_out - Write out a log descriptor - * @desc: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_desc_out(struct gfs_log_descriptor *desc, char *buf) -{ - struct gfs_log_descriptor *str = (struct gfs_log_descriptor *) buf; - - gfs_meta_header_out(&desc->ld_header, buf); - - CPOUT_32(desc, str, ld_type); - CPOUT_32(desc, str, ld_length); - CPOUT_32(desc, str, ld_data1); - CPOUT_32(desc, str, ld_data2); - - CPOUT_08(desc, str, ld_reserved, 64); - -} - -/** - * gfs_desc_print - Print out a log descriptor - * @ld: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_desc_print(struct gfs_log_descriptor *ld, int console) -{ - - gfs_meta_header_print(&ld->ld_header, console); - - pv(ld, ld_type, "%u"); - pv(ld, ld_length, "%u"); - pv(ld, ld_data1, "%u"); - pv(ld, ld_data2, "%u"); - - pa(ld, ld_reserved, 64); - -} - -/** - * gfs_block_tag_in - Read in a block tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_block_tag_in(struct gfs_block_tag *tag, char *buf) -{ - struct gfs_block_tag *str = (struct gfs_block_tag *) buf; - - CPIN_64(tag, str, bt_blkno); - CPIN_32(tag, str, bt_flags); - CPIN_32(tag, str, bt_pad); - -} - -/** - * gfs_block_tag_out - Write out a block tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_block_tag_out(struct gfs_block_tag *tag, char *buf) -{ - struct gfs_block_tag *str = (struct gfs_block_tag *) buf; - - CPOUT_64(tag, str, bt_blkno); - CPOUT_32(tag, str, bt_flags); - CPOUT_32(tag, str, bt_pad); - -} - -/** - * gfs_block_tag_print - Print out a block tag - * @tag: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_block_tag_print(struct gfs_block_tag *tag, int console) -{ - - pv(tag, bt_blkno, "%" PRIu64); - pv(tag, bt_flags, "%u"); - pv(tag, bt_pad, "%u"); - -} - -/** - * gfs_quota_tag_in - Read in a quota tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf) -{ - struct gfs_quota_tag *str = (struct gfs_quota_tag *) buf; - - CPIN_64(tag, str, qt_change); - CPIN_32(tag, str, qt_flags); - CPIN_32(tag, str, qt_id); - -} - -/** - * gfs_quota_tag_out - Write out a quota tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf) -{ - struct gfs_quota_tag *str = (struct gfs_quota_tag *) buf; - - CPOUT_64(tag, str, qt_change); - CPOUT_32(tag, str, qt_flags); - CPOUT_32(tag, str, qt_id); - -} - -/** - * gfs_quota_tag_print - Print out a quota tag - * @tag: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_quota_tag_print(struct gfs_quota_tag *tag, int console) -{ - - pv(tag, qt_change, "%" PRId64); - pv(tag, qt_flags, "0x%.8X"); - pv(tag, qt_id, "%u"); - -} - -/** - * gfs_ea_header_in - Read in a Extended Attribute header - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_ea_header_in(struct gfs_ea_header *ea, char *buf) -{ - struct gfs_ea_header *str = (struct gfs_ea_header *) buf; - - CPIN_32(ea, str, ea_rec_len); - CPIN_32(ea, str, ea_data_len); - ea->ea_name_len = str->ea_name_len; - ea->ea_type = str->ea_type; - ea->ea_flags = str->ea_flags; - ea->ea_num_ptrs = str->ea_num_ptrs; - CPIN_32(ea, str, ea_pad); - -} - -/** - * gfs_ea_header_out - Write out a Extended Attribute header - * @ea: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_ea_header_out(struct gfs_ea_header *ea, char *buf) -{ - struct gfs_ea_header *str = (struct gfs_ea_header *) buf; - - CPOUT_32(ea, str, ea_rec_len); - CPOUT_32(ea, str, ea_data_len); - str->ea_name_len = ea->ea_name_len; - str->ea_type = ea->ea_type; - str->ea_flags = ea->ea_flags; - str->ea_num_ptrs = ea->ea_num_ptrs; - CPOUT_32(ea, str, ea_pad); - -} - -/** - * gfs_ea_header_printt - Print out a Extended Attribute header - * @ea: the cpu-order buffer - * @console - TRUE if this should be printed to the console, - * FALSE if it should be just printed to the incore debug - * buffer - * - */ - -void -gfs_ea_header_print(struct gfs_ea_header *ea, int console) -{ - - pv(ea, ea_rec_len, "%u"); - pv(ea, ea_data_len, "%u"); - pv(ea, ea_name_len, "%u"); - pv(ea, ea_type, "%u"); - pv(ea, ea_flags, "%u"); - pv(ea, ea_num_ptrs, "%u"); - pv(ea, ea_pad, "%u"); - -} - -static const uint32_t crc_32_tab[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, - 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, - 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, - 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, - 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, - 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, - 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, - 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, - 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, - 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, - 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, - 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, - 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, - 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, - 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, - 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, - 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, - 0x5a05df1b, 0x2d02ef8d -}; - -/** - * gfs_dir_hash - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * Take some data and convert it to a 32-bit hash. - * - * The hash function is a 32-bit CRC of the data. The algorithm uses - * the crc_32_tab table above. - * - * This may not be the fastest hash function, but it does a fair bit better - * at providing uniform results than the others I've looked at. That's - * really important for efficient directories. - * - * Returns: the hash - */ - -uint32_t -gfs_dir_hash(const char *data, int len) -{ - uint32_t hash = 0xFFFFFFFF; - - for (; len--; data++) - hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); - - hash = ~hash; - - return hash; -} diff --git a/gfs/gfs_fsck/ondisk.h b/gfs/gfs_fsck/ondisk.h deleted file mode 100644 index 2859887..0000000 --- a/gfs/gfs_fsck/ondisk.h +++ /dev/null @@ -1,2058 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* - * On-disk structures. - * - * THE BIG PICTURE of on-disk layout: - * - * GFS filesystem code views the entire filesystem, including journals, as - * one contiguous group of blocks on one (perhaps virtual) storage device. - * The filesystem space is shared, not distributed; each node in the cluster - * must see the entire filesystem space. - * - * If the filesystem is spread across multiple physical storage devices, - * volume management (device mapping) must be used to present the fileystem - * space to GFS as one (virtual) device, with contiguous blocks. - * - * The superblock contains basic information about the filesytem, and appears - * at a location 64 KBytes into the filesystem. The first 64 KBytes of the - * filesystem are empty, providing a safety buffer against wayward volume - * management software (that sometimes write data into the first few bytes of - * a device) or administrators. - * - * After the superblock, the rest of the filesystem is divided into multiple - * Resource Groups and several journals. - * - * The Resource Groups (RGs or rgrps) contain the allocatable blocks that are - * used for storing files, directories, etc., and all of the associated - * metadata. Each RG has its own set of block allocation statistics (within - * the RG header), a number of blocks containing the block allocation bitmap, - * and a large number of allocatable blocks for file data and metadata. - * Multiple RGs allow multiple nodes to simultaneously allocate blocks from the - * filesystem (using different RGs), enhancing parallel access. RG size and - * number of RGs are determined by gfs_mkfs when creating the filesystem. - * An administrator can specify RG size (see man gfs_mkfs). - * - * The journals contain temporary copies of metadata blocks, along with - * other data, that allow GFS to recover the filesystem to a consistent state - * (at least as far as metadata is concerned) if a node fails in the midst - * of performing a write transaction. There must be one journal for each node - * in the cluster. Since access to the entire filesystem space is shared, - * if a node crashes, another node will be able to read the crashed node's - * journal, and perform recovery. - * - * Currently, gfs_mkfs places the journals right in the middle of a freshly - * created filesystem space, between 2 large groups of RGs. From a filesystem - * layout perspective, this placement is not a requirement; the journals - * could be placed anywhere within the filesystem space. - * - * New Resource Groups and Journals may be added to the filesystem after the - * filesystem has been created, if the filesystem's (virtual) device is made - * larger. See man gfs_grow and gfs_jadd. - * - * A few special hidden inodes are contained in a GFS filesystem. They do - * not appear in any directories; instead, the superblock points to them - * using block numbers for their location. The special inodes are: - * - * Root inode: Root directory of the filesystem - * Resource Group Index: A file containing block numbers and sizes of all RGs - * Journal Index: A file containing block numbers and sizes of all journals - * Quota: A file containing all quota information for the filesystem - * License: A file containing license information - * - * Note that there is NOTHING RELATED TO INTER-NODE LOCK MANAGEMENT ON-DISK. - * Locking is handled completely off-disk, typically via LAN. - * - * NOTE: - * If you add 8 byte fields to these structures, they must be 8 byte - * aligned. 4 byte field must be 4 byte aligned, etc... - * - * All structures must be a multiple of 8 bytes long. - * - * GRIPES: - * We should have forgetten about supporting 512B FS block sizes - * and made the di_reserved field in the struct gfs_dinode structure - * much bigger. - * - * de_rec_len in struct gfs_dirent should really have been a 32-bit value - * as it now limits us to a 64k FS block size (with the current code - * in dir.c). - */ - -#ifndef __GFS_ONDISK_DOT_H__ -#define __GFS_ONDISK_DOT_H__ - -#define GFS_MAGIC (0x01161970) /* for all on-disk headers */ -#define GFS_BASIC_BLOCK (512) /* "basic block" = "sector" = 512B */ -#define GFS_BASIC_BLOCK_SHIFT (9) - -/* Controls how much data can be logged in-core before dumping log to disk */ - -#define GFS_DUMPS_PER_LOG (4) /* 1/4 of on-disk journal size*/ - -/* Lock numbers of the LM_TYPE_NONDISK type. These protect certain - * cluster-wide operations (rather than on-disk entities). - * Currently, the LIVE lock is not used for any real purpose. */ - -#define GFS_MOUNT_LOCK (0) /* only one node can Mount at a time */ -#define GFS_LIVE_LOCK (1) /* shared by all mounted nodes */ -#define GFS_TRANS_LOCK (2) /* Transaction, protects jrnl recovery */ -#define GFS_RENAME_LOCK (3) /* only one node can Rename at a time */ - -/* On-disk format (version) numbers for various metadata types, - * used in gfs_meta_header */ - -#define GFS_FORMAT_SB (100) /* Super-Block */ -#define GFS_FORMAT_RG (200) /* Resource Group Header */ -#define GFS_FORMAT_RB (300) /* Resource Group Block Alloc BitBlock */ -#define GFS_FORMAT_DI (400) /* "Disk" inode (dinode) */ -#define GFS_FORMAT_IN (500) /* Indirect dinode block list */ -#define GFS_FORMAT_LF (600) /* Leaf dinode block list */ -#define GFS_FORMAT_JD (700) /* Journal Data */ -#define GFS_FORMAT_LH (800) /* Log Header */ -#define GFS_FORMAT_LD (900) /* Log Descriptor */ -/* These don't have actual struct gfs_meta_header structures to go with them */ -#define GFS_FORMAT_JI (1000) /* Journal Index */ -#define GFS_FORMAT_RI (1100) /* Resource Group Index */ -#define GFS_FORMAT_DE (1200) /* Directory Entry */ -#define GFS_FORMAT_QU (1500) /* Quota */ -#define GFS_FORMAT_EA (1600) /* Extended Attribute */ -#define GFS_FORMAT_ED (1700) /* Extended Attribute data */ -/* These version #s are embedded in the superblock */ -#define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */ -#define GFS_FORMAT_MULTI (1401) /* Multi-Host */ - -/* - * An on-disk inode number - * Initially, the on-disk block address of the inode block is assigned as the - * formal (permanent) ID as well. Block address can change (to move inode - * on-disk), but formal ID must stay unchanged once assigned. - */ - -#define gfs_inum_equal(ino1, ino2) \ -(((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \ - ((ino1)->no_addr == (ino2)->no_addr)) - -struct gfs_inum { - uint64_t no_formal_ino; /* inode identifier */ - uint64_t no_addr; /* block # of dinode block */ -}; - -/* - * Generic metadata head structure - * - * Every inplace buffer logged in the journal must start - * with a struct gfs_meta_header. - * - * In addition to telling what kind of metadata is in the block, - * the metaheader contains the important generation and incarnation - * numbers. - * - * The generation number is used during journal recovery to determine - * whether an in-place block on-disk is older than an on-disk journaled copy - * of the block. If so, GFS overwrites the in-place block with the journaled - * version of the block. - * - * A meta block's generation number must increment monotonically across the - * cluster, each time new contents are committed to the block. This means - * that whenever GFS allocates a pre-existing metadata block, GFS must read - * that block from disk (in case another node has incremented it). It also - * means that GFS must sync the block (with incremented generation number) - * to disk (both log and in-place blocks), not only after changing contents - * of the block, but also after de-allocating the block (GFS can't just throw - * away incore metadata for a file that it's just erased). - * - * The incarnation number is used only for on-disk (d)inodes. GFS increments - * it each time it de-allocates a dinode block (i.e. each time the dinode - * loses its identity with a particular file, directory, etc.). When the - * dinode is later allocated (i.e. to be identified with a new file, etc.), - * GFS copies the incarnation number into the VFS inode's i_generation member. - * If GFS is used as the backing store for an NFS server, GFS uses this - * i_generation number as part of the NFS filehandle, which differentiates - * it from the previous identity of the dinode, and helps protect against - * filesystem corruption that could happen with the use of outdated, - * invalid, or malicious filehandles. See ops_export.c. - * - * GFS caches de-allocated meta-headers, to minimize disk reads. - * See struct gfs_meta_header_cache. - */ - -#define GFS_METATYPE_NONE (0) -#define GFS_METATYPE_SB (1) /* Super-Block */ -#define GFS_METATYPE_RG (2) /* Resource Group Header */ -#define GFS_METATYPE_RB (3) /* Resource Group Block Alloc BitBlock */ -#define GFS_METATYPE_DI (4) /* "Disk" inode (dinode) */ -#define GFS_METATYPE_IN (5) /* Indirect dinode block list */ -#define GFS_METATYPE_LF (6) /* Leaf dinode block list */ -#define GFS_METATYPE_JD (7) /* Journal Data */ -#define GFS_METATYPE_LH (8) /* Log Header (gfs_log_header) */ -#define GFS_METATYPE_LD (9) /* Log Descriptor (gfs_log_descriptor) */ -#define GFS_METATYPE_EA (10) /* Extended Attribute */ -#define GFS_METATYPE_ED (11) /* Extended Attribute data */ - - -#define GFS_META_CLUMP (64) /* # blocks to convert fm data to meta */ - -struct gfs_meta_header { - uint32_t mh_magic; /* GFS_MAGIC sanity check magic number */ - uint32_t mh_type; /* GFS_METATYPE_XX type of metadata block */ - uint64_t mh_generation; /* increment before writing to journal */ - uint32_t mh_format; /* GFS_FORMAT_XX (version # for this type) */ - uint32_t mh_incarn; /* increment when marking dinode "unused" */ -}; - -/* - * super-block structure - * - * One of these is at beginning of filesystem. - * It's probably good if SIZEOF_SB <= GFS_BASIC_BLOCK (512 bytes) - */ - -/* Address of SuperBlock in GFS basic blocks. 1st 64K of filesystem is empty - for safety against getting clobbered by wayward volume managers, etc. - 64k was chosen because it's the largest GFS-supported fs block size. */ -#define GFS_SB_ADDR (128) - -/* The lock number for the superblock (must be zero) */ -#define GFS_SB_LOCK (0) -#define GFS_CRAP_LOCK (1) - -/* Requirement: GFS_LOCKNAME_LEN % 8 == 0 - Includes: the fencing zero at the end */ -#define GFS_LOCKNAME_LEN (64) - -struct gfs_sb { - /* Order is important; need to be able to read old superblocks - in order to support on-disk version upgrades */ - struct gfs_meta_header sb_header; - - uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ - uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ - uint32_t sb_flags; /* ?? */ - - uint32_t sb_bsize; /* fundamental FS block size in bytes */ - uint32_t sb_bsize_shift; /* log2(sb_bsize) */ - uint32_t sb_seg_size; /* Journal segment size in FS blocks */ - - /* These special inodes do not appear in any on-disk directory. */ - struct gfs_inum sb_jindex_di; /* journal index inode */ - struct gfs_inum sb_rindex_di; /* resource group index inode */ - struct gfs_inum sb_root_di; /* root directory inode */ - - /* Default inter-node locking protocol (lock module) and namespace */ - char sb_lockproto[GFS_LOCKNAME_LEN]; /* lock protocol name */ - char sb_locktable[GFS_LOCKNAME_LEN]; /* unique name for this FS */ - - /* More special inodes */ - struct gfs_inum sb_quota_di; /* quota inode */ - struct gfs_inum sb_license_di; /* license inode */ - - char sb_reserved[96]; -}; - -/* - * journal index structure - * - * One for each journal used by the filesystem. - * These descriptors are packed contiguously within the jindex inode (file). - */ - -struct gfs_jindex { - uint64_t ji_addr; /* starting block of the journal */ - uint32_t ji_nsegment; /* number (quantity) of segments in journal */ - uint32_t ji_pad; - - char ji_reserved[64]; -}; - -/* - * resource index structure - * - * One of these for each resource group in the filesystem. - * These descriptors are packed contiguously within the rindex inode (file). - * Also see struct gfs_rgrp. - */ - -struct gfs_rindex { - uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ - uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ - uint32_t ri_pad; - - uint64_t ri_data1; /* block # of first data/meta block in rgrp */ - uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ - - uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ - - char ri_reserved[64]; -}; - -/* - * resource group header structure - * - * One of these at beginning of the first block of an rgrp, - * followed by block alloc bitmap data in remainder of first block. - * Each resource group contains: - * Header block, including block allocation statistics (struct gfs_rgrp) - * and first part of block alloc bitmap. - * Bitmap block(s), continuing block alloc bitmap started in header block. - * Data/meta blocks, allocatable blocks containing file data and metadata. - * - * In older versions, now-unused (but previously allocated) dinodes were - * saved for re-use in an on-disk linked list (chain). This is no longer - * done, but support still exists for reclaiming dinodes from this list, - * to support upgrades from older on-disk formats. - */ - -/* Each data block within rgrp is represented by 2 bits in the alloc bitmap */ -#define GFS_NBBY (4) /* # blocks represented by 1 bitmap byte */ -#define GFS_BIT_SIZE (2) -#define GFS_BIT_MASK (0x00000003) - -/* - * 4 possible block allocation states: - * bit 0 = alloc(1)/free(0) - * bit 1 = metadata(1)/data(0) - */ -#define GFS_BLKST_FREE (0) -#define GFS_BLKST_USED (1) -#define GFS_BLKST_FREEMETA (2) -#define GFS_BLKST_USEDMETA (3) - -struct gfs_rgrp { - struct gfs_meta_header rg_header; - - uint32_t rg_flags; /* ?? */ - - uint32_t rg_free; /* Number (qty) of free data blocks */ - - /* Dinodes are USEDMETA, but are handled separately from other METAs */ - uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ - uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ - struct gfs_inum rg_freedi_list; /* 1st block in chain of free dinodes */ - - /* These META statistics do not include dinodes (used or free) */ - uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ - uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ - - char rg_reserved[64]; -}; - -/* - * quota structure - */ - -struct gfs_quota { - uint64_t qu_limit; - uint64_t qu_warn; - int64_t qu_value; - - char qu_reserved[64]; -}; - -/* - * dinode (disk inode) structure - * The ondisk representation of inodes - * One for each file, directory, etc. - * GFS does not put more than one inode in a single block. - * The inode may be "stuffed", carrying file data along with metadata, - * if the file data is small enough. - * Otherwise, the inode block contains pointers to other blocks that contain - * either file data or other pointers to other blocks (indirect addressing - * via a metadata tree). - */ - -#define GFS_MAX_META_HEIGHT (10) -#define GFS_DIR_MAX_DEPTH (17) - -/* Dinode types */ -#define GFS_FILE_NON (0) -#define GFS_FILE_REG (1) /* regular file */ -#define GFS_FILE_DIR (2) /* directory */ -#define GFS_FILE_LNK (5) /* link */ -#define GFS_FILE_BLK (7) /* block device node */ -#define GFS_FILE_CHR (8) /* character device node */ -#define GFS_FILE_FIFO (101) /* fifo/pipe */ -#define GFS_FILE_SOCK (102) /* socket */ - -/* Dinode flags */ -#define GFS_DIF_JDATA (0x00000001) /* jrnl all data for this file */ -#define GFS_DIF_EXHASH (0x00000002) /* hashed directory (leaves) */ -#define GFS_DIF_UNUSED (0x00000004) /* unused dinode */ -#define GFS_DIF_EA_INDIRECT (0x00000008) /* extended attribute, indirect*/ -#define GFS_DIF_DIRECTIO (0x00000010) -#define GFS_DIF_IMMUTABLE (0x00000020) /* Can't change file */ -#define GFS_DIF_APPENDONLY (0x00000040) /* Can only add to end of file */ -#define GFS_DIF_NOATIME (0x00000080) /* Don't update access time - (currently unused/ignored) */ -#define GFS_DIF_SYNC (0x00000100) /* Flush to disk, don't cache - (currently unused/ignored) */ -#define GFS_DIF_INHERIT_DIRECTIO (0x40000000) /* new files get DIRECTIO flag */ -#define GFS_DIF_INHERIT_JDATA (0x80000000) /* new files get JDATA flag */ - -struct gfs_dinode { - struct gfs_meta_header di_header; - - struct gfs_inum di_num; /* formal inode # and block address */ - - uint32_t di_mode; /* mode of file */ - uint32_t di_uid; /* owner's user id */ - uint32_t di_gid; /* owner's group id */ - uint32_t di_nlink; /* number (qty) of links to this file */ - uint64_t di_size; /* number (qty) of bytes in file */ - uint64_t di_blocks; /* number (qty) of blocks in file */ - int64_t di_atime; /* time last accessed */ - int64_t di_mtime; /* time last modified */ - int64_t di_ctime; /* time last changed */ - - /* Non-zero only for character or block device nodes */ - uint32_t di_major; /* device major number */ - uint32_t di_minor; /* device minor number */ - - /* Block allocation strategy */ - uint64_t di_rgrp; /* dinode rgrp block number */ - uint64_t di_goal_rgrp; /* rgrp to alloc from next */ - uint32_t di_goal_dblk; /* data block goal */ - uint32_t di_goal_mblk; /* metadata block goal */ - - uint32_t di_flags; /* GFS_DIF_... */ - - /* struct gfs_rindex, struct gfs_jindex, or struct gfs_dirent */ - uint32_t di_payload_format; /* GFS_FORMAT_... */ - uint16_t di_type; /* GFS_FILE_... type of file */ - uint16_t di_height; /* height of metadata (0 == stuffed) */ - uint32_t di_incarn; /* incarnation (unused, see gfs_meta_header) */ - uint16_t di_pad; - - /* These only apply to directories */ - uint16_t di_depth; /* Number of bits in the table */ - uint32_t di_entries; /* The # (qty) of entries in the directory */ - - /* This formed an on-disk chain of unused dinodes */ - struct gfs_inum di_next_unused; /* used in old versions only */ - - uint64_t di_eattr; /* extended attribute block number */ - - char di_reserved[56]; -}; - -/* - * indirect block header - * - * A component of a dinode's indirect addressing metadata tree. - * These are pointed to by pointers in dinodes or other indirect blocks. - */ - -struct gfs_indirect { - struct gfs_meta_header in_header; - - char in_reserved[64]; -}; - -/* - * directory structure - many of these per directory file - * - * See comments at beginning of dir.c - */ - -#define GFS_FNAMESIZE (255) -#define GFS_DIRENT_SIZE(name_len) ((sizeof(struct gfs_dirent) + (name_len) + 7) & ~7) - -struct gfs_dirent { - struct gfs_inum de_inum; /* formal inode number and block address */ - uint32_t de_hash; /* hash of the filename */ - uint16_t de_rec_len; /* the length of the dirent */ - uint16_t de_name_len; /* the length of the name */ - uint16_t de_type; /* GFS_FILE_... type of dinode this points to */ - - char de_reserved[14]; -}; - -/* - * Header of leaf directory nodes - * - * See comments at beginning of dir.c - */ - -struct gfs_leaf { - struct gfs_meta_header lf_header; - - uint16_t lf_depth; /* Depth of leaf */ - uint16_t lf_entries; /* Number of dirents in leaf */ - uint32_t lf_dirent_format; /* GFS_FORMAT_DE (version #) */ - uint64_t lf_next; /* Next leaf, if overflow */ - - char lf_reserved[64]; -}; - -/* - * Log header structure - * - * Two of these are in the first block of a transaction log: - * 1) at beginning of block - * 2) at end of first 512-byte sector within block - */ - -#define GFS_LOG_HEAD_UNMOUNT (0x00000001) /* log is clean, can unmount fs */ - -struct gfs_log_header { - struct gfs_meta_header lh_header; - - uint32_t lh_flags; /* GFS_LOG_HEAD_... */ - uint32_t lh_pad; - - uint64_t lh_first; /* Block number of first header in this trans */ - uint64_t lh_sequence; /* Sequence number of this transaction */ - - uint64_t lh_tail; /* Block number of log tail */ - uint64_t lh_last_dump; /* Block number of last dump */ - - char lh_reserved[64]; -}; - -/* - * Log type descriptor - * - * One of these for each chunk in a transaction - */ - -#define GFS_LOG_DESC_METADATA (300) /* metadata */ -/* ld_data1 is the number (quantity) of metadata blocks in the descriptor. - ld_data2 is unused. - */ - -#define GFS_LOG_DESC_IUL (400) /* unlinked inode */ -/* ld_data1 is TRUE if this is a dump. - ld_data2 is unused. - FixMe!!! ld_data1 should be the number (quantity) of entries. - ld_data2 should be "TRUE if this is a dump". - */ - -#define GFS_LOG_DESC_IDA (401) /* de-allocated inode */ -/* ld_data1 is unused. - ld_data2 is unused. - FixMe!!! ld_data1 should be the number (quantity) of entries. - */ - -#define GFS_LOG_DESC_Q (402) /* quota */ -/* ld_data1 is the number of quota changes in the descriptor. - ld_data2 is TRUE if this is a dump. - */ - -#define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */ -/* ld_data1 is unused. - ld_data2 is unused. - */ - -struct gfs_log_descriptor { - struct gfs_meta_header ld_header; - - uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ - uint32_t ld_length; /* Number of buffers in this chunk */ - uint32_t ld_data1; /* descriptor-specific field */ - uint32_t ld_data2; /* descriptor-specific field */ - - char ld_reserved[64]; -}; - -/* - * Metadata block tags - * - * One for each logged block. Tells where block really belongs on-disk. - * These descriptor tags are packed contiguously after a gfs_log_descriptor. - */ - -struct gfs_block_tag { - uint64_t bt_blkno; /* inplace block number */ - uint32_t bt_flags; /* ?? */ - uint32_t bt_pad; -}; - -/* - * Quota Journal Tag - */ - -#define GFS_QTF_USER (0x00000001) - -struct gfs_quota_tag { - int64_t qt_change; - uint32_t qt_flags; /* GFS_QTF_... */ - uint32_t qt_id; -}; - -/* - * Extended attribute header format - */ - -#define GFS_EA_MAX_NAME_LEN (255) -#define GFS_EA_MAX_DATA_LEN (65536) - -#define GFS_EATYPE_UNUSED (0) -#define GFS_EATYPE_USR (1) /* user attribute */ -#define GFS_EATYPE_SYS (2) /* system attribute */ -#define GFS_EATYPE_SECURITY (3) /* security attribute */ - -#define GFS_EATYPE_LAST (3) -#define GFS_EATYPE_VALID(x) ((x) <= GFS_EATYPE_LAST) - -#define GFS_EAFLAG_LAST (0x01) /* last ea in block */ - -struct gfs_ea_header { - uint32_t ea_rec_len; /* total record length: hdr + name + data */ - uint32_t ea_data_len; /* data length, in bytes */ - uint8_t ea_name_len; /* no NULL pointer after the string */ - uint8_t ea_type; /* GFS_EATYPE_... */ - uint8_t ea_flags; /* GFS_EAFLAG_... */ - uint8_t ea_num_ptrs; /* # fs blocks needed for EA */ - uint32_t ea_pad; -}; - -/* Endian functions */ - -#define GFS_ENDIAN_BIG - -#ifdef GFS_ENDIAN_BIG - -#define gfs16_to_cpu be16_to_cpu -#define gfs32_to_cpu be32_to_cpu -#define gfs64_to_cpu be64_to_cpu - -#define cpu_to_gfs16 cpu_to_be16 -#define cpu_to_gfs32 cpu_to_be32 -#define cpu_to_gfs64 cpu_to_be64 - -#else /* GFS_ENDIAN_BIG */ - -#define gfs16_to_cpu le16_to_cpu -#define gfs32_to_cpu le32_to_cpu -#define gfs64_to_cpu le64_to_cpu - -#define cpu_to_gfs16 cpu_to_le16 -#define cpu_to_gfs32 cpu_to_le32 -#define cpu_to_gfs64 cpu_to_le64 - -#endif /* GFS_ENDIAN_BIG */ - -/* Translation functions */ - -void gfs_inum_in(struct gfs_inum *no, char *buf); -void gfs_inum_out(struct gfs_inum *no, char *buf); -void gfs_meta_header_in(struct gfs_meta_header *mh, char *buf); -void gfs_meta_header_out(struct gfs_meta_header *mh, char *buf); -void gfs_sb_in(struct gfs_sb *sb, char *buf); -void gfs_sb_out(struct gfs_sb *sb, char *buf); -void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); -void gfs_jindex_out(struct gfs_jindex *jindex, char *buf); -void gfs_rindex_in(struct gfs_rindex *rindex, char *buf); -void gfs_rindex_out(struct gfs_rindex *rindex, char *buf); -void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf); -void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf); -void gfs_quota_in(struct gfs_quota *quota, char *buf); -void gfs_quota_out(struct gfs_quota *quota, char *buf); -void gfs_dinode_in(struct gfs_dinode *dinode, char *buf); -void gfs_dinode_out(struct gfs_dinode *dinode, char *buf); -void gfs_indirect_in(struct gfs_indirect *indirect, char *buf); -void gfs_indirect_out(struct gfs_indirect *indirect, char *buf); -void gfs_dirent_in(struct gfs_dirent *dirent, char *buf); -void gfs_dirent_out(struct gfs_dirent *dirent, char *buf); -void gfs_leaf_in(struct gfs_leaf *leaf, char *buf); -void gfs_leaf_out(struct gfs_leaf *leaf, char *buf); -void gfs_log_header_in(struct gfs_log_header *head, char *buf); -void gfs_log_header_out(struct gfs_log_header *head, char *buf); -void gfs_desc_in(struct gfs_log_descriptor *desc, char *buf); -void gfs_desc_out(struct gfs_log_descriptor *desc, char *buf); -void gfs_block_tag_in(struct gfs_block_tag *btag, char *buf); -void gfs_block_tag_out(struct gfs_block_tag *btag, char *buf); -void gfs_quota_tag_in(struct gfs_quota_tag *qtag, char *buf); -void gfs_quota_tag_out(struct gfs_quota_tag *qtag, char *buf); -void gfs_ea_header_in(struct gfs_ea_header *qtag, char *buf); -void gfs_ea_header_out(struct gfs_ea_header *qtag, char *buf); - -/* Printing functions */ - -void gfs_inum_print(struct gfs_inum *no, int console); -void gfs_meta_header_print(struct gfs_meta_header *mh, int console); -void gfs_sb_print(struct gfs_sb *sb, int console); -void gfs_jindex_print(struct gfs_jindex *jindex, int console); -void gfs_rindex_print(struct gfs_rindex *rindex, int console); -void gfs_rgrp_print(struct gfs_rgrp *rgrp, int console); -void gfs_quota_print(struct gfs_quota *quota, int console); -void gfs_dinode_print(struct gfs_dinode *dinode, int console); -void gfs_indirect_print(struct gfs_indirect *indirect, int console); -void gfs_dirent_print(struct gfs_dirent *dirent, char *name, int console); -void gfs_leaf_print(struct gfs_leaf *leaf, int console); -void gfs_log_header_print(struct gfs_log_header *head, int console); -void gfs_desc_print(struct gfs_log_descriptor *desc, int console); -void gfs_block_tag_print(struct gfs_block_tag *tag, int console); -void gfs_quota_tag_print(struct gfs_quota_tag *tag, int console); -void gfs_ea_header_print(struct gfs_ea_header *ea, int console); - -/* The hash function for ExHash directories */ - -uint32_t gfs_dir_hash(const char *data, int len); - -#endif /* __GFS_ONDISK_DOT_H__ */ - - - -#ifdef WANT_GFS_CONVERSION_FUNCTIONS - -#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} -#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} -#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} -#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} -#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} -#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} -#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} -#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} - -#define pa(struct, member, count) print_array(#member, struct->member, count); - -/** - * print_array - Print out an array of bytes - * @title: what to print before the array - * @buf: the array - * @count: the number of bytes - * - */ - -static void -print_array(char *title, char *buf, int count) -{ - ENTER(GFN_PRINT_ARRAY) - int x; - - printk(" %s =\n", title); - for (x = 0; x < count; x++) { - printk("%.2X ", (unsigned char)buf[x]); - if (x % 16 == 15) - printk("\n"); - } - if (x % 16) - printk("\n"); - - RET(GFN_PRINT_ARRAY); -} - -/** - * gfs_inum_in - Read in an inode number - * @no: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_inum_in(struct gfs_inum *no, char *buf) -{ - ENTER(GFN_INUM_IN) - struct gfs_inum *str = (struct gfs_inum *)buf; - - CPIN_64(no, str, no_formal_ino); - CPIN_64(no, str, no_addr); - - RET(GFN_INUM_IN); -} - -/** - * gfs_inum_out - Write out an inode number - * @no: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_inum_out(struct gfs_inum *no, char *buf) -{ - ENTER(GFN_INUM_OUT) - struct gfs_inum *str = (struct gfs_inum *)buf; - - CPOUT_64(no, str, no_formal_ino); - CPOUT_64(no, str, no_addr); - - RET(GFN_INUM_OUT); -} - -/** - * gfs_inum_print - Print out a inode number - * @no: the cpu-order buffer - * - */ - -void -gfs_inum_print(struct gfs_inum *no) -{ - ENTER(GFN_INUM_PRINT) - pv(no, no_formal_ino, "%"PRIu64); - pv(no, no_addr, "%"PRIu64); - RET(GFN_INUM_PRINT); -} - -/** - * gfs_meta_header_in - Read in a metadata header - * @mh: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_meta_header_in(struct gfs_meta_header *mh, char *buf) -{ - ENTER(GFN_META_HEADER_IN) - struct gfs_meta_header *str = (struct gfs_meta_header *)buf; - - CPIN_32(mh, str, mh_magic); - CPIN_32(mh, str, mh_type); - CPIN_64(mh, str, mh_generation); - CPIN_32(mh, str, mh_format); - CPIN_32(mh, str, mh_incarn); - - RET(GFN_META_HEADER_IN); -} - -/** - * gfs_meta_header_in - Write out a metadata header - * @mh: the cpu-order structure - * @buf: the disk-order buffer - * - * Don't ever change the generation number in this routine. - * It's done manually in increment_generation(). - */ - -void -gfs_meta_header_out(struct gfs_meta_header *mh, char *buf) -{ - ENTER(GFN_META_HEADER_OUT) - struct gfs_meta_header *str = (struct gfs_meta_header *)buf; - - CPOUT_32(mh, str, mh_magic); - CPOUT_32(mh, str, mh_type); -#if 0 - /* Don't do this! - Mh_generation should only be change manually. */ - CPOUT_64(mh, str, mh_generation); -#endif - CPOUT_32(mh, str, mh_format); - CPOUT_32(mh, str, mh_incarn); - - RET(GFN_META_HEADER_OUT); -} - -/** - * gfs_meta_header_print - Print out a metadata header - * @mh: the cpu-order buffer - * - */ - -void -gfs_meta_header_print(struct gfs_meta_header *mh) -{ - ENTER(GFN_META_HEADER_PRINT) - - pv(mh, mh_magic, "0x%.8X"); - pv(mh, mh_type, "%u"); - pv(mh, mh_generation, "%"PRIu64); - pv(mh, mh_format, "%u"); - pv(mh, mh_incarn, "%u"); - - RET(GFN_META_HEADER_PRINT); -} - -/** - * gfs_sb_in - Read in a superblock - * @sb: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_sb_in(struct gfs_sb *sb, char *buf) -{ - ENTER(GFN_SB_IN) - struct gfs_sb *str = (struct gfs_sb *)buf; - - gfs_meta_header_in(&sb->sb_header, buf); - - CPIN_32(sb, str, sb_fs_format); - CPIN_32(sb, str, sb_multihost_format); - CPIN_32(sb, str, sb_flags); - - CPIN_32(sb, str, sb_bsize); - CPIN_32(sb, str, sb_bsize_shift); - CPIN_32(sb, str, sb_seg_size); - - gfs_inum_in(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); - gfs_inum_in(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); - gfs_inum_in(&sb->sb_root_di, (char *)&str->sb_root_di); - - CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); - CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); - - gfs_inum_in(&sb->sb_quota_di, (char *)&str->sb_quota_di); - gfs_inum_in(&sb->sb_license_di, (char *)&str->sb_license_di); - - CPIN_08(sb, str, sb_reserved, 96); - - RET(GFN_SB_IN); -} - -/** - * gfs_sb_out - Write out a superblock - * @sb: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_sb_out(struct gfs_sb *sb, char *buf) -{ - ENTER(GFN_SB_OUT) - struct gfs_sb *str = (struct gfs_sb *)buf; - - gfs_meta_header_out(&sb->sb_header, buf); - - CPOUT_32(sb, str, sb_fs_format); - CPOUT_32(sb, str, sb_multihost_format); - CPOUT_32(sb, str, sb_flags); - - CPOUT_32(sb, str, sb_bsize); - CPOUT_32(sb, str, sb_bsize_shift); - CPOUT_32(sb, str, sb_seg_size); - - gfs_inum_out(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); - gfs_inum_out(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); - gfs_inum_out(&sb->sb_root_di, (char *)&str->sb_root_di); - - CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); - CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); - - gfs_inum_out(&sb->sb_quota_di, (char *)&str->sb_quota_di); - gfs_inum_out(&sb->sb_license_di, (char *)&str->sb_license_di); - - CPOUT_08(sb, str, sb_reserved, 96); - - RET(GFN_SB_OUT); -} - -/** - * gfs_sb_print - Print out a superblock - * @sb: the cpu-order buffer - * - */ - -void -gfs_sb_print(struct gfs_sb *sb) -{ - ENTER(GFN_SB_PRINT) - - gfs_meta_header_print(&sb->sb_header); - - pv(sb, sb_fs_format, "%u"); - pv(sb, sb_multihost_format, "%u"); - pv(sb, sb_flags, "%u"); - - pv(sb, sb_bsize, "%u"); - pv(sb, sb_bsize_shift, "%u"); - pv(sb, sb_seg_size, "%u"); - - gfs_inum_print(&sb->sb_jindex_di); - gfs_inum_print(&sb->sb_rindex_di); - gfs_inum_print(&sb->sb_root_di); - - pv(sb, sb_lockproto, "%s"); - pv(sb, sb_locktable, "%s"); - - gfs_inum_print(&sb->sb_quota_di); - gfs_inum_print(&sb->sb_license_di); - - pa(sb, sb_reserved, 96); - - RET(GFN_SB_PRINT); -} - -/** - * gfs_jindex_in - Read in a journal index structure - * @jindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_jindex_in(struct gfs_jindex *jindex, char *buf) -{ - ENTER(GFN_JINDEX_IN) - struct gfs_jindex *str = (struct gfs_jindex *)buf; - - CPIN_64(jindex, str, ji_addr); - CPIN_32(jindex, str, ji_nsegment); - CPIN_32(jindex, str, ji_pad); - - CPIN_08(jindex, str, ji_reserved, 64); - - RET(GFN_JINDEX_IN); -} - -/** - * gfs_jindex_out - Write out a journal index structure - * @jindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_jindex_out(struct gfs_jindex *jindex, char *buf) -{ - ENTER(GFN_JINDEX_OUT) - struct gfs_jindex *str = (struct gfs_jindex *)buf; - - CPOUT_64(jindex, str, ji_addr); - CPOUT_32(jindex, str, ji_nsegment); - CPOUT_32(jindex, str, ji_pad); - - CPOUT_08(jindex, str, ji_reserved, 64); - - RET(GFN_JINDEX_OUT); -} - -/** - * gfs_jindex_print - Print out a journal index structure - * @ji: the cpu-order buffer - * - */ - -void -gfs_jindex_print(struct gfs_jindex *ji) -{ - ENTER(GFN_JINDEX_PRINT) - - pv(ji, ji_addr, "%"PRIu64); - pv(ji, ji_nsegment, "%u"); - pv(ji, ji_pad, "%u"); - - pa(ji, ji_reserved, 64); - - RET(GFN_JINDEX_PRINT); -} - -/** - * gfs_rindex_in - Read in a resource index structure - * @rindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rindex_in(struct gfs_rindex *rindex, char *buf) -{ - ENTER(GFN_RINDEX_IN) - struct gfs_rindex *str = (struct gfs_rindex *)buf; - - CPIN_64(rindex, str, ri_addr); - CPIN_32(rindex, str, ri_length); - CPIN_32(rindex, str, ri_pad); - - CPIN_64(rindex, str, ri_data1); - CPIN_32(rindex, str, ri_data); - - CPIN_32(rindex, str, ri_bitbytes); - - CPIN_08(rindex, str, ri_reserved, 64); - - RET(GFN_RINDEX_IN); -} - -/** - * gfs_rindex_out - Write out a resource index structure - * @rindex: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rindex_out(struct gfs_rindex *rindex, char *buf) -{ - ENTER(GFN_RINDEX_OUT) - struct gfs_rindex *str = (struct gfs_rindex *)buf; - - CPOUT_64(rindex, str, ri_addr); - CPOUT_32(rindex, str, ri_length); - CPOUT_32(rindex, str, ri_pad); - - CPOUT_64(rindex, str, ri_data1); - CPOUT_32(rindex, str, ri_data); - - CPOUT_32(rindex, str, ri_bitbytes); - - CPOUT_08(rindex, str, ri_reserved, 64); - - RET(GFN_RINDEX_OUT); -} - -/** - * gfs_rindex_print - Print out a resource index structure - * @ri: the cpu-order buffer - * - */ - -void -gfs_rindex_print(struct gfs_rindex *ri) -{ - ENTER(GFN_RINDEX_PRINT) - - pv(ri, ri_addr, "%"PRIu64); - pv(ri, ri_length, "%u"); - pv(ri, ri_pad, "%u"); - - pv(ri, ri_data1, "%"PRIu64); - pv(ri, ri_data, "%u"); - - pv(ri, ri_bitbytes, "%u"); - - pa(ri, ri_reserved, 64); - - RET(GFN_RINDEX_PRINT); -} - -/** - * gfs_rgrp_in - Read in a resource group header - * @rgrp: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf) -{ - ENTER(GFN_RGRP_IN) - struct gfs_rgrp *str = (struct gfs_rgrp *)buf; - - gfs_meta_header_in(&rgrp->rg_header, buf); - - CPIN_32(rgrp, str, rg_flags); - - CPIN_32(rgrp, str, rg_free); - - CPIN_32(rgrp, str, rg_useddi); - CPIN_32(rgrp, str, rg_freedi); - gfs_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); - - CPIN_32(rgrp, str, rg_usedmeta); - CPIN_32(rgrp, str, rg_freemeta); - - CPIN_08(rgrp, str, rg_reserved, 64); - - RET(GFN_RGRP_IN); -} - -/** - * gfs_rgrp_out - Write out a resource group header - * @rgrp: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf) -{ - ENTER(GFN_RGRP_OUT) - struct gfs_rgrp *str = (struct gfs_rgrp *)buf; - - gfs_meta_header_out(&rgrp->rg_header, buf); - - CPOUT_32(rgrp, str, rg_flags); - - CPOUT_32(rgrp, str, rg_free); - - CPOUT_32(rgrp, str, rg_useddi); - CPOUT_32(rgrp, str, rg_freedi); - gfs_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); - - CPOUT_32(rgrp, str, rg_usedmeta); - CPOUT_32(rgrp, str, rg_freemeta); - - CPOUT_08(rgrp, str, rg_reserved, 64); - - RET(GFN_RGRP_OUT); -} - -/** - * gfs_rgrp_print - Print out a resource group header - * @rg: the cpu-order buffer - * - */ - -void -gfs_rgrp_print(struct gfs_rgrp *rg) -{ - ENTER(GFN_RGRP_PRINT) - - gfs_meta_header_print(&rg->rg_header); - - pv(rg, rg_flags, "%u"); - - pv(rg, rg_free, "%u"); - - pv(rg, rg_useddi, "%u"); - pv(rg, rg_freedi, "%u"); - gfs_inum_print(&rg->rg_freedi_list); - - pv(rg, rg_usedmeta, "%u"); - pv(rg, rg_freemeta, "%u"); - - pa(rg, rg_reserved, 64); - - RET(GFN_RGRP_PRINT); -} - -/** - * gfs_quota_in - Read in a quota structures - * @quota: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_in(struct gfs_quota *quota, char *buf) -{ - ENTER(GFN_QUOTA_IN) - struct gfs_quota *str = (struct gfs_quota *)buf; - - CPIN_64(quota, str, qu_limit); - CPIN_64(quota, str, qu_warn); - CPIN_64(quota, str, qu_value); - - CPIN_08(quota, str, qu_reserved, 64); - - RET(GFN_QUOTA_IN); -} - -/** - * gfs_quota_out - Write out a quota structure - * @quota: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_out(struct gfs_quota *quota, char *buf) -{ - ENTER(GFN_QUOTA_OUT) - struct gfs_quota *str = (struct gfs_quota *)buf; - - CPOUT_64(quota, str, qu_limit); - CPOUT_64(quota, str, qu_warn); - CPOUT_64(quota, str, qu_value); - - CPOUT_08(quota, str, qu_reserved, 64); - - RET(GFN_QUOTA_OUT); -} - -/** - * gfs_quota_print - Print out a quota structure - * @quota: the cpu-order buffer - * - */ - -void -gfs_quota_print(struct gfs_quota *quota) -{ - ENTER(GFN_QUOTA_PRINT) - - pv(quota, qu_limit, "%"PRIu64); - pv(quota, qu_warn, "%"PRIu64); - pv(quota, qu_value, "%"PRId64); - - pa(quota, qu_reserved, 64); - - RET(GFN_QUOTA_PRINT); -} - -/** - * gfs_dinode_in - Read in a dinode - * @dinode: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dinode_in(struct gfs_dinode *dinode, char *buf) -{ - ENTER(GFN_DINODE_IN) - struct gfs_dinode *str = (struct gfs_dinode *)buf; - - gfs_meta_header_in(&dinode->di_header, buf); - - gfs_inum_in(&dinode->di_num, (char *)&str->di_num); - - CPIN_32(dinode, str, di_mode); - CPIN_32(dinode, str, di_uid); - CPIN_32(dinode, str, di_gid); - CPIN_32(dinode, str, di_nlink); - CPIN_64(dinode, str, di_size); - CPIN_64(dinode, str, di_blocks); - CPIN_64(dinode, str, di_atime); - CPIN_64(dinode, str, di_mtime); - CPIN_64(dinode, str, di_ctime); - CPIN_32(dinode, str, di_major); - CPIN_32(dinode, str, di_minor); - - CPIN_64(dinode, str, di_rgrp); - CPIN_64(dinode, str, di_goal_rgrp); - CPIN_32(dinode, str, di_goal_dblk); - CPIN_32(dinode, str, di_goal_mblk); - CPIN_32(dinode, str, di_flags); - CPIN_32(dinode, str, di_payload_format); - CPIN_16(dinode, str, di_type); - CPIN_16(dinode, str, di_height); - CPIN_32(dinode, str, di_incarn); - CPIN_16(dinode, str, di_pad); - - CPIN_16(dinode, str, di_depth); - CPIN_32(dinode, str, di_entries); - - gfs_inum_in(&dinode->di_next_unused, (char *)&str->di_next_unused); - - CPIN_64(dinode, str, di_eattr); - - CPIN_08(dinode, str, di_reserved, 56); - - RET(GFN_DINODE_IN); -} - -/** - * gfs_dinode_out - Write out a dinode - * @dinode: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dinode_out(struct gfs_dinode *dinode, char *buf) -{ - ENTER(GFN_DINODE_OUT) - struct gfs_dinode *str = (struct gfs_dinode *)buf; - - gfs_meta_header_out(&dinode->di_header, buf); - - gfs_inum_out(&dinode->di_num, (char *)&str->di_num); - - CPOUT_32(dinode, str, di_mode); - CPOUT_32(dinode, str, di_uid); - CPOUT_32(dinode, str, di_gid); - CPOUT_32(dinode, str, di_nlink); - CPOUT_64(dinode, str, di_size); - CPOUT_64(dinode, str, di_blocks); - CPOUT_64(dinode, str, di_atime); - CPOUT_64(dinode, str, di_mtime); - CPOUT_64(dinode, str, di_ctime); - CPOUT_32(dinode, str, di_major); - CPOUT_32(dinode, str, di_minor); - - CPOUT_64(dinode, str, di_rgrp); - CPOUT_64(dinode, str, di_goal_rgrp); - CPOUT_32(dinode, str, di_goal_dblk); - CPOUT_32(dinode, str, di_goal_mblk); - CPOUT_32(dinode, str, di_flags); - CPOUT_32(dinode, str, di_payload_format); - CPOUT_16(dinode, str, di_type); - CPOUT_16(dinode, str, di_height); - CPOUT_32(dinode, str, di_incarn); - CPOUT_16(dinode, str, di_pad); - - CPOUT_16(dinode, str, di_depth); - CPOUT_32(dinode, str, di_entries); - - gfs_inum_out(&dinode->di_next_unused, (char *)&str->di_next_unused); - - CPOUT_64(dinode, str, di_eattr); - - CPOUT_08(dinode, str, di_reserved, 56); - - RET(GFN_DINODE_OUT); -} - -/** - * gfs_dinode_print - Print out a dinode - * @di: the cpu-order buffer - * - */ - -void -gfs_dinode_print(struct gfs_dinode *di) -{ - ENTER(GFN_DINODE_PRINT) - - gfs_meta_header_print(&di->di_header); - - gfs_inum_print(&di->di_num); - - pv(di, di_mode, "0%o"); - pv(di, di_uid, "%u"); - pv(di, di_gid, "%u"); - pv(di, di_nlink, "%u"); - pv(di, di_size, "%"PRIu64); - pv(di, di_blocks, "%"PRIu64); - pv(di, di_atime, "%"PRId64); - pv(di, di_mtime, "%"PRId64); - pv(di, di_ctime, "%"PRId64); - pv(di, di_major, "%u"); - pv(di, di_minor, "%u"); - - pv(di, di_rgrp, "%"PRIu64); - pv(di, di_goal_rgrp, "%"PRIu64); - pv(di, di_goal_dblk, "%u"); - pv(di, di_goal_mblk, "%u"); - pv(di, di_flags, "0x%.8X"); - pv(di, di_payload_format, "%u"); - pv(di, di_type, "%u"); - pv(di, di_height, "%u"); - pv(di, di_incarn, "%u"); - pv(di, di_pad, "%u"); - - pv(di, di_depth, "%u"); - pv(di, di_entries, "%u"); - - gfs_inum_print(&di->di_next_unused); - - pv(di, di_eattr, "%"PRIu64); - - pa(di, di_reserved, 56); - - RET(GFN_DINODE_PRINT); -} - -/** - * gfs_indirect_in - copy in the header of an indirect block - * @indirect: the in memory copy - * @buf: the buffer copy - * - */ - -void -gfs_indirect_in(struct gfs_indirect *indirect, char *buf) -{ - ENTER(GFN_INDIRECT_IN) - struct gfs_indirect *str = (struct gfs_indirect *)buf; - - gfs_meta_header_in(&indirect->in_header, buf); - - CPIN_08(indirect, str, in_reserved, 64); - - RET(GFN_INDIRECT_IN); -} - -/** - * gfs_indirect_out - copy out the header of an indirect block - * @indirect: the in memory copy - * @buf: the buffer copy - * - */ - -void -gfs_indirect_out(struct gfs_indirect *indirect, char *buf) -{ - ENTER(GFN_INDIRECT_OUT) - struct gfs_indirect *str = (struct gfs_indirect *)buf; - - gfs_meta_header_out(&indirect->in_header, buf); - - CPOUT_08(indirect, str, in_reserved, 64); - - RET(GFN_INDIRECT_OUT); -} - -/** - * gfs_indirect_print - Print out a indirect block header - * @indirect: the cpu-order buffer - * - */ - -void -gfs_indirect_print(struct gfs_indirect *indirect) -{ - ENTER(GFN_INDIRECT_PRINT) - - gfs_meta_header_print(&indirect->in_header); - - pa(indirect, in_reserved, 64); - - RET(GFN_INDIRECT_PRINT); -} - -/** - * gfs_dirent_in - Read in a directory entry - * @dirent: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dirent_in(struct gfs_dirent *dirent, char *buf) -{ - ENTER(GFN_DIRENT_IN) - struct gfs_dirent *str = (struct gfs_dirent *)buf; - - gfs_inum_in(&dirent->de_inum, (char *)&str->de_inum); - CPIN_32(dirent, str, de_hash); - CPIN_16(dirent, str, de_rec_len); - CPIN_16(dirent, str, de_name_len); - CPIN_16(dirent, str, de_type); - - CPIN_08(dirent, str, de_reserved, 14); - - RET(GFN_DIRENT_IN); -} - -/** - * gfs_dirent_out - Write out a directory entry - * @dirent: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_dirent_out(struct gfs_dirent *dirent, char *buf) -{ - ENTER(GFN_DIRENT_OUT) - struct gfs_dirent *str = (struct gfs_dirent *)buf; - - gfs_inum_out(&dirent->de_inum, (char *)&str->de_inum); - CPOUT_32(dirent, str, de_hash); - CPOUT_16(dirent, str, de_rec_len); - CPOUT_16(dirent, str, de_name_len); - CPOUT_16(dirent, str, de_type); - - CPOUT_08(dirent, str, de_reserved, 14); - - RET(GFN_DIRENT_OUT); -} - -/** - * gfs_dirent_print - Print out a directory entry - * @de: the cpu-order buffer - * @name: the filename - * - */ - -void -gfs_dirent_print(struct gfs_dirent *de, char *name) -{ - ENTER(GFN_DIRENT_PRINT) - char buf[GFS_FNAMESIZE + 1]; - - gfs_inum_print(&de->de_inum); - pv(de, de_hash, "0x%.8X"); - pv(de, de_rec_len, "%u"); - pv(de, de_name_len, "%u"); - pv(de, de_type, "%u"); - - pa(de, de_reserved, 14); - - memset(buf, 0, GFS_FNAMESIZE + 1); - memcpy(buf, name, de->de_name_len); - printk(" name = %s\n", buf); - - RET(GFN_DIRENT_PRINT); -} - -/** - * gfs_leaf_in - Read in a directory leaf header - * @leaf: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_leaf_in(struct gfs_leaf *leaf, char *buf) -{ - ENTER(GFN_LEAF_IN) - struct gfs_leaf *str = (struct gfs_leaf *)buf; - - gfs_meta_header_in(&leaf->lf_header, buf); - - CPIN_16(leaf, str, lf_depth); - CPIN_16(leaf, str, lf_entries); - CPIN_32(leaf, str, lf_dirent_format); - CPIN_64(leaf, str, lf_next); - - CPIN_08(leaf, str, lf_reserved, 64); - - RET(GFN_LEAF_IN); -} - -/** - * gfs_leaf_out - Write out a directory leaf header - * @leaf: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_leaf_out(struct gfs_leaf *leaf, char *buf) -{ - ENTER(GFN_LEAF_OUT) - struct gfs_leaf *str = (struct gfs_leaf *)buf; - - gfs_meta_header_out(&leaf->lf_header, buf); - - CPOUT_16(leaf, str, lf_depth); - CPOUT_16(leaf, str, lf_entries); - CPOUT_32(leaf, str, lf_dirent_format); - CPOUT_64(leaf, str, lf_next); - - CPOUT_08(leaf, str, lf_reserved, 64); - - RET(GFN_LEAF_OUT); -} - -/** - * gfs_leaf_print - Print out a directory leaf header - * @lf: the cpu-order buffer - * - */ - -void -gfs_leaf_print(struct gfs_leaf *lf) -{ - ENTER(GFN_LEAF_PRINT) - - gfs_meta_header_print(&lf->lf_header); - - pv(lf, lf_depth, "%u"); - pv(lf, lf_entries, "%u"); - pv(lf, lf_dirent_format, "%u"); - pv(lf, lf_next, "%"PRIu64); - - pa(lf, lf_reserved, 64); - - RET(GFN_LEAF_PRINT); -} - -/** - * gfs_log_header_in - Read in a log header - * @head: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_log_header_in(struct gfs_log_header *head, char *buf) -{ - ENTER(GFN_LOG_HEADER_IN) - struct gfs_log_header *str = (struct gfs_log_header *)buf; - - gfs_meta_header_in(&head->lh_header, buf); - - CPIN_32(head, str, lh_flags); - CPIN_32(head, str, lh_pad); - - CPIN_64(head, str, lh_first); - CPIN_64(head, str, lh_sequence); - - CPIN_64(head, str, lh_tail); - CPIN_64(head, str, lh_last_dump); - - CPIN_08(head, str, lh_reserved, 64); - - RET(GFN_LOG_HEADER_IN); -} - -/** - * gfs_log_header_out - Write out a log header - * @head: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_log_header_out(struct gfs_log_header *head, char *buf) -{ - ENTER(GFN_LOG_HEADER_OUT) - struct gfs_log_header *str = (struct gfs_log_header *)buf; - - gfs_meta_header_out(&head->lh_header, buf); - - CPOUT_32(head, str, lh_flags); - CPOUT_32(head, str, lh_pad); - - CPOUT_64(head, str, lh_first); - CPOUT_64(head, str, lh_sequence); - - CPOUT_64(head, str, lh_tail); - CPOUT_64(head, str, lh_last_dump); - - CPOUT_08(head, str, lh_reserved, 64); - - RET(GFN_LOG_HEADER_OUT); -} - -/** - * gfs_log_header_print - Print out a log header - * @head: the cpu-order buffer - * - */ - -void -gfs_log_header_print(struct gfs_log_header *lh) -{ - ENTER(GFN_LOG_HEADER_PRINT) - - gfs_meta_header_print(&lh->lh_header); - - pv(lh, lh_flags, "0x%.8X"); - pv(lh, lh_pad, "%u"); - - pv(lh, lh_first, "%"PRIu64); - pv(lh, lh_sequence, "%"PRIu64); - - pv(lh, lh_tail, "%"PRIu64); - pv(lh, lh_last_dump, "%"PRIu64); - - pa(lh, lh_reserved, 64); - - RET(GFN_LOG_HEADER_PRINT); -} - -/** - * gfs_desc_in - Read in a log descriptor - * @desc: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_desc_in(struct gfs_log_descriptor *desc, char *buf) -{ - ENTER(GFN_DESC_IN) - struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; - - gfs_meta_header_in(&desc->ld_header, buf); - - CPIN_32(desc, str, ld_type); - CPIN_32(desc, str, ld_length); - CPIN_32(desc, str, ld_data1); - CPIN_32(desc, str, ld_data2); - - CPIN_08(desc, str, ld_reserved, 64); - - RET(GFN_DESC_IN); -} - -/** - * gfs_desc_out - Write out a log descriptor - * @desc: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_desc_out(struct gfs_log_descriptor *desc, char *buf) -{ - ENTER(GFN_DESC_OUT) - struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; - - gfs_meta_header_out(&desc->ld_header, buf); - - CPOUT_32(desc, str, ld_type); - CPOUT_32(desc, str, ld_length); - CPOUT_32(desc, str, ld_data1); - CPOUT_32(desc, str, ld_data2); - - CPOUT_08(desc, str, ld_reserved, 64); - - RET(GFN_DESC_OUT); -} - -/** - * gfs_desc_print - Print out a log descriptor - * @ld: the cpu-order buffer - * - */ - -void -gfs_desc_print(struct gfs_log_descriptor *ld) -{ - ENTER(GFN_DESC_PRINT) - - gfs_meta_header_print(&ld->ld_header); - - pv(ld, ld_type, "%u"); - pv(ld, ld_length, "%u"); - pv(ld, ld_data1, "%u"); - pv(ld, ld_data2, "%u"); - - pa(ld, ld_reserved, 64); - - RET(GFN_DESC_PRINT); -} - -/** - * gfs_block_tag_in - Read in a block tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_block_tag_in(struct gfs_block_tag *tag, char *buf) -{ - ENTER(GFN_BLOCK_TAG_IN) - struct gfs_block_tag *str = (struct gfs_block_tag *)buf; - - CPIN_64(tag, str, bt_blkno); - CPIN_32(tag, str, bt_flags); - CPIN_32(tag, str, bt_pad); - - RET(GFN_BLOCK_TAG_IN); -} - -/** - * gfs_block_tag_out - Write out a block tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_block_tag_out(struct gfs_block_tag *tag, char *buf) -{ - ENTER(GFN_BLOCK_TAG_OUT) - struct gfs_block_tag *str = (struct gfs_block_tag *)buf; - - CPOUT_64(tag, str, bt_blkno); - CPOUT_32(tag, str, bt_flags); - CPOUT_32(tag, str, bt_pad); - - RET(GFN_BLOCK_TAG_OUT); -} - -/** - * gfs_block_tag_print - Print out a block tag - * @tag: the cpu-order buffer - * - */ - -void -gfs_block_tag_print(struct gfs_block_tag *tag) -{ - ENTER(GFN_BLOCK_TAG_PRINT) - - pv(tag, bt_blkno, "%"PRIu64); - pv(tag, bt_flags, "%u"); - pv(tag, bt_pad, "%u"); - - RET(GFN_BLOCK_TAG_PRINT); -} - -/** - * gfs_quota_tag_in - Read in a quota tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf) -{ - ENTER(GFN_QUOTA_TAG_IN) - struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; - - CPIN_64(tag, str, qt_change); - CPIN_32(tag, str, qt_flags); - CPIN_32(tag, str, qt_id); - - RET(GFN_QUOTA_TAG_IN); -} - -/** - * gfs_quota_tag_out - Write out a quota tag - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf) -{ - ENTER(GFN_QUOTA_TAG_OUT) - struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; - - CPOUT_64(tag, str, qt_change); - CPOUT_32(tag, str, qt_flags); - CPOUT_32(tag, str, qt_id); - - RET(GFN_QUOTA_TAG_OUT); -} - -/** - * gfs_quota_tag_print - Print out a quota tag - * @tag: the cpu-order buffer - * - */ - -void -gfs_quota_tag_print(struct gfs_quota_tag *tag) -{ - ENTER(GFN_QUOTA_TAG_PRINT) - - pv(tag, qt_change, "%"PRId64); - pv(tag, qt_flags, "0x%.8X"); - pv(tag, qt_id, "%u"); - - RET(GFN_QUOTA_TAG_PRINT); -} - -/** - * gfs_ea_header_in - Read in a Extended Attribute header - * @tag: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_ea_header_in(struct gfs_ea_header *ea, char *buf) -{ - ENTER(GFN_EA_HEADER_IN) - struct gfs_ea_header *str = (struct gfs_ea_header *)buf; - - CPIN_32(ea, str, ea_rec_len); - CPIN_32(ea, str, ea_data_len); - ea->ea_name_len = str->ea_name_len; - ea->ea_type = str->ea_type; - ea->ea_flags = str->ea_flags; - ea->ea_num_ptrs = str->ea_num_ptrs; - CPIN_32(ea, str, ea_pad); - - RET(GFN_EA_HEADER_IN); -} - -/** - * gfs_ea_header_out - Write out a Extended Attribute header - * @ea: the cpu-order structure - * @buf: the disk-order buffer - * - */ - -void -gfs_ea_header_out(struct gfs_ea_header *ea, char *buf) -{ - ENTER(GFN_EA_HEADER_OUT) - struct gfs_ea_header *str = (struct gfs_ea_header *)buf; - - CPOUT_32(ea, str, ea_rec_len); - CPOUT_32(ea, str, ea_data_len); - str->ea_name_len = ea->ea_name_len; - str->ea_type = ea->ea_type; - str->ea_flags = ea->ea_flags; - str->ea_num_ptrs = ea->ea_num_ptrs; - CPOUT_32(ea, str, ea_pad); - - RET(GFN_EA_HEADER_OUT); -} - -/** - * gfs_ea_header_printt - Print out a Extended Attribute header - * @ea: the cpu-order buffer - * - */ - -void -gfs_ea_header_print(struct gfs_ea_header *ea, char *name) -{ - ENTER(GFN_EA_HEADER_PRINT) - char buf[GFS_EA_MAX_NAME_LEN + 1]; - - pv(ea, ea_rec_len, "%u"); - pv(ea, ea_data_len, "%u"); - pv(ea, ea_name_len, "%u"); - pv(ea, ea_type, "%u"); - pv(ea, ea_flags, "%u"); - pv(ea, ea_num_ptrs, "%u"); - pv(ea, ea_pad, "%u"); - - memset(buf, 0, GFS_EA_MAX_NAME_LEN + 1); - memcpy(buf, name, ea->ea_name_len); - printk(" name = %s\n", buf); - - RET(GFN_EA_HEADER_PRINT); -} - -static const uint32_t crc_32_tab[] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -/** - * gfs_dir_hash - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * Take some data and convert it to a 32-bit hash. - * - * The hash function is a 32-bit CRC of the data. The algorithm uses - * the crc_32_tab table above. - * - * This may not be the fastest hash function, but it does a fair bit better - * at providing uniform results than the others I've looked at. That's - * really important for efficient directories. - * - * Returns: the hash - */ - -uint32_t -gfs_dir_hash(const char *data, int len) -{ - ENTER(GFN_DIR_HASH) - uint32_t hash = 0xFFFFFFFF; - - for (; len--; data++) - hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); - - hash = ~hash; - - RETURN(GFN_DIR_HASH, hash); -} - -#endif /* WANT_GFS_CONVERSION_FUNCTIONS */ - diff --git a/gfs/gfs_fsck/pass1.c b/gfs/gfs_fsck/pass1.c deleted file mode 100644 index dbf0c22..0000000 --- a/gfs/gfs_fsck/pass1.c +++ /dev/null @@ -1,936 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* pass1 checks inodes for format & type, duplicate blocks, & incorrect - * block count. - * - * It builds up tables that contains the state of each block (free, - * block in use, metadata type, etc), as well as bad blocks and - * duplicate blocks. (See block_list.[ch] for more info) - * - */ - -#include <stdio.h> - -#include "fsck_incore.h" -#include "fsck.h" -#include "bio.h" -#include "fs_dir.h" -#include "fs_inode.h" -#include "util.h" -#include "block_list.h" -#include "log.h" -#include "inode_hash.h" -#include "inode.h" -#include "link.h" -#include "metawalk.h" - -struct block_count { - uint64_t indir_count; - uint64_t data_count; - uint64_t ea_count; -}; - -static int leaf(struct fsck_inode *ip, uint64_t block, osi_buf_t **bh, - void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - struct block_count *bc = (struct block_count *) private; - if(check_range(sdp, block)){ - log_warn("Leaf block #%"PRIu64" is out of range for " - "directory #%"PRIu64".\n", - block, ip->i_di.di_num.no_addr); - block_set(sdp->bl, ip->i_di.di_num.no_addr, bad_block); - return 1; - } - if(get_and_read_buf(sdp, block, bh, 0)){ - log_err("Unable to read leaf block #%"PRIu64" for " - "directory #%"PRIu64".\n", - block, ip->i_di.di_num.no_addr); - if(query(sdp, "Clear directory inode at %"PRIu64"? (y/n) ", - ip->i_di.di_num.no_addr)) { - block_set(sdp->bl, ip->i_di.di_num.no_addr, meta_inval); - } else { - log_err("Unreadable block %"PRIu64" ignored\n"); - } - return 1; - } - - if(check_meta(*bh, GFS_METATYPE_LF)){ - log_err("Bad meta header for leaf block #%"PRIu64 - " in directory #%"PRIu64". - is %u, should be %u\n", - BH_BLKNO(*bh), ip->i_di.di_num.no_addr, - ((struct gfs_meta_header *)BH_DATA((*bh)))->mh_type, - GFS_METATYPE_LF); - if(query(sdp, "Clear directory inode at %"PRIu64"? (y/n) ", - ip->i_di.di_num.no_addr)) { - block_set(sdp->bl, ip->i_di.di_num.no_addr, - meta_inval); - log_err("Directory inode marked invalid\n"); - } else { - log_err("Invalid block %"PRIu64" ignored\n"); - } - return 1; - } - - log_debug("\tLeaf block at %15"PRIu64"\n", BH_BLKNO(*bh)); - block_set(sdp->bl, BH_BLKNO(*bh), leaf_blk); - bc->indir_count++; - - return 0; -} - -static int check_metalist(struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - struct block_query q = {0}; - int found_dup = 0; - osi_buf_t *nbh; - struct block_count *bc = (struct block_count *)private; - - *bh = NULL; - - if (check_range(ip->i_sbd, block)){ /* blk outside of FS */ - block_set(sdp->bl, ip->i_di.di_num.no_addr, bad_block); - log_debug("Bad indirect block pointer (out of range).\n"); - - return 1; - } - if(block_check(sdp->bl, block, &q)) { - stack; - return -1; - } - if(q.block_type != block_free) { - log_debug("Found duplicate block in indirect block -" - " was marked %d\n", q.block_type); - block_mark(sdp->bl, block, dup_block); - found_dup = 1; - } - get_and_read_buf(ip->i_sbd, block, &nbh, 0); - - /** Attention -- experimental code **/ - if (check_meta(nbh, GFS_METATYPE_IN)){ - log_debug("Bad indirect block pointer " - "(points to something that is not an indirect block).\n"); - if(!found_dup) { - block_set(sdp->bl, block, meta_inval); - relse_buf(ip->i_sbd, nbh); - return 1; - } - - relse_buf(ip->i_sbd, nbh); - }else{ /* blk check ok */ - *bh = nbh; - } - /** Attention -- experimental code end **/ - - block_set(sdp->bl, block, indir_blk); - bc->indir_count++; - - return 0; -} - - - -static int check_data(struct fsck_inode *ip, uint64_t block, void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - struct block_query q = {0}; - osi_buf_t *data_bh; - struct block_count *bc = (struct block_count *) private; - - if (check_range(ip->i_sbd, block)) { - - log_err( "Bad data block pointer (out of range)\n"); - /* Mark the owner of this block with the bad_block - * designator so we know to check it for out of range - * blocks later */ - block_set(ip->i_sbd->bl, ip->i_di.di_num.no_addr, bad_block); - - return 1; - } - - if (ip->i_di.di_flags & GFS_DIF_JDATA){ - /* Journaled data *is* metadata */ - if(get_and_read_buf(ip->i_sbd, block, &data_bh, 0)) { - stack; - block_set(sdp->bl, ip->i_di.di_num.no_addr, meta_inval); - return 1; - } - if(check_meta(data_bh, GFS_METATYPE_JD)) { - log_err("Block #%"PRIu64" in inode %"PRIu64" does not have " - "correct meta header. is %u should be %u\n", - block, ip->i_di.di_num.no_addr, - gfs32_to_cpu(((struct gfs_meta_header *) - BH_DATA((data_bh)))->mh_type), - GFS_METATYPE_JD); - relse_buf(sdp, data_bh); - block_set(sdp->bl, ip->i_di.di_num.no_addr, meta_inval); - return 1; - } - - if(block_check(sdp->bl, block, &q)) { - stack; - relse_buf(sdp, data_bh); - return -1; - } - if(q.block_type != block_free) { - log_debug("Found duplicate block at %" - PRIu64"\n", block); - block_mark(sdp->bl, block, dup_block); - bc->data_count++; - relse_buf(sdp, data_bh); - return 1; - } - log_debug("Setting %"PRIu64 " to journal block\n", block); - block_set(sdp->bl, block, journal_blk); - bc->data_count++; - relse_buf(sdp, data_bh); - } - else { - if(block_check(sdp->bl, block, &q)) { - stack; - return -1; - } - if(q.block_type != block_free) { - log_debug("Found duplicate block at %" - PRIu64"\n", block); - block_mark(sdp->bl, block, dup_block); - bc->data_count++; - return 1; - } - log_debug("Setting %"PRIu64 " to data block\n", block); - block_set(sdp->bl, block, block_used); - bc->data_count++; - } - - return 0; -} - -static int check_eattr_indir(struct fsck_inode *ip, uint64_t indirect, - uint64_t parent, osi_buf_t **bh, void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - int ret = 0; - struct block_query q = {0}; - struct block_count *bc = (struct block_count *) private; - - /* This inode contains an eattr - it may be invalid, but the - * eattr attributes points to a non-zero block */ - block_set(sdp->bl, ip->i_num.no_addr, eattr_block); - - if(check_range(sdp, indirect)) { - /*log_warn("EA indirect block #%"PRIu64" is out of range.\n", - indirect); - block_set(sdp->bl, parent, bad_block);*/ - /* Doesn't help to mark this here - this gets checked - * in pass1c */ - ret = 1; - } - else if(block_check(sdp->bl, indirect, &q)) { - stack; - ret = -1; - } - else if(q.block_type != block_free) { - log_debug("Duplicate block found at #%"PRIu64".\n", - indirect); - block_set(sdp->bl, indirect, dup_block); - bc->ea_count++; - ret = 1; - } - else if(get_and_read_buf(sdp, indirect, bh, 0)) { - log_warn("Unable to read EA indirect block #%"PRIu64".\n", - indirect); - block_set(sdp->bl, indirect, meta_inval); - ret = 1; - } - else if(check_meta(*bh, GFS_METATYPE_IN)) { - log_warn("EA indirect block has incorrect type.\n"); - block_set(sdp->bl, BH_BLKNO(*bh), meta_inval); - ret = 1; - } - else { - /* FIXME: do i need to differentiate this as an ea_indir? */ - block_set(sdp->bl, BH_BLKNO(*bh), indir_blk); - bc->ea_count++; - } - return ret; -} - -/** - * check_extended_leaf_eattr - * @ip - * @el_blk: block number of the extended leaf - * - * An EA leaf block can contain EA's with pointers to blocks - * where the data for that EA is kept. Those blocks still - * have the gfs meta header of type GFS_METATYPE_EA - * - * Returns: 0 if correct[able], -1 if removal is needed - */ -static int check_extended_leaf_eattr(struct fsck_inode *ip, uint64_t *data_ptr, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - osi_buf_t *el_buf; - struct fsck_sb *sdp = ip->i_sbd; - struct block_query q; - uint64_t el_blk = gfs64_to_cpu(*data_ptr); - struct block_count *bc = (struct block_count *) private; - - if(check_range(sdp, el_blk)){ - log_err("EA extended leaf block #%"PRIu64" " - "is out of range.\n", - el_blk); - block_set(sdp->bl, ip->i_di.di_eattr, bad_block); - return 1; - } - - if(block_check(sdp->bl, el_blk, &q)) { - stack; - return -1; - } - if(q.block_type != block_free) { - block_set(sdp->bl, el_blk, dup_block); - bc->ea_count++; - return 1; - } - - if(get_and_read_buf(sdp, el_blk, &el_buf, 0)){ - log_err("Unable to check extended leaf block.\n"); - block_set(sdp->bl, el_blk, meta_inval); - return 1; - } - - if(check_meta(el_buf, GFS_METATYPE_ED)) { - log_err("EA extended leaf block has incorrect type.\n"); - relse_buf(sdp, el_buf); - block_set(sdp->bl, el_blk, meta_inval); - return 1; - } - - block_set(sdp->bl, el_blk, meta_eattr); - bc->ea_count++; - relse_buf(sdp, el_buf); - return 0; -} - -static int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - osi_buf_t *leaf_bh; - int ret = 0; - struct block_query q = {0}; - struct block_count *bc = (struct block_count *) private; - - /* This inode contains an eattr - it may be invalid, but the - * eattr attributes points to a non-zero block */ - block_set(sdp->bl, ip->i_num.no_addr, eattr_block); - - if(check_range(sdp, block)){ - log_warn("EA leaf block #%"PRIu64" in inode %"PRIu64 - " is out of range.\n", - ip->i_num.no_addr, block); - block_set(sdp->bl, ip->i_di.di_eattr, bad_block); - ret = 1; - } - else if(block_check(sdp->bl, block, &q)) { - stack; - return -1; - } - else if(q.block_type != block_free) { - log_debug("Duplicate block found at #%"PRIu64".\n", - block); - block_set(sdp->bl, block, dup_block); - bc->ea_count++; - } - else if(get_and_read_buf(sdp, block, &leaf_bh, 0)){ - log_warn("Unable to read EA leaf block #%"PRIu64".\n", - block); - block_set(sdp->bl, block, meta_inval); - ret = 1; - } else if(check_meta(leaf_bh, GFS_METATYPE_EA)) { - log_warn("EA leaf block has incorrect type.\n"); - block_set(sdp->bl, BH_BLKNO(leaf_bh), meta_inval); - relse_buf(sdp, leaf_bh); - ret = 1; - } - else { - block_set(sdp->bl, BH_BLKNO(leaf_bh), meta_eattr); - bc->ea_count++; - } - - *bh = leaf_bh; - - return ret; -} - -static int check_eattr_entries(struct fsck_inode *ip, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - char ea_name[256]; - - if(!ea_hdr->ea_name_len){ - /* Skip this entry for now */ - return 1; - } - - memset(ea_name, 0, sizeof(ea_name)); - strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs_ea_header), - ea_hdr->ea_name_len); - - if(!GFS_EATYPE_VALID(ea_hdr->ea_type) && - ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){ - /* Skip invalid entry */ - return 1; - } - - if(ea_hdr->ea_num_ptrs){ - uint32 avail_size; - int max_ptrs; - - avail_size = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header); - max_ptrs = (gfs32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size; - - if(max_ptrs > ea_hdr->ea_num_ptrs) { - return 1; - } else { - log_debug(" Pointers Required: %d\n" - " Pointers Reported: %d\n", - max_ptrs, - ea_hdr->ea_num_ptrs); - } - - } - - return 0; -} - -struct metawalk_fxns pass1_fxns = { - .private = NULL, - .check_leaf = leaf, - .check_metalist = check_metalist, - .check_data = check_data, - .check_eattr_indir = check_eattr_indir, - .check_eattr_leaf = check_eattr_leaf, - .check_dentry = NULL, - .check_eattr_entry = check_eattr_entries, - .check_eattr_extentry = check_extended_leaf_eattr, -}; - -int clear_metalist(struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - struct block_query q = {0}; - - *bh = NULL; - - if(block_check(sdp->bl, block, &q)) { - stack; - return -1; - } - if(!q.dup_block) { - block_set(sdp->bl, block, block_free); - return 0; - } - return 0; -} - -int clear_data(struct fsck_inode *ip, uint64_t block, void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - struct block_query q = {0}; - - if(block_check(sdp->bl, block, &q)) { - stack; - return -1; - } - if(!q.dup_block) { - block_set(sdp->bl, block, block_free); - return 0; - } - return 0; - -} - -int clear_leaf(struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private) -{ - - struct fsck_sb *sdp = ip->i_sbd; - struct block_query q = {0}; - log_crit("Clearing leaf %"PRIu64"\n", block); - - if(block_check(sdp->bl, block, &q)) { - stack; - return -1; - } - if(!q.dup_block) { - log_crit("Setting leaf invalid\n"); - if(block_set(sdp->bl, block, block_free)) { - stack; - return -1; - } - return 0; - } - return 0; - -} - -int add_to_dir_list(struct fsck_sb *sbp, uint64_t block) -{ - struct dir_info *di = NULL; - struct dir_info *newdi; - - /* FIXME: This list should probably be a b-tree or - * something...but since most of the time we're going to be - * tacking the directory onto the end of the list, it doesn't - * matter too much */ - find_di(sbp, block, &di); - if(di) { - log_err("Attempting to add directory block %"PRIu64 - " which is already in list\n", block); - return -1; - } - - if(!(newdi = (struct dir_info *) malloc(sizeof(*newdi)))) { - log_crit("Unable to allocate dir_info structure\n"); - return -1; - } - if(!memset(newdi, 0, sizeof(*newdi))) { - log_crit("error while zeroing dir_info structure\n"); - return -1; - } - - newdi->dinode = block; - - dinode_hash_insert(sbp->dir_hash, block, newdi); - - return 0; -} - - - - -int handle_di(struct fsck_sb *sdp, osi_buf_t *bh, uint64_t block, int mfree) -{ - struct block_query q = {0}; - struct fsck_inode *ip; - int error; - struct block_count bc = {0}; - struct metawalk_fxns invalidate_metatree = {0}; - invalidate_metatree.check_metalist = clear_metalist; - invalidate_metatree.check_data = clear_data; - invalidate_metatree.check_leaf = clear_leaf; - - if(copyin_inode(sdp, bh, &ip)) { - stack; - return -1; - } - - if (ip->i_di.di_flags & GFS_DIF_UNUSED){ - if(mfree) { - if(block_set(sdp->bl, block, meta_free)) { - stack; - goto fail; - } - goto success; - } else { - log_err("Found unused inode marked in-use\n"); - if(query(sdp, "Clear unused inode at block %" - PRIu64"? (y/n) ", block)) { - if(block_set(sdp->bl, block, meta_inval)) { - stack; - goto fail; - } - goto success; - } else { - log_err("Unused inode still marked in-use\n"); - } - } - - } else { - if(mfree) { - if(block_set(sdp->bl, block, meta_free)) { - stack; - goto fail; - } - goto success; - } - } - - if (ip->i_di.di_num.no_addr != block) { - log_err("Bad dinode Address. " - "Found %"PRIu64", " - "Expected %"PRIu64"\n", - ip->i_di.di_num.no_addr, block); - if(query(sdp, "Fix address in inode at block %" - PRIu64"? (y/n) ", block)) { - ip->i_di.di_num.no_addr = - ip->i_di.di_num.no_formal_ino = - block; - if(fs_copyout_dinode(ip)){ - log_crit("Bad dinode address can not be reset.\n"); - goto fail; - } else { - log_err("Bad dinode address reset.\n"); - } - } else { - log_err("Address in inode at block %"PRIu64 - " not fixed\n", block); - } - - } - - if(block_check(sdp->bl, block, &q)) { - stack; - goto fail; - } - if(q.block_type != block_free) { - log_debug("Found duplicate block at %"PRIu64"\n", - block); - if(block_mark(sdp->bl, block, dup_block)) { - stack; - goto fail; - } - goto success; - } - - switch(ip->i_di.di_type) { - - case GFS_FILE_DIR: - if(block_set(sdp->bl, block, inode_dir)) { - stack; - goto fail; - } - if(add_to_dir_list(sdp, block)) { - stack; - goto fail; - } - break; - case GFS_FILE_REG: - if(block_set(sdp->bl, block, inode_file)) { - stack; - goto fail; - } - break; - case GFS_FILE_LNK: - if(block_set(sdp->bl, block, inode_lnk)) { - stack; - goto fail; - } - break; - case GFS_FILE_BLK: - if(block_set(sdp->bl, block, inode_blk)) { - stack; - goto fail; - } - break; - case GFS_FILE_CHR: - if(block_set(sdp->bl, block, inode_chr)) { - stack; - goto fail; - } - break; - case GFS_FILE_FIFO: - if(block_set(sdp->bl, block, inode_fifo)) { - stack; - goto fail; - } - break; - case GFS_FILE_SOCK: - if(block_set(sdp->bl, block, inode_sock)) { - stack; - goto fail; - } - break; - default: - if(block_set(sdp->bl, block, meta_inval)) { - stack; - goto fail; - } - goto success; - } - if(set_link_count(ip->i_sbd, ip->i_num.no_formal_ino, - ip->i_di.di_nlink)) { - stack; - goto fail; - } - - /* FIXME: fix height and depth here - wasn't implemented in - * old fsck either, so no biggy... */ - if (ip->i_di.di_height < compute_height(sdp, ip->i_di.di_size)){ - log_warn("Dinode #%"PRIu64" has bad height " - "Found %u, Expected >= %u\n", - ip->i_di.di_num.no_addr, ip->i_di.di_height, - compute_height(sdp, ip->i_di.di_size)); - /* once implemented, remove continue statement */ - log_warn("Marking inode invalid\n"); - if(block_set(sdp->bl, block, meta_inval)) { - stack; - goto fail; - } - goto success; - } - - if (ip->i_di.di_type == (GFS_FILE_DIR && - (ip->i_di.di_flags & GFS_DIF_EXHASH))) - { - if (((1 << ip->i_di.di_depth) * sizeof(uint64_t)) != - ip->i_di.di_size) - { - log_warn("Directory dinode #%"PRIu64" has bad depth. " - "Found %u, Expected %u\n", - ip->i_di.di_num.no_addr, ip->i_di.di_depth, - (1 >> (ip->i_di.di_size/sizeof(uint64)))); - /* once implemented, remove continue statement */ - log_warn("Marking inode invalid\n"); - if(block_set(sdp->bl, block, meta_inval)) { - stack; - goto fail; - } - goto success; - } - } - - pass1_fxns.private = &bc; - - error = check_metatree(ip, &pass1_fxns); - if(error < 0) { - return 0; - } - if(error > 0) { - log_warn("Marking inode invalid\n"); - /* FIXME: Must set all leaves invalid as well */ - check_metatree(ip, &invalidate_metatree); - block_set(ip->i_sbd->bl, ip->i_di.di_num.no_addr, meta_inval); - return 0; - } - - /* FIXME: is this correct? */ - if(check_inode_eattr(ip, &pass1_fxns) < 0){ - osi_buf_t *di_bh; - ip->i_di.di_eattr = 0; - if(get_and_read_buf(sdp, ip->i_di.di_num.no_addr, &di_bh, 0)){ - stack; - log_crit("Bad EA reference remains.\n"); - } else { - gfs_dinode_out(&ip->i_di, BH_DATA(di_bh)); - if(write_buf(ip->i_sbd, di_bh, 0) < 0){ - stack; - log_crit("Bad EA reference remains.\n"); - } else { - log_warn("Bad EA reference cleared.\n"); - } - relse_buf(sdp, di_bh); - } - } - - if(ip->i_di.di_blocks != (1 + bc.indir_count + bc.data_count + bc.ea_count)) { - osi_buf_t *di_bh; - log_err("Ondisk block count does not match what fsck" - " found for inode %"PRIu64"\n", ip->i_di.di_num.no_addr); - if(query(sdp, "Fix ondisk block count? (y/n) ")) { - ip->i_di.di_blocks = 1 + bc.indir_count + - bc.data_count + - bc.ea_count; - if(get_and_read_buf(sdp, ip->i_di.di_num.no_addr, - &di_bh, 0)){ - stack; - log_crit("Bad block count remains\n"); - } else { - gfs_dinode_out(&ip->i_di, BH_DATA(di_bh)); - if(write_buf(ip->i_sbd, di_bh, 0) < 0){ - stack; - log_crit("Bad block count remains\n"); - } else { - log_warn("Bad block count fixed\n"); - } - relse_buf(sdp, di_bh); - } - } else { - log_err("Bad block count for %"PRIu64" not fixed\n", - ip->i_di.di_num.no_addr); - } - } - - success: - free(ip); - return 0; - - fail: - free(ip); - return -1; - -} - - -int scan_meta(struct fsck_sb *sdp, osi_buf_t *bh, uint64_t block, int mfree) -{ - - if (check_meta(bh, 0)) { - log_debug("Found invalid metadata at %"PRIu64"\n", block); - if(block_set(sdp->bl, block, meta_inval)) { - stack; - return -1; - } - return 0; - } - - log_debug("Checking metadata block %"PRIu64"\n", block); - - if (!check_type(bh, GFS_METATYPE_DI)) { - if(handle_di(sdp, bh, block, mfree)) { - stack; - return -1; - } - } - else if (!check_type(bh, GFS_METATYPE_NONE)) { - if(block_set(sdp->bl, block, meta_free)) { - stack; - return -1; - } - } else { - log_debug("Metadata block %"PRIu64 - " not an inode or free metadata\n", - block); - } - /* Ignore everything else - they should be hit by the - * handle_di step */ - - return 0; -} - -/** - * pass1 - walk through inodes and check inode state - * - * this walk can be done using root inode and depth first search, - * watching for repeat inode numbers - * - * format & type - * link count - * duplicate blocks - * bad blocks - * inodes size - * dir info - */ -int pass1(struct fsck_sb *sbp) -{ - osi_buf_t *bh; - osi_list_t *tmp; - uint64_t block; - struct fsck_rgrp *rgd; - int first; - uint64_t i; - uint64_t j; - uint64_t blk_count; - uint64_t offset; - uint64_t rg_count = 0; - int mfree = 0; - - /* FIXME: What other metadata should we look for? */ - - /* Mark the journal blocks as 'other metadata' */ - for (i = 0; i < sbp->journals; i++) { - struct gfs_jindex *ji; - ji = &sbp->jindex[i]; - for(j = ji->ji_addr; - j < ji->ji_addr + (ji->ji_nsegment * sbp->sb.sb_seg_size); - j++) { - if(block_set(sbp->bl, j, journal_blk)) { - stack; - return -1; - } - } - } - - - /* So, do we do a depth first search starting at the root - * inode, or use the rg bitmaps, or just read every fs block - * to find the inodes? If we use the depth first search, why - * have pass3 at all - if we use the rg bitmaps, pass5 is at - * least partially invalidated - if we read every fs block, - * things will probably be intolerably slow. The current fsck - * uses the rg bitmaps, so maybe that's the best way to start - * things - we can change the method later if necessary. - */ - - for (tmp = sbp->rglist.next; tmp != &sbp->rglist; - tmp = tmp->next, rg_count++){ - log_info("Checking metadata in Resource Group %"PRIu64"\n", - rg_count); - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - if(fs_rgrp_read(rgd, FALSE)){ - stack; - return -1; - } - log_debug("RG at %"PRIu64" is %u long\n", rgd->rd_ri.ri_addr, - rgd->rd_ri.ri_length); - for (i = 0; i < rgd->rd_ri.ri_length; i++) { - if(block_set(sbp->bl, rgd->rd_ri.ri_addr + i, - meta_other)){ - stack; - return -1; - } - } - - offset = sizeof(struct gfs_rgrp); - blk_count = 1; - - first = 1; - - while (1) { - - /* "block" is relative to the entire file system */ - if(next_rg_meta_free(rgd, &block, first, &mfree)) - break; - - warm_fuzzy_stuff(block); - if (fsck_abort) /* if asked to abort */ - return 0; - if (skip_this_pass) { - printf("Skipping pass 1 is not a good idea.\n"); - skip_this_pass = FALSE; - fflush(stdout); - } - if(get_and_read_buf(sbp, block, &bh, 0)){ - stack; - log_crit("Unable to retrieve block %"PRIu64 - "\n", block); - fs_rgrp_relse(rgd); - return -1; - } - - if(scan_meta(sbp, bh, block, mfree)) { - stack; - relse_buf(sbp, bh); - fs_rgrp_relse(rgd); - return -1; - } - relse_buf(sbp, bh); - first = 0; - } - fs_rgrp_relse(rgd); - } - - return 0; -} diff --git a/gfs/gfs_fsck/pass1b.c b/gfs/gfs_fsck/pass1b.c deleted file mode 100644 index 5cb7d66..0000000 --- a/gfs/gfs_fsck/pass1b.c +++ /dev/null @@ -1,534 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fsck_incore.h" -#include "fsck.h" -#include "osi_list.h" -#include "bio.h" -#include "fs_inode.h" -#include "block_list.h" -#include "util.h" -#include "inode.h" -#include "inode_hash.h" -#include "metawalk.h" - -struct inode_with_dups { - osi_list_t list; - uint64_t block_no; - int dup_count; - int ea_only; - uint64_t parent; - char *name; -}; - -struct blocks { - osi_list_t list; - uint64_t block_no; - osi_list_t ref_inode_list; -}; - -struct fxn_info { - uint64_t block; - int found; - int ea_only; /* The only dups were found in EAs */ -}; - -struct dup_handler { - struct blocks *b; - struct inode_with_dups *id; - int ref_inode_count; - int ref_count; -}; - -static inline void inc_if_found(uint64_t block, int not_ea, void *private) { - struct fxn_info *fi = (struct fxn_info *) private; - if(block == fi->block) { - (fi->found)++; - if(not_ea) - fi->ea_only = 0; - } -} - -static int check_metalist(struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private) -{ - inc_if_found(block, 1, private); - - return 0; -} - -static int check_data(struct fsck_inode *ip, uint64_t block, void *private) -{ - inc_if_found(block, 1, private); - - return 0; -} - -static int check_eattr_indir(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - struct fsck_sb *sbp = ip->i_sbd; - osi_buf_t *indir_bh = NULL; - - inc_if_found(block, 0, private); - if(get_and_read_buf(sbp, block, &indir_bh, 0)){ - log_warn("Unable to read EA leaf block #%"PRIu64".\n", - block); - return 1; - } - - *bh = indir_bh; - - return 0; -} - -static int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - struct fsck_sb *sbp = ip->i_sbd; - osi_buf_t *leaf_bh = NULL; - - inc_if_found(block, 0, private); - if(get_and_read_buf(sbp, block, &leaf_bh, 0)){ - log_warn("Unable to read EA leaf block #%"PRIu64".\n", - block); - return 1; - } - - *bh = leaf_bh; - return 0; -} - -static int check_eattr_entry(struct fsck_inode *ip, osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - return 0; -} - -static int check_eattr_extentry(struct fsck_inode *ip, uint64_t *ea_data_ptr, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - uint64_t block = gfs64_to_cpu(*ea_data_ptr); - - inc_if_found(block, 0, private); - - return 0; -} - -static int find_dentry(struct fsck_inode *ip, struct gfs_dirent *de, - struct gfs_dirent *prev, - osi_buf_t *bh, char *filename, int *update, - uint16_t *count, void *priv) -{ - osi_list_t *tmp1, *tmp2; - struct blocks *b; - struct inode_with_dups *id; - osi_list_foreach(tmp1, &ip->i_sbd->dup_list) { - b = osi_list_entry(tmp1, struct blocks, list); - osi_list_foreach(tmp2, &b->ref_inode_list) { - id = osi_list_entry(tmp2, struct inode_with_dups, - list); - if(id->name) - /* We can only have one parent of - * inodes that contain duplicate - * blocks... */ - continue; - if(id->block_no == de->de_inum.no_addr) { - id->name = strdup(filename); - id->parent = ip->i_di.di_num.no_addr; - log_debug("Duplicate block %"PRIu64 - " is in file or directory %"PRIu64 - " named %s\n", id->block_no, - ip->i_di.di_num.no_addr, filename); - /* If there are duplicates of - * duplicates, I guess we'll miss them - * here */ - break; - } - } - } - return 0; -} - -static int clear_dup_metalist(struct fsck_inode *ip, uint64_t block, - osi_buf_t **bh, void *private) -{ - struct dup_handler *dh = (struct dup_handler *) private; - - if(dh->ref_count == 1) - return 1; - if(block == dh->b->block_no) { - log_err("Found dup in inode "%s" (block #%"PRIu64 - ") with block #%"PRIu64"\n", - dh->id->name ? dh->id->name : "unknown name", - ip->i_di.di_num.no_addr, block); - log_err("inode %s is in directory %"PRIu64"\n", - dh->id->name ? dh->id->name : "", - dh->id->parent); - inode_hash_remove(ip->i_sbd->inode_hash, ip->i_di.di_num.no_addr); - /* Setting the block to invalid means the inode is - * cleared in pass2 */ - block_set(ip->i_sbd->bl, ip->i_di.di_num.no_addr, meta_inval); - } - return 0; -} -static int clear_dup_data(struct fsck_inode *ip, uint64_t block, void *private) -{ - struct dup_handler *dh = (struct dup_handler *) private; - - if(dh->ref_count == 1) { - return 1; - } - if(block == dh->b->block_no) { - log_err("Found dup in inode "%s" (block #%"PRIu64 - ") with block #%"PRIu64"\n", - dh->id->name ? dh->id->name : "unknown name", - ip->i_di.di_num.no_addr, block); - log_err("inode %s is in directory %"PRIu64"\n", - dh->id->name ? dh->id->name : "", - dh->id->parent); - inode_hash_remove(ip->i_sbd->inode_hash, ip->i_di.di_num.no_addr); - /* Setting the block to invalid means the inode is - * cleared in pass2 */ - block_set(ip->i_sbd->bl, ip->i_di.di_num.no_addr, meta_inval); - } - - return 0; -} -static int clear_dup_eattr_indir(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private) -{ - struct dup_handler *dh = (struct dup_handler *) private; - /* Can't use fxns from eattr.c since we need to check the ref - * count */ - if(dh->ref_count == 1) - return 1; - if(block == dh->b->block_no) { - log_err("Found dup in inode "%s" (block #%"PRIu64 - ") with block #%"PRIu64"\n", - dh->id->name ? dh->id->name : "unknown name", - ip->i_di.di_num.no_addr, block); - log_err("inode %s is in directory %"PRIu64"\n", - dh->id->name ? dh->id->name : "", - dh->id->parent); - block_set(ip->i_sbd->bl, ip->i_di.di_eattr, meta_inval); - } - - return 0; -} -static int clear_dup_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - struct dup_handler *dh = (struct dup_handler *) private; - if(dh->ref_count == 1) - return 1; - if(block == dh->b->block_no) { - log_err("Found dup in inode "%s" (block #%"PRIu64 - ") with block #%"PRIu64"\n", - dh->id->name ? dh->id->name : "unknown name", - ip->i_di.di_num.no_addr, block); - log_err("inode %s is in directory %"PRIu64"\n", - dh->id->name ? dh->id->name : "", - dh->id->parent); - - /* mark the main eattr block invalid */ - block_set(ip->i_sbd->bl, ip->i_di.di_eattr, meta_inval); - } - - return 0; -} - -static int clear_eattr_entry (struct fsck_inode *ip, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - char ea_name[256]; - - if(!ea_hdr->ea_name_len){ - /* Skip this entry for now */ - return 1; - } - - memset(ea_name, 0, sizeof(ea_name)); - strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs_ea_header), - ea_hdr->ea_name_len); - - if(!GFS_EATYPE_VALID(ea_hdr->ea_type) && - ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){ - /* Skip invalid entry */ - return 1; - } - - if(ea_hdr->ea_num_ptrs){ - uint32 avail_size; - int max_ptrs; - - avail_size = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header); - max_ptrs = (gfs32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size; - - if(max_ptrs > ea_hdr->ea_num_ptrs) { - return 1; - } else { - log_debug(" Pointers Required: %d\n" - " Pointers Reported: %d\n", - max_ptrs, - ea_hdr->ea_num_ptrs); - } - - - } - return 0; -} - -static int clear_eattr_extentry(struct fsck_inode *ip, uint64_t *ea_data_ptr, - osi_buf_t *leaf_bh, struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, void *private) -{ - uint64_t block = gfs64_to_cpu(*ea_data_ptr); - struct dup_handler *dh = (struct dup_handler *) private; - if(dh->ref_count == 1) - return 1; - if(block == dh->b->block_no) { - log_err("Found dup in inode "%s" (block #%"PRIu64 - ") with block #%"PRIu64"\n", - dh->id->name ? dh->id->name : "unknown name", - ip->i_di.di_num.no_addr, block); - log_err("inode %s is in directory %"PRIu64"\n", - dh->id->name ? dh->id->name : "", - dh->id->parent); - /* mark the main eattr block invalid */ - block_set(ip->i_sbd->bl, ip->i_di.di_eattr, meta_inval); - } - - return 0; - -} - -/* Finds all references to duplicate blocks in the metadata */ -int find_block_ref(struct fsck_sb *sbp, uint64_t inode, struct blocks *b) -{ - struct fsck_inode *ip; - struct fxn_info myfi = {b->block_no, 0, 1}; - struct inode_with_dups *id = NULL; - struct metawalk_fxns find_refs = { - .private = (void*) &myfi, - .check_leaf = NULL, - .check_metalist = check_metalist, - .check_data = check_data, - .check_eattr_indir = check_eattr_indir, - .check_eattr_leaf = check_eattr_leaf, - .check_dentry = NULL, - .check_eattr_entry = check_eattr_entry, - .check_eattr_extentry = check_eattr_extentry, - }; - - if(load_inode(sbp, inode, &ip)) { - stack; - return -1; - } - log_info("Checking inode %"PRIu64"'s metatree for references to block %"PRIu64"\n", - inode, b->block_no); - if(check_metatree(ip, &find_refs)) { - stack; - free_inode(&ip); - return -1; - } - log_info("Done checking metatree\n"); - - if (myfi.found) { - if(!(id = malloc(sizeof(*id)))) { - log_crit("Unable to allocate inode_with_dups structure\n"); - return -1; - } - if(!(memset(id, 0, sizeof(*id)))) { - log_crit("Unable to zero inode_with_dups structure\n"); - return -1; - } - log_debug("Found %d entries with block %"PRIu64 - " in inode #%"PRIu64"\n", - myfi.found, b->block_no, inode); - id->dup_count = myfi.found; - id->block_no = inode; - id->ea_only = myfi.ea_only; - osi_list_add_prev(&id->list, &b->ref_inode_list); - free_inode(&ip); - return 0; - } - free_inode(&ip); - return 0; -} - -/* Finds all blocks marked in the duplicate block bitmap */ -int find_dup_blocks(struct fsck_sb *sbp) -{ - uint64_t block_no = 0; - struct blocks *b; - - while (!find_next_block_type(sbp->bl, dup_block, &block_no)) { - if(!(b = malloc(sizeof(*b)))) { - log_crit("Unable to allocate blocks structure\n"); - return -1; - } - if(!memset(b, 0, sizeof(*b))) { - log_crit("Unable to zero blocks structure\n"); - return -1; - } - b->block_no = block_no; - osi_list_init(&b->ref_inode_list); - log_notice("Found dup block at %"PRIu64"\n", block_no); - osi_list_add(&b->list, &sbp->dup_list); - block_no++; - } - return 0; -} - - - -int handle_dup_blk(struct fsck_sb *sbp, struct blocks *b) -{ - osi_list_t *tmp; - struct inode_with_dups *id; - struct metawalk_fxns clear_dup_fxns = { - .private = NULL, - .check_leaf = NULL, - .check_metalist = clear_dup_metalist, - .check_data = clear_dup_data, - .check_eattr_indir = clear_dup_eattr_indir, - .check_eattr_leaf = clear_dup_eattr_leaf, - .check_dentry = NULL, - .check_eattr_entry = clear_eattr_entry, - .check_eattr_extentry = clear_eattr_extentry, - }; - struct fsck_inode *ip; - struct dup_handler dh = {0}; - - osi_list_foreach(tmp, &b->ref_inode_list) { - id = osi_list_entry(tmp, struct inode_with_dups, list); - dh.ref_inode_count++; - dh.ref_count += id->dup_count; - } - log_notice("Block %"PRIu64" has %d inodes referencing it for" - "a total of %d duplicate references\n", - b->block_no, dh.ref_inode_count, dh.ref_count); - - osi_list_foreach(tmp, &b->ref_inode_list) { - id = osi_list_entry(tmp, struct inode_with_dups, list); - log_warn("Inode %s has %d reference(s) to block %"PRIu64 - "\n", id->name, id->dup_count, b->block_no); - /* FIXME: User input */ - log_warn("Clearing...\n"); - load_inode(sbp, id->block_no, &ip); - dh.b = b; - dh.id = id; - clear_dup_fxns.private = (void *) &dh; - /* Clear the EAs for the inode first */ - check_inode_eattr(ip, &clear_dup_fxns); - /* If the dup wasn't only in the EA, clear the inode */ - if(!id->ea_only) - check_metatree(ip, &clear_dup_fxns); - - free_inode(&ip); - dh.ref_inode_count--; - if(dh.ref_inode_count == 1) - break; - /* Inode is marked invalid and is removed in pass2 */ - /* FIXME: other option should be to duplicate the - * block for each duplicate and point the metadata at - * the cloned blocks */ - } - return 0; - -} - -/* Pass 1b handles finding the previous inode for a duplicate block - * When found, store the inodes pointing to the duplicate block for - * use in pass2 */ -int pass1b(struct fsck_sb *sbp) -{ - struct blocks *b; - uint64_t i; - struct block_query q; - osi_list_t *tmp; - struct metawalk_fxns find_dirents = {0}; - find_dirents.check_dentry = &find_dentry; - int rc = 0; - - osi_list_init(&sbp->dup_list); - /* Shove all blocks marked as duplicated into a list */ - log_info("Looking for duplicate blocks...\n"); - find_dup_blocks(sbp); - - /* If there were no dups in the bitmap, we don't need to do anymore */ - if(osi_list_empty(&sbp->dup_list)) { - log_info("No duplicate blocks found\n"); - return 0; - } - - /* Rescan the fs looking for pointers to blocks that are in - * the duplicate block map */ - log_info("Scanning filesystem for inodes containing duplicate blocks...\n"); - log_debug("Filesystem has %"PRIu64" blocks total\n", sbp->last_fs_block); - for(i = 0; i < sbp->last_fs_block; i += 1) { - warm_fuzzy_stuff(i); - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - goto out; - log_debug("Scanning block %"PRIu64" for inodes\n", i); - if(block_check(sbp->bl, i, &q)) { - stack; - rc = -1; - goto out; - } - if((q.block_type == inode_dir) || - (q.block_type == inode_file) || - (q.block_type == inode_lnk) || - (q.block_type == inode_blk) || - (q.block_type == inode_chr) || - (q.block_type == inode_fifo) || - (q.block_type == inode_sock)) { - osi_list_foreach(tmp, &sbp->dup_list) { - b = osi_list_entry(tmp, struct blocks, list); - if(find_block_ref(sbp, i, b)) { - stack; - rc = -1; - goto out; - } - } - } - if(q.block_type == inode_dir) { - check_dir(sbp, i, &find_dirents); - } - } - - /* Fix dups here - it's going to slow things down a lot to fix - * it later */ - log_info("Handling duplicate blocks\n"); -out: - /*osi_list_foreach(tmp, &sbp->dup_list) {*/ - while (!osi_list_empty(&sbp->dup_list)) { - b = osi_list_entry(sbp->dup_list.next, struct blocks, list); - if (!skip_this_pass && !rc) /* no error & not asked to skip the rest */ - handle_dup_blk(sbp, b); - osi_list_del(&b->list); - free(b); - } - return rc; -} diff --git a/gfs/gfs_fsck/pass1c.c b/gfs/gfs_fsck/pass1c.c deleted file mode 100644 index 4320185..0000000 --- a/gfs/gfs_fsck/pass1c.c +++ /dev/null @@ -1,286 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "fsck.h" -#include "fsck_incore.h" -#include "bio.h" -#include "inode.h" -#include "util.h" -#include "block_list.h" -#include "metawalk.h" - -static int remove_eattr_entry(struct fsck_sb *sdp, osi_buf_t *leaf_bh, - struct gfs_ea_header *curr, - struct gfs_ea_header *prev) -{ - log_warn("Removing EA located in block #%"PRIu64".\n", - BH_BLKNO(leaf_bh)); - if(!prev){ - curr->ea_type = GFS_EATYPE_UNUSED; - } else { - prev->ea_rec_len = - cpu_to_gfs32(gfs32_to_cpu(curr->ea_rec_len) + - gfs32_to_cpu(prev->ea_rec_len)); - if (curr->ea_flags & GFS_EAFLAG_LAST) - prev->ea_flags |= GFS_EAFLAG_LAST; - } - if(write_buf(sdp, leaf_bh, 0)){ - stack; - log_err("EA removal failed.\n"); - return -1; - } - return 0; -} - -int check_eattr_indir(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, - void *private) -{ - int *update = (int *) private; - struct fsck_sb *sbp = ip->i_sbd; - struct block_query q; - osi_buf_t *indir_bh; - - if(check_range(sbp, block)) { - log_err("Extended attributes indirect block out of range...removing\n"); - ip->i_di.di_eattr = 0; - *update = 1; - return 1; - } - else if (block_check(sbp->bl, block, &q)) { - stack; - return -1; - } - else if(q.block_type != indir_blk) { - log_err("Extended attributes indirect block invalid...removing\n"); - ip->i_di.di_eattr = 0; - *update = 1; - return 1; - } - else if(get_and_read_buf(sbp, block, &indir_bh, 0)){ - log_warn("Unable to read EA leaf block #%"PRIu64".\n", - block); - ip->i_di.di_eattr = 0; - *update = 1; - return 1; - } - - *bh = indir_bh; - return 0; -} -int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - int *update = (int *) private; - struct fsck_sb *sbp = ip->i_sbd; - struct block_query q; - osi_buf_t *leaf_bh; - - if(check_range(sbp, block)) { - log_err("Extended attributes block out of range...removing\n"); - ip->i_di.di_eattr = 0; - *update = 1; - return 1; - } - else if (block_check(sbp->bl, block, &q)) { - stack; - return -1; - } - else if(q.block_type != meta_eattr) { - log_err("Extended attributes block invalid...removing\n"); - ip->i_di.di_eattr = 0; - *update = 1; - return 1; - } - else if(get_and_read_buf(sbp, block, &leaf_bh, 0)){ - log_warn("Unable to read EA leaf block #%"PRIu64".\n", - block); - ip->i_di.di_eattr = 0; - *update = 1; - return 1; - } - - *bh = leaf_bh; - - return 0; - -} - - -static int check_eattr_entry(struct fsck_inode *ip, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - struct fsck_sb *sdp = ip->i_sbd; - char ea_name[256]; - uint32_t offset = (uint32_t)(((unsigned long)ea_hdr) - - ((unsigned long)BH_DATA(leaf_bh))); - uint32_t max_size = sdp->sb.sb_bsize; - if(!ea_hdr->ea_rec_len){ - log_err("EA has rec length == 0\n"); - ea_hdr->ea_flags |= GFS_EAFLAG_LAST; - ea_hdr->ea_rec_len = cpu_to_gfs32(max_size - offset); - if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } - if(offset + gfs32_to_cpu(ea_hdr->ea_rec_len) > max_size){ - log_err("EA rec length too long\n"); - ea_hdr->ea_flags |= GFS_EAFLAG_LAST; - ea_hdr->ea_rec_len = cpu_to_gfs32(max_size - offset); - if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } - if(offset + gfs32_to_cpu(ea_hdr->ea_rec_len) == max_size && - (ea_hdr->ea_flags & GFS_EAFLAG_LAST) == 0){ - log_err("last EA has no last entry flag\n"); - ea_hdr->ea_flags |= GFS_EAFLAG_LAST; - if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } - if(!ea_hdr->ea_name_len){ - log_err("EA has name length == 0\n"); - if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } - - memset(ea_name, 0, sizeof(ea_name)); - strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs_ea_header), - ea_hdr->ea_name_len); - - if(!GFS_EATYPE_VALID(ea_hdr->ea_type) && - ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){ - log_err("EA (%s) type is invalid (%d > %d).\n", - ea_name, ea_hdr->ea_type, GFS_EATYPE_LAST); - if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } - - if(ea_hdr->ea_num_ptrs){ - uint32 avail_size; - int max_ptrs; - - avail_size = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header); - max_ptrs = (gfs32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size; - - if(max_ptrs > ea_hdr->ea_num_ptrs){ - log_err("EA (%s) has incorrect number of pointers.\n", ea_name); - log_err(" Required: %d\n" - " Reported: %d\n", - max_ptrs, ea_hdr->ea_num_ptrs); - if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } else { - log_debug(" Pointers Required: %d\n" - " Pointers Reported: %d\n", - max_ptrs, - ea_hdr->ea_num_ptrs); - } - - } - - return 0; -} - -int check_eattr_extentry(struct fsck_inode *ip, uint64_t *ea_ptr, - osi_buf_t *leaf_bh, - struct gfs_ea_header *ea_hdr, - struct gfs_ea_header *ea_hdr_prev, - void *private) -{ - struct block_query q; - struct fsck_sb *sbp = ip->i_sbd; - if(block_check(sbp->bl, gfs64_to_cpu(*ea_ptr), &q)) { - stack; - return -1; - } - if(q.block_type != meta_eattr) { - if(remove_eattr_entry(sbp, leaf_bh, ea_hdr, ea_hdr_prev)){ - stack; - return -1; - } - return 1; - } - return 0; -} - -/* Go over all inodes with extended attributes and verify the EAs are - * valid */ -int pass1c(struct fsck_sb *sbp) -{ - uint64_t block_no = 0; - osi_buf_t *bh; - struct fsck_inode *ip = NULL; - int update = 0; - struct metawalk_fxns pass1c_fxns = { 0 }; - int error = 0; - - pass1c_fxns.check_eattr_indir = &check_eattr_indir; - pass1c_fxns.check_eattr_leaf = &check_eattr_leaf; - pass1c_fxns.check_eattr_entry = &check_eattr_entry; - pass1c_fxns.check_eattr_extentry = &check_eattr_extentry; - pass1c_fxns.private = (void *) &update; - - log_info("Looking for inodes containing ea blocks...\n"); - while (!find_next_block_type(sbp->bl, eattr_block, &block_no)) { - - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - log_info("EA in inode %"PRIu64"\n", block_no); - if(get_and_read_buf(sbp, block_no, &bh, 0)) { - stack; - return -1; - } - if(copyin_inode(sbp, bh, &ip)) { - stack; - return -1; - } - - log_debug("Found eattr at %"PRIu64"\n", ip->i_di.di_eattr); - /* FIXME: Handle walking the eattr here */ - error = check_inode_eattr(ip, &pass1c_fxns); - if(error < 0) { - stack; - return -1; - } - - if(update) { - gfs_dinode_out(&ip->i_di, BH_DATA(bh)); - write_buf(sbp, bh, 0); - } - - free_inode(&ip); - relse_buf(sbp, bh); - - block_no++; - } - return 0; -} diff --git a/gfs/gfs_fsck/pass2.c b/gfs/gfs_fsck/pass2.c deleted file mode 100644 index 1b8f577..0000000 --- a/gfs/gfs_fsck/pass2.c +++ /dev/null @@ -1,957 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "stdio.h" -#include "fsck_incore.h" -#include "fsck.h" -#include "block_list.h" -#include "bio.h" -#include "fs_inode.h" -#include "fs_dir.h" -#include "util.h" -#include "log.h" -#include "inode_hash.h" -#include "inode.h" -#include "link.h" -#include "metawalk.h" -#include "eattr.h" - -#define MAX_FILENAME 256 - -struct dir_status { - uint8_t dotdir:1; - uint8_t dotdotdir:1; - struct block_query q; - uint32_t entry_count; -}; - - -static int check_leaf(struct fsck_inode *ip, uint64_t block, osi_buf_t **lbh, - void *private) -{ - uint64_t chain_no; - struct fsck_sb *sbp = ip->i_sbd; - struct gfs_leaf leaf; - osi_buf_t *chain_head = NULL; - osi_buf_t *bh = NULL; - int chain=0; - int error; - - chain_no = block; - - do { - /* FIXME: check the range of the leaf? */ - /* check the leaf and stuff */ - - error = get_and_read_buf(sbp, chain_no, &bh, 0); - - if(error){ - stack; - goto fail; - } - - gfs_leaf_in(&leaf, BH_DATA(bh)); - - /* Check the leaf headers */ - - if(!chain){ - chain = 1; - chain_head = bh; - chain_no = leaf.lf_next; - } - else { - relse_buf(sbp, bh); - bh = NULL; - break; - } - } while(chain_no); - - *lbh = chain_head; - return 0; - - fail: - /* FIXME: check this error path */ - if(chain_head){ - if(chain_head == bh){ bh = NULL; } - relse_buf(sbp, chain_head); - } - if(bh) - relse_buf(sbp, bh); - - return -1; - -} - - -/* Set children's parent inode in dir_info structure - ext2 does not set - * dotdot inode here, but instead in pass3 - should we? */ -int set_parent_dir(struct fsck_sb *sbp, uint64_t childblock, - uint64_t parentblock) -{ - struct dir_info *di; - - if(!find_di(sbp, childblock, &di)) { - if(di->dinode == childblock) { - if (di->treewalk_parent) { - log_err("Another directory (%"PRIu64 - ") already contains" - " this child - checking %"PRIu64"\n", - di->treewalk_parent, parentblock); - return 1; - } - di->treewalk_parent = parentblock; - } - } else { - log_err("Unable to find block %"PRIu64" in dir_info list\n", - childblock); - return -1; - } - - return 0; -} - -/* Set's the child's '..' directory inode number in dir_info structure */ -int set_dotdot_dir(struct fsck_sb *sbp, uint64_t childblock, - uint64_t parentblock) -{ - struct dir_info *di; - - if(!find_di(sbp, childblock, &di)) { - if(di->dinode == childblock) { - /* Special case for root inode because we set - * it earlier */ - if(di->dotdot_parent && sbp->sb.sb_root_di.no_addr - != di->dinode) { - /* This should never happen */ - log_crit("dotdot parent already set for" - " block %"PRIu64" -> %"PRIu64"\n", - childblock, di->dotdot_parent); - return -1; - } - di->dotdot_parent = parentblock; - } - } else { - log_err("Unable to find block %"PRIu64" in dir_info list\n", - childblock); - return -1; - } - - return 0; - -} - -static int check_eattr_indir(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - - return 0; -} -static int check_eattr_leaf(struct fsck_inode *ip, uint64_t block, - uint64_t parent, osi_buf_t **bh, void *private) -{ - osi_buf_t *leaf_bh; - - if(get_and_read_buf(ip->i_sbd, block, &leaf_bh, 0)){ - log_warn("Unable to read EA leaf block #%"PRIu64".\n", - block); - block_set(ip->i_sbd->bl, block, meta_inval); - return 1; - } - - - return 0; -} - -static int check_file_type(uint16_t de_type, uint8_t block_type) { - switch(block_type) { - case inode_dir: - if(de_type != GFS_FILE_DIR) - return 1; - break; - case inode_file: - if(de_type != GFS_FILE_REG) - return 1; - break; - case inode_lnk: - if(de_type != GFS_FILE_LNK) - return 1; - break; - case inode_blk: - if(de_type != GFS_FILE_BLK) - return 1; - break; - case inode_chr: - if(de_type != GFS_FILE_CHR) - return 1; - break; - case inode_fifo: - if(de_type != GFS_FILE_FIFO) - return 1; - break; - case inode_sock: - if(de_type != GFS_FILE_SOCK) - return 1; - break; - default: - log_err("Invalid block type\n"); - return -1; - break; - } - return 0; -} - -/* FIXME: should maybe refactor this a bit - but need to deal with - * FIXMEs internally first */ -int check_dentry(struct fsck_inode *ip, struct gfs_dirent *dent, - struct gfs_dirent *prev_de, - osi_buf_t *bh, char *filename, int *update, - uint16_t *count, void *priv) -{ - struct fsck_sb *sbp = ip->i_sbd; - struct block_query q = {0}; - char tmp_name[MAX_FILENAME]; - uint64_t entryblock; - struct dir_status *ds = (struct dir_status *) priv; - int error; - struct fsck_inode *entry_ip = NULL; - struct metawalk_fxns clear_eattrs = {0}; - struct gfs_dirent dentry, *de; - - memset(&dentry, 0, sizeof(struct gfs_dirent)); - gfs_dirent_in(&dentry, (char *)dent); - de = &dentry; - - clear_eattrs.check_eattr_indir = clear_eattr_indir; - clear_eattrs.check_eattr_leaf = clear_eattr_leaf; - clear_eattrs.check_eattr_entry = clear_eattr_entry; - clear_eattrs.check_eattr_extentry = clear_eattr_extentry; - - entryblock = de->de_inum.no_addr; - - /* Start of checks */ - if (de->de_rec_len < GFS_DIRENT_SIZE(de->de_name_len)){ - log_err("Dir entry with bad record or name length\n" - "\tRecord length = %u\n" - "\tName length = %u\n", - de->de_rec_len, - de->de_name_len); - block_set(sbp->bl, ip->i_num.no_addr, meta_inval); - return 1; - /* FIXME: should probably delete the entry here at the - * very least - maybe look at attempting to fix it */ - } - - if (de->de_hash != gfs_dir_hash(filename, de->de_name_len)){ - log_err("Dir entry with bad hash or name length\n" - "\tHash found = %u\n" - "\tName found = %s\n" - "\tName length found = %u\n" - "\tHash expected = %u\n", - de->de_hash, - filename, - de->de_name_len, - gfs_dir_hash(filename, de->de_name_len)); - return 1; - } - /* FIXME: This should probably go to the top of the fxn, and - * references to filename should be replaced with tmp_name */ - memset(tmp_name, 0, MAX_FILENAME); - if(de->de_name_len < MAX_FILENAME){ - strncpy(tmp_name, filename, de->de_name_len); - } else { - strncpy(tmp_name, filename, MAX_FILENAME - 1); - } - - if(check_range(ip->i_sbd, entryblock)) { - log_err("Block # referenced by directory entry %s is out of range\n", - tmp_name); - if(query(ip->i_sbd, "Clear directory entry tp out of range block? (y/n) ")) { - log_err("Clearing %s\n", tmp_name); - if(dirent_del(ip, bh, prev_de, dent)) - log_err("Error encountered while removing bad " - "directory entry. Skipping.\n"); - return 1; - } else { - log_err("Directory entry to out of range block remains\n"); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - if(block_check(sbp->bl, de->de_inum.no_addr, &q)) { - stack; - return -1; - } - /* Get the status of the directory inode */ - if(q.bad_block) { - /* This entry's inode has bad blocks in it */ - - /* FIXME: user interface */ - /* FIXME: do i want to kill the inode here? */ - /* Handle bad blocks */ - log_err("Found a bad directory entry: %s\n", filename); - - if(query(sbp, "Clear entry to inode containing bad blocks? (y/n)")) { - - load_inode(sbp, de->de_inum.no_addr, &entry_ip); - check_inode_eattr(entry_ip, &clear_eattrs); - free_inode(&entry_ip); - - /* FIXME: make sure all blocks referenced by - * this inode are cleared in the bitmap */ - - dirent_del(ip, bh, prev_de, dent); - - block_set(sbp->bl, de->de_inum.no_addr, meta_inval); - return 1; - } else { - log_warn("Entry to inode containing bad blocks remains\n"); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - - } - if(q.block_type != inode_dir && q.block_type != inode_file && - q.block_type != inode_lnk && q.block_type != inode_blk && - q.block_type != inode_chr && q.block_type != inode_fifo && - q.block_type != inode_sock) { - log_err("Found directory entry '%s' in %"PRIu64" to something" - " not a file or directory!\n", tmp_name, - ip->i_num.no_addr); - log_debug("block #%"PRIu64" in %"PRIu64"\n", - de->de_inum.no_addr, ip->i_num.no_addr); - - if(query(sbp, "Clear directory entry to non-inode block? (y/n) ")) { - /* FIXME: make sure all blocks referenced by - * this inode are cleared in the bitmap */ - - if(dirent_del(ip, bh, prev_de, dent)) - log_err("Error encountered while removing bad " - "directory entry. Skipping.\n"); - log_warn("Directory entry '%s' cleared\n", tmp_name); - return 1; - } else { - log_err("Directory entry to non-inode block remains\n"); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - - - error = check_file_type(de->de_type, q.block_type); - if(error < 0) { - stack; - return -1; - } - if(error > 0) { - log_warn("Type in dir entry (%s, %"PRIu64") conflicts with " - "type in dinode. (Dir entry is stale.)\n", - tmp_name, de->de_inum.no_addr); - if(query(sbp, "Clear stale directory entry? (y/n) ")) { - load_inode(sbp, de->de_inum.no_addr, &entry_ip); - check_inode_eattr(entry_ip, &clear_eattrs); - free_inode(&entry_ip); - - if(dirent_del(ip, bh, prev_de, dent)) - log_err("Error encountered while removing bad " - "directory entry. Skipping.\n"); - return 1; - } else { - log_err("Stale directory entry remains\n"); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - - - if(!strcmp(".", tmp_name)) { - log_debug("Found . dentry\n"); - - if(ds->dotdir) { - log_err("already found '.' entry\n"); - if(query(sbp, "Clear duplicate '.' entry? (y/n) ")) { - - load_inode(sbp, de->de_inum.no_addr, &entry_ip); - check_inode_eattr(entry_ip, &clear_eattrs); - free_inode(&entry_ip); - - dirent_del(ip, bh, prev_de, dent); - return 1; - } else { - log_err("Duplicate '.' entry remains\n"); - /* FIXME: Should we continue on here - * and check the rest of the '.' - * entry? */ - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - - /* GFS does not rely on '.' being in a certain - * location */ - - /* check that '.' refers to this inode */ - if(de->de_inum.no_addr != ip->i_num.no_addr) { - log_err("'.' entry's value incorrect." - " Points to %"PRIu64 - " when it should point to %" - PRIu64".\n", - de->de_inum.no_addr, - ip->i_num.no_addr); - if(query(sbp, "remove '.' reference? (y/n) ")) { - load_inode(sbp, de->de_inum.no_addr, &entry_ip); - check_inode_eattr(entry_ip, &clear_eattrs); - free_inode(&entry_ip); - - dirent_del(ip, bh, prev_de, dent); - return 1; - - } else { - log_err("Invalid '.' reference remains\n"); - /* Not setting ds->dotdir here since - * this '.' entry is invalid */ - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - - ds->dotdir = 1; - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - - return 0; - } - if(!strcmp("..", tmp_name)) { - log_debug("Found .. dentry\n"); - if(ds->dotdotdir) { - log_err("already found '..' entry\n"); - if(query(sbp, "Clear duplicate '..' entry? (y/n) ")) { - - load_inode(sbp, de->de_inum.no_addr, &entry_ip); - check_inode_eattr(entry_ip, &clear_eattrs); - free_inode(&entry_ip); - - dirent_del(ip, bh, prev_de, dent); - *update = 1; - return 1; - } else { - log_err("Duplicate '..' entry remains\n"); - /* FIXME: Should we continue on here - * and check the rest of the '..' - * entry? */ - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - - if(q.block_type != inode_dir) { - log_err("Found '..' entry pointing to" - " something that's not a directory"); - if(query(sbp, "Clear bad '..' directory entry? (y/n) ")) { - load_inode(sbp, de->de_inum.no_addr, &entry_ip); - check_inode_eattr(entry_ip, &clear_eattrs); - free_inode(&entry_ip); - - dirent_del(ip, bh, prev_de, dent); - *update = 1; - return 1; - } else { - log_err("Bad '..' directory entry remains\n"); - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - /* GFS does not rely on '..' being in a - * certain location */ - - /* Add the address this entry is pointing to - * to this inode's dotdot_parent in - * dir_info */ - if(set_dotdot_dir(sbp, ip->i_num.no_addr, - entryblock)) { - stack; - return -1; - } - - ds->dotdotdir = 1; - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - - /* After this point we're only concerned with - * directories */ - if(q.block_type != inode_dir) { - log_debug("Found non-dir inode dentry\n"); - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - - log_debug("Found plain directory dentry\n"); - error = set_parent_dir(sbp, entryblock, ip->i_num.no_addr); - if(error > 0) { - log_err("Hard link to block %"PRIu64" detected.\n", filename, entryblock); - - if(query(sbp, "Clear hard link to directory? (y/n) ")) { - *update = 1; - - dirent_del(ip, bh, prev_de, dent); - log_warn("Directory entry %s cleared\n", filename); - - return 1; - } else { - log_err("Hard link to directory remains\n"); - *update = 1; - (*count)++; - ds->entry_count++; - return 0; - } - } - else if (error < 0) { - stack; - return -1; - } - increment_link(sbp, de->de_inum.no_addr); - *update = 1; - (*count)++; - ds->entry_count++; - /* End of checks */ - return 0; -} - - -struct metawalk_fxns pass2_fxns = { - .private = NULL, - .check_leaf = check_leaf, - .check_metalist = NULL, - .check_data = NULL, - .check_eattr_indir = check_eattr_indir, - .check_eattr_leaf = check_eattr_leaf, - .check_dentry = check_dentry, - .check_eattr_entry = NULL, -}; - - - - -int build_rooti(struct fsck_sb *sbp) -{ - struct fsck_inode *ip; - osi_buf_t *bh; - get_and_read_buf(sbp, GFS_SB_ADDR >> sbp->fsb2bb_shift, &bh, 0); - /* Create a new inode ondisk */ - create_inode(sbp, GFS_FILE_DIR, &ip); - /* Attach it to the superblock's sb_root_di address */ - sbp->sb.sb_root_di.no_addr = - sbp->sb.sb_root_di.no_formal_ino = ip->i_num.no_addr; - /* Write out sb change */ - gfs_sb_out(&sbp->sb, BH_DATA(bh)); - write_buf(sbp, bh, 1); - relse_buf(sbp, bh); - sbp->rooti = ip; - - if(fs_dir_add(ip, &(osi_filename_t){".", 1}, - &(ip->i_num), ip->i_di.di_type)){ - stack; - log_err("Unable to add "." entry to new root inode\n"); - return -1; - } - - if(fs_dir_add(ip, &(osi_filename_t){"..", 2}, - &ip->i_num, ip->i_di.di_type)){ - stack; - log_err("Unable to add ".." entry to new root inode\n"); - return -1; - } - - block_set(sbp->bl, ip->i_num.no_addr, inode_dir); - add_to_dir_list(sbp, ip->i_num.no_addr); - - /* Attach l+f to it */ - if(fs_mkdir(sbp->rooti, "l+f", 00700, &(sbp->lf_dip))){ - log_err("Unable to create/locate l+f directory.\n"); - return -1; - } - - if(sbp->lf_dip){ - log_debug("Lost and Found directory inode is at " - "block #%"PRIu64".\n", - sbp->lf_dip->i_num.no_addr); - } - block_set(sbp->bl, sbp->lf_dip->i_num.no_addr, inode_dir); - - add_to_dir_list(sbp, sbp->lf_dip->i_num.no_addr); - - return 0; -} - -/* Check root inode and verify it's in the bitmap */ -int check_root_dir(struct fsck_sb *sbp) -{ - uint64_t rootblock; - struct dir_status ds = {0}; - struct fsck_inode *ip; - osi_buf_t b, *bh = &b; - osi_filename_t filename; - char tmp_name[256]; - int update=0, error = 0; - /* Read in the root inode, look at its dentries, and start - * reading through them */ - rootblock = sbp->sb.sb_root_di.no_addr; - - /* FIXME: check this block's validity */ - - if(block_check(sbp->bl, rootblock, &ds.q)) { - log_crit("Can't get root block %"PRIu64" from block list\n", - rootblock); - /* FIXME: Need to check if the root block is out of - * the fs range and if it is, rebuild it. Still can - * error out if the root block number is valid, but - * block_check fails */ - return -1; -/* if(build_rooti(sbp)) { - stack; - return -1; - }*/ - } - - /* if there are errors with the root inode here, we need to - * create a new root inode and get it all setup - of course, - * everything will be in l+f then, but we *need* a root inode - * before we can do any of that. - */ - if(ds.q.block_type != inode_dir) { - log_err("Block %"PRIu64" marked as root inode in" - " superblock not a directory\n", rootblock); - if(query(sbp, "Create new root inode? (y/n) ")) { - if(build_rooti(sbp)) { - stack; - return -1; - } - } else { - log_err("Cannot continue without valid root inode\n"); - return -1; - } - } - - rootblock = sbp->sb.sb_root_di.no_addr; - pass2_fxns.private = (void *) &ds; - if(ds.q.bad_block) { - /* First check that the directory's metatree is valid */ - load_inode(sbp, rootblock, &ip); - if(check_metatree(ip, &pass2_fxns)) { - stack; - free_inode(&ip); - return -1; - } - free_inode(&ip); - } - error = check_dir(sbp, rootblock, &pass2_fxns); - if(error < 0) { - stack; - return -1; - } - if (error > 0) { - block_set(sbp->bl, rootblock, meta_inval); - } - - if(get_and_read_buf(sbp, rootblock, &bh, 0)){ - log_err("Unable to retrieve block #%"PRIu64"\n", - rootblock); - block_set(sbp->bl, rootblock, meta_inval); - return -1; - } - - if(copyin_inode(sbp, bh, &ip)) { - stack; - relse_buf(sbp, bh); - return -1; - } - - if(check_inode_eattr(ip, &pass2_fxns)) { - stack; - return -1; - } - /* FIXME: Should not have to do this here - fs_dir_add reads - * the buffer too though, and commits the change to disk, so I - * have to reread the buffer after calling it if I'm going to - * make more changes */ - relse_buf(sbp, bh); - - if(!ds.dotdir) { - log_err("No '.' entry found\n"); - sprintf(tmp_name, "."); - filename.len = strlen(tmp_name); /* no trailing NULL */ - if(!(filename.name = malloc(sizeof(char) * filename.len))) { - log_err("Unable to allocate name string\n"); - stack; - return -1; - } - if(!(memset(filename.name, 0, sizeof(char) * filename.len))) { - log_err("Unable to zero name string\n"); - stack; - return -1; - } - memcpy(filename.name, tmp_name, filename.len); - log_warn("Adding '.' entry\n"); - if(fs_dir_add(ip, &filename, &(ip->i_num), - ip->i_di.di_type)){ - log_err("Failed to link "." entry to directory.\n"); - return -1; - } - - increment_link(ip->i_sbd, ip->i_num.no_addr); - ds.entry_count++; - free(filename.name); - update = 1; - } - free_inode(&ip); - if(get_and_read_buf(sbp, rootblock, &bh, 0)){ - log_err("Unable to retrieve block #%"PRIu64"\n", - rootblock); - block_set(sbp->bl, rootblock, meta_inval); - return -1; - } - - if(copyin_inode(sbp, bh, &ip)) { - stack; - relse_buf(sbp, bh); - return -1; - } - - if(ip->i_di.di_entries != ds.entry_count) { - log_err("Entries is %d - should be %d for %"PRIu64"\n", - ip->i_di.di_entries, ds.entry_count, ip->i_di.di_num.no_addr); - if(query(sbp, "Fix entries for %"PRIu64"? (y/n) ", - ip->i_di.di_num.no_addr)) { - ip->i_di.di_entries = ds.entry_count; - log_warn("Entries updated\n"); - update = 1; - } else { - log_err("Entries for %"PRIu64" left out of sync\n", - ip->i_di.di_num.no_addr); - } - } - - if(update) { - gfs_dinode_out(&ip->i_di, BH_DATA(bh)); - write_buf(sbp, bh, 0); - } - - free_inode(&ip); - relse_buf(sbp, bh); - return 0; -} - -/* What i need to do in this pass is check that the dentries aren't - * pointing to invalid blocks...and verify the contents of each - * directory. and start filling in the directory info structure*/ - -/** - * pass2 - check pathnames - * - * verify root inode - * directory name length - * entries in range - */ -int pass2(struct fsck_sb *sbp, struct options *opts) -{ - uint64_t i; - struct block_query q; - struct dir_status ds = {0}; - struct fsck_inode *ip; - osi_buf_t b, *bh = &b; - osi_filename_t filename; - char tmp_name[256]; - if(check_root_dir(sbp)) { - stack; - return -1; - } - int error = 0; - - log_info("Checking directory inodes.\n"); - /* Grab each directory inode, and run checks on it */ - for(i = 0; i < sbp->last_fs_block; i++) { - - warm_fuzzy_stuff(i); - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - - /* Skip the root inode - it's checked above */ - if(i == sbp->sb.sb_root_di.no_addr) - continue; - - if(block_check(sbp->bl, i, &q)) { - log_err("Can't get block %"PRIu64 " from block list\n", - i); - return -1; - } - - if(q.block_type != inode_dir) - continue; - - log_debug("Checking directory inode at block %"PRIu64"\n", i); - - - memset(&ds, 0, sizeof(ds)); - pass2_fxns.private = (void *) &ds; - if(ds.q.bad_block) { - /* First check that the directory's metatree - * is valid */ - load_inode(sbp, i, &ip); - if(check_metatree(ip, &pass2_fxns)) { - stack; - free_inode(&ip); - return -1; - } - free_inode(&ip); - } - error = check_dir(sbp, i, &pass2_fxns); - if(error < 0) { - stack; - return -1; - } - if (error > 0) { - struct dir_info *di = NULL; - error = find_di(sbp, i, &di); - if(error < 0) { - stack; - return -1; - } - if(error == 0) { - /* FIXME: factor */ - if(query(sbp, "Remove directory entry for bad" - " inode %"PRIu64" in %"PRIu64 - "? (y/n)", i, di->treewalk_parent)) { - error = remove_dentry_from_dir(sbp, - di->treewalk_parent, - i); - if(error < 0) { - stack; - return -1; - } - if(error > 0) { - log_warn("Unable to find dentry for %" - PRIu64" in %"PRIu64"\n", - i, di->treewalk_parent); - } - log_warn("Directory entry removed\n"); - } else { - log_err("Directory entry to invalid inode remains\n"); - } - } - block_set(sbp->bl, i, meta_inval); - } - if(get_and_read_buf(sbp, i, &bh, 0)){ - /* This shouldn't happen since we were able to - * read it before */ - log_err("Unable to retrieve block #%"PRIu64 - " for directory\n", - i); - return -1; - } - - if(copyin_inode(sbp, bh, &ip)) { - stack; - relse_buf(sbp, bh); - return -1; - } - /* FIXME: Should not have to do this here - fs_dir_add reads - * the buffer too though, and commits the change to disk, so I - * have to reread the buffer after calling it if I'm going to - * make more changes */ - relse_buf(sbp, bh); - - if(!ds.dotdir) { - log_err("No '.' entry found\n"); - sprintf(tmp_name, "."); - filename.len = strlen(tmp_name); /* no trailing NULL */ - if(!(filename.name = malloc(sizeof(char) * filename.len))) { - log_err("Unable to allocate name string\n"); - stack; - return -1; - } - if(!memset(filename.name, 0, sizeof(char) * filename.len)) { - log_err("Unable to zero name string\n"); - stack; - return -1; - } - memcpy(filename.name, tmp_name, filename.len); - - if(fs_dir_add(ip, &filename, &(ip->i_num), - ip->i_di.di_type)){ - log_err("Failed to link "." entry to directory.\n"); - return -1; - } - - increment_link(ip->i_sbd, ip->i_num.no_addr); - ds.entry_count++; - free(filename.name); - - } - free_inode(&ip); - - if(get_and_read_buf(sbp, i, &bh, 0)){ - log_err("Unable to retrieve block #%"PRIu64"\n", - i); - block_set(sbp->bl, i, meta_inval); - return -1; - } - - if(copyin_inode(sbp, bh, &ip)) { - stack; - relse_buf(sbp, bh); - return -1; - } - if(ip->i_di.di_entries != ds.entry_count) { - log_err("Entries is %d - should be %d for %"PRIu64"\n", - ip->i_di.di_entries, ds.entry_count, - ip->i_di.di_num.no_addr); - ip->i_di.di_entries = ds.entry_count; - gfs_dinode_out(&ip->i_di, BH_DATA(bh)); - write_buf(sbp, bh, 0); - } - free_inode(&ip); - relse_buf(sbp, bh); - } - return 0; -} - - - diff --git a/gfs/gfs_fsck/pass3.c b/gfs/gfs_fsck/pass3.c deleted file mode 100644 index cc0ee72..0000000 --- a/gfs/gfs_fsck/pass3.c +++ /dev/null @@ -1,287 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include "osi_list.h" -#include "fsck_incore.h" -#include "fsck.h" -#include "inode.h" -#include "lost_n_found.h" -#include "block_list.h" -#include "fs_dir.h" -#include "link.h" -#include "metawalk.h" - -static int attach_dotdot_to(struct fsck_sb *sbp, uint64_t newdotdot, - uint64_t olddotdot, uint64_t block) -{ - osi_filename_t filename; - struct fsck_inode *ip, *pip; - - load_inode(sbp, block, &ip); - load_inode(sbp, newdotdot, &pip); - /* FIXME: Need to add some interactive - * options here and come up with a - * good default for non-interactive */ - /* FIXME: do i need to correct the - * '..' entry for this directory in - * this case? */ - - filename.len = strlen(".."); - if(!(filename.name = malloc(sizeof(char) * filename.len))) { - log_err("Unable to allocate name\n"); - stack; - return -1; - } - if(!memset(filename.name, 0, sizeof(char) * filename.len)) { - log_err("Unable to zero name\n"); - stack; - return -1; - } - memcpy(filename.name, "..", filename.len); - if(fs_dirent_del(ip, NULL, &filename)){ - log_warn("Unable to remove ".." directory entry.\n"); - } - else { - decrement_link(sbp, olddotdot); - } - if(fs_dir_add(ip, &filename, &pip->i_num, - pip->i_di.di_type)){ - log_err("Failed to link ".." entry to directory.\n"); - block_set(ip->i_sbd->bl, ip->i_num.no_addr, meta_inval); - free_inode(&ip); - free_inode(&pip); - return -1; - } - increment_link(sbp, newdotdot); - free_inode(&ip); - free_inode(&pip); - return 0; -} - -struct dir_info *mark_and_return_parent(struct fsck_sb *sbp, - struct dir_info *di) -{ - struct dir_info *pdi; - - struct block_query q_dotdot, q_treewalk; - - di->checked = 1; - - if(!di->treewalk_parent) { - return NULL; - } - - if(di->dotdot_parent != di->treewalk_parent) { - log_warn(".. and treewalk conections are not the same for %"PRIu64 - "\n", di->dinode); - log_notice("%"PRIu64" %"PRIu64"\n", di->dotdot_parent, di->treewalk_parent); - if(block_check(sbp->bl, di->dotdot_parent, &q_dotdot)) { - log_err("Unable to find block %"PRIu64 - " in block map\n", - di->dotdot_parent); - return NULL; - } - if(block_check(sbp->bl, di->treewalk_parent, &q_treewalk)) { - log_err("Unable to find block %"PRIu64 - " in block map\n", - di->treewalk_parent); - return NULL; - } - /* if the dotdot entry isn't a directory, but the - * treewalk is, treewalk is correct - if the treewalk - * entry isn't a directory, but the dotdot is, dotdot - * is correct - if both are directories, which do we - * choose? if neither are directories, we have a - * problem - need to move this directory into l+f - */ - if(q_dotdot.block_type != inode_dir) { - if(q_treewalk.block_type != inode_dir) { - log_err( "Orphaned directory, move to l+f\n"); - return NULL; - } - else { - log_warn("Treewalk parent is correct," - " fixing dotdot -> %"PRIu64"\n", - di->treewalk_parent); - attach_dotdot_to(sbp, di->treewalk_parent, - di->dotdot_parent, di->dinode); - di->dotdot_parent = di->treewalk_parent; - - } - } - else { - if(q_treewalk.block_type != inode_dir) { - int error = 0; - log_warn(".. parent is valid, but treewalk" - "is bad - reattaching to l+f"); - - /* FIXME: add a dinode for this entry instead? */ - if(query(sbp, "Remove directory entry for bad" - " inode %"PRIu64" in %"PRIu64 - "? (y/n)", di->dinode, - di->treewalk_parent)) { - error = remove_dentry_from_dir(sbp, - di->treewalk_parent, - di->dinode); - if(error < 0) { - stack; - return NULL; - } - if(error > 0) { - log_warn("Unable to find dentry for %" - PRIu64" in %"PRIu64"\n", - di->dinode, di->treewalk_parent); - } - log_warn("Directory entry removed\n"); - } else { - log_err("Directory entry to invalid inode remains\n"); - } - log_info("Marking directory unlinked\n"); - - return NULL; - } - else { - log_err("Both .. and treewalk parents are " - "directories, going with treewalk for " - "now...\n"); - attach_dotdot_to(sbp, di->treewalk_parent, - di->dotdot_parent, di->dinode); - di->dotdot_parent = di->treewalk_parent; - - } - } - } - else { - if(block_check(sbp->bl, di->dotdot_parent, &q_dotdot)) { - log_err("Unable to find parent block %"PRIu64 - " in block map\n", - di->dotdot_parent); - return NULL; - } - if(q_dotdot.block_type != inode_dir) { - log_err("Orphaned directory, move to l+f (Block #%" - PRIu64")\n", di->dinode); - return NULL; - } - } - find_di(sbp, di->dotdot_parent, &pdi); - - return pdi; - -} - -/** - * pass3 - check connectivity of directories - * - * handle disconnected directories - * handle lost+found directory errors (missing, not a directory, no space) - */ -int pass3(struct fsck_sb *sbp, struct options *opts) -{ - osi_list_t *tmp; - struct dir_info *di, *tdi; - struct fsck_inode *ip; - struct block_query q; - int i; - - find_di(sbp, sbp->sb.sb_root_di.no_addr, &di); - if(di) { - log_info("Marking root inode connected\n"); - di->checked = 1; - } - - /* Go through the directory list, working up through the parents - * until we find one that's been checked already. If we don't - * find a parent, put in lost+found. - */ - log_info("Checking directory linkage.\n"); - for(i = 0; i < FSCK_HASH_SIZE; i++) { - osi_list_foreach(tmp, &sbp->dir_hash[i]) { - di = osi_list_entry(tmp, struct dir_info, list); - while(!di->checked) { - /* FIXME: Change this so it returns success or - * failure and put the parent inode in a - * param */ - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - tdi = mark_and_return_parent(sbp, di); - - /* FIXME: Factor this ? */ - if(!tdi) { - if(block_check(sbp->bl, di->dinode, &q)) { - stack; - return -1; - } - if(q.bad_block) { - log_err("Found unlinked directory containing" - "bad block\n"); - if(query(sbp, "Clear unlinked directory with bad blocks? (y/n) ")) { - block_set(sbp->bl, di->dinode, block_free); - break; - } else { - log_err("Unlinked directory with bad blocks remains\n"); - } - } - if(q.block_type != inode_dir && - q.block_type != inode_file && - q.block_type != inode_lnk && - q.block_type != inode_blk && - q.block_type != inode_chr && - q.block_type != inode_fifo && - q.block_type != inode_sock) { - log_err("Unlinked block marked as inode not an inode\n"); - block_set(sbp->bl, di->dinode, block_free); - log_err("Cleared\n"); - break; - } - - log_err("Found unlinked directory %"PRIu64"\n", di->dinode); - load_inode(sbp, di->dinode, &ip); - /* Don't skip zero size directories - * with eattrs */ - if(!ip->i_di.di_size && !ip->i_di.di_eattr){ - log_err("Unlinked directory has zero size.\n"); - if(query(sbp, "Remove zero-size unlinked directory? (y/n) ")) { - block_set(sbp->bl, di->dinode, block_free); - free_inode(&ip); - break; - } else { - log_err("Zero-size unlinked directory remains\n"); - } - } - if(query(sbp, "Add unlinked directory to l+f? (y/n) ")) { - if(add_inode_to_lf(ip)) { - stack; - return -1; - } - log_warn("Directory relinked to l+f\n"); - } else { - log_err("Unlinked directory remains unlinked\n"); - } - free_inode(&ip); - break; - } - else { - log_debug("Directory at block %" PRIu64 " connected\n", - di->dinode); - } - di = tdi; - } - } - } - if(sbp->lf_dip) - log_debug("At end of pass3, l+f entries is %u\n", - sbp->lf_dip->i_di.di_entries); - return 0; -} diff --git a/gfs/gfs_fsck/pass4.c b/gfs/gfs_fsck/pass4.c deleted file mode 100644 index 8226df5..0000000 --- a/gfs/gfs_fsck/pass4.c +++ /dev/null @@ -1,194 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "stdio.h" -#include "fsck_incore.h" -#include "fsck.h" -#include "bio.h" -#include "fs_inode.h" -#include "inode_hash.h" -#include "inode.h" -#include "lost_n_found.h" - -/* Updates the link count of an inode to what the fsck has seen for - * link count */ -int fix_inode_count(struct fsck_sb *sbp, struct inode_info *ii, - struct fsck_inode *ip) -{ - log_info("Fixing inode count for %"PRIu64"\n", - ip->i_di.di_num.no_addr); - if(ip->i_di.di_nlink == ii->counted_links) - return 0; - ip->i_di.di_nlink = ii->counted_links; - - log_debug("Changing inode %"PRIu64" to have %u links\n", - ip->i_di.di_num.no_addr, ii->counted_links); - - fs_copyout_dinode(ip); - - return 0; -} - -int scan_inode_list(struct fsck_sb *sbp, osi_list_t *list) { - osi_list_t *tmp; - struct inode_info *ii; - struct fsck_inode *ip; - int lf_addition = 0; - struct block_query q; - - /* FIXME: should probably factor this out into a generic - * scanning fxn */ - osi_list_foreach(tmp, list) { - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - if(!(ii = osi_list_entry(tmp, struct inode_info, list))) { - log_crit("osi_list_foreach broken in scan_info_list!!\n"); - exit(1); - } - /* Don't check reference counts on the special gfs files */ - if((ii->inode == sbp->sb.sb_rindex_di.no_addr) || - (ii->inode == sbp->sb.sb_jindex_di.no_addr) || - (ii->inode == sbp->sb.sb_quota_di.no_addr) || - (ii->inode == sbp->sb.sb_license_di.no_addr)) - continue; - log_debug("Checking reference count on inode at block %"PRIu64 - "\n", ii->inode); - if(ii->counted_links == 0) { - log_err("Found unlinked inode at %"PRIu64"\n", - ii->inode); - if(block_check(sbp->bl, ii->inode, &q)) { - stack; - return -1; - } - if(q.bad_block) { - log_err("Unlinked inode contains" - "bad blocks\n", - ii->inode); - if(query(sbp, "Clear unlinked inode with bad blocks? (y/n) ")) { - block_set(sbp->bl, ii->inode, block_free); - continue; - } else { - log_err("Unlinked inode with bad blocks not cleared\n"); - } - } - if(q.block_type != inode_dir && - q.block_type != inode_file && - q.block_type != inode_lnk && - q.block_type != inode_blk && - q.block_type != inode_chr && - q.block_type != inode_fifo && - q.block_type != inode_sock) { - log_err("Unlinked block marked as inode not an inode\n"); - block_set(sbp->bl, ii->inode, block_free); - log_err("Cleared\n"); - continue; - } - if(load_inode(sbp, ii->inode, &ip)) { - stack; - return -1; - } - /* We don't want to clear zero-size files with - * eattrs - there might be relevent info in - * them. */ - if(!ip->i_di.di_size && !ip->i_di.di_eattr){ - log_err("Unlinked inode has zero size\n"); - if(query(sbp, "Clear zero-size unlinked inode? (y/n) ")) { - block_set(sbp->bl, ii->inode, block_free); - free_inode(&ip); - continue; - } - - } - if(query(sbp, "Add unlinked inode to l+f? (y/n)")) { - if(add_inode_to_lf(ip)) { - stack; - free_inode(&ip); - return -1; - } - else { - fix_inode_count(sbp, ii, ip); - lf_addition = 1; - } - } else { - log_err("Unlinked inode left unlinked\n"); - } - free_inode(&ip); - } - else if(ii->link_count != ii->counted_links) { - log_err("Link count inconsistent for inode %"PRIu64 - " - %u %u\n", - ii->inode, ii->link_count, ii->counted_links); - /* Read in the inode, adjust the link count, - * and write it back out */ - if(query(sbp, "Update link count for inode %" - PRIu64"? (y/n) ", ii->inode)) { - load_inode(sbp, ii->inode, &ip); - fix_inode_count(sbp, ii, ip); - free_inode(&ip); - log_warn("Link count updated for inode %" - PRIu64"\n", ii->inode); - } else { - log_err("Link count for inode %" - PRIu64" still incorrect\n", ii->inode); - } - } - log_debug("block %"PRIu64" has link count %d\n", ii->inode, - ii->link_count); - } - - if (lf_addition) { - if(!(ii = inode_hash_search(sbp->inode_hash, - sbp->lf_dip->i_num.no_addr))) { - log_crit("Unable to find l+f inode in inode_hash!!\n"); - return -1; - } else { - fix_inode_count(sbp, ii, sbp->lf_dip); - } - } - - - return 0; -} - -/** - * pass4 - Check reference counts (pass 2 & 6 in current fsck) - * - * handle unreferenced files - * lost+found errors (missing, not a directory, no space) - * adjust link count - * handle unreferenced inodes of other types - * handle bad blocks - */ -int pass4(struct fsck_sb *sbp, struct options *opts) -{ - uint32_t i; - osi_list_t *list; - if(sbp->lf_dip) - log_debug("At beginning of pass4, l+f entries is %u\n", - sbp->lf_dip->i_di.di_entries); - log_info("Checking inode reference counts.\n"); - for (i = 0; i < FSCK_HASH_SIZE; i++) { - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - list = &sbp->inode_hash[i]; - if(scan_inode_list(sbp, list)) { - stack; - return -1; - } - } - - if(sbp->lf_dip) - log_debug("At end of pass4, l+f entries is %u\n", - sbp->lf_dip->i_di.di_entries); - return 0; -} diff --git a/gfs/gfs_fsck/pass5.c b/gfs/gfs_fsck/pass5.c deleted file mode 100644 index 5546503..0000000 --- a/gfs/gfs_fsck/pass5.c +++ /dev/null @@ -1,378 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include "fsck_incore.h" -#include "fsck.h" -#include "ondisk.h" -#include "fs_bits.h" -#include "bio.h" -#include "util.h" - -#ifdef DEBUG -int rgrp_countbits(unsigned char *buffer, unsigned int buflen, - uint32_t *bit_array) -{ - unsigned char *byte, *end; - unsigned int bit; - unsigned char state; - - byte = buffer; - bit = 0; - end = buffer + buflen; - - while (byte < end){ - state = ((*byte >> bit) & GFS_BIT_MASK); - switch (state) { - case GFS_BLKST_FREE: - bit_array[0]++; - break; - case GFS_BLKST_USED: - bit_array[1]++; - break; - case GFS_BLKST_FREEMETA: - bit_array[2]++; - break; - case GFS_BLKST_USEDMETA: - bit_array[3]++; - break; - default: - log_err("Invalid state %d found at byte %u, bit %u\n", - state, byte, bit); - return -1; - break; - } - - bit += GFS_BIT_SIZE; - if (bit >= 8){ - bit = 0; - byte++; - } - } - return 0; -} - -int fsck_countbits(struct fsck_sb *sbp, uint64_t start_blk, uint64_t count, - uint32_t *bit_array) -{ - uint64_t i; - struct block_query q; - for(i = start_blk; i < start_blk+count; i++) { - block_check(sbp->bl, i, &q); - switch(q.block_type) { - case block_free: - bit_array[0]++; - break; - case block_used: - bit_array[1]++; - break; - case meta_free: - case meta_inval: - bit_array[2]++; - break; - case indir_blk: - case inode_dir: - case inode_file: - case leaf_blk: - case journal_blk: - case meta_other: - case meta_eattr: - bit_array[3]++; - break; - default: - log_err("Invalid state %d found at block%"PRIu64"\n", - mark, i); - return -1; - break; - } - } - return 0; -} - - -int count_bmaps(struct fsck_rgrp *rgp) -{ - uint32_t i; - uint32_t bit_array_rgrp[4] = {0}; - uint32_t bit_array_fsck[4] = {0}; - fs_bitmap_t *bits; - - for(i = 0; i < rgp->rd_ri.ri_length; i++) { - bits = &rgp->rd_bits[i]; - rgrp_countbits(BH_DATA(rgp->rd_bh[i]) + bits->bi_offset, - bits->bi_len, bit_array_rgrp); - } - log_err("rgrp: free %u used %u meta_free %u meta_used %u\n", - bit_array_rgrp[0], bit_array_rgrp[1], - bit_array_rgrp[2], bit_array_rgrp[3]); - fsck_countbits(rgp->rd_sbd, rgp->rd_ri.ri_data1, - rgp->rd_ri.ri_data, bit_array_fsck); - log_err("fsck: free %u used %u meta_free %u meta_used %u\n", - bit_array_fsck[0], bit_array_fsck[1], - bit_array_fsck[2], bit_array_fsck[3]); - - for(i = 0; i < 4; i++) { - if(bit_array_rgrp[i] != bit_array_fsck[i]) { - log_err("Bitmap count in index %d differ: " - "ondisk %d, fsck %d\n", i, - bit_array_rgrp[i], bit_array_fsck[i]); - } - } - return 0; -} -#endif /* DEBUG */ - -int convert_mark(enum mark_block mark, uint32_t *count) -{ - switch(mark) { - - case meta_inval: - /* Convert invalid metadata to free blocks */ - case block_free: - count[0]++; - return GFS_BLKST_FREE; - - case meta_free: - count[4]++; - return GFS_BLKST_FREEMETA; - - case block_used: - return GFS_BLKST_USED; - - case inode_dir: - case inode_file: - case inode_lnk: - case inode_blk: - case inode_chr: - case inode_fifo: - case inode_sock: - count[1]++; - return GFS_BLKST_USEDMETA; - - case indir_blk: - case leaf_blk: - case journal_blk: - case meta_other: - case meta_eattr: - count[3]++; - return GFS_BLKST_USEDMETA; - - default: - log_err("Invalid state %d found\n", mark); - return -1; - - } - return -1; -} - - -int check_block_status(struct fsck_sb *sbp, char *buffer, unsigned int buflen, - uint64_t *rg_block, uint64_t rg_data, uint32_t *count) -{ - unsigned char *byte, *end; - unsigned int bit; - unsigned char rg_status, block_status; - struct block_query q; - uint64_t block; - - byte = buffer; - bit = 0; - end = buffer + buflen; - - while(byte < end) { - rg_status = ((*byte >> bit) & GFS_BIT_MASK); - block = rg_data + *rg_block; - log_debug("Checking block %" PRIu64 "\n", block); - warm_fuzzy_stuff(block); - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - block_check(sbp->bl, block, &q); - - block_status = convert_mark(q.block_type, count); - - if(rg_status != block_status) { - log_debug("Ondisk is %u - FSCK thinks it is %u (%u)\n", - rg_status, block_status, q.block_type); - if((rg_status == GFS_BLKST_FREEMETA) && - (block_status == GFS_BLKST_FREE)) { - log_info("Converting free metadata block at %" - PRIu64" to a free data block\n", block); - if(!sbp->opts->no) { - if(fs_set_bitmap(sbp, block, block_status)) { - log_warn("Failed to convert free metadata block to free data block at %PRIu64.\n", block); - } - else { - log_info("Succeeded.\n"); - } - } - } - else { - - log_err("ondisk and fsck bitmaps differ at" - " block %"PRIu64"\n", block); - - if(query(sbp, "Fix bitmap for block %" - PRIu64"? (y/n) ", block)) { - if(fs_set_bitmap(sbp, block, block_status)) { - log_err("Failed.\n"); - } - else { - log_err("Succeeded.\n"); - } - } else { - log_err("Bitmap at block %"PRIu64 - " left inconsistent\n", block); - } - } - } - (*rg_block)++; - bit += GFS_BIT_SIZE; - if (bit >= 8){ - bit = 0; - byte++; - } - } - - return 0; -} - -#define FREE_COUNT 1 -#define USED_INODE_COUNT 2 -#define FREE_INODE_COUNT 4 -#define USED_META_COUNT 8 -#define FREE_META_COUNT 16 -#define CONVERT_FREEMETA_TO_FREE (FREE_COUNT | FREE_META_COUNT) - -int update_rgrp(struct fsck_rgrp *rgp, uint32_t *count, int rgcount) -{ - uint32_t i; - fs_bitmap_t *bits; - uint64_t rg_block = 0; - uint8_t bmap = 0; - - for(i = 0; i < rgp->rd_ri.ri_length; i++) { - bits = &rgp->rd_bits[i]; - - /* update the bitmaps */ - check_block_status(rgp->rd_sbd, - BH_DATA(rgp->rd_bh[i]) + bits->bi_offset, - bits->bi_len, &rg_block, - rgp->rd_ri.ri_data1, count); - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - } - - /* Compare the rgrps counters with what we found */ - if(rgp->rd_rg.rg_free != count[0]) { - bmap |= FREE_COUNT; - } - if(rgp->rd_rg.rg_useddi != count[1]) { - bmap |= USED_INODE_COUNT; - } - if(rgp->rd_rg.rg_freedi != count[2]) { - bmap |= FREE_INODE_COUNT; - } - if(rgp->rd_rg.rg_usedmeta != count[3]) { - bmap |= USED_META_COUNT; - } - if(rgp->rd_rg.rg_freemeta != count[4]) { - bmap |= FREE_META_COUNT; - } - - if(bmap && !(bmap & ~CONVERT_FREEMETA_TO_FREE)) { - log_notice("Converting %d unused metadata blocks to free data blocks...\n", - rgp->rd_rg.rg_freemeta - count[4]); - rgp->rd_rg.rg_free = count[0]; - rgp->rd_rg.rg_freemeta = count[4]; - gfs_rgrp_out(&rgp->rd_rg, BH_DATA(rgp->rd_bh[0])); - if(!rgp->rd_sbd->opts->no) { - write_buf(rgp->rd_sbd, rgp->rd_bh[0], 0); - } - } else if(bmap) { - /* actually adjust counters and write out to disk */ - if(bmap & FREE_COUNT) { - log_err("RG #%d free count inconsistent: is %u should be %u\n", - rgcount, rgp->rd_rg.rg_free, count[0] ); - rgp->rd_rg.rg_free = count[0]; - } - if(bmap & USED_INODE_COUNT) { - log_err("RG #%d used inode count inconsistent: is %u should be %u\n", - rgcount, rgp->rd_rg.rg_useddi, count[1]); - rgp->rd_rg.rg_useddi = count[1]; - } - if(bmap & FREE_INODE_COUNT) { - log_err("RG #%d free inode count inconsistent: is %u should be %u\n", - rgcount, rgp->rd_rg.rg_freedi, count[2]); - rgp->rd_rg.rg_freedi = count[2]; - } - if(bmap & USED_META_COUNT) { - log_err("RG #%d used meta count inconsistent: is %u should be %u\n", - rgcount, rgp->rd_rg.rg_usedmeta, count[3]); - rgp->rd_rg.rg_usedmeta = count[3]; - } - if(bmap & FREE_META_COUNT) { - log_err("RG #%d free meta count inconsistent: is %u should be %u\n", - rgcount, rgp->rd_rg.rg_freemeta, count[4]); - rgp->rd_rg.rg_freemeta = count[4]; - } - - if(query(rgp->rd_sbd, - "Update resource group counts? (y/n) ")) { - log_warn("Resource group counts updated\n"); - /* write out the rgrp */ - gfs_rgrp_out(&rgp->rd_rg, BH_DATA(rgp->rd_bh[0])); - write_buf(rgp->rd_sbd, rgp->rd_bh[0], 0); - } else { - log_err("Resource group counts left inconsistent\n"); - } - } - - return 0; -} - -/** - * pass5 - check resource groups - * - * fix free block maps - * fix used inode maps - */ -int pass5(struct fsck_sb *sbp, struct options *opts) -{ - osi_list_t *tmp; - struct fsck_rgrp *rgp = NULL; - uint32_t count[5]; - uint64_t rg_count = 1; - - /* Reconcile RG bitmaps with fsck bitmap */ - for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){ - if (skip_this_pass || fsck_abort) /* if asked to skip the rest */ - return 0; - log_info("Updating Resource Group %"PRIu64"\n", rg_count); - memset(count, 0, sizeof(*count) * 5); - rgp = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - - if(fs_rgrp_read(rgp, FALSE)){ - stack; - return -1; - } - /* Compare the bitmaps and report the differences */ - update_rgrp(rgp, count, rg_count); - rg_count++; - fs_rgrp_relse(rgp); - } - /* Fix up superblock info based on this - don't think there's - * anything to do here... */ - - - return 0; -} diff --git a/gfs/gfs_fsck/rgrp.c b/gfs/gfs_fsck/rgrp.c deleted file mode 100644 index cf8e3ed..0000000 --- a/gfs/gfs_fsck/rgrp.c +++ /dev/null @@ -1,637 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - -#include "util.h" -#include "bio.h" -#include "fs_bits.h" -#include "fs_inode.h" -#include "fsck_incore.h" -#include "fsck.h" -#include "rgrp.h" -#include "inode.h" - -/** - * fs_compute_bitstructs - Compute the bitmap sizes - * @rgd: The resource group descriptor - * - * Returns: 0 on success, -1 on error - */ -int fs_compute_bitstructs(struct fsck_rgrp *rgd) -{ - struct fsck_sb *sdp = rgd->rd_sbd; - fs_bitmap_t *bits; - uint32 length = rgd->rd_ri.ri_length; - uint32 bytes_left, bytes; - int x; - - /* Max size of an rg is 2GB. A 2GB RG with (minimum) 512-byte blocks - has 4194304 blocks. We can represent 4 blocks in one bitmap byte. - Therefore, all 4194304 blocks can be represented in 1048576 bytes. - Subtract a metadata header for each 512-byte block and we get - 488 bytes of bitmap per block. Divide 1048576 by 488 and we can - be assured we should never have more than 2149 of them. */ - if (length > 2149 || length == 0) { - log_err("Invalid length %u found in rindex.\n", length); - return -1; - } - if(!(rgd->rd_bits = (fs_bitmap_t *)malloc(length * sizeof(fs_bitmap_t)))) { - log_err("Unable to allocate bitmap structure\n"); - stack; - return -1; - } - if(!memset(rgd->rd_bits, 0, length * sizeof(fs_bitmap_t))) { - log_err("Unable to zero bitmap structure\n"); - stack; - return -1; - } - - bytes_left = rgd->rd_ri.ri_bitbytes; - - for (x = 0; x < length; x++){ - bits = &rgd->rd_bits[x]; - - if (length == 1){ - bytes = bytes_left; - bits->bi_offset = sizeof(struct gfs_rgrp); - bits->bi_start = 0; - bits->bi_len = bytes; - } - else if (x == 0){ - bytes = sdp->sb.sb_bsize - sizeof(struct gfs_rgrp); - bits->bi_offset = sizeof(struct gfs_rgrp); - bits->bi_start = 0; - bits->bi_len = bytes; - } - else if (x + 1 == length){ - bytes = bytes_left; - bits->bi_offset = sizeof(struct gfs_meta_header); - bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; - bits->bi_len = bytes; - } - else{ - bytes = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header); - bits->bi_offset = sizeof(struct gfs_meta_header); - bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; - bits->bi_len = bytes; - } - - bytes_left -= bytes; - } - - if(bytes_left){ - log_err( "fs_compute_bitstructs: Too many blocks in rgrp to " - "fit into available bitmap.\n"); - return -1; - } - - if((rgd->rd_bits[length - 1].bi_start + - rgd->rd_bits[length - 1].bi_len) * GFS_NBBY != rgd->rd_ri.ri_data){ - log_err( "fs_compute_bitstructs: # of blks in rgrp do not equal " - "# of blks represented in bitmap.\n" - "\tbi_start = %u\n" - "\tbi_len = %u\n" - "\tGFS_NBBY = %u\n" - "\tri_data = %u\n", - rgd->rd_bits[length - 1].bi_start, - rgd->rd_bits[length - 1].bi_len, - GFS_NBBY, - rgd->rd_ri.ri_data); - return -1; - } - - - if(!(rgd->rd_bh = (osi_buf_t **)malloc(length * sizeof(osi_buf_t *)))) { - log_err("Unable to allocate osi_buf structure\n"); - stack; - return -1; - } - if(!memset(rgd->rd_bh, 0, length * sizeof(osi_buf_t *))) { - log_err("Unable to zero osi_buf structure\n"); - stack; - return -1; - } - - return 0; -} - - -/** - * blk2rgrpd - Find resource group for a given data block number - * @sdp: The GFS superblock - * @n: The data block number - * - * Returns: Ths resource group, or NULL if not found - */ -struct fsck_rgrp *fs_blk2rgrpd(struct fsck_sb *sdp, uint64 blk) -{ - osi_list_t *tmp; - struct fsck_rgrp *rgd = NULL; - struct gfs_rindex *ri; - - for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){ - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - ri = &rgd->rd_ri; - - if (ri->ri_data1 <= blk && blk < ri->ri_data1 + ri->ri_data){ - break; - } else - rgd = NULL; - } - return rgd; -} - -/** - * fs_rgrp_read - read in the resource group information from disk. - * @rgd - resource group structure - * @repair_if_corrupted - If TRUE, rgrps found to be corrupt should be repaired - * according to the index. If FALSE, no corruption is fixed. - */ -int fs_rgrp_read(struct fsck_rgrp *rgd, int repair_if_corrupted) -{ - struct fsck_sb *sdp = rgd->rd_sbd; - unsigned int x, length = rgd->rd_ri.ri_length; - int error; - - if(rgd->rd_open_count){ - log_debug("rgrp already read...\n"); - rgd->rd_open_count++; - return 0; - } - - for (x = 0; x < length; x++){ - if(rgd->rd_bh[x]){ - log_err("Programmer error! Bitmaps are already present in rgrp.\n"); - exit(1); - } - error = get_and_read_buf(sdp, rgd->rd_ri.ri_addr + x, - &(rgd->rd_bh[x]), 0); - if (error) { - log_err("Unable to read rgrp from disk.\n"); - goto fail; - } - - if(check_meta(rgd->rd_bh[x], (x) ? GFS_METATYPE_RB : GFS_METATYPE_RG)){ - log_err("Block #%"PRIu64" (0x%"PRIx64") (%d of %d) is neither" - " GFS_METATYPE_RB nor GFS_METATYPE_RG.\n", - BH_BLKNO(rgd->rd_bh[x]), BH_BLKNO(rgd->rd_bh[x]), - (int)x+1, (int)length); - if (repair_if_corrupted) { - if (query(sdp, "Fix the RG? (y/n)")) { - log_err("Attempting to repair the RG.\n"); - if (x) { - struct gfs_meta_header mh; - - memset(&mh, 0, sizeof(mh)); - mh.mh_magic = GFS_MAGIC; - mh.mh_type = GFS_METATYPE_RB; - mh.mh_format = GFS_FORMAT_RB; - gfs_meta_header_out(&mh, - BH_DATA(rgd->rd_bh[x])); - } else { - memset(&rgd->rd_rg, 0, - sizeof(struct gfs_rgrp)); - rgd->rd_rg.rg_header.mh_magic = GFS_MAGIC; - rgd->rd_rg.rg_header.mh_type = - GFS_METATYPE_RG; - rgd->rd_rg.rg_header.mh_format = - GFS_FORMAT_RG; - rgd->rd_rg.rg_free = rgd->rd_ri.ri_data; - gfs_rgrp_out(&rgd->rd_rg, - BH_DATA(rgd->rd_bh[x])); - } - write_buf(sdp, rgd->rd_bh[x], BW_WAIT); - } - } - else { - error = -1; - goto fail; - } - } - } - - gfs_rgrp_in(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - rgd->rd_open_count = 1; - - return 0; - - fail: - for (x = 0; x < length; x++){ - if (rgd->rd_bh[x]) { - relse_buf(sdp, rgd->rd_bh[x]); - rgd->rd_bh[x] = NULL; - } - } - - log_err("Resource group or index is corrupted.\n"); - return error; -} - -void fs_rgrp_relse(struct fsck_rgrp *rgd) -{ - int x, length = rgd->rd_ri.ri_length; - - rgd->rd_open_count--; - if(rgd->rd_open_count){ - log_debug("rgrp still held...\n"); - } else { - for (x = 0; x < length; x++){ - if (rgd->rd_bh[x]) { - relse_buf(rgd->rd_sbd, rgd->rd_bh[x]); - rgd->rd_bh[x] = NULL; - } - } - } -} - -#if 0 /* no one calls this, so don't waste memory for it: */ -/** - * rgrp_verify - Verify that a resource group is consistent - * @sdp: the filesystem - * @rgd: the rgrp - * - * Returns: 0 if ok, -1 on error - */ -int fs_rgrp_verify(struct fsck_rgrp *rgd) -{ - fs_bitmap_t *bits = NULL; - uint32 length = rgd->rd_ri.ri_length; - uint32 count[4], tmp; - int buf, x; - - for (x = 0; x < 4; x++){ - count[x] = 0; - - for (buf = 0; buf < length; buf++){ - bits = &rgd->rd_bits[buf]; - count[x] += fs_bitcount(BH_DATA(rgd->rd_bh[buf]) + bits->bi_offset, - bits->bi_len, x); - } - } - - if(count[0] != rgd->rd_rg.rg_free){ - log_err("free data mismatch: %u != %u\n", - count[0], rgd->rd_rg.rg_free); - return -1; - } - - tmp = rgd->rd_ri.ri_data - - (rgd->rd_rg.rg_usedmeta + rgd->rd_rg.rg_freemeta) - - (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi) - - rgd->rd_rg.rg_free; - - if(count[1] != tmp){ - log_err("used data mismatch: %u != %u\n", - count[1], tmp); - return -1; - } - if(count[2] != rgd->rd_rg.rg_freemeta){ - log_err("free metadata mismatch: %u != %u\n", - count[2], rgd->rd_rg.rg_freemeta); - return -1; - } - - tmp = rgd->rd_rg.rg_usedmeta + - (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi); - - if(count[3] != tmp){ - log_err("used metadata mismatch: %u != %u\n", - count[3], tmp); - return -1; - } - return 0; -} -#endif - -/** - * fs_rgrp_recount - adjust block tracking numbers - * rgd: resource group - * - * The resource groups keep track of how many free blocks, used blocks, - * etc there are. This function readjusts those numbers based on the - * current state of the bitmap. - * - * Returns: 0 on success, -1 on failure - */ -int fs_rgrp_recount(struct fsck_rgrp *rgd){ - int i,j; - fs_bitmap_t *bits = NULL; - uint32 length = rgd->rd_ri.ri_length; - uint32 count[4], tmp; - - for(i=0; i < 4; i++){ - count[i] = 0; - for(j = 0; j < length; j++){ - bits = &rgd->rd_bits[j]; - count[i] += fs_bitcount(BH_DATA(rgd->rd_bh[j]) + bits->bi_offset, - bits->bi_len, i); - } - } - if(count[0] != rgd->rd_rg.rg_free){ - log_warn("\tAdjusting free block count (%u -> %u).\n", - rgd->rd_rg.rg_free, count[0]); - rgd->rd_rg.rg_free = count[0]; - } - if(count[2] != rgd->rd_rg.rg_freemeta){ - log_warn("\tAdjusting freemeta block count (%u -> %u).\n", - rgd->rd_rg.rg_freemeta, count[2]); - rgd->rd_rg.rg_freemeta = count[2]; - } - tmp = rgd->rd_rg.rg_usedmeta + - (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi); - - if(count[3] != tmp){ - int first = 1; - struct fsck_sb *sdp = rgd->rd_sbd; - uint32 useddi = 0; - uint32 freedi = 0; - uint64 block; - struct fsck_inode *ip; - - while (1){ /* count the used dinodes */ - if(next_rg_metatype(rgd, &block, - GFS_METATYPE_DI, first)){ - break; - } - first = 0; - if(load_inode(sdp, block, &ip)) { - stack; - continue; - } - - if (ip->i_di.di_flags & GFS_DIF_UNUSED){ - freedi++; - continue; - } - free_inode(&ip); - useddi++; - } - - if(useddi != rgd->rd_rg.rg_useddi){ - log_warn("\tAdjusting used dinode block count (%u -> %u).\n", - rgd->rd_rg.rg_useddi, useddi); - rgd->rd_rg.rg_useddi = useddi; - } - if(freedi != rgd->rd_rg.rg_freedi){ - log_warn("\tAdjusting free dinode block count (%u -> %u).\n", - rgd->rd_rg.rg_freedi, freedi); - rgd->rd_rg.rg_freedi = freedi; - } - if(rgd->rd_rg.rg_usedmeta != count[3] - (freedi + useddi)){ - log_warn("\tAdjusting used meta block count (%u -> %u).\n", - rgd->rd_rg.rg_usedmeta, - (count[3] - (freedi + useddi))); - rgd->rd_rg.rg_usedmeta = count[3] - (freedi + useddi); - } - } - - tmp = rgd->rd_ri.ri_data - - (rgd->rd_rg.rg_usedmeta + rgd->rd_rg.rg_freemeta) - - (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi) - - rgd->rd_rg.rg_free; - - if(count[1] != tmp){ - log_err("Could not reconcile rgrp block counts.\n"); - return -1; - } - return 0; -} - - - -/** - * clump_alloc - Allocate a clump of metadata - * @rgd: the resource group descriptor - * @goal: the goal block in the RG - * - * Returns: 0 on success, -1 on failure - */ -int clump_alloc(struct fsck_rgrp *rgd, uint32 goal) -{ - struct fsck_sb *sdp = rgd->rd_sbd; - struct gfs_meta_header mh; - osi_buf_t *bh[GFS_META_CLUMP] = {0}; - uint32 block; - int i,j; - int error = 0; - - memset(&mh, 0, sizeof(struct gfs_meta_header)); - mh.mh_magic = GFS_MAGIC; - mh.mh_type = GFS_METATYPE_NONE; - - if(rgd->rd_rg.rg_free < GFS_META_CLUMP){ - log_debug(" Not enough free blocks in rgrp.\n"); - return -1; - } - - for (i = 0; i < GFS_META_CLUMP; i++){ - block = fs_blkalloc_internal(rgd, goal, - GFS_BLKST_FREE, - GFS_BLKST_FREEMETA, TRUE); - log_debug("Got block %u\n", block); - - if(block == BFITNOENT) { - log_err("Unable to get enough blocks\n"); - goto fail; - } - block += rgd->rd_ri.ri_data1; - block_set(rgd->rd_sbd->bl, block, meta_free); - if(get_buf(sdp, block, &(bh[i]))){ - log_err("Unable to allocate new buffer.\n"); - goto fail; - } - gfs_meta_header_out(&mh, BH_DATA(bh[i])); - - goal = block; - } - - log_debug("64 Meta blocks (%"PRIu64" - %"PRIu64"), allocated in rgrp 0x%lx\n", - (rgd->rd_ri.ri_data1 + block)-63, - (rgd->rd_ri.ri_data1 + block), - (unsigned long)rgd); - for (j = 0; j < GFS_META_CLUMP; j++){ - - error = write_buf(sdp, bh[j], BW_WAIT); - if (error){ - log_err("Unable to write allocated metablock to disk.\n"); - goto fail; - } - } - - if(rgd->rd_rg.rg_free < GFS_META_CLUMP){ - log_err("More blocks were allocated from rgrp " - "than are available.\n"); - goto fail; - } - rgd->rd_rg.rg_free -= GFS_META_CLUMP; - rgd->rd_rg.rg_freemeta += GFS_META_CLUMP; - - for (i = 0; i < GFS_META_CLUMP; i++) - relse_buf(sdp, bh[i]); - - return 0; - - fail: - log_debug("clump_alloc failing...\n"); - for(--i; i >=0; i--){ - fs_set_bitmap(sdp, BH_BLKNO(bh[i]), GFS_BLKST_FREE); - /*relse_buf(sdp, bh[i]);*/ - } - return -1; -} - - -/** - * fs_blkalloc - Allocate a data block - * @ip: the inode to allocate the data block for - * @block: the block allocated - * - * Returns: 0 on success, -1 on failure - */ -int fs_blkalloc(struct fsck_inode *ip, uint64 *block) -{ - osi_list_t *tmp; - struct fsck_sb *sdp = ip->i_sbd; - struct fsck_rgrp *rgd; - uint32 goal; - int same; - - for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){ - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - - if(!rgd){ - log_err( "fs_blkalloc: Bad rgrp list!\n"); - return -1; - } - - if(fs_rgrp_read(rgd, FALSE)){ - log_err( "fs_blkalloc: Unable to read rgrp.\n"); - return -1; - } - - if(!rgd->rd_rg.rg_free){ - fs_rgrp_relse(rgd); - continue; - } - - same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); - goal = (same) ? ip->i_di.di_goal_dblk : 0; - - *block = fs_blkalloc_internal(rgd, goal, - GFS_BLKST_FREE, - GFS_BLKST_USED, TRUE); - - log_debug("Got block %"PRIu64"\n", *block); - if(*block == BFITNOENT) { - fs_rgrp_relse(rgd); - continue; - } - if (!same){ - ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; - ip->i_di.di_goal_mblk = 0; - } - - *block += rgd->rd_ri.ri_data1; - ip->i_di.di_goal_dblk = *block; - - rgd->rd_rg.rg_free--; - - gfs_rgrp_out(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - if(write_buf(sdp, rgd->rd_bh[0], 0)){ - log_err( "Unable to write out rgrp block #%" - PRIu64".\n", - BH_BLKNO(rgd->rd_bh[0])); - fs_rgrp_relse(rgd); - return -1; - } - fs_rgrp_relse(rgd); - return 0; - } - - return 1; -} - - -/** - * fs_metaalloc - Allocate a metadata block to a file - * @ip: the file - * @block: the block allocated - * - * Returns: 0 on success, -1 on failure - */ -int fs_metaalloc(struct fsck_inode *ip, uint64 *block) -{ - osi_list_t *tmp; - struct fsck_sb *sdp = ip->i_sbd; - struct fsck_rgrp *rgd; - uint32 goal; - int same; - int error = 0; - - /* ATTENTION -- maybe we should try to allocate from goal rgrp first */ - for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){ - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - - if(!rgd){ - log_err( "fs_metaalloc: Bad rgrp list!\n"); - return -1; - } - - if(fs_rgrp_read(rgd, FALSE)){ - log_err( "fs_metaalloc: Unable to read rgrp.\n"); - return -1; - } - - same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); - goal = (same) ? ip->i_di.di_goal_mblk : 0; - - if (!rgd->rd_rg.rg_freemeta){ - error = clump_alloc(rgd, goal); - if (error){ - fs_rgrp_relse(rgd); - continue; - } - } - - - if(!rgd->rd_rg.rg_freemeta){ - fs_rgrp_relse(rgd); - continue; - } - *block = fs_blkalloc_internal(rgd, goal, - GFS_BLKST_FREEMETA, - GFS_BLKST_USEDMETA, TRUE); - log_debug("Got block %"PRIu64"\n", *block); - if(*block == BFITNOENT) { - fs_rgrp_relse(rgd); - continue; - } - if (!same){ - ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; - ip->i_di.di_goal_dblk = 0; - } - *block += rgd->rd_ri.ri_data1; - ip->i_di.di_goal_mblk = *block; - - rgd->rd_rg.rg_freemeta--; - rgd->rd_rg.rg_usedmeta++; - - gfs_rgrp_out(&rgd->rd_rg, BH_DATA(rgd->rd_bh[0])); - write_buf(sdp, rgd->rd_bh[0], 0); - fs_rgrp_relse(rgd); - /* if we made it this far, then we are ok */ - return 0; - } - - return -1; -} diff --git a/gfs/gfs_fsck/rgrp.h b/gfs/gfs_fsck/rgrp.h deleted file mode 100644 index af9b8f4..0000000 --- a/gfs/gfs_fsck/rgrp.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _RGRP_H -#define _RGRP_H - -struct fsck_sb; -struct fsck_rgrp; -struct fsck_inode; - -int fs_compute_bitstructs(struct fsck_rgrp *rgd); -struct fsck_rgrp *fs_blk2rgrpd(struct fsck_sb *sdp, uint64_t blk); - -int fs_rgrp_read(struct fsck_rgrp *rgd, int repair_if_corrupted); -void fs_rgrp_relse(struct fsck_rgrp *rgd); -int fs_rgrp_verify(struct fsck_rgrp *rgd); -int fs_rgrp_recount(struct fsck_rgrp *rgd); - -int clump_alloc(struct fsck_rgrp *rgd, uint32_t goal); -int fs_blkalloc(struct fsck_inode *ip, uint64_t *block); -int fs_metaalloc(struct fsck_inode *ip, uint64_t *block); - -#endif /* _RGRP_H */ diff --git a/gfs/gfs_fsck/super.c b/gfs/gfs_fsck/super.c deleted file mode 100644 index 55ff997..0000000 --- a/gfs/gfs_fsck/super.c +++ /dev/null @@ -1,1290 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdint.h> -#include <errno.h> - -#include "osi_list.h" -#include "osi_user.h" -#include "bio.h" -#include "util.h" -#include "file.h" -#include "rgrp.h" -#include "fsck.h" -#include "ondisk.h" -#include "super.h" -#include "fsck_incore.h" - -#ifndef BLKGETSIZE64 -#define BLKGETSIZE64 _IOR(0x12, 114, size_t) -#endif - -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) -#define ri_compare(rg, ondisk, expected, field, fmt) \ - if (ondisk.field != expected.field) { \ - log_warn("rgindex #%d " #field " discrepancy: index 0x%" fmt \ - " != expected: 0x%" fmt "\n", \ - rg + 1, ondisk.field, expected.field); \ - ondisk.field = expected.field; \ - rgindex_modified = TRUE; \ - } - -static uint64 total_journal_space; - -/** - * check_sb - Check superblock - * @sdp: the filesystem - * @sb: The superblock - * - * Checks the version code of the FS is one that we understand how to - * read and that the sizes of the various on-disk structures have not - * changed. - * - * Returns: 0 on success, -1 on failure - */ -static int check_sb(struct fsck_sb *sdp, struct gfs_sb *sb) -{ - int error = 0; - if (sb->sb_header.mh_magic != GFS_MAGIC || - sb->sb_header.mh_type != GFS_METATYPE_SB){ - log_crit("Either the super block is corrupted, or this " - "is not a GFS filesystem\n"); - log_debug("Header magic: %X Header Type: %X\n", - sb->sb_header.mh_magic, - sb->sb_header.mh_type); - error = -EINVAL; - goto out; - } - - /* If format numbers match exactly, we're done. */ - if (sb->sb_fs_format != GFS_FORMAT_FS || - sb->sb_multihost_format != GFS_FORMAT_MULTI){ - log_warn("Old file system detected.\n"); - } - - out: - return error; -} - - -/* - * read_sb: read the super block from disk - * sdp: in-core super block - * - * This function reads in the super block from disk and - * initializes various constants maintained in the super - * block - * - * Returns: 0 on success, -1 on failure. - */ -int read_sb(struct fsck_sb *sdp) -{ - osi_buf_t *bh; - uint64 space = 0; - unsigned int x; - int error; - error = get_and_read_buf(sdp, GFS_SB_ADDR >> sdp->fsb2bb_shift, &bh, 0); - if (error){ - log_crit("Unable to read superblock\n"); - goto out; - } - - gfs_sb_in(&sdp->sb, BH_DATA(bh)); - - relse_buf(sdp, bh); - - error = check_sb(sdp, &sdp->sb); - if (error) - goto out; - -/* FIXME: Need to verify all this */ - /* FIXME: What's this 9? */ - sdp->fsb2bb_shift = sdp->sb.sb_bsize_shift - 9; - sdp->diptrs = - (sdp->sb.sb_bsize - sizeof(struct gfs_dinode)) / - sizeof(uint64); - sdp->inptrs = - (sdp->sb.sb_bsize - sizeof(struct gfs_indirect)) / - sizeof(uint64); - sdp->jbsize = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header); - /* FIXME: Why is this /2 */ - sdp->hash_bsize = sdp->sb.sb_bsize / 2; - sdp->hash_ptrs = sdp->hash_bsize / sizeof(uint64); - sdp->heightsize[0] = sdp->sb.sb_bsize - - sizeof(struct gfs_dinode); - sdp->heightsize[1] = sdp->sb.sb_bsize * sdp->diptrs; - for (x = 2; ; x++){ - space = sdp->heightsize[x - 1] * sdp->inptrs; - /* FIXME: Do we really need this first check?? */ - if (space / sdp->inptrs != sdp->heightsize[x - 1] || - space % sdp->inptrs != 0) - break; - sdp->heightsize[x] = space; - } - sdp->max_height = x; - if(sdp->max_height > GFS_MAX_META_HEIGHT){ - log_err("Bad max metadata height.\n"); - error = -1; - goto out; - } - - sdp->jheightsize[0] = sdp->sb.sb_bsize - - sizeof(struct gfs_dinode); - sdp->jheightsize[1] = sdp->jbsize * sdp->diptrs; - for (x = 2; ; x++){ - space = sdp->jheightsize[x - 1] * sdp->inptrs; - if (space / sdp->inptrs != sdp->jheightsize[x - 1] || - space % sdp->inptrs != 0) - break; - sdp->jheightsize[x] = space; - } - sdp->max_jheight = x; - if(sdp->max_jheight > GFS_MAX_META_HEIGHT){ - log_err("Bad max jheight.\n"); - error = -1; - } - - out: - - return error; -} - - -/* - * ji_update - fill in journal info - * ip: the journal index inode - * - * Given the inode for the journal index, read in all - * the journal indexes. - * - * Returns: 0 on success, -1 on failure - */ -int ji_update(struct fsck_sb *sdp) -{ - struct fsck_inode *ip = sdp->jiinode; - char buf[sizeof(struct gfs_jindex)]; - unsigned int j; - int error=0; - - - if(ip->i_di.di_size % sizeof(struct gfs_jindex) != 0){ - log_err("The size reported in the journal index" - " inode is not a\n" - "\tmultiple of the size of a journal index.\n"); - return -1; - } - - if(!(sdp->jindex = (struct gfs_jindex *)malloc(ip->i_di.di_size))) { - log_err("Unable to allocate journal index\n"); - return -1; - } - if(!memset(sdp->jindex, 0, ip->i_di.di_size)) { - log_err("Unable to zero journal index\n"); - return -1; - } - total_journal_space = 0; - - for (j = 0; ; j++) { - struct gfs_jindex *journ; - error = readi(ip, buf, j * sizeof(struct gfs_jindex), - sizeof(struct gfs_jindex)); - if(!error) - break; - if (error != sizeof(struct gfs_jindex)){ - log_err("An error occurred while reading the" - " journal index file.\n"); - goto fail; - } - - journ = sdp->jindex + j; - gfs_jindex_in(journ, buf); - total_journal_space += journ->ji_nsegment * sdp->sb.sb_seg_size; - } - - - if(j * sizeof(struct gfs_jindex) != ip->i_di.di_size){ - log_err("journal inode size invalid\n"); - log_debug("j * sizeof(struct gfs_jindex) !=" - " ip->i_di.di_size\n"); - log_debug("%d != %d\n", - j * sizeof(struct gfs_jindex), ip->i_di.di_size); - goto fail; - } - sdp->journals = j; - log_debug("%d journals found.\n", j); - - return 0; - - fail: - free(sdp->jindex); - return -1; -} - -/* Print out debugging information in same format as gfs_edit. */ -int hexdump(uint64 startaddr, const unsigned char *lpBuffer, int len) -{ - const unsigned char *pointer, *ptr2; - int i; - uint64 l; - - pointer = (unsigned char *)lpBuffer; - ptr2 = (unsigned char *)lpBuffer; - l = 0; - while (l < len) { - log_info("%.8" PRIX64, startaddr + l); - for (i = 0; i < 16; i++) { /* first print it in hex */ - if (i % 4 == 0) - log_info(" "); - log_info("%02X", *pointer); - pointer++; - } - log_info(" ["); - for (i = 0; i < 16; i++) { /* now print it in character format */ - if ((*ptr2 >= ' ') && (*ptr2 <= '~')) - log_info("%c", *ptr2); - else - log_info("."); - ptr2++; - } - log_info("] \n"); - l += 16; - } - return (len); -} - - -/** - * rgrplength2bitblocks - Stolen from gfs_mkfs. - * - * @sdp: the superblock - * @length: the number of blocks in a RG - * - * Give a number of blocks in a RG, figure out the number of blocks - * needed for bitmaps. - * - * Returns: the number of bitmap blocks - */ - -uint32 rgrplength2bitblocks(struct fsck_sb *sdp, uint32 length) -{ - uint32 bitbytes; - uint32 old_blocks = 0, blocks; - int tries = 0; - - for (;;) { - bitbytes = (length - old_blocks) / GFS_NBBY; - blocks = 1; - - if (bitbytes > sdp->sb.sb_bsize - sizeof(struct gfs_rgrp)) { - bitbytes -= sdp->sb.sb_bsize - sizeof(struct gfs_rgrp); - blocks += DIV_RU(bitbytes, (sdp->sb.sb_bsize - - sizeof(struct gfs_meta_header))); - } - if (blocks == old_blocks) - break; - old_blocks = blocks; - if (tries++ > 10) { - blocks = 0; - break; - } - } - return blocks; -} - -/* - * gfs_rgindex_rebuild - rebuild a corrupt Resource Group (RG) index manually - * where trust_lvl == distrust - * - * If this routine is called, it means we have RGs in odd/unexpected places, - * and there is a corrupt RG. In other words, we can't trust the RG index - * is completely sane, and the RGs don't fit on nice neat fs boundaries. - * So we have no choice but to go through the count them by hand. - * We've tried twice to recover the RGs and RG index, and failed. This is - * our last chance to remedy the situation. - * - * In some cases, we have no choice but to trust the rgindex file. Since - * it is completely hidden from the users, if we find an inconsistency, - * it's safer to assume the index is correct and the RG is corrupt rather - * than the RG is correct and the index is bad. This routine goes to great - * lengths to determine which is the case and figure it out regardless. - * - * This routine tries to minimize performance impact by: - * 1. Skipping through the filesystem at known increments when possible. - * 2. Shuffle through every block when RGs are not found at the predicted - * locations. - * - * Note: A GFS filesystem is built by gfs_mkfs into several "subdevices." - * These are just logical divisions of the logical volume. The gfs_mkfs - * program considers two types of subdevices: RG-subdevices and journal - * subdevices. RG subdevices contain one or more RGs. Journal subdevices - * contain one or more journals. For the purposes of gfs_fsck, when I talk - * about subdevices, I'm talking about RG-subdevices only. For a freshly - * created GFS filesystem, the logical volume will be broken apart like this: - * - * RG-subdevice 0: n Resource Groups - * Journal subdevice - * RG-subdevice 1: n Resource Groups (same as RG-subdevice 0) - * - * If the filesystem has been resized via gfs_grow, there will be more - * RG-subdevices containing more RGs. However, gfs_fsck treats them all - * as "subdevice 2." - * - * NOTE: When giving messages to the users, I am referring to them as - * "sections" 1, 2, and 3 because "subdevice" sounds too confusing. - * - * If an RG is not found at a predicted location, it either means that - * there is a corrupted RG, or else the RG has been added after the fact - * by gfs_grow. We can only predict the locations for RGs within a subdevice, - * but the subdevice boundaries are not that predictable. (Actually, they - * are, but since we're dealing with a likely corrupt filesystem, I don't - * want to rely on good data too much to do it this way.) - * - * I am, however, going to rely on the fact that the first original subdevice - * will have the same number of RGs as the second original subdevice. - * Other RGs found after that will be considered "extra." - */ -int gfs_rgindex_rebuild(struct fsck_sb *sdp, osi_list_t *ret_list, - int *num_rgs) -{ - osi_buf_t *bh; /* buffer handle */ - uint64 subdevice_size, fs_total_size; - int number_of_rgs; /* #RGs this subdevice. - min of 2 per segment * 2 segments = 4 */ - int rg_number; /* real RG number (0 - x) */ - int subd; - int error, corrupt_rgs; - int rgi, rgs_per_subd; - uint64 blok, block_of_last_rg; - uint64 block_bump; - uint64 shortest_dist_btwn_rgs[2]; /* one for each subdevice */ - uint64 first_rg_dist[2], initial_first_rg_dist[2]; - struct fsck_rgrp *calc_rgd, *prev_rgd; - struct gfs_rgrp tmp_rgrp; - osi_list_t *tmp; - int rg_was_fnd = FALSE; - struct gfs_rindex buf, tmpndx; - uint64 fs_size_from_rgindex = 0; - int index_entries_per_subd = 0, subd_ndx_entry, rg; - uint64_t last_known_ri_addr = 0, prev_known_ri_addr = 0; - uint32_t last_known_ri_length = 0; - uint32_t last_known_ri_data = 0; - - osi_list_init(ret_list); - *num_rgs = 0; - /* Get the total size of the device */ - error = ioctl(sdp->diskfd, BLKGETSIZE64, - &fs_total_size); /* Size in bytes */ - fs_total_size /= sdp->sb.sb_bsize; - log_debug("fs_total_size = 0x%" PRIX64 " blocks.\n", fs_total_size); - block_of_last_rg = 0; - subdevice_size = 0; - rgs_per_subd = 0; - /* ----------------------------------------------------------------- */ - /* First, figure out the exact end of the second subdevice. */ - /* That will tell us where the third RG-subdevice should start. */ - /* We need to keep track of how many entries are in the index before */ - /* we hit the journal blocks. That will tell us how many index */ - /* entries will be in the first subdevice, and the second subdevice */ - /* should have the same number. After that, we don't care. */ - /* Note: we're using values in the rgindex, even though we don't */ - /* trust it. We're relatively okay because we're just trying to */ - /* find the highest RG value for the second subdevice. */ - /* ----------------------------------------------------------------- */ - subd = 0; - index_entries_per_subd = 0; - subd_ndx_entry = 0; - for (rg = 0; ; rg++) { - uint64 end_of_rg; - - error = readi(sdp->riinode, - (char *)&buf, rg * sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (!error) /* if end of file */ - break; /* stop looking */ - gfs_rindex_in(&tmpndx, (char *)&buf); /* read in the index */ - subd_ndx_entry++; - if (!subd) { /* if we're still in the first subdevice */ - if (tmpndx.ri_addr >= sdp->jindex->ji_addr + total_journal_space) { - subd++; /* this rgindex belongs to the second subdevice */ - prev_known_ri_addr = 0; - last_known_ri_addr = 0; - subd_ndx_entry = 1; - } - else { - index_entries_per_subd++; - /* Check if this is the last index entry for subdevice */ - if (tmpndx.ri_addr + tmpndx.ri_length + tmpndx.ri_data >= - sdp->jindex->ji_addr - GFS_NBBY) { - subd++; /* NEXT rgindex belongs to the second subdevice */ - subd_ndx_entry = 0; - prev_known_ri_addr = 0; - last_known_ri_addr = 0; - continue; - } - } - } - end_of_rg = tmpndx.ri_addr + tmpndx.ri_length + tmpndx.ri_data; - /* ----------------------------------------------------------------- */ - /* Make sure the rgindex looks relatively sane. After all, */ - /* at this stage of the game, we don't trust it. */ - /* ----------------------------------------------------------------- */ - if (subd && end_of_rg > sdp->jindex->ji_addr + total_journal_space && - end_of_rg <= fs_total_size) { /* looks relatively sane */ - /* Save some data values we can fall back on: */ - prev_known_ri_addr = last_known_ri_addr; - last_known_ri_addr = tmpndx.ri_addr; - last_known_ri_length = tmpndx.ri_length; - last_known_ri_data = tmpndx.ri_data; - if (fs_size_from_rgindex < end_of_rg) - fs_size_from_rgindex = end_of_rg; - /* Quit after we hit the same number of entries as 1st subdevice */ - if (subd_ndx_entry >= index_entries_per_subd) - break; - } - else if (!subd && end_of_rg < sdp->jindex->ji_addr && - end_of_rg > 0) { /* looks relatively sane */ - /* Save some data values we can fall back on: */ - prev_known_ri_addr = last_known_ri_addr; - last_known_ri_addr = tmpndx.ri_addr; - last_known_ri_length = tmpndx.ri_length; - last_known_ri_data = tmpndx.ri_data; - if (fs_size_from_rgindex < end_of_rg) - fs_size_from_rgindex = end_of_rg; - } - else { /* Otherwise we have a corrupt index entry */ - log_debug("Likely damage to rgindex entry %d.\n", - subd_ndx_entry + (subd * index_entries_per_subd)); - if (prev_known_ri_addr) { - /* Try to extrapolate from the previous one */ - tmpndx.ri_addr = last_known_ri_addr + - (last_known_ri_addr - prev_known_ri_addr); - tmpndx.ri_length = last_known_ri_length; - tmpndx.ri_data = last_known_ri_data; - log_debug("Extrapolating addr=0x%" PRIx64 ", length=0x%x, " - "data=%x\n", tmpndx.ri_addr, - tmpndx.ri_length, tmpndx.ri_data); - end_of_rg = tmpndx.ri_addr + tmpndx.ri_length + - tmpndx.ri_data; - if (end_of_rg > sdp->jindex->ji_addr + - total_journal_space && - end_of_rg <= fs_total_size) { /* looks relatively okay */ - /* Adjust data values we can fall back on: */ - last_known_ri_addr = tmpndx.ri_addr; - if (fs_size_from_rgindex < end_of_rg) - fs_size_from_rgindex = end_of_rg; - /* Quit after we hit the same number of entries as - the first subdevice/section */ - if (subd_ndx_entry >= index_entries_per_subd) - break; - } - } /* if we have a good previous */ - else { - log_debug("Not enough data to figure it out--skipped.\n"); - } - } /* corrupt RG index entry */ - } /* for all RGs in the index */ - log_debug("Index entries/section=%d, third section addr = 0x%"PRIx64"\n", - index_entries_per_subd, fs_size_from_rgindex); - initial_first_rg_dist[0] = first_rg_dist[0] = sdp->jindex->ji_addr - - ((GFS_SB_ADDR >> sdp->fsb2bb_shift) + 1); - initial_first_rg_dist[1] = first_rg_dist[1] = sdp->jindex->ji_addr; - /* ----------------------------------------------------------------- */ - /* Now let's figure out the space between RGs for the first subd, */ - /* and the second subd. Subsequent RGs will be unpredictable. */ - /* We need to know the distance between RGs because if one is */ - /* corrupt or overwritten, we need to salvage it at the correct */ - /* location. For example, if RG #2 is nuked, at first glance, it */ - /* appears as if our RGs are twice as far apart as they should be. */ - /* So we should chase down a couple to get more than one opinion. */ - /* If several RGs are nuked, sorry, I'll only go so far to recover. */ - /* This check will be slower because we have to read blocks 1 by 1. */ - /* Luckily, we only have to do a few this way. */ - /* Later, we can bump ahead by the amount we find here. */ - /* ----------------------------------------------------------------- */ - subdevice_size = sdp->jindex->ji_addr; /* addr of first journal */; - for (subd = 0; subd < 2; subd++) { - uint64 start_block; - - if (!subd) - start_block = (GFS_SB_ADDR >> sdp->fsb2bb_shift) + 1; - else - start_block = sdp->jindex->ji_addr + total_journal_space; - block_of_last_rg = start_block; - number_of_rgs = 0; - shortest_dist_btwn_rgs[subd] = subdevice_size; - for (blok = start_block; blok < fs_total_size; blok++) { - error = get_and_read_buf(sdp, blok, &bh, 0); - if (error){ - log_crit("Unable to read block 0x%" PRIX64 "\n", blok); - return -1; - } - if ((blok == start_block) || /* If first RG block or */ - !check_type(bh, GFS_METATYPE_RG)) { /* we found an RG */ - log_debug("%d:RG found at block 0x%" PRIx64 "\n", subd + 1, - blok); - /* If we spilled into the next subdevice, quit. */ - if (blok + GFS_NBBY >= start_block + subdevice_size) { - log_debug("This is in the next subdevice--skipping.\n"); - break; - } - gfs_rgrp_in(&tmp_rgrp, BH_DATA(bh)); - if (blok == start_block) { - shortest_dist_btwn_rgs[subd] = subdevice_size; - log_debug("Start of section %d.\n", subd + 1); - } - else { - uint64 rgdist; - - rgdist = blok - block_of_last_rg; - log_debug("%d:dist 0x%" PRIx64 " = 0x% " PRIx64 - " - 0x%" PRIx64, subd + 1, rgdist, - blok, block_of_last_rg); - /* ----------------------------------------------------- */ - /* We found another RG. Check to see if we need to set */ - /* the first_rg_dist based on whether it's still at its */ - /* initial value (i.e. the whole subdevice size). */ - /* The first rg distance is different from the rest */ - /* because of the superblock and 64K dead space */ - /* ----------------------------------------------------- */ - if (first_rg_dist[subd] == initial_first_rg_dist[subd]) - first_rg_dist[subd] = rgdist; - if (rgdist < shortest_dist_btwn_rgs[subd]) - { - shortest_dist_btwn_rgs[subd] = rgdist; - log_debug("(shortest so far)\n"); - } - else - log_debug("\n"); - } - number_of_rgs++; /* number of RGs this subdevice */ - /* --------------------------------------------------------- */ - /* Check to see if we're the last RG we want to examine. */ - /* If so, forget checking the next index entry and exit. */ - /* (The next index entry may be for the next RG anyway). */ - /* --------------------------------------------------------- */ - if (number_of_rgs >= 4 || - number_of_rgs >= index_entries_per_subd) - break; - /* --------------------------------------------------------- */ - /* Read in the index entry for the NEXT RG in line and */ - /* compare the RG size difference with what we know. */ - /* --------------------------------------------------------- */ - rg_number = number_of_rgs + (subd * index_entries_per_subd); - error = readi(sdp->riinode, (char *)&buf, - rg_number * sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (error) { /* if we read some data (no error really) */ - gfs_rindex_in(&tmpndx, (char *)&buf); - if (tmpndx.ri_addr > start_block && - tmpndx.ri_addr < fs_total_size && - tmpndx.ri_addr != blok && - tmpndx.ri_addr - blok < - shortest_dist_btwn_rgs[subd]) { - shortest_dist_btwn_rgs[subd] = - tmpndx.ri_addr - blok; - log_debug("Section %d RG %d(%d): shortest=0x%"PRIx64 - "\n", subd + 1, number_of_rgs, rg_number, - shortest_dist_btwn_rgs[subd]); - } - } - block_of_last_rg = blok; - /* --------------------------------------------------------- */ - /* We can't just check every block because some of the files */ - /* in the fs (i.e. inside an RG) might have data that looks */ - /* exactly like a valid RG. Sounds farfetched, but it's not, */ - /* based on my own experiences. */ - /* In my experience, the RG locations are spaced differently */ - /* from their used and free space numbers because of the way */ - /* gfs_mkfs puts them. In other words, the RG locations */ - /* according to the index will be different from the sum of */ - /* the space they take. Why? I don't know, but maybe it */ - /* has to do with the variable size of bitmaps. */ - /* At any rate, used+free can get us close, but not exact. */ - /* Therefore, we have to search for the RG after that. */ - /* --------------------------------------------------------- */ - if (!error && - ((tmp_rgrp.rg_useddi + tmp_rgrp.rg_free + 1) >> 2) == - (tmpndx.ri_addr >> 2)) { - blok = tmpndx.ri_addr - 1; /* go by the index */ - log_debug("I(0x%" PRIx64 ")\n", blok); - } - else { - blok += tmp_rgrp.rg_useddi + tmp_rgrp.rg_free; - log_debug("R(0x%" PRIx64 ")\n", blok); - } - } /* If first RG block or RG */ - relse_buf(sdp, bh); /* release the read buffer */ - } /* for blok */ - /* -------------------------------------------------------------- */ - /* Sanity-check our first_rg_dist. If RG #2 got nuked, the */ - /* first_rg_dist would measure from #1 to #3, which would be bad. */ - /* We need to take remedial measures to fix it (from the index). */ - /* -------------------------------------------------------------- */ - if (first_rg_dist[subd] >= shortest_dist_btwn_rgs[subd] + - (shortest_dist_btwn_rgs[subd] / 4)) { - log_debug("%d:Shortest dist is: 0x%" PRIx64 "\n", subd + 1, - shortest_dist_btwn_rgs[subd]); - /* read in the second RG index entry for this subd. */ - readi(sdp->riinode, (char *)&buf, - (1 + (subd * index_entries_per_subd)) * - sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - gfs_rindex_in(&tmpndx, (char *)&buf); - if (tmpndx.ri_addr > start_block) { /* sanity check */ - log_warn("RG %d is damaged: recomputing RG dist from index: ", - 2 + (subd * index_entries_per_subd)); - first_rg_dist[subd] = tmpndx.ri_addr - start_block; - log_warn("0x%" PRIx64 "\n", first_rg_dist[subd]); - } - else { - log_warn("RG index %d is damaged: extrapolating RG dist: ", - 2 + (subd * index_entries_per_subd)); - first_rg_dist[subd] = (subdevice_size - start_block) % - ((index_entries_per_subd - 1) * - shortest_dist_btwn_rgs[subd]); - log_warn("0x%" PRIx64 "\n", first_rg_dist[subd]); - } - } /* if first RG distance is within tolerance */ - log_debug("First RG distance: 0x%" PRIx64 "\n", first_rg_dist[subd]); - log_debug("Section %d: distance between RGs: 0x%" PRIx64 "\n", - subd + 1, shortest_dist_btwn_rgs[subd]); - log_debug("Section size: 0x%" PRIx64 "\n", subdevice_size); - } /* for subd */ - number_of_rgs = 0; /* reset this because it is reused below */ - /* ----------------------------------------------------------------- */ - /* Start reading the filesystem starting with the block after the */ - /* superblock, which should be the first RG. */ - /* The problem is that gfs_grow puts the RGs at unpredictable */ - /* locations. If the fs was only grown once, that would be */ - /* predictable. But if it grows twice, by different amounts, then */ - /* our RGs could be anywhere. After carefully studying the problem */ - /* I've determined that the best thing we can do is to trust the */ - /* rgindex and hope to God it's correct. That's the only way we're */ - /* going to be able to recover RGs in the third section. */ - /* ----------------------------------------------------------------- */ - prev_rgd = NULL; - block_bump = first_rg_dist[0]; - corrupt_rgs = 0; - for (subd = 0; subd < 3; subd++) { /* third subdevice is for all RGs - extended past the normal 2 with - gfs_grow, etc. */ - uint64 start_block, end_block; - - if (subd == 0) { - start_block = (GFS_SB_ADDR >> sdp->fsb2bb_shift) + 1; - end_block = subdevice_size - 1; - } - else if (subd == 1) { - start_block = sdp->jindex->ji_addr + total_journal_space; - /* Moral dilemma: should we go to the last block or should */ - /* we trust the index? If they're close to one another, */ - /* let's use the index. */ - if ((fs_size_from_rgindex >> 2) == - ((start_block + subdevice_size - 1) >> 2)) /* if we're close */ - end_block = fs_size_from_rgindex - 1; /* trust the index */ - else /* otherwise */ - end_block = start_block + subdevice_size - 1; /* go to end */ - } - else { - start_block = end_block + 1; - end_block = fs_total_size; - if (start_block + GFS_NBBY >= end_block) - break; - } - log_warn("Section %d: 0x%" PRIx64 " - 0x%" PRIx64 "\n", subd + 1, - start_block, end_block); - for (blok = start_block; blok <= end_block; blok += block_bump) { - uint64 fwd_block; - int bitmap_was_fnd; - - log_debug("Block 0x%" PRIx64 "\n", blok); - error = get_and_read_buf(sdp, blok, &bh, 0); - if (error) { - log_crit("Unable to read block 0x%" PRIX64 "\n", blok); - return -1; - } - rg_was_fnd = (!check_type(bh, GFS_METATYPE_RG)); - relse_buf(sdp, bh); /* release the read buffer */ - /* ------------------------------------------------------------- */ - /* For the first and second subdevice, we know the RG size. */ - /* Since we're bumping by that amount, this better be an RG. */ - /* ------------------------------------------------------------- */ - /* Allocate a new RG and index. */ - calc_rgd = (struct fsck_rgrp *)malloc(sizeof(struct fsck_rgrp)); - memset(calc_rgd, 0, sizeof(struct fsck_rgrp)); - calc_rgd->rd_sbd = sdp; /* hopefully this is not used */ - osi_list_add_prev(&calc_rgd->rd_list, ret_list); - calc_rgd->rd_ri.ri_length = 1; - calc_rgd->rd_ri.ri_addr = blok; - if (!rg_was_fnd) { /* if not an RG */ - /* ----------------------------------------------------- */ - /* This SHOULD be an RG but isn't. */ - /* ----------------------------------------------------- */ - corrupt_rgs++; - if (corrupt_rgs < 5) - log_debug("Missing or damaged RG at block 0x%" PRIx64 \ - "\n", blok); - else { - log_crit("Error: too many bad RGs.\n"); - return -1; - } - } - /* ------------------------------------------------ */ - /* Now go through and count the bitmaps for this RG */ - /* ------------------------------------------------ */ - bitmap_was_fnd = FALSE; - for (fwd_block = blok + 1; fwd_block < fs_total_size; - fwd_block++) { - error = get_and_read_buf(sdp, fwd_block, &bh, 0); - if (error){ - log_crit("Unable to read block 0x%" PRIX64 "\n", - fwd_block); - return -1; - } - bitmap_was_fnd = (!check_type(bh, GFS_METATYPE_RB)); - relse_buf(sdp, bh); - if (bitmap_was_fnd) /* if a bitmap */ - calc_rgd->rd_ri.ri_length++; - else - break; /* end of bitmap, so call it quits. */ - } /* for subsequent bitmaps */ - calc_rgd->rd_ri.ri_data1 = calc_rgd->rd_ri.ri_addr + - calc_rgd->rd_ri.ri_length; - if (prev_rgd) { - prev_rgd->rd_ri.ri_data = block_bump - - rgrplength2bitblocks(sdp, block_bump); - prev_rgd->rd_ri.ri_data -= prev_rgd->rd_ri.ri_data % - GFS_NBBY; - prev_rgd->rd_ri.ri_bitbytes = prev_rgd->rd_ri.ri_data / - GFS_NBBY; - log_debug("Prev ri_data set to: %" PRIx32 ".\n", - prev_rgd->rd_ri.ri_data); - /*prev_rgd->rd_ri.ri_data = block_bump;*/ - } - number_of_rgs++; - log_warn("%c RG %d at block 0x%" PRIX64 " %s", - (rg_was_fnd ? ' ' : '*'), number_of_rgs, blok, - (rg_was_fnd ? "intact" : "*** DAMAGED ***")); - rgs_per_subd++; - prev_rgd = calc_rgd; - block_of_last_rg = blok; - if (subd == 2) { /* if beyond the normal RGs into gfs_grow RGs */ - /* -------------------------------------------------------- */ - /* RG location is rounded down to the nearest multiple of */ - /* GFS_NBBY, so RG location is only known within a 4 block */ - /* range. It's better to use the rgindex to figure out */ - /* the address of the next RG and bump by the difference. */ - /* However, there's another complication: gfs_grow has */ - /* been known to add RGs to the index in a non-ascending */ - /* order. Therefore, we can't assume the Nth entry in the */ - /* index corresponds to the Nth RG on disk. Wish it was. */ - /* Instead, we have to read all of the rgindex until we */ - /* find an entry that has the smallest address greater than */ - /* the block we're on (blok). */ - /* -------------------------------------------------------- */ - uint64_t rgndx_next_block; - - rgndx_next_block = end_block; - for (rgi = 0; ; rgi++) { - error = readi(sdp->riinode, (char *)&buf, - rgi * sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (!error) /* if end of the rgindex */ - break; /* stop processing for more RGs */ - gfs_rindex_in(&tmpndx, (char *)&buf); - /* if this index entry is the next RG physically */ - if (tmpndx.ri_addr > blok && - tmpndx.ri_addr < rgndx_next_block) { - rgndx_next_block = tmpndx.ri_addr; /* remember it */ - } - } - block_bump = rgndx_next_block - blok; - if (rgndx_next_block == end_block) { /* if no more RGs */ - log_warn(" [length 0x%" PRIx64 "]\n", block_bump); - break; /* stop processing */ - } - } - else { - if (blok == start_block) - block_bump = first_rg_dist[subd]; - else - block_bump = shortest_dist_btwn_rgs[subd]; - } - if (block_bump != 1) - log_warn(" [length 0x%" PRIx64 "]\n", block_bump); - } /* for blocks in subdevice */ - } /* for subdevices */ - /* ------------------------------------------------------------------- */ - /* if we got to the end of the fs, we still need to fix the allocation */ - /* information for the very last RG. */ - /* ------------------------------------------------------------------- */ - if (prev_rgd && !prev_rgd->rd_ri.ri_data) { - log_debug("Prev ri_data set to: %" PRIx32 ".\n", block_bump); - prev_rgd->rd_ri.ri_data = block_bump - - rgrplength2bitblocks(sdp, block_bump); - prev_rgd->rd_ri.ri_data -= prev_rgd->rd_ri.ri_data % GFS_NBBY; - prev_rgd->rd_ri.ri_bitbytes = prev_rgd->rd_ri.ri_data / GFS_NBBY; - prev_rgd = NULL; /* make sure we don't use it later */ - } - /* else No previous to fix. */ - /* ---------------------------- */ - /* Now dump out the information */ - /* ---------------------------- */ - log_debug("RG index rebuilt as follows:\n"); - for (tmp = ret_list->next, rgi = 0; tmp != ret_list; - tmp = tmp->next, rgi++) { - calc_rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - log_debug("%d: %x / 0x%" PRIx64 " / 0x%08X / 0x%08X\n", - rgi + 1, calc_rgd->rd_ri.ri_length, calc_rgd->rd_ri.ri_data1, - calc_rgd->rd_ri.ri_data, calc_rgd->rd_ri.ri_bitbytes); - /*memset(rgindex_buf_ondisk, 0, sizeof(rgindex_buf_ondisk));*/ - /*gfs_rindex_out(&calc_rgd->rd_ri, rgindex_buf_ondisk);*/ - /* Note: rgindex_buf_ondisk is ONLY used for debug to see what - the entry would look like on disk. */ - /*hexdump(rgi*sizeof(struct gfs_rindex), rgindex_buf_ondisk, - sizeof(struct gfs_rindex));*/ - } - *num_rgs = number_of_rgs; - log_debug("Number of RGs = %d.\n", number_of_rgs); - return 0; -} - -/* - * gfs_rgindex_calculate - calculate what the rgindex should look like - * in a perfect world (trust_lvl == open_minded) - * - * Calculate what the rgindex should look like if no gfs_grow-like operations - * were performed, so we can later check if all RG index entries are sane. - * - * This function goes in blind, assuming the entire rgindex is destroyed. - * That way, we can rebuild it if really is trashed. - * - * However, this won't work if the filesystem has been extended or shrunk. - * If the RGs aren't where we expect them to be, we have to take more drastic - * measures to recover them. - * - * Assumes: journal index file is minimally sane. - * - * We need to check if the address and length values are okay. - * First RG should start after the superblock at block #x11 - * Number of RGs=subdevice size / (2^rgsize/block size) - * - * Returns: 0 on success, -1 on failure - * Sets: ret_list to a linked list of fsck_rgrp structs representing - * what we think the rgindex should really look like. - */ -int gfs_rgindex_calculate(struct fsck_sb *sdp, osi_list_t *ret_list, - int *num_rgs) -{ - osi_buf_t *bh; /* buffer handle */ - uint64 subdevice_size, adjust_subdevice_size, fs_total_size; - int number_of_rgs; /* min of 4 per segment * 2 segments = 8 */ - int rgnum_within_subdevice; - int first_half; - int error; - int rgi, rgs_per_subd; - uint64 subdevice_start; - uint64 addr, prev_addr, length, prev_length; - uint64 blocks; - struct fsck_rgrp *calc_rgd; - char rgindex_buf_ondisk[sizeof(struct gfs_rindex)]; - struct gfs_rindex buf, tmpndx; - - osi_list_init(ret_list); - *num_rgs = 0; - /* Get the total size of the device */ - error = ioctl(sdp->diskfd, BLKGETSIZE64, - &fs_total_size); /* Size in bytes */ - fs_total_size /= sdp->sb.sb_bsize; - log_debug("fs_total_size = 0x%" PRIX64 " blocks.\n", fs_total_size); - - /* The end of the first subdevice is also where the first journal is.*/ - subdevice_size = sdp->jindex->ji_addr; /* addr of 1st journal (blks) */ - log_debug("subdevice_size = 0x%" PRIX64 ".\n", subdevice_size); - - /* ----------------------------------------------------------------- */ - /* Read the first block of the subdevice and make sure it's an RG. */ - /* ----------------------------------------------------------------- */ - subdevice_start = fs_total_size - subdevice_size; - error = get_and_read_buf(sdp, subdevice_start, &bh, 0); - if (error){ - log_crit("Unable to read start of last subdevice.\n"); - return -1; - } - if(check_type(bh, GFS_METATYPE_RG)){ - log_warn("The middle RG is not on an even boundary (fs has grown?)\n"); - relse_buf(sdp, bh); - return -1; - } - log_debug("First RG is okay.\n"); - /* --------------------------------------------------------------------- */ - /* Calculate how many RGs there are supposed to be based on the */ - /* rgindex filesize. Remember that our trust level is open-minded here. */ - /* If the filesize of the rgindex file is not a multiple of our rgindex */ - /* structures, then something's wrong and we can't trust the index. */ - /* --------------------------------------------------------------------- */ - number_of_rgs = sdp->riinode->i_di.di_size / sizeof(struct gfs_rindex); - *num_rgs = number_of_rgs; - log_warn("number_of_rgs = %d.\n", number_of_rgs); - if (sdp->riinode->i_di.di_size % sizeof(struct gfs_rindex)) { - log_warn("WARNING: rgindex file is corrupt.\n"); - return -1; - } - /* --------------------------------------------------------------------- */ - /* Check to see if the filesystem has been extended via gfs_grow. */ - /* If so, our assumptions will be wrong and we can't continue. */ - /* Instead, we need to progress to level 3 and dig deeper for the RGs. */ - /* We'll know if the filesystem has been extended by whether or not the */ - /* RG that's midway is on the wrong side of the journals. */ - /* For example, if we have 50 RGs, we'd expect 25 to be on one side of */ - /* the journals, and 25 to be on the other side. If we find out that */ - /* RG number 25 (index 1, or 24 index 0) is on the other side, we grew. */ - /* --------------------------------------------------------------------- */ - rgi = (number_of_rgs / 2) - 1; - error = readi(sdp->riinode, - (char *)&buf, rgi * sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (!error) { /* if end of file */ - log_warn("Error reading RG index.\n"); - return -1; /* stop looking */ - } - gfs_rindex_in(&tmpndx, (char *)&buf); /* read in the index entry. */ - if (tmpndx.ri_addr >= sdp->jindex->ji_addr) { /* wrong side of journals */ - log_warn("This filesystem has probably been resized by gfs_grow.\n"); - return -1; /* stop looking */ - } - /* --------------------------------------------------------------------- */ - /* Now that we know how many RGs there should be, we can calculate */ - /* exactly where we think they should be and build our index with it. */ - /* --------------------------------------------------------------------- */ - rgs_per_subd = (number_of_rgs / 2); - for (rgi = 0; rgi < number_of_rgs; rgi++) { - - first_half = (rgi < rgs_per_subd ? 1 : 0); - adjust_subdevice_size = subdevice_size; - if (first_half) { - adjust_subdevice_size -= ((GFS_SB_ADDR >> sdp->fsb2bb_shift) + 1); - rgnum_within_subdevice = rgi; - } - else - rgnum_within_subdevice = rgi - rgs_per_subd; - prev_length = length; - if (rgnum_within_subdevice) - length = adjust_subdevice_size / rgs_per_subd; - else - length = adjust_subdevice_size - - (rgs_per_subd - 1) * (adjust_subdevice_size / rgs_per_subd); - - calc_rgd = (struct fsck_rgrp *)malloc(sizeof(struct fsck_rgrp)); - memset(calc_rgd, 0, sizeof(struct fsck_rgrp)); - calc_rgd->rd_sbd = sdp; /* hopefully this is not used */ - osi_list_add_prev(&calc_rgd->rd_list, ret_list); - prev_addr = addr; - if (!rgnum_within_subdevice) { - if (!rgi) { - /* The first RG immediately follows the superblock */ - addr = (GFS_SB_ADDR >> sdp->fsb2bb_shift) + 1; - } - else /* First RG on second subdevice is at the beginning of it */ - addr = subdevice_start; - } - else - addr = prev_addr + prev_length; - calc_rgd->rd_ri.ri_addr = addr; - log_debug("ri_addr[%d] = 0x%"PRIX64 " / ", rgi, - calc_rgd->rd_ri.ri_addr); - blocks = length - rgrplength2bitblocks(sdp, length); - blocks -= blocks % GFS_NBBY; - calc_rgd->rd_ri.ri_length = rgrplength2bitblocks(sdp, length); - calc_rgd->rd_ri.ri_data1 = calc_rgd->rd_ri.ri_addr + - calc_rgd->rd_ri.ri_length; - calc_rgd->rd_ri.ri_data = blocks; - calc_rgd->rd_ri.ri_bitbytes = calc_rgd->rd_ri.ri_data / GFS_NBBY; - log_info("%d / %08X / %08X / %08X\n", calc_rgd->rd_ri.ri_length, - calc_rgd->rd_ri.ri_data1, calc_rgd->rd_ri.ri_data, - calc_rgd->rd_ri.ri_bitbytes); - memset(rgindex_buf_ondisk, 0, sizeof(rgindex_buf_ondisk)); - gfs_rindex_out(&calc_rgd->rd_ri, rgindex_buf_ondisk); - /* Note: rgindex_buf_ondisk is ONLY used for debug to see what the - entry would look like on disk. */ - hexdump(rgi*sizeof(struct gfs_rindex), rgindex_buf_ondisk, - sizeof(struct gfs_rindex)); - } /* for */ - relse_buf(sdp, bh); /* release the read buffer if we have one */ - return 0; -} - -/* - * ri_cleanup - free up the memory we previously allocated. - */ -void ri_cleanup(osi_list_t *rglist) -{ - struct fsck_rgrp *rgd; - - while(!osi_list_empty(rglist)){ - rgd = osi_list_entry(rglist->next, struct fsck_rgrp, rd_list); - if(rgd->rd_bits) - free(rgd->rd_bits); - if(rgd->rd_bh) - free(rgd->rd_bh); - osi_list_del(&rgd->rd_list); - free(rgd); - } -} - -/** - * ri_update - attach rgrps to the super block - * @sdp: - * - * Given the rgrp index inode, link in all rgrps into the super block - * and be sure that they can be read. - * - * If we encounter problems with any RGs, it either means we have a corrupt - * RG or a corrupt RG file entry (which is less likely). We make up to three - * attempts to do this. First, we trust that the RG index is correct and - * read the RGs. If that fails, we become a little less trusting and - * try to calculate what the RG index should look like in a perfect world. - * If that doesn't work, we become even less trusting and go to great lengths - * to figure out exactly where those RGs should be and what the index should - * look like. - * - * Returns: 0 on success, -1 on failure. - */ -int ri_update(struct fsck_sb *sdp) -{ - struct fsck_rgrp *rgd, *expected_rgd; - osi_list_t expected_rglist; /* List of expected resource groups */ - osi_list_t *tmp; - struct gfs_rindex buf; - unsigned int rg, calc_rg_count; - int error, count1 = 0, count2 = 0; - int fix_grow_problems = 0, grow_problems = 0; - enum rgindex_trust_level { /* how far can we trust our RG index? */ - blind_faith = 0, /* We'd like to trust the rgindex. We always used to - before bz 179069. This should cover most cases. */ - open_minded = 1, /* At least 1 RG is corrupt. Try to calculate what it - should be, in a perfect world where our RGs are all - on even boundaries. Blue sky. Chirping birds. */ - distrust = 2 /* The world isn't perfect, our RGs are not on nice neat - boundaries. The fs must have been messed with by - gfs_grow or something. Count the RGs by hand. */ - } trust_lvl; - - log_info("Validating Resource Group index.\n"); - for (trust_lvl = blind_faith; trust_lvl <= distrust; trust_lvl++) { - log_info("Level %d check.\n", trust_lvl + 1); - count1 = count2 = 0; - /* ---------------------------------------------------------------- */ - /* Step 1 - Calculate or figure out our own RG index */ - /* ---------------------------------------------------------------- */ - if (trust_lvl == blind_faith) { /* For now, assume rgindex is gospel */ - osi_list_init(&expected_rglist); - error = FALSE; - } - else if (trust_lvl == open_minded) { /* If we can't trust RG index */ - /* Calculate our own RG index for comparison */ - error = gfs_rgindex_calculate(sdp, &expected_rglist, - &calc_rg_count); - if (error) { /* If calculated RGs don't reasonably match the fs */ - log_info("(failed--trying again at level 3)\n"); - ri_cleanup(&sdp->rglist); - continue; /* Try again, this time counting them manually */ - } - } - else if (trust_lvl == distrust) { /* If we can't trust RG index */ - error = gfs_rgindex_rebuild(sdp, &expected_rglist, - &calc_rg_count); /* count the RGs. */ - if (error) { /* If calculated RGs don't reasonably match the fs */ - log_info("(failed--giving up)\n"); - goto fail; /* try again, this time counting them manually */ - } - } - /* ---------------------------------------------------------------- */ - /* Step 2 - Read the real RG index and check its integrity */ - /* ---------------------------------------------------------------- */ - for (rg = 0; ; rg++) { - int rgindex_modified; - - rgindex_modified = FALSE; - error = readi(sdp->riinode, (char *)&buf, - rg * sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (!error) /* if no data was read */ - break; /* we found the end of the rg index file */ - if (error != sizeof(struct gfs_rindex)) { - log_err("Unable to read resource group index #%u.\n", rg); - goto fail; - } - - rgd = (struct fsck_rgrp *)malloc(sizeof(struct fsck_rgrp)); - memset(rgd, 0, sizeof(struct fsck_rgrp)); - rgd->rd_sbd = sdp; - osi_list_add_prev(&rgd->rd_list, &sdp->rglist); - gfs_rindex_in(&rgd->rd_ri, (char *)&buf); - if (trust_lvl != blind_faith) { - expected_rgd = osi_list_entry(expected_rglist.next, - struct fsck_rgrp, rd_list); - /* --------------------------------------------------------- */ - /* Now compare the index to the one we calculated / rebuilt */ - /* Since this is fsck and fsck's job is to fix filesystem */ - /* corruption, it's probably better to trust the calculated */ - /* value and discard what's reported on disk. */ - /* --------------------------------------------------------- */ - ri_compare(rg, rgd->rd_ri, expected_rgd->rd_ri, - ri_addr, PRIx64); - ri_compare(rg, rgd->rd_ri, expected_rgd->rd_ri, - ri_length, PRIx32); - ri_compare(rg, rgd->rd_ri, expected_rgd->rd_ri, - ri_data1, PRIx64); - ri_compare(rg, rgd->rd_ri, expected_rgd->rd_ri, - ri_data, PRIx32); - ri_compare(rg, rgd->rd_ri, expected_rgd->rd_ri, - ri_bitbytes, PRIx32); - /* If we modified the index, write it back to disk. */ - if (rgindex_modified) { - if(query(sdp, "Fix the index? (y/n)")) { - gfs_rindex_out(&rgd->rd_ri, (char *)&buf); - error = writei(sdp->riinode, (char *)&buf, - rg * sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (error != sizeof(struct gfs_rindex)) { - log_err("Unable to fix resource group index %u.\n", - rg + 1); - goto fail; - } - } - else - log_err("RG index not fixed.\n"); - } - osi_list_del(&expected_rgd->rd_list); - free(expected_rgd); - } /* if we can't trust the rg index */ - else { /* blind faith -- just check for the gfs_grow problem */ - if (rgd->rd_ri.ri_data == 4294967292) { - if (!fix_grow_problems) { - log_err("A problem with the rindex file caused by gfs_grow was detected.\n"); - if(query(sdp, "Fix the rindex problem? (y/n)")) - fix_grow_problems = 1; - } - /* Keep a counter in case we hit it more than once. */ - grow_problems++; - osi_list_del(&rgd->rd_list); /* take it out of the equation */ - free(rgd); - continue; - } else if (fix_grow_problems) { - /* Once we detect the gfs_grow rindex problem, we have to */ - /* rewrite the entire rest of the rindex file, starting */ - /* with the entry AFTER the one that has the problem. */ - gfs_rindex_out(&rgd->rd_ri, (char *)&buf); - error = writei(sdp->riinode, (char *)&buf, - (rg - grow_problems) * - sizeof(struct gfs_rindex), - sizeof(struct gfs_rindex)); - if (error != sizeof(struct gfs_rindex)) { - log_err("Unable to fix rindex entry %u.\n", - rg + 1); - goto fail; - } - } - } - error = fs_compute_bitstructs(rgd); - if (error) - break; - rgd->rd_open_count = 0; - count1++; - } /* for all RGs in the index */ - rg -= grow_problems; - if (!error) { - log_info("%u resource groups found.\n", rg); - if (trust_lvl != blind_faith && rg != calc_rg_count) - log_warn("Resource group count discrepancy. Index says %d. " \ - "Should be %d.\n", rg, calc_rg_count); - /* ------------------------------------------------------------- */ - /* Step 3 - Read the real RGs and check their integrity. */ - /* Now we can somewhat trust the rgindex and the RG addresses, */ - /* so let's read them in, check them and optionally fix them. */ - /* ------------------------------------------------------------- */ - error = FALSE; - for (tmp = sdp->rglist.next; !error && tmp != &sdp->rglist; - tmp = tmp->next) { - rgd = osi_list_entry(tmp, struct fsck_rgrp, rd_list); - error = fs_rgrp_read(rgd, trust_lvl); - if (error) - log_err("Unable to read in rgrp descriptor.\n"); - else - fs_rgrp_relse(rgd); - count2++; - } - if (!error && count1 != count2){ - log_err("Rgrps allocated (%d) does not equal" - " rgrps read (%d).\n", count1, count2); - error = -1; - } - sdp->rgcount = count1; - } - if (fix_grow_problems) { - osi_buf_t *dibh; - - get_and_read_buf(sdp, sdp->sb.sb_rindex_di.no_addr, &dibh, 0); - sdp->riinode->i_di.di_size = rg * sizeof(struct gfs_rindex); - gfs_dinode_out(&sdp->riinode->i_di, BH_DATA(dibh)); - write_buf(sdp, dibh, 0); - grow_problems = fix_grow_problems = 0; - relse_buf(sdp, dibh); - } - if (!error) { /* if no problems encountered with the rgs */ - log_info("(passed)\n"); - break; /* no reason to distrust what we saw. Otherwise, we - reiterate and become a little less trusting. */ - } - else { - if (trust_lvl < distrust) - log_info("(failed--trying again at level 2)\n"); - else - log_info("(failed--recovery impossible)\n"); - } - ri_cleanup(&sdp->rglist); - } /* for trust_lvl */ - return 0; - - fail: - ri_cleanup(&sdp->rglist); - return -1; -} - -int write_sb(struct fsck_sb *sbp) -{ - int error = 0; - osi_buf_t *bh; - - error = get_and_read_buf(sbp, GFS_SB_ADDR >> sbp->fsb2bb_shift, &bh, 0); - if (error){ - log_crit("Unable to read superblock\n"); - goto out; - } - - gfs_sb_out(&sbp->sb, BH_DATA(bh)); - - if((error = write_buf(sbp, bh, BW_WAIT))) { - stack; - goto out; - } - - relse_buf(sbp, bh); -out: - return error; - -} - diff --git a/gfs/gfs_fsck/super.h b/gfs/gfs_fsck/super.h deleted file mode 100644 index 743036f..0000000 --- a/gfs/gfs_fsck/super.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef _SUPER_H -#define _SUPER_H - -#include "fsck_incore.h" - -int read_sb(struct fsck_sb *sdp); -int ji_update(struct fsck_sb *sdp); -int ri_update(struct fsck_sb *sdp); -int write_sb(struct fsck_sb *sdp); - -#endif /* _SUPER_H */ diff --git a/gfs/gfs_fsck/test_bitmap.c b/gfs/gfs_fsck/test_bitmap.c deleted file mode 100644 index 6daaed2..0000000 --- a/gfs/gfs_fsck/test_bitmap.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdint.h> -#include <stdio.h> -#include "log.h" -#include "bitmap.h" - -int main(int argc, char **argv) -{ - struct bmap map; - uint8_t val = 0; - - bitmap_create(&map, 1000, 8); - - bitmap_set(&map, 1, 3); - - bitmap_get(&map, 1, &val); - - printf("%d\n", val); - - bitmap_set(&map, 2, 7); - - bitmap_get(&map, 2, &val); - - printf("%d\n", val); - - bitmap_get(&map, 3, &val); - - printf("%d\n", val); - - bitmap_clear(&map, 2); - - bitmap_get(&map, 2, &val); - - printf("%d\n", val); - - bitmap_destroy(&map); - - -} diff --git a/gfs/gfs_fsck/test_block_list.c b/gfs/gfs_fsck/test_block_list.c deleted file mode 100644 index 049eb91..0000000 --- a/gfs/gfs_fsck/test_block_list.c +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdint.h> -#include "block_list.h" - -#define BITS 100 -void print_map(struct block_list *il, int count); - -int main(int argc, char **argv) -{ - int i; - struct block_list *il; - - il = block_list_create(BITS, gbmap); - - /*for(i = 0; i < BITS; i++) { - block_check(il, i, &k); - printf("Block %d is %lu\n", i, k); - }*/ - print_map(il, BITS); - - block_mark(il, 3, meta_free); - block_mark(il, 6, inode_lnk); - block_mark(il, 6, bad_block); - block_mark(il, BITS-2, meta_inval); - block_mark(il, BITS-1, meta_free); - if(block_mark(il, BITS, meta_free)) { - fprintf(stderr, "Block %d out of bounds\n", BITS); - } - - /*for(i = 0; i < BITS; i++) { - block_check(il, i, &k); - printf("Block %d is %lu\n", i, k); - }*/ - print_map(il, BITS); - - for(i = 70; i < 80; i++) { - block_mark(il, i, meta_free); - } - - block_clear(il, BITS-2, meta_free); - - /*for(i = 0; i < BITS; i++) { - block_check(il, i, &k); - printf("Block %d is %lu\n", i, k); - }*/ - print_map(il, BITS); - return 0; - -} - -void print_map(struct block_list *il, int count) -{ - int i, j; - struct block_query q; - - printf("Printing map of blocks - 60 blocks per row\n"); - j = 0; - for(i = 0; i < count; i++) { - - if(j > 59) { - printf("\n"); - j = 0; - } - else if(!(j %10) && j != 0) { - printf(" "); - } - j++; - block_check(il, i, &q); - printf("%X", q.block_type); - - } - printf("\n"); - - printf("Printing map of bad blocks - 60 blocks per row\n"); - j = 0; - for(i = 0; i < count; i++) { - - if(j > 59) { - printf("\n"); - j = 0; - } - else if(!(j %10) && j != 0) { - printf(" "); - } - j++; - block_check(il, i, &q); - printf("%X", q.bad_block); - - } - printf("\n"); -} diff --git a/gfs/gfs_fsck/util.c b/gfs/gfs_fsck/util.c deleted file mode 100644 index 9f0e8d6..0000000 --- a/gfs/gfs_fsck/util.c +++ /dev/null @@ -1,342 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include "bio.h" -#include "fs_bits.h" - -#include "util.h" -#include "log.h" - -/** - * compute_height - * @sdp: - * @sz: - * - */ -int compute_height(struct fsck_sb *sdp, uint64 sz) -{ - unsigned int height; - uint64 space, old_space; - unsigned int bsize = sdp->sb.sb_bsize; - - if (sz <= (bsize - sizeof(struct gfs_dinode))) - return 0; - - height = 1; - space = sdp->diptrs * bsize; - - while (sz > space) - { - old_space = space; - - height++; - space *= sdp->inptrs; - - if (space / sdp->inptrs != old_space || - space % sdp->inptrs != 0) - break; - } - - return height; -} - - -/* - * check_range - check if blkno is within FS limits - * @sdp: super block - * @blkno: block number - * - * Returns: 0 if ok, -1 if out of bounds - */ -int check_range(struct fsck_sb *sdp, uint64 blkno){ - if((blkno > sdp->last_fs_block) || - (blkno < sdp->first_data_block)) - return -1; - return 0; -} - - -/* - * set_meta - set the meta header of a buffer - * @bh - * @type - * - * Returns: 0 if ok, -1 on error - */ -int set_meta(osi_buf_t *bh, int type, int format){ - struct gfs_meta_header header; - - if(!check_meta(bh, 0)){ - log_debug("Setting metadata\n"); - ((struct gfs_meta_header *)BH_DATA(bh))->mh_type = cpu_to_gfs32(type); - ((struct gfs_meta_header *)BH_DATA(bh))->mh_format = cpu_to_gfs32(format); - } else { - memset(&header, 0, sizeof(struct gfs_meta_header)); - header.mh_magic = GFS_MAGIC; - header.mh_type = type; - header.mh_format = format; - - gfs_meta_header_out(&header, BH_DATA(bh)); - } - return 0; -} - - - - -/* - * check_meta - check the meta header of a buffer - * @bh: buffer to check - * @type: meta type (or 0 if don't care) - * - * Returns: 0 if ok, -1 on error - */ -int check_meta(osi_buf_t *bh, int type){ - uint32 check_magic = ((struct gfs_meta_header *)BH_DATA((bh)))->mh_magic; - uint32 check_type = ((struct gfs_meta_header *)BH_DATA((bh)))->mh_type; - - check_magic = gfs32_to_cpu(check_magic); - check_type = gfs32_to_cpu(check_type); - if((check_magic != GFS_MAGIC) || (type && (check_type != type))){ - log_debug("For %"PRIu64" Expected %X:%X - got %X:%X\n", BH_BLKNO(bh), GFS_MAGIC, type, - check_magic, check_type); - return -1; - } - return 0; -} - -/* - * check_type - check the meta type of a buffer - * @bh: buffer to check - * @type: meta type - * - * Returns: 0 if ok, -1 on error - */ -int check_type(osi_buf_t *bh, int type){ - uint32 check_magic = ((struct gfs_meta_header *)BH_DATA((bh)))->mh_magic; - uint32 check_type = ((struct gfs_meta_header *)BH_DATA((bh)))->mh_type; - - check_magic = gfs32_to_cpu(check_magic); - check_type = gfs32_to_cpu(check_type); - if((check_magic != GFS_MAGIC) || (check_type != type)){ - return -1; - } - return 0; -} - -/** - * next_rg_meta - * @rgd: - * @block: - * @first: if set, start at zero and ignore block - * - * The position to start looking from is *block. When a block - * is found, it is returned in block. - * - * Returns: 0 on success, -1 when finished - */ -int next_rg_meta(struct fsck_rgrp *rgd, uint64 *block, int first) -{ - fs_bitmap_t *bits = NULL; - uint32 length = rgd->rd_ri.ri_length; - uint32 blk = (first)? 0: (uint32)((*block+1)-rgd->rd_ri.ri_data1); - int i; - - if(!first && (*block < rgd->rd_ri.ri_data1)){ - log_err("next_rg_meta: Start block is outside rgrp bounds.\n"); - exit(1); - } - - for(i=0; i < length; i++){ - bits = &rgd->rd_bits[i]; - if(blk < bits->bi_len*GFS_NBBY){ - break; - } - blk -= bits->bi_len*GFS_NBBY; - } - - - for(; i < length; i++){ - bits = &rgd->rd_bits[i]; - - blk = fs_bitfit(BH_DATA(rgd->rd_bh[i]) + bits->bi_offset, - bits->bi_len, blk, GFS_BLKST_USEDMETA); - - if(blk != BFITNOENT){ - *block = blk + (bits->bi_start * GFS_NBBY) + rgd->rd_ri.ri_data1; - break; - } - - blk=0; - } - - if(i == length){ - return -1; - } - return 0; -} - -/** - * next_rg_meta_free - finds free or used metadata - * @rgd: - * @block: - * @first: if set, start at zero and ignore block - * - * The position to start looking from is *block. When a block - * is found, it is returned in block. - * - * Returns: 0 on success, -1 when finished - */ -int next_rg_meta_free(struct fsck_rgrp *rgd, uint64 *block, int first, int *mfree) -{ - fs_bitmap_t *bits = NULL; - uint32 length = rgd->rd_ri.ri_length; - uint32 blk = (first)? 0: (uint32)((*block+1)-rgd->rd_ri.ri_data1); - uint32 ublk, fblk; - int i; - - if(!first && (*block < rgd->rd_ri.ri_data1)){ - log_err("next_rg_meta: Start block is outside rgrp bounds.\n"); - exit(1); - } - - for(i=0; i < length; i++){ - bits = &rgd->rd_bits[i]; - if(blk < bits->bi_len*GFS_NBBY){ - break; - } - blk -= bits->bi_len*GFS_NBBY; - } - - - for(; i < length; i++){ - bits = &rgd->rd_bits[i]; - - ublk = fs_bitfit(BH_DATA(rgd->rd_bh[i]) + bits->bi_offset, - bits->bi_len, blk, GFS_BLKST_USEDMETA); - - fblk = fs_bitfit(BH_DATA(rgd->rd_bh[i]) + bits->bi_offset, - bits->bi_len, blk, GFS_BLKST_FREEMETA); - if(ublk < fblk) { - blk = ublk; - *mfree = 0; - } else { - blk = fblk; - *mfree = 1; - } - if(blk != BFITNOENT){ - *block = blk + (bits->bi_start * GFS_NBBY) + rgd->rd_ri.ri_data1; - break; - } - - blk=0; - } - - if(i == length){ - return -1; - } - return 0; -} - - -/** - * next_rg_metatype - * @rgd: - * @block: - * @type: the type of metadata we're looking for - * @first: if set we should start at block zero and block is ignored - * - * Returns: 0 on success, -1 on error or finished - */ -int next_rg_metatype(struct fsck_rgrp *rgd, uint64 *block, uint32 type, int first) -{ - struct fsck_sb *sdp = rgd->rd_sbd; - osi_buf_t *bh=NULL; - - do{ - relse_buf(sdp, bh); - if(next_rg_meta(rgd, block, first)) - return -1; - - if(get_and_read_buf(sdp, *block, &bh, 0)){ - log_err("next_rg_metatype: Unable to read meta block " - "#%"PRIu64" from disk\n", *block); - exit(1); - } - - if(check_meta(bh,0)){ - log_err("next_rg_metatype: next_rg_meta returned block #%"PRIu64",\n" - " which is not a valid meta block.\n", *block); - exit(1); - } - - first = 0; - } while(check_meta(bh, type)); - relse_buf(sdp, bh); - - return 0; -} - - - -#if 0 -/** - * search_list - * @list - * @addr - * - * Returns: di_info_t ptr if found, NULL otherwise - */ -struct di_info *search_list(osi_list_t *list, uint64 addr) -{ - osi_list_t *tmp; - struct di_info *dinfo; - - for (tmp = list->next; tmp != list; tmp = tmp->next) - { - dinfo = osi_list_entry(tmp, struct di_info, din_list); - - if (dinfo->din_addr == addr) - return(dinfo); - } - - return NULL; -} -#endif - -/* Put out a warm, fuzzy message every second so the user */ -/* doesn't think we hung. (This may take a long time). */ -void warm_fuzzy_stuff(uint64_t block) -{ - static uint64_t one_percent = 0; - static struct timeval tv; - static uint32_t seconds = 0; - - if (!one_percent) - one_percent = last_fs_block / 100; - if (block - last_reported_block >= one_percent) { - last_reported_block = block; - gettimeofday(&tv, NULL); - if (!seconds) - seconds = tv.tv_sec; - if (tv.tv_sec - seconds) { - static uint64_t percent; - - seconds = tv.tv_sec; - if (last_fs_block) { - percent = (block * 100) / last_fs_block; - log_notice("\r%" PRIu64 " percent complete.\r", percent); - } - } - } -} diff --git a/gfs/gfs_fsck/util.h b/gfs/gfs_fsck/util.h deleted file mode 100644 index 04b9664..0000000 --- a/gfs/gfs_fsck/util.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __UTIL_H__ -#define __UTIL_H__ - -#include "fsck_incore.h" - -#define do_lseek(fd, off) \ - ((lseek((fd), (off), SEEK_SET) == (off)) ? 0 : -1) - -#define do_read(fd, buff, len) \ - ((read((fd), (buff), (len)) == (len)) ? 0 : -1) - -#define do_write(fd, buff, len) \ - ((write((fd), (buff), (len)) == (len)) ? 0 : -1) - - -int compute_height(struct fsck_sb *sdp, uint64 sz); -int check_range(struct fsck_sb *sdp, uint64 blkno); -int set_meta(osi_buf_t *bh, int type, int format); -int check_type(osi_buf_t *bh, int type); -int check_meta(osi_buf_t *bh, int type); -int next_rg_meta(struct fsck_rgrp *rgd, uint64 *block, int first); -int next_rg_meta_free(struct fsck_rgrp *rgd, uint64 *block, int first, int *free); -int next_rg_metatype(struct fsck_rgrp *rgd, uint64 *block, uint32 type, int first); -struct di_info *search_list(osi_list_t *list, uint64 addr); -void warm_fuzzy_stuff(uint64_t block); - -#endif /* __UTIL_H__ */ diff --git a/gfs/gfs_grow/Makefile b/gfs/gfs_grow/Makefile deleted file mode 100644 index 320a42e..0000000 --- a/gfs/gfs_grow/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -TARGET= gfs_grow - -SOURCE= main.c \ - ondisk.c - -CFLAGS+= -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config -I${incdir} - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -LDFLAGS+= -L${libdir} -LOADLIBS+= -liddev - -all: ${TARGET} - -gfs_grow: main.c - ${CC} ${CFLAGS} ${INCLUDE} main.c ondisk.c ${LDFLAGS} ${LOADLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/gfs/gfs_grow/main.c b/gfs/gfs_grow/main.c deleted file mode 100644 index dae9dae..0000000 --- a/gfs/gfs_grow/main.c +++ /dev/null @@ -1,970 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <getopt.h> -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> -#define __user -#include <linux/gfs_ioctl.h> -#include "osi_list.h" -typedef uint64_t uint64; -#include "iddev.h" - -#include "copyright.cf" - -struct rglist_entry { - osi_list_t list; - struct gfs_rindex ri; - struct gfs_rgrp rg; -}; - -struct jilist_entry { - osi_list_t list; - struct gfs_jindex ji; -}; - -/* - * verbose: 0 = no messages, 1 = normal, 2 = everything - * test: 0 = normal, 1 = don't actually write data, but do everything else - * fspath: path to root of mounted GFS filesystem - * device: the device upon which the GFS filesystem is mounted - * fsoptions: the mount options used - * devsize: the size of the device (in filesystem blocks, rounded down) - * fssize: the size of the filesystem (in filesystem blocks, rounded down) - * override_device_size: if non-zero, this is used for the device size - */ -static int verbose = 1; -static int test = 0; -static char fspath[4096]; -static char device[1024]; -static char fsoptions[4096]; -static uint64_t devsize; -static uint64_t fssize; -static uint64_t override_device_size = 0; - -/* - * fs_sb: the superblock read from the mounted filesystem - * rglist_current: list of resource groups currently making up the filesystem - * rglist_new: where we put the new resource groups to be written - * jilist_current: list of current journals in the filesystem - */ -static struct gfs_sb fs_sb; -static osi_list_decl(rglist_current); -static osi_list_decl(rglist_new); -static osi_list_decl(jilist_current); - -/** - * device_geometry - Find out the size of a block device - * @device: The name of the device - * - * Returns: The size of the device in FS blocks - */ - -static uint64_t -device_geometry(char *device) -{ - int fd; - uint64_t bytes; - int error; - - if (override_device_size) - bytes = override_device_size; - else { - fd = open(device, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "gfs_grow: can't open %s: %s\n", - device, strerror(errno)); - exit(EXIT_FAILURE); - } - - error = device_size(fd, &bytes); - if (error) { - fprintf(stderr, - "gfs_grow: can't determine size of %s: %s\n", - device, strerror(errno)); - exit(EXIT_FAILURE); - } - - close(fd); - } - - return bytes >> fs_sb.sb_bsize_shift; -} - -/** - * jread - Read from journaled file using ioctl() - * @fd: The fd to read from - * @file: The file to read - * @buf: The buffer to fill - * @size: The amount of data to read - * @offset: The offset to read from - * - * Returns: Error code, or amount of data read - */ - -static int -jread(int fd, char *file, void *buf, uint64_t size, uint64_t *offset) -{ - struct gfs_ioctl gi; - char *argv[] = { "do_hfile_read", file }; - int error; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = size; - gi.gi_offset = *offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error > 0) - *offset += error; - - return error; -} - -/** - * jwrite - Write to journaled file using ioctl() - * @fd: The fd to write to - * @file: The file to write - * @buf: The buffer to write - * @size: The amount of data to write - * @offset: The offset at which to write the data - * - * Returns: Error code, or the amount of data written - */ - -static int -jwrite(int fd, char *file, void *buf, uint64_t size, uint64_t *offset) -{ - struct gfs_ioctl gi; - char *argv[] = { "do_hfile_write", file }; - int error; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = size; - gi.gi_offset = *offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error > 0) - *offset += error; - - return error; -} - -/** - * filesystem_size - Calculate the size of the filesystem - * - * Reads the lists of journals and resource groups in order to - * work out where the last block of the filesystem is located. - * - * Returns: The calculated size - */ - -static uint64_t -filesystem_size(void) -{ - osi_list_t *tmp, *head; - struct rglist_entry *rgl; - struct jilist_entry *jil; - uint64_t size = 0; - uint64_t extent; - - tmp = head = &rglist_current; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - rgl = osi_list_entry(tmp, struct rglist_entry, list); - extent = rgl->ri.ri_addr + rgl->ri.ri_length + rgl->ri.ri_data; - if (extent > size) - size = extent; - } - - tmp = head = &jilist_current; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - jil = osi_list_entry(tmp, struct jilist_entry, list); - extent = jil->ji.ji_addr + jil->ji.ji_nsegment * fs_sb.sb_seg_size; - if (extent > size) - size = extent; - } - - return size; -} - -/** - * gfs_jientry - Get journal index entry - * @fd: The fd of the journal index - * @offset: The offset at which the journal entry appears - * - * Reads a single entry from the journal index file and - * adds it to the list of current journal entries. - * - * Returns: 1 on EOF, 0 otherwise - */ - -static int -get_jientry(int fd, uint64_t *offset) -{ - char buffer[sizeof(struct gfs_jindex)]; - int len = jread(fd, "jindex", buffer, - sizeof(struct gfs_jindex), offset); - struct jilist_entry *jil; - - if (len != sizeof(struct gfs_jindex)) { - if (len == 0) - return 1; - fprintf(stderr, "Erk! Read odd size from jindex (%d)\n", len); - exit(EXIT_FAILURE); - } - if ((jil = malloc(sizeof(struct jilist_entry))) == NULL) { - perror("jilist_entry"); - exit(EXIT_FAILURE); - } - memset(jil, 0, sizeof(struct jilist_entry)); - gfs_jindex_in(&jil->ji, buffer); - osi_list_add(&jil->list, &jilist_current); - return 0; -} - -/** - * read_journals - Read the whole journal index - * @fs_fd: An fd for some file or directory within the mounted GFS filesystem - * - */ - -static void -read_journals(int fs_fd) -{ - uint64_t offset = 0; - while (get_jientry(fs_fd, &offset) == 0) - /* do nothing */; -} - -/** - * get_rgrp - Read a single rindex entry - * @fd: The fd for the rindex file - * @offset: The offset at which to read the rindex entry - * - * Reads a single rindex entry and adds it to the list of current - * resource group entries. - * - * Returns: 1 on EOF, 0 otherwise - */ - -static int -get_rgrp(int fd, uint64_t *offset) -{ - char buffer[sizeof(struct gfs_rindex)]; - int len = jread(fd, "rindex", buffer, - sizeof(struct gfs_rindex), offset); - struct rglist_entry *rgl; - - if (len != sizeof(struct gfs_rindex)) { - if (len == 0) - return 1; - fprintf(stderr, "Erk! Read odd size from rindex (%d)\n", len); - exit(EXIT_FAILURE); - } - if ((rgl = malloc(sizeof(struct rglist_entry))) == NULL) { - perror("rglist_entry"); - exit(EXIT_FAILURE); - } - memset(rgl, 0, sizeof(struct rglist_entry)); - gfs_rindex_in(&rgl->ri, buffer); - osi_list_add(&rgl->list, &rglist_current); - return 0; -} - -/** - * read_rgrps - Reads the contents of the rindex file - * @fs_fd: An fd for any file or directory within the mounted GFS filesytem - * - */ - -static void -read_rgrps(int fs_fd) -{ - uint64_t offset = 0; - while (get_rgrp(fs_fd, &offset) == 0) - /* do nothing */; -} - -/** - * write_a_block - Write a block to the current device - * @where: The position to write the block (in filesystem blocks) - * @rg: The (optional) resource group to write - * - * Writes a single disk block to the device. It has a safety check which - * prevents it writing to the device at a position within the control of - * the active filesystem. If @rg is NULL, it writes a single block of - * zeros with a meta_header, otherwise the resource group is copied - * into the start of the block. - */ - -static void -write_a_block(int fd, struct gfs_rgrp *rg) -{ - char buffer[4096]; - - memset(buffer, 0, fs_sb.sb_bsize); - if (rg) - gfs_rgrp_out(rg, buffer); - else { - struct gfs_meta_header mh; - - mh.mh_magic = GFS_MAGIC; - mh.mh_type = GFS_METATYPE_RB; - mh.mh_format = GFS_FORMAT_RB; - gfs_meta_header_out(&mh, buffer); - } - if (write(fd, buffer, fs_sb.sb_bsize) != fs_sb.sb_bsize) { - perror("write_zero_block"); - exit(EXIT_FAILURE); - } -} - -/** - * write_whole_rgrp - Write a complete rgrp, including bitmaps - * @rgl: The information about the resource group - * - * Writes a complete rgrp, including any bitmap blocks required - * by calling write_a_block() a number of times. Calls sync() to - * ensure data really reached disk. - */ - -static void -write_whole_rgrp(int fd, struct rglist_entry *rgl) -{ - uint32_t l; - uint32_t nzb = rgl->ri.ri_length; - uint64_t fsoffset = rgl->ri.ri_addr * (uint64_t) fs_sb.sb_bsize; - - if (fsoffset < fssize) { - fprintf(stderr, - "Sanity check failed: Caught trying to write to live filesystem!\n"); - exit(EXIT_FAILURE); - } - if (lseek(fd, fsoffset, SEEK_SET) != fsoffset) { - perror(device); - exit(EXIT_FAILURE); - } - write_a_block(fd, &rgl->rg); - for (l = 1; l < nzb; l++) - write_a_block(fd, NULL); -} - -/** - * get_length - Use stat() to get the length of a file - * @fd: The fd of the file whose length we wish to know - * - * Returns: The length - */ - -static uint64_t -get_length(int fd, char *file) -{ - struct gfs_ioctl gi; - char *argv[] = { "get_hfile_stat", file }; - struct gfs_dinode di; - int error; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) { - perror("stat"); - fprintf(stderr, "Failed to get size of file. Aborting.\n"); - exit(EXIT_FAILURE); - } - - return di.di_size; -} - -/** - * write_rindex - Writes new records to the end of the rindex file - * @fs_fd: A fd of any file or directory withint the GFS filesystem - * - * This is the critical function in expanding a filesystem. It does the - * actual write to the rindex which causes the GFS filesystem to see the - * new resource groups which were previously added. - */ - -static void -write_rindex(int fs_fd) -{ - osi_list_t *tmp, *head; - struct rglist_entry *rgl; - char *buffer; - int b, data_per_blk, data_per_page, firstblock; - int chunks_this_page, page_freebytes, data_this_page; - long page_size; - uint64_t offset, size; - - page_size = sysconf(_SC_PAGESIZE); - buffer = malloc(page_size * 2); - if (!buffer) { - fprintf(stderr, "Error: out of memory.\n"); - exit(EXIT_FAILURE); - } - offset = get_length(fs_fd, "rindex"); - - /* - * This is the critical section. - * If things mess up here, it could be very difficult to put right - */ - tmp = head = &rglist_new; - firstblock = 1; - data_per_blk = fs_sb.sb_bsize - sizeof(struct gfs_meta_header); - data_per_page = (page_size / fs_sb.sb_bsize) * data_per_blk; - for (;;) { - size = 0; - /* We used to write new rindex entries out one by one. - However, that can be very slow, especially if there's a - load on the file system. That's because each write is - done with the glock sync option and the journal will need - to be synced before the glock is freed up for the next - write. (The rindex file is journaled data). If the block - size matches the page size, the syncs happen much faster. - If the block size is smaller, it takes a huge amount of - time to get all the blocks to settle within the page. - - What I'm trying to do here is optimize our writes so - that multiple blocks may be allocated during a single - write request, all under the same glock, in order to - get a page-full of data written. This makes the syncing - go much faster. The exception is the very first write - (see note below). */ - data_this_page = offset % data_per_page; - page_freebytes = page_size - data_this_page; - if (page_freebytes < sizeof(struct gfs_rindex)) - page_freebytes = data_per_page; - chunks_this_page = (page_freebytes / - sizeof(struct gfs_rindex)) + 1; - for (b = 0; b < chunks_this_page; b++) { - tmp = tmp->next; - if (tmp == head) - break; - rgl = osi_list_entry(tmp, struct rglist_entry, list); - gfs_rindex_out(&rgl->ri, buffer + size); - size += sizeof(struct gfs_rindex); - /* Write the first block on its own. This minimizes - the chance of running out of blocks on a nearly - full file system. Once that first block is written, - the file system should have more free blocks to - allocate in chunks. */ - if (firstblock) { - firstblock = 0; - break; - } - } - if (size && - jwrite(fs_fd, "rindex", buffer, size, &offset) != size) { - perror("write: rindex"); - fprintf(stderr, "Aborting...\n"); - exit(EXIT_FAILURE); - } - if (tmp == head) - break; - } - /* - * This is the end of the critical section - */ - free(buffer); -} - -/** - * write_rgrps - Write the new resource groups to disk - * @fs_fd: An fd from any file or directory on the GFS mounted filesystem - * - * This first writes out the new resource group information to the - * area of the disk beyond the area the filesystem is currently - * using and then calls write_rindex() to make the filesystem see - * the newly written resource groups. - */ - -static void -write_rgrps(int fs_fd) -{ - osi_list_t *tmp, *head; - struct rglist_entry *rgl; - int fd = open(device, O_RDWR); - - if (fd < 0) { - perror(device); - exit(EXIT_FAILURE); - } - tmp = head = &rglist_new; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - rgl = osi_list_entry(tmp, struct rglist_entry, list); - write_whole_rgrp(fd, rgl); - } - sync(); - close(fd); - - sync(); - sync(); - sync(); - - write_rindex(fs_fd); - - sync(); - sync(); - sync(); -} - -/** - * gather_info - Gathers all the information about the existing filesystem - * - */ - -static void -gather_info(void) -{ - int fd; - struct gfs_ioctl gi; - char *argv[] = { "get_super" }; - int error; - - fd = open(fspath, O_RDONLY); - if (fd < 0) { - perror(fspath); - exit(EXIT_FAILURE); - } - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = (char *)&fs_sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) { - perror("ioctl: GFS_GET_SUPER"); - exit(EXIT_FAILURE); - } - - read_rgrps(fd); - read_journals(fd); - close(fd); - devsize = device_geometry(device); - fssize = filesystem_size(); -} - -/** - * print_rgrps - Print information about resource groups - * @lh: The list of resource groups to print - * - */ - -static void -print_rgrps(osi_list_t *lh) -{ - osi_list_t *tmp, *head; - struct rglist_entry *rgl; - int n = 0; - - tmp = head = lh; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - rgl = osi_list_entry(tmp, struct rglist_entry, list); - n++; - printf("RI: Addr %"PRIu64", RgLen %u, Start %"PRIu64", DataLen %u, BmapLen %u\n", - rgl->ri.ri_addr, rgl->ri.ri_length, - rgl->ri.ri_data1, rgl->ri.ri_data, rgl->ri.ri_bitbytes); - } - printf("RGRP: %d Resource groups in total\n", n); -} - -/** - * print_journals - Print a list of journals - * - */ - -static void -print_journals(osi_list_t *lh) -{ - osi_list_t *tmp, *head; - struct jilist_entry *jil; - int n = 0; - - tmp = head = lh; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - jil = osi_list_entry(tmp, struct jilist_entry, list); - n++; - printf("JI: Addr %"PRIu64" NumSeg %u SegSize %u\n", - jil->ji.ji_addr, jil->ji.ji_nsegment, fs_sb.sb_seg_size); - } - printf("JRNL: %d Journals in total\n", n); -} - -/** - * print_info - Print out various bits of (interesting?) information - * - */ - -static void -print_info(void) -{ - printf("FS: Mount Point: %s\n", fspath); - printf("FS: Device: %s\n", device); - printf("FS: Options: %s\n", fsoptions); - printf("FS: Size: %"PRIu64"\n", fssize); - if (verbose > 1) { - printf("RGRP: Current Resource Group List:\n"); - print_rgrps(&rglist_current); - printf("JRNL: Current Journal List:\n"); - print_journals(&jilist_current); - } - printf("DEV: Size: %"PRIu64"\n", devsize); - if (verbose > 1) { - printf("RGRP: New Resource Group List:\n"); - print_rgrps(&rglist_new); - } -} - -#define RGRP_STUFFED_BLKS(sb) (((sb)->sb_bsize - sizeof(struct gfs_rgrp)) * GFS_NBBY) -#define RGRP_BITMAP_BLKS(sb) (((sb)->sb_bsize - sizeof(struct gfs_meta_header)) * GFS_NBBY) - -/** - * rgrp_length - Calculate the length of a resource group - * @size: The total size of the resource group - * - */ - -uint64_t -rgrp_length(uint64_t size) -{ - uint64_t bitbytes = RGRP_BITMAP_BLKS(&fs_sb) + 1; - uint64_t stuff = RGRP_STUFFED_BLKS(&fs_sb) + 1; - uint64_t blocks = 1; - - if (size < stuff) - goto out; - size -= stuff; - while (size > bitbytes) { - blocks++; - size -= bitbytes; - } - if (size) - blocks++; - out: - return blocks; -} - -/** - * make_rgrp - Make a new rglist_entry - * @offset: The offset at which the new rgrp will go - * @size: The size of the new rgrp - * - * Returns: The end of the new resource group - */ - -uint64_t -make_rgrp(uint64_t offset, uint64_t size) -{ - struct rglist_entry *rgl = malloc(sizeof(struct rglist_entry)); - if (rgl == NULL) - exit(EXIT_FAILURE); - memset(rgl, 0, sizeof(struct rglist_entry)); - - rgl->ri.ri_addr = offset; - rgl->ri.ri_length = rgrp_length(size); - rgl->ri.ri_data1 = offset + rgl->ri.ri_length; - rgl->ri.ri_data = size - rgl->ri.ri_length; - - /* Round down to nearest multiple of GFS_NBBY */ - while (rgl->ri.ri_data & 0x03) - rgl->ri.ri_data--; - - rgl->ri.ri_bitbytes = rgl->ri.ri_data / GFS_NBBY; - - rgl->rg.rg_header.mh_magic = GFS_MAGIC; - rgl->rg.rg_header.mh_type = GFS_METATYPE_RG; - rgl->rg.rg_header.mh_format = GFS_FORMAT_RG; - rgl->rg.rg_free = rgl->ri.ri_data; - - osi_list_add_prev(&rgl->list, &rglist_new); - return offset + size; -} - -/** - * create_rgrps - Create a list of the new rgrps - * - */ - -static void -create_rgrps(void) -{ - uint64_t space = devsize - fssize; - uint64_t optimal_rgrp_size = RGRP_STUFFED_BLKS(&fs_sb) + - 14 * RGRP_BITMAP_BLKS(&fs_sb) + 15; - uint64_t rgrps = space / optimal_rgrp_size; - uint64_t offset = fssize; - uint64_t rgsize; - uint64_t n; - - if (space % optimal_rgrp_size) - rgrps++; - rgsize = optimal_rgrp_size; - - for (n = 0; n < rgrps; n++) - offset = make_rgrp(offset, (n != 0) ? rgsize : - (space - ((rgrps - 1) * rgsize))); - - if (offset > devsize) { - fprintf(stderr, "Calculation error: Out of bounds\n"); - exit(EXIT_FAILURE); - } -} - -/** - * update_fs - Actually perform the filesystem update - * - */ - -static void -update_fs(void) -{ - int fd = open(fspath, O_RDONLY); - if (fd < 0) { - perror(fspath); - exit(EXIT_FAILURE); - } - if (verbose) - printf("Preparing to write new FS information...\n"); - write_rgrps(fd); - if (verbose) - printf("Done.\n"); - close(fd); -} - -/** - * find_fs - Find the filesystem which the user specified - * @name: The name of a device or mount point - * - * Returns: 0 if the filesystem is located, 1 otherwise - */ - -static int -find_fs(char *name) -{ - FILE *fp = fopen("/proc/mounts", "r"); - char buffer[4096]; - char fstype[80]; - int fsdump, fspass; - - if (fp == NULL) { - perror("open: /proc/mounts"); - exit(EXIT_FAILURE); - } - while ((fgets(buffer, 4095, fp)) != NULL) { - buffer[4095] = 0; - if (strstr(buffer, name) == 0) - continue; - if (sscanf(buffer, "%s %s %s %s %d %d", device, fspath, fstype, - fsoptions, &fsdump, &fspass) != 6) - continue; - if (strcmp(fstype, "gfs") != 0) - continue; - if ((strcmp(device, name) != 0) && (strcmp(fspath, name) != 0)) - continue; - fclose(fp); - return 0; - } - fprintf(stderr, "GFS Filesystem %s not found\n", name); - fclose(fp); - return 1; -} - -/** - * delete_rgrp_list - Delete a list of rgrps - * @list: The list to delete - * - */ - -static void -delete_rgrp_list(osi_list_t *list) -{ - struct rglist_entry *rg; - - while (!osi_list_empty(list)) { - rg = osi_list_entry(list->next, struct rglist_entry, list); - osi_list_del(&rg->list); - free(rg); - } -} - -/** - * delete_jrnl_list - Delete a list of journals - * @list: the list to delete - * - */ - -static void -delete_jrnl_list(osi_list_t *list) -{ - struct jilist_entry *ji; - - while (!osi_list_empty(list)) { - ji = osi_list_entry(list->next, struct jilist_entry, list); - osi_list_del(&ji->list); - free(ji); - } -} - -/** - * usage - Print out the usage message - * - * This function does not include documentation for the -D option - * since normal users have no use for it at all. The -D option is - * only for developers. It intended use is in combination with the - * -T flag to find out what the result would be of trying different - * device sizes without actually having to try them manually. - */ - -static void -usage(void) -{ - fprintf(stdout, - "Usage:\n" - "\n" - "gfs_grow [options] /path/to/filesystem\n" - "\n" - "Options:\n" - " -h Usage information\n" - " -q Quiet, reduce verbosity\n" - " -T Test, do everything except update FS\n" - " -V Version information\n" - " -v Verbose, increase verbosity\n"); -} - -/** - * main - Tha main function - * @argc: The argument count - * @argv: The argument vector - * - * Runs through the filesystem expansion code for each of the specified - * filesystems. Each filesystem specified on the command line has the - * same options applied to it. You'll need to run the program multiple times - * if you want to use it on several different filesystems with different - * options for each. If you forget to specify a filesystem, then it is - * assumed that the program has run successfully, since its done everything - * asked of it, and it exits without printing a message. - * - * Returns: 0 on success, -1 otherwise - */ - -int -main(int argc, char *argv[]) -{ - int opt; - int error = 0; - - while ((opt = getopt(argc, argv, "VD:hqTv?")) != EOF) { - switch (opt) { - case 'D': /* This option is for testing only */ - override_device_size = atoi(optarg); - override_device_size <<= 20; - break; - case 'V': - printf("%s %s (built %s %s)\n", argv[0], - GFS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - case 'h': - usage(); - exit(0); - case 'q': - if (verbose) - verbose--; - break; - case 'T': - test = 1; - break; - case 'v': - verbose++; - break; - case ':': - case '?': - /* Unknown flag */ - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - default: - fprintf(stderr, "Bad programmer! You forgot" - " to catch the %c flag\n", opt); - exit(EXIT_FAILURE); - break; - } - } - - if (optind == argc) { - usage(); - exit(EXIT_FAILURE); - } - - while ((argc - optind) > 0) { - if (find_fs(argv[optind++])) { - error = 1; - continue; - } - gather_info(); - if (fssize > devsize) { - error = 1; - fprintf(stderr, - "Filesystem thinks device is bigger than it really is.... skipping\n"); - continue; - } - if ((devsize - fssize) < 100) { - error = 1; - fprintf(stderr, - "Device has grown by less than 100 blocks.... skipping\n"); - continue; - } - create_rgrps(); - if (verbose) - print_info(); - if (!test) - update_fs(); - delete_rgrp_list(&rglist_current); - delete_rgrp_list(&rglist_new); - delete_jrnl_list(&jilist_current); - } - - return error; -} diff --git a/gfs/gfs_grow/ondisk.c b/gfs/gfs_grow/ondisk.c deleted file mode 100644 index ebb14ad..0000000 --- a/gfs/gfs_grow/ondisk.c +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> diff --git a/gfs/gfs_jadd/Makefile b/gfs/gfs_jadd/Makefile deleted file mode 100644 index e84f4ce..0000000 --- a/gfs/gfs_jadd/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -TARGET= gfs_jadd - -SOURCE= main.c \ - ondisk.c - -CFLAGS+= -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config \ - -I${incdir} - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -LDFLAGS+= -L${libdir} -LOADLIBES+= -liddev - -all: ${TARGET} - -gfs_jadd: - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} - - diff --git a/gfs/gfs_jadd/main.c b/gfs/gfs_jadd/main.c deleted file mode 100644 index c210eaa..0000000 --- a/gfs/gfs_jadd/main.c +++ /dev/null @@ -1,922 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <getopt.h> -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> -#define __user -#include <linux/gfs_ioctl.h> -#include "osi_list.h" -typedef uint64_t uint64; -#include "iddev.h" - -#include "copyright.cf" - -#define BLOCK_END(buffer, type) ((buffer) + GFS_BASIC_BLOCK - sizeof(type)) - -struct rglist_entry { - osi_list_t list; - struct gfs_rindex ri; - struct gfs_rgrp rg; -}; - -struct jilist_entry { - osi_list_t list; - struct gfs_jindex ji; -}; - -/* - * verbose: 0 = no messages, 1 = normal, 2 = everything - * test: 0 = normal, 1 = don't actually write data, but do everything else - * fspath: path to root of mounted GFS filesystem - * device: the device upon which the GFS filesystem is mounted - * fsoptions: the mount options used - * devsize: the size of the device (in filesystem blocks, rounded down) - * fssize: the size of the filesystem (in filesystem blocks, rounded down) - * override_device_size: if non-zero, this is used for the device size - * number_of_journals: Number of journals to add to each fs - * journal_size: The size of each journal, in MB - * journal_size_blocks: The size of each journal in fs blocks - */ -static int verbose = 1; -static int test = 0; -static char fspath[4096]; -static char device[1024]; -static char fsoptions[4096]; -static uint64_t devsize; -static uint64_t fssize; -static uint64_t override_device_size = 0; -static unsigned int number_of_journals = 1; -static uint64_t journal_size = 128; -static uint64_t journal_size_blocks; - -/* - * fs_sb: the superblock read from the mounted filesystem - * rglist_current: list of resource groups currently making up the filesystem - * jilist_current: list of current journals in the filesystem - * jilist_new: where we put the new resource groups to be written - */ -static struct gfs_sb fs_sb; -static osi_list_decl(rglist_current); -static osi_list_decl(jilist_current); -static osi_list_decl(jilist_new); - -/** - * device_geometry - Find out the size of a block device - * @device: The name of the device - * - * Returns: The size of the device in FS blocks - */ - -static uint64_t -device_geometry(char *device) -{ - int fd; - uint64_t bytes; - int error; - - if (override_device_size) - bytes = override_device_size; - else { - fd = open(device, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "gfs_jadd: can't open %s: %s\n", - device, strerror(errno)); - exit(EXIT_FAILURE); - } - - error = device_size(fd, &bytes); - if (error) { - fprintf(stderr, - "gfs_grow: can't determine size of %s: %s\n", - device, strerror(errno)); - exit(EXIT_FAILURE); - } - - close(fd); - } - - return bytes >> fs_sb.sb_bsize_shift; -} - -/** - * jread - Read from journaled file using ioctl() - * @fd: The fd to read from - * @file: The file to read - * @buf: The buffer to fill - * @size: The amount of data to read - * @offset: The offset to read from - * - * Returns: Error code, or amount of data read - */ - -int -jread(int fd, char *file, void *buf, uint64_t size, uint64_t *offset) -{ - struct gfs_ioctl gi; - char *argv[] = { "do_hfile_read", file }; - int error; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = size; - gi.gi_offset = *offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error > 0) - *offset += error; - - return error; -} - -/** - * jwrite - Write to journaled file using ioctl() - * @fd: The fd to write to - * @file: The file to write - * @buf: The buffer to write - * @size: The amount of data to write - * @offset: The offset at which to write the data - * - * Returns: Error code, or the amount of data written - */ - -int -jwrite(int fd, char *file, void *buf, uint64_t size, uint64_t *offset) -{ - struct gfs_ioctl gi; - char *argv[] = { "do_hfile_write", file }; - int error; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = size; - gi.gi_offset = *offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error > 0) - *offset += error; - - return error; -} - -/** - * filesystem_size - Calculate the size of the filesystem - * - * Reads the lists of journals and resource groups in order to - * work out where the last block of the filesystem is located. - * - * Returns: The calculated size - */ - -static uint64_t -filesystem_size(void) -{ - osi_list_t *tmp, *head; - struct rglist_entry *rgl; - struct jilist_entry *jil; - uint64_t size = 0; - uint64_t extent; - - tmp = head = &rglist_current; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - rgl = osi_list_entry(tmp, struct rglist_entry, list); - extent = rgl->ri.ri_addr + rgl->ri.ri_length + rgl->ri.ri_data; - if (extent > size) - size = extent; - } - - tmp = head = &jilist_current; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - jil = osi_list_entry(tmp, struct jilist_entry, list); - extent = jil->ji.ji_addr + jil->ji.ji_nsegment * fs_sb.sb_seg_size; - if (extent > size) - size = extent; - } - - return size; -} - -/** - * gfs_jientry - Get journal index entry - * @fd: The fd of the journal index - * @offset: The offset at which the journal entry appears - * - * Reads a single entry from the journal index file and - * adds it to the list of current journal entries. - * - * Returns: 1 on EOF, 0 otherwise - */ - -static int -get_jientry(int fd, uint64_t *offset) -{ - char buffer[sizeof(struct gfs_jindex)]; - int len = jread(fd, "jindex", buffer, - sizeof(struct gfs_jindex), offset); - struct jilist_entry *jil; - - if (len != sizeof(struct gfs_jindex)) { - if (len == 0) - return 1; - fprintf(stderr, "Erk! Read odd size from jindex (%d)\n", len); - exit(EXIT_FAILURE); - } - if ((jil = malloc(sizeof(struct jilist_entry))) == NULL) { - perror("jilist_entry"); - exit(EXIT_FAILURE); - } - memset(jil, 0, sizeof(struct jilist_entry)); - gfs_jindex_in(&jil->ji, buffer); - osi_list_add(&jil->list, &jilist_current); - return 0; -} - -/** - * read_journals - Read the whole journal index - * @fs_fd: An fd for some file or directory within the mounted GFS filesystem - * - */ - -static void -read_journals(int fs_fd) -{ - uint64_t offset = 0; - while (get_jientry(fs_fd, &offset) == 0) - /* do nothing */; -} - -/** - * get_rgrp - Read a single rindex entry - * @fd: The fd for the rindex file - * @offset: The offset at which to read the rindex entry - * - * Reads a single rindex entry and adds it to the list of current - * resource group entries. - * - * Returns: 1 on EOF, 0 otherwise - */ - -static int -get_rgrp(int fd, uint64_t *offset) -{ - char buffer[sizeof(struct gfs_rindex)]; - int len = jread(fd, "rindex", buffer, - sizeof(struct gfs_rindex), offset); - struct rglist_entry *rgl; - - if (len != sizeof(struct gfs_rindex)) { - if (len == 0) - return 1; - fprintf(stderr, "Erk! Read odd size from rindex (%d)\n", len); - exit(EXIT_FAILURE); - } - if ((rgl = malloc(sizeof(struct rglist_entry))) == NULL) { - perror("rglist_entry"); - exit(EXIT_FAILURE); - } - memset(rgl, 0, sizeof(struct rglist_entry)); - gfs_rindex_in(&rgl->ri, buffer); - osi_list_add(&rgl->list, &rglist_current); - return 0; -} - -/** - * read_rgrps - Reads the contents of the rindex file - * @fs_fd: An fd for any file or directory within the mounted GFS filesytem - * - */ - -static void -read_rgrps(int fs_fd) -{ - uint64_t offset = 0; - while (get_rgrp(fs_fd, &offset) == 0) - /* do nothing */; -} - -/** - * write_a_block - Write a block to the current device - * @where: The position to write the block (in filesystem blocks) - * - * Writes a single disk block to the device. It has a safety check which - * prevents it writing to the device at a position within the control of - * the active filesystem. - */ - -static void -write_a_block(uint64_t where, uint64_t seq) -{ - char buffer[4096]; - uint64_t fsoffset = where * (uint64_t) fs_sb.sb_bsize; - int fd = open(device, O_RDWR); - struct gfs_log_header lh; - - memset(&lh, 0, sizeof(struct gfs_log_header)); - - lh.lh_header.mh_magic = GFS_MAGIC; - lh.lh_header.mh_type = GFS_METATYPE_LH; - lh.lh_header.mh_format = GFS_FORMAT_LH; - lh.lh_flags = GFS_LOG_HEAD_UNMOUNT; - lh.lh_first = where; - lh.lh_sequence = seq; - - if (fd < 0) { - perror(device); - exit(EXIT_FAILURE); - } - if (where < fssize) { - fprintf(stderr, - "Sanity check failed: Caught trying to write to live filesystem!\n"); - exit(EXIT_FAILURE); - } - - memset(buffer, 0, 4096); - gfs_log_header_out(&lh, buffer); - gfs_log_header_out(&lh, BLOCK_END(buffer, struct gfs_log_header)); - - if (lseek(fd, fsoffset, SEEK_SET) != fsoffset) { - perror(device); - exit(EXIT_FAILURE); - } - if (write(fd, buffer, fs_sb.sb_bsize) != fs_sb.sb_bsize) { - perror("write_a_block"); - exit(EXIT_FAILURE); - } - close(fd); -} - -/** - * write_whole_journal - Write a complete journal to the disk - * @jil: The information about the journal - * - * Write a complete new journal on disk. - */ - -static void -write_whole_journal(struct jilist_entry *jil) -{ - uint64_t seg; - uint64_t offset; - - for (seg = 0; seg < jil->ji.ji_nsegment; seg++) { - offset = seg * fs_sb.sb_seg_size; - write_a_block(jil->ji.ji_addr + offset, offset); - } - - sync(); -} - -/** - * get_length - Use stat() to get the length of a file - * @fd: The fd of the file whose length we wish to know - * - * Returns: The length - */ - -static uint64_t -get_length(int fd, char *file) -{ - struct gfs_ioctl gi; - char *argv[] = { "get_hfile_stat", file }; - struct gfs_dinode di; - int error; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) { - perror("stat"); - fprintf(stderr, "Failed to get size of file. Aborting.\n"); - exit(EXIT_FAILURE); - } - - return di.di_size; -} - -/** - * write_jindex - Writes new records to the end of the jindex file - * @fs_fd: A fd of any file or directory withint the GFS filesystem - * - * This is the critical function in adding journals. It does the - * actual write to the jindex which causes the GFS filesystem to see the - * new journals which were previously added. - */ - -static void -write_jindex(int fs_fd) -{ - osi_list_t *tmp, *head; - struct jilist_entry *jil; - char buffer[sizeof(struct gfs_jindex)]; - uint64_t offset; - - offset = get_length(fs_fd, "jindex"); - - /* - * This is the critical section. - * If things mess up here, it could be very difficult to put right - */ - tmp = head = &jilist_new; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - jil = osi_list_entry(tmp, struct jilist_entry, list); - gfs_jindex_out(&jil->ji, buffer); - if (jwrite(fs_fd, "jindex", buffer, - sizeof(struct gfs_jindex), &offset) != - sizeof(struct gfs_jindex)) { - perror("write: jindex"); - fprintf(stderr, "Aborting...\n"); - exit(EXIT_FAILURE); - } - } - /* - * This is the end of the critical section - */ -} - -/** - * write_journals - Write the new journals to disk - * @fs_fd: An fd from any file or directory on the GFS mounted filesystem - * - * This first writes out the new journal information to the - * area of the disk beyond the area the filesystem is currently - * using and then calls write_jindex() to make the filesystem see - * the newly written journal. - */ - -static void -write_journals(int fs_fd) -{ - osi_list_t *tmp, *head; - struct jilist_entry *jil; - - tmp = head = &jilist_new; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - jil = osi_list_entry(tmp, struct jilist_entry, list); - write_whole_journal(jil); - } - - sync(); - sync(); - sync(); - - write_jindex(fs_fd); - - sync(); - sync(); - sync(); -} - -/** - * gather_info - Gathers all the information about the existing filesystem - * - */ - -static void -gather_info(void) -{ - int fd; - struct gfs_ioctl gi; - char *argv[] = { "get_super" }; - int error; - - fd = open(fspath, O_RDONLY); - if (fd < 0) { - perror(fspath); - exit(EXIT_FAILURE); - } - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = (char *)&fs_sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) { - perror("ioctl: GFS_GET_SUPER"); - exit(EXIT_FAILURE); - } - - read_rgrps(fd); - read_journals(fd); - close(fd); - devsize = device_geometry(device); - fssize = filesystem_size(); - - journal_size_blocks = journal_size << (20 - fs_sb.sb_bsize_shift); - /* - * Round size down to integer number of segments - */ - while (journal_size_blocks % fs_sb.sb_seg_size) { - journal_size_blocks--; - journal_size -= fs_sb.sb_bsize; - } -} - -/** - * print_rgrps - Print information about resource groups - * @lh: The list of resource groups to print - * - */ - -static void -print_rgrps(osi_list_t *lh) -{ - osi_list_t *tmp, *head; - struct rglist_entry *rgl; - int n = 0; - - tmp = head = lh; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - rgl = osi_list_entry(tmp, struct rglist_entry, list); - n++; - printf("RI: Addr %"PRIu64", RgLen %u, Start %"PRIu64", DataLen %u, BmapLen %u\n", - rgl->ri.ri_addr, rgl->ri.ri_length, - rgl->ri.ri_data1, rgl->ri.ri_data, rgl->ri.ri_bitbytes); - } - printf("RGRP: %d Resource groups in total\n", n); -} - -/** - * print_journals - Print a list of journals - * - */ - -static void -print_journals(osi_list_t *lh) -{ - osi_list_t *tmp, *head; - struct jilist_entry *jil; - int n = 0; - - tmp = head = lh; - for (;;) { - tmp = tmp->next; - if (tmp == head) - break; - jil = osi_list_entry(tmp, struct jilist_entry, list); - n++; - printf("JI: Addr %"PRIu64" NumSeg %u SegSize %u\n", - jil->ji.ji_addr, jil->ji.ji_nsegment, fs_sb.sb_seg_size); - } - printf("JRNL: %d Journals in total\n", n); -} - -/** - * print_info - Print out various bits of (interesting?) information - * - */ - -static void -print_info(void) -{ - printf("FS: Mount Point: %s\n", fspath); - printf("FS: Device: %s\n", device); - printf("FS: Options: %s\n", fsoptions); - printf("FS: Size: %"PRIu64"\n", fssize); - if (verbose > 1) { - printf("RGRP: Current Resource Group List:\n"); - print_rgrps(&rglist_current); - printf("JRNL: Current Journal List:\n"); - print_journals(&jilist_current); - } - printf("DEV: Size: %"PRIu64"\n", devsize); - if (verbose > 1) { - printf("JRNL: New Journal List:\n"); - print_journals(&jilist_new); - } -} - -/** - * make_journal - Make a new jilist_entry - * @offset: The offset at which the new journal will go - * @size: The size of the new journal in fs blocks - * - */ - -uint64_t -make_journal(uint64_t offset, uint64_t size) -{ - struct jilist_entry *jil = malloc(sizeof(struct jilist_entry)); - if (jil == NULL) { - perror("jilist_entry"); - exit(EXIT_FAILURE); - } - memset(jil, 0, sizeof(struct jilist_entry)); - - if (offset % fs_sb.sb_seg_size) { - size -= fs_sb.sb_seg_size - (offset % fs_sb.sb_seg_size); - offset += fs_sb.sb_seg_size - (offset % fs_sb.sb_seg_size); - } - - jil->ji.ji_addr = offset; - jil->ji.ji_nsegment = size / fs_sb.sb_seg_size; - - osi_list_add(&jil->list, &jilist_new); - return offset + size; -} - -/** - * create_journals - Create a list of the new journals - * - */ - -static int -create_journals(void) -{ - uint64_t offset = fssize; - int n; - - if ((journal_size_blocks * number_of_journals) > (devsize - fssize)) { - fprintf(stderr, - "Requested size (%" PRIu64 - " blocks) greater than available space (%" PRIu64 - " blocks)\n", journal_size_blocks * number_of_journals, - devsize - fssize); - return -1; - } - - for (n = 0; n < number_of_journals; n++) - offset = make_journal(offset, journal_size_blocks); - - if (offset > devsize) { - fprintf(stderr, "Calculation error: Out of bounds\n"); - exit(EXIT_FAILURE); - } - - return 0; -} - -/** - * update_fs - Actually perform the filesystem update - * - */ - -static void -update_fs(void) -{ - int fd = open(fspath, O_RDONLY); - if (fd < 0) { - perror(fspath); - exit(EXIT_FAILURE); - } - if (verbose) - printf("Preparing to write new FS information...\n"); - write_journals(fd); - if (verbose) - printf("Done.\n"); - close(fd); -} - -/** - * find_fs - Find the filesystem which the user specified - * @name: The name of a device or mount point - * - * Returns: 0 if the filesystem is located, 1 otherwise - */ - -static int -find_fs(char *name) -{ - FILE *fp = fopen("/proc/mounts", "r"); - char buffer[4096]; - char fstype[80]; - int fsdump, fspass; - - if (fp == NULL) { - perror("open: /proc/mounts"); - exit(EXIT_FAILURE); - } - while ((fgets(buffer, 4095, fp)) != NULL) { - buffer[4095] = 0; - if (strstr(buffer, name) == 0) - continue; - if (sscanf(buffer, "%s %s %s %s %d %d", device, fspath, fstype, - fsoptions, &fsdump, &fspass) != 6) - continue; - if (strcmp(fstype, "gfs") != 0) - continue; - if ((strcmp(device, name) != 0) && (strcmp(fspath, name) != 0)) - continue; - fclose(fp); - return 0; - } - fprintf(stderr, "GFS Filesystem %s not found\n", name); - fclose(fp); - return 1; -} - -/** - * delete_rgrp_list - Delete a list of rgrps - * @list: The list to delete - * - */ - -static void -delete_rgrp_list(osi_list_t *list) -{ - struct rglist_entry *rg; - - while (!osi_list_empty(list)) { - rg = osi_list_entry(list->next, struct rglist_entry, list); - osi_list_del(&rg->list); - free(rg); - } -} - -/** - * delete_jrnl_list - Delete a list of journals - * @list: The list to delete - * - */ - -static void -delete_jrnl_list(osi_list_t *list) -{ - struct jilist_entry *ji; - - while (!osi_list_empty(list)) { - ji = osi_list_entry(list->next, struct jilist_entry, list); - osi_list_del(&ji->list); - free(ji); - } -} - -/** - * usage - Print out the usage message - * - * This function does not include documentation for the -D option - * since normal users have no use for it at all. The -D option is - * only for developers. It intended use is in combination with the - * -T flag to find out what the result would be of trying different - * device sizes without actually having to try them manually. - */ - -static void -usage(void) -{ - fprintf(stdout, - "Usage:\n" - "\n" - "gfs_jadd [options] /path/to/filesystem\n" - "\n" - "Options:\n" - " -h Print this usage information.\n" - " -J <MB> Size of journals in MB (minimum 32, default 128)\n" - " -j <num> Number of journals to add (default 1)\n" - " -q Quiet, reduce verbosity\n" - " -T Test, do everything except update FS\n" - " -V Version information\n" - " -v Verbose, increase verbosity\n"); -} - -/** - * main - Tha main function - * @argc: The argument count - * @argv: The argument vector - * - * Runs through the filesystem expansion code for each of the specified - * filesystems. Each filesystem specified on the command line has the - * same options applied to it. You'll need to run the program multiple times - * if you want to use it on several different filesystems with different - * options for each. If you forget to specify a filesystem, then it is - * assumed that the program has run successfully, since its done everything - * asked of it, and it exits without printing a message. - * - * Returns: 0 on success, -1 otherwise - */ - -int -main(int argc, char *argv[]) -{ - int opt; - int error = 0; - - while ((opt = getopt(argc, argv, "D:Vhj:J:vqT?")) != EOF) { - switch (opt) { - case 'D': /* This option is for testing only */ - override_device_size = atoi(optarg); - override_device_size <<= 20; - break; - case 'V': - printf("%s %s (built %s %s)\n", argv[0], - GFS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - case 'h': - usage(); - exit(0); - case 'j': - number_of_journals = atoi(optarg); - if (number_of_journals < 1) { - fprintf(stderr, - "Erk! Number of journals must be 1 or greater.\n"); - usage(); - exit(EXIT_FAILURE); - } - break; - case 'J': - journal_size = atoi(optarg); - if (journal_size < 32) { - fprintf(stderr, - "Erk! Specified journal size of %" - PRIu64 " is too small.\n", - journal_size); - usage(); - exit(EXIT_FAILURE); - } - break; - case 'q': - if (verbose) - verbose--; - break; - case 'T': - test = 1; - break; - case 'v': - verbose++; - break; - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - default: - fprintf(stderr, "Bad programmer! You forgot" - " to catch the %c flag\n", opt); - exit(EXIT_FAILURE); - break; - } - } - - if (optind == argc) { - usage(); - exit(EXIT_FAILURE); - } - - while ((argc - optind) > 0) { - if (find_fs(argv[optind++])) { - error = 1; - continue; - } - gather_info(); - if (fssize > devsize) { - fprintf(stderr, - "Filesystem thinks device is bigger than it really is.... skipping\n"); - error = 1; - continue; - } - if (create_journals()) { - error = 1; - continue; - } - if (verbose) - print_info(); - if (!test) - update_fs(); - delete_rgrp_list(&rglist_current); - delete_jrnl_list(&jilist_current); - delete_jrnl_list(&jilist_new); - } - - return error; -} diff --git a/gfs/gfs_jadd/ondisk.c b/gfs/gfs_jadd/ondisk.c deleted file mode 100644 index ebb14ad..0000000 --- a/gfs/gfs_jadd/ondisk.c +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> diff --git a/gfs/gfs_mkfs/Makefile b/gfs/gfs_mkfs/Makefile deleted file mode 100644 index 58d4a35..0000000 --- a/gfs/gfs_mkfs/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -TARGET= gfs_mkfs - -SOURCE= \ - device_geometry.c \ - fs_geometry.c \ - locking.c \ - main.c \ - ondisk.c \ - structures.c - -CFLAGS+= -O2 -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config \ - -I${incdir} - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -LDFLAGS+= -L${libdir} -LOADLIBES+= -liddev - -all: ${TARGET} - -gfs_mkfs: ${SOURCE} - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} - - diff --git a/gfs/gfs_mkfs/device_geometry.c b/gfs/gfs_mkfs/device_geometry.c deleted file mode 100644 index 7a7c4b0..0000000 --- a/gfs/gfs_mkfs/device_geometry.c +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <assert.h> -#include <time.h> -#include <sys/param.h> - -#include "global.h" -#include <linux/gfs_ondisk.h> -#include "osi_list.h" -#include "iddev.h" - -#include "mkfs_gfs.h" - - - - - -/** - * device_geometry - Get the size of a device - * @comline: the command line - * @device: the structure the geometry is returned in - * - */ - -void device_geometry(commandline_t *comline, mkfs_device_t *device) -{ - int fd; - uint64 bytes; - int error; - - - fd = open(comline->device, O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", comline->device, strerror(errno)); - - error = device_size(fd, &bytes); - if (error) - die("can't determine size of %s: %s\n", comline->device, strerror(errno)); - - close(fd); - - - if (comline->debug) - printf("\nPartition size = %"PRIu64"\n", bytes >> 9); - - - device->nsubdev = 1; - - type_zalloc(device->subdev, mkfs_subdevice_t, 1); - - device->subdev->start = 0; - device->subdev->length = bytes >> 9; -} - - -/** - * add_journals_to_device - carve space out of a mkfs_device_t to add journals - * @comline: the command line arguments - * @device: the mkfs_device_t - * - */ - -void add_journals_to_device(commandline_t *comline, mkfs_device_t *device) -{ - mkfs_subdevice_t *old; - uint64 jsize; - unsigned int x; - - - MKFS_ASSERT(device->nsubdev == 1 && - !device->subdev->is_journal, ); - - - if (!comline->journals) - die("No journals specified (use -j)\n"); - - if (!comline->jsize) - die("journal size is zero (use -J)\n"); - - jsize = comline->jsize * (1 << 20) / GFS_BASIC_BLOCK; - - if (comline->journals * jsize > device->subdev->length) - die("Partition too small for number/size of journals\n"); - - - old = device->subdev; - - - device->nsubdev = comline->journals + 2; - type_zalloc(device->subdev, mkfs_subdevice_t, device->nsubdev); - - device->subdev[0].start = old->start; - device->subdev[0].length = (old->length - comline->journals * jsize) / 2; - - for (x = 1; x <= comline->journals; x++) - { - device->subdev[x].start = device->subdev[x - 1].start + device->subdev[x - 1].length; - device->subdev[x].length = jsize; - device->subdev[x].is_journal = TRUE; - } - - device->subdev[x].start = device->subdev[x - 1].start + device->subdev[x - 1].length; - device->subdev[x].length = device->subdev[0].length; - - - free(old); -} - - -/** - * fix_device_geometry - round off address and lengths and convert to FS blocks - * @comline: the command line - * @device: the description of the underlying device - * - */ - -void fix_device_geometry(commandline_t *comline, mkfs_device_t *device) -{ - unsigned int x; - uint64 offset, len; - uint32 bbsize = comline->bsize >> 9; - - - if (comline->debug) - { - printf("\nDevice Geometry: (in basic blocks)\n"); - for (x = 0; x < device->nsubdev; x++) - printf(" SubDevice #%d: %s: start = %"PRIu64", len = %"PRIu64"\n", - x, - (device->subdev[x].is_journal) ? "journal" : "data", - device->subdev[x].start, - device->subdev[x].length); - } - - - /* Make sure all the subdevices are aligned */ - - for (x = 0; x < device->nsubdev; x++) - { - offset = device->subdev[x].start; - len = device->subdev[x].length; - - - if (len < 100 * bbsize) - die("subdevice %d is way too small (%"PRIu64" bytes)\n", x, len * GFS_BASIC_BLOCK); - - - if (offset % bbsize) - { - len -= bbsize - (offset % bbsize); - offset += bbsize - (offset % bbsize); - } - - - device->subdev[x].start = offset / bbsize; - device->subdev[x].length = len / bbsize; - } - - - if (comline->debug) - { - printf("\nDevice Geometry: (in FS blocks)\n"); - for (x = 0; x < device->nsubdev; x++) - printf(" SubDevice #%d: %s: start = %"PRIu64", len = %"PRIu64"\n", - x, - (device->subdev[x].is_journal) ? "journal" : "data", - device->subdev[x].start, - device->subdev[x].length); - - printf("\njournals = %u\n", comline->journals); - } -} - - - diff --git a/gfs/gfs_mkfs/fs_geometry.c b/gfs/gfs_mkfs/fs_geometry.c deleted file mode 100644 index 722d37a..0000000 --- a/gfs/gfs_mkfs/fs_geometry.c +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <assert.h> -#include <time.h> - -#include "global.h" -#include <linux/gfs_ondisk.h> -#include "osi_list.h" - -#include "mkfs_gfs.h" - - - - - -/** - * how_many_rgrps - figure out how many RG to put in a subdevice - * @comline: the command line - * @sdev: the subdevice - * - * Returns: the number of RGs - */ - -static uint64 how_many_rgrps(commandline_t *comline, mkfs_subdevice_t *sdev) -{ - uint64 nrgrp; - unsigned int min = (comline->expert) ? 1 : 4; - - nrgrp = DIV_RU(sdev->length, (comline->rgsize << 20) / comline->bsize); - - if (nrgrp < min) - nrgrp = min; - - if (comline->debug) - printf(" nrgrp = %"PRIu64"\n", nrgrp); - - return nrgrp; -} - - -/** - * compute_rgrp_layout - figure out where the RG in a FS are - * @comline: the command line - * @device: the device layout - * @rlist: the list of resource groups - * - * Returns: a list of rgrp_list_t structures - */ - -void compute_rgrp_layout(commandline_t *comline, mkfs_device_t *device, osi_list_t *rlist) -{ - mkfs_subdevice_t *sdev; - rgrp_list_t *rl, *rlast = NULL; - osi_list_t *tmp; - uint64 rgrp, nrgrp; - unsigned int x; - int first_sdev = TRUE; - - - for (x = 0; x < device->nsubdev; x++) - { - sdev = &device->subdev[x]; - - if (!sdev->is_journal) - { - /* If this is the first subdevice reserve space for the superblock */ - - if (first_sdev) - sdev->length -= comline->sb_addr + 1; - - - if (comline->debug) - printf("\nData Subdevice %u\n", x); - - nrgrp = how_many_rgrps(comline, sdev); - - - for (rgrp = 0; rgrp < nrgrp; rgrp++) - { - type_zalloc(rl, rgrp_list_t, 1); - - rl->subdevice = x; - - if (rgrp) - { - rl->rg_offset = rlast->rg_offset + rlast->rg_length; - rl->rg_length = sdev->length / nrgrp; - } - else - { - rl->rg_offset = sdev->start; - rl->rg_length = sdev->length - (nrgrp - 1) * (sdev->length / nrgrp); - - if (first_sdev) - rl->rg_offset += comline->sb_addr + 1; - } - - osi_list_add_prev(&rl->list, rlist); - - rlast = rl; - } - - first_sdev = FALSE; - - comline->rgrps += nrgrp; - } - } - - - if (comline->debug) - { - printf("\n"); - - for (tmp = rlist->next; tmp != rlist; tmp = tmp->next) - { - rl = osi_list_entry(tmp, rgrp_list_t, list); - printf("subdevice %u: rg_o = %"PRIu64", rg_l = %"PRIu64"\n", - rl->subdevice, - rl->rg_offset, rl->rg_length); - } - } -} - - -/** - * compute_journal_layout - figure out where the journals in a FS are - * @comline: the command line - * @device: the device layout - * @jlist: the list of journals - * - * Returns: a list of journal_list_t structures - */ - -void compute_journal_layout(commandline_t *comline, mkfs_device_t *device, osi_list_t *jlist) -{ - mkfs_subdevice_t *sdev; - journal_list_t *jl; - osi_list_t *tmp; - unsigned int x, j = 0; - uint64 boffset, bcount; - unsigned int min_jsize = (comline->expert) ? 1 : 32; - - - for (x = 0; x < device->nsubdev; x++) - { - sdev = &device->subdev[x]; - - if (sdev->is_journal) - { - type_zalloc(jl, journal_list_t, 1); - - /* Align the journals on seg_size boundries */ - - boffset = sdev->start; - bcount = sdev->length; - - if ((bcount + comline->seg_size) * comline->bsize < min_jsize << 20) - die("journal %d is too small (minimum size is %u MB)\n", j, min_jsize); - - if (boffset % comline->seg_size) - { - bcount -= comline->seg_size - (boffset % comline->seg_size); - boffset += comline->seg_size - (boffset % comline->seg_size); - } - - jl->start = boffset; - jl->segments = bcount / comline->seg_size; - - osi_list_add_prev(&jl->list, jlist); - - j++; - } - } - - - if (comline->debug) - { - printf("\n"); - - for (tmp = jlist->next, j = 0; tmp != jlist; tmp = tmp->next, j++) - { - jl = osi_list_entry(tmp, journal_list_t, list); - printf("journal %u: start = %"PRIu64", segments = %u\n", - j, jl->start, jl->segments); - } - } -} - diff --git a/gfs/gfs_mkfs/locking.c b/gfs/gfs_mkfs/locking.c deleted file mode 100644 index 91db9f4..0000000 --- a/gfs/gfs_mkfs/locking.c +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include "global.h" -#include <linux/gfs_ondisk.h> -#include "osi_list.h" - -#include "mkfs_gfs.h" - - - - - -/** - * test_locking - Make sure the GFS is set up to use the right lock protocol - * @lockproto: the lock protocol to mount - * @locktable: the locktable name - * @estr: returns the a string describing the error - * @elen: the length of @estr - * - * Returns: 0 if things are ok, -1 on error (with estr set) - */ - -int test_locking(char *lockproto, char *locktable, char *estr, unsigned int elen) -{ - char *c; - - if (strcmp(lockproto, "lock_nolock") == 0) - { - /* Nolock is always ok. */ - } - else if (strcmp(lockproto, "lock_gulm") == 0 || - strcmp(lockproto, "lock_dlm") == 0) - { - for (c = locktable; *c; c++) - { - if (isspace(*c)) - { - snprintf(estr, elen, "locktable error: contains space characters"); - return -1; - } - if (!isprint(*c)) - { - snprintf(estr, elen, "locktable error: contains unprintable characters"); - return -1; - } - } - - c = strstr(locktable, ":"); - if (!c) - { - snprintf(estr, elen, "locktable error: missing colon in the locktable"); - return -1; - } - - if (c == locktable) - { - snprintf(estr, elen, "locktable error: missing cluster name"); - return -1; - } - - if (c - locktable > 16) - { - snprintf(estr, elen, "locktable error: cluster name too long"); - return -1; - } - - c++; - if (!c) - { - snprintf(estr, elen, "locktable error: missing filesystem name"); - return -1; - } - - if (strstr(c, ":")) - { - snprintf(estr, elen, "locktable error: more than one colon present"); - return -1; - } - - if (!strlen(c)) - { - snprintf(estr, elen, "locktable error: missing filesystem name"); - return -1; - } - - if (strlen(c) > 16) - { - snprintf(estr, elen, "locktable error: filesystem name too long"); - return -1; - } - } - else - { - snprintf(estr, elen, "lockproto error: %s unknown", lockproto); - return -1; - } - - return 0; -} diff --git a/gfs/gfs_mkfs/main.c b/gfs/gfs_mkfs/main.c deleted file mode 100644 index f2d1580..0000000 --- a/gfs/gfs_mkfs/main.c +++ /dev/null @@ -1,407 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <assert.h> -#include <time.h> - -#include "global.h" -#include <linux/gfs_ondisk.h> -#include "osi_list.h" -#include "iddev.h" - -#include "copyright.cf" - -#define EXTERN -#include "mkfs_gfs.h" - - - -#define OPTION_STRING ("b:DhJ:j:Op:qr:s:t:VX") - - - - - -/** - * print_usage - print out usage information - * - */ - -static void print_usage() -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options] <device>\n", prog_name); - printf("\n"); - printf("Options:\n"); - printf("\n"); - printf(" -b <bytes> Filesystem block size\n"); - printf(" -D Enable debugging code\n"); - printf(" -h Print this help, then exit\n"); - printf(" -J <MB> Size of journals\n"); - printf(" -j <num> Number of journals\n"); - printf(" -O Don't ask for confirmation\n"); - printf(" -p <name> Name of the locking protocol\n"); - printf(" -q Don't print anything\n"); - printf(" -r <MB> Resource Group Size\n"); - printf(" -s <blocks> Journal segment size\n"); - printf(" -t <name> Name of the lock table\n"); - printf(" -V Print program version information, then exit\n"); -} - - -/** - * decode_arguments - decode command line arguments and fill in the commandline_t - * @argc: - * @argv: - * @comline: the decoded command line arguments - * - */ - -static void decode_arguments(int argc, char *argv[], commandline_t *comline) -{ - int cont = TRUE; - int optchar; - - - while (cont) - { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) - { - case 'b': - comline->bsize = atoi(optarg); - break; - - - case 'D': - comline->debug = TRUE; - break; - - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - - case 'J': - comline->jsize = atoi(optarg); - break; - - - case 'j': - comline->journals = atoi(optarg); - break; - - - case 'O': - comline->override = TRUE; - break; - - - case 'p': - if (strlen(optarg) >= GFS_LOCKNAME_LEN) - die("lock protocol name %s is too long\n", optarg); - strcpy(comline->lockproto, optarg); - break; - - - case 'q': - comline->quiet = TRUE; - break; - - - case 'r': - comline->rgsize = atoi(optarg); - break; - - - case 's': - comline->seg_size = atoi(optarg); - break; - - - case 't': - if (strlen(optarg) >= GFS_LOCKNAME_LEN) - die("lock table name %s is too long\n", optarg); - strcpy(comline->locktable, optarg); - break; - - - case 'V': - printf("gfs_mkfs %s (built %s %s)\n", GFS_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - - case 'X': - comline->expert = TRUE; - break; - - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - - case EOF: - cont = FALSE; - break; - - - default: - die("unknown option: %c\n", optchar); - break; - }; - } - - - if (optind < argc) - { - comline->device = argv[optind]; - optind++; - } - else - die("no device specified (try -h for help)\n"); - - - - if (optind < argc) - die("Unrecognized option: %s\n", argv[optind]); - - - if (comline->debug) - { - printf("Command Line Arguments:\n"); - printf(" proto = %s\n", comline->lockproto); - printf(" table = %s\n", comline->locktable); - printf(" bsize = %u\n", comline->bsize); - printf(" seg_size = %u\n", comline->seg_size); - printf(" journals = %u\n", comline->journals); - printf(" jsize = %u\n", comline->jsize); - printf(" rgsize = %u\n", comline->rgsize); - printf(" debug = %d\n", comline->debug); - printf(" device = %s\n", comline->device); - } -} - - -/** - * are_you_sure - protect lusers from themselves - * @comline: the command line - * - */ - -void are_you_sure(commandline_t *comline) -{ - char buf[1024]; - char input[32]; - int unknown; - - unknown = identify_device(comline->fd, buf, 1024); - if (unknown < 0) - die("error identifying the contents of %s: %s\n", comline->device, strerror(errno)); - - printf("This will destroy any data on %s.\n", comline->device); - if (!unknown) - printf(" It appears to contain a %s.\n", buf); - - printf("\nAre you sure you want to proceed? [y/n] "); - fgets(input, 32, stdin); - - if (input[0] != 'y') - die("aborted\n"); - else - printf("\n"); -} - - -/** - * print_results - print out summary information - * @comline: the command line - * - */ - -void print_results(commandline_t *comline) -{ - if (comline->quiet) - return; - - if (comline->expert) - printf("Expert mode: on\n"); - - printf("Device: %s\n", comline->device); - - printf("Blocksize: %u\n", comline->bsize); - printf("Filesystem Size: %"PRIu64"\n", comline->fssize); - - printf("Journals: %u\n", comline->journals); - printf("Resource Groups: %"PRIu64"\n", comline->rgrps); - - printf("Locking Protocol: %s\n", comline->lockproto); - printf("Lock Table: %s\n", comline->locktable); - - printf("\nSyncing...\n"); - - sync(); - - printf("All Done\n"); -} - - -/** - * main - do everything - * @argc: - * @argv: - * - * Returns: 0 on success, non-0 on failure - */ - -int main(int argc, char *argv[]) -{ - commandline_t comline; - mkfs_device_t device; - osi_list_t rlist; - osi_list_t jlist; - unsigned int x; - - - prog_name = argv[0]; - - osi_list_init(&rlist); - osi_list_init(&jlist); - - - /* Process the command line arguments */ - - memset(&comline, 0, sizeof(commandline_t)); - comline.bsize = MKFS_DEFAULT_BSIZE; - comline.seg_size = MKFS_DEFAULT_SEG_SIZE; - comline.jsize = MKFS_DEFAULT_JSIZE; - comline.rgsize = MKFS_DEFAULT_RGSIZE; - - decode_arguments(argc, argv, &comline); - - if (!comline.expert) - { - char buf[256]; - if (test_locking(comline.lockproto, comline.locktable, buf, 256)) - die("%s\n", buf); - } - - - - /* Block sizes must be a power of two from 512 to 65536 */ - - for (x = 512; x; x <<= 1) - if (x == comline.bsize) - break; - - if (!x || comline.bsize > 65536) - die("block size must be a power of two between 512 and 65536\n"); - - comline.sb_addr = GFS_SB_ADDR * GFS_BASIC_BLOCK / comline.bsize; - - if (comline.seg_size < 2) - die("segment size too small\n"); - - if (!comline.expert && (uint64)comline.seg_size * comline.bsize > 4194304) - die("segment size too large\n"); - - if (comline.expert) - { - if (1 > comline.rgsize || comline.rgsize > 2048) - die("bad resource group size\n"); - } - else - { - if (32 > comline.rgsize || comline.rgsize > 2048) - die("bad resource group size\n"); - } - - - - /* Get the device geometry */ - - memset(&device, 0, sizeof(mkfs_device_t)); - - device_geometry(&comline, &device); - add_journals_to_device(&comline, &device); - - fix_device_geometry(&comline, &device); - - - - /* Compute the resource group layouts */ - - compute_rgrp_layout(&comline, &device, &rlist); - - compute_journal_layout(&comline, &device, &jlist); - - - /* Start writing stuff out */ - - comline.fd = open(comline.device, O_RDWR); - if (comline.fd < 0) - die("can't open device %s\n", comline.device); - - - if (!comline.override) - are_you_sure(&comline); - - - write_sb(&comline, &rlist); - - /* Figure out where we start allocting in rgrp 0 */ - comline.rgrp0_next = comline.sb->sb_root_di.no_addr + 1; - - write_jindex(&comline, &jlist); - - write_rindex(&comline, &rlist); - - write_root(&comline); - - write_quota(&comline); - - write_license(&comline); - - write_rgrps(&comline, &rlist); - - write_journals(&comline, &jlist); - - - close(comline.fd); - - - print_results(&comline); - - - exit(EXIT_SUCCESS); -} - - - diff --git a/gfs/gfs_mkfs/mkfs_gfs.h b/gfs/gfs_mkfs/mkfs_gfs.h deleted file mode 100644 index 6f7b642..0000000 --- a/gfs/gfs_mkfs/mkfs_gfs.h +++ /dev/null @@ -1,192 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __MKFS_GFS_DOT_H__ -#define __MKFS_GFS_DOT_H__ - - -/* Extern Macro */ - -#ifndef EXTERN -#define EXTERN extern -#define INIT(X) -#else -#undef EXTERN -#define EXTERN -#define INIT(X) =X -#endif - - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -#define MKFS_ASSERT(x, todo) \ -do \ -{ \ - if (!(x)) \ - { \ - {todo} \ - die("assertion failed on line %d of file %s\n", __LINE__, __FILE__); \ - } \ -} \ -while (0) - -#define type_zalloc(ptr, type, count) \ -do \ -{ \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if ((ptr)) \ - memset((char *)(ptr), 0, sizeof(type) * (count)); \ - else \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} \ -while (0) - -#define type_alloc(ptr, type, count) \ -do \ -{ \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if (!(ptr)) \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} \ -while (0) - -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) - - - - - -struct mkfs_subdevice -{ - uint64 start; - uint64 length; - int is_journal; -}; -typedef struct mkfs_subdevice mkfs_subdevice_t; - - -struct mkfs_device -{ - unsigned int nsubdev; - mkfs_subdevice_t *subdev; -}; -typedef struct mkfs_device mkfs_device_t; - - -struct commandline -{ - char lockproto[GFS_LOCKNAME_LEN]; - char locktable[GFS_LOCKNAME_LEN]; - - uint32 bsize; /* The block size of the FS */ - uint32 seg_size; /* The journal segment size */ - uint32 journals; /* Number of journals */ - uint32 jsize; /* Size of journals */ - uint32 rgsize; /* The Resource Group size */ - - int debug; /* Print out debugging information? */ - int quiet; /* No messages */ - int expert; - int override; - - char *device; /* device */ - - - /* Not specified on the command line, but... */ - - uint64 rgrps; /* Number of rgrps */ - int fd; /* fd of the device */ - struct gfs_sb *sb; /* A copy of the superblock */ - uint64 fssize; /* size of the filesystem */ - - uint64 sb_addr; - - uint64 rgrp0_next; /* The address of the next available block in rgrp 0 */ -}; -typedef struct commandline commandline_t; - - -struct rgrp_list -{ - osi_list_t list; - - uint32 subdevice; /* The subdevice who holds this resource group */ - - uint64 rg_offset; /* The offset of the beginning of this resource group */ - uint64 rg_length; /* The length of this resource group */ - - struct gfs_rindex *ri; -}; -typedef struct rgrp_list rgrp_list_t; - - -struct journal_list -{ - osi_list_t list; - - uint64 start; - uint32 segments; -}; -typedef struct journal_list journal_list_t; - - -EXTERN char *prog_name; - - -#define MKFS_DEFAULT_BSIZE (4096) -#define MKFS_DEFAULT_SEG_SIZE (16) -#define MKFS_DEFAULT_JSIZE (128) -#define MKFS_DEFAULT_RGSIZE (256) - - -/* device_geometry.c */ - -void device_geometry(commandline_t *comline, mkfs_device_t *device); -void add_journals_to_device(commandline_t *comline, mkfs_device_t *device); -void fix_device_geometry(commandline_t *comline, mkfs_device_t *device); - - -/* fs_geometry.c */ - -void compute_rgrp_layout(commandline_t *comline, mkfs_device_t *device, osi_list_t *rlist); -void compute_journal_layout(commandline_t *comline, mkfs_device_t *device, osi_list_t *jlist); - - -/* locking.c */ - -int test_locking(char *lockproto, char *locktable, char *estr, unsigned int elen); - - -/* structures.c */ - -void write_sb(commandline_t *comline, osi_list_t *rlist); -void write_jindex(commandline_t *comline, osi_list_t *jlist); -void write_rindex(commandline_t *comline, osi_list_t *rlist); -void write_root(commandline_t *comline); -void write_quota(commandline_t *comline); -void write_license(commandline_t *comline); -void write_rgrps(commandline_t *comline, osi_list_t *rlist); -void write_journals(commandline_t *comline, osi_list_t *jlist); - - -#endif /* __MKFS_GFS_DOT_H__ */ - diff --git a/gfs/gfs_mkfs/ondisk.c b/gfs/gfs_mkfs/ondisk.c deleted file mode 100644 index 2e51b7b..0000000 --- a/gfs/gfs_mkfs/ondisk.c +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "global.h" -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> - diff --git a/gfs/gfs_mkfs/structures.c b/gfs/gfs_mkfs/structures.c deleted file mode 100644 index 273dfee..0000000 --- a/gfs/gfs_mkfs/structures.c +++ /dev/null @@ -1,1042 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <assert.h> -#include <time.h> - -#include "global.h" -#include <linux/gfs_ondisk.h> -#include "osi_list.h" -#include "linux_endian.h" - -#include "mkfs_gfs.h" - - -#define MKFS_ROOT_MODE (0755) -#define MKFS_HIDDEN_MODE (0600) - - -#define do_lseek(fd, off) \ -{ \ - if (lseek((fd), (off), SEEK_SET) != (off)) \ - die("bad seek: %s on line %d of file %s\n", \ - strerror(errno),__LINE__, __FILE__); \ -} - -#define do_read(fd, buff, len) \ -{ \ - if (read((fd), (buff), (len)) != (len)) \ - die("bad read: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} - -#define do_write(fd, buff, len) \ -{ \ - if (write((fd), (buff), (len)) != (len)) \ - die("bad write: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} - - - - - -/** - * rgblocks2bitblocks - blerg - * @bsize: the FS block size - * @rgblocks: The total number of the blocks in the RG - * Also, returns the number of allocateable blocks - * @bitblocks: Returns the number of bitmap blocks - * - * Give a number of blocks in a RG, figure out the number of blocks - * needed for bitmaps. - * - */ - -static void -rgblocks2bitblocks(unsigned int bsize, - uint32_t *rgblocks, - uint32_t *bitblocks) -{ - unsigned int bitbytes_provided, last = 0; - unsigned int bitbytes_needed; - - *bitblocks = 1; - bitbytes_provided = bsize - sizeof(struct gfs_rgrp); - - for (;;) { - bitbytes_needed = (*rgblocks - *bitblocks) / GFS_NBBY; - - if (bitbytes_provided >= bitbytes_needed) { - if (last >= bitbytes_needed) - (*bitblocks)--; - break; - } - - last = bitbytes_provided; - (*bitblocks)++; - bitbytes_provided += bsize - sizeof(struct gfs_meta_header); - } - - *rgblocks = bitbytes_needed * GFS_NBBY; -} - - -/** - * write_sb - write the superblock - * @comline: the command line - * @rlist: the list of RGs - * - */ - -void write_sb(commandline_t *comline, osi_list_t *rlist) -{ - struct gfs_sb *sb; - uint64 jindex_dinode; - char buf[comline->bsize]; - int x; - - - memset(buf, 0, comline->bsize); - - for (x = 0; x < comline->sb_addr; x++) - { - do_lseek(comline->fd, x * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - } - - - /* Figure out the location of the journal index inode */ - - { - rgrp_list_t *rl = osi_list_entry(rlist->next, rgrp_list_t, list); - uint32_t rgblocks, bitblocks; - - rgblocks = rl->rg_length; - rgblocks2bitblocks(comline->bsize, &rgblocks, &bitblocks); - - jindex_dinode = rl->rg_offset + bitblocks; - } - - - /* Now, fill in the superblock */ - - type_zalloc(sb, struct gfs_sb, 1); - comline->sb = sb; - - - sb->sb_header.mh_magic = GFS_MAGIC; - sb->sb_header.mh_type = GFS_METATYPE_SB; - sb->sb_header.mh_format = GFS_FORMAT_SB; - - sb->sb_fs_format = GFS_FORMAT_FS; - sb->sb_multihost_format = GFS_FORMAT_MULTI; - - sb->sb_bsize = comline->bsize; - sb->sb_bsize_shift = ffs(comline->bsize) - 1; - sb->sb_seg_size = comline->seg_size; - - sb->sb_jindex_di.no_formal_ino = jindex_dinode; - sb->sb_jindex_di.no_addr = jindex_dinode; - sb->sb_rindex_di.no_formal_ino = jindex_dinode + 1; - sb->sb_rindex_di.no_addr = jindex_dinode + 1; - sb->sb_root_di.no_formal_ino = jindex_dinode + 4; - sb->sb_root_di.no_addr = jindex_dinode + 4; - - strcpy(sb->sb_lockproto, comline->lockproto); - strcpy(sb->sb_locktable, comline->locktable); - - sb->sb_quota_di.no_formal_ino = jindex_dinode + 2; - sb->sb_quota_di.no_addr = jindex_dinode + 2; - sb->sb_license_di.no_formal_ino = jindex_dinode + 3; - sb->sb_license_di.no_addr = jindex_dinode + 3; - - - gfs_sb_out(sb, buf); - - - do_lseek(comline->fd, comline->sb_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - - if (comline->debug) - { - printf("\nSuperblock:\n"); - gfs_sb_print(sb); - } -} - - -/** - * compute_height - give a file length and block size compute the file's height - * @sz: the file size - * @bsize: the blocksize - * - * Returns: the file height - */ - -static unsigned int compute_height(uint64 sz, unsigned int bsize) -{ - uint32 diptrs = (bsize - sizeof(struct gfs_dinode)) / sizeof(uint64); - uint32 inptrs = (bsize - sizeof(struct gfs_indirect)) / sizeof(uint64); - unsigned int height; - uint64 space, old_space; - - - bsize -= sizeof(struct gfs_meta_header); - - height = 1; - space = diptrs * bsize; - - - for (;;) - { - if (sz <= space) - break; - - old_space = space; - - height++; - space *= inptrs; - - if (space / inptrs != old_space || - space % inptrs != 0) - break; - } - - - return height; -} - - -/** - * build_tree - build the pointers and indirect blocks for a file - * @comline: the command line - * @di: the dinode - * @addr: the start of the file - * @blocks: the number of blocks in the file - * - */ - -static void build_tree(commandline_t *comline, struct gfs_dinode *di, uint64 addr, unsigned int blocks) -{ - struct gfs_indirect ind; - char *buf; - unsigned int x, offset; - unsigned int height; - unsigned int indblocks; - uint64 tmp_addr; - unsigned int tmp_blocks; - - - di->di_height = compute_height(di->di_size, comline->bsize); - - - if (di->di_height == 1) - { - type_zalloc(buf, char, comline->bsize); - - for (x = 0; x < blocks; x++) - ((uint64 *)(buf + sizeof(struct gfs_dinode)))[x] = cpu_to_gfs64(addr + x); - - gfs_dinode_out(di, buf); - - do_lseek(comline->fd, di->di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - free(buf); - } - else - { - tmp_addr = addr; - tmp_blocks = blocks; - - - for (height = di->di_height; height > 1; height--) - { - memset(&ind, 0, sizeof(struct gfs_indirect)); - ind.in_header.mh_magic = GFS_MAGIC; - ind.in_header.mh_type = GFS_METATYPE_IN; - ind.in_header.mh_format = GFS_FORMAT_IN; - - - indblocks = DIV_RU((tmp_blocks * sizeof(uint64)), - (comline->bsize - sizeof(struct gfs_indirect))); - - type_zalloc(buf, char, indblocks * comline->bsize); - - - offset = 0; - for (x = 0; x < tmp_blocks; x++) - { - if (!(offset % comline->bsize)) - { - gfs_indirect_out(&ind, buf + offset); - offset += sizeof(struct gfs_indirect); - } - - *((uint64 *)(buf + offset)) = cpu_to_gfs64(tmp_addr + x); - offset += sizeof(uint64); - } - - - do_lseek(comline->fd, comline->rgrp0_next * comline->bsize); - do_write(comline->fd, buf, indblocks * comline->bsize); - - free(buf); - - tmp_addr = comline->rgrp0_next; - tmp_blocks = indblocks; - - di->di_blocks += indblocks; - - comline->rgrp0_next += indblocks; - } - - - type_zalloc(buf, char, comline->bsize); - - for (x = 0; x < tmp_blocks; x++) - ((uint64 *)(buf + sizeof(struct gfs_dinode)))[x] = cpu_to_gfs64(tmp_addr + x); - - gfs_dinode_out(di, buf); - - do_lseek(comline->fd, di->di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - free(buf); - } -} - - -/** - * fill_jindex - create the journal index data - * @comline: the command line - * @jlist: the list of journals - * - * Returns: a pointer data for the jindex - */ - -static char *fill_jindex(commandline_t *comline, osi_list_t *jlist) -{ - journal_list_t *jl; - struct gfs_jindex ji; - osi_list_t *tmp; - char *buf; - unsigned int j = 0; - - - type_alloc(buf, char, comline->journals * sizeof(struct gfs_jindex)); - - - for (tmp = jlist->next; tmp != jlist; tmp = tmp->next) - { - jl = osi_list_entry(tmp, journal_list_t, list); - - memset(&ji, 0, sizeof(struct gfs_jindex)); - - ji.ji_addr = jl->start; - ji.ji_nsegment = jl->segments; - - gfs_jindex_out(&ji, buf + j * sizeof(struct gfs_jindex)); - - j++; - } - - - if (comline->debug) - { - printf("\nJournal Index data:\n"); - - for (j = 0; j < comline->journals; j++) - { - gfs_jindex_in(&ji, buf + j * sizeof(struct gfs_jindex)); - - printf("\n Journal %d\n", j); - gfs_jindex_print(&ji); - } - } - - - return buf; -} - - -/** - * write_jindex - write out the journal index - * @comline: the command line - * @jlist: the list of journals - * - */ - -void write_jindex(commandline_t *comline, osi_list_t *jlist) -{ - struct gfs_dinode di; - struct gfs_meta_header jd; - char *buf, *data; - uint64 addr; - unsigned int blocks; - unsigned int x, left, jbsize = comline->bsize - sizeof(struct gfs_meta_header); - - - memset(&di, 0, sizeof(struct gfs_dinode)); - - di.di_header.mh_magic = GFS_MAGIC; - di.di_header.mh_type = GFS_METATYPE_DI; - di.di_header.mh_format = GFS_FORMAT_DI; - - di.di_num = comline->sb->sb_jindex_di; - - di.di_mode = MKFS_HIDDEN_MODE; - di.di_nlink = 1; - di.di_size = comline->journals * sizeof(struct gfs_jindex); - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = time(NULL); - - di.di_flags = GFS_DIF_JDATA; - di.di_payload_format = GFS_FORMAT_JI; - di.di_type = GFS_FILE_REG; - - - data = fill_jindex(comline, jlist); - - - if (di.di_size < comline->bsize - sizeof(struct gfs_dinode)) - { - type_zalloc(buf, char, comline->bsize); - - gfs_dinode_out(&di, buf); - - memcpy(buf + sizeof(struct gfs_dinode), data, comline->journals * sizeof(struct gfs_jindex)); - - do_lseek(comline->fd, di.di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - free(buf); - } - else - { - blocks = DIV_RU(di.di_size, (comline->bsize - sizeof(struct gfs_meta_header))); - di.di_blocks += blocks; - - addr = comline->rgrp0_next; - - - memset(&jd, 0, sizeof(struct gfs_meta_header)); - jd.mh_magic = GFS_MAGIC; - jd.mh_type = GFS_METATYPE_JD; - jd.mh_format = GFS_FORMAT_JD; - - - type_zalloc(buf, char, blocks * comline->bsize); - - left = comline->journals * sizeof(struct gfs_jindex); - for (x = 0; x < blocks; x++) - { - gfs_meta_header_out(&jd, buf + x * comline->bsize); - memcpy(buf + x * comline->bsize + sizeof(struct gfs_meta_header), - data + x * jbsize, - (left > jbsize) ? jbsize : left); - left -= jbsize; - } - - - do_lseek(comline->fd, addr * comline->bsize); - do_write(comline->fd, buf, blocks * comline->bsize); - - free(buf); - - - comline->rgrp0_next += blocks; - - build_tree(comline, &di, addr, blocks); - } - - - free(data); - - - if (comline->debug) - { - printf("\nJournal index dinode:\n"); - gfs_dinode_print(&di); - } -} - - -/** - * fill_rindex - create the resource group index data - * @comline: the command line - * @rlist: the list of RGs - * - * Returns: a pointer data for the rindex - */ - -static char *fill_rindex(commandline_t *comline, osi_list_t *rlist) -{ - struct gfs_rindex *ri, rindex; - rgrp_list_t *rl; - osi_list_t *tmp; - char *buf; - unsigned int r = 0; - uint32 rgblocks, bitblocks; - - - type_alloc(buf, char, comline->rgrps * sizeof(struct gfs_rindex)); - - - for (tmp = rlist->next; tmp != rlist; tmp = tmp->next) - { - rl = osi_list_entry(tmp, rgrp_list_t, list); - - rgblocks = rl->rg_length; - rgblocks2bitblocks(comline->bsize, &rgblocks, &bitblocks); - - type_zalloc(ri, struct gfs_rindex, 1); - rl->ri = ri; - - ri->ri_addr = rl->rg_offset; - ri->ri_length = bitblocks; - - ri->ri_data1 = rl->rg_offset + bitblocks; - ri->ri_data = rgblocks; - - ri->ri_bitbytes = rgblocks / GFS_NBBY; - - gfs_rindex_out(ri, buf + r * sizeof(struct gfs_rindex)); - - comline->fssize += rgblocks; - - r++; - } - - - if (comline->debug) - { - printf("\nResource Index data:\n"); - - for (r = 0; r < comline->rgrps; r++) - { - gfs_rindex_in(&rindex, buf + r * sizeof(struct gfs_rindex)); - - printf("\n Resource index %d\n", r); - gfs_rindex_print(&rindex); - } - } - - - return buf; -} - - -/** - * write_rindex - write out the resource group index - * @comline: the command line - * @jlist: the list of RGs - * - */ - -void write_rindex(commandline_t *comline, osi_list_t *rlist) -{ - struct gfs_dinode di; - struct gfs_meta_header jd; - char *buf, *data; - uint64 addr; - unsigned int blocks; - unsigned int x, left, jbsize = comline->bsize - sizeof(struct gfs_meta_header); - - - memset(&di, 0, sizeof(struct gfs_dinode)); - - di.di_header.mh_magic = GFS_MAGIC; - di.di_header.mh_type = GFS_METATYPE_DI; - di.di_header.mh_format = GFS_FORMAT_DI; - - di.di_num = comline->sb->sb_rindex_di; - - di.di_mode = MKFS_HIDDEN_MODE; - di.di_nlink = 1; - di.di_size = comline->rgrps * sizeof(struct gfs_rindex); - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = time(NULL); - - di.di_flags = GFS_DIF_JDATA; - di.di_payload_format = GFS_FORMAT_RI; - di.di_type = GFS_FILE_REG; - - - data = fill_rindex(comline, rlist); - - - if (di.di_size < comline->bsize - sizeof(struct gfs_dinode)) - { - type_zalloc(buf, char, comline->bsize); - - gfs_dinode_out(&di, buf); - - memcpy(buf + sizeof(struct gfs_dinode), data, comline->rgrps * sizeof(struct gfs_rindex)); - - do_lseek(comline->fd, di.di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - free(buf); - } - else - { - blocks = DIV_RU(di.di_size, (comline->bsize - sizeof(struct gfs_meta_header))); - di.di_blocks += blocks; - - addr = comline->rgrp0_next; - - - memset(&jd, 0, sizeof(struct gfs_meta_header)); - jd.mh_magic = GFS_MAGIC; - jd.mh_type = GFS_METATYPE_JD; - jd.mh_format = GFS_FORMAT_JD; - - - type_zalloc(buf, char, blocks * comline->bsize); - - left = comline->rgrps * sizeof(struct gfs_rindex); - for (x = 0; x < blocks; x++) - { - gfs_meta_header_out(&jd, buf + x * comline->bsize); - memcpy(buf + x * comline->bsize + sizeof(struct gfs_meta_header), - data + x * jbsize, - (left > jbsize) ? jbsize : left); - left -= jbsize; - } - - - do_lseek(comline->fd, addr * comline->bsize); - do_write(comline->fd, buf, blocks * comline->bsize); - - free(buf); - - - comline->rgrp0_next += blocks; - - build_tree(comline, &di, addr, blocks); - } - - - free(data); - - - if (comline->debug) - { - printf("\nResource index dinode:\n"); - gfs_dinode_print(&di); - } -} - - -/** - * write_root - write out the root dinode - * @comline: the command line - * - */ - -void write_root(commandline_t *comline) -{ - struct gfs_dinode di; - struct gfs_dirent de; - - char buf[comline->bsize]; - - - memset(&di, 0, sizeof(struct gfs_dinode)); - memset(buf, 0, comline->bsize); - - - di.di_header.mh_magic = GFS_MAGIC; - di.di_header.mh_type = GFS_METATYPE_DI; - di.di_header.mh_format = GFS_FORMAT_DI; - - di.di_num = comline->sb->sb_root_di; - - di.di_mode = MKFS_ROOT_MODE; - di.di_nlink = 2; - di.di_size = comline->bsize - sizeof(struct gfs_dinode); - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = time(NULL); - - di.di_flags = GFS_DIF_JDATA; - di.di_payload_format = GFS_FORMAT_DE; - di.di_type = GFS_FILE_DIR; - - di.di_entries = 2; - - gfs_dinode_out(&di, buf); - - - /* Fill in . */ - - memset(&de, 0, sizeof(struct gfs_dirent)); - - de.de_inum = comline->sb->sb_root_di; - de.de_hash = gfs_dir_hash(".", 1); - de.de_rec_len = GFS_DIRENT_SIZE(1); - de.de_name_len = 1; - de.de_type = GFS_FILE_DIR; - - gfs_dirent_out(&de, buf + sizeof(struct gfs_dinode)); - memcpy(buf + sizeof(struct gfs_dinode) + sizeof(struct gfs_dirent), ".", 1); - - if (comline->debug) - { - printf("\nRoot Dinode dirent:\n"); - gfs_dirent_print(&de, "."); - } - - - /* Fill in .. */ - - memset(&de, 0, sizeof(struct gfs_dirent)); - - de.de_inum = comline->sb->sb_root_di; - de.de_hash = gfs_dir_hash("..", 2); - de.de_rec_len = comline->bsize - GFS_DIRENT_SIZE(1) - sizeof(struct gfs_dinode); - de.de_name_len = 2; - de.de_type = GFS_FILE_DIR; - - gfs_dirent_out(&de, buf + sizeof(struct gfs_dinode) + GFS_DIRENT_SIZE(1)); - memcpy(buf + sizeof(struct gfs_dinode) + GFS_DIRENT_SIZE(1) + sizeof(struct gfs_dirent), "..", 2); - - if (comline->debug) - { - printf("\nRoot Dinode dirent:\n"); - gfs_dirent_print(&de, ".."); - } - - - do_lseek(comline->fd, di.di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - - if (comline->debug) - { - printf("\nRoot dinode:\n"); - gfs_dinode_print(&di); - } -} - - -/** - * write_quota - write out the quota dinode - * @comline: the command line - * - */ - -void write_quota(commandline_t *comline) -{ - struct gfs_dinode di; - struct gfs_quota qu; - - char buf[comline->bsize]; - - - memset(&di, 0, sizeof(struct gfs_dinode)); - memset(buf, 0, comline->bsize); - - - di.di_header.mh_magic = GFS_MAGIC; - di.di_header.mh_type = GFS_METATYPE_DI; - di.di_header.mh_format = GFS_FORMAT_DI; - - di.di_num = comline->sb->sb_quota_di; - - di.di_mode = MKFS_HIDDEN_MODE; - di.di_nlink = 1; - di.di_size = 2 * sizeof(struct gfs_quota); - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = time(NULL); - - di.di_flags = GFS_DIF_JDATA; - di.di_payload_format = GFS_FORMAT_QU; - di.di_type = GFS_FILE_REG; - - gfs_dinode_out(&di, buf); - - - /* Fill in the root user quota */ - - memset(&qu, 0, sizeof(struct gfs_quota)); - qu.qu_value = comline->rgrp0_next - comline->sb->sb_jindex_di.no_addr; - - gfs_quota_out(&qu, buf + sizeof(struct gfs_dinode)); - - if (comline->debug) - { - printf("\nRoot user quota:\n"); - gfs_quota_print(&qu); - } - - - /* Fill in the root group quota */ - - memset(&qu, 0, sizeof(struct gfs_quota)); - qu.qu_value = comline->rgrp0_next - comline->sb->sb_jindex_di.no_addr; - - gfs_quota_out(&qu, buf + sizeof(struct gfs_dinode) + sizeof(struct gfs_quota)); - - if (comline->debug) - { - printf("\nRoot group quota:\n"); - gfs_quota_print(&qu); - } - - - do_lseek(comline->fd, di.di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - - if (comline->debug) - { - printf("\nQuota dinode:\n"); - gfs_dinode_print(&di); - } -} - - -/** - * write_license - write out the quota dinode - * @comline: the command line - * - */ - -void write_license(commandline_t *comline) -{ - struct gfs_dinode di; - - char buf[comline->bsize]; - - - memset(&di, 0, sizeof(struct gfs_dinode)); - memset(buf, 0, comline->bsize); - - - di.di_header.mh_magic = GFS_MAGIC; - di.di_header.mh_type = GFS_METATYPE_DI; - di.di_header.mh_format = GFS_FORMAT_DI; - - di.di_num = comline->sb->sb_license_di; - - di.di_mode = MKFS_HIDDEN_MODE; - di.di_nlink = 1; - di.di_size = 0; - di.di_blocks = 1; - di.di_atime = di.di_mtime = di.di_ctime = time(NULL); - - di.di_flags = GFS_DIF_JDATA; - di.di_payload_format = GFS_FORMAT_QU; - di.di_type = GFS_FILE_REG; - - gfs_dinode_out(&di, buf); - - - do_lseek(comline->fd, di.di_num.no_addr * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - - if (comline->debug) - { - printf("\nLicense dinode:\n"); - gfs_dinode_print(&di); - } -} - - -/** - * write_rgrps - write out the resource group headers - * @comline: the command line - * @rlist: the RG list - * - */ - -void write_rgrps(commandline_t *comline, osi_list_t *rlist) -{ - struct gfs_rgrp rg; - struct gfs_meta_header rb; - rgrp_list_t *rl; - osi_list_t *tmp; - char *buf, *data; - unsigned int x, offset; - unsigned int byte, bit; - unsigned int blk_count; - unsigned int r = 0; - - - memset(&rb, 0, sizeof(struct gfs_meta_header)); - rb.mh_magic = GFS_MAGIC; - rb.mh_type = GFS_METATYPE_RB; - rb.mh_format = GFS_FORMAT_RB; - - - for (tmp = rlist->next; tmp != rlist; tmp = tmp->next) - { - rl = osi_list_entry(tmp, rgrp_list_t, list); - - memset(&rg, 0, sizeof(struct gfs_rgrp)); - rg.rg_header.mh_magic = GFS_MAGIC; - rg.rg_header.mh_type = GFS_METATYPE_RG; - rg.rg_header.mh_format = GFS_FORMAT_RG; - rg.rg_free = rl->ri->ri_data; - - type_zalloc(data, char, rl->ri->ri_bitbytes); - type_zalloc(buf, char, rl->ri->ri_length * comline->bsize); - - - /* Deal with the special case of the first dinode */ - - if (!r) - { - if (comline->rgrp0_next > rl->ri->ri_data1 + rl->ri->ri_data) - die("RG 0 is full.\n"); - - /* Compensate for the hidden dinodes */ - - *data = (GFS_BLKST_USEDMETA << 3 * GFS_BIT_SIZE) | - (GFS_BLKST_USEDMETA << 2 * GFS_BIT_SIZE) | - (GFS_BLKST_USEDMETA << GFS_BIT_SIZE) | - GFS_BLKST_USEDMETA; - *(data + 1) = GFS_BLKST_USEDMETA; - rg.rg_free -= 5; - rg.rg_useddi = 5; - - /* Compensate for the data the hidden dinodes point to */ - - for (x = rl->ri->ri_data1 + 5; x < comline->rgrp0_next; x++) - { - byte = (x - rl->ri->ri_data1) / GFS_NBBY; - bit = (x - rl->ri->ri_data1) % GFS_NBBY; - - data[byte] |= GFS_BLKST_USEDMETA << (bit * GFS_BIT_SIZE); - - rg.rg_free--; - rg.rg_usedmeta++; - } - } - - - gfs_rgrp_out(&rg, buf); - offset = sizeof(struct gfs_rgrp); - blk_count = 1; - - for (x = 0; x < rl->ri->ri_bitbytes; x++) - { - if (!(offset % comline->bsize)) - { - gfs_meta_header_out(&rb, buf + offset); - offset += sizeof(struct gfs_meta_header); - blk_count++; - } - - buf[offset] = data[x]; - offset++; - } - - if (blk_count != rl->ri->ri_length) - die("RG underflow (rg = %u, blk_count = %u, rl->ri->ri_length = %u)\n", - r, blk_count, rl->ri->ri_length); - - - do_lseek(comline->fd, rl->ri->ri_addr * comline->bsize); - do_write(comline->fd, buf, rl->ri->ri_length * comline->bsize); - - - free(buf); - free(data); - - - if (comline->debug) - { - printf("\nResource group header %d\n", r); - gfs_rgrp_print(&rg); - } - - r++; - } -} - - -/** - * write_journals - write out the journal log headers - * @comline: the command line - * @rlist: the RG list - * - */ - -void write_journals(commandline_t *comline, osi_list_t *jlist) -{ - struct gfs_log_header lh; - journal_list_t *jl; - osi_list_t *tmp; - char buf[comline->bsize]; - uint32 seg, sequence; - int x = 0; - - - srandom(time(NULL)); - - - for (tmp = jlist->next; tmp != jlist; tmp = tmp->next) - { - jl = osi_list_entry(tmp, journal_list_t, list); - - if (comline->debug) - printf("Starting journal %d\n", x++); - - sequence = jl->segments / (RAND_MAX + 1.0) * random(); - - for (seg = 0; seg < jl->segments; seg++) - { - memset(buf, 0, comline->bsize); - memset(&lh, 0, sizeof(struct gfs_log_header)); - - lh.lh_header.mh_magic = GFS_MAGIC; - lh.lh_header.mh_type = GFS_METATYPE_LH; - lh.lh_header.mh_format = GFS_FORMAT_LH; - lh.lh_flags = GFS_LOG_HEAD_UNMOUNT; - lh.lh_first = jl->start + seg * comline->seg_size; - lh.lh_sequence = sequence; - /* Don't care about tail */ - /* Don't care about log dump */ - - gfs_log_header_out(&lh, buf); - gfs_log_header_out(&lh, buf + GFS_BASIC_BLOCK - sizeof(struct gfs_log_header)); - - do_lseek(comline->fd, lh.lh_first * comline->bsize); - do_write(comline->fd, buf, comline->bsize); - - if (++sequence == jl->segments) - sequence = 0; - - if (!(seg % 100)) - if (comline->debug) - printf("seg #%u\n", seg); - - } - } -} - - diff --git a/gfs/gfs_quota/Makefile b/gfs/gfs_quota/Makefile deleted file mode 100644 index b95b0f9..0000000 --- a/gfs/gfs_quota/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -TARGET= gfs_quota - -SOURCE= \ - check.c \ - main.c \ - names.c \ - ondisk.c \ - layout.c - -CFLAGS+= -O2 -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -all: ${TARGET} - -gfs_quota: ${SOURCE} - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} - - diff --git a/gfs/gfs_quota/check.c b/gfs/gfs_quota/check.c deleted file mode 100644 index 3f72f94..0000000 --- a/gfs/gfs_quota/check.c +++ /dev/null @@ -1,646 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <time.h> -#include <dirent.h> -#include <limits.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> -#define __user -#include <linux/gfs_ioctl.h> -#include "osi_list.h" - -#include "gfs_quota.h" - -struct values { - osi_list_t v_list; - - uint32_t v_id; - int64_t v_blocks; -}; -typedef struct values values_t; - -struct hardlinks { - osi_list_t hl_list; - - ino_t hl_ino; -}; -typedef struct hardlinks hardlinks_t; - -/** - * add_value - add a ID / Allocated Blocks pair to the list - * @list: the list - * @id: the ID number - * @blocks: the number of blocks to add - * - */ - -static void -add_value(osi_list_t *list, uint32_t id, int64_t blocks) -{ - osi_list_t *tmp; - values_t *v; - - for (tmp = list->next; tmp != list; tmp = tmp->next) { - v = osi_list_entry(tmp, values_t, v_list); - if (v->v_id != id) - continue; - - v->v_blocks += blocks; - - osi_list_del(&v->v_list); - osi_list_add(&v->v_list, list); - - return; - } - - type_zalloc(v, values_t, 1); - - v->v_id = id; - v->v_blocks = blocks; - - osi_list_add(&v->v_list, list); -} - -/** - * test_and_add_hard_link - Add a inode that has hard links to the list - * @list: the list of inodes with hard links - * @ino: the number of the inode to add - * - * Returns: Returns TRUE if the inode was already on the list, FALSE if it wasn't - */ - -static int -test_and_add_hard_link(osi_list_t *list, ino_t ino) -{ - osi_list_t *tmp; - hardlinks_t *hl; - - for (tmp = list->next; tmp != list; tmp = tmp->next) { - hl = osi_list_entry(tmp, hardlinks_t, hl_list); - if (hl->hl_ino != ino) - continue; - - return TRUE; - } - - type_zalloc(hl, hardlinks_t, 1); - - hl->hl_ino = ino; - - osi_list_add(&hl->hl_list, list); - - return FALSE; -} - -/** - * scan_fs - recursively scan a filesystem and figure out what IDs have what - * @device: the device the filesystem is on - * @dirname: the name of the directory to read - * @uid: returned list of UIDs for this FS - * @gid: returned list of GIDs for this FS - * @hl: returned list of hard links for this FS - * - */ - -static void -scan_fs(dev_t device, char *dirname, - osi_list_t *uid, osi_list_t *gid, osi_list_t *hl) -{ - DIR *dir; - struct dirent *de; - struct stat st; - char *name; - int error; - - dir = opendir(dirname); - if (!dir) - die("can't open directory %s: %s\n", dirname, strerror(errno)); - - while ((de = readdir(dir))) { - if (strcmp(de->d_name, "..") == 0) - continue; - - type_alloc(name, char, - strlen(dirname) + strlen(de->d_name) + 2); - if (dirname[strlen(dirname) - 1] == '/') - sprintf(name, "%s%s", dirname, de->d_name); - else - sprintf(name, "%s/%s", dirname, de->d_name); - - error = lstat(name, &st); - if (error) - die("can't stat file %s: %s\n", name, strerror(errno)); - - if (st.st_dev != device) - die("umount %s and try again\n", name); - - if (S_ISDIR(st.st_mode)) { - if (strcmp(de->d_name, ".") == 0) { - add_value(uid, st.st_uid, st.st_blocks); - add_value(gid, st.st_gid, st.st_blocks); - } else - scan_fs(device, name, uid, gid, hl); - } else if (st.st_nlink == 1 || - !test_and_add_hard_link(hl, st.st_ino)) { - add_value(uid, st.st_uid, st.st_blocks); - add_value(gid, st.st_gid, st.st_blocks); - } - - free(name); - } - - closedir(dir); -} - -/** - * read_quota_file - read the quota file and return list of its contents - * @comline: the command line arguments - * @uid: returned list of UIDs for the filesystem - * @gid: returned list of GIDs for the filesystem - * - */ - -static void -read_quota_file(commandline_t *comline, osi_list_t *uid, osi_list_t *gid) -{ - int fd; - struct gfs_sb sb; - uint64_t hidden_blocks; - struct gfs_ioctl gi; - char buf[sizeof(struct gfs_quota)]; - struct gfs_quota q; - uint64_t offset = 0; - uint32_t id; - int error; - - fd = open(comline->filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", comline->filesystem, - strerror(errno)); - - check_for_gfs(fd, comline->filesystem); - - do_get_super(fd, &sb); - - hidden_blocks = compute_hidden_blocks(comline, fd); - - do { - char *argv[] = { "do_hfile_read", "quota" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = sizeof(struct gfs_quota); - gi.gi_offset = offset; - - memset(buf, 0, sizeof(struct gfs_quota)); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("can't read quota file (%d): %s\n", - error, strerror(errno)); - - gfs_quota_in(&q, buf); - - id = (offset / sizeof(struct gfs_quota)) >> 1; - if (!id) - q.qu_value -= hidden_blocks; - q.qu_value <<= sb.sb_bsize_shift - 9; - - if (q.qu_value) { - if (id * sizeof(struct gfs_quota) * 2 == offset) - add_value(uid, id, q.qu_value); - else - add_value(gid, id, q.qu_value); - } - - offset += sizeof(struct gfs_quota); - } while (error == sizeof(struct gfs_quota)); - - close(fd); -} - -/** - * print_list - print the contents of an ID list - * @str: a string describing the list - * @list: the list - * - */ - -static void -print_list(char *str, osi_list_t *list) -{ -#if 0 - osi_list_t *tmp; - values_t *v; - - for (tmp = list->next; tmp != list; tmp = tmp->next) { - v = osi_list_entry(tmp, values_t, v_list); - printf("%s %10u: %"PRId64"\n", str, v->v_id, v->v_blocks); - } -#endif -} - -/** - * do_compare - compare to ID lists and see if they match - * @type: the type of list (UID or GID) - * @fs_list: the list derived from scaning the FS - * @qf_list: the list derived from reading the quota file - * - * Returns: TRUE if there was a mismatch - */ - -static int -do_compare(char *type, osi_list_t *fs_list, osi_list_t *qf_list) -{ - osi_list_t *tmp1, *tmp2; - values_t *v1, *v2; - int found; - int mismatch = FALSE; - - for (tmp1 = fs_list->next; tmp1 != fs_list; tmp1 = tmp1->next) { - v1 = osi_list_entry(tmp1, values_t, v_list); - - found = FALSE; - - for (tmp2 = qf_list->next; tmp2 != qf_list; tmp2 = tmp2->next) { - v2 = osi_list_entry(tmp2, values_t, v_list); - if (v1->v_id != v2->v_id) - continue; - - if (v1->v_blocks != v2->v_blocks) { - printf("mismatch: %s %u: scan = %"PRId64", quotafile = %"PRId64"\n", - type, v1->v_id, - v1->v_blocks, v2->v_blocks); - mismatch = TRUE; - } - - osi_list_del(&v2->v_list); - free(v2); - - found = TRUE; - break; - } - - if (!found) { - printf("mismatch: %s %u: scan = %"PRId64", quotafile = %"PRId64"\n", - type, v1->v_id, - v1->v_blocks, (int64_t)0); - mismatch = TRUE; - } - } - - for (tmp2 = qf_list->next; tmp2 != qf_list; tmp2 = tmp2->next) { - v2 = osi_list_entry(tmp2, values_t, v_list); - - printf("mismatch: %s %u: scan = %"PRId64", quotafile = %"PRId64"\n", - type, v2->v_id, - (int64_t)0, v2->v_blocks); - mismatch = TRUE; - } - - return mismatch; -} - -/** - * verify_pathname - make sure the path on the command line is a mount point - * @comline: the command line arguments - * - * Returns: the device the filesystem is on - */ - -static dev_t -verify_pathname(commandline_t *comline) -{ - struct stat st1, st2; - dev_t device; - char *name; - int error; - - if (!*comline->filesystem) - die("need a filesystem to work on\n"); - - error = lstat(comline->filesystem, &st1); - if (error) - die("can't stat %s: %s\n", comline->filesystem, - strerror(errno)); - - if (!S_ISDIR(st1.st_mode)) - die("%s must be a directory\n", comline->filesystem); - - device = st1.st_dev; - - for (;;) { - type_alloc(name, char, strlen(comline->filesystem) + 4); - sprintf(name, "%s/..", comline->filesystem); - - error = lstat(name, &st2); - if (error) - die("can't stat %s: %s\n", name, strerror(errno)); - - if (st2.st_dev != device || st2.st_ino == st1.st_ino) { - free(name); - break; - } - - if (!realpath(name, comline->filesystem)) - die("error resolving filesystem pathname: %s\n", - strerror(errno)); - - free(name); - - st1 = st2; - } - - return device; -} - -/** - * do_check - Check what's in the quota file - * @comline: the struct containing the parsed command line arguments - * - */ - -void -do_check(commandline_t *comline) -{ - dev_t device; - osi_list_t fs_uid, fs_gid, qf_uid, qf_gid; - osi_list_t hl; - int mismatch; - - osi_list_init(&fs_uid); - osi_list_init(&fs_gid); - osi_list_init(&qf_uid); - osi_list_init(&qf_gid); - osi_list_init(&hl); - - device = verify_pathname(comline); - - scan_fs(device, comline->filesystem, &fs_uid, &fs_gid, &hl); - read_quota_file(comline, &qf_uid, &qf_gid); - - print_list("fs user ", &fs_uid); - print_list("fs group", &fs_gid); - print_list("qf user ", &qf_uid); - print_list("qf group", &qf_gid); - - mismatch = do_compare("user", &fs_uid, &qf_uid); - mismatch |= do_compare("group", &fs_gid, &qf_gid); - - if (mismatch) - exit(EXIT_FAILURE); -} - -/** - * set_list - write a list of IDs into the quota file - * @comline: the command line arguments - * @user: TRUE if this is a list of UIDs, FALSE if it is a list of GIDs - * @list: the list of IDs and block counts - * @multiplier: multiply block counts by this - * - */ - -static void -set_list(commandline_t *comline, int user, osi_list_t *list, int64_t multiplier) -{ - int fd; - struct gfs_sb sb; - osi_list_t *tmp; - values_t *v; - uint64_t offset; - int64_t value; - struct gfs_ioctl gi; - char buf[256]; - int error; - - fd = open(comline->filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", comline->filesystem, - strerror(errno)); - - check_for_gfs(fd, comline->filesystem); - do_get_super(fd, &sb); - - for (tmp = list->next; tmp != list; tmp = tmp->next) { - v = osi_list_entry(tmp, values_t, v_list); - - offset = (2 * (uint64_t)v->v_id + ((user) ? 0 : 1)) * - sizeof(struct gfs_quota); - offset += (unsigned long)(&((struct gfs_quota *)NULL)->qu_value); - - value = v->v_blocks * multiplier; - value >>= sb.sb_bsize_shift - 9; - value = cpu_to_gfs64(value); - - { - char *argv[] = { "do_hfile_write", "quota"}; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&value; - gi.gi_size = sizeof(int64_t); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != sizeof(int64_t)) - die("can't write quota file (%d): %s\n", - error, strerror(errno)); - } - - sprintf(buf, "%s:%u", - (user) ? "u" : "g", - v->v_id); - - { - char *argv[] = { "do_quota_refresh", buf }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error) - die("can't refresh the quota LVB 1: %s\n", - strerror(errno)); - } - } - - close(fd); -} - -/** - * add_hidden - add in the hidden file block count into the root UID and GID - * @comline: the command line arguments - * - */ - -static void -add_hidden(commandline_t *comline) -{ - int fd; - uint64_t hidden_blocks; - uint64_t offset = (unsigned long)(&((struct gfs_quota *)NULL)->qu_value); - struct gfs_ioctl gi; - int64_t value; - unsigned int pass = 0; - char buf[256]; - int error; - - fd = open(comline->filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", comline->filesystem, - strerror(errno)); - - check_for_gfs(fd, comline->filesystem); - - hidden_blocks = compute_hidden_blocks(comline, fd); - - for (;;) { - { - char *argv[] = { "do_hfile_read", "quota" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&value; - gi.gi_size = sizeof(int64_t); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != sizeof(int64_t)) - die("can't read quota file (%d): %s\n", - error, strerror(errno)); - } - - value = gfs64_to_cpu(value); - value += hidden_blocks; - value = cpu_to_gfs64(value); - - { - char *argv[] = { "do_hfile_write", "quota" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&value; - gi.gi_size = sizeof(int64_t); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != sizeof(int64_t)) - die("can't write quota file (%d): %s\n", - error, strerror(errno)); - } - - sprintf(buf, "%s:%u", - (pass) ? "g" : "u", - 0); - - { - char *argv[] = { "do_quota_refresh", buf }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error) - die("can't refresh the quota LVB 2: %s\n", - strerror(errno)); - } - - if (!pass) { - offset += sizeof(struct gfs_quota); - pass = 1; - } else - break; - } - - close(fd); -} - -/** - * do_init - initialize the quota file - * @comline: the command line arguments - * - */ - -void -do_init(commandline_t *comline) -{ - dev_t device; - osi_list_t fs_uid, fs_gid, qf_uid, qf_gid; - osi_list_t hl; - values_t *v; - - osi_list_init(&fs_uid); - osi_list_init(&fs_gid); - osi_list_init(&qf_uid); - osi_list_init(&qf_gid); - osi_list_init(&hl); - - device = verify_pathname(comline); - - scan_fs(device, comline->filesystem, &fs_uid, &fs_gid, &hl); - read_quota_file(comline, &qf_uid, &qf_gid); - - type_zalloc(v, values_t, 1); - v->v_id = 0; - v->v_blocks = 0; - osi_list_add(&v->v_list, &qf_uid); - - type_zalloc(v, values_t, 1); - v->v_id = 0; - v->v_blocks = 0; - osi_list_add(&v->v_list, &qf_gid); - - print_list("fs user ", &fs_uid); - print_list("fs group", &fs_gid); - print_list("qf user ", &qf_uid); - print_list("qf group", &qf_gid); - - /* Yes, do the set_list() calls twice. Gotta get around - the fact that writing to the quota file causes - quota changes */ - - set_list(comline, TRUE, &qf_uid, 0); - set_list(comline, FALSE, &qf_gid, 0); - set_list(comline, TRUE, &fs_uid, 1); - set_list(comline, FALSE, &fs_gid, 1); - - do_sync(comline); - do_sync(comline); - - set_list(comline, TRUE, &qf_uid, 0); - set_list(comline, FALSE, &qf_gid, 0); - set_list(comline, TRUE, &fs_uid, 1); - set_list(comline, FALSE, &fs_gid, 1); - - do_sync(comline); - - add_hidden(comline); - - do_sync(comline); - - do_check(comline); -} diff --git a/gfs/gfs_quota/gfs_quota.h b/gfs/gfs_quota/gfs_quota.h deleted file mode 100644 index effdfb5..0000000 --- a/gfs/gfs_quota/gfs_quota.h +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFS_QUOTA_DOT_H__ -#define __GFS_QUOTA_DOT_H__ - - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#define die(fmt, args...) \ -do { \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} while (0) - -#define type_zalloc(ptr, type, count) \ -do { \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if ((ptr)) \ - memset((char *)(ptr), 0, sizeof(type) * (count)); \ - else \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} while (0) - -#define type_alloc(ptr, type, count) \ -do { \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if (!(ptr)) \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} while (0) - -#define GQ_OP_LIST (12) -#define GQ_OP_SYNC (13) -#define GQ_OP_GET (14) -#define GQ_OP_LIMIT (15) -#define GQ_OP_WARN (16) -#define GQ_OP_CHECK (17) -#define GQ_OP_INIT (18) - -#define GQ_ID_USER (23) -#define GQ_ID_GROUP (24) - -#define GQ_UNITS_MEGABYTE (0) -#define GQ_UNITS_KILOBYTE (34) -#define GQ_UNITS_FSBLOCK (35) -#define GQ_UNITS_BASICBLOCK (36) - -struct commandline { - unsigned int operation; - - uint64_t new_value; - int new_value_set; - - unsigned int id_type; - uint32_t id; - - unsigned int units; - - int no_hidden_file_blocks; - int numbers; - - char filesystem[PATH_MAX]; -}; -typedef struct commandline commandline_t; - -extern char *prog_name; - -/* main.c */ - -void check_for_gfs(int fd, char *path); -void do_get_super(int fd, struct gfs_sb *sb); -void do_sync(commandline_t *comline); -uint64_t compute_hidden_blocks(commandline_t *comline, int fd); - -/* check.c */ - -void do_check(commandline_t *comline); -void do_init(commandline_t *comline); - -/* names.c */ - -uint32_t name_to_id(int user, char *name, int numbers); -char *id_to_name(int user, uint32_t id, int numbers); - -/* layout.c */ - -void print_quota_file(commandline_t *comline); -#endif /* __GFS_QUOTA_DOT_H__ */ diff --git a/gfs/gfs_quota/layout.c b/gfs/gfs_quota/layout.c deleted file mode 100644 index be0e67a..0000000 --- a/gfs/gfs_quota/layout.c +++ /dev/null @@ -1,613 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#define __user -#include <linux/gfs_ioctl.h> -#include <linux/gfs_ondisk.h> - -#include "osi_list.h" -#include "linux_endian.h" - -#include "gfs_quota.h" - -#define LAYOUT_DATA_QUANTUM (4194304) - -extern void -print_quota(commandline_t *comline, - int user, uint32_t id, - struct gfs_quota *q, - struct gfs_sb *sb); - -struct extent { - osi_list_t list; - - uint64_t offset; - uint64_t start; - unsigned int len; -}; -typedef struct extent extent_t; - -struct buffer { - osi_list_t list; - uint64_t blkno; - char *data; - - int touched; -}; -typedef struct buffer buffer_t; - -struct lblk_range { - osi_list_t list; - - uint64_t start; - unsigned int len; -}; -typedef struct lblk_range lblk_range_t; - -struct world { - char *buf_data; - unsigned int buf_size; - int buf_count; - osi_list_t blist; - osi_list_t elist; - - struct gfs_sb sb; - unsigned int diptrs; - unsigned int inptrs; - unsigned int jbsize; - unsigned int hash_bsize; - unsigned int hash_ptrs; - - buffer_t *dibh; - struct gfs_dinode di; -}; -typedef struct world world_t; - -typedef void (*pointer_call_t) (world_t *w, - unsigned int height, uint64_t bn, void *data); - -static lblk_range_t *lblk_range_list; -static unsigned int j_blk_size; - -/** - * add_lblk_range - Add a range of logical block numbers to lblk_list - * @lblk_list: the list to add to - * @start: the starting block number of the range - * @len: the length of the range - * - */ - -static void -add_lblk_range(lblk_range_t *lblk_list, uint64_t start, unsigned int len) -{ - lblk_range_t *tmp; - - tmp = malloc(sizeof(lblk_range_t)); - if (!tmp) - die("out of memory\n"); - - tmp->start = start; - tmp->len = len; - - osi_list_add_prev(&tmp->list, &lblk_list->list); -} - -/** - * build_list - build a list of buffer_t's to represent the data from the kernel - * @w: the world structure - * - */ - -static void -build_list(world_t *w) -{ - buffer_t *b; - unsigned int x; - - for (x = 0; x < w->buf_count; x += sizeof(uint64_t) + w->sb.sb_bsize) { - b = malloc(sizeof(buffer_t)); - if (!b) - die("out of memory\n"); - - memset(b, 0, sizeof(buffer_t)); - - b->blkno = *(uint64_t *) (w->buf_data + x); - b->data = w->buf_data + x + sizeof(uint64_t); - - osi_list_add_prev(&b->list, &w->blist); - } - - if (x != w->buf_count) - die("the kernel passed back unaligned data\n"); -} - -/** - * check_list - check the buffers passed back by the kernel - * @w: the world - * - */ - -static void -check_list(world_t *w) -{ - osi_list_t *tmp; - buffer_t *b; - struct gfs_meta_header mh; - char *type; - - for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) { - b = osi_list_entry(tmp, buffer_t, list); - - gfs_meta_header_in(&mh, b->data); - - if (mh.mh_magic != GFS_MAGIC) - die("bad magic number on block\n"); - - switch (mh.mh_type) { - case GFS_METATYPE_DI: - type = "GFS_METATYPE_DI"; - - if (w->dibh) - die("more than one dinode in file\n"); - else { - w->dibh = b; - gfs_dinode_in(&w->di, b->data); - - b->touched = TRUE; - } - break; - case GFS_METATYPE_IN: - type = "GFS_METATYPE_IN"; - break; - case GFS_METATYPE_LF: - type = "GFS_METATYPE_LF"; - break; - case GFS_METATYPE_JD: - type = "GFS_METATYPE_JD"; - break; - case GFS_METATYPE_EA: - type = "GFS_METATYPE_EA"; - break; - case GFS_METATYPE_ED: - die("GFS_METATYPE_ED shouldn't be present\n"); - default: - die("strange meta type\n"); - } - } - - if (!w->dibh) - die("no dinode\n"); -} - -/** - * getbuf - get the buffer_t for a given block number - * @w: the world - * @blkno: the block number - * - * Returns: the buffer_t - */ - -static buffer_t * -getbuf(world_t *w, uint64_t blkno) -{ - osi_list_t *tmp; - buffer_t *b; - - for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) { - b = osi_list_entry(tmp, buffer_t, list); - if (b->blkno == blkno) { - osi_list_del(&b->list); - osi_list_add(&b->list, &w->blist); - - b->touched = TRUE; - - return b; - } - } - - die("buffer not found\n"); -} - -/** - * recursive_scan - call a function for each block pointer in a file - * @w: the world - * @height: the height of the block being pointed to - * @block: the block being pointed to - * @pc: the function to call - * @data: private data for the @pc function - * - */ - -static void -recursive_scan(world_t *w, unsigned int height, - uint64_t block, pointer_call_t pc, void *data) -{ - buffer_t *b = NULL; - uint64_t *top, *bottom; - uint64_t bn; - - if (!height) { - b = w->dibh; - - top = (uint64_t *) (b->data + sizeof(struct gfs_dinode)); - bottom = - (uint64_t *) (b->data + sizeof(struct gfs_dinode)) + - w->diptrs; - } else { - b = getbuf(w, block); - - top = (uint64_t *) (b->data + sizeof(struct gfs_indirect)); - bottom = - (uint64_t *) (b->data + sizeof(struct gfs_indirect)) + - w->inptrs; - } - - for (; top < bottom; top++) { - bn = gfs64_to_cpu(*top); - - pc(w, height, bn, data); - - if (bn && height < w->di.di_height - 1) - recursive_scan(w, height + 1, bn, pc, data); - } -} - -/** - * add_extent - add an extend to the list of the file's data extents - * @w: the world - * @offset: the starting logical block of the extent - * @start: the starting disk block of the extent - * @len: the number of blocks in the extent - * - */ - -static void -add_extent(world_t *w, uint64_t offset, uint64_t start, unsigned int len) -{ - extent_t *e; - - e = malloc(sizeof(extent_t)); - if (!e) - die("out of memory\n"); - - memset(e, 0, sizeof(extent_t)); - - e->offset = offset; - e->start = start; - e->len = len; - - osi_list_add_prev(&e->list, &w->elist); -} - -struct do_pf_s { - unsigned int height; - uint64_t offset; - uint64_t start; - uint64_t skip; - unsigned int len; -}; -typedef struct do_pf_s do_pf_t; - -/** - * do_pf: called for every pointer in the file (prints/collects extent info) - * @w: the world - * @height: the height of the block containing the pointer - * @bn: the contents of the pointer - * @data: a do_pf_t structure - * - */ - -static void -do_pf(world_t *w, unsigned int height, uint64_t bn, void *data) -{ - do_pf_t *pf = (do_pf_t *) data; - unsigned int x; - uint64_t skip; - - if (pf->height < height + 1) - return; - - if (!bn) { - if (pf->height == height + 1) - pf->skip++; - else { - x = pf->height - height - 1; - skip = w->inptrs; - while (--x) - skip *= w->inptrs; - pf->skip += skip; - } - - return; - } - - if (pf->height == height + 1) { - if (pf->start + pf->len == bn && pf->len == pf->skip) { - pf->len++; - pf->skip++; - } else { - if (pf->start) { - if (pf->height == w->di.di_height) { - add_extent(w, pf->offset, pf->start, - pf->len); - add_lblk_range(lblk_range_list, - pf->offset, pf->len); - } - } - - pf->offset += pf->skip; - pf->start = bn; - pf->len = 1; - pf->skip = 1; - } - } -} - -/** - * get_dblk_ranges - Run through the file and add valid data block ranges to - * lblk_range_list - * @w: the world - * - */ - -static void -get_dblk_ranges(world_t *w) -{ - do_pf_t pf; - unsigned int h; - - for (h = 1; h <= w->di.di_height; h++) { - - memset(&pf, 0, sizeof(do_pf_t)); - pf.height = h; - - recursive_scan(w, 0, 0, do_pf, &pf); - - if (pf.start) { - if (h == w->di.di_height) { - add_extent(w, pf.offset, pf.start, pf.len); - add_lblk_range(lblk_range_list, pf.offset, - pf.len); - } - } - } -} - -/** - * compute_layout - Computes the layout and store the valid data page ranges - * in lblk_range_list - * @argc: - * @argv: - * - */ - -void -compute_layout(char *path) -{ - world_t w; - int fd; - int retry = TRUE; - struct gfs_ioctl gi; - int error; - - memset(&w, 0, sizeof(world_t)); - w.buf_size = LAYOUT_DATA_QUANTUM; - osi_list_init(&w.blist); - osi_list_init(&w.elist); - - - fd = open(path, O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", path, strerror(errno)); - - check_for_gfs(fd, path); - - { - char *argv[] = { "get_super" }; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = (char *)&w.sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_super (%d): %s\n", - error, strerror(errno)); - } - - w.diptrs = (w.sb.sb_bsize - sizeof(struct gfs_dinode)) / - sizeof(uint64_t); - w.inptrs = (w.sb.sb_bsize - sizeof(struct gfs_indirect)) / - sizeof(uint64_t); - w.jbsize = w.sb.sb_bsize - sizeof(struct gfs_meta_header); - j_blk_size = w.jbsize; - w.hash_bsize = w.sb.sb_bsize / 2; - w.hash_ptrs = w.hash_bsize / sizeof(uint64_t); - - for (;;) { - char *argv[] = { "get_file_meta_quota" }; - - w.buf_data = malloc(w.buf_size); - if (!w.buf_data) - die("out of memory\n"); - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = w.buf_data; - gi.gi_size = w.buf_size; - - w.buf_count = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (w.buf_count >= 0) - break; - - if (errno == ENOMEM) { - if (retry) { - free(w.buf_data); - w.buf_size += LAYOUT_DATA_QUANTUM; - continue; - } else - die("%u bytes isn't enough memory\n", - w.buf_size); - } - die("error doing get_file_meta: %s\n", - strerror(errno)); - } - - build_list(&w); - check_list(&w); - - get_dblk_ranges(&w); - - close(fd); -} - -/** - * print_quota_range - print the quota information in the given sequence of - * blocks - * @argc: - * @argv: - * - */ -void -print_quota_range(commandline_t *comline, int type, uint64_t start, - unsigned int len) -{ - uint64_t blk_offt, blk_end_offt, offset; - uint64_t quo; - unsigned int rem; - int fd; - struct gfs_sb sb; - struct gfs_ioctl gi; - char buf[sizeof(struct gfs_quota)]; - struct gfs_quota q; - uint64_t hidden_blocks = 0; - uint32_t id; - int error; - - blk_offt = start * (uint64_t)j_blk_size; - blk_end_offt = blk_offt + (uint64_t)(len * j_blk_size); - - quo = blk_offt / (uint64_t)(2 * sizeof(struct gfs_quota)); - rem = blk_offt % (uint64_t)(2 * sizeof(struct gfs_quota)); - - offset = type == GQ_ID_USER ? blk_offt : - blk_offt + sizeof(struct gfs_quota); - - if (rem && type == GQ_ID_USER) - offset = (quo + 1) * (uint64_t)(2 * sizeof(struct gfs_quota)); - - if (rem && type == GQ_ID_GROUP) { - if (rem <= sizeof(struct gfs_quota)) - offset = quo * (uint64_t)(2 * sizeof(struct gfs_quota)) - + sizeof(struct gfs_quota); - else - offset = (quo + 1) * - (uint64_t)(2 * sizeof(struct gfs_quota)) + - sizeof(struct gfs_quota); - } - - fd = open(comline->filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", comline->filesystem, - strerror(errno)); - - check_for_gfs(fd, comline->filesystem); - do_get_super(fd, &sb); - - if (comline->no_hidden_file_blocks) - hidden_blocks = compute_hidden_blocks(comline, fd); - - do { - char *argv[] = { "do_hfile_read", "quota" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = sizeof(struct gfs_quota); - gi.gi_offset = offset; - - memset(buf, 0, sizeof(struct gfs_quota)); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("can't read quota file: %s\n", - strerror(errno)); - - gfs_quota_in(&q, buf); - - id = (offset / sizeof(struct gfs_quota)) >> 1; - if (!id && comline->no_hidden_file_blocks) - q.qu_value -= hidden_blocks; - - if (q.qu_limit || q.qu_warn || q.qu_value) - print_quota(comline, type == GQ_ID_GROUP ? FALSE : TRUE, - id, &q, &sb); - - offset += 2 * sizeof(struct gfs_quota); - } while ((error == sizeof(struct gfs_quota)) && - (offset < blk_end_offt)); - - close(fd); -} - -void -print_quota_file(commandline_t *comline) -{ - lblk_range_t lblk_range, *bar; - osi_list_t *t, *x; - - lblk_range_list = &lblk_range; - - osi_list_init(&lblk_range_list->list); - - compute_layout(comline->filesystem); - - if (osi_list_empty(&lblk_range_list->list)) { - /* stuffed quota inode */ - print_quota_range(comline, GQ_ID_USER, 0, 1); - print_quota_range(comline, GQ_ID_GROUP, 0, 1); - } else { - /* print the user quotas */ - osi_list_foreach(t, &lblk_range_list->list) { - bar = osi_list_entry(t, lblk_range_t, list); - print_quota_range(comline, GQ_ID_USER, bar->start, - bar->len); - } - /* print the group quotas */ - osi_list_foreach(t, &lblk_range_list->list) { - bar = osi_list_entry(t, lblk_range_t, list); - print_quota_range(comline, GQ_ID_GROUP, bar->start, - bar->len); - } - /* free the list */ - osi_list_foreach_safe(t, &lblk_range_list->list, x) { - bar = osi_list_entry(t, lblk_range_t, list); - osi_list_del(&bar->list); - free(bar); - } - } -} diff --git a/gfs/gfs_quota/main.c b/gfs/gfs_quota/main.c deleted file mode 100644 index 1203621..0000000 --- a/gfs/gfs_quota/main.c +++ /dev/null @@ -1,747 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <time.h> -#include <limits.h> -#include <sys/param.h> -#include <sys/mount.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> -#define __user -#include <linux/gfs_ioctl.h> - -#include "copyright.cf" - -#include "gfs_quota.h" - -/* Constants */ - -#define OPTION_STRING ("bdf:g:hkl:mnsu:V") - -char *prog_name; - -/** - * print_usage - print usage info to the user - * - */ - -static void -print_usage() -{ - printf("Usage:\n"); - printf("\n"); - printf("%s <list|sync|get|limit|warn|check|init> [options]\n", - prog_name); - printf("\n"); - printf("Actions:\n"); - printf(" list list the whole quota file\n"); - printf(" sync sync out unsynced quotas\n"); - printf(" get get quota values for an ID\n"); - printf(" limit set a quota limit value for an ID\n"); - printf(" warn set a quota warning value for an ID\n"); - printf(" check check the quota file\n"); - printf(" init initialize the quota file\n"); - printf("\n"); - printf("Options:\n"); - printf(" -b sizes are in FS blocks\n"); - printf(" -d don't include hidden inode blocks\n"); - printf(" -f <directory> the filesystem to work on\n"); - printf(" -g <gid> get/set a group ID\n"); - printf(" -h Print this help, then exit\n"); - printf(" -k sizes are in KB\n"); - printf(" -l <size> the new limit or warn value\n"); - printf(" -m sizes are in MB\n"); - printf(" -n print out UID/GID numbers instead of names\n"); - printf(" -s sizes are in 512-byte blocks\n"); - printf(" -u <uid> get/set a user ID\n"); - printf(" -V Print program version information, then exit\n"); -} - -/** - * check_for_gfs - Check to see if a descriptor is a file on a GFS filesystem - * @fd: the file descriptor - * @path: the path used to open the descriptor - * - */ - -void -check_for_gfs(int fd, char *path) -{ - unsigned int magic = 0; - int error; - - error = ioctl(fd, GFS_IOCTL_IDENTIFY, &magic); - if (error || magic != GFS_MAGIC) - die("%s is not a GFS file/filesystem\n", path); -} - -/** - * do_get_super - * fd: - * sb: - * - */ - -void -do_get_super(int fd, struct gfs_sb *sb) -{ - struct gfs_ioctl gi; - char *argv[] = { "get_super" }; - int error; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = (char *)sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("can't read the superblock (%d): %s\n", - error, strerror(errno)); -} - -/** - * decode_arguments - parse command line arguments - * @argc: well, it's argc... - * @argv: well, it's argv... - * @comline: the structure filled in with the parsed arguments - * - * Function description - * - * Returns: what is returned - */ - -static void -decode_arguments(int argc, char *argv[], commandline_t *comline) -{ - int cont = TRUE; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - case 'u': - comline->id_type = GQ_ID_USER; - comline->id = name_to_id(TRUE, optarg, comline->numbers); - break; - - case 'g': - comline->id_type = GQ_ID_GROUP; - comline->id = name_to_id(FALSE, optarg, comline->numbers); - break; - - case 'l': - if (!isdigit(*optarg)) - die("argument to -l must be a number\n"); - sscanf(optarg, "%"SCNu64, &comline->new_value); - comline->new_value_set = TRUE; - break; - - case 'f': - if (!realpath(optarg, comline->filesystem)) - die("can't find %s: %s\n", optarg, - strerror(errno)); - break; - - case 'm': - comline->units = GQ_UNITS_MEGABYTE; - break; - - case 'k': - comline->units = GQ_UNITS_KILOBYTE; - break; - - case 'b': - comline->units = GQ_UNITS_FSBLOCK; - break; - - case 's': - comline->units = GQ_UNITS_BASICBLOCK; - break; - - case 'd': - comline->no_hidden_file_blocks = TRUE; - break; - - case 'n': - comline->numbers = TRUE; - break; - - case 'V': - printf("gfs_quota %s (built %s %s)\n", GFS_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case EOF: - cont = FALSE; - break; - - default: - die("unknown option: %c\n", optchar); - break; - }; - } - - while (optind < argc) { - if (strcmp(argv[optind], "list") == 0 || - strcmp(argv[optind], "dump") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_LIST; - } else if (strcmp(argv[optind], "sync") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_SYNC; - } else if (strcmp(argv[optind], "get") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_GET; - } else if (strcmp(argv[optind], "limit") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_LIMIT; - } else if (strcmp(argv[optind], "warn") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_WARN; - } else if (strcmp(argv[optind], "check") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_CHECK; - } else if (strcmp(argv[optind], "init") == 0) { - if (comline->operation) - die("can't specify two operations\n"); - comline->operation = GQ_OP_INIT; - } else - die("unknown option %s\n", argv[optind]); - - optind++; - } -} - -/** - * compute_hidden_blocks - figure out how much space the hidden inodes use - * @comline: the struct containing the parsed command line arguments - * @fd: the filedescriptor to the filesystem - * - * Returns: the number of hidden blocks - */ - -uint64_t -compute_hidden_blocks(commandline_t *comline, int fd) -{ - struct gfs_dinode di; - struct gfs_ioctl gi; - uint64_t hidden_blocks = 0; - int error; - - { - char *argv[] = { "get_hfile_stat", "jindex" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("can't stat jindex (%d): %s\n", - error, strerror(errno)); - hidden_blocks += di.di_blocks; - } - - { - char *argv[] = { "get_hfile_stat", "rindex" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("can't stat rindex (%d): %s\n", - error, strerror(errno)); - hidden_blocks += di.di_blocks; - } - - { - char *argv[] = { "get_hfile_stat", "quota" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("can't stat quota file (%d): %s\n", - error, strerror(errno)); - hidden_blocks += di.di_blocks; - } - - { - char *argv[] = { "get_hfile_stat", "license" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("can't stat license file (%d): %s\n", - error, strerror(errno)); - hidden_blocks += di.di_blocks; - } - - return hidden_blocks; -} - -/** - * print_quota - Print out a quota entry - * @comline: the struct containing the parsed command line arguments - * @user: TRUE if this is a user quota, FALSE if it's a group quota - * @id: the ID - * @q: the quota value - * @sb: the superblock of the filesystem this quota belongs to - * - */ - -void -print_quota(commandline_t *comline, - int user, uint32_t id, - struct gfs_quota *q, - struct gfs_sb *sb) -{ - printf("%-5s %10s: ", (user) ? "user" : "group", - id_to_name(user, id, comline->numbers)); - - switch (comline->units) { - case GQ_UNITS_MEGABYTE: - printf("limit: %-10.1f warn: %-10.1f value: %-10.1f\n", - (double) q->qu_limit * sb->sb_bsize / 1048576, - (double) q->qu_warn * sb->sb_bsize / 1048576, - (double) q->qu_value * sb->sb_bsize / 1048576); - break; - - case GQ_UNITS_KILOBYTE: - if (sb->sb_bsize == 512) - printf("limit: %-10"PRIu64" warn: %-10"PRIu64"value: %-10"PRId64"\n", - q->qu_limit / 2, - q->qu_warn / 2, - q->qu_value / 2); - else - printf("limit: %-10"PRIu64" warn: %-10"PRIu64"value: %-10"PRId64"\n", - q->qu_limit << (sb->sb_bsize_shift - 10), - q->qu_warn << (sb->sb_bsize_shift - 10), - q->qu_value << (sb->sb_bsize_shift - 10)); - break; - - case GQ_UNITS_FSBLOCK: - printf("limit: %-10"PRIu64" warn: %-10"PRIu64" value: %-10"PRId64"\n", - q->qu_limit, q->qu_warn, q->qu_value); - break; - - case GQ_UNITS_BASICBLOCK: - printf("limit: %-10"PRIu64" warn: %-10"PRIu64" value: %-10"PRId64"\n", - q->qu_limit << (sb->sb_bsize_shift - 9), - q->qu_warn << (sb->sb_bsize_shift - 9), - q->qu_value << (sb->sb_bsize_shift - 9)); - break; - - default: - die("bad units\n"); - break; - } -} - -/** - * do_list - List all the quota data for a filesystem - * @comline: the struct containing the parsed command line arguments - * - */ - -static void -do_list(commandline_t *comline) -{ - print_quota_file(comline); -} - -/** - * do_sync_one - sync the quotas on one GFS filesystem - * @path: a file/directory in the filesystem - * - */ - -static void -do_sync_one(char *filesystem) -{ - int fd; - char *argv[] = { "do_quota_sync" }; - struct gfs_ioctl gi; - int error; - - fd = open(filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", filesystem, strerror(errno)); - - check_for_gfs(fd, filesystem); - - gi.gi_argc = 1; - gi.gi_argv = argv; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error) - die("can't sync quotas: %s\n", strerror(errno)); - - close(fd); -} - -/** - * do_sync - sync out unsyned quotas - * @comline: the struct containing the parsed command line arguments - * - */ - -void -do_sync(commandline_t *comline) -{ - sync(); - - if (*comline->filesystem) - do_sync_one(comline->filesystem); - else { - char buf[256], device[256], path[256], type[256]; - FILE *file; - - file = fopen("/proc/mounts", "r"); - if (!file) - die("can't open /proc/mounts: %s\n", strerror(errno)); - - while (fgets(buf, 256, file)) { - if (sscanf(buf, "%s %s %s", device, path, type) != 3) - continue; - if (strcmp(type, "gfs") != 0) - continue; - - do_sync_one(path); - } - - fclose(file); - } -} - -/** - * do_get_one - Get a quota value from one FS - * @comline: the struct containing the parsed command line arguments - * @filesystem: the filesystem to get from - * - */ - -static void -do_get_one(commandline_t *comline, char *filesystem) -{ - int fd; - char buf[256]; - struct gfs_ioctl gi; - struct gfs_quota q; - struct gfs_sb sb; - int error; - - fd = open(filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", comline->filesystem, - strerror(errno)); - - check_for_gfs(fd, filesystem); - - sprintf(buf, "%s:%u", - (comline->id_type == GQ_ID_USER) ? "u" : "g", - comline->id); - - { - char *argv[] = { "do_quota_read", buf }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&q; - gi.gi_size = sizeof(struct gfs_quota); - - memset(&q, 0, sizeof(struct gfs_quota)); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("can't get quota info (%d): %s\n", - error, strerror(errno)); - } - - if (comline->no_hidden_file_blocks && !comline->id) - q.qu_value -= compute_hidden_blocks(comline, fd); - - do_get_super(fd, &sb); - - print_quota(comline, - (comline->id_type == GQ_ID_USER), comline->id, - &q, &sb); - - close(fd); -} - -/** - * do_get - Get a quota value - * @comline: the struct containing the parsed command line arguments - * - */ - -static void -do_get(commandline_t *comline) -{ - int first = TRUE; - - if (*comline->filesystem) - do_get_one(comline, comline->filesystem); - else { - char buf[256], device[256], path[256], type[256]; - FILE *file; - - file = fopen("/proc/mounts", "r"); - if (!file) - die("can't open /proc/mounts: %s\n", strerror(errno)); - - while (fgets(buf, 256, file)) { - if (sscanf(buf, "%s %s %s", device, path, type) != 3) - continue; - if (strcmp(type, "gfs") != 0) - continue; - - if (first) - first = FALSE; - else - printf("\n"); - - printf("%s:\n", path); - do_get_one(comline, path); - } - - fclose(file); - } -} - -/** - * do_set - Set a quota value - * @comline: the struct containing the parsed command line arguments - * - */ - -static void -do_set(commandline_t *comline) -{ - int fd; - uint64_t offset; - struct gfs_ioctl gi; - struct gfs_sb sb; - uint64_t new_value; - char buf[256]; - int error; - - if (!*comline->filesystem) - die("need a filesystem to work on\n"); - if (!comline->new_value_set) - die("need a new value\n"); - - fd = open(comline->filesystem, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", comline->filesystem, - strerror(errno)); - - check_for_gfs(fd, comline->filesystem); - - switch (comline->id_type) { - case GQ_ID_USER: - offset = (2 * (uint64_t)comline->id) * sizeof(struct gfs_quota); - break; - - case GQ_ID_GROUP: - offset = (2 * (uint64_t)comline->id + 1) * sizeof(struct gfs_quota); - break; - - default: - die("invalid user/group ID\n"); - break; - } - - switch (comline->operation) { - case GQ_OP_LIMIT: - offset += (unsigned long)(&((struct gfs_quota *) NULL)->qu_limit); - break; - - case GQ_OP_WARN: - offset += (unsigned long)(&((struct gfs_quota *) NULL)->qu_warn); - break; - - default: - die("invalid operation\n"); - break; - }; - - do_get_super(fd, &sb); - - switch (comline->units) { - case GQ_UNITS_MEGABYTE: - new_value = comline->new_value << (20 - sb.sb_bsize_shift); - break; - - case GQ_UNITS_KILOBYTE: - if (sb.sb_bsize == 512) - new_value = comline->new_value * 2; - else - new_value = comline->new_value >> (sb.sb_bsize_shift - 10); - break; - - case GQ_UNITS_FSBLOCK: - new_value = comline->new_value; - break; - - case GQ_UNITS_BASICBLOCK: - new_value = comline->new_value >> (sb.sb_bsize_shift - 9); - break; - - default: - die("bad units\n"); - break; - } - - new_value = cpu_to_gfs64(new_value); - - { - char *argv[] = { "do_hfile_write", "quota" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&new_value; - gi.gi_size = sizeof(uint64_t); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("can't write quota file (%d): %s\n", - error, strerror(errno)); - } - - sprintf(buf, "%s:%u", - (comline->id_type == GQ_ID_USER) ? "u" : "g", - comline->id); - - { - char *argv[] = { "do_quota_refresh", buf }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error) - die("can't refresh the quota LVB: %s\n", - strerror(errno)); - } - - close(fd); -} - -/** - * main - Do everything - * @argc: well, it's argc... - * @argv: well, it's argv... - * - * Returns: exit status - */ - -int -main(int argc, char *argv[]) -{ - commandline_t comline; - - prog_name = argv[0]; - - memset(&comline, 0, sizeof(commandline_t)); - - decode_arguments(argc, argv, &comline); - - switch (comline.operation) { - case GQ_OP_LIST: - do_list(&comline); - break; - - case GQ_OP_SYNC: - do_sync(&comline); - break; - - case GQ_OP_GET: - do_get(&comline); - break; - - case GQ_OP_LIMIT: - case GQ_OP_WARN: - do_set(&comline); - break; - - case GQ_OP_CHECK: - do_sync(&comline); - do_sync(&comline); - do_check(&comline); - break; - - case GQ_OP_INIT: - do_sync(&comline); - do_sync(&comline); - do_init(&comline); - break; - - default: - if (!comline.id_type) { - comline.id_type = GQ_ID_USER; - comline.id = geteuid(); - } - do_get(&comline); - break; - } - - exit(EXIT_SUCCESS); -} diff --git a/gfs/gfs_quota/names.c b/gfs/gfs_quota/names.c deleted file mode 100644 index 3ae0944..0000000 --- a/gfs/gfs_quota/names.c +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <time.h> -#include <dirent.h> -#include <limits.h> -#include <pwd.h> -#include <grp.h> -#include <stdint.h> -#include <inttypes.h> - -#include <linux/gfs_ondisk.h> - -#include "gfs_quota.h" - -uint32_t -name_to_id(int user, char *name, int numbers) -{ - struct passwd *u; - struct group *g; - uint32_t id; - int ok = FALSE; - - if (numbers) { - } else if (user) { - u = getpwnam(name); - if (u) { - id = u->pw_uid; - ok = TRUE; - } - } else { - g = getgrnam(name); - if (g) { - id = g->gr_gid; - ok = TRUE; - } - } - - if (!ok) { - if (!isdigit(name[0])) - die("can't find %s %s\n", - (user) ? "user" : "group", - name); - sscanf(name, "%u", &id); - } - - return id; -} - -char * -id_to_name(int user, uint32_t id, int numbers) -{ - struct passwd *u; - struct group *g; - static char name[256]; - int ok = FALSE; - - if (numbers) { - } else if (user) { - u = getpwuid(id); - if (u) { - strcpy(name, u->pw_name); - ok = TRUE; - } - } else { - g = getgrgid(id); - if (g) { - strcpy(name, g->gr_name); - ok = TRUE; - } - } - - if (!ok) - sprintf(name, "%u", id); - - return name; -} diff --git a/gfs/gfs_quota/ondisk.c b/gfs/gfs_quota/ondisk.c deleted file mode 100644 index ebb14ad..0000000 --- a/gfs/gfs_quota/ondisk.c +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> diff --git a/gfs/gfs_tool/Makefile b/gfs/gfs_tool/Makefile deleted file mode 100644 index 2d3e2e7..0000000 --- a/gfs/gfs_tool/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir= .. -include ${top_srcdir}/make/defines.mk - -TARGET= gfs_tool - -SOURCE= counters.c \ - df.c \ - layout.c \ - main.c \ - misc.c \ - ondisk.c \ - sb.c \ - tune.c \ - util.c - -CFLAGS+= -O2 -Wall -D_FILE_OFFSET_BITS=64 \ - -DGFS_RELEASE_NAME="${RELEASE}" - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -all: ${TARGET} - -gfs_tool: ${SOURCE} - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: ${TARGET} - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} - - diff --git a/gfs/gfs_tool/counters.c b/gfs/gfs_tool/counters.c deleted file mode 100644 index 1d31430..0000000 --- a/gfs/gfs_tool/counters.c +++ /dev/null @@ -1,215 +0,0 @@ - /****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#define __user -#include <linux/gfs_ioctl.h> -#include "osi_list.h" - -#include "gfs_tool.h" - -#define SIZE (4096) - -struct token_list { - osi_list_t list; - char *token; - unsigned int last; -}; - -static osi_list_decl(token_list); - -/** - * find_update_last - find and update the last value of a token - * @token: the token to look for - * @this: the current value of the token - * - * Returns: the last value of the token - */ - -static unsigned int -find_update_last(char *token, unsigned int this) -{ - osi_list_t *tmp, *head; - struct token_list *tl; - unsigned int last; - - for (head = &token_list, tmp = head->next; tmp != head; tmp = tmp->next) { - tl = osi_list_entry(tmp, struct token_list, list); - if (strcmp(tl->token, token)) - continue; - - last = tl->last; - tl->last = this; - return last; - } - - tl = malloc(sizeof (struct token_list) + strlen(token) + 1); - if (!tl) - die("out of memory\n"); - tl->token = (char *) (tl + 1); - strcpy(tl->token, token); - tl->last = this; - osi_list_add(&tl->list, &token_list); - - return 0; -} - -/** - * print_line - print out a counter - * @token: the name of the counter - * @description: the text description of the counter - * @option: an optional modifier - * @value: the value of the counter - * - */ - -static void -print_line(char *token, char *description, char *option, char *value) -{ - static unsigned int sd_log_seg_free; - unsigned int this, last; - - if (!strcmp(token, "sd_log_seg_free")) - sscanf(value, "%u", &sd_log_seg_free); - - else if (!strcmp(token, "ji_nsegment")) { - sscanf(value, "%u", &this); - printf("%39s %.2f%%\n", - "log space used", - 100.0 * (this - sd_log_seg_free) / this); - - } else if (continuous && !strcmp(option, "diff")) { - sscanf(value, "%u", &this); - last = find_update_last(token, this); - printf("%39s %-10s %d/s\n", - description, value, - (this - last + interval - 1) / interval); - - } else - printf("%39s %s\n", description, value); -} - -/** - * parse_line: break up a chunk of data into counter fields - * @buf: the data - * @count: the number of bytes of data - * - */ - -static void -parse_lines(char *buf, unsigned int count) -{ - char line[SIZE]; - char part1[SIZE], part2[SIZE], part3[SIZE], part4[SIZE]; - char *c, *c2; - unsigned int x; - - printf("\n"); - - while (count) { - for (c = line; count; c++) { - *c = *buf; - buf++; - count--; - if (*c == '\n') - break; - } - *c = 0; - - *part1 = *part2 = *part3 = *part4 = 0; - - for (c = line, x = 0; (c2 = strsep(&c, ":")); x++) { - if (!*c2) - continue; - - if (x == 0) - strcpy(part1, c2); - else if (x == 1) - strcpy(part2, c2); - else if (x == 2) - strcpy(part3, c2); - else - strcpy(part4, c2); - } - - if (x == 4) - print_line(part1, part2, part3, part4); - } -} - -/** - * print_counters - print out the current countersable parameters for a filesystem - * @argc: - * @argv: - * - */ - -void -print_counters(int argc, char **argv) -{ - char *fs; - int fd; - - if (optind < argc) - fs = argv[optind++]; - else - die("Usage: gfs_tool counters <mountpoint>\n"); - - fd = open(fs, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", fs, strerror(errno)); - - check_for_gfs(fd, fs); - - for (;;) { - struct gfs_ioctl gi; - char *argv[] = { "get_counters" }; - char data[SIZE]; - int error; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = data; - gi.gi_size = SIZE; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("can't get counters: %s\n", strerror(errno)); - - if (debug) - write(STDOUT_FILENO, data, error); - - parse_lines(data, error); - - if (!continuous) - break; - - fflush(stdout); - - sleep(interval); - } - - close(fd); -} diff --git a/gfs/gfs_tool/decipher_lockstate_dump b/gfs/gfs_tool/decipher_lockstate_dump deleted file mode 100755 index acafd7b..0000000 --- a/gfs/gfs_tool/decipher_lockstate_dump +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -foreach $arg (@ARGV) -{ - if ($arg eq '-nosort') - { - $nosort = 1; - } - else - { - push(@files, $arg); - } -} - - -foreach $file (@files) -{ - open(FILE, "< $file") || die "decipher_lockstate_dump: can't open file %s: $!\n"; - - while ($line = <FILE>) - { - $line =~ s/\n/ \n/; - - if ($line =~ /^Glock/) - { - $locks[$ln++] .= "\n" if (!$nosort && $notfirst++); - $line =~ s/((0),/(reserved[$1],/; - $line =~ s/((1),/(nondisk[$1],/; - $line =~ s/((2),/(inode[$1],/; - $line =~ s/((3),/(rgrp[$1],/; - $line =~ s/((4),/(meta[$1],/; - $line =~ s/((5),/(iopen[$1],/; - $line =~ s/((6),/(flock[$1],/; - $line =~ s/((7),/(jid[$1],/; - $line =~ s/((8),/(quota[$1],/; - - $line =~ s/(nondisk(\S+), (0))/(nondisk$1, mount[$2])/; - $line =~ s/(nondisk(\S+), (1))/(nondisk$1, live[$2])/; - $line =~ s/(nondisk(\S+), (2))/(nondisk$1, trans[$2])/; - $line =~ s/(nondisk(\S+), (3))/(nondisk$1, rename[$2])/; - - $line =~ s/(meta(\S+), (0))/(meta$1, super[$2])/; - $line =~ s/(meta(\S+), (1))/(meta$1, crap[$2])/; - - if ($line =~ /(quota\S+, (\d+))/) - { - $qid = (($1 % 2) ? "Group" : "User") . int($1 / 2) . "[$1]"; - $line =~ s/(quota(\S+), \d+)/(quota$1, $qid)/; - } - } - if ($line =~ /gl_flags/) - { - $line =~ s/ (0) / plug[$1] /; - $line =~ s/ (1) / lock[$1] /; - $line =~ s/ (2) / sticky[$1] /; - $line =~ s/ (3) / prefetch[$1]/; - $line =~ s/ (4) / sync[$1] /; - $line =~ s/ (5) / dirty[$1] /; - $line =~ s/ (6) / skip_waiters2[$1] /; - $line =~ s/ (7) / greedy[$1] /; - } - if ($line =~ /state/) - { - $line =~ s/(0)/unlocked[$1]/; - $line =~ s/(1)/exclusive[$1]/; - $line =~ s/(2)/deferred[$1]/; - $line =~ s/(3)/shared[$1]/; - } - if ($line =~ /gh_flags/) - { - $line =~ s/ (0) / try[$1] /; - $line =~ s/ (1) / try_1cb[$1] /; - $line =~ s/ (2) / noexp[$1] /; - $line =~ s/ (3) / any[$1] /; - $line =~ s/ (4) / priority[$1] /; - $line =~ s/ (5) / local_excl[$1] /; - $line =~ s/ (6) / async[$1] /; - $line =~ s/ (7) / exact[$1] /; - $line =~ s/ (8) / skip[$1] /; - $line =~ s/ (9) / atime[$1] /; - $line =~ s/ (10) / nocache[$1] /; - $line =~ s/ (11) / sync[$1] /; - $line =~ s/ (12) / nocancel[$1] /; - } - if ($line =~ /gh_iflags/) - { - $line =~ s/ (0) / mutex[$1] /; - $line =~ s/ (1) / promote[$1] /; - $line =~ s/ (2) / demote[$1] /; - $line =~ s/ (3) / greedy[$1] /; - $line =~ s/ (4) / alloced[$1] /; - $line =~ s/ (5) / dealloc[$1] /; - $line =~ s/ (6) / holder[$1] /; - $line =~ s/ (7) / first[$1] /; - $line =~ s/ (8) / recurse[$1] /; - $line =~ s/ (9) / aborted[$1] /; - } - if ($line =~ /owner/) - { - $line =~ s/(-1)/none[$1]/; - } - if ($line =~ /type/) - { - $line =~ s/(0)/none[$1]/; - $line =~ s/(1)/regular[$1]/; - $line =~ s/(2)/directory[$1]/; - $line =~ s/(5)/symbolic link[$1]/; - $line =~ s/(7)/block device[$1]/; - $line =~ s/(8)/character device[$1]/; - $line =~ s/(101)/fifo[$1]/; - $line =~ s/(102)/socket[$1]/; - } - if ($line =~ /i_flags/) - { - $line =~ s/ (0) / qd_locked[$1] /; - $line =~ s/ (1) / paged[$1] /; - $line =~ s/ (2) / sw_paged[$1] /; - } - - $locks[$ln] .= $line; - $ln++ if ($nosort); - } - - close(FILE); -} - - -@locks = sort funky @locks unless ($nosort); - - -foreach $lock (@locks) -{ - print $lock; -} - - - -sub funky -{ - my($a_iopen, $b_iopen) = (0, 0); - my($a_locked, $b_locked) = (0, 0); - my($a_queued, $b_queued) = (0, 0); - my($a_unlocked, $b_unlocked) = (0, 0); - - - $a_iopen = 1 if ($a =~ /iopen/); - $b_iopen = 1 if ($b =~ /iopen/); - - $a_locked = 1 if ($a =~ /gl_flags.*lock.*\n/); - $b_locked = 1 if ($b =~ /gl_flags.*lock.*\n/); - - $a_queued = 1 if ($a =~ /Request/ || - $a =~ /Holder/ || - $a =~ /Waiter/); - $b_queued = 1 if ($b =~ /Request/ || - $b =~ /Holder/ || - $b =~ /Waiter/); - - $a_unlocked = 1 if ($a =~ /gl_state.*unlocked.*\n/); - $b_unlocked = 1 if ($b =~ /gl_state.*unlocked.*\n/); - - - return ($a_iopen <=> $b_iopen) if ($a_iopen != $b_iopen); - return -($a_locked <=> $b_locked) if ($a_locked != $b_locked); - return -($a_queued <=> $b_queued) if ($a_queued != $b_queued); - return ($a_unlocked <=> $b_unlocked) if ($a_unlocked != $b_unlocked); - - - return 0; -} - - diff --git a/gfs/gfs_tool/df.c b/gfs/gfs_tool/df.c deleted file mode 100644 index 2d1030c..0000000 --- a/gfs/gfs_tool/df.c +++ /dev/null @@ -1,275 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#define __user -#include <linux/gfs_ioctl.h> -#include <linux/gfs_ondisk.h> -struct file { int x; }; -struct file_lock { int x; }; -#include <linux/lm_interface.h> - -#include "gfs_tool.h" - -#define SIZE (4096) - -/** - * do_df_one - print out information about one filesystem - * @path: the path to the filesystem - * - */ - -static void -do_df_one(char *path) -{ - int fd; - struct gfs_ioctl gi; - char stat_gfs[SIZE], args[SIZE], lockstruct[SIZE]; - struct gfs_sb sb; - struct gfs_dinode ji, ri; - uint64_t journals, rgrps; - uint64_t used_data; - unsigned int flags; - unsigned int percentage; - int error; - - - fd = open(path, O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", path, strerror(errno)); - - check_for_gfs(fd, path); - - - { - char *argv[] = { "get_stat_gfs" }; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = stat_gfs; - gi.gi_size = SIZE; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("error doing get_stat_gfs (%d): %s\n", - error, strerror(errno)); - } - { - char *argv[] = { "get_super" }; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = (char *)&sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_super (%d): %s\n", - error, strerror(errno)); - } - { - char *argv[] = { "get_args" }; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = args; - gi.gi_size = SIZE; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("error doing get_args (%d): %s\n", - error, strerror(errno)); - } - { - char *argv[] = { "get_lockstruct" }; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = lockstruct; - gi.gi_size = SIZE; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error < 0) - die("error doing get_lockstruct (%d): %s\n", - error, strerror(errno)); - } - { - char *argv[] = { "get_hfile_stat", - "jindex" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&ji; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_hfile_stat for jindex (%d): %s\n", - error, strerror(errno)); - } - { - char *argv[] = { "get_hfile_stat", - "rindex" }; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&ri; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_hfile_stat for rindex (%d): %s\n", - error, strerror(errno)); - } - - - close(fd); - - - journals = ji.di_size; - if (journals % sizeof(struct gfs_jindex)) - die("bad jindex size\n"); - journals /= sizeof(struct gfs_jindex); - - rgrps = ri.di_size; - if (rgrps % sizeof(struct gfs_rindex)) - die("bad rindex size\n"); - rgrps /= sizeof(struct gfs_rindex); - - - used_data = name2u64(stat_gfs, "total_blocks") - - name2u64(stat_gfs, "free") - - (name2u64(stat_gfs, "used_dinode") + name2u64(stat_gfs, "free_dinode")) - - (name2u64(stat_gfs, "used_meta") + name2u64(stat_gfs, "free_meta")); - - - printf("%s:\n", path); - printf(" SB lock proto = "%s"\n", sb.sb_lockproto); - printf(" SB lock table = "%s"\n", sb.sb_locktable); - printf(" SB ondisk format = %u\n", sb.sb_fs_format); - printf(" SB multihost format = %u\n", sb.sb_multihost_format); - printf(" Block size = %u\n", name2u32(stat_gfs, "bsize")); - printf(" Journals = %"PRIu64"\n", journals); - printf(" Resource Groups = %"PRIu64"\n", rgrps); - printf(" Mounted lock proto = "%s"\n", - (name2value(args, "lockproto")[0]) ? - name2value(args, "lockproto") : sb.sb_lockproto); - printf(" Mounted lock table = "%s"\n", - (name2value(args, "locktable")[0]) ? - name2value(args, "locktable") : sb.sb_locktable); - printf(" Mounted host data = "%s"\n", name2value(args, "hostdata")); - printf(" Journal number = %u\n", name2u32(lockstruct, "jid")); - flags = name2u32(lockstruct, "flags"); - printf(" Lock module flags = "); - if (flags & LM_LSFLAG_LOCAL) - printf("local "); - printf("\n"); - printf(" Local flocks = %s\n", (name2u32(args, "localflocks")) ? "TRUE" : "FALSE"); - printf(" Local caching = %s\n", (name2u32(args, "localcaching")) ? "TRUE" : "FALSE"); - printf(" Oopses OK = %s\n", (name2u32(args, "oopses_ok")) ? "TRUE" : "FALSE"); - printf("\n"); - printf(" %-15s%-15s%-15s%-15s%-15s\n", "Type", "Total", "Used", "Free", "use%"); - printf(" ------------------------------------------------------------------------\n"); - - percentage = (name2u64(stat_gfs, "used_dinode") + name2u64(stat_gfs, "free_dinode")) ? - (100.0 * name2u64(stat_gfs, "used_dinode") / (name2u64(stat_gfs, "used_dinode") + - name2u64(stat_gfs, "free_dinode")) + 0.5) : 0; - printf(" %-15s%-15"PRIu64"%-15"PRIu64"%-15"PRIu64"%u%%\n", - "inodes", - name2u64(stat_gfs, "used_dinode") + name2u64(stat_gfs, "free_dinode"), - name2u64(stat_gfs, "used_dinode"), - name2u64(stat_gfs, "free_dinode"), - percentage); - - percentage = (name2u64(stat_gfs, "used_meta") + name2u64(stat_gfs, "free_meta")) ? - (100.0 * name2u64(stat_gfs, "used_meta") / (name2u64(stat_gfs, "used_meta") + - name2u64(stat_gfs, "free_meta")) + 0.5) : 0; - printf(" %-15s%-15"PRIu64"%-15"PRIu64"%-15"PRIu64"%u%%\n", - "metadata", - name2u64(stat_gfs, "used_meta") + name2u64(stat_gfs, "free_meta"), - name2u64(stat_gfs, "used_meta"), - name2u64(stat_gfs, "free_meta"), - percentage); - - percentage = (used_data + name2u64(stat_gfs, "free")) ? - (100.0 * used_data / (used_data + name2u64(stat_gfs, "free")) + 0.5) : 0; - printf(" %-15s%-15"PRIu64"%-15"PRIu64"%-15"PRIu64"%u%%\n", - "data", - used_data + name2u64(stat_gfs, "free"), - used_data, - name2u64(stat_gfs, "free"), - percentage); -} - - -/** - * print_df - print out information about filesystems - * @argc: - * @argv: - * - */ - -void -print_df(int argc, char **argv) -{ - if (optind < argc) { - char buf[PATH_MAX]; - - if (!realpath(argv[optind], buf)) - die("can't determine real path: %s\n", strerror(errno)); - - do_df_one(buf); - - return; - } - - { - FILE *file; - char buf[256], device[256], path[256], type[256]; - int first = TRUE; - - file = fopen("/proc/mounts", "r"); - if (!file) - die("can't open /proc/mounts: %s\n", strerror(errno)); - - while (fgets(buf, 256, file)) { - if (sscanf(buf, "%s %s %s", device, path, type) != 3) - continue; - if (strcmp(type, "gfs") != 0) - continue; - - if (first) - first = FALSE; - else - printf("\n"); - - do_df_one(path); - } - - fclose(file); - } -} - - diff --git a/gfs/gfs_tool/gfs_tool.h b/gfs/gfs_tool/gfs_tool.h deleted file mode 100644 index 550f6b4..0000000 --- a/gfs/gfs_tool/gfs_tool.h +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GFS_TOOL_DOT_H__ -#define __GFS_TOOL_DOT_H__ - - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#define die(fmt, args...) \ -do { \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} while (0) - - -extern char *prog_name; -extern char *action; -extern int override; -extern int expert; -extern int debug; -extern int continuous; -extern int interval; - - -/* From counters.c */ - -void print_counters(int argc, char **argv); - - -/* From df.c */ - -void print_df(int argc, char **argv); - - -/* From layout.c */ - -void print_layout(int argc, char **argv); - - -/* From main.c */ - -void print_usage(void); - - -/* From misc.c */ - -void do_file_flush(int argc, char **argv); -void do_freeze(int argc, char **argv); -void margs(int argc, char **argv); -void print_lockdump(int argc, char **argv); -void set_flag(int argc, char **argv); -void print_stat(int argc, char **argv); -void print_sb(int argc, char **argv); -void print_jindex(int argc, char **argv); -void print_rindex(int argc, char **argv); -void print_quota(int argc, char **argv); -void print_list(void); -void reclaim_metadata(int argc, char **argv); -void do_shrink(int argc, char **argv); -void do_withdraw(int argc, char **argv); - - -/* From sb.c */ - -void do_sb(int argc, char **argv); - - -/* From tune.c */ - -void get_tune(int argc, char **argv); -void set_tune(int argc, char **argv); - - -/* From util.c */ - -void check_for_gfs(int fd, char *path); -char *get_list(void); -char **str2lines(char *str); -char *mp2cookie(char *mp, int ioctl_ok); -char *name2value(char *str, char *name); -uint32_t name2u32(char *str, char *name); -uint64_t name2u64(char *str, char *name); - - -#endif /* __GFS_TOOL_DOT_H__ */ diff --git a/gfs/gfs_tool/layout.c b/gfs/gfs_tool/layout.c deleted file mode 100644 index 7842def..0000000 --- a/gfs/gfs_tool/layout.c +++ /dev/null @@ -1,855 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#define __user -#include <linux/gfs_ioctl.h> -#include <linux/gfs_ondisk.h> - -#include "osi_list.h" -#include "linux_endian.h" - -#include "gfs_tool.h" - -#define LAYOUT_DATA_QUANTUM (4194304) - -struct extent { - osi_list_t list; - - uint64_t offset; - uint64_t start; - unsigned int len; -}; -typedef struct extent extent_t; - -struct buffer { - osi_list_t list; - uint64_t blkno; - char *data; - - int touched; -}; -typedef struct buffer buffer_t; - -struct world { - char *buf_data; - unsigned int buf_size; - int buf_count; - osi_list_t blist; - osi_list_t elist; - - struct gfs_sb sb; - unsigned int diptrs; - unsigned int inptrs; - unsigned int jbsize; - unsigned int hash_bsize; - unsigned int hash_ptrs; - - buffer_t *dibh; - struct gfs_dinode di; -}; -typedef struct world world_t; - -typedef void (*pointer_call_t) (world_t *w, - unsigned int height, uint64_t bn, void *data); -typedef void (*leaf_call_t) (world_t *w, - uint32_t index, uint32_t len, uint64_t leaf_no, - void *data); - -/** - * build_list - build a list of buffer_t's to represent the data from the kernel - * @w: the world structure - * - */ - -static void -build_list(world_t *w) -{ - buffer_t *b; - unsigned int x; - - for (x = 0; x < w->buf_count; x += sizeof(uint64_t) + w->sb.sb_bsize) { - b = malloc(sizeof(buffer_t)); - if (!b) - die("out of memory\n"); - - memset(b, 0, sizeof(buffer_t)); - - b->blkno = *(uint64_t *) (w->buf_data + x); - b->data = w->buf_data + x + sizeof(uint64_t); - - osi_list_add_prev(&b->list, &w->blist); - } - - if (x != w->buf_count) - die("the kernel passed back unaligned data\n"); -} - -/** - * check_list - check the buffers passed back by the kernel - * @w: the world - * - */ - -static void -check_list(world_t *w) -{ - osi_list_t *tmp; - buffer_t *b; - struct gfs_meta_header mh; - char *type; - - for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) { - b = osi_list_entry(tmp, buffer_t, list); - - gfs_meta_header_in(&mh, b->data); - - if (mh.mh_magic != GFS_MAGIC) - die("bad magic number on block\n"); - - switch (mh.mh_type) { - case GFS_METATYPE_DI: - type = "GFS_METATYPE_DI"; - - if (w->dibh) - die("more than one dinode in file\n"); - else { - w->dibh = b; - gfs_dinode_in(&w->di, b->data); - - b->touched = TRUE; - } - - break; - case GFS_METATYPE_IN: - type = "GFS_METATYPE_IN"; - break; - case GFS_METATYPE_LF: - type = "GFS_METATYPE_LF"; - break; - case GFS_METATYPE_JD: - type = "GFS_METATYPE_JD"; - break; - case GFS_METATYPE_EA: - type = "GFS_METATYPE_EA"; - break; - case GFS_METATYPE_ED: - die("GFS_METATYPE_ED shouldn't be present\n"); - default: - die("strange meta type\n"); - } - } - - if (!w->dibh) - die("no dinode\n"); -} - -/** - * getbuf - get the buffer_t for a given block number - * @w: the world - * @blkno: the block number - * - * Returns: the buffer_t - */ - -static buffer_t * -getbuf(world_t *w, uint64_t blkno) -{ - osi_list_t *tmp; - buffer_t *b; - - for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) { - b = osi_list_entry(tmp, buffer_t, list); - if (b->blkno == blkno) { - osi_list_del(&b->list); - osi_list_add(&b->list, &w->blist); - - b->touched = TRUE; - - return b; - } - } - - die("buffer not found\n"); -} - -/** - * recursive_scan - call a function for each block pointer in a file - * @w: the world - * @height: the height of the block being pointed to - * @block: the block being pointed to - * @pc: the function to call - * @data: private data for the @pc function - * - */ - -static void -recursive_scan(world_t *w, - unsigned int height, uint64_t block, pointer_call_t pc, void *data) -{ - buffer_t *b = NULL; - uint64_t *top, *bottom; - uint64_t bn; - - if (!height) { - b = w->dibh; - - top = (uint64_t *) (b->data + sizeof(struct gfs_dinode)); - bottom = - (uint64_t *) (b->data + sizeof(struct gfs_dinode)) + - w->diptrs; - } else { - b = getbuf(w, block); - - top = (uint64_t *) (b->data + sizeof(struct gfs_indirect)); - bottom = - (uint64_t *) (b->data + sizeof(struct gfs_indirect)) + - w->inptrs; - } - - for (; top < bottom; top++) { - bn = gfs64_to_cpu(*top); - - pc(w, height, bn, data); - - if (bn && height < w->di.di_height - 1) - recursive_scan(w, height + 1, bn, pc, data); - } -} - -/** - * bmap - return the buffer_t for a given logical block in the file - * @w: the world - * @lbn: the logical block number - * - * Returns: the buffer_t - */ - -static buffer_t * -bmap(world_t *w, uint64_t lbn) -{ - osi_list_t *tmp; - extent_t *e; - - for (tmp = w->elist.next; tmp != &w->elist; tmp = tmp->next) { - e = osi_list_entry(tmp, extent_t, list); - - if (e->offset <= lbn && lbn < e->offset + e->len) - return getbuf(w, e->start + lbn - e->offset); - } - - return NULL; -} - -/** - * journaled_read - read some of the contents of a journaled file - * @w: the world - * @buf: the buffer to read into - * @offset: the offset to read from - * @size: the number of bytes to read - * - */ - -static void -journaled_read(world_t *w, char *buf, uint64_t offset, unsigned int size) -{ - buffer_t *b; - uint64_t lbn; - unsigned int o, chunk; - - if (!(w->di.di_flags & GFS_DIF_JDATA)) - die("not a journaled file\n"); - - if (!w->di.di_height) { - if (offset >= w->sb.sb_bsize - sizeof(struct gfs_dinode)) - memset(buf, 0, size); - else { - chunk = - w->sb.sb_bsize - sizeof(struct gfs_dinode) - - offset; - if (chunk > size) - chunk = size; - memcpy(buf, - w->dibh->data + sizeof(struct gfs_dinode) + - offset, chunk); - if (chunk < size) - memset(buf + chunk, 0, size - chunk); - } - } else - while (size) { - lbn = offset / w->jbsize; - o = offset % w->jbsize; - chunk = (size > w->jbsize - o) ? (w->jbsize - o) : size; - - b = bmap(w, lbn); - if (b) - memcpy(buf, - b->data + - sizeof(struct gfs_meta_header) + o, - chunk); - else - memset(buf, 0, chunk); - - buf += chunk; - offset += chunk; - size -= chunk; - } -} - -/** - * foreach_leaf - call a function for each leaf in a directory - * @w: the world - * @lc: the function to call for each each - * @data: private data to pass to it - * - * Returns: 0 on success, -EXXX on failure - */ - -static void -foreach_leaf(world_t *w, leaf_call_t lc, void *data) -{ - buffer_t *b; - struct gfs_leaf leaf; - uint32_t hsize, len; - uint32_t ht_offset, lp_offset, ht_offset_cur = -1; - uint32_t index = 0; - uint64_t lp[w->hash_ptrs]; - uint64_t leaf_no; - - hsize = 1 << w->di.di_depth; - if (hsize * sizeof(uint64_t) != w->di.di_size) - die("bad hash table size\n"); - - while (index < hsize) { - lp_offset = index % w->hash_ptrs; - ht_offset = index - lp_offset; - - if (ht_offset_cur != ht_offset) { - journaled_read(w, (char *) lp, - ht_offset * sizeof(uint64_t), - w->hash_bsize); - ht_offset_cur = ht_offset; - } - - leaf_no = gfs64_to_cpu(lp[lp_offset]); - if (!leaf_no) - die("NULL leaf pointer\n"); - - b = getbuf(w, leaf_no); - gfs_leaf_in(&leaf, b->data); - - len = 1 << (w->di.di_depth - leaf.lf_depth); - - lc(w, index, len, leaf_no, data); - - index += len; - } - - if (index != hsize) - die("screwed up directory\n"); -} - -/** - * add_extent - add an extend to the list of the file's data extents - * @w: the world - * @offset: the starting logical block of the extent - * @start: the starting disk block of the extent - * @len: the number of blocks in the extent - * - */ - -static void -add_extent(world_t *w, uint64_t offset, uint64_t start, unsigned int len) -{ - extent_t *e; - - e = malloc(sizeof(extent_t)); - if (!e) - die("out of memory\n"); - - memset(e, 0, sizeof(extent_t)); - - e->offset = offset; - e->start = start; - e->len = len; - - osi_list_add_prev(&e->list, &w->elist); -} - -struct do_pf_s { - unsigned int height; - uint64_t offset; - uint64_t start; - uint64_t skip; - unsigned int len; -}; -typedef struct do_pf_s do_pf_t; - -/** - * do_pf: called for every pointer in the file (prints/collects extent info) - * @w: the world - * @height: the height of the block containing the pointer - * @bn: the contents of the pointer - * @data: a do_pf_t structure - * - */ - -static void -do_pf(world_t *w, unsigned int height, uint64_t bn, void *data) -{ - do_pf_t *pf = (do_pf_t *) data; - unsigned int x; - uint64_t skip; - - if (pf->height < height + 1) - return; - - if (!bn) { - if (pf->height == height + 1) - pf->skip++; - else { - x = pf->height - height - 1; - skip = w->inptrs; - while (--x) - skip *= w->inptrs; - pf->skip += skip; - } - - return; - } - - if (pf->height == height + 1) { - if (pf->start + pf->len == bn && pf->len == pf->skip) { - pf->len++; - pf->skip++; - } else { - if (pf->start) { - printf(" %-20" PRIu64 " %-20" PRIu64 " %-20" - PRIu64 " %u\n", pf->offset, - pf->offset + pf->len - 1, pf->start, - pf->len); - if (pf->height == w->di.di_height) - add_extent(w, pf->offset, pf->start, - pf->len); - } - - pf->offset += pf->skip; - pf->start = bn; - pf->len = 1; - pf->skip = 1; - } - } -} - -/** - * print_file - print out the extent lists for all the heights of a file - * @w: the world - * - */ - -static void -print_file(world_t *w) -{ - do_pf_t pf; - unsigned int h; - char *type; - - switch (w->di.di_type) { - case GFS_FILE_REG: - type = "File"; - break; - case GFS_FILE_DIR: - type = "Directory"; - break; - case GFS_FILE_LNK: - type = "Symbolic Link"; - break; - case GFS_FILE_BLK: - type = "Block Device"; - break; - case GFS_FILE_CHR: - type = "Character Device"; - break; - case GFS_FILE_FIFO: - type = "FIFO"; - break; - case GFS_FILE_SOCK: - type = "Socket"; - break; - default: - die("strange file type\n"); - }; - - printf("%s dinode:\n", type); - printf(" %" PRIu64 "\n", w->di.di_num.no_addr); - - if (!w->di.di_height) { - if (w->di.di_type == GFS_FILE_DIR) { - if (w->di.di_flags & GFS_DIF_EXHASH) - printf("\nStuffed hash table\n"); - } else - printf("\nStuffed file data\n"); - - return; - } - - for (h = 1; h <= w->di.di_height; h++) { - if (w->di.di_type == GFS_FILE_DIR) - type = - (h == w->di.di_height) ? "hash table" : "indirect"; - else - type = (h == w->di.di_height) ? "data" : "indirect"; - - printf("\n"); - printf("At height %u (%s):\n", h, type); - printf(" %-20s %-20s %-20s %s\n", - "From LBlock", "To LBlock", "DBlock", "Blocks"); - - memset(&pf, 0, sizeof(do_pf_t)); - pf.height = h; - - recursive_scan(w, 0, 0, do_pf, &pf); - - if (pf.start) { - printf(" %-20" PRIu64 " %-20" PRIu64 " %-20" PRIu64 - " %u\n", pf.offset, pf.offset + pf.len - 1, - pf.start, pf.len); - if (h == w->di.di_height) - add_extent(w, pf.offset, pf.start, pf.len); - } - } -} - -/** - * do_lc - print out info about a leaf block - * @w: the world - * @index: the index of the leaf - * @len: the number of pointers to the leaf - * @leaf_no: the leaf block number - * @data: unused - * - */ - -static void -do_lc(world_t *w, uint32_t index, uint32_t len, uint64_t leaf_no, void *data) -{ - buffer_t *b; - struct gfs_leaf leaf; - uint64_t blk; - - for (blk = leaf_no; blk; blk = leaf.lf_next) { - b = getbuf(w, blk); - gfs_leaf_in(&leaf, b->data); - - printf(" %.8X %.8X %-20" PRIu64 - " %u\n", index << (32 - w->di.di_depth), - ((index + len) << (32 - w->di.di_depth)) - 1, blk, - leaf.lf_entries); - } - -} - -/** - * print_leaves - print out the location of the exhash leaves - * @w: the world - * - */ - -static void -print_leaves(world_t *w) -{ - printf("\n"); - - if (w->di.di_flags & GFS_DIF_EXHASH) { - printf("Leaves:\n"); - printf(" %-20s %-20s %-20s %s\n", - "From Hash", "To Hash", "DBlock", "Entries"); - foreach_leaf(w, do_lc, NULL); - } else - printf("Stuffed directory data\n"); -} - -/** - * print_eattr_data - print out the locations of the eattr data blocks - * @w: the world - * - */ - -#define MAKE_MULT8(x) (((x) + 7) & ~7) -#define GFS_EA_REC_LEN(ea) gfs32_to_cpu((ea)->ea_rec_len) -#define GFS_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) -#define GFS_EA_IS_LAST(ea) ((ea)->ea_flags & GFS_EAFLAG_LAST) -#define GFS_EA2NAME(ea) ((char *)((struct gfs_ea_header *)(ea) + 1)) -#define GFS_EA2DATAPTRS(ea) \ -((uint64_t *)(GFS_EA2NAME(ea) + MAKE_MULT8((ea)->ea_name_len))) -#define GFS_EA2NEXT(ea) \ -((struct gfs_ea_header *)((char *)(ea) + GFS_EA_REC_LEN(ea))) -#define GFS_EA_BH2FIRST(b) \ -((struct gfs_ea_header *)((b)->data + \ - sizeof(struct gfs_meta_header))) - -static void -print_eattr_data(world_t *w, uint64_t blkno, int *first) -{ - buffer_t *b = getbuf(w, blkno); - struct gfs_ea_header *ea; - - ea = GFS_EA_BH2FIRST(b); - for (;;) { - if (!GFS_EA_IS_STUFFED(ea)) { - char name[300]; - uint64_t *p, blkno; - uint64_t b; - unsigned int l; - unsigned int x; - int c; - - if (*first) { - printf("\nExtended Attributes data blocks:\n"); - printf(" %-20s %-10s %s\n", - "DBlock", "Blocks", "Name"); - *first = FALSE; - } - - if (ea->ea_type == GFS_EATYPE_UNUSED) - strcpy(name, "unused"); - else { - unsigned int x; - switch (ea->ea_type) { - case GFS_EATYPE_USR: - strcpy(name, "user."); - break; - case GFS_EATYPE_SYS: - strcpy(name, "system."); - break; - default: - strcpy(name, "unknown."); - break; - } - x = strlen(name); - memcpy(name + x, - GFS_EA2NAME(ea), ea->ea_name_len); - name[x + ea->ea_name_len] = 0; - } - - b = 0; - l = 0; - c = FALSE; - - p = GFS_EA2DATAPTRS(ea); - for (x = 0; x < ea->ea_num_ptrs; x++) { - blkno = gfs64_to_cpu(*p); - if (b + l == blkno) - l++; - else { - if (b) { - printf(" %-20" PRIu64 - " %-10u %s\n", b, l, - name); - if (!c) { - strcat(name, " (cont)"); - c = TRUE; - } - } - b = blkno; - l = 1; - } - p++; - } - printf(" %-20" PRIu64 " %-10u %s\n", b, l, name); - } - if (GFS_EA_IS_LAST(ea)) - break; - ea = GFS_EA2NEXT(ea); - } -} - -/** - * print_eattr - print out the locations of the eattr blocks - * @w: the world - * - */ - -static void -print_eattr(world_t *w) -{ - int first = TRUE; - - if (w->di.di_flags & GFS_DIF_EA_INDIRECT) { - buffer_t *b = getbuf(w, w->di.di_eattr); - uint64_t *blkno; - unsigned int x; - - printf("\nExtended Attribute indirect block:\n"); - printf(" %" PRIu64 "\n", w->di.di_eattr); - - printf("\nExtended Attribute blocks:\n"); - blkno = (uint64_t *) (b->data + sizeof(struct gfs_indirect)); - for (x = 0; x < w->inptrs; x++) { - if (!*blkno) - break; - printf(" %" PRIu64 "\n", gfs64_to_cpu(*blkno)); - blkno++; - } - - blkno = (uint64_t *) (b->data + sizeof(struct gfs_indirect)); - for (x = 0; x < w->inptrs; x++) { - if (!*blkno) - break; - print_eattr_data(w, gfs64_to_cpu(*blkno), &first); - blkno++; - } - } else { - printf("\nExtended Attribute block:\n"); - printf(" %" PRIu64 "\n", w->di.di_eattr); - - print_eattr_data(w, w->di.di_eattr, &first); - } -} - -/** - * check_for_untouched_buffers - - * @w: the world - * - */ - -static void -check_for_untouched_buffers(world_t *w) -{ - osi_list_t *tmp; - buffer_t *b; - - for (tmp = w->blist.next; tmp != &w->blist; tmp = tmp->next) { - b = osi_list_entry(tmp, buffer_t, list); - if (b->touched) - continue; - - printf("Buffer %" PRIu64 " untouched\n", b->blkno); - } -} - -/** - * print_layout - print out the ondisk layout of a file - * @argc: - * @argv: - * - */ - -void -print_layout(int argc, char **argv) -{ - world_t w; - char *path; - int fd; - int retry = TRUE; - struct gfs_ioctl gi; - int error; - - memset(&w, 0, sizeof(world_t)); - w.buf_size = LAYOUT_DATA_QUANTUM; - osi_list_init(&w.blist); - osi_list_init(&w.elist); - - if (optind == argc) - die("Usage: gfs_tool layout <filename> [buffersize]\n"); - - path = argv[optind++]; - if (optind < argc ) { - w.buf_size = atoi(argv[3]); - retry = FALSE; - } - - fd = open(path, O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", path, strerror(errno)); - - check_for_gfs(fd, path); - - { - char *argv[] = { "get_super" }; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = (char *)&w.sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_super (%d): %s\n", - error, strerror(errno)); - } - - w.diptrs = (w.sb.sb_bsize - sizeof(struct gfs_dinode)) / - sizeof(uint64_t); - w.inptrs = (w.sb.sb_bsize - sizeof(struct gfs_indirect)) / - sizeof(uint64_t); - w.jbsize = w.sb.sb_bsize - sizeof(struct gfs_meta_header); - w.hash_bsize = w.sb.sb_bsize / 2; - w.hash_ptrs = w.hash_bsize / sizeof(uint64_t); - - for (;;) { - char *argv[] = { "get_file_meta" }; - - w.buf_data = malloc(w.buf_size); - if (!w.buf_data) - die("out of memory\n"); - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = w.buf_data; - gi.gi_size = w.buf_size; - - w.buf_count = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (w.buf_count >= 0) - break; - - if (errno == ENOMEM) { - if (retry) { - free(w.buf_data); - w.buf_size += LAYOUT_DATA_QUANTUM; - continue; - } else - die("%u bytes isn't enough memory\n", - w.buf_size); - } - die("error doing get_file_meta: %s\n", - strerror(errno)); - } - - build_list(&w); - check_list(&w); - - print_file(&w); - - if (w.di.di_type == GFS_FILE_DIR) - print_leaves(&w); - - if (w.di.di_eattr) - print_eattr(&w); - - check_for_untouched_buffers(&w); - - close(fd); -} diff --git a/gfs/gfs_tool/main.c b/gfs/gfs_tool/main.c deleted file mode 100644 index a3ac96a..0000000 --- a/gfs/gfs_tool/main.c +++ /dev/null @@ -1,277 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#include "copyright.cf" - -#include "gfs_tool.h" - -char *prog_name; -char *action = NULL; -int override = FALSE; -int expert = FALSE; -int debug = FALSE; -int continuous = FALSE; -int interval = 1; - -static const char *usage[] = { - "Clear a flag on a inode\n", - " gfs_tool clearflag flag <filenames>\n", - "\n", - "Print the counters for a filesystem\n", - " gfs_tool counters <mountpoint>\n", - "\n", - "Do a GFS specific "df"\n", - " gfs_tool df <mountpoint>\n", - "\n", - "Force files from a machine's cache\n", - " gfs_tool flush <filenames>\n", - "\n", - "Freeze a GFS cluster:\n", - " gfs_tool freeze <mountpoint>\n", - "\n", - "Print the superblock of a mounted filesystem:\n", - " gfs_tool getsb <mountpoint>\n", - "\n", - "Get tuneable parameters for a filesystem\n", - " gfs_tool gettune <mountpoint>\n", - "\n", - "Print the journal index of a mounted filesystem:\n", - " gfs_tool jindex <mountpoint>\n", - "\n", - "Print out the ondisk layout for a file:\n", - " gfs_tool layout <filename> [buffersize]\n", - "\n", - "List filesystems:\n", - " gfs_tool list\n", - "\n", - "Have GFS dump its lock state:\n", - " gfs_tool lockdump <mountpoint> [buffersize]\n", - "\n", - "Provide arguments for next mount:\n", - " gfs_tool margs <mountarguments>\n", - "\n", - "Print the quota file of a mounted filesystem:\n", - " gfs_tool quota <mountpoint>\n", - "\n", - "Free unused disk inodes:\n", - " gfs_tool reclaim <mountpoint>\n", - "\n", - "Print the resource group index of a mounted filesystem:\n", - " gfs_tool rindex <mountpoint>\n", - "\n", - "Tune a GFS superblock\n", - " gfs_tool sb <device> proto [newval]\n", - " gfs_tool sb <device> table [newval]\n", - " gfs_tool sb <device> ondisk [newval]\n", - " gfs_tool sb <device> multihost [newval]\n", - " gfs_tool sb <device> all\n", - "\n", - "Set a flag on a inode\n", - " gfs_tool setflag flag <filenames>\n", - "\n", - "Tune a running filesystem\n", - " gfs_tool settune <mountpoint> <parameter> <value>\n", - "\n", - "Shrink a filesystem's inode cache:\n", - " gfs_tool shrink <mountpoint>\n", - "\n", - "Print file stat data:\n", - " gfs_tool stat <filename>\n", - "\n", - "Unfreeze a GFS cluster:\n", - " gfs_tool unfreeze <mountpoint>\n", - "\n", - "Print tool version information\n", - " gfs_tool version\n", - "\n", - "Withdraw this machine from participating in a filesystem:\n", - " gfs_tool withdraw <mountpoint>\n", - "", -}; - -/** - * print_usage - print out usage information - * - */ - -void -print_usage(void) -{ - int x; - - for (x = 0; usage[x][0]; x++) - printf(usage[x]); -} - -/** - * print_version - - * - */ - -static void -print_version(void) -{ - printf("gfs_tool %s (built %s %s)\n", - GFS_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", - REDHAT_COPYRIGHT); -} - -/** - * decode_arguments - - * @argc: - * @argv: - * - */ - -static void -decode_arguments(int argc, char *argv[]) -{ - int cont = TRUE; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, "cDhi:OVX"); - - switch (optchar) { - case 'c': - continuous = TRUE; - break; - - case 'D': - debug = TRUE; - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - - case 'i': - sscanf(optarg, "%u", &interval); - break; - - case 'O': - override = TRUE; - break; - - case 'V': - print_version(); - exit(EXIT_SUCCESS); - - case 'X': - expert = TRUE; - break; - - case EOF: - cont = FALSE; - break; - - default: - die("unknown option: %c\n", optchar); - }; - } - - if (optind < argc) { - action = argv[optind]; - optind++; - } else - die("no action specified\n"); -} - -/** - * main - Do everything - * @argc: - * @argv: - * - */ - -int -main(int argc, char *argv[]) -{ - prog_name = argv[0]; - - if (argc < 2) { - print_usage(); - exit(EXIT_SUCCESS); - } - - decode_arguments(argc, argv); - - if (FALSE) { - /* Do Nothing */ - } else if (strcmp(action, "clearflag") == 0) - set_flag(argc, argv); - else if (strcmp(action, "counters") == 0) - print_counters(argc, argv); - else if (strcmp(action, "df") == 0) - print_df(argc, argv); - else if (strcmp(action, "flush") == 0) - do_file_flush(argc, argv); - else if (strcmp(action, "freeze") == 0) - do_freeze(argc, argv); - else if (strcmp(action, "getsb") == 0) - print_sb(argc, argv); - else if (strcmp(action, "gettune") == 0) - get_tune(argc, argv); - else if (strcmp(action, "jindex") == 0) - print_jindex(argc, argv); - else if (strcmp(action, "layout") == 0) - print_layout(argc, argv); - else if (strcmp(action, "list") == 0) - print_list(); - else if (strcmp(action, "lockdump") == 0) - print_lockdump(argc, argv); - else if (strcmp(action, "margs") == 0) - margs(argc, argv); - else if (strcmp(action, "quota") == 0) - print_quota(argc, argv); - else if (strcmp(action, "reclaim") == 0) - reclaim_metadata(argc, argv); - else if (strcmp(action, "rindex") == 0) - print_rindex(argc, argv); - else if (strcmp(action, "sb") == 0) - do_sb(argc, argv); - else if (strcmp(action, "setflag") == 0) - set_flag(argc, argv); - else if (strcmp(action, "settune") == 0) - set_tune(argc, argv); - else if (strcmp(action, "shrink") == 0) - do_shrink(argc, argv); - else if (strcmp(action, "stat") == 0) - print_stat(argc, argv); - else if (strcmp(action, "unfreeze") == 0) - do_freeze(argc, argv); - else if (strcmp(action, "version") == 0) - print_version(); - else if (strcmp(action, "withdraw") == 0) - do_withdraw(argc, argv); - else - die("unknown action: %s\n", - action); - - exit(EXIT_SUCCESS); -} diff --git a/gfs/gfs_tool/misc.c b/gfs/gfs_tool/misc.c deleted file mode 100644 index 405aca5..0000000 --- a/gfs/gfs_tool/misc.c +++ /dev/null @@ -1,746 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#define __user -#include <linux/gfs_ioctl.h> -#include <linux/gfs_ondisk.h> - -#include "gfs_tool.h" - -/** - * do_file_flush - - * @argc: - * @argv: - * - */ - -void -do_file_flush(int argc, char **argv) -{ - char *gi_argv[] = { "do_file_flush" }; - struct gfs_ioctl gi; - int fd; - int error; - - if (optind == argc) - die("Usage: gfs_tool flush <filenames>\n"); - - gi.gi_argc = 1; - gi.gi_argv = gi_argv; - - for (; optind < argc; optind++) { - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error) - die("error doing do_file_flush (%d): %s\n", - error, strerror(errno)); - - close(fd); - } -} - -/** - * do_freeze - freeze a GFS filesystem - * @argc: - * @argv: - * - */ - -void -do_freeze(int argc, char **argv) -{ - char *command = argv[optind - 1]; - char *cookie; - int fd; - char buf[256]; - int x; - - if (optind == argc) - die("Usage: gfs_tool %s <mountpoint>\n", - command); - - cookie = mp2cookie(argv[optind], FALSE); - x = sprintf(buf, "%s %s\n", command, cookie); - - fd = open("/proc/fs/gfs", O_RDWR); - if (fd < 0) - die("can't open /proc/fs/gfs: %s\n", - strerror(errno)); - - if (write(fd, buf, x) != x) - die("can't write %s command: %s\n", - command, strerror(errno)); - if (read(fd, buf, 256)) - die("can't %s %s: %s\n", - command, argv[optind], strerror(errno)); - - close(fd); - sync(); -} - -/** - * print_lockdump - - * @argc: - * @argv: - * - */ - -void -print_lockdump(int argc, char **argv) -{ - int fd; - char *mp, *cookie; - unsigned int size = 4194304; - char *data; - char command[256]; - int retry = TRUE; - int x, count; - - - if (optind < argc) - mp = argv[optind++]; - else - die("Usage: gfs_tool lockdump <mountpoint> [buffersize]\n"); - - if (optind < argc) { - sscanf(argv[optind++], "%u", &size); - retry = FALSE; - } - - cookie = mp2cookie(mp, FALSE); - x = sprintf(command, "lockdump %s\n", cookie); - - - fd = open("/proc/fs/gfs", O_RDWR); - if (fd < 0) - die("can't open /proc/fs/gfs: %s\n", - strerror(errno)); - - for (;;) { - data = malloc(size); - if (!data) - die("out of memory\n"); - - if (write(fd, command, x) != x) - die("can't write lockdump command: %s\n", - strerror(errno)); - count = read(fd, data, size); - if (count >= 0) - break; - - if (errno == ENOMEM) { - if (retry) { - free(data); - size += 4194304; - continue; - } else - die("%u bytes isn't enough memory\n", size); - } - die("error doing lockdump: %s\n", - strerror(errno)); - } - - close(fd); - - - write(STDOUT_FILENO, data, count); - - free(data); -} - -/** - * margs - - * @argc: - * @argv: - * - */ - -void -margs(int argc, char **argv) -{ - int fd; - char *buf; - unsigned int x; - - if (optind == argc) - die("Usage: gfs_tool margs <mountarguments>\n"); - - x = strlen(argv[optind]) + 7; - buf = malloc(x + 1); - if (!buf) - die("out of memory\n"); - sprintf(buf, "margs %s\n", argv[optind]); - - fd = open("/proc/fs/gfs", O_RDWR); - if (fd < 0) - die("can't open /proc/fs/gfs: %s\n", - strerror(errno)); - - if (write(fd, buf, x) != x) - die("can't write margs command: %s\n", - strerror(errno)); - if (read(fd, buf, x)) - die("can't set mount args: %s\n", - strerror(errno)); - - close(fd); -} - -/** - * print_flags - print the flags in a dinode's di_flags field - * @di: the dinode structure - * - */ - -static void -print_flags(struct gfs_dinode *di) -{ - if (di->di_flags) { - printf("Flags:\n"); - if (di->di_flags & GFS_DIF_JDATA) - printf(" jdata\n"); - if (di->di_flags & GFS_DIF_EXHASH) - printf(" exhash\n"); - if (di->di_flags & GFS_DIF_UNUSED) - printf(" unused\n"); - if (di->di_flags & GFS_DIF_EA_INDIRECT) - printf(" ea_indirect\n"); - if (di->di_flags & GFS_DIF_DIRECTIO) - printf(" directio\n"); - if (di->di_flags & GFS_DIF_IMMUTABLE) - printf(" immutable\n"); - if (di->di_flags & GFS_DIF_APPENDONLY) - printf(" appendonly\n"); -#if 0 - if (di->di_flags & GFS_DIF_NOATIME) - printf(" noatime\n"); - if (di->di_flags & GFS_DIF_SYNC) - printf(" sync\n"); -#endif - if (di->di_flags & GFS_DIF_INHERIT_DIRECTIO) - printf(" inherit_directio\n"); - if (di->di_flags & GFS_DIF_INHERIT_JDATA) - printf(" inherit_jdata\n"); - } -} - -/** - * set_flag - set or clear flags in some dinodes - * @argc: - * @argv: - * - */ - -void -set_flag(int argc, char **argv) -{ - struct gfs_dinode di; - char *set; - char *flag; - struct gfs_ioctl gi; - int fd; - int error; - - if (optind == argc) { - di.di_flags = 0xFFFFFFFF; - print_flags(&di); - return; - } - - set = (strcmp(argv[optind - 1], "setflag") == 0) ? "set" : "clear"; - flag = argv[optind++]; - - for (; optind < argc; optind++) { - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - { - char *gi_argv[] = { "set_file_flag", - set, - flag }; - gi.gi_argc = 3; - gi.gi_argv = gi_argv; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error) - die("can't change flag on %s: %s\n", argv[optind], strerror(errno)); - } - - close(fd); - } -} - -/** - * print_stat - print out the struct gfs_dinode for a file - * @argc: - * @argv: - * - */ - -void -print_stat(int argc, char **argv) -{ - int fd; - char *gi_argv[] = { "get_file_stat" }; - struct gfs_ioctl gi; - struct gfs_dinode di; - int error; - - if (optind == argc) - die("Usage: gfs_tool stat <filename>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - gi.gi_argc = 1; - gi.gi_argv = gi_argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_file_stat (%d): %s\n", - error, strerror(errno)); - - close(fd); - - gfs_dinode_print(&di); - printf("\n"); - print_flags(&di); -} - -/** - * print_sb - the superblock - * @argc: - * @argv: - * - */ - -void -print_sb(int argc, char **argv) -{ - int fd; - char *gi_argv[] = { "get_super" }; - struct gfs_ioctl gi; - struct gfs_sb sb; - int error; - - if (optind == argc) - die("Usage: gfs_tool getsb <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - gi.gi_argc = 1; - gi.gi_argv = gi_argv; - gi.gi_data = (char *)&sb; - gi.gi_size = sizeof(struct gfs_sb); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_super (%d): %s\n", - error, strerror(errno)); - - close(fd); - - gfs_sb_print(&sb); -} - -/** - * print_jindex - print out the journal index - * @argc: - * @argv: - * - */ - -void -print_jindex(int argc, char **argv) -{ - int fd; - struct gfs_ioctl gi; - uint64_t offset; - unsigned int x; - int error; - - - if (optind == argc) - die("Usage: gfs_tool jindex <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - - { - char *argv[] = { "get_hfile_stat", - "jindex" }; - struct gfs_dinode di; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_hfile_stat (%d): %s\n", - error, strerror(errno)); - - gfs_dinode_print(&di); - } - - - for (offset = 0, x = 0; ; offset += sizeof(struct gfs_jindex), x++) { - char *argv[] = { "do_hfile_read", - "jindex" }; - char buf[sizeof(struct gfs_jindex)]; - struct gfs_jindex ji; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = sizeof(struct gfs_jindex); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (!error) - break; - if (error != sizeof(struct gfs_jindex)) - die("error doing do_hfile_read (%d): %s\n", - error, strerror(errno)); - - gfs_jindex_in(&ji, buf); - - printf("\nJournal %u:\n\n", x); - gfs_jindex_print(&ji); - } - - - close(fd); -} - -/** - * print_rindex - print out the journal index - * @argc: - * @argv: - * - */ - -void -print_rindex(int argc, char **argv) -{ - int fd; - struct gfs_ioctl gi; - uint64_t offset; - unsigned int x; - int error; - - - if (optind == argc) - die("Usage: gfs_tool rindex <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - - { - char *argv[] = { "get_hfile_stat", - "rindex" }; - struct gfs_dinode di; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_hfile_stat (%d): %s\n", - error, strerror(errno)); - - gfs_dinode_print(&di); - } - - - for (offset = 0, x = 0; ; offset += sizeof(struct gfs_rindex), x++) { - char *argv[] = { "do_hfile_read", - "rindex" }; - char buf[sizeof(struct gfs_rindex)]; - struct gfs_rindex ri; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = sizeof(struct gfs_rindex); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (!error) - break; - if (error != sizeof(struct gfs_rindex)) - die("error doing do_hfile_read (%d): %s\n", - error, strerror(errno)); - - gfs_rindex_in(&ri, buf); - - printf("\nRG %u:\n\n", x); - gfs_rindex_print(&ri); - } - - - close(fd); -} - -/** - * print_quota - print out the journal index - * @argc: - * @argv: - * - */ - -void -print_quota(int argc, char **argv) -{ - int fd; - struct gfs_ioctl gi; - uint64_t offset; - unsigned int x; - int error; - - - if (optind == argc) - die("Usage: gfs_tool quota <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - - { - char *argv[] = { "get_hfile_stat", - "quota" }; - struct gfs_dinode di; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = (char *)&di; - gi.gi_size = sizeof(struct gfs_dinode); - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (error != gi.gi_size) - die("error doing get_hfile_stat (%d): %s\n", - error, strerror(errno)); - - gfs_dinode_print(&di); - } - - - for (offset = 0, x = 0; ; offset += sizeof(struct gfs_quota), x++) { - char *argv[] = { "do_hfile_read", - "quota" }; - char buf[sizeof(struct gfs_quota)]; - struct gfs_quota q; - - gi.gi_argc = 2; - gi.gi_argv = argv; - gi.gi_data = buf; - gi.gi_size = sizeof(struct gfs_quota); - gi.gi_offset = offset; - - error = ioctl(fd, GFS_IOCTL_SUPER, &gi); - if (!error) - break; - if (error != sizeof(struct gfs_quota)) - die("error doing do_hfile_read (%d): %s\n", - error, strerror(errno)); - - gfs_quota_in(&q, buf); - - if (q.qu_limit || q.qu_warn || q.qu_value) { - printf("\nQuota %s %u:\n\n", (x & 1) ? "group" : "user", x >> 1); - gfs_quota_print(&q); - } - } - - - close(fd); -} - -/** - * print_list - print the list of mounted filesystems - * - */ - -void -print_list(void) -{ - char *list = get_list(); - printf("%s", list); -} - -/** - * reclaim_metadata - reclaim unused metadata blocks - * @argc: - * @argv: - * - * This routine uses an ioctl command to quiesce the cluster and then - * hunt down and free all disk inodes that have been freed. This will - * gain back meta data blocks to be used for data (or metadata) again. - * - */ - -void -reclaim_metadata(int argc, char **argv) -{ - int fd; - char *gi_argv[] = { "do_reclaim" }; - struct gfs_ioctl gi; - char buf[256]; - - if (optind == argc) - die("Usage: gfs_tool reclaim <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - if (!override) { - printf("Don't do this if this file system is being exported by NFS (on any machine).\n"); - printf("\nAre you sure you want to proceed? [y/n] "); - fgets(buf, 255, stdin); - - if (buf[0] != 'y') - die("aborted\n"); - - printf("\n"); - } - - gi.gi_argc = 1; - gi.gi_argv = gi_argv; - gi.gi_data = buf; - gi.gi_size = 256; - - if (ioctl(fd, GFS_IOCTL_SUPER, &gi) < 0) - die("error doing do_reclaim: %s\n", strerror(errno)); - - close(fd); - - printf("Reclaimed:\n"); - printf("%s", buf); -} - -/** - * do_shrink - shrink the inode cache for a filesystem - * @argc: - * @argv: - * - */ - -void -do_shrink(int argc, char **argv) -{ - int fd; - char *gi_argv[] = { "do_shrink" }; - struct gfs_ioctl gi; - - if (optind == argc) - die("Usage: gfs_tool shrink <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", - argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - gi.gi_argc = 1; - gi.gi_argv = gi_argv; - - if (ioctl(fd, GFS_IOCTL_SUPER, &gi)) - die("error doing ioctl: %s\n", - strerror(errno)); - - close(fd); -} - -/** - * do_withdraw - freeze a GFS filesystem - * @argc: - * @argv: - * - */ - -void -do_withdraw(int argc, char **argv) -{ - char *cookie; - int fd; - char buf[256]; - int x; - - if (optind == argc) - die("Usage: gfs_tool withdraw <mountpoint>\n"); - - cookie = mp2cookie(argv[optind], FALSE); - x = sprintf(buf, "withdraw %s\n", cookie); - - fd = open("/proc/fs/gfs", O_RDWR); - if (fd < 0) - die("can't open /proc/fs/gfs: %s\n", - strerror(errno)); - - if (write(fd, buf, x) != x) - die("can't write withdraw command: %s\n", - strerror(errno)); - if (read(fd, buf, 256)) - die("can't withdraw %s: %s\n", - argv[optind], strerror(errno)); - - close(fd); -} diff --git a/gfs/gfs_tool/ondisk.c b/gfs/gfs_tool/ondisk.c deleted file mode 100644 index 93da930..0000000 --- a/gfs/gfs_tool/ondisk.c +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> - -#include "linux_endian.h" -#include <linux/gfs_ondisk.h> - -#define printk printf -#define pv(struct, member, fmt) \ -printf(" "#member" = "fmt"\n", struct->member); - -#define WANT_GFS_CONVERSION_FUNCTIONS -#include <linux/gfs_ondisk.h> - - diff --git a/gfs/gfs_tool/parse_lockdump b/gfs/gfs_tool/parse_lockdump deleted file mode 100755 index 2cc8ed4..0000000 --- a/gfs/gfs_tool/parse_lockdump +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -&do_input(@ARGV); - -print 'Entries: ', scalar(@gl), "\n"; -print 'Glocks: ', scalar(keys(%gl)), "\n"; -print 'PIDs: ', scalar(keys(%pid)), "\n"; -print "\n"; - -for ($x = 0; $x < @gl; $x++) -{ - if (!$done[$x]) - { - @chain = &find_chain($x); - $req = 0; - - print scalar(@chain), " chain:\n"; - - foreach $y (@chain) - { - print $gl[$y]; - $req++ if ($gl[$y] =~ /request/i); - $done[$y]++; - } - - print "$req requests\n"; - print "\n"; - - $chains++; - } -} - -for ($x = 0; $x < @gl; $x++) -{ - die "parse_lockdump: something is hosed\n" unless ($done[$x] == 1); -} - -print "Chains: $chains\n"; - - - - - -sub do_input -{ - my(@host) = @_; - my($host); - local(*FILE); - my($line); - my($gl); - - foreach $host (@host) - { - open(FILE, "< $host") || die; - - while ($line = <FILE>) - { - if ($line eq "\n") - { - &file($host, $gl); - $gl = ''; - } - else - { - $gl .= $line; - } - } - - if ($gl ne '') - { - &file($host, $gl); - $gl = ''; - } - - close(FILE); - } -} - - -# Builds: -# -# @gl: A list of all the glock sections read in -# @name: Contains the name of the glock of each member of @gl -# @pid: Contains the pids contained in each member of @gl -# %gl: Maps a lockname to the members of @gl that coorespond to that name -# %pid: Maps a pid to the members of @gl that correspond to that pid - -sub file -{ - my($host, $gl) = @_; - my($x); - my($name, $pid); - - ($name) = $gl =~ /^Glock ((.*))/; - - push(@gl, "$host $gl"); - $x = @gl - 1; - push(@name, $name); - - $gl{$name} .= "$x "; - - foreach (split("\n", $gl)) - { - if (/owner = (\d+)/) - { - $pid = "$host:$1"; - - if (!&is_in($pid, split(' ', $pid[$x]))) - { - $pid[$x] .= "$pid "; - $pid{$pid} .= "$x "; - } - } - } -} - - -sub find_chain -{ - my($x, @chain) = @_; - my($y, $z); - my($name, $pid); - - $name = $name[$x]; - - foreach $y (split(' ', $gl{$name})) - { - push(@chain, $y); - } - - foreach $y (split(' ', $gl{$name})) - { - foreach $pid (split(' ', $pid[$y])) - { - foreach $z (split(' ', $pid{$pid})) - { - @chain = &find_chain($z, @chain) unless (&is_in($z, @chain)); - } - } - } - - return @chain; -} - - -sub is_in -{ - my($val, @list) = @_; - - foreach (@list) - { - return 1 if ($_ eq $val); - } - - return 0; -} - - diff --git a/gfs/gfs_tool/sb.c b/gfs/gfs_tool/sb.c deleted file mode 100644 index 5f4cf03..0000000 --- a/gfs/gfs_tool/sb.c +++ /dev/null @@ -1,166 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#include <linux/gfs_ondisk.h> - -#include "gfs_tool.h" - -#define do_lseek(fd, off) \ -do { \ - if (lseek((fd), (off), SEEK_SET) != (off)) \ - die("bad seek: %s on line %d of file %s\n", \ - strerror(errno),__LINE__, __FILE__); \ -} while (0) - -#define do_read(fd, buff, len) \ -do { \ - if (read((fd), (buff), (len)) != (len)) \ - die("bad read: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} while (0) - -#define do_write(fd, buff, len) \ -do { \ - if (write((fd), (buff), (len)) != (len)) \ - die("bad write: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} while (0) - -/** - * do_sb - examine/modify a unmounted FS' superblock - * @argc: - * @argv: - * - */ - -void -do_sb(int argc, char **argv) -{ - char *device, *field, *newval = NULL; - int fd; - unsigned char buf[GFS_BASIC_BLOCK], input[256]; - struct gfs_sb sb; - - if (optind == argc) - die("Usage: gfs_tool sb <device> <field> [newval]\n"); - - device = argv[optind++]; - - if (optind == argc) - die("Usage: gfs_tool sb <device> <field> [newval]\n"); - - field = argv[optind++]; - - if (optind < argc) { - if (strcmp(field, "all") == 0) - die("can't specify new value for "all"\n"); - newval = argv[optind++]; - } - - - fd = open(device, (newval) ? O_RDWR : O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", device, strerror(errno)); - - if (newval && !override) { - printf("You shouldn't change any of these values if the filesystem is mounted.\n"); - printf("\nAre you sure? [y/n] "); - fgets(input, 255, stdin); - - if (input[0] != 'y') - die("aborted\n"); - - printf("\n"); - } - - do_lseek(fd, GFS_SB_ADDR * GFS_BASIC_BLOCK); - do_read(fd, buf, GFS_BASIC_BLOCK); - - gfs_sb_in(&sb, buf); - - if (sb.sb_header.mh_magic != GFS_MAGIC || - sb.sb_header.mh_type != GFS_METATYPE_SB) - die("there isn't a GFS filesystem on %s\n", device); - - if (strcmp(field, "proto") == 0) { - printf("current lock protocol name = "%s"\n", - sb.sb_lockproto); - - if (newval) { - if (strlen(newval) >= GFS_LOCKNAME_LEN) - die("new lockproto name is too long\n"); - strcpy(sb.sb_lockproto, newval); - printf("new lock protocol name = "%s"\n", - sb.sb_lockproto); - } - } else if (strcmp(field, "table") == 0) { - printf("current lock table name = "%s"\n", - sb.sb_locktable); - - if (newval) { - if (strlen(newval) >= GFS_LOCKNAME_LEN) - die("new locktable name is too long\n"); - strcpy(sb.sb_locktable, newval); - printf("new lock table name = "%s"\n", - sb.sb_locktable); - } - } else if (strcmp(field, "ondisk") == 0) { - printf("current ondisk format = %u\n", - sb.sb_fs_format); - - if (newval) { - sb.sb_fs_format = atoi(newval); - printf("new ondisk format = %u\n", - sb.sb_fs_format); - } - } else if (strcmp(field, "multihost") == 0) { - printf("current multihost format = %u\n", - sb.sb_multihost_format); - - if (newval) { - sb.sb_multihost_format = atoi(newval); - printf("new multihost format = %u\n", - sb.sb_multihost_format); - } - } else if (strcmp(field, "all") == 0) { - gfs_sb_print(&sb); - newval = FALSE; - } else - die("unknown field %s\n", field); - - if (newval) { - gfs_sb_out(&sb, buf); - - do_lseek(fd, GFS_SB_ADDR * GFS_BASIC_BLOCK); - do_write(fd, buf, GFS_BASIC_BLOCK); - - fsync(fd); - - printf("Done\n"); - } - - close(fd); -} diff --git a/gfs/gfs_tool/tune.c b/gfs/gfs_tool/tune.c deleted file mode 100644 index 1e8bc1a..0000000 --- a/gfs/gfs_tool/tune.c +++ /dev/null @@ -1,148 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> - -#define __user -#include <linux/gfs_ioctl.h> - -#include "gfs_tool.h" - -#define SIZE (4096) - -/** - * get_tune - print out the current tuneable parameters for a filesystem - * @argc: - * @argv: - * - */ - -void -get_tune(int argc, char **argv) -{ - int fd; - char *gi_argv[] = { "get_tune" }; - struct gfs_ioctl gi; - char str[SIZE], str2[SIZE]; - char **lines, **l; - - if (optind == argc) - die("Usage: gfs_tool gettune <mountpoint>\n"); - - fd = open(argv[optind], O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", - argv[optind], strerror(errno)); - - check_for_gfs(fd, argv[optind]); - - gi.gi_argc = 1; - gi.gi_argv = gi_argv; - gi.gi_data = str; - gi.gi_size = SIZE; - - if (ioctl(fd, GFS_IOCTL_SUPER, &gi) < 0) - die("error doing get_tune: %s\n", - strerror(errno)); - - close(fd); - - strcpy(str2, str); - lines = str2lines(str2); - - for (l = lines; **l; l++) { - char *p; - for (p = *l; *p; p++) - if (*p == ' ') { - *p++ = 0; - break; - } - - if (strcmp(*l, "version") == 0) - continue; - if (strcmp(*l, "quota_scale_num") == 0) { - printf("quota_scale = %.4f (%u, %u)\n", - (double)name2u32(str, "quota_scale_num") / name2u32(str, "quota_scale_den"), - name2u32(str, "quota_scale_num"), name2u32(str, "quota_scale_den")); - continue; - } - if (strcmp(*l, "quota_scale_den") == 0) - continue; - - printf("%s = %s\n", *l, p); - } -} - -/** - * set_tune - set a tuneable parameter - * @argc: - * @argv: - * - */ - -void -set_tune(int argc, char **argv) -{ - char *mp, *param, *value; - int fd; - struct gfs_ioctl gi; - char buf[256]; - - if (optind == argc) - die("Usage: gfs_tool settune <mountpoint> <parameter> <value>\n"); - mp = argv[optind++]; - if (optind == argc) - die("Usage: gfs_tool settune <mountpoint> <parameter> <value>\n"); - param = argv[optind++]; - if (optind == argc) - die("Usage: gfs_tool settune <mountpoint> <parameter> <value>\n"); - value = argv[optind++]; - - fd = open(mp, O_RDONLY); - if (fd < 0) - die("can't open file %s: %s\n", - mp, strerror(errno)); - - check_for_gfs(fd, mp); - - if (strcmp(param, "quota_scale") == 0) { - float s; - sscanf(value, "%f", &s); - sprintf(buf, "%u %u", (unsigned int)(s * 10000.0 + 0.5), 10000); - value = buf; - } - - { - char *argv[] = { "set_tune", param, value }; - - gi.gi_argc = 3; - gi.gi_argv = argv; - - if (ioctl(fd, GFS_IOCTL_SUPER, &gi)) - die("can't change tunable parameter %s: %s\n", - param, strerror(errno)); - } - - close(fd); -} diff --git a/gfs/gfs_tool/util.c b/gfs/gfs_tool/util.c deleted file mode 100644 index 3893c96..0000000 --- a/gfs/gfs_tool/util.c +++ /dev/null @@ -1,283 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include <errno.h> -#include <libgen.h> - -#define __user -#include <linux/gfs_ioctl.h> -#include <linux/gfs_ondisk.h> - -#include "gfs_tool.h" - -/** - * check_for_gfs - Check to see if a descriptor is a file on a GFS filesystem - * @fd: the file descriptor - * @path: the path used to open the descriptor - * - */ - -void -check_for_gfs(int fd, char *path) -{ - unsigned int magic = 0; - int error; - - error = ioctl(fd, GFS_IOCTL_IDENTIFY, &magic); - if (error || magic != GFS_MAGIC) - die("%s is not a GFS file/filesystem\n", - path); -} - -/** - * get_list - Get the list of GFS filesystems - * - * Returns: a NULL terminated string - */ - -#define LIST_SIZE (1048576) - -char * -get_list(void) -{ - char *list; - int fd; - int x; - - list = malloc(LIST_SIZE); - if (!list) - die("out of memory\n"); - - fd = open("/proc/fs/gfs", O_RDWR); - if (fd < 0) - die("can't open /proc/fs/gfs: %s\n", - strerror(errno)); - - if (write(fd, "list", 4) != 4) - die("can't write list command: %s\n", - strerror(errno)); - x = read(fd, list, LIST_SIZE - 1); - if (x < 0) - die("can't get list of filesystems: %s\n", - strerror(errno)); - - close(fd); - - list[x] = 0; - - return list; -} - -/** - * str2lines - parse a string into lines - * @list: the list - * - * Returns: An array of character pointers - */ - -char ** -str2lines(char *str) -{ - char *p; - unsigned int n = 0; - char **lines; - unsigned int x = 0; - - for (p = str; *p; p++) - if (*p == '\n') - n++; - - lines = malloc((n + 1) * sizeof(char *)); - if (!lines) - die("out of memory\n"); - - for (lines[x] = p = str; *p; p++) - if (*p == '\n') { - *p = 0; - lines[++x] = p + 1; - } - - return lines; -} - -/** - * mp2cookie - Find the cookie for a filesystem given its mountpoint - * @mp: - * @ioctl_ok: If this is FALSE, it's not acceptable to open() the mountpoint - * - * Returns: the cookie - */ - -char * -mp2cookie(char *mp, int ioctl_ok) -{ - char *cookie; - char *list, **lines; - FILE *file; - char line[256], device[256], dev_id[256]; - unsigned int x; - struct stat st; - - cookie = malloc(256); - if (!cookie) - die("out of memory\n"); - list = get_list(); - lines = str2lines(list); - - file = fopen("/proc/mounts", "r"); - if (!file) - die("can't open /proc/mounts: %s\n", - strerror(errno)); - - memset(dev_id, 0, sizeof(dev_id)); - while (fgets(line, 256, file)) { - char path[256], type[256]; - - if (sscanf(line, "%s %s %s", device, path, type) != 3) - continue; - if (strcmp(path, mp)) - continue; - if (strcmp(type, "gfs")) - die("%s is not a GFS filesystem\n", mp); - - if (stat(device, &st)) - continue; - sprintf(dev_id, "%u:%u", major(st.st_rdev),minor(st.st_rdev)); - break; - } - - fclose(file); - - for (x = 0; *lines[x]; x++) { - char device_id[256]; - sscanf(lines[x], "%s %s", cookie, device_id); - if (dev_id[0]) { - if (strcmp(device_id, dev_id) == 0) - return cookie; - } else { - if (strcmp(cookie, mp) == 0) - return cookie; - } - } - - if (ioctl_ok) { - struct gfs_ioctl gi; - char *argv[] = { "get_cookie" }; - int fd; - - gi.gi_argc = 1; - gi.gi_argv = argv; - gi.gi_data = cookie; - gi.gi_size = 256; - - fd = open(mp, O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", - mp, strerror(errno)); - - check_for_gfs(fd, mp); - - if (ioctl(fd, GFS_IOCTL_SUPER, &gi) < 0) - die("can't get cookie for %s: %s\n", - mp, strerror(errno)); - - close(fd); - - return cookie; - } - - die("unknown mountpoint %s\n", mp); -} - -/** - * name2value - find the value of a name-value pair in a string - * @str_in: - * @name: - * - * Returns: the value string in a static buffer - */ - -char * -name2value(char *str_in, char *name) -{ - char str[strlen(str_in) + 1]; - static char value[256]; - char **lines; - unsigned int x; - unsigned int len = strlen(name); - - strcpy(str, str_in); - value[0] = 0; - - lines = str2lines(str); - - for (x = 0; *lines[x]; x++) - if (memcmp(lines[x], name, len) == 0 && - lines[x][len] == ' ') { - strcpy(value, lines[x] + len + 1); - break; - } - - free(lines); - - return value; -} - -/** - * name2u32 - find the value of a name-value pair in a string - * @str_in: - * @name: - * - * Returns: the value uint32 - */ - -uint32_t -name2u32(char *str, char *name) -{ - char *value = name2value(str, name); - uint32_t x = 0; - - sscanf(value, "%u", &x); - - return x; -} - -/** - * name2u64 - find the value of a name-value pair in a string - * @str_in: - * @name: - * - * Returns: the value uint64 - */ - -uint64_t -name2u64(char *str, char *name) -{ - char *value = name2value(str, name); - uint64_t x = 0; - - sscanf(value, "%"SCNu64, &x); - - return x; -} diff --git a/gfs/include/global.h b/gfs/include/global.h deleted file mode 100644 index ef4a204..0000000 --- a/gfs/include/global.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GLOBAL_DOT_H__ -#define __GLOBAL_DOT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(__KERNEL__) || defined(_KERNEL) -#error "don't use global.h in kernel space" -#endif - - - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - - - -#include <inttypes.h> - -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; - - - -#ifdef __cplusplus -} -#endif - -#endif /* __GLOBAL_H__ */ diff --git a/gfs/include/linux_endian.h b/gfs/include/linux_endian.h deleted file mode 100644 index 8054673..0000000 --- a/gfs/include/linux_endian.h +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __LINUX_ENDIAN_DOT_H__ -#define __LINUX_ENDIAN_DOT_H__ - - -#include <endian.h> -#include <byteswap.h> - - -/* I'm not sure which versions of alpha glibc/gcc are broken, - so fix all of them. */ -#ifdef __alpha__ -#undef bswap_64 -static __inline__ unsigned long bswap_64(unsigned long x) -{ - unsigned int h = x >> 32; - unsigned int l = x; - - h = bswap_32(h); - l = bswap_32(l); - - return ((unsigned long)l << 32) | h; -} -#endif /* __alpha__ */ - - -#if __BYTE_ORDER == __BIG_ENDIAN - -#define be16_to_cpu(x) (x) -#define be32_to_cpu(x) (x) -#define be64_to_cpu(x) (x) - -#define cpu_to_be16(x) (x) -#define cpu_to_be32(x) (x) -#define cpu_to_be64(x) (x) - -#define le16_to_cpu(x) (bswap_16((x))) -#define le32_to_cpu(x) (bswap_32((x))) -#define le64_to_cpu(x) (bswap_64((x))) - -#define cpu_to_le16(x) (bswap_16((x))) -#define cpu_to_le32(x) (bswap_32((x))) -#define cpu_to_le64(x) (bswap_64((x))) - -#endif /* __BYTE_ORDER == __BIG_ENDIAN */ - - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -#define be16_to_cpu(x) (bswap_16((x))) -#define be32_to_cpu(x) (bswap_32((x))) -#define be64_to_cpu(x) (bswap_64((x))) - -#define cpu_to_be16(x) (bswap_16((x))) -#define cpu_to_be32(x) (bswap_32((x))) -#define cpu_to_be64(x) (bswap_64((x))) - -#define le16_to_cpu(x) (x) -#define le32_to_cpu(x) (x) -#define le64_to_cpu(x) (x) - -#define cpu_to_le16(x) (x) -#define cpu_to_le32(x) (x) -#define cpu_to_le64(x) (x) - -#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ - - -#endif /* __LINUX_ENDIAN_DOT_H__ */ diff --git a/gfs/include/osi_list.h b/gfs/include/osi_list.h deleted file mode 100644 index 6e525b1..0000000 --- a/gfs/include/osi_list.h +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OSI_LIST_DOT_H__ -#define __OSI_LIST_DOT_H__ - - - -struct osi_list -{ - struct osi_list *next, *prev; -}; -typedef struct osi_list osi_list_t; - - - -#define osi_list_decl(var) osi_list_t var = { &var, &var } - -#define osi_list_empty(var) ((var)->next == (var)) -#define osi_list_entry(var, type, mem) ((type *)((unsigned long)(var) - (unsigned long)(&((type *)NULL)->mem))) - - - -#define osi_list_init(head) \ -do \ -{ \ - osi_list_t *osi_list_var = (head); \ - osi_list_var->next = osi_list_var->prev = osi_list_var; \ -} \ -while (0) - -#define osi_list_add(new, head) \ -do \ -{ \ - osi_list_t *osi_list_var_new = (new); \ - osi_list_t *osi_list_var_head = (head); \ - osi_list_var_new->next = osi_list_var_head->next; \ - osi_list_var_new->prev = osi_list_var_head; \ - osi_list_var_head->next->prev = osi_list_var_new; \ - osi_list_var_head->next = osi_list_var_new; \ -} \ -while (0) - -#define osi_list_add_next osi_list_add - -#define osi_list_add_prev(new, head) \ -do \ -{ \ - osi_list_t *osi_list_var_new = (new); \ - osi_list_t *osi_list_var_head = (head); \ - osi_list_var_new->prev = osi_list_var_head->prev; \ - osi_list_var_new->next = osi_list_var_head; \ - osi_list_var_head->prev->next = osi_list_var_new; \ - osi_list_var_head->prev = osi_list_var_new; \ -} \ -while (0) - -#define osi_list_del(var) \ -do \ -{ \ - osi_list_t *osi_list_var = (var); \ - osi_list_var->next->prev = osi_list_var->prev; \ - osi_list_var->prev->next = osi_list_var->next; \ -} \ -while (0) - -#define osi_list_del_init(var) \ -do \ -{ \ - osi_list_t *osi_list_var = (var); \ - osi_list_var->next->prev = osi_list_var->prev; \ - osi_list_var->prev->next = osi_list_var->next; \ - osi_list_var->next = osi_list_var->prev = osi_list_var; \ -} \ -while (0) - -#define osi_list_foreach(tmp, head) \ - for ((tmp) = (head)->next; (tmp) != (head); (tmp) = (tmp)->next) - -#define osi_list_foreach_safe(tmp, head, x) \ - for ((tmp) = (head)->next, (x) = (tmp)->next; \ - (tmp) != (head); \ - (tmp) = (x), (x) = (x)->next) - - - -#endif /* __OSI_LIST_DOT_H__ */ diff --git a/gfs/include/osi_user.h b/gfs/include/osi_user.h deleted file mode 100644 index 29c9ad2..0000000 --- a/gfs/include/osi_user.h +++ /dev/null @@ -1,434 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OSI_USER_DOT_H__ -#define __OSI_USER_DOT_H__ - -/* Include Files - These should only be the ones necessary to compile the common code. */ - -#include <stdlib.h> -#include <stdio.h> -#include <sys/time.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <time.h> -#include <sys/ioctl.h> - -#include "global.h" -#include "osi_list.h" - - - -/* Memory allocation abstraction */ - -static __inline__ void *osi_malloc(unsigned int size) -{ - return malloc(size); -} - -static __inline__ void osi_free(void *data, unsigned int size) -{ - free(data); -} - - - -/* Memory copy abstraction */ - -#define osi_copy_to_user(uaddr, kaddr, len) (memcpy((uaddr), (kaddr), (len)) ? 0 : -EFAULT) -#define osi_clear_user(uaddr, len) ((memset((uaddr), 0, (len))) ? 0 : -EFAULT) -#define osi_copy_from_user(kaddr, uaddr, len) ((memcpy((kaddr), (uaddr), (len))) ? 0 : -EFAULT) -#define osi_strncpy_from_user(kaddr, uaddr, len) ((strncpy((kaddr), (uaddr), (len))) ? 0 : -EFAULT) - -#define osi_read_access_ok(uaddr, len) (TRUE) -#define osi_write_access_ok(uaddr, len) (TRUE) - -#define osi_memset memset -#define osi_memcpy memcpy -#define osi_memcmp memcmp - -#define osi_strlen strlen -#define osi_strstr strstr -#define osi_strcmp strcmp -#define osi_strncmp strncmp -#define osi_strtok strtok -#define osi_strchr strchr -#define osi_strcpy strcpy -#define osi_strncpy strncpy -#define osi_strcasecmp strcasecmp -#define osi_strtod strtod -#define osi_strtol strtol - - - -/* printf() abstraction */ - -#define osi_printf printf -#define osi_sprintf sprintf -#define osi_snprintf snprintf -#define osi_vsnprintf vsnprintf - -#define osi_sscanf sscanf - -#define osi_fprintf fprintf - -#define osi_tty_printf printf - - - -/* panic abstractions */ - -#define panic(fmt, args...) \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ## args); \ - exit(-1); \ -} - -#define osi_panic panic -#define osi_bug(x) \ -{ \ - fprintf(stderr, "%s: BUG: %s\n", prog_name, (x)); \ - exit(-1); \ -} - - - -/* GFS to VFS abstraction */ - -typedef int osi_vfs_t; -typedef int osi_vnode_t; -typedef int osi_vfile_t; - -#define vf2vn(vfile) ((osi_vnode_t *)(vfile)) -#define vn2vfs(vnode) ((osi_vfs_t *)(vnode)) - - - -/* I/O abstraction */ - -struct buffer_head -{ - unsigned long b_blocknr; - unsigned long b_size; - unsigned long b_state; - char *b_data; - char *b_pdata; - osi_list_t b_list; -}; -typedef struct buffer_head osi_buf_t; - - - -/* Device type abstraction */ - -typedef unsigned short osi_dev_t; - -#define osi_make_dev MKDEV -#define osi_u2k_dev -#define osi_k2u_dev - - - -/* Atomic Bit Manipulation interface */ - -struct osi_bitfield -{ - unsigned long bitfield; -}; -typedef struct osi_bitfield osi_bitfield_t; - -#define osi_test_bit(nr, addr) ((addr)->bitfield & (1 << nr)) -#define osi_set_bit(nr, addr) ((addr)->bitfield |= (1 << nr)) -#define osi_clear_bit(nr, addr) ((addr)->bitfield &= ~(1 << nr)) -#define osi_test_and_set_bit(nr, addr) ((addr)->bitfield |= (1 << nr)) -#define osi_test_and_clear_bit(nr, addr) ((addr)->bitfield &= ~(1 << nr)) - - - -/* Atomic Counter Interface */ - -struct osi_atomic -{ - int atomic; -}; -typedef struct osi_atomic osi_atomic_t; - -#define osi_atomic_inc(x) ((x)->atomic += 1) -#define osi_atomic_dec(x) ((x)->atomic -= 1) -#define osi_atomic_read(x) ((x)->atomic) -#define osi_atomic_dec_and_test(x) ((x)->atomic -= 1) -#define osi_atomic_set(x, y) ((x)->atomic = (y)) - - - -/* Endianness conversion abstraction */ - -#include "linux_endian.h" - - - -/* Filename structure */ - -struct osi_filename -{ - unsigned char *name; - unsigned int len; -}; -typedef struct osi_filename osi_filename_t; - - - -/* Sleeping mutual exclusion primitive abstraction - - All macros take a pointer to a osi_mutex_t structure. - osi_mutex_down_try() returns TRUE if the down() succeeds - */ - -typedef int osi_mutex_t; - -#define osi_mutex_init(x) -#define osi_mutex_init_lkd(x) - -#define osi_mutex_lock(x) -#define osi_mutex_lock_intr(x) -#define osi_mutex_trylock(x) (TRUE) -#define osi_mutex_unlock(x) - - - -/* Reader/writer Sleeping mutual exclusion primitive abstraction */ - -typedef int osi_mutex_rw_t; - -#define osi_mutex_rw_init(x) - -#define osi_mutex_read_lock(x) -#define osi_mutex_write_lock(x) -#define osi_mutex_read_trylock(x) (0) -#define osi_mutex_write_trylock(x) (0) -#define osi_mutex_read_unlock(x) -#define osi_mutex_write_unlock(x) - - - -/* Spinlock abstraction */ - -typedef int osi_spin_t; - -#define osi_spin_init(lock) - -#define osi_spin_lock(lock) -#define osi_spin_unlock(lock) -#define osi_spin_trylock(lock) (TRUE) - - - -/* RW-Spinlock abstraction */ - -typedef int osi_spin_rw_t; - -#define osi_spin_rw_init(lock) - -#define osi_spin_read_lock(lock) -#define osi_spin_write_lock(lock) -#define osi_spin_read_unlock(lock) -#define osi_spin_write_unlock(lock) -#define osi_spin_write_trylock(lock) (TRUE) - - - -/* Process abstraction */ - -#define osi_pid() 1 -#define osi_pname() ("main") - -typedef int osi_task_t; - -#define osi_task_is_set(taskp) (*(taskp)) -#define osi_task_is_me(taskp) (TRUE) -#define osi_task_is_equal(task1p, task2p) (TRUE) -#define osi_task_to_pid(taskp) (1) -#define osi_task_to_pname(taskp) ("main") - -#define osi_task_clear(taskp) do { *(taskp) = 0; } while (0) -#define osi_task_remember_me(taskp) do { *(taskp) = 1; } while (0) -#define osi_task_sleep(taskp, x) do { } while (0) -#define osi_task_wakeup(taskp) do { } while (0) - - - -/* Kernel Thead code */ - -#define osi_daemonize(thread_name) -#define osi_undaemonize() - - - -/* Time abstraction */ - -#define osi_current_time() time(NULL) - -static __inline__ uint64 osi_gettimeofday(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (uint64)tv.tv_sec * 1000000 + tv.tv_usec; -} - -struct osi_clock_ticks -{ - unsigned long value; -}; -typedef struct osi_clock_ticks osi_clock_ticks_t; - -static __inline__ void osi_time_stamp(osi_clock_ticks_t *stamp) -{ -} - -static __inline__ int osi_check_timeout(osi_clock_ticks_t *stamp, int seconds) -{ - return 0; -} - -static __inline__ unsigned int osi_time_diff(osi_clock_ticks_t *stamp) -{ - return FALSE; -} - -static __inline__ int osi_time_valid(osi_clock_ticks_t *stamp) -{ - return FALSE; -} - - - -/* Timer abstraction */ - - -typedef int osi_timer_t; -typedef void (osi_timer_func)(void *); -typedef void (linux_timer_func)(unsigned long); - -static __inline__ void osi_init_timer(osi_timer_t *t, osi_timer_func *fp, void *data) -{ -} - -static __inline__ void osi_del_timer(osi_timer_t *t) -{ -} - -static __inline__ void osi_set_timer(osi_timer_t *t, unsigned long sec) -{ -} - -static __inline__ void osi_set_deci_timer(osi_timer_t *t, unsigned long dsec) -{ -} - -static __inline__ int osi_timer_pending(osi_timer_t *t) -{ - return -ENOSYS; -} - - - -/* Schedule abstraction - Macro that makes a process temporarily - give up control of the processor and lets other processes have - a change to run. - Sleep abstraction - Sleep for x number of sections. */ - -#define osi_schedule() -#define osi_sleep(x) -#define osi_sleep_intr(x) - - - -/* Wait queue abstraction */ - -typedef int osi_wchan_t; - -#define osi_wchan_init(x) do { } while (0) -#define osi_wchan_cond_sleep(chan, sleep_cond) do { } while (0) -#define osi_wchan_cond_sleep_intr(chan, sleep_cond) do { } while (0) -#define osi_wchan_wakeup(x) do { } while (0) - - - -/* Completion events */ - -struct osi_completion -{ -}; -typedef struct osi_completion osi_completion_t; - -#define osi_completion_init(x) do { } while (0) - -#define osi_wait_for_completion(x) do { } while (0) -#define osi_complete(x) do { } while (0) - - - -/* Credentials structure */ - -struct osi_cred -{ - uint32 cr_uid; - uint32 cr_gid; -}; -typedef struct osi_cred osi_cred_t; - -#define osi_cred_to_uid(credp) ((credp) ? (credp)->cr_uid : 0) -#define osi_cred_to_gid(credp) ((credp) ? (credp)->cr_gid : 0) -#define osi_cred_in_group(credp, gid) ((credp) ? ((cred)->cr_gid == (gid)) : FALSE) - - - -/* Signals abstraction */ - -#define osi_pending_signals() FALSE - - - -/* Weird errnos */ - -#define ERESTARTSYS EINTR - - - -/* Module stuff */ - -typedef int osi_module_t; - -#define osi_module_this (NULL) - -#define osi_module_init(mod) do { } while (0) -#define osi_module_inc(mod) do { } while (0) -#define osi_module_inc_cond(mod) (FALSE) -#define osi_module_dec(mod) do { } while (0) -#define osi_module_busy(mod) (TRUE) - - - -/* Other Stuff */ - -extern char *prog_name; - -#define OSI_CACHE_ALIGNED - - - -#endif /* __OSI_USER_DOT_H__ */ - diff --git a/gfs/init.d/Makefile b/gfs/init.d/Makefile deleted file mode 100644 index 6635487..0000000 --- a/gfs/init.d/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= gfs - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -copytobin: - -clean: - -install: - install -d ${DESTDIR}/etc/init.d - install ${TARGET} ${DESTDIR}/etc/init.d - -uninstall: - ${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d diff --git a/gfs/init.d/gfs b/gfs/init.d/gfs deleted file mode 100755 index 41839cb..0000000 --- a/gfs/init.d/gfs +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# -# -# -# chkconfig: 345 26 74 -# description: mount/unmount gfs filesystems configured in /etc/fstab -# -# -### BEGIN INIT INFO -# Provides: -### END INIT INFO - -. /etc/init.d/functions -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - -# -# This script's behavior is modeled closely after the netfs script. -# -GFSFSTAB=$(LC_ALL=C awk '!/^#/ && $3 ~ /^gfs/ && $4 !~ /noauto/ { print $2 }' /etc/fstab) -GFSMTAB=$(LC_ALL=C awk '!/^#/ && $3 ~ /^gfs/ && $2 != "/" { print $2 }' /proc/mounts) - -# See how we were called. -case "$1" in - start) - if [ -n "$GFSFSTAB" ] - then - #load_module lock_harness MODULE_LOCK_HARNESS - #load_module crc32 MODULE_CRC32 - #load_module lock_gulm MODULE_LOCK_GULM - #load_module gfs MODULE_GFS - - action $"Mounting GFS filesystems: " mount -a -t gfs - fi - touch /var/lock/subsys/gfs - ;; - - stop) - if [ -n "$GFSMTAB" ] - then - sig= - retry=6 - remaining=`LC_ALL=C awk '!/^#/ && $3 ~ /^gfs/ && $2 != "/" {print $2}' /proc/mounts` - while [ -n "$remaining" -a "$retry" -gt 0 ] - do - action $"Unmounting GFS filesystems: " umount -a -t gfs - - if [ $retry -eq 0 ] - then - action $"Unmounting GFS filesystems (lazy): " umount -l -a -t gfs - break - fi - - sleep 2 - remaining=`LC_ALL=C awk '!/^#/ && $3 ~ /^gfs/ && $2 != "/" {print $2}' /proc/mounts` - [ -z "$remaining" ] && break - /sbin/fuser -k -m $sig $remaining >/dev/null - sleep 10 - retry=$(($retry - 1)) - sig=-9 - done - fi - - modprobe -r gfs - modprobe -r lock_gulm - modprobe -r lock_dlm - rm -f /var/lock/subsys/gfs - ;; - - status) - if [ -f /proc/mounts ] - then - [ -n "$GFSFSTAB" ] && { - echo $"Configured GFS mountpoints: " - for fs in $GFSFSTAB; do echo $fs ; done - } - [ -n "$GFSMTAB" ] && { - echo $"Active GFS mountpoints: " - for fs in $GFSMTAB; do echo $fs ; done - } - else - echo "/proc filesystem unavailable" - fi - ;; - - restart) - $0 stop - $0 start - ;; - - reload) - $0 start - ;; - *) - echo $"Usage: $0 {start|stop|restart|reload|status}" - exit 1 -esac - -exit 0 diff --git a/gfs/make/defines.mk.input b/gfs/make/defines.mk.input deleted file mode 100644 index 289f33f..0000000 --- a/gfs/make/defines.mk.input +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/gfs/make/flags.mk b/gfs/make/flags.mk deleted file mode 100644 index 1338351..0000000 --- a/gfs/make/flags.mk +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - diff --git a/gfs/make/release.mk.input b/gfs/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/gfs/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/gfs/man/Makefile b/gfs/man/Makefile deleted file mode 100644 index 9a26a81..0000000 --- a/gfs/man/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET8= \ - gfs.8 \ - gfs_mount.8 \ - gfs_fsck.8 \ - gfs_grow.8 \ - gfs_jadd.8 \ - gfs_mkfs.8 \ - gfs_quota.8 \ - gfs_tool.8 - - -top_srcdir = .. - -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk - -install: - install -d ${mandir}/man8 - install ${TARGET8} ${mandir}/man8 - -uninstall: - ${UNINSTALL} ${TARGET8} ${mandir}/man8 diff --git a/gfs/man/gfs.8 b/gfs/man/gfs.8 deleted file mode 100644 index af05285..0000000 --- a/gfs/man/gfs.8 +++ /dev/null @@ -1,40 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs 8 - -.SH NAME -GFS reference guide - -.SH SYNOPSIS -Overview of manpages and their locations - -.SH DESCRIPTION -The GFS documentation has been split into a number of sections. Please -refer to the table below to determine which man page coincides with the -command/feature you are looking for. -.TP 16 -gfs -GFS overview (this man page) -.TP -gfs_mount -Mounting a GFS file system -.TP -gfs_fsck -The GFS file system checker -.TP -gfs_grow -Growing a GFS file system -.TP -gfs_jadd -Adding a journal to a GFS file system -.TP -gfs_mkfs -Make a GFS file system -.TP -gfs_quota -Manipulate GFS disk quotas -.TP -gfs_tool -Tool to manipulate a GFS file system - diff --git a/gfs/man/gfs_fsck.8 b/gfs/man/gfs_fsck.8 deleted file mode 100644 index 9b4dede..0000000 --- a/gfs/man/gfs_fsck.8 +++ /dev/null @@ -1,62 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs_fsck 8 - -.SH NAME -gfs_fsck - Offline GFS file system checker - -.SH SYNOPSIS -.B gfs_fsck -[\fIOPTION\fR]... \fIDEVICE\fR - -.SH WARNING -All GFS nodes \fImust\fP have the GFS filesystem unmounted before running -gfs_fsck. Failure to unmount all nodes may result in filesystem corruption. - -.SH DESCRIPTION -gfs_fsck will check that the GFS file system on a device is structurally valid. -It should not be run on a mounted file system. If file system corruption is -detected, it will attempt to repair the file system. There is a limit to what -gfs_fsck can do. If important file system structures are destroyed, such that -the checker can not determine what the repairs should be, reparations could -fail. - -GFS is a journaled file system, and as such should be able to repair damages to -the file system on its own. However, faulty hardware has the ability to write -incomplete blocks to a file system thereby causing corruption that GFS can not -fix. The first step to ensuring a healthy file system is the selection of -reliable hardware (i.e. storage systems that will write complete blocks - even -in the event of power failure). - -.SH OPTIONS -.TP -\fB-h\fP -Help. - -This prints out the proper command line usage syntax. -.TP -\fB-n\fP -No to all questions. - -By specifying this option, gfs_fsck will only show the changes that -would be made, not make any changes to the filesystem. -.TP -\fB-q\fP -Quiet. -.TP -\fB-V\fP -Version. - -Print out the current version name. -.TP -\fB-v\fP -Verbose operation. - -Print more information while running. -.TP -\fB-y\fP -Yes to all questions. - -By specifying this option, gfs_fsck will not prompt before making -changes. diff --git a/gfs/man/gfs_grow.8 b/gfs/man/gfs_grow.8 deleted file mode 100644 index 8f1749f..0000000 --- a/gfs/man/gfs_grow.8 +++ /dev/null @@ -1,66 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs_grow 8 - -.SH NAME -gfs_grow - Expand a GFS filesystem - -.SH SYNOPSIS -.B gfs_grow -[\fIOPTION\fR]... <\fIDEVICE\fR|\fIMOINTPOINT\fR>... - -.SH DESCRIPTION -gfs_grow is used to expand a GFS filesystem after the device -upon which the filesystem resides has also been expanded. By -running gfs_grow on a GFS filesystem, you are requesting that -any spare space between the current end of the filesystem and -the end of the device is filled with a newly initialized GFS -filesystem extension. When this operation is complete, the resource -index for the filesystem is updated so that all nodes in the -cluster can use the extra storage space which has been added. - -You may only run gfs_grow on a mounted filesystem; expansion of -unmounted filesystems is not supported. You only need to -run gfs_grow on one node in the cluster. All the other nodes will -see the expansion has occurred and automatically start to use the -newly available space. - -You must be superuser to execute \fBgfs_grow\fP. The gfs_grow -tool tries to prevent you from corrupting your filesystem by checking as -many of the likely problems as it can. When expanding a filesystem, -only the last step of updating the resource index affects the currently -mounted filesystem and so failure part way through the expansion process -should leave your filesystem in its original unexpanded state. - -You can run gfs_grow with the \fB-Tv\fP flags to get a display -of the current state of a mounted GFS filesystem. This can be useful -to do after the expansion process to see if the changes have been -successful. - -\fBgfs_grow\fP will consume all the remaining space in a device and add -it to the filesystem. If you want to add journals too, you need to add -the journals first using \fBgfs_jadd\fP. - -.SH OPTIONS -.TP -\fB-h\fP -Prints out a short usage message and exits. -.TP -\fB-q\fP -Quiet. Turns down the verbosity level. -.TP -\fB-T\fP -Test. Do all calculations, but do not write any data to the disk and do -not expand the filesystem. This is used to discover what the tool would -have done were it run without this flag. You probably want to turn the -verbosity level up in order to gain most information from this option. -.TP -\fB-V\fP -Version. Print out version information, then exit. -.TP -\fB-v\fP -Verbose. Turn up verbosity of messages. - -.SH SEE ALSO -gfs_mkfs(8) gfs_jadd(8) diff --git a/gfs/man/gfs_jadd.8 b/gfs/man/gfs_jadd.8 deleted file mode 100644 index 1a3cf4b..0000000 --- a/gfs/man/gfs_jadd.8 +++ /dev/null @@ -1,78 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs_jadd 8 - -.SH NAME -gfs_jadd - Add journals to a GFS filesystem - -.SH SYNOPSIS -.B gfs_jadd -[\fIOPTION\fR]... <\fIDEVICE\fR|\fIMOINTPOINT\fR>... - -.SH DESCRIPTION -\fIgfs_jadd\fR is used to add journals to a GFS filesystem after -the device upon which the filesystem resides has been grown. -By running \fIgfs_jadd\fR -on a GFS filesystem, you are filling in space between the current end -of the filesystem and the end of the device upon which the filesystem -resides. When this operation -is complete, the journal index is updated so that machines mounting the -filesystem at a later date will see the newly created journals in -addition to the journals already there. Machines which are already running -in the cluster are unaffected. - -\fIgfs_jadd\fR will not use space that has been formatted for filesystem data even if that space has never been populated with files. - -You may only run \fIgfs_jadd\fR on a mounted filesystem, addition of journals to -unmounted filesystems is not supported. -You only need to run \fIgfs_jadd\fR -on one node in the cluster. All the other nodes will see the expansion -has occurred when required. - -You must be superuser to execute \fIgfs_jadd\fR. The -\fIgfs_jadd\fR -tool tries to prevent you from corrupting your filesystem by checking as -many of the likely problems as it can. When growing a filesystem, -only the last step of updating the journal index affects the currently -mounted filesystem and so failure part way through the expansion process -should leave your filesystem in its original state. - -You can run \fIgfs_jadd\fR with the \fI-Tv\fR -flags to get a display of the current state of a mounted GFS filesystem. -This can be useful to do after the journal addition process to see if the -changes have been successful. - -.SH OPTIONS -.TP -\fB-j num\fP -The number of new journals to add. This defaults to 1. -.TP -\fB-J size\fP -The size of the new journals in megabytes. The defaults to 128MB (the -minimum size allowed is 32MB). If you want to add journals of different -sizes to the filesystem, you'll need to run gfs_jadd once for each -different size of journal. The size you specify here will be rounded -down so that it is a multiple of the journal segment size which was -specified at filesystem creation time. -.TP -\fB-h\fP -Help. Prints out a short usage message and exits. -.TP -\fB-q\fP -Quiet. Turns down the verbosity level. -.TP -\fB-T\fP -Test. Do all calculations, but do not write any data to the disk and do -not add journals. This is used to discover what the tool would -have done were it run without this flag. You probably want to turn the -verbosity level up in order to gain most information from this option. -.TP -\fB-V\fP -Version. Print version information, then exit. -.TP -\fB-v\fP -Verbose. Turn up verbosity of messages. - -.SP SEE ALSO -gfs_mkfs(8) gfs_grow(8) diff --git a/gfs/man/gfs_mkfs.8 b/gfs/man/gfs_mkfs.8 deleted file mode 100644 index 0ec4820..0000000 --- a/gfs/man/gfs_mkfs.8 +++ /dev/null @@ -1,87 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs_mkfs 8 - -.SH NAME -gfs_mkfs - Make a GFS filesystem - -.SH SYNOPSIS -.B gfs_mkfs -[\fIOPTION\fR]... \fIDEVICE\fR - -.SH DESCRIPTION -gfs_mkfs is used to create a Global File System. - -.SH OPTIONS -.TP -\fB-b\fP \fIBlockSize\fR -Set the filesystem block size to \fIBlockSize\fR (must be a power of -two). The minimum block size is 512. The FS block size cannot exceed -the machine's memory page size. On the most architectures (i386, -x86_64, s390, s390x), the memory page size is 4096 bytes. On other -architectures it may be bigger. The default block size is 4096 bytes. -In general, GFS filesystems should not deviate from the default value. -.TP -\fB-D\fP -Enable debugging output. -.TP -\fB-h\fP -Print out a help message describing available -options, then exit. -.TP -\fB-J\fP \fIMegaBytes\fR -The size of the journals in Megabytes. The default journal size is -128 megabytes. The minimum size is 32 megabytes. -.TP -\fB-j\fP \fINumber\fR -The number of journals for gfs_mkfs to create. You need at least one -journal per machine that will mount the filesystem. -.TP -\fB-O\fP -This option prevents gfs_mkfs from asking for confirmation before writing -the filesystem. -.TP -\fB-p\fP \fILockProtoName\fR -LockProtoName is the name of the locking protocol to use. Acceptable -locking protocols are \fIlock_dlm\fR, \fIlock_gulm\fR or if you are using GFS -as a local filesystem (\fB1 node only\fP), you can specify the -\fIlock_nolock\fR protocol. -.TP -\fB-q\fP -Be quiet. Don't print anything. -.TP -\fB-r\fP \fIMegaBytes\fR -gfs_mkfs will try to make Resource Groups about this big. -The default is 256 MB. -.TP -\fB-s\fP \fIBlocks\fR -Journal segment size in filesystem blocks. This value must be at -least two and not large enough to produce a segment size greater than -4MB. -.TP -\fB-t\fP \fILockTableName\fR -The lock table field appropriate to the lock module you're using. -It is \fIclustername:fsname\fR. -Clustername must match that in cluster.conf; only members of this -cluster are permitted to use this file system. -Fsname is a unique file system name used to distinguish this GFS file -system from others created (1 to 16 characters). Lock_nolock doesn't -use this field. -.TP -\fB-V\fP -Print program version information, then exit. - -.SH EXAMPLE -.TP -gfs_mkfs -t mycluster:mygfs -p lock_dlm -j 2 /dev/vg0/mygfs -This will make a Global File System on the block device -"/dev/vg0/mygfs". It will belong to "mycluster" and register itself -as wanting locking for "mygfs". It will use DLM for locking and make -two journals. -.TP -gfs_mkfs -t mycluster:mygfs -p lock_gulm -j 2 /dev/vg0/mygfs -This will make a Global File System on the block device -"/dev/vg0/mygfs". It will belong to "mycluster" and register itself -as wanting locking for "mygfs". It will use GULM for locking and make -two journals. diff --git a/gfs/man/gfs_mount.8 b/gfs/man/gfs_mount.8 deleted file mode 100644 index faf5d83..0000000 --- a/gfs/man/gfs_mount.8 +++ /dev/null @@ -1,214 +0,0 @@ -." Portions copyright (c) 2001-2003 The OpenGFS Project -." Portions copyright (c) 2004 ben.m.cahill@intel.com -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. - -.TH gfs_mount 8 - -.SH NAME -gfs_mount - GFS mount options - -.SH SYNOPSIS -.B mount -[\fIStandardMountOptions\fR] \fB-t\fP gfs \fIDEVICE\fR \fIMOUNTPOINT\fR \fB-o\fP [GFSOption1,GFSOption2,GFSOptionX...] - -.SH DESCRIPTION -GFS may be used as a local (single computer) filesystem, but its real purpose -is in clusters, where multiple computers (nodes) share a common storage device. - -Above is the format typically used to mount a GFS filesystem, using the -\fBmount\fP(8) command. The \fIdevice\fR may be any block device on which you -have created a GFS filesystem. Examples include a -single disk partition (e.g. /dev/sdb3), a loopback device, a device exported -from another node (e.g. an iSCSI device or a \fBgnbd\fP(8) device), or a -logical volume (typically comprised of a number of individual disks). - -\fIdevice\fR does not necessarily need to match the device name as seen on -another node in the cluster, nor does it need to be a logical volume. However, -the use of a cluster-aware volume manager such as CLVM2 (see \fBlvm\fP(8)) -will guarantee that the managed devices are named identically on each node in a -cluster (for much easier management), and will allow you to configure a very -large volume from multiple storage units (e.g. disk drives). - -\fIdevice\fR must make the entire filesystem storage area visible to the -computer. That is, you cannot mount different parts of a single filesystem on -different computers. Each computer must see an entire filesystem. You -may, however, mount several GFS filesystems if you want to distribute your -data storage in a controllable way. - -\fImountpoint\fR is the same as \fIdir\fR in the \fBmount\fP(8) man page. - -This man page describes GFS-specific options that can be passed to the GFS -file system at mount time, using the \fB-o\fP flag. There are many other -\fB-o\fP options handled by the generic mount command \fBmount\fP(8). -However, the options described below are specifically for GFS, and are not -interpreted by the mount command nor by the kernel's Virtual File System. GFS -and non-GFS options may be intermingled after the \fB-o\fP, separated by -commas (but no spaces). - -As an alternative to mount command line options, you may send mount -options to gfs using "gfs_tool margs" (after loading the gfs kernel -module, but before mounting GFS). For example, you may need to do -this when working from an initial ramdisk \fBinitrd\fP(4). The -options are restricted to the ones described on this man page (no -general \fBmount\fP(8) options will be recognized), must not be -preceded by -o, and must be separated by commas (no spaces). Example: - -# gfs_tool margs "lockproto=lock_nolock,ignore_local_fs" - -Options loaded via "gfs_tool margs" have a lifetime of only one GFS -mount. If you wish to mount another GFS filesystem, you must set -another group of options with "gfs_tool margs". - -If you have trouble mounting GFS, check the syslog (e.g. /var/log/messages) -for specific error messages. - -.SH OPTIONS -.TP -\fBlockproto=\fP\fILockModuleName\fR -This specifies which inter-node lock protocol is used by the GFS filesystem -for this mount, overriding the default lock protocol name stored in the -filesystem's on-disk superblock. - -The \fILockModuleName\fR must be an exact match of the protocol name presented -by the lock module when it registers with the lock harness. Traditionally, -this matches the .o filename of the lock module, e.g. \fIlock_dlm\fR, -\fIlock_gulm\fR, or \fIlock_nolock\fR. - -The default lock protocol name is written to disk initially when creating the -filesystem with \fBgfs_mkfs\fP(8), -p option. It can be changed on-disk by -using the \fBgfs_tool\fP(8) utility's \fBsb proto\fP command. - -The \fBlockproto\fP mount option should be used only under special -circumstances in which you want to temporarily use a different lock protocol -without changing the on-disk default. -.TP -\fBlocktable=\fP\fILockTableName\fR -This specifies the identity of the cluster and of the filesystem for this -mount, overriding the default cluster/filesystem identify stored in the -filesystem's on-disk superblock. The cluster/filesystem name is recognized -globally throughout the cluster, and establishes a unique namespace for -the inter-node locking system, enabling the mounting of multiple GFS -filesystems. - -The format of \fILockTableName\fR is lock-module-specific. For lock_gulm -and lock_dlm, the format is \fIclustername:fsname\fR. For -lock_nolock, the field is ignored. - -The default cluster/filesystem name is written to disk initially when creating -the filesystem with \fBgfs_mkfs\fP(8), -t option. It can be changed on-disk -by using the \fBgfs_tool\fP(8) utility's \fBsb table\fP command. - -The \fBlocktable\fP mount option should be used only under special -circumstances in which you want to mount the filesystem in a different cluster, -or mount it as a different filesystem name, without changing the on-disk -default. -.TP -\fBhostdata=\fP\fIHostIDInfo\fR -This field sends host (the computer on which the filesystem is being mounted) -identity information to the lock module. - -The format and behavior of \fIHostIDInfo\fR is lock-module-specific. -For lock_gulm, it overrides the \fBuname\fP(1) -n network node name -used as default by lock_gulm. - -This field is ignored by \fIlock_dlm\fR and \fIlock_nolock\fR. -.TP -\fBlocalcaching\fP -This flag tells GFS that it is running as a local (not clustered) filesystem, -so it can turn on some block caching optimizations that can't be used when -running in cluster mode. - -This is turned on automatically by the lock_nolock module, -but can be overridden by using the \fBignore_local_fs\fP option. -.TP -\fBlocalflocks\fP -This flag tells GFS that it is running as a local (not clustered) filesystem, -so it can allow the kernel VFS layer to do all flock and fcntl file locking. -When running in cluster mode, these file locks require inter-node locks, -and require the support of GFS. When running locally, better performance -is achieved by letting VFS handle the whole job. - -This is turned on automatically by the lock_nolock module, -but can be overridden by using the \fBignore_local_fs\fP option. -.TP -\fBoopses_ok\fP -Normally, GFS automatically turns on the "kernel.panic_on_oops" -sysctl to cause the machine to panic if an oops (an in-kernel -segfault or GFS assertion failure) happens. An oops on one machine of -a cluster filesystem can cause the filesystem to stall on all machines -in the cluster. (Panics don't have this "feature".) By turning on -"panic_on_oops", GFS tries to make sure the cluster remains in -operation even if one machine has a problem. There are cases, -however, where this behavior is not desireable -- debugging being -the main one. The \fBoopses_ok\fP option causes GFS to leave the -"panic_on_oops" variable alone so oopses can happen. Use this option -with care. - -This is turned on automatically by the lock_nolock module, -but can be overridden by using the \fBignore_local_fs\fP option. -.TP -\fBignore_local_fs\fP -By default, using the nolock lock module automatically turns on the -\fBlocalcaching\fP and \fBlocalflocks\fP optimizations. \fBignore_local_fs\fP -forces GFS to treat the filesystem as if it were a multihost (clustered) -filesystem, with \fBlocalcaching\fP and \fBlocalflocks\fP optimizations -turned off. -.TP -\fBupgrade\fP -This flag tells GFS to upgrade the filesystem's on-disk format to the version -supported by the current GFS software installation on this computer. -If you try to mount an old-version disk image, GFS will notify you via a syslog -message that you need to upgrade. Try mounting again, using the -\fB-o upgrade\fP option. When upgrading, only one node may mount the GFS -filesystem. -.TP -\fBnum_glockd\fP -Tunes GFS to alleviate memory pressure when rapidly aquiring many locks (e.g. -several processes scanning through huge directory trees). GFS' glockd kernel -daemon cleans up memory for no-longer-needed glocks. Multiple instances -of the daemon clean up faster than a single instance. The default value is -one daemon, with a maximum of 32. Since this option was introduced, other -methods of rapid cleanup have been developed within GFS, so this option may go -away in the future. -.TP -\fBacl\fP -Enables POSIX Access Control List \fBacl\fP(5) support within GFS. -.TP -\fBsuiddir\fP -Sets owner of any newly created file or directory to be that of parent -directory, if parent directory has S_ISUID permission attribute bit set. -Sets S_ISUID in any new directory, if its parent directory's S_ISUID is set. -Strips all execution bits on a new file, if parent directory owner is different -from owner of process creating the file. Set this option only if you know -why you are setting it. -.TP -\fBnoquota\fP -Disables quota accounting and quota enforcement during mount. The effect of -using this mount option is identical to mounting gfs without \fB-o noquota\fP -and then invoking \fBgfs_tool settune <mountpoint> quota_account 0\fP. In -order to enable quotas in the future the quota file must be initialized using -\fBgfs_quota init -f <mountpoint>\fP. See \fBgfs_quota\fP(8) - -.SH LINKS -.TP 30 -http://sources.redhat.com/cluster --- home site of GFS -.TP -http://www.suse.de/~agruen/acl/linux-acls/ --- good writeup on ACL support in Linux - -.SH SEE ALSO - -\fBgfs\fP(8), -\fBmount\fP(8) for general mount options, -\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, -\fBacl\fP(5) for access control lists, -\fBlvm\fP(8) for volume management, -\fBccs\fP(7) for cluster management, -\fBlock_gulmd\fP(8), -\fBumount\fP(8), -\fBinitrd\fP(4). - diff --git a/gfs/man/gfs_quota.8 b/gfs/man/gfs_quota.8 deleted file mode 100644 index 5102b30..0000000 --- a/gfs/man/gfs_quota.8 +++ /dev/null @@ -1,104 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs_quota 8 - -.SH NAME -gfs_quota - Manipulate GFS disk quotas - -.SH SYNOPSIS -.B gfs_quota -<list|sync|get|limit|warn|check|init> [\fIOPTION\fR]... - -.SH DESCRIPTION -gfs_quota is used to examine and change quota values in a GFS filesystem. -This command has a number of different actions. - -.SH ACTIONS -.TP -\fBlist\fP -List the contents of the quota file. Only IDs that have a non-zero hard limit, -warn limit, or value are printed. -.TP -\fBsync\fP -Sync any local quota changes to the quota file. -.TP -\fBget\fP -Get the current data for the ID specified by the -u or -g argument. -.TP -\fBlimit\fP -Set the current hard limit for the ID specified by the -u or -g argument to -the value specified by the -l argument on the specified filesystem. -The filesystem won't let the user or group use more than this much space. -A value of zero here means that no limit is enforced. -.TP -\fBwarn\fP -Set the current warn limit for the ID specified by the -u or -g argument to -the value specified by the -l argument on the specified filesystem. -The filesystem will start complaining to the user or group when more -than this much space is used. A value of zero here means that the -user won't ever be warned. -.TP -\fBcheck\fP -Scan a filesystem and make sure that what's out there on the disk matches -what's in the quota file. This is only accurate if the filesystem is -idle when this is running. If there is a mismatch, it is printed to -stdout. Note: GFS quotas are transactional and a quota check is \fBnot\fP -needed every time there is a system crash. -.TP -\fBinit\fP -Scan a filesystem and initialize the quota file with the values obtained -from the scan. The filesystem should be idle when this is run. You should -only need to do this if you upgrade a pre-quota GFS filesystem (pre-GFS 5.1). - -.SH OPTIONS -\fB-b\fP -The units for disk space are filesystem blocks. -.TP -\fB-d\fP -Don't include the space allocated to GFS' hidden files in -what's reported for the root UID and GID values. This is useful -if you're trying to get the numbers reported by gfs_quota to match -up with the numbers reported by du. -.TP -\fB-f\fP \fIDirectory\fR -Specifies which filesystem to perform the action on. -.TP -\fB-g\fP \fIGID\fR -Specifies the group ID for get, limit, or warn. It can be either -the group name from the group file, or the GID number. -.TP -\fB-h\fP -Print out a help message describing available -options, then exit. -.TP -\fB-k\fP -The units for disk space are kilobytes. -.TP -\fB-l\fP \fISize\fR -Specifies the new value for the limit or warn actions. -The value is assumed to be in the units specified by the --m, -k, -s, -b arguments. The default is megabytes. -.TP -\fB-m\fP -The units for disk space are megabytes. This is the default. -.TP -\fB-n\fP -Don't try to resolve UIDs and GIDs into user and group names. -.TP -\fB-s\fP -The units for disk space are sectors (512-byte blocks). -.TP -\fB-u\fP \fIUID\fR -Specifies the user ID for get, limit, or warn. It can be either -the username from the password file, or the UID number. -.TP -\fB-V\fP -Print program version information, then exit. - -.SH EXAMPLE -To set the hard limit for user "nobody" to -1048576 kilobytes on filesystem /gfs0 - -gfs_quota limit -l 1048576 -k -u nobody -f /gfs0 - diff --git a/gfs/man/gfs_tool.8 b/gfs/man/gfs_tool.8 deleted file mode 100644 index 398bfad..0000000 --- a/gfs/man/gfs_tool.8 +++ /dev/null @@ -1,140 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gfs_tool 8 - -.SH NAME -gfs_tool - interface to gfs ioctl calls - -.SH SYNOPSIS -.B gfs_tool -\fICOMMAND\fR [\fIOPTION\fR]... - -.SH DESCRIPTION -gfs_tool is an interface to a variety of the GFS ioctl calls. - -.SH COMMANDS -.TP -\fBclearflag\fP \fIFlag\fR \fIFile1\fR \fIFile2\fR \fI...\fR -Clear an attribute flag on a file. -.TP -\fBcounters\fP \fIMountPoint\fR [-c] -Print out statistics about a filesystem. If -c is used, gfs_tool continues -to run printing out the stats once a second. -.TP -\fBdf\fP \fIMountPoint\fR -Print out a space usage summary of a given filesystem. The information -printed is more detailed than a standard "df". -.TP -\fBfreeze\fP \fIMountPoint\fR -Freeze (quiesce) a GFS cluster. -.TP -\fBgetsb\fP \fIMountPoint\fR -Print out the superblock of a mounted filesystem. -.TP -\fBgettune\fP \fIMountPoint\fR -Print out the current values of the tuning parameters in a running -filesystem. -.TP -\fBjindex\fP \fIMountPoint\fR -Print out the journal index of a mounted filesystem. -.TP -\fBlayout\fP \fIFile\fR \fI[buffersize]\fR -Print out on-disk layout information about a file or directory. -Buffersize is the size of the buffer (in bytes) that gfs_tool allocates -to store the file's metadata during processing. It defaults to 4194304 -bytes. If you are printing a very big directory you may need to specify -a bigger size. -.TP -\fBlist\fP -List the currently mounted GFS filesystems. Each line represents -a filesystem. The columns represent (in order): 1) A number that -is a cookie that represents the mounted filesystem. 2) The name of the -device that holds the filesystem (well, the name as the Linux -kernel knows it). 3) The lock table field that the filesystem was -mounted with. -.TP -\fBlockdump\fP \fIMountPoint\fR \fI[buffersize]\fR -Print out information about the locks this machine holds for a given -filesystem. Buffersize is the size of the buffer (in bytes) that gfs_tool -allocates to store the lock data during processing. It defaults to 4194304 -bytes. -.TP -\fBmargs\fP \fIarguments\fR -This loads arguments into the module what will override the mount -options passed with the -o field on the next mount. See gfs_mount(8). -.TP -\fBreclaim\fP \fIFile\fR -Returns unused on-disk metadata blocks to free blocks. -.TP -\fBrindex\fP \fIMountPoint\fR -Print out the resource group index of a mounted filesystem. -.TP -\fBquota\fP \fIMountPoint\fR -Print out the quota file of a mounted filesystem. Also see -the "gfs_quota list" command. -.TP -\fBsb\fP \fIdevice\fR \fBproto\fP \fI[newvalue]\fR -View (and possibly replace) the name of the locking protocol in the -file system superblock. The file system shouldn't be mounted by any -client when you do this. -.TP -\fBsb\fP \fIdevice\fR \fBtable\fP \fI[newvalue]\fR -View (and possibly replace) the name of the locking table in the -file system superblock. The file system shouldn't be mounted by any -client when you do this. -.TP -\fBsb\fP \fIdevice\fR \fBondisk\fP \fI[newvalue]\fR -View (and possibly replace) the ondisk format number in the -file system superblock. The file system shouldn't be mounted by any -client when you do this. No one should have to use this. -.TP -\fBsb\fP \fIdevice\fR \fBmultihost\fP \fI[newvalue]\fR -View (and possibly replace) the multihost format number in the -file system superblock. The file system shouldn't be mounted by any -client when you do this. No one should have to use this. -.TP -\fBsb\fP \fIdevice\fR \fBall\fP -Print out the superblock. -.TP -\fBsetflag\fP \fIFlag\fR \fIFile1\fR \fIFile2\fR \fI...\fR -Set an attribute flag on a file. There are four currently -supported flags. They are jdata, directio, inherit_jdata, and -inherit_directio. - -The \fIjdata\fR flag causes all the data written to a regular file -to be journaled. The jdata flag can only be set (or cleared) if the file -is zero length. - -The \fIdirectio\fR flag causes all I/O to a regular file to be Direct -I/O, even if the O_DIRECT flag isn't used on the open() command. - -The \fIinherit_jdata\fR flag is set on a directory. It causes all new -regular files created in that directory automatically inherit the -\fIjdata\fR flag. The \fIinherit_jdata\fR is also inherited by any new -subdirectories created in that directory. - -The \fIinherit_directio\fR flag is set on a directory. It causes all new -regular files created in that directory automatically inherit the -\fIdirectio\fR flag. The \fIinherit_directio\fR is also inherited by -any new subdirectories created in that directory. -.TP -\fBsettune\fP \fIMountPoint\fR \fIparameter\fR \fInewvalue\fR -Set the value of tuning parameter. Use \fBgettune\fP for a listing of -tunable parameters. -.TP -\fBshrink\fP \fIMountPoint\fR -Causes any unused inodes to be thrown out of memory. -.TP -\fBstat\fP \fIFile\fR -Print out extended stat information about a file. -.TP -\fBunfreeze\fP \fIMountPoint\fR -Unfreeze a GFS cluster. -.TP -\fBversion\fP -Print out the version of GFS that this program goes with. -.TP -\fBwithdraw\fP \fIMountPoint\fR -Cause GFS to abnormally shutdown a given filesystem on this node. - diff --git a/gfs/scripts/uninstall.pl b/gfs/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/gfs/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/gfs/tests/filecon2/Makefile b/gfs/tests/filecon2/Makefile deleted file mode 100644 index ac1bf3c..0000000 --- a/gfs/tests/filecon2/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -TARGETS=filecon2_server filecon2_client - - - -all: $(TARGETS) - - -filecon2_server: filecon2_server.c - $(CC) -O3 -Wall -o filecon2_server filecon2_server.c -I../../include -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 - -filecon2_client: filecon2_client.c - $(CC) -O3 -Wall -o filecon2_client filecon2_client.c -I../../include -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 - - -clean: - rm -f *.o *.s *.a *~ core .depend $(TARGETS) - diff --git a/gfs/tests/filecon2/filecon2.h b/gfs/tests/filecon2/filecon2.h deleted file mode 100644 index d04684b..0000000 --- a/gfs/tests/filecon2/filecon2.h +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __FILECON2_DOT_H__ -#define __FILECON2_DOT_H__ - - - -/* Extern Macro */ - -#ifndef EXTERN -#define EXTERN extern -#define INIT(X) -#else -#undef EXTERN -#define EXTERN -#define INIT(X) =X -#endif - - - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -#define type_zalloc(ptr, type, count) \ -do \ -{ \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if ((ptr)) \ - memset((char *)(ptr), 0, sizeof(type) * (count)); \ - else \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} \ -while (0) - -#define type_alloc(ptr, type, count) \ -do \ -{ \ - (ptr) = (type *)malloc(sizeof(type) * (count)); \ - if (!(ptr)) \ - die("unable to allocate memory on line %d of file %s\n", \ - __LINE__, __FILE__); \ -} \ -while (0) - -#define do_lseek(fd, off) \ -do \ -{ \ - if (lseek((fd), (off), SEEK_SET) != (off)) \ - die("bad seek: %s on line %d of file %s\n", \ - strerror(errno),__LINE__, __FILE__); \ -} \ -while (0) - -#define do_read(fd, buf, len) \ -do \ -{ \ - int do_read_out; \ - do_read_out = read((fd), (buf), (len)); \ - if (do_read_out != (len)) \ - die("bad read: result = %d (%s) on line %d of file %s\n", \ - do_read_out, strerror(errno), __LINE__, __FILE__); \ -} \ -while (0) - -#define do_write(fd, buf, len) \ -do \ -{ \ - int do_write_out; \ - do_write_out = write((fd), (buf), (len)); \ - if (do_write_out != (len)) \ - die("bad write: result = %d (%s) on line %d of file %s\n", \ - do_write_out, strerror(errno), __LINE__, __FILE__); \ -} \ -while (0) - -#define do_ftruncate(fd, off) \ -do \ -{ \ - if (ftruncate((fd), (off)) < 0) \ - die("bad truncate: %s on line %d of file %s\n", \ - strerror(errno), __LINE__, __FILE__); \ -} \ -while (0) - -#define RAND(x) ((x) * (random() / (RAND_MAX + 1.0))) - -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) - - - -#define FILECON2_PORT (12046) -#define FILECON2_MAGIC (0x76543210) - -#define FCR_READ_BUFFERED (16241) -#define FCR_READ_DIRECT (16242) -#define FCR_READ_MMAPPED (16243) -#define FCR_WRITE_BUFFERED (16244) -#define FCR_WRITE_DIRECT (16245) -#define FCR_WRITE_MMAPPED (16246) -#define FCR_TRUNC (16247) -#define FCR_NOP (16248) -#define FCR_SEED (16249) -#define FCR_STOP (16250) - -struct filecon2_request -{ - uint32 magic; - uint32 type; - uint32 length; - uint32 data; - uint64 offset; -}; -typedef struct filecon2_request filecon2_request_t; - -static __inline__ void request_in(filecon2_request_t *req, char *buf) -{ - filecon2_request_t *str = (filecon2_request_t *)buf; - req->magic = be32_to_cpu(str->magic); - req->type = be32_to_cpu(str->type); - req->length = be32_to_cpu(str->length); - req->data = be32_to_cpu(str->data); - req->offset = be64_to_cpu(str->offset); -} - -static __inline__ void request_out(filecon2_request_t *req, char *buf) -{ - filecon2_request_t *str = (filecon2_request_t *)buf; - str->magic = cpu_to_be32(req->magic); - str->type = cpu_to_be32(req->type); - str->length = cpu_to_be32(req->length); - str->data = cpu_to_be32(req->data); - str->offset = cpu_to_be64(req->offset); -} - - -EXTERN char *prog_name; -EXTERN pid_t pid; - - -#endif /* __FILECON2_DOT_H__ */ - diff --git a/gfs/tests/filecon2/filecon2_client.c b/gfs/tests/filecon2/filecon2_client.c deleted file mode 100644 index d4d5bed..0000000 --- a/gfs/tests/filecon2/filecon2_client.c +++ /dev/null @@ -1,854 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> -#include <time.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> - -#include "global.h" -#include "linux_endian.h" -#define EXTERN -#include "filecon2.h" - - - -#ifndef O_DIRECT -#define O_DIRECT (0) -#warning O_DIRECT is broken -#endif -#ifndef PAGE_SIZE -#define PAGE_SIZE (65536) -#endif - -#define CHANCES (8) - -#define PATTERN_RAND (12341) -#define PATTERN_OPNUM (12342) - - - -struct operation -{ - char *name; - void (*func)(); -}; -typedef struct operation operation_t; - - - -unsigned int port = FILECON2_PORT; -unsigned int seed = 0; -uint64 offset = 0; -uint64 length = 1048576; -uint32 chunk = 1024; -unsigned int pattern = PATTERN_RAND; -int buffered = FALSE; -int direct = FALSE; -int mmapped = FALSE; -int trunc = FALSE; -int nop = FALSE; -unsigned int align = 1; -int reread = FALSE; -int respect_eof = FALSE; -int check_file_size = FALSE; -int verbose = FALSE; -char *servername = NULL; -char *filename = NULL; - -int user_seed = FALSE; -int fd_b = -1, fd_d = -1; -int sock; - -int first = FALSE; -unsigned char *mmap_data = NULL; - -uint64 file_size; -unsigned int opnum; - -float chances[CHANCES]; - - - - - -void rand_extent(uint64 *o, uint32 *l) -{ - uint64 off; - uint32 len; - - if (align > 1) - { - do - { - off = RAND(length / align); - len = RAND(chunk / align) + 1; - off *= align; - len *= align; - } - while (off + len > length); - } - else - { - do - { - off = RAND(length); - len = RAND(chunk) + 1; - } - while (off + len > length); - } - - *o = off; - *l = len; -} - - -void fill_pattern(unsigned char *data, unsigned int len) -{ - unsigned int x; - - switch (pattern) - { - case PATTERN_RAND: - while (len--) - *data++ = RAND(256); - break; - - case PATTERN_OPNUM: - x = cpu_to_be32(opnum); - while (len) - { - if (len > sizeof(unsigned int)) - { - memcpy(data, &x, sizeof(unsigned int)); - data += sizeof(unsigned int); - len -= sizeof(unsigned int); - } - else - { - memcpy(data, &x, len); - break; - } - } - break; - - default: - die("unknown pattern\n"); - } -} - - -void do_first() -{ - filecon2_request_t req; - unsigned char data[sizeof(filecon2_request_t) + 1]; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_WRITE_BUFFERED; - req.length = 1; - req.data = 1; - req.offset = offset + length - 1; - - fill_pattern(data + sizeof(filecon2_request_t), 1); - - do_lseek(fd_b, offset + length - 1); - do_write(fd_b, data + sizeof(filecon2_request_t), 1); - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + 1); - - mmap_data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_b, offset); - if (mmap_data == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - first = FALSE; -} - - -void do_check_file_size() -{ - struct stat st; - int error; - - error = fstat(fd_b, &st); - if (error) - die("can't stat file: %s\n", strerror(errno)); - - if (file_size != st.st_size) - die("file size mismatch (server = %"PRIu64", me = %"PRIu64")\n", - file_size, st.st_size); -} - - -void op_buffered_read() -{ - filecon2_request_t req; - uint64 off; - uint32 len; - unsigned char *data; - int error; - - rand_extent(&off, &len); - off += offset; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_READ_BUFFERED; - req.length = len; - req.data = len; - req.offset = off; - - type_alloc(data, char, sizeof(filecon2_request_t) + len); - - do_lseek(fd_b, off); - error = read(fd_b, data + sizeof(filecon2_request_t), len); - if (error < 0) - die("error reading from file: %s\n", strerror(errno)); - req.data = error; - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + req.data); - - free(data); -} - - -void op_buffered_write() -{ - filecon2_request_t req; - uint64 off; - uint32 len; - unsigned char *data; - - rand_extent(&off, &len); - off += offset; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_WRITE_BUFFERED; - req.length = len; - req.data = len; - req.offset = off; - - type_alloc(data, char, sizeof(filecon2_request_t) + len); - - fill_pattern(data + sizeof(filecon2_request_t), len); - - do_lseek(fd_b, off); - do_write(fd_b, data + sizeof(filecon2_request_t), len); - - if (reread) - { - unsigned char *data_reread; - - type_alloc(data_reread, char, len); - - do_lseek(fd_b, off); - do_read(fd_b, data_reread, len); - - if (memcmp(data + sizeof(filecon2_request_t), data_reread, len) != 0) - die("buffered write: bad reread\n"); - - free(data_reread); - } - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + req.data); - - free(data); -} - - -void op_direct_read() -{ - filecon2_request_t req; - uint64 off; - uint32 len; - unsigned char *data, *data_orig; - unsigned int remainder; - int error; - - if (respect_eof) - { - if (file_size < offset + align) - { - off = offset; - len = 0; - } - else - for (;;) - { - rand_extent(&off, &len); - off += offset; - if (off + len <= file_size) - break; - } - } - else - { - rand_extent(&off, &len); - off += offset; - } - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_READ_DIRECT; - req.length = len; - req.data = len; - req.offset = off; - - data = data_orig = malloc(sizeof(filecon2_request_t) + len + PAGE_SIZE); - if (!data) - die("out of memory\n"); - remainder = ((unsigned long)(data + sizeof(filecon2_request_t))) & (PAGE_SIZE - 1); - if (remainder) - data += PAGE_SIZE - remainder; - - do_lseek(fd_d, off); - error = read(fd_d, data + sizeof(filecon2_request_t), len); - if (error < 0) - die("error reading from file: %s\n", strerror(errno)); - req.data = error; - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + req.data); - - free(data_orig); -} - - -void op_direct_write() -{ - filecon2_request_t req; - uint64 off; - uint32 len; - unsigned char *data, *data_orig; - unsigned int remainder; - - rand_extent(&off, &len); - off += offset; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_WRITE_DIRECT; - req.length = len; - req.data = len; - req.offset = off; - - data = data_orig = malloc(sizeof(filecon2_request_t) + len + PAGE_SIZE); - if (!data) - die("out of memory\n"); - remainder = ((unsigned long)(data + sizeof(filecon2_request_t))) & (PAGE_SIZE - 1); - if (remainder) - data += PAGE_SIZE - remainder; - - fill_pattern(data + sizeof(filecon2_request_t), len); - - do_lseek(fd_d, off); - do_write(fd_d, data + sizeof(filecon2_request_t), len); - - if (reread) - { - unsigned char *data_reread, *data_reread_orig; - - data_reread = data_reread_orig = malloc(len + PAGE_SIZE); - if (!data_reread) - die("out of memory\n"); - remainder = ((unsigned long)data_reread) & (PAGE_SIZE - 1); - if (remainder) - data_reread += PAGE_SIZE - remainder; - - do_lseek(fd_d, off); - do_read(fd_d, data_reread, len); - - if (memcmp(data + sizeof(filecon2_request_t), data_reread, len) != 0) - die("direct write: bad reread\n"); - - free(data_reread_orig); - } - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + req.data); - - free(data_orig); -} - - -void op_mmapped_read() -{ - filecon2_request_t req; - uint64 off; - uint32 len; - unsigned char *data; - - rand_extent(&off, &len); - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_READ_MMAPPED; - req.length = len; - req.data = len; - req.offset = offset + off; - - type_alloc(data, char, sizeof(filecon2_request_t) + len); - - memcpy(data + sizeof(filecon2_request_t), mmap_data + off, len); - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + req.data); - - free(data); -} - - -void op_mmapped_write() -{ - filecon2_request_t req; - uint64 off; - uint32 len; - unsigned char *data; - - rand_extent(&off, &len); - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_WRITE_MMAPPED; - req.length = len; - req.data = len; - req.offset = offset + off; - - type_alloc(data, char, sizeof(filecon2_request_t) + len); - - fill_pattern(data + sizeof(filecon2_request_t), len); - - memcpy(mmap_data + off, data + sizeof(filecon2_request_t), len); - - if (reread) - { - if (memcmp(mmap_data + off, data + sizeof(filecon2_request_t), len) != 0) - die("mmapped write: bad reread\n"); - } - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t) + req.data); - - free(data); -} - - -void op_trunc() -{ - filecon2_request_t req; - uint64 off; - unsigned char data[sizeof(filecon2_request_t)]; - - if (align > 1) - { - off = RAND((length / align) + 1); - off *= align; - } - else - off = RAND(length + 1); - - off += offset; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_TRUNC; - req.offset = off; - - do_ftruncate(fd_b, off); - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t)); -} - - -void op_nop() -{ - filecon2_request_t req; - unsigned char data[sizeof(filecon2_request_t)]; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_NOP; - - request_out(&req, data); - do_write(sock, data, sizeof(filecon2_request_t)); -} - - -const static operation_t ops[] = -{ - { "buffered read", op_buffered_read }, - { "buffered write", op_buffered_write }, - { "direct read", op_direct_read }, - { "direct write", op_direct_write }, - { "mmapped read", op_mmapped_read }, - { "mmapped write", op_mmapped_write }, - { "truncate", op_trunc }, - { "nop", op_nop }, -}; - - -int do_op() -{ - filecon2_request_t req; - unsigned char buf[sizeof(filecon2_request_t)]; - float c, x = 0.0; - unsigned int op; - - - do_read(sock, buf, sizeof(filecon2_request_t)); - request_in(&req, buf); - - if (req.magic != FILECON2_MAGIC) - die("magic number mismatch\n"); - if (req.type == FCR_STOP) - return FALSE; - if (req.type) - die("strange message from server\n"); - - file_size = req.offset; - opnum = req.length; - - - if (first) - { - do_first(); - return TRUE; - } - else if (check_file_size) - do_check_file_size(); - - - for (;;) - { - op = 0; - c = RAND(1); - - for (;;) - { - if (chances[op]) - { - x += chances[op]; - if (x > c) - { - ops[op].func(); - return TRUE; - } - } - - op++; - if (op == CHANCES) - break; - } - } - - - die("D'oh!\n"); -} - - -void compute_chances() -{ - unsigned int x; - float sum = 0.0; - - for (x = 0; x < CHANCES; x++) - chances[x] = 0.0; - - if (buffered) - { - chances[0] = 1.0; - chances[1] = 1.0; - } - if (direct) - { - chances[2] = 1.0; - chances[3] = 1.0; - } - if (mmapped) - { - chances[4] = 1.0; - chances[5] = 1.0; - } - if (trunc) - chances[6] = 0.1; - if (nop) - chances[7] = 0.1; - - for (x = 0; x < CHANCES; x++) - sum += chances[x]; - - for (x = 0; x < CHANCES; x++) - chances[x] /= sum; -} - - -void do_seed() -{ - filecon2_request_t req; - unsigned char buf[sizeof(filecon2_request_t)]; - - do_read(sock, buf, sizeof(filecon2_request_t)); - request_in(&req, buf); - - if (req.magic != FILECON2_MAGIC) - die("magic number mismatch\n"); - if (req.type != FCR_SEED) - die("strange message from server\n"); - - if (!user_seed) - seed = req.length; - - if (verbose) - printf("\nseed = %u\n", seed); - - srandom(seed); -} - - -int main(int argc, char *argv[]) -{ - int optchar, cont = TRUE; - struct hostent *hname; - struct sockaddr_in sin; - unsigned int x; - int error; - - - prog_name = argv[0]; - pid = getpid(); - - - if (argc < 3) - { - fprintf(stderr, "%s usage:\n\n", prog_name); - fprintf(stderr, "%s -p <port> -s <seed> -o <offset> -l <length> -c <chunksize> -f <pattern> -b -d -m -t -n -a <align> -r -e -x -v server file\n\n", prog_name); - fprintf(stderr, " -p <port> Port to connect to\n"); - fprintf(stderr, " -s <seed> Seed for the random number generator\n"); - fprintf(stderr, " -o <offset> The start of the active region in bytes\n"); - fprintf(stderr, " -l <length> The length of the active region in bytes\n"); - fprintf(stderr, " -c <chunksize> Read/Write up to this amount in one I/O\n"); - fprintf(stderr, " -f <pattern> Do writes with this pattern (rand, opnum)\n"); - fprintf(stderr, " -b Do buffered I/O\n"); - fprintf(stderr, " -d Do direct I/O\n"); - fprintf(stderr, " -m Do memory mapped I/O\n"); - fprintf(stderr, " -t Do truncates\n"); - fprintf(stderr, " -n Do nops\n"); - fprintf(stderr, " -a <align> I/O should be aligned to multiples of this value\n"); - fprintf(stderr, " -r Reread writes\n"); - fprintf(stderr, " -e Don't try to read past the EOF when doing Direct I/O\n"); - fprintf(stderr, " -x Always check to make sure the file's size is correct\n"); - fprintf(stderr, " -v Be verbose\n"); - exit(EXIT_FAILURE); - } - - while (cont) - { - optchar = getopt(argc, argv, "p:s:o:l:c:f:bdmtna:rexv"); - switch (optchar) - { - case 'p': - sscanf(optarg, "%u", &port); - break; - case 's': - sscanf(optarg, "%u", &seed); - user_seed = TRUE; - break; - case 'o': - sscanf(optarg, "%"SCNu64"", &offset); - break; - case 'l': - sscanf(optarg, "%"SCNu64"", &length); - break; - case 'c': - sscanf(optarg, "%u", &chunk); - break; - case 'f': - if (strcmp(optarg, "rand") == 0) - pattern = PATTERN_RAND; - else if (strcmp(optarg, "opnum") == 0) - pattern = PATTERN_OPNUM; - else - die("unknown pattern %s\n", optarg); - break; - case 'b': - buffered = TRUE; - break; - case 'd': - direct = TRUE; - break; - case 'm': - mmapped = TRUE; - break; - case 't': - trunc = TRUE; - break; - case 'n': - nop = TRUE; - break; - case 'a': - sscanf(optarg, "%u", &align); - break; - case 'r': - reread = TRUE; - break; - case 'e': - respect_eof = TRUE; - break; - case 'x': - check_file_size = TRUE; - break; - case 'v': - verbose = TRUE; - break; - case EOF: - cont = FALSE; - break; - default: - die("bad argument\n"); - } - } - - if (optind < argc) - servername = argv[optind++]; - else - die("no servername\n"); - - if (optind < argc) - filename = argv[optind++]; - else - die("no filename\n"); - - if (port >= 65536) - die("invalid port number: %u\n", port); - - if (align > chunk || chunk > length) - die("bad sizes, should be: -a <= -c < = -l\n"); - - if (offset % align) - die("offset not aligned\n"); - - if (mmapped) - { - if (trunc) - die("can't do both -m and -t\n"); - first = TRUE; - } - - - compute_chances(); - - - if (verbose) - { - printf("port = %u\n", port); - if (user_seed) - printf("seed = %u\n", seed); - else - printf("seed = <ProvidedByServer>\n"); - printf("offset = %"PRIu64"\n", offset); - printf("length = %"PRIu64"\n", length); - printf("chunk = %u\n", chunk); - switch (pattern) - { - case PATTERN_RAND: - printf("pattern = rand\n"); - break; - case PATTERN_OPNUM: - printf("pattern = opnum\n"); - break; - default: - printf("pattern = unknown\n"); - break; - } - printf("buffered = %d\n", buffered); - printf("direct = %d\n", direct); - printf("mmapped = %d\n", mmapped); - printf("trunc = %d\n", trunc); - printf("nop = %d\n", nop); - printf("align = %u\n", align); - printf("reread = %d\n", reread); - printf("respect_eof = %d\n", respect_eof); - printf("check_file_size = %d\n", check_file_size); - printf("verbose = %d\n", verbose); - printf("servername = %s\n", servername); - printf("filename = %s\n", filename); - - printf("\n"); - for (x = 0; x < CHANCES; x++) - printf("%s %f\n", ops[x].name, chances[x]); - } - - - fd_b = open(filename, O_RDWR); - if (fd_b < 0) - die("can't open file %s: %s\n", filename, strerror(errno)); - - if (direct) - { - fd_d = open(filename, O_RDWR | O_DIRECT); - if (fd_d < 0) - die("can't open file %s: %s\n", filename, strerror(errno)); - } - - - hname = gethostbyname(servername); - if (!hname) - die("can't resolve host %s: %s\n", servername, strerror(errno)); - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - die("can't open socket: %s\n", strerror(errno)); - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = *((uint32 *)*(hname->h_addr_list)); - sin.sin_port = cpu_to_be16(port); - - error = connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); - if (error < 0) - die("can't connect to host %s (%u): %s\n", servername, port, strerror(errno)); - - - do_seed(); - - - while (do_op()) /* Do nothing */; - - - close(sock); - if (direct) - close(fd_d); - if (mmap_data) - munmap(mmap_data, length); - close(fd_b); - - - exit(EXIT_SUCCESS); -} - - - diff --git a/gfs/tests/filecon2/filecon2_server.c b/gfs/tests/filecon2/filecon2_server.c deleted file mode 100644 index 87a9f90..0000000 --- a/gfs/tests/filecon2/filecon2_server.c +++ /dev/null @@ -1,610 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> -#include <time.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> - -#include "global.h" -#include "osi_list.h" -#include "linux_endian.h" -#define EXTERN -#include "filecon2.h" - - - -struct log -{ - osi_list_t list; - unsigned int cli; - filecon2_request_t req; -}; -typedef struct log log_t; - - - -int fd = -1; -unsigned int clients = 0; -struct sockaddr_in *ssin = NULL; -int *sock = NULL; -unsigned int t = 0; - -int log = FALSE; -osi_list_decl(log_list); - - - - - -char *type2string(unsigned int type) -{ - char *type_string; - - switch (type) - { - case FCR_READ_BUFFERED: - type_string = "read(b)"; - break; - case FCR_READ_DIRECT: - type_string = "read(d)"; - break; - case FCR_READ_MMAPPED: - type_string = "read(m)"; - break; - case FCR_WRITE_BUFFERED: - type_string = "write(b)"; - break; - case FCR_WRITE_DIRECT: - type_string = "write(d)"; - break; - case FCR_WRITE_MMAPPED: - type_string = "write(m)"; - break; - case FCR_TRUNC: - type_string = "trunc"; - break; - case FCR_NOP: - type_string = "nop"; - break; - case FCR_SEED: - type_string = "seed"; - break; - case FCR_STOP: - type_string = "stop"; - break; - default: - type_string = "unknown"; - break; - } - - return type_string; -} - - -void request_print(unsigned int cli, filecon2_request_t *req) -{ - printf("Request from %u/%.8X/%.4X:\n", - cli, be32_to_cpu(ssin[cli].sin_addr.s_addr), be16_to_cpu(ssin[cli].sin_port)); - printf(" magic = 0x%X\n", req->magic); - printf(" type = %s (%u)\n", type2string(req->type), req->type); - printf(" length = %u\n", req->length); - printf(" data = %u\n", req->data); - printf(" offset = %"PRIu64"\n", req->offset); -} - - -void dump_data(filecon2_request_t *req, unsigned char *client, unsigned char *server) -{ - FILE *outfile; - unsigned int x; - unsigned int first = (unsigned int)-1, last = (unsigned int)-1; - uint64 f1, l1, f2, l2; - - for (x = 0; x < req->data; x++) - if (client[x] != server[x]) - { - first = x; - break; - } - - if (first == (unsigned int)-1) - die("blerg1\n"); - - for (x = req->data; x--; ) - if (client[x] != server[x]) - { - last = x; - break; - } - - if (last == (unsigned int)-1) - die("blerg2\n"); - - f1 = req->offset + first; - l1 = req->offset + last; - - printf("Error range (%"PRIu64" - %"PRIu64"), (%u - %u) \n", - f1, l1, first, last); - - if (log) - { - osi_list_t *tmp, *head; - log_t *l; - unsigned int t = 0; - - for (head = &log_list, tmp = head->next; - tmp != head; - tmp = tmp->next, t++) - { - l = osi_list_entry(tmp, log_t, list); - - if (l->req.type == FCR_NOP) - continue; - else if (l->req.type == FCR_TRUNC) - { - f2 = l->req.offset; - l2 = l->req.offset; - } - else - { - f2 = l->req.offset; - l2 = l->req.offset + l->req.data - 1; - } - - if ((f1 <= f2 && f2 <= l1) || - (f1 <= l2 && l2 <= l1) || - (f2 <= f1 && f1 <= l2) || - (f2 <= l1 && l1 <= l2)) - { - printf("%.7u: %u/%.8X/%.4X: %s (%"PRIu64" - %"PRIu64")\n", - t, - l->cli, be32_to_cpu(ssin[l->cli].sin_addr.s_addr), be16_to_cpu(ssin[l->cli].sin_port), - type2string(l->req.type), - f2, l2); - } - } - } - - outfile = fopen("out.client", "w"); - if (!outfile) - die("can't open file %s: %s\n", "out.client", strerror(errno)); - for (x = 0; x < req->data; x++) - { - fprintf(outfile, "%.2X", client[x]); - if (x % 32 == 31) - fprintf(outfile, "\n"); - } - if (x % 32) - fprintf(outfile, "\n"); - fclose(outfile); - - outfile = fopen("out.server", "w"); - if (!outfile) - die("can't open file %s: %s\n", "out.server", strerror(errno)); - for (x = 0; x < req->data; x++) - { - fprintf(outfile, "%.2X", server[x]); - if (x % 32 == 31) - fprintf(outfile, "\n"); - } - if (x % 32) - fprintf(outfile, "\n"); - fclose(outfile); -} - - -void do_op(unsigned int cli) -{ - struct stat st; - filecon2_request_t req; - unsigned char buf[sizeof(filecon2_request_t)]; - uint64 first, last; - unsigned char *data1 = NULL; - unsigned char *data2; - unsigned int x = 0; - int error; - - error = fstat(fd, &st); - if (error) - die("can't stat file: %s\n", strerror(errno)); - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.length = t; - req.offset = st.st_size; - request_out(&req, buf); - do_write(sock[cli], buf, sizeof(filecon2_request_t)); - - do_read(sock[cli], buf, sizeof(filecon2_request_t)); - request_in(&req, buf); - - if (req.magic != FILECON2_MAGIC) - { - request_print(cli, &req); - die("magic number mismatch\n"); - } - - if (req.type == FCR_NOP) - first = last = 0; - else if (req.type == FCR_TRUNC) - first = last = req.offset; - else - { - first = req.offset; - last = req.offset + req.data - 1; - } - - printf("%.7u: %d/%u/%.8X/%.4X: %s (%"PRIu64" - %"PRIu64")\n", - t, pid, - cli, be32_to_cpu(ssin[cli].sin_addr.s_addr), be16_to_cpu(ssin[cli].sin_port), - type2string(req.type), - first, last); - - if (log) - { - log_t *l; - l = malloc(sizeof(log_t)); - if (!l) - die("out of memory\n"); - memset(l, 0, sizeof(log_t)); - l->cli = cli; - l->req = req; - osi_list_add_prev(&l->list, &log_list); - } - - if (req.data) - { - data1 = malloc(req.data); - if (!data1) - { - request_print(cli, &req); - die("out of memory\n"); - } - - for (;;) - { - error = read(sock[cli], data1 + x, req.data - x); - if (error < 0) - { - request_print(cli, &req); - die("can't read from socket: %s\n", strerror(errno)); - } - - x += error; - - if (x == req.data) - break; - if (x > req.data) - { - request_print(cli, &req); - die("data overflow from client: %u\n", x); - } - } - } - - if (req.type == FCR_READ_BUFFERED || - req.type == FCR_READ_MMAPPED) - { - data2 = malloc(req.data + 1); /* req.data might be zero */; - if (!data2) - { - request_print(cli, &req); - die("out of memory\n"); - } - - do_lseek(fd, req.offset); - error = read(fd, data2, req.length); - if (error < 0) - { - request_print(cli, &req); - die("bad read from file: %s\n", strerror(errno)); - } - - if (error != req.data) - { - request_print(cli, &req); - die("length mismatch from read: %u\n", error); - } - if (req.data && memcmp(data1, data2, req.data) != 0) - { - request_print(cli, &req); - dump_data(&req, data1, data2); - die("value mismatch\n"); - } - - free(data2); - } - else if (req.type == FCR_READ_DIRECT) - { - data2 = malloc(req.length + 1); - if (!data2) - { - request_print(cli, &req); - die("out of memory\n"); - } - - do_lseek(fd, req.offset); - error = read(fd, data2, req.length); - if (error < 0) - { - request_print(cli, &req); - die("bad read from file: %s\n", strerror(errno)); - } - - /* FixMe!!! */ - if (error < req.data || error - req.data > 4096) - { - request_print(cli, &req); - die("length mismatch from read: %u\n", error); - } - if (req.data && memcmp(data1, data2, req.data) != 0) - { - request_print(cli, &req); - dump_data(&req, data1, data2); - die("value mismatch\n"); - } - - free(data2); - } - else if (req.type == FCR_WRITE_BUFFERED || - req.type == FCR_WRITE_DIRECT || - req.type == FCR_WRITE_MMAPPED) - { - if (!req.data) - { - request_print(cli, &req); - die("no data to write\n"); - } - if (req.length != req.data) - { - request_print(cli, &req); - die("length != data on write\n"); - } - - do_lseek(fd, req.offset); - error = write(fd, data1, req.length); - if (error < 0) - { - request_print(cli, &req); - die("bad write to file: %s\n", strerror(errno)); - } - if (error != req.length) - { - request_print(cli, &req); - die("short write: %u\n", error); - } - } - else if (req.type == FCR_TRUNC) - { - error = ftruncate(fd, req.offset); - if (error) - { - request_print(cli, &req); - die("bad truncate: %s\n", strerror(errno)); - } - } - else if (req.type == FCR_NOP) - { - /* Do nothing */ - } - else - { - request_print(cli, &req); - die("strange message from client\n"); - } - - if (req.data) - free(data1); -} - - -void do_seed(int sock) -{ - filecon2_request_t req; - unsigned char buf[sizeof(filecon2_request_t)]; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_SEED; - req.length = random(); - request_out(&req, buf); - do_write(sock, buf, sizeof(filecon2_request_t)); -} - - -void do_stop(int sock) -{ - filecon2_request_t req; - unsigned char buf[sizeof(filecon2_request_t)]; - - memset(&req, 0, sizeof(filecon2_request_t)); - req.magic = FILECON2_MAGIC; - req.type = FCR_STOP; - request_out(&req, buf); - do_write(sock, buf, sizeof(filecon2_request_t)); -} - - -int main(int argc, char *argv[]) -{ - unsigned int port = FILECON2_PORT; - unsigned int seed = time(NULL) ^ getpid(); - unsigned int wait_clients = 1; - unsigned int to = 0; - char *filename; - - int optchar, cont = TRUE; - int asking_sock; - int trueint = TRUE; - struct sockaddr_in sin; - fd_set fds; - struct timeval tv; - unsigned int size; - unsigned int cli; - int error; - - - prog_name = argv[0]; - pid = getpid(); - - - if (argc < 2) - { - fprintf(stderr, "%s usage:\n\n", prog_name); - fprintf(stderr, "%s -p <port> -s <seed> -w <clients> -t <to> filename\n\n", prog_name); - fprintf(stderr, " -p <port> The port to listen on (%u by default)\n", FILECON2_PORT); - fprintf(stderr, " -s <seed> Seed for the random number generator\n"); - fprintf(stderr, " -w <clients> Wait for a number of clients to join\n"); - fprintf(stderr, " -t <to> Only do a given number of operations\n"); - fprintf(stderr, " -l Log operations for error reporting\n"); - exit(EXIT_FAILURE); - } - - while (cont) - { - optchar = getopt(argc, argv, "p:s:w:t:l"); - switch (optchar) - { - case 'p': - sscanf(optarg, "%u", &port); - break; - case 's': - sscanf(optarg, "%u", &seed); - break; - case 'w': - sscanf(optarg, "%u", &wait_clients); - break; - case 't': - sscanf(optarg, "%u", &to); - break; - case 'l': - log = TRUE; - break; - case EOF: - cont = FALSE; - break; - default: - die("bad argument\n"); - } - } - - if (optind < argc) - filename = argv[optind]; - else - die("no filename\n"); - - if (port >= 65536) - die("invalid port number: %u\n", port); - - - srandom(seed); - - - fd = open(filename, O_RDWR, 0644); - if (fd < 0) - die("can't open file %s: %s\n", filename, strerror(errno)); - - - asking_sock = socket(AF_INET, SOCK_STREAM, 0); - if (asking_sock < 0) - die("can't open socket: %s\n", strerror(errno)); - - error = setsockopt(asking_sock, SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int)); - if (error < 0) - die("can't set SO_REUSEADDR: %s\n", strerror(errno)); - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = cpu_to_be16(port); - - error = bind(asking_sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); - if (error < 0) - die("can't bind to port %u: %s\n", port, strerror(errno)); - - error = listen(asking_sock, 5); - if (error < 0) - die("can't bind to socket: %s\n", strerror(errno)); - - - for (;;) - { - FD_ZERO(&fds); - FD_SET(asking_sock, &fds); - tv.tv_sec = 0; - tv.tv_usec = 0; - - error = select(asking_sock + 1, &fds, NULL, NULL, - (clients < wait_clients) ? NULL : &tv); - if (error < 0) - die("can't select: %s\n", strerror(errno)); - - if (error) /* Add a new client */ - { - cli = clients; - clients++; - - sock = realloc(sock, clients * sizeof(int)); - if (!sock) - die("can't alloc memory: %s\n", strerror(errno)); - ssin = realloc(ssin, clients * sizeof(struct sockaddr_in)); - if (!sock) - die("can't alloc memory: %s\n", strerror(errno)); - - size = sizeof(struct sockaddr_in); - sock[cli] = accept(asking_sock, &ssin[cli], &size); - if (sock[cli] < 0) - die("can't accept: %s\n", strerror(errno)); - - do_seed(sock[cli]); - - printf("connect %u/%.8X/%.4X\n", - cli, be32_to_cpu(ssin[cli].sin_addr.s_addr), be16_to_cpu(ssin[cli].sin_port)); - } - - if (clients < wait_clients) - continue; - - - cli = RAND(clients); - do_op(cli); - t++; - - if (to && t == to) - break; - } - - - for (cli = 0; cli < clients; cli++) - { - do_stop(sock[cli]); - close(sock[cli]); - } - close(fd); - - - exit(EXIT_SUCCESS); -} - - - diff --git a/gfs/tests/mmdd/Makefile b/gfs/tests/mmdd/Makefile deleted file mode 100644 index 89b9b19..0000000 --- a/gfs/tests/mmdd/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################## -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -CC=gcc -LD=gcc - -TARGETS=mmdd sfdd - -all: $(TARGETS) - - -mmdd: mmdd.c - $(CC) -Wall -O2 -o mmdd mmdd.c -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 - -sfdd: mmdd.c - $(CC) -Wall -O2 -o sfdd mmdd.c -D_GNU_SOURCE -DUSE_SENDFILE - -clean: - rm -f *.o *.s *.a *~ core .depend $(TARGETS) diff --git a/gfs/tests/mmdd/mmdd.c b/gfs/tests/mmdd/mmdd.c deleted file mode 100644 index 6ce97a4..0000000 --- a/gfs/tests/mmdd/mmdd.c +++ /dev/null @@ -1,716 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifdef __linux__ -#else -#undef USE_SENDFILE -#endif - -#ifdef __FreeBSD__ -#define O_SYNC O_FSYNC -#else -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/time.h> -#include <sys/mman.h> -#ifdef USE_SENDFILE -#include <sys/sendfile.h> -#endif - - - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - -#define TRUE (1) -#define FALSE (0) - - - -#ifndef O_DIRECT -#define O_DIRECT (0) -#warning O_DIRECT is broken -#endif -#ifndef PAGE_SIZE -#define PAGE_SIZE (65536) -#endif - - - -char *prog_name; -off_t read_offset = 0; -off_t write_offset = 0; -int private = FALSE; - - - - - -#ifdef USE_SENDFILE -void send_sendfile(int ifd, int ofd, unsigned bs) -{ - int count; - - count = sendfile(ofd, ifd, &read_offset, bs); - if (count != bs) - die("Bad sendfile return %d: %s\n", count, strerror(errno)); - - write_offset += bs; -} -#endif - - -void do_bothmapped(int ifd, int ofd, unsigned bs) -{ - char *data_in; - char *data_out; - - data_in = mmap(NULL, bs, PROT_READ, (private) ? MAP_PRIVATE : MAP_SHARED, ifd, read_offset); - if (data_in == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - data_out = mmap(NULL, bs, PROT_READ | PROT_WRITE, (private) ? MAP_PRIVATE : MAP_SHARED, ofd, write_offset); - if (data_out == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - memcpy(data_out, data_in, bs); - - munmap(data_in, bs); - munmap(data_out, bs); - - read_offset += bs; - write_offset += bs; -} - - -void do_imapped(int ifd, int ofd, unsigned bs) -{ - char *data; - int count; - - data = mmap(NULL, bs, PROT_READ, (private) ? MAP_PRIVATE : MAP_SHARED, ifd, read_offset); - if (data == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - count = write(ofd, data, bs); - if (count != bs) - die("bad write return %d: %s\n", count, strerror(errno)); - - munmap(data, bs); - - read_offset += bs; - write_offset += bs; -} - - -void do_omapped(int ifd, int ofd, unsigned bs) -{ - char *data; - int count; - - data = mmap(NULL, bs, PROT_READ | PROT_WRITE, (private) ? MAP_PRIVATE : MAP_SHARED, ofd, write_offset); - if (data == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - count = read(ifd, data, bs); - if (count != bs) - die("bad read return %d: %s\n", count, strerror(errno)); - - munmap(data, bs); - - read_offset += bs; - write_offset += bs; -} - - -void do_mapped_read(int fd, char *buf, unsigned int bs) -{ - char *data; - - data = mmap(NULL, bs, PROT_READ, (private) ? MAP_PRIVATE : MAP_SHARED, fd, read_offset); - if (data == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - memcpy(buf, data, bs); - - munmap(data, bs); - - read_offset += bs; -} - - -void do_raw_read(int fd, char *buf, unsigned int bs) -{ - int count; - - count = read(fd, buf, bs); - if (count != bs) - die("bad read return %d: %s\n", count, strerror(errno)); -} - - -void do_mapped_write(int fd, char *buf, unsigned int bs) -{ - char *data; - - data = mmap(NULL, bs, PROT_READ | PROT_WRITE, (private) ? MAP_PRIVATE : MAP_SHARED, fd, write_offset); - if (data == MAP_FAILED) - die("can't mmap file: %s\n", strerror(errno)); - - memcpy(data, buf, bs); - - munmap(data, bs); - - write_offset += bs; -} - - -void do_raw_write(int fd, char *buf, unsigned int bs) -{ - int count; - - count = write(fd, buf, bs); - if (count != bs) - die("bad write return %d: %s\n", count, strerror(errno)); -} - - -int main(int argc, char *argv[]) -{ - int arg; - - char *ifname = NULL; - char *ofname = NULL; - int imapped = FALSE, omapped = FALSE; - unsigned int bs = 4096; - unsigned long long move = 0; - unsigned long long count = 0; - unsigned long long skip = 0; - unsigned long long seek = 0; - int do_fsync = FALSE; - int do_osync = FALSE; - int verbose = FALSE; - int notrunc = FALSE; - int nobounce = FALSE; - int append = FALSE; - int direct = FALSE; - int fgt = FALSE; - int do_excl = FALSE; - - int done_bs = FALSE; - int done_amount = FALSE; - int done_skip = FALSE; - int done_seek = FALSE; - int done_fsync = FALSE; - int done_osync = FALSE; - int done_notrunc = FALSE; - int done_nobounce = FALSE; - int done_append = FALSE; - int done_direct = FALSE; - int done_private = FALSE; - int done_fgt = FALSE; - int done_excl = FALSE; - -#ifdef USE_SENDFILE - int do_sendfile = FALSE; - int done_sendfile = FALSE; -#endif - - int ifd = -1, ofd = -1; - - char c; - char *data; - unsigned long long x; - unsigned int remainder; - - unsigned int timeslots, index = 0; - struct timeval *tv; - unsigned long long t1, t2; - double seconds, mbps; - - struct stat st; - char *fgt_name = NULL; - FILE *fgt_file; - - int error; - - - - prog_name = argv[0]; - - - - if (argc == 1) - die("options: Help me! Help me!\n"); - - - - for (arg = 1; arg < argc; arg++) - { - if (strncmp(argv[arg], "if=", 3) == 0) - { - if (ifname) - die("you're only allowed one "i?f="\n"); - - ifname = argv[arg] + 3; - imapped = FALSE; - } - else if (strncmp(argv[arg], "imf=", 4) == 0) - { - if (ifname) - die("you're only allowed one "i?f="\n"); - - ifname = argv[arg] + 4; - imapped = TRUE; - } - else if (strncmp(argv[arg], "of=", 3) == 0) - { - if (ofname) - die("you're only allowed one "o?f="\n"); - - ofname = argv[arg] + 3; - omapped = FALSE; - } - else if (strncmp(argv[arg], "omf=", 4) == 0) - { - if (ofname) - die("you're only allowed one "o?f="\n"); - - ofname = argv[arg] + 4; - omapped = TRUE; - } - else if (strncmp(argv[arg], "bs=", 3) == 0) - { - if (done_bs) - die("you're only allowed one "bs="\n"); - done_bs = TRUE; - - bs = atoi(argv[arg] + 3); - c = argv[arg][strlen(argv[arg]) - 1]; - if (c == 'k') - bs <<= 10; - else if (c == 'm') - bs <<= 20; - else if (c == 'g') - bs <<= 30; - - if (!bs) - die("invalid blocksize: %u\n", bs); - } - else if (strncmp(argv[arg], "move=", 5) == 0) - { - if (done_amount) - die("you're only allowed one amount\n"); - done_amount = TRUE; - - sscanf(argv[arg] + 5, "%qu", &move); - c = argv[arg][strlen(argv[arg]) - 1]; - if (c == 'k') - move <<= 10; - else if (c == 'm') - move <<= 20; - else if (c == 'g') - move <<= 30; - - if (!move) - die("zero move\n"); - } - else if (strncmp(argv[arg], "count=", 6) == 0) - { - if (done_amount) - die("you're only allowed one amount\n"); - done_amount = TRUE; - - sscanf(argv[arg] + 6, "%qu", &count); - - if (!count) - die("zero count\n"); - } - else if (strncmp(argv[arg], "skip=", 5) == 0) - { - if (done_skip) - die("you're only allowed one skip\n"); - done_skip = TRUE; - - sscanf(argv[arg] + 5, "%qu", &skip); - } - else if (strncmp(argv[arg], "seek=", 5) == 0) - { - if (done_seek) - die("you're only allowed one seek\n"); - done_seek = TRUE; - - sscanf(argv[arg] + 5, "%qu", &seek); - } - else if (strncmp(argv[arg], "fsync=", 6) == 0) - { - if (done_fsync) - die("you're only allowed one "fsync="\n"); - done_fsync = TRUE; - - do_fsync = atoi(argv[arg] + 6); - } - else if (strncmp(argv[arg], "osync=", 6) == 0) - { - if (done_osync) - die("you're only allowed one "osync="\n"); - done_osync = TRUE; - - do_osync = atoi(argv[arg] + 6); - } - else if (strncmp(argv[arg], "notrunc=", 8) == 0) - { - if (done_notrunc) - die("you're only allowed one "notrunc="\n"); - done_notrunc = TRUE; - - notrunc = atoi(argv[arg] + 8); - } - else if (strncmp(argv[arg], "nobounce=", 9) == 0) - { - if (done_nobounce) - die("you're only allowed one "nobounce="\n"); - done_nobounce = TRUE; - - nobounce = atoi(argv[arg] + 9); - } - else if (strncmp(argv[arg], "append=", 7) == 0) - { - if (done_append) - die("you're only allowed one "append="\n"); - done_append = TRUE; - - append = atoi(argv[arg] + 7); - } - else if (strncmp(argv[arg], "direct=", 7) == 0) - { - if (done_direct) - die("you're only allowed one "direct="\n"); - done_direct = TRUE; - - direct = atoi(argv[arg] + 7); - } -#ifdef USE_SENDFILE - else if (strncmp(argv[arg], "sendfile=", 9) == 0) - { - if (done_sendfile) - die("you're only allowed one "sendfile="\n"); - done_sendfile = TRUE; - - do_sendfile = atoi(argv[arg] + 9); - } -#endif - else if (strncmp(argv[arg], "private=", 8) == 0) - { - if (done_private) - die("you're only allowed one "private="\n"); - done_private = TRUE; - - private = atoi(argv[arg] + 8); - } - else if (strncmp(argv[arg], "fgt=", 4) == 0) - { - if (done_fgt) - die("you're only allowed one "fgt="\n"); - done_fgt = TRUE; - - if (isdigit(*(argv[arg] + 4))) - fgt = atoi(argv[arg] + 4); - else - { - fgt = TRUE; - fgt_name = argv[arg] + 4; - } - } - else if (strncmp(argv[arg], "excl=", 5) == 0) - { - if (done_excl) - die("you're only allowed one "excl="\n"); - done_excl = TRUE; - - do_excl = atoi(argv[arg] + 5); - } - else if (strcmp(argv[arg], "-v") == 0) - { - verbose = TRUE; - } - else - { - die("unknown/unimplemented option: %s\n", argv[arg]); - } - } - - - - if (!done_amount) - die("need an amount to move\n"); - - if (verbose) - { - fprintf(stderr, "ifname = %s (%s)\n", ifname, (imapped) ? "mapped" : "raw"); - fprintf(stderr, "ofname = %s (%s)\n", ofname, (omapped) ? "mapped" : "raw"); - fprintf(stderr, "bs = %u\n", bs); - fprintf(stderr, "move = %qu\n", move); - fprintf(stderr, "count = %qu\n", count); - fprintf(stderr, "skip = %qu\n", skip); - fprintf(stderr, "seek = %qu\n", seek); - fprintf(stderr, "fsync = %d\n", do_fsync); - fprintf(stderr, "notrunc = %d\n", notrunc); - fprintf(stderr, "nobounce = %d\n", nobounce); - fprintf(stderr, "append = %d\n", append); - fprintf(stderr, "direct = %d\n", direct); -#ifdef USE_SENDFILE - fprintf(stderr, "sendfile = %d\n", do_sendfile); -#endif - fprintf(stderr, "private = %d\n", private); - fprintf(stderr, "fine grain timing = %d\n", fgt); - fprintf(stderr, "fine grain timing file = %s\n", (fgt_name) ? fgt_name : "NULL"); - fprintf(stderr, "excl = %d\n", do_excl); - } - - if (!count) - { - if (move % bs != 0) - die("move size (%qu) not divisible by block size (%u)\n", move, bs); - count = move / bs; - } - - - - data = (char *)malloc(bs + PAGE_SIZE); - if (!data) - die("out of memory\n"); - - remainder = ((unsigned long)data) & (PAGE_SIZE - 1); - if (remainder) - data += PAGE_SIZE - remainder; - - memset(data, 0, bs); - - - - if (fgt) - { - if (count & 0xFFFFFFFFF0000000) - die("count is too high -- can't do fine grain timing\n"); - timeslots = count + 3; - } - else - timeslots = 2; - - tv = malloc(timeslots * sizeof(struct timeval)); - if (!tv) - die("out of memory\n"); - - - - gettimeofday(&tv[index++], NULL); - - - - if (ifname) - { - if (strcmp(ifname, "-") == 0) - ifd = STDIN_FILENO; - else - { - ifd = open(ifname, O_RDONLY | ((direct) ? O_DIRECT : 0)); - if (ifd < 0) - die("can't open file %s: %s\n", ifname, strerror(errno)); - if (verbose) - { - error = fstat(ifd, &st); - if (error) - die("can't stat file %s: %s\n", ifname, strerror(errno)); - fprintf(stderr, "input inode = %qu\n", (unsigned long long)st.st_ino); - } - - if (skip && lseek(ifd, skip * bs, SEEK_SET) != skip * bs) - die("can't skip: %s\n", strerror(errno)); - } - } - - if (ofname) - { - if (strcmp(ofname, "-") == 0) - ofd = STDOUT_FILENO; - else - { - ofd = open(ofname, - O_RDWR | - O_CREAT | - ((notrunc) ? 0 : O_TRUNC) | - ((direct) ? O_DIRECT : 0) | - ((append) ? O_APPEND : 0) | - ((do_osync) ? O_SYNC : 0) | - ((do_excl) ? O_EXCL : 0), - 0644); - if (ofd < 0) - die("can't open file %s: %s\n", ofname, strerror(errno)); - if (verbose) - { - error = fstat(ofd, &st); - if (error) - die("can't stat file %s: %s\n", ofname, strerror(errno)); - fprintf(stderr, "output inode = %qu\n", (unsigned long long)st.st_ino); - } - - if (seek && lseek(ofd, seek * bs, SEEK_SET) != seek * bs) - die("can't seek: %s\n", strerror(errno)); - } - } - - if (ofd >= 0 && omapped) - { - if (ftruncate(ofd, bs * count) < 0) - die("can't truncate bigger: %s\n", strerror(errno)); - } - - - - if (fgt) - gettimeofday(&tv[index++], NULL); - - - - for (x = 0; x < count; x++) - { -#ifdef USE_SENDFILE - if (do_sendfile && ifd >= 0 && ofd >= 0) - send_sendfile(ifd, ofd, bs); - else -#endif - if (nobounce && ifd >= 0 && ofd >= 0 && (imapped || omapped)) - { - if (imapped && omapped) - do_bothmapped(ifd, ofd, bs); - else if (imapped) - do_imapped(ifd, ofd, bs); - else - do_omapped(ifd, ofd, bs); - } - else - { - if (ifd >= 0) - { - if (imapped) - do_mapped_read(ifd, data, bs); - else - do_raw_read(ifd, data, bs); - } - - if (ofd >= 0) - { - if (omapped) - do_mapped_write(ofd, data, bs); - else - do_raw_write(ofd, data, bs); - } - } - - if (verbose) - fprintf(stderr, "%qu\n", x); - - if (fgt) - gettimeofday(&tv[index++], NULL); - } - - - - if (ifd >= 0) - close(ifd); - - if (ofd >= 0) - { - if (do_fsync) - fsync(ofd); - close(ofd); - } - - - - gettimeofday(&tv[index++], NULL); - - if (index != timeslots) - die("index != timeslots\n"); - - - - if (fgt) - { - if (fgt_name) - { - fgt_file = fopen(fgt_name, "w"); - if (!fgt_file) - die("can't open file %s: %s\n", fgt_name, strerror(errno)); - } - else - fgt_file = stderr; - - t1 = (unsigned long long)tv[0].tv_sec * 1000000 + tv[0].tv_usec; - fprintf(fgt_file, "start = %qu\n", t1); - - for (index = 1; index < timeslots; index++) - { - t1 = (unsigned long long)tv[index - 1].tv_sec * 1000000 + tv[index - 1].tv_usec; - t2 = (unsigned long long)tv[index].tv_sec * 1000000 + tv[index].tv_usec; - - if (index == 1) - fprintf(fgt_file, "setup = %qu\n", t2 - t1); - else if (index == timeslots - 1) - fprintf(fgt_file, "cleanup = %qu\n", t2 - t1); - else - fprintf(fgt_file, "loop %u = %qu\n", index - 2, t2 - t1); - } - - t1 = (unsigned long long)tv[0].tv_sec * 1000000 + tv[0].tv_usec; - t2 = (unsigned long long)tv[timeslots - 1].tv_sec * 1000000 + tv[timeslots - 1].tv_usec; - - fprintf(fgt_file, "total = %qu\n", t2 - t1); - - if (fgt_name) - fclose(fgt_file); - } - - - - t1 = (unsigned long long)tv[0].tv_sec * 1000000 + tv[0].tv_usec; - t2 = (unsigned long long)tv[timeslots - 1].tv_sec * 1000000 + tv[timeslots - 1].tv_usec; - - seconds = (t2 - t1) / 1000000.0; - mbps = bs * count / 1048576.0 / seconds; - - fprintf(stderr, "seconds = %.4f, MB/s = %.4f\n", seconds, mbps); - - - - exit(EXIT_SUCCESS); -} - - - diff --git a/gnbd-kernel/Makefile b/gnbd-kernel/Makefile deleted file mode 100644 index a1b0df5..0000000 --- a/gnbd-kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: - cd src && ${MAKE} all - -clean: - cd src && ${MAKE} clean - -install: - cd src && ${MAKE} install - -uninstall: - cd src && ${MAKE} uninstall - -distclean: clean - rm -f make/defines.mk \ No newline at end of file diff --git a/gnbd-kernel/configure b/gnbd-kernel/configure deleted file mode 100755 index 430d161..0000000 --- a/gnbd-kernel/configure +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$kernel_src) { - $kernel_src="/usr/src/linux-2.6"; -} -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -open VER, "<$kernel_src/include/linux/version.h" or die "Can't open $kernel_src/include/linux/version.h"; -while(<VER>){ - chomp; - if( $_ =~ /^#define\s*UTS_RELEASE\s*"(.*)"$/ ){ - $kernel_version = $1; - $module_dir = "${prefix}/lib/modules/$1/kernel"; - } -} - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@KERNEL_VERSION@/$kernel_version/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@MODULE_DIR@/$module_dir/; - $_ =~ s/@SBINDIR@/$sbindir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/gnbd-kernel/make/defines.mk.input b/gnbd-kernel/make/defines.mk.input deleted file mode 100644 index 0c2ea7a..0000000 --- a/gnbd-kernel/make/defines.mk.input +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -module_dir ?= ${DESTDIR}/@MODULE_DIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ -KERNEL_VERSION = @KERNEL_VERSION@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} - -YACC = bison -YFLAGS = -y -d -LEX = flex -LFLAGS = -i -t - diff --git a/gnbd-kernel/make/release.mk.input b/gnbd-kernel/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/gnbd-kernel/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/gnbd-kernel/patches/2.6.9/00001.patch b/gnbd-kernel/patches/2.6.9/00001.patch deleted file mode 100644 index 7c02369..0000000 --- a/gnbd-kernel/patches/2.6.9/00001.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -urN linux-2.6.9/drivers/block/Kconfig linux-2.6.9-patched/drivers/block/Kconfig ---- linux-2.6.9/drivers/block/Kconfig 2004-10-18 16:53:43.000000000 -0500 -+++ linux-2.6.9-patched/drivers/block/Kconfig 2004-10-22 13:27:52.938836304 -0500 -@@ -356,6 +356,13 @@ - your machine, or if you want to have a raid or loopback device - bigger than 2TB. Otherwise say N. - -+config BLK_DEV_GNBD -+ tristate "Global network block device support" -+ depends on NET -+ ---help--- -+ -+ If unsure, say N. -+ - source "drivers/s390/block/Kconfig" - - endmenu -diff -urN linux-2.6.9/drivers/block/Makefile linux-2.6.9-patched/drivers/block/Makefile ---- linux-2.6.9/drivers/block/Makefile 2004-10-18 16:54:55.000000000 -0500 -+++ linux-2.6.9-patched/drivers/block/Makefile 2004-10-22 13:30:48.224188880 -0500 -@@ -43,4 +43,4 @@ - obj-$(CONFIG_VIODASD) += viodasd.o - obj-$(CONFIG_BLK_DEV_SX8) += sx8.o - obj-$(CONFIG_BLK_DEV_UB) += ub.o -- -+obj-$(CONFIG_BLK_DEV_GNBD) += gnbd.o diff --git a/gnbd-kernel/scripts/uninstall.pl b/gnbd-kernel/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/gnbd-kernel/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/gnbd-kernel/src/Makefile b/gnbd-kernel/src/Makefile deleted file mode 100644 index a2702f7..0000000 --- a/gnbd-kernel/src/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir = .. -ifndef USING_KBUILD -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl -endif - -linux_orig = ${top_srcdir}/patches/linux-orig -linux_patched = ${top_srcdir}/patches/linux-patched - - -PATCH_TARGET = gnbd.patch - -PWD := $(shell pwd) - -obj-m := gnbd.o -lock_gnbd-objs := gnbd.c - -EXTRA_CFLAGS += -I$(obj) - -all: - rm -f linux - ln -s . linux - ${MAKE} -C ${KERNEL_SRC} M=${PWD} modules USING_KBUILD=yes - -install: all - install -d ${incdir}/linux - install gnbd.h ${incdir}/linux - install -d ${module_dir}/drivers/block/gnbd - install gnbd.ko ${module_dir}/drivers/block/gnbd - -uninstall: - ${UNINSTALL} gnbd.ko ${module_dir}/drivers/block/gnbd - ${UNINSTALL} gnbd.h ${incdir}/linux - -clean: - rm -rf linux *.mod.c .gnbd.ko.cmd \ - .tmp_versions *o .*.o.cmd *~ - - -clean: - - -patches: pre add post - -pre: - @if [ ! -d ${linux_orig} ] ; then \ - echo "No linux source directory (${linux_orig})" ; \ - exit 1; \ - fi - mkdir -p ${linux_patched} - rsync -a --delete ${linux_orig}/ ${linux_patched}/ - -post: - ( cd ${top_srcdir}/patches ; diff -urN linux-orig linux-patched > ${PATCH_TARGET} ; exit 0 ) - -add: - cp gnbd.c ${linux_patched}/drivers/block/ - cp gnbd.h ${linux_patched}/include/linux/ diff --git a/gnbd-kernel/src/gnbd.c b/gnbd-kernel/src/gnbd.c deleted file mode 100644 index e355e79..0000000 --- a/gnbd-kernel/src/gnbd.c +++ /dev/null @@ -1,1054 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* Large chunks of this code were lifted from nbd.c */ - -#include <linux/major.h> - -#include <linux/blkdev.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/bio.h> -#include <linux/stat.h> -#include <linux/errno.h> -#include <linux/file.h> -#include <linux/ioctl.h> -#include <net/sock.h> -#include <linux/in.h> -#include <linux/buffer_head.h> -#include <linux/miscdevice.h> - -#include <linux/devfs_fs_kernel.h> - -#include <asm/uaccess.h> -#include <asm/types.h> - -#include <linux/gnbd.h> - -static int major_nr = 0; -uint64_t insmod_time; - - -#define GNBD_MAGIC 0x74d06100 - -#ifdef NDEBUG -#define dprintk(flags, fmt...) -#else /* NDEBUG */ -#define dprintk(flags, fmt...) do { \ - if (debugflags & (flags)) printk(KERN_DEBUG fmt); \ -} while (0) -#define DBG_IOCTL 0x0004 -#define DBG_INIT 0x0010 -#define DBG_EXIT 0x0020 -#define DBG_BLKDEV 0x0100 -#define DBG_RX 0x0200 -#define DBG_TX 0x0400 -static unsigned int debugflags; -#endif /* NDEBUG */ - -static struct gnbd_device gnbd_dev[MAX_GNBD]; - -struct request shutdown_req; -struct request ping_req; - -static spinlock_t gnbd_lock = SPIN_LOCK_UNLOCKED; - -#define to_gnbd_dev(d) container_of(d, struct gnbd_device, class_dev) - -static void gnbd_class_release(struct class_device *class_dev) -{ - /* FIXME -- What the hell do I have to free up here */ -} - -static struct class gnbd_class = { - .name = "gnbd", - .release = gnbd_class_release -}; - - -static ssize_t show_pid(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - return sprintf(buf, "%d\n", dev->receiver_pid); -} - -static CLASS_DEVICE_ATTR(pid, S_IRUGO, show_pid, NULL); - -static ssize_t show_server(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - if (dev->server_name) - return sprintf(buf, "%s/%hx\n", dev->server_name, - dev->server_port); - else - return sprintf(buf, "\n"); -} - -/* FIXME -- should a empty store free the memory */ -static ssize_t store_server(struct class_device *class_dev, - const char *buf, size_t count) -{ - int res; - short unsigned int port; - char *ptr; - struct gnbd_device *dev = to_gnbd_dev(class_dev); - if (down_trylock(&dev->do_it_lock)) - return -EBUSY; - if (dev->server_name) - kfree(dev->server_name); - dev->server_name = kmalloc(count + 1, GFP_KERNEL); - if (!dev->server_name) - return -ENOMEM; - memcpy(dev->server_name, buf, count); - dev->server_name[count] = 0; - ptr = strchr(dev->server_name, '/'); - if (!ptr) - return -EINVAL; - *ptr++ = 0; - res = sscanf(ptr, "%4hx", &port); - if (res != 1){ - up(&dev->do_it_lock); - return -EINVAL; - } - dev->server_port = port; - up(&dev->do_it_lock); - return count; -} - -CLASS_DEVICE_ATTR(server, S_IRUGO | S_IWUSR, show_server, store_server); - -static ssize_t show_name(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - return sprintf(buf, "%s\n", dev->name); -} - -static ssize_t store_name(struct class_device *class_dev, - const char *buf, size_t count) -{ - int res; - struct gnbd_device *dev = to_gnbd_dev(class_dev); - if (down_trylock(&dev->do_it_lock)) - return -EBUSY; - res = sscanf(buf, "%31s", dev->name); - up(&dev->do_it_lock); - if (res != 1) - return -EINVAL; - return count; -} - -CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_name, store_name); - - -static ssize_t show_sectors(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - return sprintf(buf, "%Lu\n", - (unsigned long long)get_capacity(dev->disk)); -} - -static ssize_t store_sectors(struct class_device *class_dev, - const char *buf, size_t count) -{ - int res; - sector_t size; - struct block_device *bdev; - struct gnbd_device *dev = to_gnbd_dev(class_dev); - - if (down_trylock(&dev->do_it_lock)) - return -EBUSY; - res = sscanf(buf, "%Lu\n", &size); - if (res != 1){ - up(&dev->do_it_lock); - return -EINVAL; - } - /* FIXME -- should I switch the order here, so that I don't have - capacity set to one thing and the bdev inode size set to another */ - set_capacity(dev->disk, size); - bdev = bdget_disk(dev->disk, 0); - if (bdev) { - down(&bdev->bd_inode->i_sem); - i_size_write(bdev->bd_inode, (loff_t)size << 9); - up(&bdev->bd_inode->i_sem); - bdput(bdev); - } - up(&dev->do_it_lock); - return count; -} - -CLASS_DEVICE_ATTR(sectors, S_IRUGO | S_IWUSR, show_sectors, store_sectors); - -static ssize_t show_usage(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - return sprintf(buf, "%d\n", dev->open_count); -} - -CLASS_DEVICE_ATTR(usage, S_IRUGO, show_usage, NULL); - -static ssize_t show_flags(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - return sprintf(buf, "0x%04x\n", dev->flags); -} - -static ssize_t store_flags(struct class_device *class_dev, - const char *buf, size_t count) -{ - int res; - - struct gnbd_device *dev = to_gnbd_dev(class_dev); - if (down_trylock(&dev->do_it_lock)) - return -EBUSY; - res = sscanf(buf, "0x%hx", &dev->flags); - up(&dev->do_it_lock); - if (res != 1) - return -EINVAL; - return count; -} - - -CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags); - -static ssize_t show_waittime(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - if (list_empty(&dev->queue_head)) - return sprintf(buf, "-1\n"); - return sprintf(buf, "%ld\n", - ((long)jiffies - (long)dev->last_received) / HZ); -} - -CLASS_DEVICE_ATTR(waittime, S_IRUGO, show_waittime, NULL); - -static ssize_t show_connected(struct class_device *class_dev, char *buf) -{ - struct gnbd_device *dev = to_gnbd_dev(class_dev); - return sprintf(buf, "%d\n", (dev->sock != NULL)); -} - -CLASS_DEVICE_ATTR(connected, S_IRUGO, show_connected, NULL); - -#ifndef NDEBUG -static const char *ioctl_cmd_to_ascii(int cmd) -{ - switch (cmd) { - case GNBD_DO_IT: return "do-it"; - case GNBD_CLEAR_QUE: return "clear-que"; - case GNBD_PRINT_DEBUG: return "print-debug"; - case GNBD_DISCONNECT: return "disconnect"; - } - return "unknown"; -} - -static const char *gnbdcmd_to_ascii(int cmd) -{ - switch (cmd) { - case GNBD_CMD_READ: return "read"; - case GNBD_CMD_WRITE: return "write"; - case GNBD_CMD_DISC: return "disconnect"; - case GNBD_CMD_PING: return "ping"; - } - return "invalid"; -} -#endif /* NDEBUG */ - -static void gnbd_end_request(struct request *req) -{ - int uptodate = (req->errors == 0) ? 1 : 0; - request_queue_t *q = req->q; - unsigned long flags; - - dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, - req, uptodate? "done": "failed"); - - if (!uptodate) - printk("%s %d called gnbd_end_request with an error\n", - current->comm, current->pid); - - spin_lock_irqsave(q->queue_lock, flags); - if (!end_that_request_first(req, uptodate, req->nr_sectors)) { - end_that_request_last(req); - } - spin_unlock_irqrestore(q->queue_lock, flags); -} - -/* - * Send or receive packet. - */ -static int sock_xmit(struct socket *sock, int send, void *buf, int size, - int msg_flags, int can_signal) -{ - mm_segment_t oldfs; - int result; - struct msghdr msg; - struct iovec iov; - unsigned long flags; - sigset_t oldset; - - oldfs = get_fs(); - set_fs(get_ds()); - spin_lock_irqsave(¤t->sighand->siglock, flags); - oldset = current->blocked; - sigfillset(¤t->blocked); - if (can_signal) - sigdelsetmask(¤t->blocked, sigmask(SIGKILL) | - sigmask(SIGTERM) | sigmask(SIGHUP)); - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); - - do { - sock->sk->sk_allocation = GFP_NOIO; - iov.iov_base = buf; - iov.iov_len = size; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_namelen = 0; - msg.msg_flags = msg_flags | MSG_NOSIGNAL; - - if (send) - result = sock_sendmsg(sock, &msg, size); - else - result = sock_recvmsg(sock, &msg, size, 0); - - if (can_signal && signal_pending(current)) { - siginfo_t info; - spin_lock_irqsave(¤t->sighand->siglock, flags); - printk(KERN_WARNING "gnbd (pid %d: %s) got signal %d\n", - current->pid, current->comm, - dequeue_signal(current, ¤t->blocked, &info)); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); - result = -EINTR; - break; - } - - if (result <= 0) { - if (result == 0) - result = -EPIPE; /* short read */ - break; - } - size -= result; - buf += result; - } while (size > 0); - - spin_lock_irqsave(¤t->sighand->siglock, flags); - current->blocked = oldset; - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); - - set_fs(oldfs); - return result; -} - -static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec, - int flags, int can_signal) -{ - int result; - void *kaddr = kmap(bvec->bv_page); - result = sock_xmit(sock, 1, kaddr + bvec->bv_offset, bvec->bv_len, - flags, can_signal); - kunmap(bvec->bv_page); - return result; -} - - -#define gnbd_send_req(dev, req, can_sig) \ -__gnbd_send_req((dev), (dev)->sock, (req), (can_sig)) - -int __gnbd_send_req(struct gnbd_device *dev, struct socket *sock, - struct request *req, int can_signal) -{ - int result, i, flags; - struct gnbd_request request; - unsigned long size = req->nr_sectors << 9; - - request.magic = htonl(GNBD_REQUEST_MAGIC); - request.type = htonl(gnbd_cmd(req)); - request.from = cpu_to_be64((u64) req->sector << 9); - request.len = htonl(size); - memcpy(request.handle, &req, sizeof(req)); - - down(&dev->tx_lock); - - if (!sock) { - printk(KERN_ERR "%s: Attempted send on closed socket\n", - dev->disk->disk_name); - result = -ENOTCONN; - goto error_out; - } - - dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%luB)\n", - dev->disk->disk_name, req, - gnbdcmd_to_ascii(gnbd_cmd(req)), - (unsigned long long)req->sector << 9, - req->nr_sectors << 9); - result = sock_xmit(sock, 1, &request, sizeof(request), - (gnbd_cmd(req) == GNBD_CMD_WRITE)? MSG_MORE: 0, - can_signal); - if (result < 0) { - printk(KERN_ERR "%s: Send control failed (result %d)\n", - dev->disk->disk_name, result); - goto error_out; - } - - if (gnbd_cmd(req) == GNBD_CMD_WRITE) { - struct bio *bio; - /* - * we are really probing at internals to determine - * whether to set MSG_MORE or not... - */ - rq_for_each_bio(bio, req) { - struct bio_vec *bvec; - bio_for_each_segment(bvec, bio, i) { - flags = 0; - if ((i < (bio->bi_vcnt - 1)) || bio->bi_next) - flags = MSG_MORE; - dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", - dev->disk->disk_name, req, - bvec->bv_len); - result = sock_send_bvec(sock, bvec, flags, - can_signal); - if (result < 0) { - printk(KERN_ERR "%s: Send data failed (result %d)\n", - dev->disk->disk_name, - result); - goto error_out; - } - } - } - } - up(&dev->tx_lock); - return 0; - -error_out: - up(&dev->tx_lock); - return result; -} - - -static int gnbd_find_request(struct gnbd_device *dev, struct request *xreq) -{ - struct request *req; - struct list_head *tmp; - - list_for_each(tmp, &dev->queue_head) { - req = list_entry(tmp, struct request, queuelist); - if (req != xreq) - continue; - return 1; - } - return 0; -} - -static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec) -{ - int result; - void *kaddr = kmap(bvec->bv_page); - result = sock_xmit(sock, 0, kaddr + bvec->bv_offset, bvec->bv_len, - MSG_WAITALL, 1); - kunmap(bvec->bv_page); - return result; -} - -int gnbd_recv_req(struct gnbd_device *dev, struct request *req) -{ - int result; - int i; - struct bio *bio; - rq_for_each_bio(bio, req) { - struct bio_vec *bvec; - bio_for_each_segment(bvec, bio, i) { - result = sock_recv_bvec(dev->sock, bvec); - if (result < 0) { - printk(KERN_ERR "%s: Receive data failed (result %d)\n", - dev->disk->disk_name, - result); - return result; - } - dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", - dev->disk->disk_name, req, bvec->bv_len); - } - } - return 0; -} - -int gnbd_do_it(struct gnbd_device *dev) -{ - int result; - struct gnbd_reply reply; - struct request *req; - struct socket *sock = dev->sock; - - BUG_ON(dev->magic != GNBD_MAGIC); - - while((result = sock_xmit(sock, 0, &reply,sizeof(reply), MSG_WAITALL, 1)) > 0){ - if (ntohl(reply.magic) == GNBD_KEEP_ALIVE_MAGIC) - /* FIXME -- I should reset the wait time here */ - continue; - - memcpy(&req, reply.handle, sizeof(req)); - if (req == &shutdown_req) - return 0; - - if (!gnbd_find_request(dev, req)){ - printk(KERN_ERR "%s: Unexpected reply (%p)\n", - dev->disk->disk_name, reply.handle); - return -EBADR; - } - if (ntohl(reply.magic) != GNBD_REPLY_MAGIC) { - printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", - dev->disk->disk_name, - (unsigned long)ntohl(reply.magic)); - return -EPROTO; - } - if (ntohl(reply.error)) { - printk(KERN_ERR "%s: Other side returned error (%d)\n", - dev->disk->disk_name, ntohl(reply.error)); - req->errors++; - goto remove_req; - } - dprintk(DBG_RX, "%s: request %p: got reply\n", - dev->disk->disk_name, req); - - if (gnbd_cmd(req) == GNBD_CMD_READ){ - result = gnbd_recv_req(dev, req); - if (result < 0) - return result; - } -remove_req: - spin_lock(&dev->queue_lock); - list_del_init(&req->queuelist); - dev->last_received = jiffies; - spin_unlock(&dev->queue_lock); - if (req != &ping_req) - gnbd_end_request(req); - } - printk(KERN_ERR "%s: Receive control failed (result %d)\n", - dev->disk->disk_name, result); - return result; -} - -void gnbd_clear_que(struct gnbd_device *dev) -{ - struct request *req; - - BUG_ON(dev->magic != GNBD_MAGIC); - - do { - req = NULL; - if (!list_empty(&dev->queue_head)) { - req = list_entry(dev->queue_head.next, struct request, queuelist); - list_del_init(&req->queuelist); - } - if (req && req != &ping_req) { - req->errors++; - gnbd_end_request(req); - } - } while (req); -} - -/* - * We always wait for result of write, for now. It would be nice to make it optional - * in future - * if ((req->cmd == WRITE) && (dev->flags & GNBD_WRITE_NOCHK)) - * { printk( "Warning: Ignoring result!\n"); gnbd_end_request( req ); } - */ - -static void do_gnbd_request(request_queue_t * q) -{ - int err; - struct request *req; - - while ((req = elv_next_request(q)) != NULL) { - struct gnbd_device *dev; - - blkdev_dequeue_request(req); - dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n", - req->rq_disk->disk_name, req, req->flags); - - if (!(req->flags & REQ_CMD)) - goto error_out; - - dev = req->rq_disk->private_data; - - if (dev->receiver_pid == -1) - goto error_out; - - BUG_ON(dev->magic != GNBD_MAGIC); - - gnbd_cmd(req) = GNBD_CMD_READ; - if (rq_data_dir(req) == WRITE) { - gnbd_cmd(req) = GNBD_CMD_WRITE; - if (dev->flags & GNBD_READ_ONLY) { - printk(KERN_ERR "%s: Write on read-only\n", - dev->disk->disk_name); - goto error_out; - } - } - - req->errors = 0; - spin_unlock_irq(q->queue_lock); - - spin_lock(&dev->queue_lock); - - if (list_empty(&dev->queue_head)) - dev->last_received = jiffies; - list_add(&req->queuelist, &dev->queue_head); - spin_unlock(&dev->queue_lock); - - err = gnbd_send_req(dev, req, 0); - - spin_lock_irq(q->queue_lock); - if (err) - goto sock_error; - continue; - -error_out: - req->errors++; - spin_unlock(q->queue_lock); - gnbd_end_request(req); - spin_lock(q->queue_lock); - } - return; - -sock_error: - return; -} - -/* - * This is called before dev-sock is set, so you dodn't need - * to worry about the tx_lock or the queue_lock - */ -static int gnbd_resend_requests(struct gnbd_device *dev, struct socket *sock) -{ - int err = 0; - struct request *req; - struct list_head *tmp; - - printk("resending requests\n"); - list_for_each(tmp, &dev->queue_head) { - req = list_entry(tmp, struct request, queuelist); - err = __gnbd_send_req(dev, sock, req, 1); - - if (err){ - printk("failed trying to resend request (%d)\n", err); - break; - } - } - - return err; -} -/* -static int get_server_info(struct gnbd_device *dev, struct socket *sock) -{ - struct sockaddr_in server; - int len; - int err; - - err = sock->ops->getname(sock, (struct sockaddr *) &server, &len, 1); - if (err) { - printk(KERN_WARNING "cannot get socket info, shutting down\n"); - } else{ - dev->server_addr = server.sin_addr; - dev->server_port = server.sin_port; - } - return err; -} -*/ - -static int gnbd_ctl_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct gnbd_device *dev = NULL; - struct block_device *bdev; - do_it_req_t req; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (cmd == GNBD_DISCONNECT || cmd == GNBD_CLEAR_QUE || - cmd == GNBD_PING || cmd == GNBD_PRINT_DEBUG) { - if (arg >= MAX_GNBD) - return -EINVAL; - dev = &gnbd_dev[arg]; - BUG_ON(dev->magic != GNBD_MAGIC); - } - - /* Anyone capable of this syscall can do *real bad* things */ - dprintk(DBG_IOCTL, "%s: gnbd_ioctl cmd=%s(0x%x) arg=%lu\n", - dev->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); - - switch (cmd) { - case GNBD_DISCONNECT: - printk(KERN_INFO "%s: GNBD_DISCONNECT\n", dev->disk->disk_name); - spin_lock(&dev->open_lock); - if (dev->open_count > 0){ - spin_unlock(&dev->open_lock); - return -EBUSY; - } - dev->receiver_pid = -1; - spin_unlock(&dev->open_lock); - /* There is no one using the device, you can disconnect it */ - if (dev->sock == NULL) - return -ENOTCONN; - gnbd_send_req(dev, &shutdown_req, 1); - return 0; - case GNBD_CLEAR_QUE: - if (down_interruptible(&dev->do_it_lock)) - return -EBUSY; - dev->receiver_pid = -1; - gnbd_clear_que(dev); - bdev = dev->bdev; - if (bdev) { - blk_run_queue(dev->disk->queue); - fsync_bdev(bdev); - invalidate_bdev(bdev, 0); - } - up(&dev->do_it_lock); - return 0; - case GNBD_DO_IT: - if (copy_from_user(&req, (do_it_req_t *)arg, sizeof(req))) - return -EFAULT; - if (req.minor >= 128) - return -EINVAL; - dev = &gnbd_dev[req.minor]; - BUG_ON(dev->magic != GNBD_MAGIC); - if (dev->file) - return -EBUSY; - error = -EINVAL; - file = fget(req.sock_fd); - if (!file) - return error; - inode = file->f_dentry->d_inode; - if (!inode->i_sock) { - fput(file); - return error; - } - if (down_trylock(&dev->do_it_lock)){ - fput(file); - return -EBUSY; - } - error = gnbd_resend_requests(dev, SOCKET_I(inode)); - if (error){ - printk("quitting NBD_DO_IT\n"); - up(&dev->do_it_lock); - fput(file); - return error; - } - dev->file = file; - dev->sock = SOCKET_I(inode); - dev->receiver_pid = current->pid; - blk_run_queue(dev->disk->queue); - error = gnbd_do_it(dev); - /* should I kill the socket first */ - up(&dev->do_it_lock); - down(&dev->tx_lock); - if (dev->sock) { - printk(KERN_WARNING "%s: shutting down socket\n", - dev->disk->disk_name); - dev->sock->ops->shutdown(dev->sock, - SEND_SHUTDOWN|RCV_SHUTDOWN); - dev->sock = NULL; - } - up(&dev->tx_lock); - file = dev->file; - dev->file = NULL; - if (file) - fput(file); - printk("exitting GNBD_DO_IT ioctl\n"); - return error; - case GNBD_PING: - /* FIXME -- should I allow pings if everything is compeletely - * shutdown */ - spin_lock(&dev->queue_lock); - /* only one outstanding ping at a time */ - if (list_empty(&ping_req.queuelist)){ - if (list_empty(&dev->queue_head)) - dev->last_received = jiffies; - list_add(&ping_req.queuelist, &dev->queue_head); - } - spin_unlock(&dev->queue_lock); - gnbd_send_req(dev, &ping_req, 1); /* ignore the errors */ - return 0; - case GNBD_PRINT_DEBUG: - printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n", - dev->disk->disk_name, - dev->queue_head.next, dev->queue_head.prev, - &dev->queue_head); - return 0; - case GNBD_GET_TIME: - if (copy_to_user((void *)arg, &insmod_time, sizeof(uint64_t))){ - printk(KERN_WARNING "couldn't compy time argument to user\n"); - return -EFAULT; - } - return 0; - } - /* FIXME -- should I print something, is EINVAL the right error */ - return -EINVAL; -} - -static int gnbd_open(struct inode *inode, struct file *file) -{ - struct gnbd_device *dev = inode->i_bdev->bd_disk->private_data; - spin_lock(&dev->open_lock); - if (dev->receiver_pid == -1){ - spin_unlock(&dev->open_lock); - return -ENXIO; - } - spin_unlock(&dev->open_lock); - if ((file->f_mode & FMODE_WRITE) && (dev->flags & GNBD_READ_ONLY)){ - printk(KERN_INFO "cannot open read only gnbd device read/write"); - return -EROFS; - } - - dev->open_count++; - dev->bdev = inode->i_bdev; - return 0; -} - -/* FIXME -- I don't sync the device at close. This means that If you write - * something, and close the device, and expect that then it is written, - * you are wrong.... This might cause problems */ -static int gnbd_release(struct inode *inode, struct file *file) -{ - struct gnbd_device *dev = inode->i_bdev->bd_disk->private_data; - - dev->open_count--; - if (dev->open_count == 0) - dev->bdev = NULL; - return 0; -} - -static struct file_operations _gnbd_ctl_fops = -{ - .ioctl = gnbd_ctl_ioctl, - .owner = THIS_MODULE, -}; - -static struct miscdevice _gnbd_misc = -{ - .minor = MISC_DYNAMIC_MINOR, - .name = "gnbd_ctl", - .devfs_name = "gnbd_ctl", - .fops = &_gnbd_ctl_fops -}; - -/* FIXME -- I should probably do more here */ -int __init gnbd_ctl_init(void) -{ - int err; - - err = misc_register(&_gnbd_misc); - if (err) { - printk("cannot register control device\n"); - return err; - } - return 0; -} - -void gnbd_ctl_cleanup(void) -{ - if (misc_deregister(&_gnbd_misc) < 0) - printk("cannot deregister control device\n"); -} - -static struct block_device_operations gnbd_fops = -{ - .open = gnbd_open, - .release = gnbd_release, - .owner = THIS_MODULE, -}; - -/* - * And here should be modules and kernel interface - * (Just smiley confuses emacs :-) - */ - -static int __init gnbd_init(void) -{ - int err = -ENOMEM; - struct timeval tv; - int i; - - if (sizeof(struct gnbd_request) != 28) { - printk(KERN_CRIT "gnbd: sizeof gnbd_request needs to be 28 in order to work!\n" ); - return -EIO; - } - shutdown_req.flags = REQ_SPECIAL; - gnbd_cmd(&shutdown_req) = GNBD_CMD_DISC; - shutdown_req.sector = 0; - shutdown_req.nr_sectors = 0; - - ping_req.flags = REQ_SPECIAL; - gnbd_cmd(&ping_req) = GNBD_CMD_PING; - ping_req.sector = 0; - ping_req.nr_sectors = 0; - - for (i = 0; i < MAX_GNBD; i++) { - struct gendisk *disk = alloc_disk(1); - if (!disk) - goto out; - gnbd_dev[i].disk = disk; - /* - * The new linux 2.5 block layer implementation requires - * every gendisk to have its very own request_queue struct. - * These structs are big so we dynamically allocate them. - */ - disk->queue = blk_init_queue(do_gnbd_request, &gnbd_lock); - if (!disk->queue) { - put_disk(disk); - goto out; - } - } - major_nr = register_blkdev(major_nr, "gnbd"); - if (major_nr < 0) { - printk("gnbd: unable to get a major number\n"); - err = major_nr; - goto out; - } - - printk(KERN_INFO "gnbd: registered device at major %d\n", major_nr); - dprintk(DBG_INIT, "gnbd: debugflags=0x%x\n", debugflags); - - devfs_mk_dir("gnbd_minor"); - err = class_register(&gnbd_class); - if (err) - goto out_unregister; - for (i = 0; i < MAX_GNBD; i++) { - struct gendisk *disk = gnbd_dev[i].disk; - gnbd_dev[i].file = NULL; - gnbd_dev[i].magic = GNBD_MAGIC; - gnbd_dev[i].flags = 0; - gnbd_dev[i].open_count = 0; - gnbd_dev[i].receiver_pid = -1; - gnbd_dev[i].server_name = NULL; - gnbd_dev[i].server_port = 0; - gnbd_dev[i].name[0] = '\0'; - gnbd_dev[i].bdev = NULL; - spin_lock_init(&gnbd_dev[i].queue_lock); - spin_lock_init(&gnbd_dev[i].open_lock); - INIT_LIST_HEAD(&gnbd_dev[i].queue_head); - init_MUTEX(&gnbd_dev[i].tx_lock); - init_MUTEX(&gnbd_dev[i].do_it_lock); - gnbd_dev[i].class_dev.class = &gnbd_class; - sprintf(gnbd_dev[i].class_dev.class_id, "gnbd%d", i); - err = class_device_register(&gnbd_dev[i].class_dev); - if (err){ - printk("class_device_register failed with %d\n", err); - goto out_unregister_class; - } - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_pid)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_server)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_name)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_sectors)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_usage)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_flags)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_waittime)) - goto out_remove_file; - if(class_device_create_file(&gnbd_dev[i].class_dev, - &class_device_attr_connected)) - goto out_remove_file; - disk->major = major_nr; - disk->first_minor = i; - disk->fops = &gnbd_fops; - disk->private_data = &gnbd_dev[i]; - sprintf(disk->disk_name, "gnbd%d", i); - sprintf(disk->devfs_name, "gnbd_minor/%d", i); - set_capacity(disk, 0); - add_disk(disk); - if(sysfs_create_link(&gnbd_dev[i].class_dev.kobj, - &gnbd_dev[i].disk->kobj, "block")) - goto out_remove_disk; - - } - - err = gnbd_ctl_init(); - if (err) - goto out_unregister_class; - - insmod_time = (uint64_t) tv.tv_sec * 1000000 + tv.tv_usec; - - return 0; -out_remove_disk: - del_gendisk(gnbd_dev[i].disk); -out_remove_file: - class_device_unregister(&gnbd_dev[i].class_dev); -out_unregister_class: - while(i--){ - del_gendisk(gnbd_dev[i].disk); - class_device_unregister(&gnbd_dev[i].class_dev); - } - i = MAX_GNBD; - class_unregister(&gnbd_class); -out_unregister: - unregister_blkdev(major_nr, "gnbd"); -out: - while (i--) { - blk_cleanup_queue(gnbd_dev[i].disk->queue); - put_disk(gnbd_dev[i].disk); - } - return err; -} - -static void __exit gnbd_cleanup(void) -{ - int i; - - gnbd_ctl_cleanup(); - for (i = 0; i < MAX_GNBD; i++) { - struct gendisk *disk = gnbd_dev[i].disk; - class_device_unregister(&gnbd_dev[i].class_dev); - if (disk) { - del_gendisk(disk); - blk_cleanup_queue(disk->queue); - put_disk(disk); - } - if (gnbd_dev[i].server_name) - kfree(gnbd_dev[i].server_name); - } - class_unregister(&gnbd_class); - devfs_remove("gnbd"); - unregister_blkdev(major_nr, "gnbd"); - printk(KERN_INFO "gnbd: unregistered device at major %d\n", major_nr); -} - -module_init(gnbd_init); -module_exit(gnbd_cleanup); - -MODULE_DESCRIPTION("Network Block Device"); -MODULE_LICENSE("GPL"); - -#ifndef NDEBUG -MODULE_PARM(debugflags, "i"); -MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); -#endif diff --git a/gnbd-kernel/src/gnbd.h b/gnbd-kernel/src/gnbd.h deleted file mode 100644 index b88ad26..0000000 --- a/gnbd-kernel/src/gnbd.h +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef LINUX_GNBD_H -#define LINUX_GNBD_H - -#define GNBD_DO_IT _IO( 0xab, 0x20 ) -#define GNBD_CLEAR_QUE _IO( 0xab, 0x21 ) -#define GNBD_PRINT_DEBUG _IO( 0xab, 0x22 ) -#define GNBD_DISCONNECT _IO( 0xab, 0x23 ) -#define GNBD_PING _IO( 0xab, 0x24 ) -#define GNBD_GET_TIME _IO( 0xab, 0x25 ) - -enum { - GNBD_CMD_READ = 0, - GNBD_CMD_WRITE = 1, - GNBD_CMD_DISC = 2, - GNBD_CMD_PING = 3 -}; - -#define gnbd_cmd(req) ((req)->cmd[0]) -#define MAX_GNBD 128 - -/* values for flags field */ -#define GNBD_READ_ONLY 0x0001 - -/* userspace doesn't need the gnbd_device structure */ -#ifdef __KERNEL__ - -struct gnbd_device { - unsigned short int flags; - struct socket * sock; - struct file * file; /* If == NULL, device is not ready, yet */ - int magic; - spinlock_t queue_lock; - spinlock_t open_lock; - struct list_head queue_head;/* Requests are added here... */ - struct semaphore tx_lock; - struct gendisk *disk; - pid_t receiver_pid; - struct semaphore do_it_lock; - int open_count; - struct class_device class_dev; - unsigned short int server_port; - char *server_name; - char name[32]; - unsigned long last_received; - struct block_device *bdev; -}; - -#endif /* __KERNEL__ */ - -/* These are sent over the network in the request/reply magic fields */ - -#define GNBD_REQUEST_MAGIC 0x37a07e00 -#define GNBD_REPLY_MAGIC 0x41f09370 -#define GNBD_KEEP_ALIVE_MAGIC 0x5B46D8C2 -/* Do *not* use magics: 0x12560953 0x96744668. */ - -/* - * This is the packet used for communication between client and - * server. All data are in network byte order. - */ -struct gnbd_request { - uint32_t magic; - uint32_t type; /* == READ || == WRITE why so long */ - char handle[8]; /* why is this a char array instead of a u64 */ - uint64_t from; - uint32_t len; -} -#ifdef __GNUC__ - __attribute__ ((packed)) -#endif /* __GNUC__ */ -; - -/* - * This is the reply packet that gnbd-server sends back to the client after - * it has completed an I/O request (or an error occurs). - */ -#define SIZE_OF_REPLY 16 -struct gnbd_reply { - uint32_t magic; - uint32_t error; /* 0 = ok, else error */ - char handle[8]; /* handle you got from request */ -}; - -struct do_it_req_s { - unsigned int minor; - int sock_fd; -}; -typedef struct do_it_req_s do_it_req_t; - -#endif /* LINUX_GNBD_H */ diff --git a/gnbd/COPYING b/gnbd/COPYING deleted file mode 100644 index 5b6e7c6..0000000 --- a/gnbd/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. -
- GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) -
-These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. -
- 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -
- 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/gnbd/Makefile b/gnbd/Makefile deleted file mode 100644 index 13c6837..0000000 --- a/gnbd/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -all: - cd client && ${MAKE} copytobin - cd server && ${MAKE} copytobin - cd tools && ${MAKE} copytobin - -clean: - cd bin && ${MAKE} clean - cd client && ${MAKE} clean - cd server && ${MAKE} clean - cd tools && ${MAKE} clean - -distclean: clean - rm -f make/defines.mk - -install: - cd bin && ${MAKE} install - cd man && ${MAKE} install - -deinstall uninstall: - cd bin && ${MAKE} uninstall - cd man && ${MAKE} uninstall - diff --git a/gnbd/bin/Makefile b/gnbd/bin/Makefile deleted file mode 100644 index 311135f..0000000 --- a/gnbd/bin/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. - -UNINSTALL= ${top_srcdir}/scripts/uninstall.pl - -SBINPROGS= \ - gnbd_export \ - gnbd_import \ - fence_gnbd \ - gnbd_recvd \ - gnbd_serv \ - gnbd_monitor \ - gnbd_clusterd \ - gnbd_get_uid - -include ${top_srcdir}/make/defines.mk - -all: - cd ..; ${MAKE} all - -clean: - @echo -n Removing all copied files... - @for f in `ls . | grep -v -i "makefile|cvs"`; do rm -f $$f; done - @echo done. - -install: all - if [ ! -d ${sbindir} ]; then \ - install -d ${sbindir}; \ - fi - for v in ${SBINPROGS}; do \ - install -m755 $${v} ${sbindir}; \ - done - -uninstall: - ${UNINSTALL} ${SBINPROGS} ${sbindir} - -copytobin: - - diff --git a/gnbd/client/Makefile b/gnbd/client/Makefile deleted file mode 100644 index e953be9..0000000 --- a/gnbd/client/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -TARGET= gnbd_recvd gnbd_monitor - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -RECV_SOURCE= gnbd_recvd.c $(top_srcdir)/utils/trans.c \ - $(top_srcdir)/utils/gnbd_utils.c - -MONITOR_SRC= gnbd_monitor.c monitor_req.c $(top_srcdir)/utils/trans.c \ - $(top_srcdir)/utils/gnbd_utils.c - -INCLUDE= -I$(top_srcdir)/include -I$(top_srcdir)/server -I$(top_srcdir)/utils \ - -I${top_srcdir}/config -I${incdir} - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -- which is incdir, which is already included -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gnbd.h ]; then \ - echo '-I${KERNEL_SRC}/include'; fi) -endif - -LDLIBS+= -L${libdir} -lmagma -ldl -lpthread - -CFLAGS+= -O2 -DGNBD_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -gnbd_recvd: ${RECV_SOURCE} - ${CC} ${CFLAGS} ${LDFLAGS} ${RECV_SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -gnbd_monitor: ${MONITOR_SRC} - ${CC} ${CFLAGS} ${LDFLAGS} ${MONITOR_SRC} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o *~ ${TARGET} diff --git a/gnbd/client/gnbd_monitor.c b/gnbd/client/gnbd_monitor.c deleted file mode 100644 index f3a4d3c..0000000 --- a/gnbd/client/gnbd_monitor.c +++ /dev/null @@ -1,786 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/poll.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <inttypes.h> -#include <magma.h> -#include <netdb.h> -#include <netinet/in.h> -#include <linux/gnbd.h> - -#include "gnbd_endian.h" -#include "list.h" -#include "trans.h" -#include "gnbd_utils.h" -#include "extern_req.h" -#include "gnbd_monitor.h" - -struct connection_s { - uint32_t action; - int size; - char *buf; - int dev; /* minor_nr of device that this connection applies to */ -}; -typedef struct connection_s connection_t; - -struct waiter_s { - pid_t pid; - int minor; - list_t list; -}; -typedef struct waiter_s waiter_t; - -list_decl(waiter_list); -connection_t *connections; -struct pollfd *polls; -int max_id; -char node_name[65]; -unsigned int checks = 0; - -#define BUFSIZE (sizeof(monitor_info_t) + sizeof(uint32_t)) -#define RESTART_CHECK 10 - -cluster_member_list_t *cluster_members; - -#define CLUSTER 0 -#define CONNECT 1 - -list_t monitor_list; - - -struct monitor_s { - int minor_nr; - int timeout; - int state; - char server[65]; - list_t list; -}; -typedef struct monitor_s monitor_t; - -monitor_t *find_device(int minor_nr){ - list_t *item; - monitor_t *dev; - - list_foreach(item, &monitor_list){ - dev = list_entry(item, monitor_t, list); - if (dev->minor_nr == minor_nr) - return dev; - } - return NULL; -} - -void remove_device(int minor_nr) -{ - monitor_t *dev; - - if( (dev = find_device(minor_nr)) != NULL){ - block_sigchld(); - list_del(&dev->list); - free(dev); - unblock_sigchld(); - } - return; -} - -int monitor_device(int minor_nr, int timeout, char *server) -{ - monitor_t *dev; - - if (strlen(server) > 64) - return -EINVAL; - - if (find_device(minor_nr) != NULL) - return 0; - dev = (monitor_t *)malloc(sizeof(monitor_t)); - if (!dev) - return -ENOMEM; - dev->minor_nr = minor_nr; - dev->timeout = timeout; - memcpy(dev->server, server, 65); - dev->state = NORMAL_STATE; - list_add(&dev->list, &monitor_list); - return 0; -} - -void setup_poll(void) -{ - int i; - polls = malloc(open_max() * sizeof(struct pollfd)); - if (!polls) - fail_startup("cannot allocate poller structure : %s\n", strerror(errno)); - connections = malloc(open_max() * sizeof(connection_t)); - if (!connections) - fail_startup("cannot allocate connection structures : %s\n", - strerror(errno)); - polls[CLUSTER].fd = clu_connect(NULL, 0); - if (polls[CLUSTER].fd < 0) - fail_startup("cannot connect to cluster manager : %s\n", - strerror(-(polls[CLUSTER].fd))); - cluster_members = clu_member_list(NULL); - if (!cluster_members) - fail_startup("cannot get initial member list\n"); - if (memb_resolve_list(cluster_members, NULL) < 0) - fail_startup("cannot resolve member list\n"); - polls[CLUSTER].events = POLLIN; - connections[CLUSTER].buf = malloc(BUFSIZE); - if (!connections[CLUSTER].buf) - fail_startup("couldn't allocation memory for cluster connection buffer\n"); - connections[CLUSTER].action = 0; - connections[CLUSTER].size = 0; - connections[CLUSTER].dev = -1; - polls[CONNECT].fd = start_comm_device("gnbd_monitorcomm"); - polls[CONNECT].events = POLLIN; - for(i = 2; i < open_max(); i++){ - polls[i].fd = -1; - polls[i].revents = 0; - } - max_id = 1; -} - -void close_poller(int index){ - close(polls[index].fd); - if (index == CLUSTER){ - log_err("lost connection to the cluster manager\n"); - /* FIXME -- should do something different */ - exit(1); - } - if (index == CONNECT){ - log_err("lost request socket\n"); - /* FIXME -- again, don't do this */ - exit(1); - } - polls[index].fd = -1; - polls[index].revents = 0; - free(connections[index].buf); - while(polls[max_id].fd == -1) - max_id--; -} - -void accept_connection(void) -{ - int sock; - struct sockaddr_un addr; - socklen_t len = sizeof(addr); - int i; - - sock = accept(polls[CONNECT].fd, (struct sockaddr *)&addr, &len); - if (sock < 0){ - log_err("error accepting connect to unix socket : %s\n", strerror(errno)); - return; - } - for (i = 0; polls[i].fd >= 0 && i < open_max(); i++); - if (i >= open_max()){ - log_err("maximum number of open file descriptors reached\n"); - close(sock); - return; - } - connections[i].buf = malloc(BUFSIZE); - if (!connections[i].buf){ - log_err("couldn't allocate memory for connection buffer\n"); - close(sock); - return; - } - connections[i].action = 0; - connections[i].size = 0; - connections[i].dev = -1; - polls[i].fd = sock; - polls[i].events = POLLIN; - if (i > max_id) - max_id = i; -} - -#define DO_TRANS(action, label)\ -do {\ - if ((action)){\ - log_err("request transfer failed at line %d : %s\n", \ - __LINE__, strerror(errno));\ - goto label;\ - }\ -} while(0) - -int get_monitor_list(char **buffer, unsigned int *list_size) -{ - monitor_info_t *ptr; - monitor_t *dev; - list_t *item; - int count = 0; - - *buffer = NULL; - list_foreach(item, &monitor_list) - count++; - if (count == 0){ - *list_size = 0; - return 0; - } - ptr = (monitor_info_t *)malloc(sizeof(monitor_info_t) * count); - if (!ptr){ - log_err("cannot allocate memory for monitor list\n"); - return -ENOMEM; - } - *buffer = (char *)ptr; - *list_size = (unsigned int)(sizeof(monitor_info_t) * count); - list_foreach(item, &monitor_list){ - dev = list_entry(item, monitor_t, list); - ptr->minor_nr = dev->minor_nr; - ptr->timeout = dev->timeout; - ptr->state = dev->state; - ptr++; - } - - return 0; -} - -cluster_member_t *check_for_node(cluster_member_list_t *list, char *node) -{ - int i; - - for(i = 0; i < list->cml_count; i++){ - if (!strcmp(list->cml_members[i].cm_name, node)) - return &list->cml_members[i]; - } - return NULL; -} - -void do_fail_device(waiter_t *waiter) -{ - int fd; - pid_t pid; - - if( (pid = fork()) < 0){ - log_err("cannot fork child to fail device #%d : %s\n", waiter->minor, - strerror(errno)); - exit(1); - } - - if (pid != 0){ - waiter->pid = pid; - return; - } - - unblock_sigchld(); - - if( (fd = open("/dev/gnbd_ctl", O_RDWR)) < 0){ - log_err("cannot open /dev/gnbd_ctl : %s\n", strerror(errno)); - exit(1); - } - if (sscanf(get_sysfs_attr(waiter->minor, "pid"), "%d", &pid) != 1){ - log_err("cannot parse /sys/class/gnbd/gnbd%d/pid\n", waiter->minor); - exit(1); - } - kill(pid, SIGKILL); - if (ioctl(fd, GNBD_CLEAR_QUE, (unsigned long)waiter->minor) < 0){ - log_err("cannot clear gnbd device #%d queue : %s\n", waiter->minor, - strerror(errno)); - exit(1); - } - exit(0); -} - -void sig_chld(int sig) -{ - int status; - pid_t pid; - list_t *list_item; - waiter_t *tmp, *waiter; - int redo; - monitor_t *dev; - - while( (pid = waitpid(-1, &status, WNOHANG)) > 0){ - redo = 0; - waiter = NULL; - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - redo = 1; - list_foreach(list_item, &waiter_list){ - tmp = list_entry(list_item, waiter_t, list); - if (tmp->pid == pid){ - waiter = tmp; - break; - } - } - if (waiter){ - if (redo) - do_fail_device(waiter); - else{ - if( (dev = find_device(waiter->minor)) != NULL) - dev->state = RESET_STATE; - waiter->pid = -1; - } - } - } -} - -void fail_device(monitor_t *dev) -{ - list_t *list_item, *tmp; - waiter_t *waiter; - - block_sigchld(); - - list_foreach_safe(list_item, &waiter_list, tmp) { - waiter = list_entry(list_item, waiter_t, list); - if (waiter->pid == -1){ - list_del(&waiter->list); - free(waiter); - } - } - waiter = malloc(sizeof(waiter_t)); - if (!waiter){ - log_err("cannot allocate memory to fail_device #%d\n", dev->minor_nr); - exit(1); - } - waiter->minor = dev->minor_nr; - list_add(&waiter->list, &waiter_list); - do_fail_device(waiter); - unblock_sigchld(); -} - -void fail_devices(cluster_member_list_t *nodes) -{ - monitor_t *dev; - list_t *item, *next; - - if (!nodes) - return; - list_foreach_safe(item, &monitor_list, next){ - dev = list_entry(item, monitor_t, list); - if (check_for_node(nodes, dev->server)){ - fail_device(dev); - } - } -} - -void handle_cluster_msg(void) -{ - int event; - cluster_member_list_t *new, *lost; - - event = clu_get_event(polls[CLUSTER].fd); - if (event == CE_SHUTDOWN){ - log_err("lost connection to cluster manager\n"); - /* FIXME -- need to retry.. Can't just give up */ - exit(1); - } - else if (event != CE_INQUORATE && event != CE_SUSPEND){ - new = clu_member_list(NULL); - lost = memb_lost(cluster_members, new); - cml_free(cluster_members); - cluster_members = new; - - fail_devices(lost); - cml_free(lost); - } -} - -void handle_msg(int index){ - connection_t *connection = &connections[index]; - uint32_t reply = MONITOR_SUCCESS_REPLY; - int sock; - int bytes; - int err; - - sock = polls[index].fd; - - bytes = read(sock, connection->buf + connection->size, - BUFSIZE - connection->size); - if (bytes <= 0){ - if (bytes == 0) - log_err("unexpectedly read EOF on connection, device: %d, action: %d\n", - connection->dev, connection->action); - else if (errno != EINTR) - log_err("cannot read from connection, device: %d, action: %d : %s\n", - connection->dev, connection->action, strerror(errno)); - log_verbose("total read : %d bytes\n", connection->size); - close_poller(index); - return; - } - - connection->size += bytes; - if (connection->size < sizeof(uint32_t)) - return; - if (connection->action == 0) - memcpy(&connection->action, connection->buf, sizeof(uint32_t)); - - switch(connection->action){ - case MONITOR_REQ: - { - monitor_info_t info; - if (connection->size < sizeof(uint32_t) + sizeof(info)) - return; - memcpy(&info, connection->buf + sizeof(uint32_t), sizeof(info)); - err = monitor_device(info.minor_nr, info.timeout, info.server); - if (err) - reply = -err; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - } - break; - case REMOVE_REQ: - { - int minor; - if (connection->size < sizeof(uint32_t) + sizeof(minor)) - return; - memcpy(&minor, connection->buf + sizeof(uint32_t), sizeof(minor)); - remove_device(minor); - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - } - break; - case LIST_REQ: - { - char *buffer = NULL; - unsigned int size; - - err = get_monitor_list(&buffer, &size); - if (err < 0){ - reply = -err; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), list_exit); - DO_TRANS(retry_write(sock, &size, sizeof(size)), list_exit); - if (size) - DO_TRANS(retry_write(sock, buffer, size), list_exit); - - list_exit: - free(buffer); - break; - } - default: - log_err("unknown request 0x%x\n", connection->action); - reply = ENOTTY; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - } - exit: - close_poller(index); -} - -cluster_member_t *get_failover_server(monitor_t *dev) -{ - cluster_member_t *server; - list_t *item; - monitor_t *other_dev; - - server = check_for_node(cluster_members, dev->server); - if (server == NULL){ - log_err("server %s is not a cluster member, cannot fence.\n", dev->server); - return NULL; - } - list_foreach(item, &monitor_list){ - other_dev = list_entry(item, monitor_t, list); - if (!strcmp(other_dev->server, dev->server)) - continue; - if (other_dev->state == NORMAL_STATE) - return server; - } - return NULL; -} - -int check_recvd(monitor_t *dev) -{ - char filename[32]; - int ret; - int pid; - - snprintf(filename, 32, "gnbd_recvd-%d.pid", dev->minor_nr); - ret = __check_lock(filename, &pid); - /* If we can't get the lock, ret is either 0 or -1. If it's -1, we've */ - /* got an error, in which case we log it. If 0, the lock file doesn't */ - /* exist yet, in which case we silently wait for it without complaining. */ - if (ret < 0) - log_err("cannot check lockfile %s/%s : %s\n", program_dir, filename, - strerror(errno)); - else - ret = pid; - return ret; -} - -int check_usage(monitor_t *dev) -{ - int usage; - - if (sscanf(get_sysfs_attr(dev->minor_nr, "usage"), "%d", &usage) != 1){ - log_err("cannot parse /sys/class/gnbd/gnbd%d/usage\n", dev->minor_nr); - exit(1); - } - return usage; -} - -int start_recvd(monitor_t *dev) -{ - int i; - pid_t pid; - int status; - char minor_str[4]; - int fd1[2], fd2[2]; - - snprintf(minor_str, 4, "%d", dev->minor_nr); - minor_str[3] = 0; - - if(pipe(fd1) || pipe(fd2)){ - log_err("pipe error : %s\n", strerror(errno)); - return -1; - } - pid = fork(); - if (pid < 0){ - log_err("cannot fork gnbd_recvd : %s\n", strerror(errno)); - return -1; - } - - if (pid){ - close(fd1[0]); - close(fd2[1]); - waitpid(pid, &status, 0); - close(fd1[1]); - close(fd2[0]); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0){ - log_err("gnbd_recvd failed (%d)\n", WEXITSTATUS(status)); - return -1; - } - return 0; - } - - close(fd1[1]); - close(fd2[0]); - if (fd2[1] == STDIN_FILENO){ - fd2[1] = dup(fd2[1]); - if (fd2[1] < 0) - exit(1); - } - if (dup2(fd1[0], STDIN_FILENO) < 0) - exit(1); - if (dup2(fd2[1], STDOUT_FILENO) < 0) - exit(1); - if (dup2(fd2[1], STDERR_FILENO) < 0) - exit(1); - for(i = open_max()-1; i > 2; --i) - close(i); - execlp("gnbd_recvd", "gnbd_recvd", "-f", "-d", minor_str); - exit(1); -} - -int whack_recvd(monitor_t *dev) -{ - int ret; - - ret = check_recvd(dev); - if (ret < 0) - return ret; - else if (ret) - return kill(ret, SIGHUP); - else - return start_recvd(dev); -} - -void check_devices(void) -{ - list_t *item, *next; - monitor_t *dev; - - checks++; - - list_foreach_safe(item, &monitor_list, next){ - int waittime; - dev = list_entry(item, monitor_t, list); - if (sscanf(get_sysfs_attr(dev->minor_nr, "waittime"), - "%d", &waittime) != 1){ - log_err("cannot parse /sys/class/gnbd/gnbd%d/waittime\n", dev->minor_nr); - exit(1); - } - switch(dev->state){ - case NORMAL_STATE: - if (waittime > dev->timeout){ - whack_recvd(dev); - dev->state = TIMED_OUT_STATE; - } - break; - case TIMED_OUT_STATE: - if (waittime <= dev->timeout){ - dev->state = NORMAL_STATE; - } - else { - cluster_member_t *server; - server = get_failover_server(dev); - if (server){ - if (clu_fence(server) < 0) - log_err("fence of %s failed\n", dev->server); - dev->state = FENCED_STATE; - } - else - whack_recvd(dev); - } - break; - case RESET_STATE: - if (!check_recvd (dev)) - dev->state = RESTARTABLE_STATE; - break; - case RESTARTABLE_STATE: - if (check_recvd(dev) > 0) /* if we got a good lock file */ - dev->state = NORMAL_STATE; /* go back to the normal state */ - else if (checks % RESTART_CHECK == 0) - start_recvd(dev); - break; - /* FENCED_STATE */ - } - } -} - -void list_monitored_devs(void){ - char state[12]; - monitor_info_t *ptr, *devs; - int i, count; - - if (do_list_monitored_devs(&devs, &count) < 0) - exit(1); - - printf("device # timeout state\n"); - ptr = devs; - - for(i = 0; i < count; i++, ptr++){ - switch(ptr->state){ - case NORMAL_STATE: - strcpy(state, "normal"); - break; - case TIMED_OUT_STATE: - strcpy(state, "timed out"); - break; - case RESET_STATE: - strcpy(state, "reset"); - break; - case RESTARTABLE_STATE: - strcpy(state, "restartable"); - break; - case FENCED_STATE: - strcpy(state, "fenced"); - break; - } - printf("%8d %7d %s\n", ptr->minor_nr, ptr->timeout, state); - } - free(devs); -} - -void do_poll(void) -{ - int err; - int i; - - err = poll(polls, max_id + 1, 5 * 1000); - if (err < 0){ - if (errno != EINTR) - log_err("poll error : %s\n", strerror(errno)); - return; - } - if (err == 0) - check_devices(); - for (i = 0; i <= max_id; i++){ - if (polls[i].revents & (POLLERR | POLLHUP | POLLNVAL)){ - log_err("Bad poll result, 0x%x on id %d\n", polls[i].revents, i); - close_poller(i); - continue; - } - if (polls[i].revents & POLLIN){ - if (i == CONNECT) - accept_connection(); - else if (i == CLUSTER) - handle_cluster_msg(); - else - handle_msg(i); - } - } -} - -void setup_signals(void) -{ - struct sigaction act; - - memset(&act, 0, sizeof(act)); - act.sa_handler = sig_chld; - if( sigaction(SIGCHLD, &act, NULL) <0) - fail_startup("cannot setup SIGCHLD handler : %s\n", strerror(errno)); -} - -int main(int argc, char *argv[]) -{ - int minor_nr; - int timeout; - int err; - - if (argc != 1 && argc != 2 && argc != 4){ - fprintf(stderr, "Usage: %s <minor_nr> <timeout> <server>\n", argv[0]); - exit(1); - } - - if (argc == 1){ - list_monitored_devs(); - exit(0); - } - - if (sscanf(argv[1], "%d", &minor_nr) != 1 || minor_nr < 0 || - minor_nr >= MAX_GNBD){ - printe("%s is not a valid minor number\n", argv[1]); - exit(1); - } - - if (argc == 2){ - if (do_remove_monitored_dev(minor_nr)) - exit(1); - exit(0); - } - - if (sscanf(argv[2], "%d", &timeout) != 1 || timeout <= 0){ - printe("%s is not a valid timeout value\n", argv[2]); - exit(1); - } - - program_name = "gnbd_monitor"; - - if (check_lock("gnbd_monitor.pid", NULL)){ - if (do_add_monitored_dev(minor_nr, timeout, argv[3]) < 0) - exit(1); - exit(0); - } - - daemonize_and_exit_parent(); - - if (!pid_lock("")) - fail_startup("Temporary problem running gnbd_monitor. Please retry"); - - setup_signals(); - - if (get_my_nodename(node_name, 1) < 0) - fail_startup("cannot get node name : %s\n", strerror(errno)); - - list_init(&monitor_list); - - setup_poll(); - - err = monitor_device(minor_nr, timeout, argv[3]); - if (err) - fail_startup("cannot add device #%d to monitor_list : %s\n", minor_nr, - strerror(err)); - - finish_startup("gnbd_monitor started. Monitoring device #%d\n", minor_nr); - - while(1){ - do_poll(); - } - return 0; -} diff --git a/gnbd/client/gnbd_monitor.h b/gnbd/client/gnbd_monitor.h deleted file mode 100644 index 1fd839e..0000000 --- a/gnbd/client/gnbd_monitor.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gnbd_monitor_h__ -#define __gnbd_monitor_h__ - -#define MONITOR_REQ 1 -#define REMOVE_REQ 2 -#define LIST_REQ 3 -#define MONITOR_SUCCESS_REPLY 0 - -#define NORMAL_STATE 0 -#define TIMED_OUT_STATE 1 -#define RESET_STATE 2 -#define RESTARTABLE_STATE 3 -#define FENCED_STATE 4 - -struct monitor_info_s { - int minor_nr; - int timeout; - int state; - char server[65]; -}; -typedef struct monitor_info_s monitor_info_t; - -int do_add_monitored_dev(int minor_nr, int timeout, char *server); -int do_remove_monitored_dev(int minor_nr); -int do_list_monitored_devs(monitor_info_t **devs, int *count); -int check_addr_info(struct addrinfo *ai1, struct addrinfo *ai2); - -#endif /* __gnbd_monitor_h__ */ diff --git a/gnbd/client/gnbd_recvd.c b/gnbd/client/gnbd_recvd.c deleted file mode 100644 index a90d8d8..0000000 --- a/gnbd/client/gnbd_recvd.c +++ /dev/null @@ -1,398 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdlib.h> -#include <getopt.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <linux/gnbd.h> -#include <inttypes.h> - -#include "gnbd_endian.h" -#include "gnbd_utils.h" -#include "gserv.h" -#include "trans.h" -#include "extern_req.h" - -#include "copyright.cf" - -unsigned int minor_num; -int devfd; -uint64_t timestamp; -int daemon_mode = 0; -int forget_mode = 0; -int have_connected = 0; -char devname[32]; -char node_name[65]; -int is_clustered = 1; - -#define fail(fmt, args...) \ -do { \ - if (daemon_mode && !have_connected) \ - fail_startup(fmt, ##args); \ - if (daemon_mode){ \ - log_err(fmt, ##args); \ - exit(1); \ - } \ - print_err(fmt, ##args); \ - exit(1); \ -} while(0) - -#define tell_msg(fmt, args...) \ -do { \ - if (daemon_mode) \ - log_msg(fmt, ##args); \ - if (!daemon_mode || !have_connected) \ - printm(fmt, ##args); \ -} while(0) - -#define tell_err(fmt, args...) \ -do { \ - if (daemon_mode) \ - log_err(fmt, ##args); \ - if (!daemon_mode || !have_connected) \ - print_err(fmt, ##args); \ -} while(0) - -#define tell_fail(fmt, args...) \ -do { \ - if (daemon_mode) \ - log_fail(fmt, ##args); \ - if (!daemon_mode || !have_connected) \ - printe(fmt, ##args); \ -} while(0) - -int usage(void){ - printf( -"Usage:\n" -"\n" -"gnbd_recvd [options]\n" -"gnbd_recvd [options] <minor_number>\n" -"\n" -"Options:\n" -" -d daemon mode. Print to syslog, not stdout/err\n" -" -f forget mode, implies daemon mode. Return immediately.\n" -" Don't wait for gnbd_recvd to connect to the server\n" -" -h print this help message\n" -" -n No cluster. Do not contact cluster manager\n" -" -q quiet mode. Only print errors.\n" -" -v verbose output\n" -" -V version information\n"); - return 0; -} - -void parse_cmdline(int argc, char **argv) -{ - int c; - struct stat stat_buf; - program_name = "gnbd_recvd"; - char sysfs_base[25]; - - while((c = getopt(argc, argv, "dfhnqvV")) != -1){ - switch(c){ - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - case 'd': - daemon_mode = 1; - continue; - case 'f': - daemon_mode = 1; - forget_mode = 0; - continue; - case 'h': - usage(); - exit(0); - case 'n': - is_clustered = 0; - continue; - case 'q': - if (verbosity == VERBOSE){ - printe("cannot use both -q and -v options\n" - "Please use '-h' for usage.\n"); - exit(1); - } - verbosity = QUIET; - continue; - case 'v': - if (verbosity == QUIET){ - printe("cannot use both -q and -v options\n" - "Please use '-h' for usage.\n"); - exit(1); - } - verbosity = VERBOSE; - continue; - case 'V': - printf("%s %s (built %s %s)\n", program_name, GNBD_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - default: - printe("No action for option -- %c\n" - "Please use '-h' for usage.\n", c); - exit(1); - } - } - if (optind == argc){ - printe("No minor number specified.\n" - "Please use '-h' for usage.\n"); - exit(1); - } - if (optind < argc - 1){ - printe("Extra arguments after minor number.\n" - "Pleae use '-h' for usage.\n"); - exit(1); - } - if (sscanf(argv[optind], "%u", &minor_num) != 1 || minor_num >= MAX_GNBD){ - printe("%s is not a valid minor number.\n" - "Please see the man page for details\n", argv[optind]); - exit(1); - } - snprintf(sysfs_base, 25, "/sys/class/gnbd/gnbd%u", minor_num); - if (stat(sysfs_base, &stat_buf) < 0){ - if (errno == ENOENT || errno == ENOTDIR) - printe("cannot stat %s : %s\n" - "Check that the gnbd module is loaded and sysfs is mounted\n", - sysfs_base, strerror(errno)); - else - printe("cannot stat %s : %s\n", sysfs_base, strerror(errno)); - exit(1); - } - if (!(S_ISDIR(stat_buf.st_mode))){ - printe("%s is not a directory\n", sysfs_base); - exit(1); - } -} - -void get_devname(void) -{ - if (do_get_sysfs_attr(minor_num, "name") == NULL) - fail("cannot get /sys/class/gnbd/gnbd%d/name value : %s\n", minor_num, - strerror(errno)); - strncpy(devname, sysfs_buf, 32); -} - -void open_device(void) -{ - if( (devfd = open("/dev/gnbd_ctl", O_RDONLY)) < 0) - fail("cannot open gnbd control device : %s\n", strerror(errno)); - if (ioctl(devfd, GNBD_GET_TIME, ×tamp) < 0) - fail("cannot get timestamp : %s\n", strerror(errno)); -} - -int kill_old_gservs(char *host, unsigned short port) -{ - int sock; - device_req_t device; - node_req_t node; - uint32_t cmd = EXTERN_KILL_GSERV_REQ; - - strncpy(device.name, devname, 32); - strncpy(node.node_name, node_name, 65); - - if( (sock = connect_to_server(host, port)) < 0){ - tell_err("cannot connect to server %s (%d) : %s\n", host, sock, - strerror(errno)); - return -1; - } - if (send_u32(sock, cmd) < 0){ - tell_err("cannot send kill server request to %s : %s\n", host, - strerror(errno)); - goto fail; - } - if (retry_write(sock, &device, sizeof(device)) < 0){ - tell_err("transfer of device name to %s failed : %s\n", host, - strerror(errno)); - goto fail; - } - if (retry_write(sock, &node, sizeof(node)) < 0){ - tell_err("transfer of my node name to %s failed : %s\n", host, - strerror(errno)); - goto fail; - } - if (recv_u32(sock, &cmd) < 0){ - tell_err("reading kill server reply from %s failed : %s\n", host, - strerror(errno)); - goto fail; - } - if (cmd && cmd != ENODEV){ - tell_err("kill server request from %s failed : %s\n", host, - strerror(errno)); - goto fail; - } - close(sock); - return 0; - - fail: - close(sock); - return -1; -} - - -/* If communication fails, retry. If I receive a failure reply, just exit */ -int gnbd_login(int sock, char *host) -{ - login_req_t login_req; - login_reply_t login_reply; - node_req_t node; - uint32_t cmd = EXTERN_LOGIN_REQ; - - strncpy(node.node_name, node_name, 65); - - if (send_u32(sock, cmd) < 0){ - tell_err("cannot send login request to %s : %s\n", host, strerror(errno)); - return -1; - } - - login_req.timestamp = timestamp; - login_req.version = PROTOCOL_VERSION; - strncpy(login_req.devname, devname, 32); - login_req.devname[31] = 0; - CPU_TO_BE_LOGIN_REQ(&login_req); - if (retry_write(sock, &login_req, sizeof(login_req)) < 0){ - tell_err("transfer of login request to %s failed : %s\n", host, - strerror(errno)); - return -1; - } - if (retry_write(sock, &node, sizeof(node)) < 0){ - tell_err("transfer of my node name to %s failed : %s\n", host, - strerror(errno)); - return -1; - } - if (retry_read(sock, &login_reply, sizeof(login_reply)) < 0){ - tell_err("transfer of login reply from %s failed : %s\n", host, - strerror(errno)); - return -1; - } - BE_LOGIN_REPLY_TO_CPU(&login_reply); - if (login_reply.err){ - if (login_reply.version) - fail("Protocol mismatch: client using version %u, " - "server using version %u", PROTOCOL_VERSION, login_reply.version); - else if (login_reply.err == ENODEV){ - tell_err("login refused by the server : %s\n", - strerror(login_reply.err)); - return -1; - } - else - fail("login refused by the server, quitting : %s\n", - strerror(login_reply.err)); - } - snprintf(sysfs_buf, 4096, "%" PRIu64, login_reply.sectors); - if (do_set_sysfs_attr(minor_num, "sectors", sysfs_buf) < 0) - fail("cannot set /sys/class/gnbd/gnbd%d/sectors value : %s\n", minor_num, - strerror(errno)); - return 0; -} - -void do_receiver(void) -{ - char host[256]; - unsigned short port; - int sock; - do_it_req_t req; - - /* FIXME -- I don't think that these can ever return a failure when - a simple retry would work... if they can, then I should not exit */ - if (do_get_sysfs_attr(minor_num, "server") == NULL) - fail("cannot get /sys/class/gnbd/gnbd%d/server value : %s\n", minor_num, - strerror(errno)); - if (parse_server(sysfs_buf, host, (uint16_t *)&port) < 0) - fail("cannot parse /sys/class/gnbd/gnbd%d/server\n", minor_num); - if (kill_old_gservs(host, port) < 0) - return; - if( (sock = connect_to_server(host, port)) < 0){ - tell_err("cannot connect to %s (%d) : %s\n", host, sock, - strerror(errno)); - return; - } - if (gnbd_login(sock, host) < 0){ - close(sock); - return; - } - if (!have_connected){ - if (daemon_mode) - finish_startup("gnbd_recvd started\n"); - else - printm("gnbd_recvd started\n"); - have_connected = 1; - } - req.minor = minor_num; - req.sock_fd = sock; - if (ioctl(devfd, GNBD_DO_IT, &req) == 0){ - log_msg("client shutting down connect with %s\n", host); - exit(0); - } - log_msg("client lost connection with %s : %s\n", host, strerror(errno)); - close(sock); - return; -} - -int main(int argc, char **argv) -{ - parse_cmdline(argc, argv); - char minor_str[20]; - struct sigaction act; - - if (daemon_mode) - daemonize_and_exit_parent(); - - memset(&act,0,sizeof(act)); - act.sa_handler = sig_hup; - if (sigaction(SIGHUP, &act, NULL) < 0) - fail("cannot set the signal handler for SIGHUP : %s\n", strerror(errno)); - - /* FIXME -- is this necessary */ - unblock_sighup(); - - if (get_my_nodename(node_name, is_clustered) < 0) - fail("cannot get node name : %s\n", strerror(errno)); - - snprintf(minor_str, 20, "-%u", minor_num); - minor_str[19] = 0; - - if (!pid_lock(minor_str)) - fail("%s already running for device #%d\n", program_name, - minor_num); - - if (forget_mode){ - finish_startup("gnbd_recvd started\n"); - have_connected = 1; - } - - get_devname(); - open_device(); - - /* FIXME -- setup signals here */ - /* FIXME -- somewhere I should set myself to nobody */ - - while(1){ - do_receiver(); - if (!have_connected) - fail("quitting\n"); - tell_msg("reconnecting\n"); - if (!got_sighup) - sleep(5); - got_sighup = 0; - } - - exit(0); -} diff --git a/gnbd/client/monitor_req.c b/gnbd/client/monitor_req.c deleted file mode 100644 index c9f8870..0000000 --- a/gnbd/client/monitor_req.c +++ /dev/null @@ -1,157 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <inttypes.h> -#include <errno.h> -#include <netdb.h> -#include <string.h> - -#include "gnbd_utils.h" -#include "trans.h" -#include "gnbd_monitor.h" - -int check_addr_info(struct addrinfo *ai1, struct addrinfo *ai2) -{ - int ret = 0; - - for(; ai1; ai1 = ai1->ai_next){ - for(; ai2; ai2 = ai2->ai_next){ - if (ai1->ai_family != ai2->ai_family) - continue; - if (ai1->ai_family != AF_INET && ai1->ai_family != AF_INET6) - continue; - if (ai1->ai_family == AF_INET){ - struct sockaddr_in *addr4_1, *addr4_2; - - addr4_1 = (struct sockaddr_in *)ai1->ai_addr; - addr4_2 = (struct sockaddr_in *)ai2->ai_addr; - if (addr4_1->sin_addr.s_addr == addr4_2->sin_addr.s_addr) - ret = 1; - } - if (ai1->ai_family == AF_INET6){ - struct sockaddr_in6 *addr6_1, *addr6_2; - - addr6_1 = (struct sockaddr_in6 *)ai1->ai_addr; - addr6_2 = (struct sockaddr_in6 *)ai2->ai_addr; - if (IN6_ARE_ADDR_EQUAL(&addr6_1->sin6_addr, &addr6_2->sin6_addr)) - ret = 1; - } - if (ret == 1) - break; - } - } - return ret; -} - -int do_add_monitored_dev(int minor_nr, int timeout, char *server) -{ - int sock; - uint32_t msg = MONITOR_REQ; - monitor_info_t info; - - info.minor_nr = minor_nr; - info.timeout = timeout; - memcpy(info.server, server, 65); - sock = connect_to_comm_device("gnbd_monitor"); - if (sock < 0) - return -1; - if (send_cmd(sock, msg, "monitor device") < 0) - goto fail; - if (retry_write(sock, &info, sizeof(info)) < 0) { - printe("cannot send device information to gnbd_monitor : %s\n", - gstrerror(errno)); - goto fail; - } - if (recv_reply(sock, "monitor device") < 0) - goto fail; - - close(sock); - return 0; - - fail: - close(sock); - return -1; -} - -int do_remove_monitored_dev(int minor_nr) -{ - int sock; - uint32_t msg = REMOVE_REQ; - - sock = connect_to_comm_device("gnbd_monitor"); - if (sock < 0) - return -1; - if (send_cmd(sock, msg, "remove") < 0) - goto fail; - if (retry_write(sock, &minor_nr, sizeof(minor_nr)) < 0){ - printe("cannot send minor_nr to gnbd_monitor : %s\n", gstrerror(errno)); - goto fail; - } - if (recv_reply(sock, "remove") < 0) - goto fail; - close(sock); - return 0; - - fail: - close(sock); - return -1; -} - -int do_list_monitored_devs(monitor_info_t **devs, int *count) -{ - int sock; - uint32_t msg = LIST_REQ; - monitor_info_t *buf; - unsigned int size; - - *devs = NULL; - *count = 0; - - sock = connect_to_comm_device("gnbd_monitor"); - if (sock < 0) - return -1; - if (send_cmd(sock, msg, "list") < 0) - goto fail; - if (recv_reply(sock, "list") < 0) - goto fail; - if (retry_read(sock, &size, sizeof(size)) < 0){ - printe("cannot get list size from gnbd_monitor : %s\n", gstrerror(errno)); - goto fail; - } - if (size == 0){ - close(sock); - return 0; - } - - buf = (monitor_info_t *)malloc(size); - if (!buf){ - printe("cannot allocate memory for gnbd_monitor list\n"); - goto fail; - } - if (retry_read(sock, buf, size) < 0){ - printe("cannot get list from gnbd_monitor : %s\n", gstrerror(errno)); - goto fail_free; - } - *devs = buf; - *count = size / sizeof(monitor_info_t); - close(sock); - return 0; - - fail_free: - free(buf); - fail: - close(sock); - return -1; -} diff --git a/gnbd/config/copyright.cf b/gnbd/config/copyright.cf deleted file mode 100644 index 75f0456..0000000 --- a/gnbd/config/copyright.cf +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) Red Hat, Inc. 2004 All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __COPYRIGHT_DOT_CF__ -#define __COPYRIGHT_DOT_CF__ - -#define REDHAT_COPYRIGHT ("Copyright (C) Red Hat, Inc. 2004 All rights reserved.") - -#endif /* __COPYRIGHT_DOT_CF__ */ - - - diff --git a/gnbd/configure b/gnbd/configure deleted file mode 100755 index dd4d532..0000000 --- a/gnbd/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/gnbd/include/global.h b/gnbd/include/global.h deleted file mode 100644 index c4f8a1d..0000000 --- a/gnbd/include/global.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GLOBAL_DOT_H__ -#define __GLOBAL_DOT_H__ - - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - - -#include <inttypes.h> - -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; - - -#endif /* __GLOBAL_H__ */ diff --git a/gnbd/include/gnbd_endian.h b/gnbd/include/gnbd_endian.h deleted file mode 100644 index 235c8dc..0000000 --- a/gnbd/include/gnbd_endian.h +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GNBD_ENDIAN_DOT_H__ -#define __GNBD_ENDIAN_DOT_H__ - - -#include <endian.h> -#include <byteswap.h> - -/* I'm not sure which versions of alpha glibc/gcc are broken, - so fix all of them. */ -#ifdef __alpha__ -#undef bswap_64 -static __inline__ unsigned long bswap_64(unsigned long x) -{ - unsigned int h = x >> 32; - unsigned int l = x; - - h = bswap_32(h); - l = bswap_32(l); - - return ((unsigned long)l << 32) | h; -} -#endif /* __alpha__ */ - -#if __BYTE_ORDER == __BIG_ENDIAN - -#define be16_to_cpu(x) (x) -#define be32_to_cpu(x) (x) -#define be64_to_cpu(x) (x) - -#define cpu_to_be16(x) (x) -#define cpu_to_be32(x) (x) -#define cpu_to_be64(x) (x) - -#define le16_to_cpu(x) (bswap_16((x))) -#define le32_to_cpu(x) (bswap_32((x))) -#define le64_to_cpu(x) (bswap_64((x))) - -#define cpu_to_le16(x) (bswap_16((x))) -#define cpu_to_le32(x) (bswap_32((x))) -#define cpu_to_le64(x) (bswap_64((x))) - -#endif /* __BYTE_ORDER == __BIG_ENDIAN */ - - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -#define be16_to_cpu(x) (bswap_16((x))) -#define be32_to_cpu(x) (bswap_32((x))) -#define be64_to_cpu(x) (bswap_64((x))) - -#define cpu_to_be16(x) (bswap_16((x))) -#define cpu_to_be32(x) (bswap_32((x))) -#define cpu_to_be64(x) (bswap_64((x))) - -#define le16_to_cpu(x) (x) -#define le32_to_cpu(x) (x) -#define le64_to_cpu(x) (x) - -#define cpu_to_le16(x) (x) -#define cpu_to_le32(x) (x) -#define cpu_to_le64(x) (x) - -#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ - - -#endif /* __GNBD_ENDIAN_DOT_H__ */ diff --git a/gnbd/make/defines.mk.input b/gnbd/make/defines.mk.input deleted file mode 100644 index 289f33f..0000000 --- a/gnbd/make/defines.mk.input +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/gnbd/make/release.mk.input b/gnbd/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/gnbd/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/gnbd/man/Makefile b/gnbd/man/Makefile deleted file mode 100644 index 4c9f411..0000000 --- a/gnbd/man/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET8= \ - gnbd.8 \ - gnbd_export.8 \ - gnbd_import.8 \ - gnbd_serv.8 \ - fence_gnbd.8 - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -all: - -copytobin: - -clean: - -install: all - install -d ${mandir}/man8 - install ${TARGET8} ${mandir}/man8 - -uninstall: - ${UNINSTALL} ${TARGET8} ${mandir}/man8 diff --git a/gnbd/man/fence_gnbd.8 b/gnbd/man/fence_gnbd.8 deleted file mode 100644 index c338da3..0000000 --- a/gnbd/man/fence_gnbd.8 +++ /dev/null @@ -1,87 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH fence_gnbd 8 - -.SH NAME -fence_gnbd - I/O Fencing agent for GNBD-based GFS clusters - -.SH SYNOPSIS -.B fence_gnbd -[\fIOPTION\fR]... - -.SH DESCRIPTION -fence_gnbd is an I/O Fencing agent used when GFS is accessed through GNBD. It -uses the gnbd_import program and tells a GNBD server to ignore I/O from a -specified machine. - -fence_gnbd accepts options on the command line as well as from stdin. -fence_node sends the options through stdin when it execs the agent. -fence_gnbd can be run by itself with command line options which is useful -for testing. - -.SH OPTIONS -.TP -\fB-h\fP -Print out a help message describing available options, then exit. -.TP -\fB-m\fP -Selects multipath style fencing. With multipath style fencing, if fence_gnbd -cannot contact the kgnbd_portd process on the gnbd server node, it will fence -that server node. This is necessary to insure that there is no way for the -fenced client to access the storage through that server. -\fBWARNING:\fP Multipath style fencing must be used on a node if it is using -pool multipathing with GNBD devices. -.TP -\fB-q\fP -quiet mode, no output. -.TP -\fB-s\fP \fInode\fP -gnbd client machine to fence. -.TP -\fB-t\fP \fInode\fP -server machine to fence the gnbd client from. If this option is -not given, the specified gnbd client node will be fenced from all gnbd server -nodes that have GNBDs imported by the machine running fence_gnbd. -Using the -t option is strongly recommended. The -t option may be used -multiple times to fence a client from multiple servers. -.TP -\fB-V\fP -Print out a version message, then exit. - -.SH STDIN PARAMETERS -.TP -\fIagent = < param >\fP -This option is used by fence_node(8) and is ignored by fence_gnbd. -.TP -\fIipaddr = < clustername >\fP -The cluster name of the node to be fenced (required) \fBNOTE:\fP This parameter -no longer allows the IP address of the node to be used. This parameter is -deprecated. Please use \fInodename\fP instead. -.TP -\fInodename = < clustername >\fP -The cluster name of the node to be fenced (required) -.TP -\fIservers = < hostname [ hostname ... ] >\fP -A whitespace seperated list of the servers to fence the client from, in -either IP address or hostname form. -.TP -\fIoption = multipath\fP -Select multipath style fencing. \fBWARNING:\fP When multipath style fencing is -used, if the kgnbd_portd process of a gnbd server node cannot be contacted, it -is fenced as well, using its appropriate fencig method. This means that when -a client is fenced, any node listed as its server that does not have the -gnbd_serv module loaded (which starts kgnbd_portd) will also be fenced. -.TP -\fIretrys = < param >\fP -Number of times to retry connecting to the server after a failed attempt, -before the server is fenced. This parameter is only valid when used -with multipath style fencing (see above). The default is 3. -.TP -\fIwait_time = < param >\fP -length of time, in seconds, to wait between retrys. This parameter -is only valid when used with multipath sytle fencing (see above). The default -is 2. - -.SH SEE ALSO -fence(8), fenced(8), gnbd_import(8) diff --git a/gnbd/man/gnbd.8 b/gnbd/man/gnbd.8 deleted file mode 100644 index 499de34..0000000 --- a/gnbd/man/gnbd.8 +++ /dev/null @@ -1,43 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gnbd 8 - -.SH NAME -GNBD reference guide - -.SH SYNOPSIS -Overview of manpages and their locations - -.SH DESCRIPTION -The GFS Network Block Device has two parts, the client (which includes the -\fBgnbd.ko\fP module and \fBgnbd_import\fP, \fBgnbd_recvd\fP, and -\fBgnbd_monitor\fP programs) and the server -(which include the \fBgnbd_serv\fP, \fBgnbd_clusterd\fP, and \fBgnbd_export\fP -programs). The GNBD server allows a computer -to export multiple block devices or files (GNBDs). The GNBD client allows a -computer to import these GNBDs, and use them as if they were local block -devices. The primary difference between GNBD and NBD (the network block -device distributed with the Linux kernel) is GNBD's ability to have multiple -clients all accessing the same served file or block device at the same -time. - -The GNBD documentation has been split into a number of sections. Please -refer to the table below to determine which man page coincides with the -command/feature you are looking for. - -.TP 16 -gnbd -GNBD overview (this man page) -.TP -gnbd_import -Configure a GNBD Client -.TP -gnbd_export -Configure a GNBD Server -.TP -fence_gnbd -Fence method for GNBD - -.SH SEE ALSO -gfs(8), fence(8), fence_gnbd(8) diff --git a/gnbd/man/gnbd_export.8 b/gnbd/man/gnbd_export.8 deleted file mode 100644 index 18bf491..0000000 --- a/gnbd/man/gnbd_export.8 +++ /dev/null @@ -1,164 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gnbd_export 8 - -.SH NAME -gnbd_export - the interface to export GNBDs - -.SH SYNOPSIS -.B gnbd_export -[\fIOPTION\fR]... - -.SH DESCRIPTION -gnbd_export exports local block devices or files as GNBDs. - -.SH OPTIONS -.TP -\fB-a\fP -Validate. - -This option forces all server processes to send a ping message to the clients -they are connected to. This forces servers with faulty connections to quit. -.TP -\fB-c\fP -Enable caching. - -Reads from the exported GNBD will take advantage of the linux page cache. -This option is used with \fB-e\fP. \fBNOTE:\fP If this option is not specified, -gnbd will run with a noticeable performance decrease. Also, if this option -is not specified, the exported GNBD will run in timeout mode, with the -default timeout (see the \fB-t\fP option). -With the \fB-c\fP option, it is not necessary to have the gnbd server machine -be part of the cluster. If \fB-c\fP option is not used, the server machine -must already have a cluster manager running on it. When the first uncached -gnbd is exported, the \fBgnbd_clusterd\fP daemon will be started. This daemon -connects to the cluster manager via the \fBmagma\fP interface. -\fBWARNING:\fP You must NOT specify -this option if you wish to use gnbd with dm multipathing, or run GFS on gnbd -server machines. To set up dm multipathing over gnbd, all -gnbds involved must run with caching disabled. Data corruption will occur -if the GNBD devices are run with caching. Any device that is exported without -the \fB-c\fP option can also be used locally, but you must access the device -directly. You MUST NOT use gnbd_import to import devices exported from the -same machine. -.TP -\fB-d\fI pathname\fR -Device. - -Specify the device to export as a GNBD. This option is used with \fB-e\fP. -\fIpathname\fR may be either a block device or a regular file. Usually block -devices are used, because this increases GNBD performance. -.TP -\fB-e\fI gnbdname\fR -Export. - -Export a device as a GNBD with the Device name \fIgnbdname\fR. You must also -specify the pathname of the device with the \fB-d\fP option. Once a GNBD -has been exported, clients can import it with \fBgnbd_import\fP. -.TP -\fB-h\fP -Help. - -Print the usage information. -.TP -\fB-l\fP -List. - -List all exported GNBDs and kgnbd_portd server information. The listing -contains each server's number (which is only for internal use), its Device -name, the pathname of the device that is being exported, it's size in -512 byte sectors, and information on whether or not it is cached, and if not, -what it's timeout is. -.TP -\fB-O\fP -Override - -This option allows you to unexport gnbd devices, even if they are still in -use. When an agent other than fence_gnbd is used to fence gnbd client nodes, -occasionally gnbd server threads are not correctly cleaned up. This causes -no performance issues. However, the affected gnbd devices cannot be unexported. -In this case, using the \fB-O\fP option with either \fB-r\fP or \fB-R\fP will -allow you to unexport the GNBD devices. \fBWARNING:\fP Make sure -that no clients have the GNBD imported before using this option. -.TP -\fB-o\fP -Readonly - -export the server in readonly mode. -.TP -\fB-q\fP -Quiet. - -Only prints out error messages. -.TP -\fB-R\fP -Remove All. - -Remove all exported GNBDs. -.TP -\fB-r\fP [\fIGNBD(s)\fR] -Remove. - -Remove named GNBD(s). -.TP -\fB-u\fP \fIuid\fR -Manually set UID. - -Manunally set the Universal Identifier for an exported device. This option is -used with \fB-e\fP. The UID is used by device-mapper-multipath to determine -which devices belong in a multipath map. A device must have a UID to be -multipathed. However, for most SCSI devices the default Get UID command -will return an appropriate id (see \fB-U\fP). \fBNOTE:\fP The UID refers to -the device being exported, not the GNBD itself. The UIDs of two GNBD devices -should be equal, only if they are exporting the same underlying device. -This means that both GNBD servers are connected to the same physical device. -\fBWARNING:\fP This should only be used for exporting shared storage devices, -when the \fB-U\fP command does not work. This should almost never happen for -SCSI devices. If two GNBD devices are not exporting the same underlying -device, but are given the same UID, data corruption WILL occur. You should -not use this option unless \fB-U\fP does not work for your setup, and you -understand why. -.TP -\fB-U\fP [\fIcommand\fR] -Get UID Command. - -This is a command the gnbd_export will run to get a Universal Identifier for -the exported device. The UID is necessary to use device-mapper-multipath with -GNBD (see \fB-u\fP for more information). The command must use the full path -of any executeable that you wish to run. A command can contain the %M, %m or -%n escape sequences. %M will be expanded to the major number of the exported -device, %m will be expaned to the minor number of the exported device, and -%n will be expanded to the sysfs name for the device. If no command is given, -gnbd will use the default command \fI"/sbin/scsi_id -g -u -s /block/%n"\fR. This -command will work for most scsi devices. -.TP -\fB-t\fP [\fIseconds\fR] -Timeout. - -Set the exported GNBD to timeout mode This option is used with \fB-p\fP. -This is the default for uncached GNBDs. For cached GNBDs, the default is wait -mode (For GFS versions up through 5.2, all GNBDs were in wait mode). In wait -mode, if the connection to the server is lost, the gnbd client waits for the -connection to be reestablished, and then resends all the pending requests. In -timeout mode, if the connection cannot be reestablished or if the gnbd client -does not receive a response from the server within the timeout period, the gnbd -client returns all -pending and future requests as failures until the imported GNBD is closed. The -default timeout period is 60 seconds. Timeout mode is necessary for failover to -work with dm multipathing over gnbd. -.TP -\fB-v\fP -Verbose. - -Increase the verbosity of the output. This option is the most useful with -\fB-l\fP. If it is used along with \fB-l\fP, an extended list of information -on each exported device will be printed. -.TP -\fB-V\fP -Version information. - -Print out version information. - -.SH SEE ALSO -gnbd_import(8), gnbd(8) diff --git a/gnbd/man/gnbd_import.8 b/gnbd/man/gnbd_import.8 deleted file mode 100644 index 029b135..0000000 --- a/gnbd/man/gnbd_import.8 +++ /dev/null @@ -1,174 +0,0 @@ -." Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -.TH gnbd_import 8 - -.SH NAME -gnbd_import - manipulate GNBD block devices on a client - -.SH SYNOPSIS -.B gnbd_import -[\fIOPTION\fR]... - -.SH DESCRIPTION -gnbd_import imports, lists, and removes GNBDs from the system. GNBD is similar to -the Network Block Device (nbd) in the Linux kernel, except that it allows -multiple clients to connect at once and has a built-in fence command. - -.SH OPTIONS -.TP -\fB-a\fP -Validate. - -Restart failed gnbd_recvd processes. Usually, if a gnbd becomes -disconnected, the \fBgnbd_recvd\fP process for that device will automatically -try to reconnect. If that process is killed, \fBgnbd_import -a\fP will -restart it. -.TP -\fB-c \fIserver\fR -Check fenced. - -List all the IP addresses currently IO fenced from the specified \fIserver\fR. -If the sepecified server does not have any IP addresses fenced, nothing will -be returned. If the server machine is not running gnbd_serv, an error will -be returned. -.TP -\fB-e \fIserver\fR -List exported. - -List GNBDs exported by the specified \fIserver\fR, along with the port at -which they can be accessed. If the specified server is not exporting any GNBDs, -nothing will be returned. If the server machine is not running gnbd_serv, an -error will be returned. -.TP -\fB-h\fP -Help. - -Print the usage information. -.TP -\fB-i \fIserver\fR -Import. - -Import all GNBDs which the specified \fIserver\fR has exported. This will not -allow a GNBD to be imported if another one with the same name has already been -imported. -.TP -\fB-l\fP -List. - -List all imported GNBDs. If no options are specified, this is the default -action. There are eight fields for each device: Device name, Minor #, -Proc name, Server, Port, State, Readonly and Sectors. The Device name is the -name that was chosen for -the device when the server exported it. The Minor # is the minor number for -the GNBD on the local machine. The Proc name is the name for the -device that will appear in /proc/partitions, since Linux does not allow -devices in /proc/partitions to have arbitrary names. \fBNOTE:\fP A GNBD's -Device name will be consistent across a cluster. Its Minor # and -Proc name may not be. Server and Port are the ones used to -communicate with the GNBD's server. State describes the state of -the device. It has three variables. The first will either say \fBOpen\fP or -\fBClosed\fP, depending on whether the imported GNBD is open or closed. -The second will either say \fBConnected\fP or \fBDisconnected\fP, depending -on whether or not there is a working TCP connection from the device to its -server. When the connection is broken, this variable might not be immediately -updated. The third variable will either say \fBPending\fP or \fBClear\fP, -depending on whether or not there are any IO requests that the GNBD has sent -to the server, but which haven't been completed yet. Readonly tells whether -the gnbd server exported this device as readonly. Sectors is the device size -in 512 bytes sectors. -.TP -\fB-n\fP -No Cluster - -This keeps gnbd_import from trying to contact the cluster manager. This option -is used with \fB-i\fP. \fBNOTE:\fP With this option, it is not possible to -import uncached devices. \fBWarning:\fP This option should only be used in -situations that do not need any clustering. Attempting to use fence_gnbd to -block access to device imported with this option may silently fail, leading to -possible data corruption in a cluster environment. -.TP -\fB-O\fP -Override - -This makes gnbd_import run in non-interactive mode. It will no longer prompt -the user before attempting unsafe actions. It is recommended that you do -not use this option. -.TP -\fB-p\fP -Port. - -Change the port to connect to on the server. This option is used with -\fB-c\fP, \fB-e\fP and \fB-i\fP. If the port option is not set, gnbd_import -will try to connect to port 14567 on the server machine to find the gnbd_serv -daemon. You should only need to use this if you have changed the gnbd_serv -port from its default. -.TP -\fB-q\fP -Quiet mode. - -Only print out errors or questions. -.TP -\fB-R\fP -Remove All. - -Remove all of the imported GNBDs from the system. Only GNBDs that are in the -\fBClosed Disconnected Clear\fP state can be removed (See the \fB-l\fP -option), unless \fB-O\fP is used. Remove All stops after the first failed -remove. -.TP -\fB-r\fP [\fIGNBD\fR | \fILIST\fR] -Remove. - -Remove named GNBD(s) from system. Only GNBDs that are in the \fBClosed -Disconnected Clear\fP state can be removed (See the \fB-l\fP option), unless -the \fB-O\fP option is used. -Remove stops after the first failed remove. -.TP -\fB-s\fP \fIhost\fR -Fence. - -IO fence the specified host. This command is generally invoked by \fBfenced\fP. -\fBWARNING\fP It is -not always possible to seamlessly reconnect a client that has had its -connection cut. You should not execute this command manually unless you know -what you are doing. See the \fB-t\fP option for more information. Once a host -is fenced from a server, it will not be able to access any GNBDs on that server -until it is unfenced (see the \fB-u\fP option). -.TP -\fB-t\fP \fIserver\fR -Fence from Server. - -Specify a server for the IO fence (only used with the \fB-s\fP option). -.TP -\fB-u\fP \fIhost\fR -Unfence. - -Unfence the specified host. \fBWARNING\fP: Unfencing a client at the incorrect -time can result in data corruption. In normal operation, it should never be -necessary to run this comman. See the \fB-t\fP option. -.TP -\fB-U\fP \fIGNBD\fR -Get UID. - -Gets the Universal Identifier for the specified GNBD. This command is used -by dm-multipathing to create multipath maps. -.TP -\fB-V\fP -Version information. - -Print out version information. -.TP -\fB-v\fP -Verbose output. - -Print additional messages during the operation of gnbd_import. - -.SH SEE ALSO -gnbd_export(8) - -.SH BUGS -A computer should not import a GNBD device that it exports. Any -significant amount of IO on that device will cause a kernel deadlock. This is -a problem common to most NBDs. Instead, the underlying device should be -used directly. See gnbd_export for more on this. diff --git a/gnbd/man/gnbd_serv.8 b/gnbd/man/gnbd_serv.8 deleted file mode 100644 index 9551093..0000000 --- a/gnbd/man/gnbd_serv.8 +++ /dev/null @@ -1,74 +0,0 @@ -." Copyright (C) 2005 Red Hat, Inc. All rights reserved. - -.TH gnbd_serv 8 - -.SH NAME -gnbd_serv - gnbd server daemon - -.SH SYNOPSIS -.B gnbd_serv -[\fIOPTION\fR]... - -.SH DESCRIPTION -gnbd_serv manages gnbd devices exported by gnbd_export and connections from -gnbd_import. It servs up data from the local disks to the connected gnbd -clients. - -.SH OPTIONS -.TP -\fB-h\fP -Help. - -Print the usage information. -.TP -\fB-k\fP -Kill. - -Kill the gnbd_serv daemon. This command will not kill the daemon if any -devices are currently being exported. The exported devices must first be -removed. -.TP -\fB-K\fP -Force Kill. - -Kill the gnbd_serv daemon regardless of whether or not there are currently -exported devices. This command will try to shut down all of the gnbd_serv -processes for the currently active connections before shutting down the -primary gnbd_serv process. However, if these processes are in uninterruptible -sleep, the primary gnbd_serv process may shut down while a there is still an -active gnbd connection. -.TP -\fB-n\fP -No Cluster. - -This command keeps gnbd_serv from trying to contact the cluster manager. -\fBNOTE:\fP With this option, it is not possible to export uncached devices. -.TP -\fB-p \fIport\fR -Port. - -Specify the port for the gnbd server to listen for external connections on. -By default, the server listens for requests on port 14567. If this port -is changed, gnbd_import must also use the \fB-p\fP option. -.TP -\fB-q\fP -Quiet mode. - -Only print out errors or questions. -.TP -\fB-V\fP -Version information. - -Print out version information. -.TP -\fB-v\fP -Verbose output. - -Print additional messages during the operation of gnbd_serv. - -.SH SEE ALSO -gnbd_export(8), gnbd_import(8) - -.SH BUGS -Occasionally, gnbd_serv -k will not clean up the gnbd_clusterd processes. -Once gnbd_serv has stopped running, this process can simply be killed. diff --git a/gnbd/scripts/find_executable b/gnbd/scripts/find_executable deleted file mode 100755 index acd62d0..0000000 --- a/gnbd/scripts/find_executable +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/sh - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -# Helper script for configure - -v=`which $1`; if [ -z "$v" ]; then echo "1"; fi - - diff --git a/gnbd/scripts/linuxver b/gnbd/scripts/linuxver deleted file mode 100755 index fa9eae6..0000000 --- a/gnbd/scripts/linuxver +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: outputs the version of linux in the src directory specified -## to stdout - -use Getopt::Std; - -getopt('d'); - -$linux_src = $opt_d; -$majorver = $opt_b; -$noextra = $opt_s; - -# help message -if(defined($opt_h)) { - $msg = "usage: $0 [OPTIONS]\n"; - $msg = $msg . "\t-b\tBrief format (MAJOR_MINOR)\n"; - $msg = $msg . "\t-s\tsimple format (MAJOR.MINOR.RELEASE)\n"; - $msg = $msg . "\t-d\tLinux src directory (Default: /usr/src/linux)\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - $msg = $msg . "\t-v\tVerbose format (${MAJOR}.${MINOR}.${RELEASE}${EXTRAVERSION}) - Default\n"; - die $msg; -} - - # if there was an argument to linuxver, use it as the linux source directory - if ($linux_src) { - $file = $linux_src . '/include/linux/version.h'; - } - # otherwise, use the default - else { - $file = '/usr/src/linux/include/linux/version.h'; - } - - - open(DATAFILE, "< $file") || die "$0: can't open $file\n"; - while ($line = <DATAFILE>) - { - if ($majorver) { - if ($line =~ /UTS_RELEASE.+"(\d+.\d+).\d+/) - { - $version = $1; - $version =~ tr/./_/; - } - } - else { - if ($noextra) { - if ($line =~ /UTS_RELEASE.+"(\d+.\d+.\d+)/) - { - $version = $1; - } - } - else { - if ($line =~ /UTS_RELEASE.+"(\d+.\d+.[+_-.\d\w]+)/) - { - $version = $1; - } - } - } - } - - close(DATAFILE); - - die "linuxver can't determine Linux version\n" unless (defined($version)); - -print "$version\n"; - diff --git a/gnbd/scripts/uninstall.pl b/gnbd/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/gnbd/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/gnbd/server/Makefile b/gnbd/server/Makefile deleted file mode 100644 index be95398..0000000 --- a/gnbd/server/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= gnbd_serv gnbd_clusterd - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -CLU_SOURCE= gnbd_clusterd.c $(top_srcdir)/utils/gnbd_utils.c - -LDLIBS+= -L${libdir} -lmagma -ldl -lpthread - -SRV_SOURCE= gnbd_serv.c local_req.c extern_req.c device.c gserv.c fence.c \ - $(top_srcdir)/utils/trans.c $(top_srcdir)/utils/gnbd_utils.c - -INCLUDE= -I$(top_srcdir)/include -I$(top_srcdir)/utils \ - -I${top_srcdir}/config -I${incdir} - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -- which is incdir, which is already included -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gnbd.h ]; then \ - echo '-I${KERNEL_SRC}/include'; fi) -endif - -CFLAGS+= -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DGNBD_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -gnbd_clusterd: ${CLU_SOURCE} - ${CC} ${CFLAGS} ${LDFLAGS} ${CLU_SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -gnbd_serv: ${SRV_SOURCE} - ${CC} ${CFLAGS} ${LDFLAGS} ${SRV_SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/gnbd/server/device.c b/gnbd/server/device.c deleted file mode 100644 index 4d98299..0000000 --- a/gnbd/server/device.c +++ /dev/null @@ -1,388 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <inttypes.h> -#include <sys/mount.h> - -#include <linux/gnbd.h> - -#ifndef BLKGETSIZE64 -#define BLKGETSIZE64 _IOR(0x12, 114, uint64_t) -#endif - -#ifndef O_DIRECT -#define O_DIRECT 040000 -#endif - -#include "list.h" -#include "gnbd_utils.h" -#include "local_req.h" -#include "device.h" -#include "gserv.h" -#include "extern_req.h" - -list_decl(device_list); - -int have_devices(void) -{ - return !list_empty(&device_list); -} - -int last_uncached_device(char *name) -{ - dev_info_t *dev = NULL; - list_t *list_item; - int uncached_devs = 0; - int found = 0; - - list_foreach(list_item, &device_list) { - dev = list_entry(list_item, dev_info_t, list); - if (strcmp(name, dev->name) == 0){ - found = 1; - if (dev->timeout == 0) - return LOCAL_SUCCESS_REPLY; - } - else if (dev->timeout) - uncached_devs++; - } - if (!found){ - log_fail("cannot find gnbd '%s' to remove\n", name); - return -ENODEV; - } - if (uncached_devs) - return LOCAL_SUCCESS_REPLY; - return LOCAL_RM_CLUSTER_REPLY; -} - -dev_info_t *find_device(char *name) -{ - list_t *list_item; - dev_info_t *dev_info = NULL; - - list_foreach(list_item, &device_list) { - dev_info = list_entry(list_item, dev_info_t, list); - if (strcmp(name, dev_info->name) == 0) - break; - dev_info = NULL; - } - - return dev_info; -} - -int open_file(char *path, unsigned int flags, int *devfd) -{ - int fd; - int err; - int open_flags = 0; - - *devfd = -1; - - /* FIXME -- This stuff might be horribly wrong. I need AIO and nocopy to - not get shouted at, and that might change this. */ - if (flags & GNBD_FLAGS_READONLY) - open_flags = O_RDONLY; - else - open_flags = O_RDWR | O_SYNC; - if (flags & GNBD_FLAGS_UNCACHED) - open_flags |= O_DIRECT; - fd = open(path, open_flags); - if (fd < 0){ - err = -errno; - log_err("cannot open %s in %s%s mode : %s\n", path, - (flags & GNBD_FLAGS_READONLY)? "O_RDONLY" : "O_RDWR | OSYNC", - (flags & GNBD_FLAGS_UNCACHED)? " | O_DIRECT" : "", - strerror(errno)); - return err; - } - - *devfd = fd; - return 0; -} - -int get_size(int fd, uint64_t *sectors) -{ - /* Should I use the uint64 size, when there's a good chance that off_t will - be correct in 2.6 */ - struct stat stat_buf; - uint64_t size_64; - unsigned long sectors_long; - off_t off_mask = ~(off_t)511; - uint64_t mask = ~(uint64_t)511; - - stat_buf.st_size = 0; - if (fstat(fd, &stat_buf) < 0){ - log_err("cannot fstat gnbd device file : %s\n", strerror(errno)); - return -errno; - } - if (S_ISREG(stat_buf.st_mode)){ - if (stat_buf.st_size < 512){ - log_err("gnbd device file must be larger than 512 bytes\n"); - /* FIXME -- There must be something better */ - return -ENOSPC; - } - if (stat_buf.st_size != (stat_buf.st_size & off_mask)) - log_verbose("gnbd device file size not a multiple of 512 bytes\n" - "export size will be rounded down\n"); - *sectors = (uint64_t)stat_buf.st_size >> 9; - return 0; - } - if (S_ISBLK(stat_buf.st_mode)){ - if (ioctl(fd, BLKGETSIZE64, &size_64) >= 0){ - if (size_64 != (size_64 & mask)){ - log_verbose("gnbd device size not a multiple of 512 bytes\n" - "export size will be rounded down\n"); - } - *sectors = size_64 >> 9; - return 0; - } - /* FIXME -- is this correct in 2.6 */ - if (ioctl(fd, BLKGETSIZE, §ors_long) >= 0){ - *sectors = (uint64_t)sectors_long; - return 0; - } - log_err("couldn't get size for gnbd block device : %s\n", strerror(errno)); - return -errno; - } - log_err("gnbd device must be either a block device or a file\n"); - return -EINVAL; -} - -int create_device(char *name, char *path, char *uid, unsigned int timeout, - unsigned int flags) -{ - int err; - dev_info_t *dev; - int devfd; - - if (is_clustered == 0 && timeout != 0){ - log_err("cannot export uncached devices when gnbd_serv is started with -n\n"); - err = -ENOTSUP; - goto fail; - } - - if (find_device(name)){ - log_err("gnbd name '%s' already in use\n", name); - err = -EBUSY; - goto fail; - } - - dev = malloc(sizeof(dev_info_t)); - if (!dev){ - log_err("couldn't allocate memory for gnbd '%s' info\n", name); - err = -ENOMEM; - goto fail; - } - - memset(dev, 0, sizeof(dev_info_t)); - - dev->timeout = timeout; - dev->flags = flags; - dev->name = malloc(buflen(name)); - if (!dev->name){ - log_err("couldn't allocate memory for gnbd '%s' name\n", name); - err = -ENOMEM; - goto fail_info; - } - strcpy(dev->name, name); - - dev->path = malloc(buflen(path)); - if (!dev->path){ - log_err("couldn't allocate memory for gnbd '%s' path (%s)\n", name, path); - err = -ENOMEM; - goto fail_name; - } - strcpy(dev->path, path); - - if (uid && uid[0]){ - dev->uid = malloc(buflen(uid)); - if (!dev->uid){ - log_err("couldn't allocate memory for gnbd '%s' uid (%s)\n", name, uid); - err = -ENOMEM; - goto fail_path; - } - strcpy(dev->uid, uid); - } else - dev->uid = NULL; - - err = open_file(dev->path, dev->flags, &devfd); - if (err < 0) - goto fail_malloc; - - err = get_size(devfd, &dev->sectors); - if (err < 0) - goto fail_file; - - close(devfd); - - list_add(&dev->list, &device_list); - - log_verbose("gnbd device '%s' serving %s exported with %Lu sectors\n", - dev->name, dev->path, (long long unsigned int)dev->sectors); - return 0; - - fail_file: - close(devfd); - fail_malloc: - free(dev->uid); - fail_path: - free(dev->path); - fail_name: - free(dev->name); - fail_info: - free(dev); - fail: - return err; -} - -int invalidate_device(char *name, int sock) -{ - int err; - dev_info_t *dev; - dev = find_device(name); - if (!dev){ - log_fail("cannot find gnbd device '%s' to remove\n", name); - return -ENODEV; - } - dev->flags |= GNBD_FLAGS_INVALID; - err = kill_gserv(0, dev, sock); - if (err < 0) - return err; - return 0; -} - - - -int remove_device(char *name) -{ - dev_info_t *dev; - dev = find_device(name); - if (!dev){ - log_fail("cannot find gnbd device '%s' to remove\n", name); - return -ENODEV; - } - if (find_gserv_info(NULL, dev)){ - log_fail("device '%s' is in use. Cannot remove\n", name); - return -EBUSY; - } - list_del(&dev->list); - if (dev->uid) - free(dev->uid); - free(dev->path); - free(dev->name); - free(dev); - - return 0; -} - -int get_dev_names(char **buffer, uint32_t *list_size) -{ - import_info_t *ptr; - dev_info_t *dev; - list_t *list_item; - int count = 0; - - *buffer = NULL; - list_foreach(list_item, &device_list){ - dev = list_entry(list_item, dev_info_t, list); - if ((dev->flags & GNBD_FLAGS_INVALID) == 0) - count++; - } - if (count == 0){ - *list_size = 0; - return 0; - } - ptr = (import_info_t *)malloc(sizeof(import_info_t) * count); - if (!ptr){ - log_err("cannot allocate memory for names replay\n"); - return -ENOMEM; - } - *buffer = (char *)ptr; - *list_size = (uint32_t)(sizeof(import_info_t) * count); - list_foreach(list_item, &device_list){ - dev = list_entry(list_item, dev_info_t, list); - if (dev->flags & GNBD_FLAGS_INVALID) - continue; - strncpy(ptr->name, dev->name, 32); - ptr->name[31] = 0; - ptr->timeout = (uint32_t)dev->timeout; - ptr->flags = (dev->flags & GNBD_FLAGS_READONLY)? GNBD_READ_ONLY : 0; - ptr++; - } - - return 0; -} - -int get_dev_uid(char *name, char **buffer, uint32_t *size) -{ - dev_info_t *dev; - - *buffer = NULL; - *size = 0; - dev = find_device(name); - if (!dev) - return -ENODEV; - if (!dev->uid) - return 0; - *buffer = dev->uid; - *size = buflen(*buffer); - return 0; -} - - -int get_dev_info(char **buffer, uint32_t *list_size) -{ - info_req_t *ptr; - dev_info_t *dev; - list_t *list_item; - int count = 0; - - *buffer = NULL; - list_foreach(list_item, &device_list) - count++; - if (count == 0){ - *list_size = 0; - return 0; - } - ptr = (info_req_t *)malloc(sizeof(info_req_t) * count); - if (!ptr){ - log_err("cannot allocate memory for info replay\n"); - return -ENOMEM; - } - *buffer = (char *)ptr; - *list_size = (uint32_t)(sizeof(info_req_t) * count); - list_foreach(list_item, &device_list){ - dev = list_entry(list_item, dev_info_t, list); - ptr->sectors = (uint64_t)dev->sectors; - ptr->timeout = (uint32_t)dev->timeout; - ptr->flags = (uint8_t)dev->flags; - strncpy(ptr->name, dev->name, 32); - ptr->name[31] = 0; - strncpy(ptr->path, dev->path, 1024); - ptr->path[1023] = 0; - if (dev->uid){ - strncpy(ptr->uid, dev->uid, 64); - ptr->uid[63] = 0; - } else - ptr->uid[0] = 0; - ptr++; - } - - return 0; -} diff --git a/gnbd/server/device.h b/gnbd/server/device.h deleted file mode 100644 index 9525084..0000000 --- a/gnbd/server/device.h +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __device_h__ -#define __device_h__ - -#include "list.h" - -/*FIXME -- this should go someplace global */ -#define buflen(x) (strlen(x) + 1) - -#define GNBD_FLAGS_READONLY 1 -#define GNBD_FLAGS_UNCACHED 2 -#define GNBD_FLAGS_INVALID 4 - -extern int is_clustered; - -struct dev_info_s { - uint64_t sectors; - /* FIXME -- should these get changed back to their uint types */ - unsigned int timeout; - unsigned int flags; - char *name; - char *path; - char *uid; - list_t list; -}; -typedef struct dev_info_s dev_info_t; - -int have_devices(void); -int open_file(char *path, unsigned int flags, int *devfd); -int get_size(int fd, uint64_t *sectors); -int create_device(char *name, char *path, char *uid, unsigned int timeout, - unsigned int flags); -int invalidate_device(char *name, int sock); -int remove_device(char *name); -int get_dev_names(char **buffer, uint32_t *list_size); -int get_dev_info(char **buffer, uint32_t *list_size); -dev_info_t *find_device(char *name); -int last_uncached_device(char *name); -int get_dev_uid(char *name, char **buffer, uint32_t *size); - -#endif /* __device_h__ */ diff --git a/gnbd/server/extern_req.c b/gnbd/server/extern_req.c deleted file mode 100644 index b7b5c8c..0000000 --- a/gnbd/server/extern_req.c +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <errno.h> -#include <string.h> -#include <signal.h> -#include <syslog.h> -#include <inttypes.h> -#include <sys/types.h> -#include <netdb.h> - -#include "gnbd_endian.h" -#include "list.h" -#include "gnbd_utils.h" -#include "extern_req.h" -#include "device.h" -#include "gserv.h" -#include "fence.h" -#include "trans.h" - -char nodename[NODENAME_SIZE]; - -int do_startup(int domain, struct sockaddr *addr) -{ - int sock; - int trueint = 1; - - if( (sock = socket(domain, SOCK_STREAM, IPPROTO_TCP)) < 0) - return -1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int)) < 0) - goto fail; - if (domain == PF_INET6){ - if (bind(sock, addr, sizeof(struct sockaddr_in6)) < 0) - goto fail; - } - else{ - if (bind(sock, addr, sizeof(struct sockaddr_in)) < 0) - goto fail; - } - if (listen(sock, 5) < 0) - goto fail; - return sock; - - fail: - close(sock); - return -1; -} - -int start_extern_socket(uint16_t port) -{ - int ret; - char port_str[7]; - struct addrinfo hint, *ai, *tmp; - memset(&hint, 0, sizeof(hint)); - hint.ai_family = PF_UNSPEC; - hint.ai_socktype = SOCK_STREAM; - hint.ai_flags = AI_PASSIVE; - - snprintf(port_str, 6, "%"PRIu16, port); - port_str[6] = 0; - - ret = getaddrinfo(NULL, port_str, &hint, &ai); - if (ret) - return ret; - for (tmp = ai; tmp; tmp = tmp->ai_next){ - if (tmp->ai_family != AF_INET6) - continue; - ret = do_startup(PF_INET6, tmp->ai_addr); - if (ret >= 0){ - freeaddrinfo(ai); - return ret; - } - } - for (tmp = ai; tmp; tmp = tmp->ai_next){ - if (tmp->ai_family != AF_INET) - continue; - ret = do_startup(PF_INET, tmp->ai_addr); - if (ret >= 0){ - freeaddrinfo(ai); - return ret; - } - } - freeaddrinfo(ai); - return -1; -} - -int accept_extern_connection(int listening_sock) -{ - int sock; - struct sockaddr_in addr; - socklen_t len = sizeof(addr); - int trueint = 1; - - sock = accept(listening_sock, (struct sockaddr *)&addr, &len); - if (sock < 0){ - log_err("error accepting connect to socket : %s\n", strerror(errno)); - return -1; - } - if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &trueint, sizeof(int)) < 0){ - log_err("couldn't set socket keepalive option : %s\n", strerror(errno)); - return -1; - } - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &trueint, sizeof(int)) < 0){ - log_err("couldn't set socket nodelay option : %s\n", strerror(errno)); - return -1; - } - log_verbose("opened external connection\n"); - - return sock; -} - -int check_extern_data_len(uint32_t req, int size) -{ - switch(req){ - case EXTERN_NAMES_REQ: - return 1; - case EXTERN_FENCE_REQ: - case EXTERN_UNFENCE_REQ: - return (size >= sizeof(node_req_t)); - case EXTERN_LIST_BANNED_REQ: - return 1; - case EXTERN_KILL_GSERV_REQ: - return (size >= sizeof(device_req_t) + sizeof(node_req_t)); - case EXTERN_LOGIN_REQ: - return (size >= sizeof(login_req_t) + sizeof(node_req_t)); - case EXTERN_NODENAME_REQ: - return 1; - case EXTERN_UID_REQ: - return (size >= sizeof(device_req_t)); - default: - log_err("unknown external request: %u. closing connection.\n", - (unsigned int)req); - return -1; - } -} - -#define DO_TRANS(action, label)\ -do {\ - if ((action)){\ - log_err("external transfer failed at line %d : %s\n", \ - __LINE__, strerror(errno));\ - goto label;\ - }\ -} while(0) - -void handle_extern_request(int sock, uint32_t cmd, void *buf) -{ - int err; - uint32_t reply = EXTERN_SUCCESS_REPLY; - - log_verbose("got external command 0x%x\n", (unsigned int)cmd); - - switch(cmd){ - case EXTERN_NAMES_REQ: - { - char *buffer = NULL; - uint32_t size; - - err = get_dev_names(&buffer, &size); - if (err < 0){ - reply = -err; - DO_TRANS(send_u32(sock, reply), exit); - break; - } - DO_TRANS(send_u32(sock, reply), names_exit); - DO_TRANS(send_u32(sock, size), names_exit); - if (size) - DO_TRANS(retry_write(sock, buffer, size), names_exit); - - names_exit: - free(buffer); - break; - } - case EXTERN_FENCE_REQ: - { - node_req_t fence_node; - - if (is_clustered == 0){ - log_err("cannot fence clients when started with the -n option\n"); - reply = ENOTSUP; - DO_TRANS(send_u32(sock, reply), exit); - break; - } - - memcpy(&fence_node, buf, sizeof(fence_node)); - - err = add_to_banned_list(fence_node.node_name); - if (!err) - err = kill_gserv(fence_node.node_name, NULL, sock); - if (err < 0){ - reply = -err; - DO_TRANS(send_u32(sock, reply), exit); - close(sock); - } - return; - } - case EXTERN_UNFENCE_REQ: - { - node_req_t unfence_node; - - memcpy(&unfence_node, buf, sizeof(unfence_node)); - remove_from_banned_list(unfence_node.node_name); - DO_TRANS(send_u32(sock, reply), exit); - break; - } - case EXTERN_UID_REQ: - { - device_req_t uid_req; - char *buffer = NULL; - uint32_t size; - - memcpy(&uid_req, buf, sizeof(uid_req)); - err = get_dev_uid(uid_req.name, &buffer, &size); - if (err < 0){ - reply = -err; - DO_TRANS(send_u32(sock,reply), exit); - break; - } - DO_TRANS(send_u32(sock, reply), exit); - DO_TRANS(send_u32(sock, size), exit); - if (size) - DO_TRANS(retry_write(sock, buffer, size), exit); - break; - } - case EXTERN_NODENAME_REQ: - { - uint32_t size; - - size = strlen(nodename) + 1; - DO_TRANS(send_u32(sock, reply), exit); - DO_TRANS(send_u32(sock, size), exit); - DO_TRANS(retry_write(sock, nodename, size), exit); - break; - } - case EXTERN_LIST_BANNED_REQ: - { - char *buffer = NULL; - uint32_t size; - - err = list_banned(&buffer, &size); - if (err < 0){ - reply = -err; - DO_TRANS(send_u32(sock, reply), exit); - break; - } - DO_TRANS(send_u32(sock, reply), banned_exit); - DO_TRANS(send_u32(sock, size), banned_exit); - if (size) - DO_TRANS(retry_write(sock, buffer, size), banned_exit); - banned_exit: - free(buffer); - break; - } - case EXTERN_KILL_GSERV_REQ: - { - device_req_t kill_req; - node_req_t node; - - memcpy(&kill_req, buf, sizeof(kill_req)); - memcpy(&node, buf + sizeof(device_req_t), sizeof(node)); - - dev_info_t *dev; - - dev = find_device(kill_req.name); - if (!dev){ - reply = ENODEV; - DO_TRANS(send_u32(sock, reply), exit); - break; - } - /* FIXME -- I also need the fence list for this */ - err = kill_gserv(node.node_name, dev, sock); - if (err < 0){ - reply = -err; - DO_TRANS(send_u32(sock, reply), exit); - close(sock); - } - return; - } - case EXTERN_LOGIN_REQ: - { - login_req_t login_req; - node_req_t node; - dev_info_t *dev; - int devfd; - - memcpy(&login_req, buf, sizeof(login_req)); - memcpy(&node, buf + sizeof(login_req_t), sizeof(node)); - - err = gserv_login(sock, node.node_name, &login_req, &dev, &devfd); - if (!err){ - fork_gserv(sock, node.node_name, dev, devfd); - close(devfd); - } - break; - } - default: - log_err("unknown exteranl request 0x%x\n", cmd); - reply = ENOTTY; - DO_TRANS(send_u32(sock, reply), exit); - } - exit: - close(sock); -} diff --git a/gnbd/server/extern_req.h b/gnbd/server/extern_req.h deleted file mode 100644 index de461f2..0000000 --- a/gnbd/server/extern_req.h +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __extern_req_h__ -#define __extern_req_h__ - -struct device_req_s { - char name[32]; -}; -typedef struct device_req_s device_req_t; - -struct node_req_s { - char node_name[65]; -}; -typedef struct node_req_s node_req_t; - -struct import_info_s { - uint32_t timeout; - uint16_t flags; - char name[32]; -}; -typedef struct import_info_s import_info_t; - -#define NODENAME_SIZE 65 - -#define EXTERN_NAMES_REQ 1 -#define EXTERN_FENCE_REQ 2 -#define EXTERN_UNFENCE_REQ 3 -/* FIXME -- should this be external */ -#define EXTERN_LIST_BANNED_REQ 4 -/* FIXME -- should this be only external */ -#define EXTERN_KILL_GSERV_REQ 5 -#define EXTERN_LOGIN_REQ 6 -#define EXTERN_NODENAME_REQ 7 -#define EXTERN_UID_REQ 8 - -#define EXTERN_SUCCESS_REPLY 0 -/* FIXME -- is this used */ -#define REPLY_ERR(x) (-((int)(x))) - -extern char nodename[NODENAME_SIZE]; -int start_extern_socket(short unsigned int port); -int accept_extern_connection(int listening_sock); -int check_extern_data_len(uint32_t req, int size); -void handle_extern_request(int sock, uint32_t cmd, void *buf); - -#endif /* __extern_req_h__ */ diff --git a/gnbd/server/fence.c b/gnbd/server/fence.c deleted file mode 100644 index acd4a9a..0000000 --- a/gnbd/server/fence.c +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <inttypes.h> -#include <sys/mount.h> - -#include "list.h" -#include "gnbd_utils.h" -#include "extern_req.h" -#include "fence.h" - -list_decl(timestamp_list); -list_decl(banned_list); - -typedef struct timestamp_s { - uint64_t timestamp; - char node[65]; - list_t list; -} timestamp_t; - -typedef struct banned_s { - char node[65]; - list_t list; -} banned_t; - -int update_timestamp_list(char *node, uint64_t timestamp) -{ - list_t *list_item; - timestamp_t *client; - - list_foreach(list_item, ×tamp_list) { - client = list_entry(list_item, timestamp_t, list); - if (strncmp(node, client->node, 64) == 0) { - if (client->timestamp != timestamp){ - remove_from_banned_list(node); - client->timestamp = timestamp; - } - return 0; - } - } - client = (timestamp_t *)malloc(sizeof(timestamp_t)); - if (!client){ - log_err("couldn't allocate memory for the client %s timestamp\n", node); - return -ENOMEM; - } - strncpy(client->node, node, 65); - client->timestamp = timestamp; - remove_from_banned_list(node); - list_add(&client->list, ×tamp_list); - - return 0; -} - -int check_banned_list(char *node) -{ - list_t *list_item; - banned_t *banned_client; - - list_foreach(list_item, &banned_list) { - banned_client = list_entry(list_item, banned_t, list); - if (strncmp(node, banned_client->node, 64) == 0) { - return 1; - } - } - return 0; -} - -int add_to_banned_list(char *node) -{ - banned_t *banned_client; - - if (check_banned_list(node)){ - log_err("client %s already banned\n", node); - return 0; - } - banned_client = (banned_t *)malloc(sizeof(banned_t)); - if (!banned_client) { - log_err("couldn't allocate memory for the banned client\n"); - return -ENOMEM; - } - strncpy(banned_client->node, node, 65); - list_add(&banned_client->list, &banned_list); - return 0; -} - -void remove_from_banned_list(char *node) -{ - list_t *list_item; - banned_t *banned_client; - - list_foreach(list_item, &banned_list) { - banned_client = list_entry(list_item, banned_t, list); - if (strncmp(banned_client->node, node, 64) == 0) { - list_del(list_item); - free(banned_client); - return; - } - } - log_verbose("client %s is not on banned list\n", node); -} - -int list_banned(char **buffer, uint32_t *list_size) -{ - node_req_t *ptr; - banned_t *banned_client; - list_t *list_item; - int count = 0; - - *buffer = NULL; - list_foreach(list_item, &banned_list) - count++; - if (count == 0){ - *list_size = 0; - return 0; - } - ptr = (node_req_t *)malloc(sizeof(node_req_t) * count); - if (!ptr) { - log_err("cannot allocate memory for banned list reply\n"); - return -ENOMEM; - } - *buffer = (char *)ptr; - *list_size = (uint32_t)(sizeof(node_req_t) * count); - list_foreach(list_item, &banned_list) { - banned_client = list_entry(list_item, banned_t, list); - strncpy(ptr->node_name, banned_client->node, 65); - ptr++; - } - - return 0; -} diff --git a/gnbd/server/fence.h b/gnbd/server/fence.h deleted file mode 100644 index ac3b4ab..0000000 --- a/gnbd/server/fence.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __fence_h__ -#define __fence_h__ - -int update_timestamp_list(char *node, uint64_t timestamp); -int check_banned_list(char *node); -int add_to_banned_list(char *node); -void remove_from_banned_list(char *node); -int list_banned(char **buffer, uint32_t *list_size); - -#endif /* __fence_h__ */ diff --git a/gnbd/server/gnbd_clusterd.c b/gnbd/server/gnbd_clusterd.c deleted file mode 100644 index 7b3915b..0000000 --- a/gnbd/server/gnbd_clusterd.c +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> -#include <string.h> -#include <errno.h> -#include <magma.h> - -#include "gnbd_utils.h" - -#define INTERFACE_GROUP "cluster::usrm" - -static int fd = -1; -static int quit = 0; - -static void sig_usr1(int sig) -{} - -static void sig_term(int sig) -{ - quit = 1; -} - -void kill_gnbd_clusterd(void){ - int pid = 0; - - if (check_lock("gnbd_clusterd.pid", &pid) == 0) - return; - - kill(pid, SIGTERM); -} - - -int main(int argc, char **argv){ - struct sigaction act; - - program_name = "gnbd_clusterd"; - - if (argc > 2 || (argc == 2 && strcmp(argv[1], "-k"))){ - printf("Usage: gnbd_clusted [-k]\n"); - exit(1); - } - - if (argc == 2){ - kill_gnbd_clusterd(); - exit(0); - } - - if (check_lock("gnbd_clusterd.pid", NULL) == 1) - exit(0); - - daemonize_and_exit_parent(); - - memset(&act, 0, sizeof(act)); - act.sa_handler = sig_term; - if (sigaction(SIGTERM, &act, NULL) < 0) - fail_startup("cannot set a handler for SIGTERM : %s\n", strerror(errno)); - act.sa_handler = sig_usr1; - if (sigaction(SIGUSR1, &act, NULL) < 0) - fail_startup("cannot set a handler for SIGUSR1 : %s\n", strerror(errno)); - - if (!pid_lock("")){ - finish_startup("gnbd_clusterd already running\n"); - exit(0); - } - fd = clu_connect("gnbd", 1); - - if (fd < 0) - fail_startup("cannot connect to cluster manager : %s\n", strerror(-fd)); - finish_startup("connected\n"); - - while(!quit){ - int event; - event = clu_get_event(fd); - } - clu_disconnect(fd); - - return 0; -} diff --git a/gnbd/server/gnbd_serv.c b/gnbd/server/gnbd_serv.c deleted file mode 100644 index b4b9f48..0000000 --- a/gnbd/server/gnbd_serv.c +++ /dev/null @@ -1,409 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <getopt.h> -#include <signal.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/un.h> -#include <errno.h> -#include <syslog.h> - -#include "gnbd_endian.h" -#include "gnbd_server.h" -#include "local_req.h" -#include "extern_req.h" -#include "gserv.h" -#include "trans.h" - -#include "copyright.cf" - -short unsigned int port = GNBD_SERVER_PORT; - -#define BUFSIZE (sizeof(info_req_t) + sizeof(uint32_t)) - -struct connecter_s { - int type; /* LOCAL or EXTERNAL */ - uint32_t req; /* EXTERN_XXX or LOCAL_XXX, 0 for no request read yet */ - int size; - char *buf; -}; -typedef struct connecter_s connecter_t; - -#define NORMAL_KILL 1 -#define FORCE_KILL 2 -int killing_gnbd_serv = 0; -connecter_t *connecters; -struct pollfd *polls; -int max_id; -int is_clustered = 1; - -#define LOCAL 0 -#define EXTERNAL 1 - -int usage(void){ - printf( -"Usage:\n" -"\n" -"gnbd_serv [options]\n" -"\n" -"Options:\n" -" -h print this help message\n" -" -k kill the currently running gnbd_serv\n" -" -K kill gnbd_serv even if there are exported devices\n" -" -n No cluster. Do not contact cluster manager\n" -" -p <port> port to start the gnbd_server on (default is 14567)\n" -" -q quiet mode. Only print errors.\n" -" -v verbose output\n" -" -V version information\n"); - return 0; -} - - -void setup_poll(void) -{ - int i; - - polls = malloc(open_max() * sizeof(struct pollfd)); - if (!polls) - fail_startup("cannot allocate poller structure : %s\n", strerror(errno)); - for (i = 0; i < open_max(); i++){ - polls[i].fd = -1; - polls[i].revents = 0; - } - connecters = malloc(open_max() * sizeof(connecter_t)); - if (!connecters) - fail_startup("cannot allocate connecter structure : %s\n", - strerror(errno)); - polls[LOCAL].fd = start_comm_device("gnbd_servcomm"); - if (polls[LOCAL].fd < 0) - fail_startup("cannot startup local connection\n"); - polls[LOCAL].events = POLLIN; - polls[EXTERNAL].fd = start_extern_socket(port); - polls[EXTERNAL].events = POLLIN; - max_id = 1; -} - -void add_poller(int fd, int type){ - int i; - - if (fd < 0) - return; - for (i = 0; polls[i].fd >= 0 && i < open_max(); i++); - if (i >= open_max()){ - log_err("maximum number of open file descriptors reached\n"); - /* FIXME -- should I send a restart fail reply */ - close(fd); - return; - } - connecters[i].buf = malloc(BUFSIZE); - if (!connecters[i].buf){ - log_err("couldn't allocate memory for connection buffer\n"); - close(fd); - return; - } - polls[i].fd = fd; - polls[i].events = POLLIN; - connecters[i].type = type; - connecters[i].req = 0; - connecters[i].size = 0; - if (i > max_id) - max_id = i; -} - -void remove_poller(int index) -{ - polls[index].fd = -1; - polls[index].revents = 0; - free(connecters[index].buf); - while(polls[max_id].fd == -1) - max_id--; -} - -void close_poller(int index) -{ - close(polls[index].fd); - if (index == LOCAL){ - polls[LOCAL].fd = start_comm_device("gnbd_servcomm"); - if (polls[LOCAL].fd < 0) - /* FIXME -- should I try to recover from this */ - raise(SIGTERM); - } - else if (index == EXTERNAL) - polls[EXTERNAL].fd = start_extern_socket(port); - else - remove_poller(index); -} - -void handle_request(int index) -{ - int bytes; - connecter_t *connecter = &connecters[index]; - int ret; - - errno = 0; - bytes = read(polls[index].fd, connecter->buf + connecter->size, - BUFSIZE - connecter->size); - if (bytes <= 0){ - if (bytes == 0) - log_err("unexpectedly read EOF on %s connection, index: %d, req: %d\n", - (connecter->type == LOCAL)? "local" : "external", - index, connecters->req); - else if (errno != EINTR) - log_err("cannot read from %s connection, index: %d, req: %d : %s\n", - (connecter->type == LOCAL)? "local" : "external", - index, connecter->req, strerror(errno)); - log_verbose("total read : %d bytes\n", connecter->size); - close_poller(index); - return; - } - - connecter->size += bytes; - if (connecter->req == 0 && connecter->size >= sizeof(uint32_t)){ - memcpy(&connecter->req, connecter->buf, sizeof(uint32_t)); - if (connecter->type == EXTERNAL) - connecter->req = be32_to_cpu(connecter->req); - } - if (connecter->size < sizeof(uint32_t)) - return; - if (connecter->type == LOCAL){ - ret = check_local_data_len(connecter->req, - connecter->size - sizeof(uint32_t)); - if (ret < 0) - close_poller(index); - else if (ret){ - handle_local_request(polls[index].fd, connecter->req, - connecter->buf + sizeof(uint32_t)); - remove_poller(index); - } - return; - } - else { - ret = check_extern_data_len(connecter->req, - connecter->size - sizeof(uint32_t)); - if (ret < 0) - close_poller(index); - else if (ret) { - handle_extern_request(polls[index].fd, connecter->req, - connecter->buf + sizeof(uint32_t)); - remove_poller(index); - } - return; - } -} - -void do_poll(void) -{ - int err; - int i; - - /* FIXME --I should probably do something every timeout, like check the - cluster manager */ - err = poll(polls, max_id + 1, -1); - if (err <= 0){ - if (err < 0 && errno != EINTR) - log_err("poll error : %s\n", strerror(errno)); - return; - } - for (i = 0; i <= max_id; i++){ - if (polls[i].revents & (POLLERR | POLLHUP | POLLNVAL)){ - log_err("Bad poll result, 0x%x on id %d\n", polls[i].revents, i); - close_poller(i); - continue; - } - if (polls[i].revents & POLLIN){ - if (i == LOCAL) - add_poller(accept_local_connection(polls[i].fd), LOCAL); - else if (i == EXTERNAL){ - int fd; - - fd = accept_extern_connection(polls[i].fd); - add_poller(fd, EXTERNAL); - } - else - handle_request(i); - } - } -} - - -void sig_term(int sig) -{ - exit(0); -} - - -void setup_signals(void) -{ - struct sigaction act; - sigset_t block_sigchld_set; - - sigemptyset(&block_sigchld_set); - sigaddset(&block_sigchld_set, SIGCHLD); - - memset(&act,0,sizeof(act)); - act.sa_handler = sig_term; - act.sa_mask = block_sigchld_set; - if( sigaction(SIGTERM, &act, NULL) <0) - fail_startup("cannot setup SIGTERM handler : %s\n", strerror(errno)); - memset(&act,0,sizeof(act)); - act.sa_handler = sig_chld; - if( sigaction(SIGCHLD, &act, NULL) <0) - fail_startup("cannot setup SIGCHLD handler : %s\n", strerror(errno)); - memset(&act,0,sizeof(act)); - act.sa_handler = sig_hup; - if( sigaction(SIGHUP, &act, NULL) <0) - fail_startup("cannot setup SIGHUP handler : %s\n", strerror(errno)); -} - -void parse_cmdline(int argc, char **argv) -{ - int c; - - program_name = "gnbd_serv"; - while ((c = getopt(argc, argv, "hkKnp:qvV")) != -1){ - switch(c){ - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - - case 'h': - usage(); - exit(0); - - case 'k': - killing_gnbd_serv = NORMAL_KILL; - continue; - - case 'K': - killing_gnbd_serv = FORCE_KILL; - continue; - - case 'n': - is_clustered = 0; - continue; - - case 'p': - if (sscanf(optarg, "%hu", &port) != 1){ - printe("invalid port %s with -p\nPlease see man page for details.\n", - optarg); - exit(1); - } - continue; - - case 'q': - if (verbosity == VERBOSE){ - printe("cannot use both -q and -v options\nPlease use '-h' for usage.\n"); - exit(1); - } - verbosity = QUIET; - continue; - - case 'v': - if (verbosity == QUIET){ - printe("cannot use both -q and -v options\nPlease use '-h' for usage.\n"); - exit(1); - } - verbosity = VERBOSE; - continue; - - case 'V': - printf("%s %s (built %s %s)\n", program_name, GNBD_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - - default: - printe("No action for option -- %c\nPlease use '-h' for usage.\n", c); - exit(1); - } - } -} - -void exit_main(void) -{ - if (!is_gserv) /* don't do this is you are a gserv process. Only - the main process should kill the gservs */ - kill_all_gserv(); -} - -int main(int argc, char **argv) -{ - parse_cmdline(argc, argv); - - if (killing_gnbd_serv){ - int pid; - if (!check_lock("gnbd_serv.pid", &pid)){ - printm("gnbd_serv not running\n"); - return 0; - } - if (killing_gnbd_serv == NORMAL_KILL){ - int fd; - - fd = connect_to_comm_device("gnbd_serv"); - if (fd < 0) - return 1; - if (send_cmd(fd, LOCAL_SHUTDOWN_REQ, "shutdown") < 0) - return 1; - if (recv_reply(fd, "shutdown") < 0) - return 1; - printm("gnbd_serv shutting down\n"); - return 0; - } - if (kill(pid, SIGTERM) < 0){ - printm("can't send gnbd_serv TERM signal : %s\n", strerror(errno)); - return 1; - } - printm("gnbd_serv killed\n"); - return 0; - } - - daemonize_and_exit_parent(); - - if(!pid_lock("")) - fail_startup("%s already running\n", program_name); - - setup_signals(); - /* FIXME -- somewhere I should set myself to nobody */ - - if (get_my_nodename(nodename, is_clustered) < 0){ - if (is_clustered){ - printe("cannot get node name : %s\n", strerror(errno)); - if (errno == ESRCH) - printe("No cluster manager is running\n"); - else if (errno == ELIBACC) - printe("cannot find magma plugins\n"); - fail_startup("If you are not planning to use a cluster manager, use -n\n"); - } - else - fail_startup("cannot get node name : %s\n", strerror(errno)); - } - - setup_poll(); - - if (atexit(exit_main) < 0) - fail_startup("cannot register function with atexit\n"); - - finish_startup("startup succeeded\n"); - - while(1){ - do_poll(); - } - - exit(0); -} diff --git a/gnbd/server/gnbd_server.h b/gnbd/server/gnbd_server.h deleted file mode 100644 index e958d77..0000000 --- a/gnbd/server/gnbd_server.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gnbd_server_h__ -#define __gnbd_server_h__ - -#include "gnbd_utils.h" - -#define GNBD_SERVER_PORT 14567 - -#endif /* __gnbd_server_h__ */ - - - - diff --git a/gnbd/server/gserv.c b/gnbd/server/gserv.c deleted file mode 100644 index ca63b2b..0000000 --- a/gnbd/server/gserv.c +++ /dev/null @@ -1,631 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#define __USE_XOPEN2K /* needed to get posix_memalign */ -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <linux/gnbd.h> - -#include "gnbd_endian.h" -#include "list.h" -#include "gnbd_utils.h" -#include "fence.h" -#include "device.h" -#include "gserv.h" -#include "trans.h" -#include "local_req.h" - -#include <sys/socket.h> - -int is_gserv = 0; /* This gets set when child is forked. It is needed so that - the gserv processes don't execute the atexit commands - set up for the main program */ - -list_decl(waiter_list); -list_decl(gserv_list); -off_t file_offset = (off_t)-1; - -struct waiter_s { - int sock; - int count; - pid_t *pids; - list_t list; -}; -typedef struct waiter_s waiter_t; - -void send_keep_alive(int sock); - -struct gserv_info_s { - char node[65]; - dev_info_t *dev; - pid_t pid; - list_t list; -}; -typedef struct gserv_info_s gserv_info_t; - -void readit(int fd, void *buf, size_t count, char *msg, int remote) -{ - int bytes; - - while(count > 0){ - got_sighup = 0; - bytes = read(fd, buf, count); - if (bytes < 0){ - if (errno != EINTR){ - log_err("failed reading %s : %s\n", msg, strerror(errno)); - exit(1); - } - log_verbose("read interrupted, retrying\n"); - if (remote && got_sighup) - send_keep_alive(fd); - continue; - } - if (bytes == 0){ - log_fail("read EOF %s\n", msg); - exit(1); - } - buf += bytes; - count -= bytes; - } -} - -void writeit(int fd, void *buf, size_t count, char *msg) -{ - int bytes; - - while(count > 0){ - bytes = write(fd, buf, count); - if (bytes < 0){ - if (errno != EINTR){ - log_err("failed writing %s : %s\n", msg, strerror(errno)); - exit(1); - } - log_verbose("write interrupted. retrying\n"); - continue; - } - /* FIXME -- should I do this */ - if (bytes == 0){ - log_fail("returned 0 when writing %s\n", msg); - exit(1); - } - buf += bytes; - count -= bytes; - } -} - -#define SEND_REPLY \ -do { \ - writeit(sock, &reply, sizeof(reply), "reply"); \ -} while(0) - -/* FIXME -- Do I need to do something with the offset pointer */ -#define SEND_ERR \ -do { \ - reply.error = cpu_to_be32(-1); \ - SEND_REPLY; \ - reply.error = 0; \ - file_offset = -1; \ -} while(0) - -void send_keep_alive(int sock) -{ - struct gnbd_reply reply; - reply.magic = be32_to_cpu(GNBD_KEEP_ALIVE_MAGIC); - /* - *You do this twice, because the first write to a dead socket - * doesn't fail - */ - SEND_REPLY; - SEND_REPLY; -} - -#define MAXSIZE 131072 - -void do_file_read(int fd, char *buf, uint64_t req_offset, uint32_t len) -{ - if (req_offset != file_offset){ - if (lseek(fd, req_offset, SEEK_SET) < 0){ - log_err("cannot seek to request location : %s\n", strerror(errno)); - exit(1); - } - file_offset = req_offset; - } - readit(fd, buf, len, "in do_file_read", 0); - file_offset += len; -} - -void do_file_write(int fd, char *buf, uint64_t req_offset, uint32_t len) -{ - if (req_offset != file_offset){ - if (lseek(fd, req_offset, SEEK_SET) < 0){ - log_err("cannot seek to request location : %s\n", strerror(errno)); - exit(1); - } - file_offset = req_offset; - } - writeit(fd, buf, len, "in do_file_write"); - file_offset += len; -} - -/* This must be called with SIGCHLD blocked */ -static list_t *get_next_valid(list_t *list_item, list_t *head){ - gserv_info_t *info; - list_t *curr, *next; - curr = list_item; - next = curr->next; - while(curr != head){ - info = list_entry(curr, gserv_info_t, list); - if (info->pid != 0) - break; - list_del(&info->list); - free(info); - curr = next; - next = curr->next; - } - return curr; -} - -/* This must be called with SIGCHLD blocked */ -#define foreach_gserv(tmp, head) \ - for ((tmp) = get_next_valid((head)->next, (head)); (tmp) != (head); \ - (tmp) = get_next_valid((tmp)->next, (head))) - -int get_gserv_info(char **buffer, uint32_t *list_size) -{ - gserv_req_t *ptr; - gserv_info_t *server; - list_t *list_item; - int count = 0; - - *buffer = NULL; - block_sigchld(); - foreach_gserv(list_item, &gserv_list) - count++; - if (count == 0){ - *list_size = 0; - return 0; - } - ptr = (gserv_req_t *)malloc(sizeof(gserv_req_t) * count); - if (!ptr){ - log_err("cannot allocate memory for server info replay\n"); - return -ENOMEM; - } - *buffer = (char *)ptr; - *list_size = (uint32_t)(sizeof(gserv_req_t) * count); - list_foreach(list_item, &gserv_list){ - server = list_entry(list_item, gserv_info_t, list); - strncpy(ptr->node, server->node, 65); - ptr->pid = (uint32_t)server->pid; - strncpy(ptr->name, server->dev->name, 32); - ptr->name[31] = 0; - ptr++; - } - unblock_sigchld(); - return 0; -} - -void gserv(int sock, char *node, uint64_t sectors, unsigned int flags, - char *name, int devfd) -{ - void *buf; - struct gnbd_request request; - struct gnbd_reply reply; - uint64_t device_size = sectors << 9; - uint64_t offset; - uint32_t len; - uint32_t type; - char from_str[70]; - char to_str[70]; - - /* FIXME -- This should be done when I first open the file.. maybe */ - if (posix_memalign(&buf, fpathconf(devfd, _PC_REC_XFER_ALIGN), - MAXSIZE) < 0){ - fprintf(stderr, "posix_memalign failed : %s\n", strerror(errno)); - exit(1); - } - - sprintf(from_str, "from %s", node); - sprintf(to_str, "to %s", node); - - /* FIXME -- setup signal handling*/ - reply.magic = be32_to_cpu(GNBD_REPLY_MAGIC); - reply.error = 0; - - while(1){ - readit(sock, &request, sizeof(request), from_str, 1); - offset = be64_to_cpu(request.from); - type = be32_to_cpu(request.type); - len = be32_to_cpu(request.len); - memcpy(reply.handle, request.handle, sizeof(reply.handle)); - - /* If I get these two errors, there is something unfixable wrong with the - gnbd client */ - if (be32_to_cpu(request.magic) != GNBD_REQUEST_MAGIC){ - log_fail("bad request magic 0x%lx %s, shutting down\n", - (unsigned long)be32_to_cpu(request.magic), from_str); - exit(1); - } - if (len > MAXSIZE){ - log_err("request len %lu is larger than my buffer, shutting down\n", - (unsigned long)len); - exit(1); - } - /* If I get these two errors, someone is sending me bunk requests. */ - if ((UINT64_MAX - offset) < len){ - readit(sock, buf, len, from_str, 1); - log_fail("request %s past the end of the block device\n", from_str); - SEND_ERR; - continue; - } - if ((offset + len) > device_size){ - readit(sock, buf, len, from_str, 1); - log_fail("request %s past the end of the device\n", from_str); - SEND_ERR; - continue; - } - - switch(type){ - case GNBD_CMD_READ: - memcpy(buf, &reply, sizeof(reply)); - do_file_read(devfd, buf, offset, len); - SEND_REPLY; - writeit(sock, buf, len, to_str); - break; - case GNBD_CMD_WRITE: - readit(sock, buf, len, from_str, 1); - do_file_write(devfd, buf, offset, len); - SEND_REPLY; - break; - case GNBD_CMD_DISC: - /* It's the clients job to make sure that there are no outstanding - writes */ - log_verbose("got shutdown request, shutting down\n"); - SEND_REPLY; - exit(0); - case GNBD_CMD_PING: - log_verbose("got ping command\n"); - SEND_REPLY; - break; - default: - log_fail("got unknown request type (%d) %s, shutting down\n", - type, from_str); - SEND_ERR; - exit(1); - } - } - free(buf); - exit(0); -} - -/* This must be called with SIGCHLD blocked */ -int add_gserv_info(int sock, char *node, dev_info_t *dev, pid_t pid) -{ - gserv_info_t *info; - - info = (gserv_info_t *)malloc(sizeof(gserv_info_t)); - if (!info){ - printe("couldn't allocate memory for server info\n"); - return -1; - } - strncpy(info->node, node, 65); - info->dev = dev; - info->pid = pid; - list_add(&info->list, &gserv_list); - - return 0; -} - -void reply_to_waiter(waiter_t *waiter) -{ - uint32_t reply = 0; - - if (retry_write(waiter->sock, &reply, sizeof(reply)) < 0) - log_err("cannot reply to remove server request : %s\n", strerror(errno)); - close(waiter->sock); -} - -/* this must be called with SIGCHLD blocked */ -void release_waiters(pid_t pid) -{ - int count; - list_t *list_item; - waiter_t *waiter; - - list_foreach(list_item, &waiter_list){ - waiter = list_entry(list_item, waiter_t, list); - for (count = 0; count < waiter->count; count++){ - if (pid == waiter->pids[count]) - break; - } - if (count >= waiter->count) - continue; - waiter->count--; - if (waiter->count) - waiter->pids[count] = waiter->pids[waiter->count]; - else - reply_to_waiter(waiter); - } -} - -void sig_chld(int sig) -{ - int status; - pid_t pid; - list_t *list_item; - gserv_info_t *info; - - while( (pid = waitpid(-1, &status, WNOHANG)) > 0){ - if(WIFEXITED(status)) - log_msg("server process %d exited with %d", pid, WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - log_msg("server process %d exited because of signal %d\n", pid, - WTERMSIG(status)); - list_foreach(list_item, &gserv_list){ - info = list_entry(list_item, gserv_info_t, list); - if (info->pid == pid){ - info->pid = 0; - release_waiters(pid); - break; - } - } - if (list_item == &gserv_list) - log_err("couldn't find server [pid: %d] in servers list\n", pid); - } -} - -void fork_gserv(int sock, char *node, dev_info_t *dev, int devfd) -{ - struct sigaction act; - pid_t pid; - block_sigchld(); - if( (pid = fork()) < 0){ - log_err("cannot for child to handle the connection : %s\n", - strerror(errno)); - return; - } - if (pid != 0){ - if (add_gserv_info(sock, node, dev, pid) < 0) - kill(pid, SIGTERM); - unblock_sigchld(); - return; - } - is_gserv = 1; - unblock_sigchld(); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - if( sigaction(SIGTERM, &act, NULL) <0){ - log_err("cannot restore SIGTERM handler : %s\n", strerror(errno)); - exit(1); - } - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - if( sigaction(SIGCHLD, &act, NULL) <0){ - log_err("cannot restore SIGCHLD handler : %s\n", strerror(errno)); - exit(1); - } - /* FIXME -- is this necessary. I think that it's already set to this */ - memset(&act,0,sizeof(act)); - act.sa_handler = sig_hup; - if( sigaction(SIGHUP, &act, NULL) <0){ - log_err("cannot set SIGHUP handler : %s\n", strerror(errno)); - exit(1); - } - /* FIXME -- need to close and free things, like the external socket, and - useless memory, and the log... I need to open a new one. - There is probably some signal stuff that I should do */ - gserv(sock, node, dev->sectors, dev->flags, dev->name, devfd); - exit(0); -} - -int gserv_login(int sock, char *node, login_req_t *login_req, - dev_info_t **devptr, int *devfd) -{ - uint64_t sectors; - int err; - login_reply_t login_reply; - dev_info_t *dev; - int fd; - - *devfd = -1; - *devptr = NULL; - login_reply.version = 0; - login_reply.err = 0; - - BE_LOGIN_REQ_TO_CPU(login_req); - - if (login_req->version != PROTOCOL_VERSION){ - log_err("protocol version mismatch: client it using version %d, " - "server is using version %d\n", login_req->version, - PROTOCOL_VERSION); - login_reply.version = PROTOCOL_VERSION; - err = -EINVAL; - goto fail_reply; - } - - err = update_timestamp_list(node, login_req->timestamp); - if (err) - goto fail_reply; - - if (check_banned_list(node)) { - log_err("client %s is banned. Canceling login\n", node); - err = -EPERM; - goto fail_reply; - } - - dev = find_device(login_req->devname); - if (dev == NULL){ - log_err("unknown device '%s'. login failed\n", login_req->devname); - err = -ENODEV; - goto fail_reply; - } - - if (dev->flags & GNBD_FLAGS_INVALID){ - log_err("device '%s' is marked invalid. login failed\n", - login_req->devname); - err = -ENODEV; - goto fail_reply; - } - - err = open_file(dev->path, dev->flags, &fd); - if (err < 0) - goto fail_reply; - - err = get_size(fd, §ors); - if (err < 0) - goto fail_reply; - if (sectors != dev->sectors){ - log_fail("size of the exported file %s has changed, aborting\n", - dev->path); - goto fail_file; - } - - login_reply.sectors = dev->sectors; - - CPU_TO_BE_LOGIN_REPLY(&login_reply); - - if (retry_write(sock, &login_reply, sizeof(login_reply)) < 0){ - err = -errno; - log_err("cannot set login reply to %s failed : %s\n", node, - strerror(errno)); - goto fail_file; - } - - *devfd = fd; - *devptr = dev; - return 0; - - fail_file: - close(fd); - - fail_reply: - login_reply.err = -err; - CPU_TO_BE_LOGIN_REPLY(&login_reply); - retry_write(sock, &login_reply, sizeof(login_reply)); - return err; -} - -int __find_gserv_info(char *node, dev_info_t *dev) -{ - list_t *list_item; - gserv_info_t *info = NULL; - foreach_gserv(list_item, &gserv_list) { - info = list_entry(list_item, gserv_info_t, list); - if ((!node || strncmp(info->node, node, 65) == 0) && - (!dev || dev == info->dev)){ - return 1; - } - } - return 0; -} - -int find_gserv_info(char *node, dev_info_t *dev) -{ - int ret; - block_sigchld(); - ret = __find_gserv_info(node, dev); - unblock_sigchld(); - return ret; -} - -/* call with sigchld blocked */ -void kill_all_gserv(void) -{ - list_t *list_item; - gserv_info_t *info = NULL; - foreach_gserv(list_item, &gserv_list) { - info = list_entry(list_item, gserv_info_t, list); - kill(info->pid, SIGTERM); - } -} - -void validate_gservs(void) -{ - list_t *list_item; - gserv_info_t *info; - - foreach_gserv(list_item, &gserv_list) { - info = list_entry(list_item, gserv_info_t, list); - kill(info->pid, SIGHUP); - } -} - -int kill_gserv(char *node, dev_info_t *dev, int sock) -{ - int err = 0; - list_t *list_item, *tmp; - gserv_info_t *info = NULL; - waiter_t *waiter = NULL; - int count = 0; - - block_sigchld(); - - /* free the dead waiters */ - list_foreach_safe(list_item, &waiter_list, tmp) { - waiter = list_entry(list_item, waiter_t, list); - if (!waiter->count){ - if (waiter->pids) - free(waiter->pids); - list_del(&waiter->list); - free(waiter); - } - } - waiter = malloc(sizeof(waiter_t)); - if (!waiter){ - log_err("cannot allocate memory for waiter\n"); - err = -ENOMEM; - goto out; - } - waiter->count = 0; - waiter->sock = sock; - waiter->pids = NULL; - foreach_gserv(list_item, &gserv_list) { - info = list_entry(list_item, gserv_info_t, list); - if ((!node || strncmp(info->node, node, 65) == 0) && - (!dev || dev == info->dev)) - waiter->count++; - } - if (!waiter->count){ - reply_to_waiter(waiter); - free(waiter); - goto out; - } - waiter->pids = malloc(waiter->count * sizeof(pid_t)); - if (!waiter->pids){ - log_err("cannot allocate memory for waiter pid list\n"); - free(waiter); - err = -ENOMEM; - goto out; - } - list_add(&waiter->list, &waiter_list); - foreach_gserv(list_item, &gserv_list) { - info = list_entry(list_item, gserv_info_t, list); - if ((!node || strncmp(info->node, node, 65) == 0) && - (!dev || dev == info->dev)){ - waiter->pids[count] = info->pid; - count++; - /* FIXME -- I need to make sure that I have I can't get EPERM here */ - kill(info->pid, SIGTERM); - } - } - out: - unblock_sigchld(); - return err; -} diff --git a/gnbd/server/gserv.h b/gnbd/server/gserv.h deleted file mode 100644 index e2ddcf8..0000000 --- a/gnbd/server/gserv.h +++ /dev/null @@ -1,67 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gserv_h__ -#define __gserv_h__ - -#include "device.h" - -#define PROTOCOL_VERSION 2 - -struct login_req_s { - uint64_t timestamp; - uint16_t version; - uint8_t pad[6]; - char devname[32]; -}; -typedef struct login_req_s login_req_t; - -#define BE_LOGIN_REQ_TO_CPU(x)\ -(x)->timestamp = be64_to_cpu((x)->timestamp);\ -(x)->version = be16_to_cpu((x)->version); - -#define CPU_TO_BE_LOGIN_REQ(x)\ -(x)->timestamp = cpu_to_be64((x)->timestamp);\ -(x)->version = cpu_to_be16((x)->version); - -struct login_reply_s { - uint64_t sectors; - uint16_t version; - uint8_t err; - uint8_t pad[5]; -}; -typedef struct login_reply_s login_reply_t; - -#define BE_LOGIN_REPLY_TO_CPU(x)\ -(x)->sectors = be64_to_cpu((x)->sectors);\ -(x)->version = be16_to_cpu((x)->version); - -#define CPU_TO_BE_LOGIN_REPLY(x)\ -(x)->sectors = cpu_to_be64((x)->sectors);\ -(x)->version = cpu_to_be16((x)->version); - -extern int is_gserv; - -void gserv(int sock, char *node, uint64_t sectors, unsigned int flags, - char *name, int devfd); -int add_gserv_info(int sock, char *node, dev_info_t *dev, pid_t pid); -void fork_gserv(int sock, char *node, dev_info_t *dev, int devfd); -int gserv_login(int sock, char *node, login_req_t *login_req, dev_info_t **dev, - int *devfd); -int kill_gserv(char *node, dev_info_t * dev, int sock); -int find_gserv_info(char *node, dev_info_t * dev); -void sig_chld(int sig); -void kill_all_gserv(void); -int get_gserv_info(char **buffer, uint32_t *size_size); -void validate_gservs(void); - -#endif /* __gserv_h__ */ diff --git a/gnbd/server/list.h b/gnbd/server/list.h deleted file mode 100644 index 2400056..0000000 --- a/gnbd/server/list.h +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __list_h__ -#define __list_h__ - -struct list -{ - struct list *next, *prev; -}; -typedef struct list list_t; - - - -#define list_decl(var) list_t var = { &var, &var } - -#define list_empty(var) ((var)->next == (var)) -#define list_entry(var, type, mem) ((type *)((unsigned long)(var) - (unsigned long)(&((type *)NULL)->mem))) - - - -#define list_init(head) \ -do \ -{ \ - list_t *list_var = (head); \ - list_var->next = list_var->prev = list_var; \ -} \ -while (0) - -#define list_add(new, head) \ -do \ -{ \ - list_t *list_var_new = (new); \ - list_t *list_var_head = (head); \ - list_var_new->next = list_var_head->next; \ - list_var_new->prev = list_var_head; \ - list_var_head->next->prev = list_var_new; \ - list_var_head->next = list_var_new; \ -} \ -while (0) - -#define list_add_next list_add - -#define list_add_prev(new, head) \ -do \ -{ \ - list_t *list_var_new = (new); \ - list_t *list_var_head = (head); \ - list_var_new->prev = list_var_head->prev; \ - list_var_new->next = list_var_head; \ - list_var_head->prev->next = list_var_new; \ - list_var_head->prev = list_var_new; \ -} \ -while (0) - -#define list_del(var) \ -do \ -{ \ - list_t *list_var = (var); \ - list_var->next->prev = list_var->prev; \ - list_var->prev->next = list_var->next; \ -} \ -while (0) - -#define list_del_init(var) \ -do \ -{ \ - list_t *list_var = (var); \ - list_var->next->prev = list_var->prev; \ - list_var->prev->next = list_var->next; \ - list_var->next = list_var->prev = list_var; \ -} \ -while (0) - -#define list_foreach(tmp, head) \ - for ((tmp) = (head)->next; (tmp) != (head); (tmp) = (tmp)->next) - -#define list_foreach_safe(tmp, head, x) \ - for ((tmp) = (head)->next, (x) = (tmp)->next; \ - (tmp) != (head); \ - (tmp) = (x), (x) = (x)->next) - - - -#endif /* __OSI_LIST_DOT_H__ */ diff --git a/gnbd/server/local_req.c b/gnbd/server/local_req.c deleted file mode 100644 index 5649c5b..0000000 --- a/gnbd/server/local_req.c +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <strings.h> -#include <errno.h> -#include <syslog.h> -#include <signal.h> -#include <inttypes.h> - -#include "list.h" -#include "gnbd_utils.h" -#include "local_req.h" -#include "device.h" -#include "gserv.h" -#include "trans.h" - -int accept_local_connection(int listening_sock) -{ - int sock; - struct sockaddr_un addr; - socklen_t len = sizeof(addr); - - sock = accept(listening_sock, (struct sockaddr *)&addr, &len); - if (sock < 0){ - log_err("error accepting connect to unix socket : %s\n", strerror(errno)); - return -1; - } - - return sock; -} - -#define DO_TRANS(action, label)\ -do {\ - if ((action)){\ - log_err("local transfer failed at line %d : %s\n", \ - __LINE__, strerror(errno));\ - goto label;\ - }\ -} while(0) - -int check_local_data_len(uint32_t req, int size) -{ - switch(req){ - case LOCAL_CREATE_REQ: - return (size >= sizeof(info_req_t)); - case LOCAL_REMOVE_REQ: - case LOCAL_INVALIDATE_REQ: - return (size >= sizeof(name_req_t)); - case LOCAL_FULL_LIST_REQ: - case LOCAL_GSERV_LIST_REQ: - case LOCAL_SHUTDOWN_REQ: - case LOCAL_VALIDATE_REQ: - return 1; - default: - log_err("unknown local request: %u. closing connection.\n", - (unsigned int)req); - return -1; - } -} - -void handle_local_request(int sock, uint32_t cmd, void *buf) -{ - int err; - uint32_t reply = LOCAL_SUCCESS_REPLY; - - /* FIXME -- the command should be text */ - log_verbose("got local command 0x%x\n", (unsigned int)cmd); - - switch(cmd){ - case LOCAL_CREATE_REQ: - { - info_req_t create_req; - - memcpy(&create_req, buf, sizeof(create_req)); - create_req.name[31] = 0; - create_req.path[255] = 0; - create_req.uid[63] = 0; - err = create_device(create_req.name, create_req.path, create_req.uid, - (unsigned int)create_req.timeout, - (unsigned int)create_req.flags); - if (err < 0) - reply = -err; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - case LOCAL_REMOVE_REQ: - { - name_req_t remove_req; - - memcpy(&remove_req, buf, sizeof(remove_req)); - err = last_uncached_device(remove_req.name); - if (err < 0){ - reply = -err; - goto remove_reply; - } - reply = err; - err = remove_device(remove_req.name); - if (err < 0) - reply = -err; - remove_reply: - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - case LOCAL_INVALIDATE_REQ: - { - name_req_t remove_req; - - memcpy(&remove_req, buf, sizeof(remove_req)); - /* This goes on a waiter list */ - err = invalidate_device(remove_req.name, sock); - if (err < 0){ - reply = -err; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - return; - } - case LOCAL_FULL_LIST_REQ: - { - char *buffer = NULL; - uint32_t size; - - err = get_dev_info(&buffer, &size); - if (err < 0){ - reply = -err; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), list_exit); - DO_TRANS(retry_write(sock, &size, sizeof(size)), list_exit); - if (size) - DO_TRANS(retry_write(sock, buffer, size), list_exit); - - list_exit: - free(buffer); - break; - } - /* FIXME -- I need to look at which server processes are serving who*/ - case LOCAL_GSERV_LIST_REQ: - { - char *buffer = NULL; - uint32_t size; - - err = get_gserv_info(&buffer, &size); - if (err < 0){ - reply = -err; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), gserv_exit); - DO_TRANS(retry_write(sock, &size, sizeof(size)), gserv_exit); - if (size) - DO_TRANS(retry_write(sock, buffer, size), gserv_exit); - - gserv_exit: - free(buffer); - break; - } - case LOCAL_SHUTDOWN_REQ: - if (have_devices()){ - reply = EBUSY; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - } - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - raise(SIGTERM); - break; - case LOCAL_VALIDATE_REQ: - validate_gservs(); - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - break; - default: - log_err("unknown local request 0x%x\n", cmd); - reply = ENOTTY; - DO_TRANS(retry_write(sock, &reply, sizeof(reply)), exit); - } - exit: - close(sock); -} diff --git a/gnbd/server/local_req.h b/gnbd/server/local_req.h deleted file mode 100644 index df43e01..0000000 --- a/gnbd/server/local_req.h +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __local_req_h__ -#define __local_req_h__ - -/* FIXME -- should this be in a file by itself */ -#define LOCAL_CREATE_REQ 1 -#define LOCAL_REMOVE_REQ 2 -#define LOCAL_INVALIDATE_REQ 3 -#define LOCAL_FULL_LIST_REQ 4 -#define LOCAL_GSERV_LIST_REQ 5 -#define LOCAL_SHUTDOWN_REQ 6 -#define LOCAL_VALIDATE_REQ 7 - -#define LOCAL_SUCCESS_REPLY 0 -/* This is so that gnbd_export knows that it can kill gnbd_clusterd */ -#define LOCAL_RM_CLUSTER_REPLY 1024 -/* FIXME -- is this used */ -#define REPLY_ERR(x) (-((int)(x))) - -struct info_req_s { - uint64_t sectors; - uint32_t timeout; - uint8_t flags; - char name[32]; - char path[1024]; - char uid[64]; -}; -typedef struct info_req_s info_req_t; - -struct name_req_s { - char name[32]; -}; -typedef struct name_req_s name_req_t; - -struct gserv_req_s { - char node[65]; - uint32_t pid; - char name[32]; -}; -typedef struct gserv_req_s gserv_req_t; - -int accept_local_connection(int listening_sock); -int check_local_data_len(uint32_t req, int size); -void handle_local_request(int sock, uint32_t cmd, void *buf); - -#endif /* __local_req_h__ */ diff --git a/gnbd/tools/Makefile b/gnbd/tools/Makefile deleted file mode 100644 index b5be961..0000000 --- a/gnbd/tools/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - - -all: - cd fence_gnbd && ${MAKE} all - cd gnbd_export && ${MAKE} all - cd gnbd_import && ${MAKE} all - -copytobin: - cd fence_gnbd && ${MAKE} copytobin - cd gnbd_export && ${MAKE} copytobin - cd gnbd_import && ${MAKE} copytobin - -clean: - cd fence_gnbd && ${MAKE} clean - cd gnbd_export && ${MAKE} clean - cd gnbd_import && ${MAKE} clean diff --git a/gnbd/tools/fence_gnbd/Makefile b/gnbd/tools/fence_gnbd/Makefile deleted file mode 100644 index 9cd222e..0000000 --- a/gnbd/tools/fence_gnbd/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= fence_gnbd - -SOURCE= main.c - -top_srcdir=../.. - -INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/tools/gnbd_import \ - -I${top_srcdir}/config - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -DGNBD_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -fence_gnbd: ${SOURCE:.c=.o} - ${CC} ${CFLAGS} ${LDFLAGS} ${SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/gnbd/tools/fence_gnbd/main.c b/gnbd/tools/fence_gnbd/main.c deleted file mode 100644 index 53d4068..0000000 --- a/gnbd/tools/fence_gnbd/main.c +++ /dev/null @@ -1,340 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/wait.h> - -#include "fence_return.h" -#include "copyright.cf" - -/* name of the command that is needed to do the gnbd fencing */ -#define GNBD_FENCE_CMD "gnbd_import" -#define NODE_FENCE_CMD "fence_node" - -char *pname = "fence_gnbd"; - -char arg[256]; -char name[256]; -char ipaddr[256]; - -int quiet_flag = 0; -int multipath = 0; - -struct serv_list{ - char name[100]; - struct serv_list *next; -}; - -typedef struct serv_list serv_list_t; - -#define printe(fmt, args...) \ -{\ - if (!quiet_flag) \ - printf(fmt, ##args); \ -} - -#define fail(fmt, args...) \ -{\ - if (!quiet_flag) \ - printf("failed: " fmt, ##args); \ - exit(1); \ -} - -serv_list_t *servers = NULL; -int num_servers = 0; -unsigned int wait_time = 2; -unsigned int retrys = 3; - -void print_usage() -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [options]\n\n", pname); - printf("Options:\n"); - printf(" -h Usage\n"); - printf(" -m use multipath style fencing\n"); - printf(" -q Quiet output\n"); - printf(" -s <node> machine to fence\n"); - printf(" -t <node> server to fence machine from\n"); - printf(" -V Version information\n"); -} - -void parse_servers(char *str){ - char *end, *ptr; - serv_list_t *tmp; - - end = str + strlen(str); - while (str < end){ - if (isspace(*str)){ - str++; - continue; - } - if (*str == ''' || *str == '"'){ - char match = *str; - str++; - ptr = strchr(str, match); - if (ptr == NULL) - fail("no closing for quote character %c in %s\n", match, str); - *ptr = 0; - } - else{ - char *match = " \f\n\r\t\v"; - ptr = strpbrk(str, match); - if (ptr != NULL) - *ptr = 0; - else - ptr = end; - } - tmp = malloc(sizeof(serv_list_t)); - if (!tmp) - fail("couldn't allocate memory for server list\n"); - strcpy(tmp->name, str); - tmp->next = servers; - servers = tmp; - num_servers++; - str = ptr + 1; - } -} - - -void get_options(int argc, char **argv) -{ - int c; - char *value; - - if (argc > 1) - { - serv_list_t *tmp; - while ((c = getopt(argc, argv, "Vhmqs:t:")) != -1) - { - switch(c) - { - case 'V': - printf("%s %s (built %s %s)\n", pname, GNBD_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - break; - - case 'h': - print_usage(); - exit(0); - - case 'm': - multipath = 1; - break; - - case 'q': - quiet_flag = 1; - break; - - case 's': - strcpy(ipaddr, optarg); - break; - - case 't': - tmp = malloc(sizeof(serv_list_t)); - if (!tmp) - fail("couldn't allocate memory for server list.\n"); - strcpy(tmp->name, optarg); - tmp->next = servers; - servers = tmp; - num_servers++; - break; - - case ':': - case '?': - /* getopt prints an error msg to stderr, so we don't have to */ - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - - default: - fail("invalid flag '-%c'\n", c); - } - } - strcpy(name, pname); - } - - else - { - errno = 0; - while(fgets(arg, 256, stdin) != NULL){ - if( (value = strchr(arg, '\n')) == NULL) - fail("line too long: '%s'\n", arg); - *value = 0; - if( (value = strchr(arg, '=')) == NULL) - fail("invalid input: '%s'\n", arg); - *value = 0; - value++; - if (!strcmp(arg, "agent")){ - strcpy(name, value); - pname = name; - } - if (!strcmp(arg, "option")){ - if (!strcmp(value, "multipath")) - multipath = 1; - else - printe("warning: option %s not recognized\n", value); - } - if (!strcmp(arg, "ipaddr") || !strcmp(arg, "nodename")){ - if (!strcmp(arg, "ipaddr")) - printe("warning: 'ipaddr' key is depricated, please see man page\n"); - strcpy(ipaddr, value); - } - if (!strcmp(arg, "wait_time")){ - int match = sscanf(value, "%u", &wait_time); - if (match != 1 || !wait_time) - fail("'%s' is not a valid value for wait_time\n", value); - } - if (!strcmp(arg, "retrys")){ - int match = sscanf(value, "%u", &retrys); - if (match != 1) - fail("'%s' is not a valid value for retrys\n", value); - } - if (!strcmp(arg, "server") || !strcmp(arg, "servers")) - parse_servers(value); - errno = 0; - } - if (errno != 0) - fail("couldn't read line: %s\n", strerror(errno)); - } -} - - -static void clear_serv(void){ - serv_list_t *prev = NULL; - while(servers){ - prev = servers; - servers = servers->next; - free(prev); - } -} - -int do_fence(char *serv_name, int fence_server){ - - int error, val; - char line[256]; - int fds[2]; - int pid; - - if (pipe(fds)) - fail("pipe error\n"); - - pid = fork(); - if (pid < 0) - fail("can't fork fencing method\n"); - - if (!pid){ - close(1); - dup(fds[1]); - close(fds[0]); - close(fds[1]); - close(2); - dup(1); - if (fence_server) - error = execlp(NODE_FENCE_CMD, NODE_FENCE_CMD, serv_name, NULL); - else - error = execlp(GNBD_FENCE_CMD, GNBD_FENCE_CMD, "-s", ipaddr, - "-t", serv_name, NULL); - printe("could not exec %s\n", (fence_server)? NODE_FENCE_CMD : GNBD_FENCE_CMD); - exit(1); - } - else{ - close(0); - dup(fds[0]); - close(fds[0]); - close(fds[1]); - - val = fcntl(0, F_GETFL, 0); - if (val >= 0){ - val |= O_NONBLOCK; - fcntl(0, F_SETFL, val); - } - waitpid(pid, &error, 0); - if (WIFEXITED(error)){ - int count; - error = WEXITSTATUS(error); - while( (count = read(0, line, 255)) > 0){ - line[count] = 0; - printf("%s", line); - } - return error; - } - else - fail("%s exitted abnormally\n", (fence_server)? NODE_FENCE_CMD : GNBD_FENCE_CMD); - } -} - -void run_fence(char *serv_name){ - int trys; - int err; - if (multipath){ - for (trys = 0; trys <= retrys; trys++){ - err = do_fence(serv_name, 0); - if (!err) - return; - if (err != SERVER_ERR) - fail("%s, %s\n", pname, ipaddr); - printe("try %d for server %s failed\n", trys + 1, serv_name); - sleep(wait_time); - } - printe("fencing unresponsive server\n"); - err = do_fence(serv_name, 1); - if (err) - fail("could not fence unresponsive server %s\n", serv_name); - return; - } - else{ - if (do_fence(serv_name, 0)) - fail("%s, %s\n", pname, ipaddr); - } -} - - -int main(int argc, char **argv) -{ - serv_list_t *tmp; - if (atexit(clear_serv) != 0) - fail("can't register exit function\n"); - - memset(arg, 0, 256); - memset(name, 0, 256); - memset(ipaddr, 0, 256); - - get_options(argc, argv); - - if (ipaddr[0] == '\0') - fail("no IP addr\n"); - - if (!servers) - fail("missing server list\n"); - - tmp = servers; - while (tmp){ - run_fence(tmp->name); - tmp = tmp->next; - } - - if(!quiet_flag) - printf("success: %s, %s\n", pname, ipaddr); - - return 0; -} diff --git a/gnbd/tools/gnbd_export/Makefile b/gnbd/tools/gnbd_export/Makefile deleted file mode 100644 index fbc88a6..0000000 --- a/gnbd/tools/gnbd_export/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= gnbd_export - -top_srcdir=../.. - -SOURCE= gnbd_export.c $(top_srcdir)/utils/gnbd_utils.c \ - $(top_srcdir)/utils/trans.c - -INCLUDE= -I$(top_srcdir)/include -I$(top_srcdir)/server \ - -I$(top_srcdir)/utils -I${top_srcdir}/config \ - -I${incdir} - -LDLIBS+= -L${libdir} -lmagma -ldl -lpthread - -include ${top_srcdir}/make/defines.mk - -CFLAGS+= -O2 -DGNBD_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -gnbd_export: ${SOURCE} - ${CC} ${CFLAGS} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all gnbd_get_uid - cp ${TARGET} ${top_srcdir}/bin - cp gnbd_get_uid ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/gnbd/tools/gnbd_export/gnbd_export.c b/gnbd/tools/gnbd_export/gnbd_export.c deleted file mode 100644 index 525d779..0000000 --- a/gnbd/tools/gnbd_export/gnbd_export.c +++ /dev/null @@ -1,864 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> -#include <sys/wait.h> -#include <arpa/inet.h> -#include <dirent.h> -#include <ctype.h> -#define _GNU_SOURCE -#include <getopt.h> - -#include "global.h" -#include "gnbd_endian.h" -#include "gnbd_utils.h" -#include "local_req.h" -#include "device.h" -#include "trans.h" - -#include "copyright.cf" - -#define TIMEOUT_DEFAULT 60 - -#define MAN_MSG "Please see man page for details.\n" -#define DEFAULT_GETUID "/sbin/gnbd_get_uid %n" - -int start_gnbd_clusterd(void) -{ - int ret; - - if( (ret = system("gnbd_clusterd")) < 0){ - printe("system() failed. canot start gnbd_clusterd : %s\n", - strerror(errno)); - return -1; - } - if (ret != 0){ - printe("gnbd_clusterd failed\n"); - return -1; - } - return 0; -} - -void stop_gnbd_clusterd(void) -{ - int ret; - - if( (ret = system("gnbd_clusterd -k")) < 0){ - printe("system() failed. cannot stop gnbd_clusterd : %s\n", - strerror(errno)); - return; - } - if (ret != 0){ - printe("stopping gnbd_clusterd failed\n"); - return; - } -} - -int servcreate(char *name, char *device, uint32_t timeout, uint8_t readonly, - char *uid){ - info_req_t create_req; - int fd; - - if (timeout && start_gnbd_clusterd()) - return 1; - - strncpy(create_req.name, name, 32); - create_req.name[31] = 0; - if (strchr(create_req.name, '/')){ - printe("server name %s is invalid. Names cannot contain a '/'\n", - create_req.name); - return 1; - } - strncpy(create_req.path, device, 1024); - create_req.path[1023] = 0; - if (uid){ - strncpy(create_req.uid, uid, 64); - create_req.uid[63] = 0; - } - else - create_req.uid[0] = 0; - create_req.timeout = timeout; - create_req.flags = (((readonly)? GNBD_FLAGS_READONLY : 0) | - ((timeout)? GNBD_FLAGS_UNCACHED : 0)); - fd = connect_to_comm_device("gnbd_serv"); - if (fd < 0) - return 1; - if (send_cmd(fd, LOCAL_CREATE_REQ, "create") < 0) - return 1; - if (write(fd, &create_req, sizeof(create_req)) != sizeof(create_req)){ - printe("sending create data failed : %s\n", strerror(errno)); - return 1; - } - if (recv_reply(fd, "create") < 0) - return 1; - printm("created GNBD %s serving file %s\n", name, device); - close(fd); - return 0; -} - -void invalidate_serv(char *name) -{ - name_req_t invalidate_req; - int fd; - - strncpy(invalidate_req.name, name, 32); - invalidate_req.name[31] = 0; - fd = connect_to_comm_device("gnbd_serv"); - if (fd < 0) - exit(1); - if (send_cmd(fd, LOCAL_INVALIDATE_REQ, "invalidate") < 0) - exit(1); - if (retry_write(fd, &invalidate_req, sizeof(invalidate_req)) < 0){ - printe("sending invalidate request data failed : %s\n", gstrerror(errno)); - exit(1); - } - if (recv_reply(fd, "invalidate") < 0) - exit(1); - close(fd); -} - -void servremove(char *name) -{ - name_req_t remove_req; - uint32_t reply; - int fd; - - strncpy(remove_req.name, name, 32); - remove_req.name[31] = 0; - fd = connect_to_comm_device("gnbd_serv"); - if (fd < 0) - exit(1); - if (send_cmd(fd, LOCAL_REMOVE_REQ, "remove") < 0) - exit(1); - if (retry_write(fd, &remove_req, sizeof(remove_req)) < 0){ - printe("sending remove req failed: %s\n", gstrerror(errno)); - exit(1); - } - if (retry_read(fd, &reply, sizeof(reply)) < 0){ - printe("reading remove reply failed : %s\n", gstrerror(errno)); - exit(1); - } - if (reply && reply != LOCAL_RM_CLUSTER_REPLY){ - printe("remove request failed : %s\n", strerror(reply)); - exit(1); - } - if (reply == LOCAL_RM_CLUSTER_REPLY) - stop_gnbd_clusterd(); - printm("removed GNBD %s\n", name); - close(fd); -} - -int validate(void) -{ - int fd; - - fd = connect_to_comm_device("gnbd_serv"); - if (fd < 0) - return 1; - if (send_cmd(fd, LOCAL_VALIDATE_REQ, "validate") < 0) - return 1; - if (recv_reply(fd, "validate") < 0) - return 1; - printm("removed invalid server processes\n"); - return 0; -} - - -int get_list_info(void **buffer, int *buffer_size, int cmd){ - void *buf; - uint32_t size; - int n, total; - int fd; - - *buffer = NULL; - *buffer_size = 0; - - fd = connect_to_comm_device("gnbd_serv"); - if (fd < 0) - return -1; - if (send_cmd(fd, cmd, "list") < 0) - return -1; - if (recv_reply(fd, "list") < 0) - return -1; - if (read(fd, &size, sizeof(size)) != sizeof(size)){ - printe("receiving list size failed : %s\n", strerror(errno)); - return -1; - } - if (size == 0){ - *buffer_size = size; - close(fd); - return 0; - } - buf = malloc(size); - if (!buf){ - printe("couldn't allocate memory for list : %s\n", strerror(errno)); - return -1; - } - total = 0; - while(total < size){ - n = read(fd, buf + total, size - total); - if (n <= 0){ - printe("receiving list failed : %s\n", strerror(errno)); - free(buf); - return -1; - } - total += n; - } - - *buffer = buf; - *buffer_size = size; - close(fd); - return 0; -} - - -int removeall(int force){ - int size; - void *buf; - info_req_t *info; - - if (get_list_info(&buf, &size, LOCAL_FULL_LIST_REQ) < 0) - return 1; - if (size == 0) - return 0; - info = (info_req_t *)buf; - while ((void *)info < buf + size){ - if (force) - invalidate_serv(info->name); - servremove(info->name); - info++; - } - free(buf); - return 0; -} - -int gserv_list(void){ - int size; - void *buf; - gserv_req_t *info; - - if (get_list_info(&buf, &size, LOCAL_GSERV_LIST_REQ) < 0) - return 1; - if (verbosity == QUIET){ - if (size) - free(buf); - return 0; - } - if (size == 0){ - printf("no server processes\n"); - return 0; - } - info = (gserv_req_t *)buf; - printf(" pid client device\n"); - printf("--------------------------------\n"); - while((void *)info < buf + size){ - printf("%5d %15s %s\n", info->pid, info->node, - info->name); - info++; - } - free(buf); - return 0; -} - -int list(void){ - int size; - void *buf; - info_req_t *info; - int i = 0; - - if (get_list_info(&buf, &size, LOCAL_FULL_LIST_REQ) < 0) - return 1; - if (verbosity == QUIET){ - if (size) - free(buf); - return 0; - } - if (size == 0){ - printf("no exported GNBDs\n"); - return 0; - } - info = (info_req_t *)buf; - while ((void *)info < buf + size){ - i++; - printf("Server[%d] : %s %s\n" - "--------------------------\n" - " file : %s\n" - " sectors : %Lu\n" - " readonly : %s\n" - " cached : %s\n", - i, info->name, (info->flags & GNBD_FLAGS_INVALID)? "(invalid)" : "", - info->path, (long long unsigned int)info->sectors, - (info->flags & GNBD_FLAGS_READONLY)? "yes" : "no", - (info->flags & GNBD_FLAGS_UNCACHED)? "no" : "yes"); - if (info->timeout) - printf(" timeout : %u\n", info->timeout); - else - printf(" timeout : no\n"); - if (info->uid[0] != '\0') - printf(" uid : %s\n", info->uid); - printf("\n"); - info++; - } - free(buf); - return 0; -} - - -void get_dev(char *path, int *major, int *minor) -{ - struct stat stat_buf; - *major = -1; - *minor = -1; - - if (stat(path, &stat_buf) < 0){ - printe("cannot stat %s : %s\n", path, strerror(errno)); - exit(1); - } - if (!S_ISBLK(stat_buf.st_mode)){ - printe("path '%s' is not a block device. cannot get uid information\n", - path); - exit(1); - } - *major = major(stat_buf.st_rdev); - *minor = minor(stat_buf.st_rdev); -} - -char *get_sysfs_info(char *path) { - int fd; - int bytes; - int count = 0; - - if ((fd = open(path, O_RDONLY)) < 0) { - printe("cannot open %s : %s\n", path, strerror(errno)); - exit(1); - } - while (count < 4096) { - bytes = read(fd, &sysfs_buf[count], 4096 - count); - if (bytes < 0 && errno != EINTR) { - printe("cannot read from %s : %s\n", path, strerror(errno)); - exit(1); - } - if (bytes == 0) - break; - count += bytes; - } - if (sysfs_buf[count - 1] == '\n' || count == 4096) - sysfs_buf[count - 1] = '\0'; - else - sysfs_buf[count] = '\0'; - close(fd); - return sysfs_buf; -} - -#define SYSFS_PATH_MAX 64 -#define SYSFS_PATH_BASE "/sys/block" -#define SYSFS_PATH_BASE_SIZE 10 -int get_sysfs_majmin(char *dev, int *major, int *minor) -{ - char path[SYSFS_PATH_MAX]; - char *buf; - - if (snprintf(path, SYSFS_PATH_MAX, "%s/%s/dev", SYSFS_PATH_BASE, dev) >= - SYSFS_PATH_MAX) { - printe("sysfs path name '%s/%s/dev' too long\n", SYSFS_PATH_BASE, dev); - exit(1); - } - buf = get_sysfs_info(path); - if (sscanf(buf, "%u:%u", major, minor) != 2){ - printe("cannot parse %s entry '%s'\n", path, buf); - exit(1); - } - return 0; -} - -int get_sysfs_range(char *dev, int *range) -{ - char path[SYSFS_PATH_MAX]; - char *buf; - - if (snprintf(path, SYSFS_PATH_MAX, "%s/%s/range", SYSFS_PATH_BASE, dev) >= - SYSFS_PATH_MAX) { - printe("sysfs path name '%s/%s/range' too long\n", SYSFS_PATH_BASE, dev); - exit(1); - } - buf = get_sysfs_info(path); - if (sscanf(buf, "%u", range) != 1){ - printe("cannot parse %s etnry '%s'\n", path, buf); - exit(1); - } - return 0; -} - -char *get_sysfs_name(int major, int minor){ - char *name = NULL; - DIR *dir; - struct dirent *dp; - - dir = opendir(SYSFS_PATH_BASE); - if (!dir) { - printe("cannot open %s to find the device name for %d:%d : %s\n", - SYSFS_PATH_BASE, major, minor, strerror(errno)); - exit(1); - } - while ((dp = readdir(dir))) { - int dev_major, dev_minor, dev_range; - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - get_sysfs_majmin(dp->d_name, &dev_major, &dev_minor); - get_sysfs_range(dp->d_name, &dev_range); - if (major == dev_major && minor >= dev_minor && - minor < dev_minor + dev_range){ - if (minor == dev_minor) - name = strdup(dp->d_name); - else { - name = malloc(SYSFS_PATH_MAX); - if (!name){ - printe("cannot allocate memory for sysfs name : %s\n", - strerror(errno)); - exit(1); - } - sprintf(name, "%s/%s%d", dp->d_name, dp->d_name, minor - dev_minor); - } - break; - } - } - if (closedir(dir) < 0){ - printe("cannot close dir %s : %s\n", SYSFS_PATH_BASE, strerror(errno)); - exit(1); - } - if (!name) { - printe("cannot find sysfs block device %d:%d\n", major, minor); - exit(1); - } - return name; -} - -size_t read_all(int fd, void *buf, size_t len) -{ - size_t total = 0; - - while (len) { - ssize_t n = read(fd, buf, len); - if (n < 0) { - if ((errno == EINTR) || (errno == EAGAIN)) - continue; - if (!total) - return -1; - return total; - } - if (!n) - return total; - buf = n + (char *)buf; - len -= n; - total += n; - } - return total; -} - - -char *execute_uid_program(char *command){ - char *uid; - char **argv = NULL; - char *ptr = command; - int fds[2], size = 0; - char *save = strdup(command); - pid_t pid; - int val, status, count; - - uid = malloc(sizeof(char) * 64); - if (!uid){ - printe("cannot allocate memory for uid\n"); - exit(1); - } - while (*ptr){ - char *delim = "\t\n\r\t\v "; - int quote = 0; - while(isspace(*ptr)) - ptr++; - if (!*ptr) - break; - if (*ptr == '''){ - quote = 1; - ptr++; - delim = "'"; - } - argv = realloc(argv, (size + 2) * sizeof(char **)); - argv[size++] = ptr; - ptr = strpbrk(ptr, delim); - if (!ptr){ - if (quote){ - printe("invalid get_uid command (%s) non terminated quote\n", save); - exit(1); - } - break; - } - *ptr++ = 0; - } - if (!size){ - printe("invalid get_uid command (%s) empty command\n", save); - exit(1); - } - argv[size] = NULL; - - if (pipe(fds) < 0){ - printe("couldn't open a pipe for get_uid command : %s\n", strerror(errno)); - exit(1); - } - pid = fork(); - if (pid < 0){ - printe("couldn't fork get_uid command : %s\n", strerror(errno)); - exit(1); - } - if (!pid){ - close(STDOUT_FILENO); - dup(fds[1]); - execv(argv[0], argv); - printe("couldn't exec '%s' : %s\n", argv[0], strerror(errno)); - exit(1); - } - close(fds[1]); - - val = fcntl(0, F_GETFL, 0); - if (val >= 0){ - val |= O_NONBLOCK; - fcntl(0, F_SETFL, val); - } - - waitpid(pid, &status, 0); - if ((count = read_all(fds[0], uid, 63)) < 0){ - printe("couldn't read from get_uid command : %s\n", strerror(errno)); - exit(1); - } - if (count && uid[count-1] == '\n') - count--; - uid[count] = 0; - close(fds[0]); - - if (!WIFEXITED(status)){ - printe("get_uid command '%s' exitted abnormally (%s)\n", argv[0], uid); - exit(1); - } - status = WEXITSTATUS(status); - if (status != 0){ - printe("get_uid command '%s' failed: %d (%s)\n", argv[0], status, uid); - exit(1); - } - return uid; -} - -#define SPACE_LEFT (&command[LINE_MAX - 1] - dest) -char *get_uid(char *format, char *path) -{ - char temp[24]; - char command[LINE_MAX]; - int escape, major, minor; - char *name, *src, *dest; - - src = format; - dest = command; - escape = 0; - major = -1; - minor = -1; - name = NULL; - - while(*src){ - if (!SPACE_LEFT){ - *dest = 0; - printe("get_uid command string '%s' too long\n", command); - exit(1); - } - if (escape){ - int len; - switch(*src){ - case 'M': - if (major == -1) - get_dev(path, &major, &minor); - sprintf(temp, "%d", major); - len = strlen(temp); - if (len > SPACE_LEFT){ - printe("get_uid command string '%s' too long\n", command); - exit(1); - } - strncpy(dest, temp, len); - dest += len; - break; - case 'm': - if (minor == -1) - get_dev(path, &major, &minor); - sprintf(temp, "%d", minor); - len = strlen(temp); - if (len > SPACE_LEFT){ - *dest = 0; - printe("get_uid command string '%s' too long\n", command); - exit(1); - } - strncpy(dest, temp, len); - dest += len; - break; - case 'n': - if (!name){ - if (major == -1) - get_dev(path, &major, &minor); - name = get_sysfs_name(major, minor); - } - len = strlen(name); - if (len > SPACE_LEFT){ - *dest = 0; - printe("get_uid command string '%s' too long\n", command); - exit(1); - } - strncpy(dest, name, len); - dest += len; - break; - default: - if (SPACE_LEFT < 2){ - *dest = 0; - printe("get_uid command string '%s' too long\n", command); - exit(1); - } - *dest++ = '%'; - *dest++ = *src; - } - escape = 0; - } - else if (*src == '%') - escape = 1; - else{ - *dest = *src; - dest++; - } - src++; - } - *dest = 0; - return execute_uid_program(command); -} - -int usage(void){ - printf( -"Usage:\n" -"\n" -"gnbd_export [options]\n" -"\n" -"Options:\n" -" -a validate the servers, and remove the bad ones\n" -" -c enable caching (used with -e)\n" -" -d <device> the device to create a GNBD on\n" -" -e <GNBD> export the specified GNBD\n" -" -h print this help message\n" -" -l list the exported GNBDS (default)\n" -" -L list the server processes\n" -" -O Force unexport. (used with -r and -R)\n" -" -o export device readonly (used with -e)\n" -" -q quiet mode\n" -" -R unexport all GNBDs\n" -" -r [GNBD | list] unexport the specified GNBD(s)\n" -" -t <seconds> set the timeout duration\n" -" -u <uid> manually set the Unique ID of a device (used with -e)\n" -" -U[command] command to get the Unique ID of a device (used with -e)\n" -" If no command is specificed, the default is\n" -" "/sbin/gnbd_get_uid %%n"\n" -" -v verbose output (useful with -l)\n" -" -V version information\n"); - return 0; -} - - -#define ACTION_EXPORT 1 -#define ACTION_REMOVE 2 -#define ACTION_LIST 3 -#define ACTION_REMOVE_ALL 4 -#define ACTION_GSERV_LIST 5 -#define ACTION_VALIDATE 6 - -char action_to_flag(int action){ - switch(action){ - case ACTION_EXPORT: - return 'e'; - case ACTION_REMOVE: - return 'r'; - case ACTION_LIST: - return 'l'; - case ACTION_REMOVE_ALL: - return 'R'; - case ACTION_GSERV_LIST: - return 'L'; - case ACTION_VALIDATE: - return 'a'; - default: - printe("invalid action value\n"); - return 0; - } -} - -#define set_action(x) \ -do{ \ - if (action){ \ - printe("flags -%c and -%c are not compatible\n", action_to_flag(action), \ - action_to_flag(x)); \ - fprintf(stderr, "Please see man page for details.\n"); \ - return 1; \ - } \ - action = (x); \ -} while(0) - -int main(int argc, char **argv){ - int c, i; - int action = 0; - int cached = 0; - unsigned int timeout = 0; - int force = 0; - int readonly = 0; - char *device = NULL; - char *gnbd_name = NULL; - char *uid = NULL; - char *uid_program = NULL; - - program_name = "gnbd_export"; - while ((c = getopt(argc, argv, "acd:e:hlLOoqrRt:u:U::vV")) != -1){ - switch(c){ - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - return 1; - case 'a': - set_action(ACTION_VALIDATE); - continue; - case 'c': - cached = 1; - continue; - case 'd': - device = optarg; - continue; - case 'e': - set_action(ACTION_EXPORT); - gnbd_name = optarg; - continue; - case 'h': - return usage(); - case 'l': - set_action(ACTION_LIST); - continue; - case 'L': - set_action(ACTION_GSERV_LIST); - continue; - case 'O': - force = 1; - continue; - case 'o': - readonly = 1; - continue; - case 'q': - verbosity = QUIET; - continue; - case 'r': - set_action(ACTION_REMOVE); - continue; - case 'R': - set_action(ACTION_REMOVE_ALL); - continue; - case 't': - if (sscanf(optarg, "%u", &timeout) != 1 || timeout == 0){ - printe("invalid timeout '%s' with -t\n" MAN_MSG, optarg); - return 1; - } - continue; - case 'u': - uid = optarg; - continue; - case 'U': - uid_program = optarg; - if (!uid_program) - uid_program = DEFAULT_GETUID; - continue; - case 'v': - verbosity = VERBOSE; - continue; - case 'V': - printf("%s %s (built %s %s)\n", argv[0], - GNBD_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - return 0; - default: - printe("invalid option -- %c\nPlease use '-h' for usage.\n", c); - return 1; - } - } - if (timeout && cached){ - printe("the -t option may not be used with the -c option\n" MAN_MSG); - return 1; - } - if ((cached || timeout || device || readonly || uid || uid_program) && - action != ACTION_EXPORT){ - printe("the -c, -t, -d , -u and -U flags may only be used with -e\n" - MAN_MSG); - return 1; - } - if (force && action != ACTION_REMOVE && action != ACTION_REMOVE_ALL){ - printe("the -O option mhy only be used with -r or -R.\n" MAN_MSG); - return 1; - } - if (action != ACTION_REMOVE && optind != argc){ - printe("extra operand for action: %s\n", argv[optind]); - fprintf(stderr, "please use '-h' for usage.\n"); - return 1; - } - switch(action){ - case ACTION_EXPORT: - if (!device){ - printe("The -d option must be specified with -e.\n" MAN_MSG); - return 1; - } - if (cached == 0 && timeout == 0) - timeout = TIMEOUT_DEFAULT; - if (uid && uid_program){ - printe("the -u and -U options cannot be used together.\n" MAN_MSG); - return 1; - } - if (uid_program) - uid = get_uid(uid_program, device); - return servcreate(gnbd_name, device, (uint32_t)timeout, (uint8_t)readonly, - uid); - case ACTION_REMOVE: - if (optind == argc){ - printe("missing operand for remove action\n"); - fprintf(stderr, "please use '-h' for usage.\n"); - return 1; - } - for (i = optind; i < argc; i++){ - if (force) - invalidate_serv(argv[i]); - servremove(argv[i]); - } - return 0; - case ACTION_LIST: case 0: - return list(); - case ACTION_REMOVE_ALL: - return removeall(force); - case ACTION_GSERV_LIST: - return gserv_list(); - case ACTION_VALIDATE: - return validate(); - default: - printe("unrecognized action value\n"); - return 1; - } -} diff --git a/gnbd/tools/gnbd_export/gnbd_get_uid b/gnbd/tools/gnbd_export/gnbd_get_uid deleted file mode 100644 index 143f2a2..0000000 --- a/gnbd/tools/gnbd_export/gnbd_get_uid +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -set -e - -base_uid=`/sbin/scsi_id -g -u -s /block/$1 2> /dev/null` -if echo $1 | grep -q '^.*/[^0-9]*[0-9]*$' > /dev/null 2>&1 ; then - part=`echo $1 | sed 's/^.*/[^0-9]*([0-9]*)$/\1/'` - echo GNBD-${part}-${base_uid} -else - echo GNBD--${base_uid} -fi diff --git a/gnbd/tools/gnbd_import/Makefile b/gnbd/tools/gnbd_import/Makefile deleted file mode 100644 index 919dd5c..0000000 --- a/gnbd/tools/gnbd_import/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= gnbd_import - -top_srcdir=../.. -include ${top_srcdir}/make/defines.mk - -SOURCE= gnbd_import.c $(top_srcdir)/utils/gnbd_utils.c \ - $(top_srcdir)/client/monitor_req.c $(top_srcdir)/utils/trans.c - -INCLUDE= -I$(top_srcdir)/include -I$(top_srcdir)/client \ - -I$(top_srcdir)/server -I$(top_srcdir)/utils \ - -I${top_srcdir}/config - -LDLIBS+= -L${libdir} -lmagma -ldl -lpthread - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gnbd.h ]; then \ - echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) -else -INCLUDE += -I${incdir} -endif - -CFLAGS+= -O2 -DGNBD_RELEASE_NAME="${RELEASE}" - -all: ${TARGET} - -gnbd_import: ${SOURCE} - ${CC} ${CFLAGS} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ - -copytobin: all - cp ${TARGET} ${top_srcdir}/bin - -clean: - rm -f *.o ${TARGET} diff --git a/gnbd/tools/gnbd_import/fence_return.h b/gnbd/tools/gnbd_import/fence_return.h deleted file mode 100644 index b3a3d63..0000000 --- a/gnbd/tools/gnbd_import/fence_return.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __fence_return_h__ -#define __fence_return_h__ - -#define SERVER_ERR 2 - -#endif /* __fence_return_h__ */ diff --git a/gnbd/tools/gnbd_import/gnbd_import.c b/gnbd/tools/gnbd_import/gnbd_import.c deleted file mode 100644 index 8b99146..0000000 --- a/gnbd/tools/gnbd_import/gnbd_import.c +++ /dev/null @@ -1,1346 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdlib.h> -#include <getopt.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <dirent.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <sys/utsname.h> -#include <linux/gnbd.h> -#include <inttypes.h> - -#include "fence_return.h" -#include "gnbd_endian.h" -#include "gnbd_utils.h" -#include "list.h" -#include "extern_req.h" -#include "gnbd_monitor.h" -#include "trans.h" - -#include "copyright.cf" - -#define MAN_MSG "Please see man page for details.\n" - -struct gnbd_info_s{ - char name[32]; - int minor_nr; - char server_name[256]; - uint16_t port; - int usage; - int connected; - long waittime; - unsigned short flags; - int pid; - uint64_t sectors; - list_t list; -}; -typedef struct gnbd_info_s gnbd_info_t; - -#define IS_UNUSED(x) ((x)->pid < 0 && (x)->sectors == 0 && (x)->usage == 0) -#define IS_READONLY(x) ((x)->flags && GNBD_READ_ONLY) - -int gnbd_major = -1; -list_t gnbd_list; -/* FIXME -- why unsigned int */ -unsigned int server_port = 14567; -int maxminor = -1; -char *sysfs_class = "/sys/class/gnbd"; -int override = 0; -char node_name[65]; -int is_clustered = 1; - -#define MODE_MASK (S_IRWXU | S_IRWXG | S_IRWXO) - -#define ACTION_FENCE 1 -#define ACTION_REMOVE 2 -#define ACTION_IMPORT 3 -#define ACTION_LIST 4 -#define ACTION_VALIDATE 5 -#define ACTION_LIST_EXPORTED 6 -#define ACTION_REMOVE_ALL 7 -#define ACTION_UNFENCE 8 -#define ACTION_LIST_BANNED 9 -#define ACTION_FAIL_SERVER 10 -#define ACTION_GET_UID 11 - -gnbd_info_t *match_info_name(char *name){ - list_t *item; - gnbd_info_t *gnbd_entry; - - list_foreach(item, &gnbd_list){ - gnbd_entry = list_entry(item, gnbd_info_t, list); - if (strncmp(gnbd_entry->name, name, 32) == 0) - return gnbd_entry; - } - return NULL; -} - - - -int talk_to_server(char *host, uint32_t request, char **buf, void *request_data, - ssize_t request_data_size) -{ - int sock_fd; - int n, total = 0; - uint32_t msg; - - *buf = NULL; - sock_fd = connect_to_server(host, (uint16_t)server_port); - if (sock_fd < 0){ - printe("cannot connect to server %s (%d) : %s\n", host, sock_fd, - strerror(errno)); - exit(1); - } - msg = cpu_to_be32(request); - if (write(sock_fd, &msg, sizeof(msg)) != sizeof(msg)){ - printe("error sending request to %s : %s\n", host, strerror(errno)); - exit(1); - } - if (request_data){ - if (write(sock_fd, request_data, request_data_size) != request_data_size){ - printe("error sending request data to %s : %s\n", host, strerror(errno)); - exit(1); - } - } - if (read(sock_fd, &msg, sizeof(msg)) != sizeof(msg)){ - printe("error reading reply from %s : %s\n", host, strerror(errno)); - exit(1); - } - msg = cpu_to_be32(msg); - if (msg != EXTERN_SUCCESS_REPLY){ - printe("request to %s failed : %s\n", host, strerror(REPLY_ERR(msg))); - exit(1); - } - if (read(sock_fd, &msg, sizeof(msg)) != sizeof(msg)){ - printe("error reading size of reply from %s : %s\n", host, - strerror(errno)); - exit(1); - } - msg = be32_to_cpu(msg); - if (!msg) - goto exit; - *buf = malloc(msg); - if (*buf == NULL){ - printe("couldn't allocate memory for server reply : %s\n", strerror(errno)); - exit(1); - } - memset(*buf, 0, msg); - while(total < msg){ - n = read(sock_fd, *buf + total, msg - total); - if (n <= 0){ - printe("error reading reply data from server %s : %s\n", host, - strerror(errno)); - exit(1); - } - total += n; - } -exit: - close(sock_fd); - return total; -} - -#define read_from_server(host, request, buf) \ - talk_to_server(host, request, buf, NULL, 0) - -int start_gnbd_monitor(int minor_nr, int timeout, char *host) -{ - int ret; - char *serv_node; - char cmd[256]; - - /* no timeout, no monitor */ - if (!timeout) - return 0; - - read_from_server(host, EXTERN_NODENAME_REQ, &serv_node); - if (!serv_node) { - printe("got empty server name\n"); - return -1; - } - - snprintf(cmd, 256, "gnbd_monitor %d %d %s", minor_nr, timeout, serv_node); - ret = system(cmd); - free(serv_node); - if( ret < 0){ - printe("system() failed : %s\n", strerror(errno)); - return -1; - } - if (ret != 0){ - printe("gnbd_monitor failed\n"); - return -1; - } - return 0; -} - -int match_info_minor(int minor_nr){ - list_t *item; - gnbd_info_t *gnbd_entry; - - list_foreach(item, &gnbd_list){ - gnbd_entry = list_entry(item, gnbd_info_t, list); - if (gnbd_entry->minor_nr == minor_nr) - return 1; - } - return 0; -} - -void info_add(gnbd_info_t *info) -{ - list_t *item; - gnbd_info_t *gnbd_entry; - - list_foreach(item, &gnbd_list){ - gnbd_entry = list_entry(item, gnbd_info_t, list); - if (gnbd_entry->minor_nr > info->minor_nr) - break; - } - list_add_prev(&info->list, item); -} - -char action_to_flag(int action){ - switch(action){ - case ACTION_FENCE: - return 's'; - case ACTION_REMOVE: - return 'r'; - case ACTION_IMPORT: - return 'i'; - case ACTION_LIST: - return 'l'; - case ACTION_VALIDATE: - return 'a'; - case ACTION_LIST_EXPORTED: - return 'e'; - case ACTION_REMOVE_ALL: - return 'R'; - case ACTION_UNFENCE: - return 'u'; - case ACTION_LIST_BANNED: - return 'c'; - case ACTION_FAIL_SERVER: - return 'k'; - default: - printe("invalid action value\n"); - return 0; - } -} - -#define set_action(x) \ -do{ \ - if (action){ \ - printe("flags -%c and -%c are not compatible\n", action_to_flag(action), \ - action_to_flag(x)); \ - fprintf(stderr, "Please see man page for details.\n"); \ - return 1; \ - } \ - action = (x); \ -} while(0) - - -int usage(void){ - printf( -"Usage:\n" -"\n" -"gnbd_import [options]\n" -"\n" -"Options:\n" -" -a validate all imported GNBDs, and remove the invalid ones\n" -" -c <server> list all nodes currently IO fenced from the server\n" -" -e <server> list all GNBDs exported by the server\n" -" -h print this help message\n" -" -i <server> import all GNBDs from the server\n" -" -l list all imported GNBDs [default action]\n" -" -n No cluster. Do not contact the cluster manager\n" -" -O Override prompts\n" -" -p <port> change the port to check on the GNBD server [default 14567]\n" -" -q quiet mode.\n" -" -R remove all imported GNBDs\n" -" -r [GNBD | list] remove specified GNBD(s)\n" -" -s <host> IO fence the host (from known servers by default)\n" -" -t <server> specify a server for the IO fence (with -s or -u)\n" -" -u <host> unfence the host (from known servers by default)\n" -" -U <GNBD> get the Universal Identifier for the specified GNBD\n" -" -V version information\n" -" -v verbose output\n" -"\n"); - return 0; -} - -int get_major_nr(void){ - char device[LINE_MAX]; - char buf[LINE_MAX]; - int major_nr; - FILE *fp; - fp = fopen("/proc/devices", "r"); - if (!fp){ - printe("could not open /proc/devices: %s\n", strerror(errno)); - exit(1); - } - while(fgets(buf, LINE_MAX, fp) != NULL) - if (sscanf(buf, "%d %s", &major_nr, device) == 2 && - strcmp(device, "gnbd") == 0) - break; - if(strcmp(device, "gnbd") == 0) - return major_nr; - printe("could not find gnbd registered in /proc/devices. This\n" - "probably means that you have not loaded the gnbd module.\n"); - exit(1); -} - -/* On success 0 is returned, on failure, -1 is returned and the - device is removed if it existed */ -int get_dev(char *path, mode_t *mode, int *major_nr, int *minor_nr){ - struct stat stats; - - if (stat(path, &stats) < 0){ - if (errno != ENOENT){ - printe("cannot stat %s : %s\n", path, strerror(errno)); - exit(1); - } - return -1; - } - if ((stats.st_mode & S_IFMT) != (*mode & S_IFMT)){ - printv("incorrect type for %s. removing\n", path); - goto out_remove; - } - if ((*mode & MODE_MASK) && ((stats.st_mode & MODE_MASK) != - (*mode & MODE_MASK))){ - printv("incorrect mode for %s. removing\n", path); - goto out_remove; - } - if ((*major_nr >= 0 && major(stats.st_rdev) != *major_nr) || - (*minor_nr >= 0 && minor(stats.st_rdev) != *minor_nr)){ - printv("incorrect major/minor number for %s. removing\n", path); - goto out_remove; - } - *major_nr = major(stats.st_rdev); - *minor_nr = minor(stats.st_rdev); - *mode = stats.st_mode; - return 0; - - out_remove: - if (unlink(path) < 0){ - printe("cannot remove %s : %s\n", path, strerror(errno)); - exit(1); - } - return -1; -} - -void check_gnbd_ctl(void) -{ - char device[LINE_MAX]; - char buf[LINE_MAX]; - int major_nr = 10; - int minor_nr; - mode_t mode = S_IFCHR | S_IRUSR | S_IWUSR; - FILE *fp; - - fp = fopen("/proc/misc", "r"); - if (!fp){ - printe("could not open /proc/misc : %s\n", strerror(errno)); - exit(1); - } - while(fgets(buf, LINE_MAX, fp) != NULL) - if (sscanf(buf, "%d %s", &minor_nr, device) == 2 && - strcmp(device, "gnbd_ctl") == 0) - break; - if(strcmp(device, "gnbd_ctl") != 0){ - printe("could not find gnbd_ctl registered in /proc/misc. This\n" - "probably means that you have not loaded the gnbd module.\n"); - exit(1); - } - if (get_dev("/dev/gnbd_ctl", &mode, &major_nr, &minor_nr) == 0) - return; - printv("creating /dev/gnbd_ctl\n"); - if (mknod("/dev/gnbd_ctl", mode, makedev(10, minor_nr)) < 0){ - printe("cannot create gnbd_ctl : %s\n", strerror(errno)); - exit(1); - } -} - -void create_gnbd_dir(void){ - if(mkdir("/dev/gnbd", S_IRWXU | S_IRGRP | S_IXGRP | - S_IROTH | S_IXOTH) == -1){ - if (errno == EEXIST) - return; - else{ - printe("unable to create directory /dev/gnbd : %s\n", strerror(errno)); - exit(1); - } - } - printm("created directory /dev/gnbd\n"); -} - -int find_empty_minor(){ - int minor; - gnbd_info_t info; - - for (minor = 0; minor < MAX_GNBD; minor++){ - if (sscanf(get_sysfs_attr(minor, "usage"), "%d", &info.usage) != 1){ - printe("cannot parse %s/gnbd%d/usage\n", sysfs_class, minor); - exit(1); - } - if (info.usage) - continue; - if (sscanf(get_sysfs_attr(minor, "pid"), "%d", &info.pid) != 1){ - printe("cannot parse %s/gnbd%d/pid\n", sysfs_class, minor); - exit(1); - } - if (info.pid != -1) - continue; - if (sscanf(get_sysfs_attr(minor, "sectors"), "%"PRIu64, - &info.sectors) != 1){ - printe("cannot parse %s/gnbd%d/sectors\n", sysfs_class, minor); - exit(1); - } - if (info.sectors == 0) - return minor; - } - printe("No available minor numbers\n"); - exit(1); -} - - -int get_info(gnbd_info_t *entry) -{ - int minor = entry->minor_nr; - if (entry->name[0] != 0){ - if (strncmp(entry->name, get_sysfs_attr(minor, "name"), 32) != 0){ - printv("/dev/gnbd/%s doesn't match up with %s/gnbd%d entry\n", - entry->name, sysfs_class, minor); - return -1; - } - } else{ - strncpy(entry->name, get_sysfs_attr(minor, "name"), 32); - entry->name[31] = 0; - } - if (parse_server(get_sysfs_attr(minor, "server"), entry->server_name, - &entry->port) < 0){ - printe("cannot parse %s/gnbd%d/server\n", sysfs_class, minor); - exit(1); - } - if (sscanf(get_sysfs_attr(minor, "sectors"), "%"PRIu64, - &entry->sectors) != 1){ - printe("cannot parse %s/gnbd%d/sectors\n", sysfs_class, minor); - exit(1); - } - if (sscanf(get_sysfs_attr(minor, "usage"), "%d\n", &entry->usage) != 1){ - printe("cannot parse %s/gnbd%d/usage\n", sysfs_class, minor); - exit(1); - } - if (sscanf(get_sysfs_attr(minor, "connected"), "%d", &entry->connected) != 1){ - printe("cannot parse %s/gnbd%d/connected\n", sysfs_class, minor); - exit(1); - } - if (sscanf(get_sysfs_attr(minor, "waittime"), "%ld", &entry->waittime) != 1){ - printe("cannot parse %s/gnbd%d/waittime\n", sysfs_class, minor); - exit(1); - } - if (sscanf(get_sysfs_attr(minor, "flags"), "%hx", &entry->flags) != 1){ - printe("cannot parse %s/gnbd%d/flags\n", sysfs_class, minor); - exit(1); - } - if (sscanf(get_sysfs_attr(minor, "pid"), "%d", &entry->pid) != 1){ - printe("cannot parse %s/gnbd%d/pid\n", sysfs_class, minor); - exit(1); - } - return 0; -} - -int add_device(char *name) -{ - gnbd_info_t *entry; - int minor_nr = -1; - char path[LINE_MAX]; - mode_t mode = S_IFBLK; - - snprintf(path, LINE_MAX, "/dev/gnbd/%s", name); - - if (get_dev(path, &mode, &gnbd_major, &minor_nr) < 0) - return -1; - - entry = (gnbd_info_t *)malloc(sizeof(gnbd_info_t)); - if (!entry){ - printe("couldn't allocated space for %s device information : %s\n", - name, strerror(errno)); - exit(1); - } - strncpy(entry->name, name, 32); - entry->name[31] = 0; - entry->minor_nr = minor_nr; - - if (get_info(entry) < 0){ - printv("deleting %s\n", path); - goto exit_unlink; - } - - if (IS_UNUSED(entry)){ - printv("%s is not in use. deleting\n", path); - goto exit_unlink; - } - - if (entry->minor_nr > maxminor) - maxminor = entry->minor_nr; - info_add(entry); - return 0; - - exit_unlink: - if(unlink(path) < 0){ - printe("cannot delete %s : %s\n", path, strerror(errno)); - exit(1); - } - free(entry); - - return -1; -} - -void create_generic_gnbd_file(int minor) -{ - int err; - char path[LINE_MAX]; - sprintf(path, "/dev/gnbd%d", minor); - retry: - err = mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, - makedev(gnbd_major, minor)); - if (err < 0 && errno != EEXIST){ - printe("could not create file %s : %s\n", - path, strerror(errno)); - exit(1); - } - if (err < 0){ - struct stat stats; - if (stat(path, &stats) < 0){ - printe("couldn't stat file %s : %s\n", path, strerror(errno)); - exit(1); - } - if (major(stats.st_rdev) != gnbd_major || minor(stats.st_rdev) != minor){ - if (unlink(path) < 0){ - printe("couldn't unlink file %s : %s\n", path, strerror(errno)); - exit(1); - } - goto retry; - } - } -} - -void cleanup_device(char *name, int minor, int fd) -{ - char path[LINE_MAX]; - - if (ioctl(fd, GNBD_CLEAR_QUE, (unsigned long)minor) < 0){ - printe("cannot clear gnbd device #%d queue : %s\n", minor, - strerror(errno)); - exit(1); - } - if (override){ - printm("waiting for all users to close device %s\n", name); - while (1){ - int usage; - if (sscanf(get_sysfs_attr(minor, "usage"), "%d\n", &usage) != 1){ - printe("cannot parse %s/gnbd%d/usage\n", sysfs_class, minor); - exit(1); - } - if (usage == 0) - break; - sleep(2); - } - } - set_sysfs_attr(minor, "sectors", "0\n"); - if (name){ - snprintf(path, LINE_MAX, "/dev/gnbd/%s", name); - if (unlink(path) < 0 && errno != ENOENT){ - printe("cannot remove fale %s : %s\n", path, strerror(errno)); - exit(1); - } - printm("removed gnbd device %s\n", name); - } -} - - -#define MULTIPATH_SCRIPT "/etc/dev.d/block/multipath.dev" -void run_multipath_code(int minor_nr, int add) -{ - int i_am_parent, fd; - char *envp[6]; - char devpath[32]; - char devname[32]; - - i_am_parent = daemonize(); - if (i_am_parent < 0){ - printm("cannot daemonize to exec multipath code : %s\n", strerror(errno)); - return; - } - if (i_am_parent) - return; - if ((fd = open("/dev/null", O_RDWR)) < 0) { - printm("cannot open /dev/null in daemon : %s\n", strerror(errno)); - exit(1); - } - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); - envp[0] = "HOME=/"; - envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - envp[2] = (add)? "ACTION=add" : "ACTION=remove"; - snprintf(devpath, 31, "DEVPATH=/block/gnbd%d", minor_nr); - devpath[31] = '\0'; - envp[3] = devpath; - snprintf(devname, 31, "DEVNAME=/dev/gnbd%d", minor_nr); - devname[31] = '\0'; - envp[4] = devname; - envp[5] = NULL; - execle(MULTIPATH_SCRIPT, MULTIPATH_SCRIPT, NULL, envp); - log_verbose("cannot exec %s : %s", MULTIPATH_SCRIPT, strerror(errno)); - exit(1); -} - -void remove_gnbd(char *name, int minor, int pid) -{ - int fd; - - if( (fd = open("/dev/gnbd_ctl", O_RDWR)) < 0){ - printe("cannot open /dev/gnbd_ctl : %s\n", strerror(errno)); - exit(1); - } - if (!override){ - if (ioctl(fd, GNBD_DISCONNECT, (unsigned long)minor) < 0 && - errno != ENOTCONN){ - printe("cannot disconnect device #%d : %s\n", minor, strerror(errno)); - exit(1); - } - } - if (check_lock("gnbd_monitor.pid", NULL)){ - if (do_remove_monitored_dev(minor) < 0){ - if (!override) - exit(1); - printe("unable to stop monitoring device %s. removing anyway\n", - name); - } - } - if (pid > 0) - kill(pid, SIGKILL); - cleanup_device(name, minor, fd); - run_multipath_code(minor, 0); - close(fd); -} - -void kill_gnbd_monitor(void){ - int pid; - if (check_lock("gnbd_monitor.pid", &pid)){ - if (pid > 0){ - kill(pid, SIGKILL); - } - } -} - -int device_active(int minor){ - list_t *item; - gnbd_info_t *gnbd_info; - char prefix[] = "/dev/gnbd/"; - char dev_path[256]; - - list_foreach(item, &gnbd_list){ - struct stat statbuf; - gnbd_info = list_entry(item, gnbd_info_t, list); - if ( gnbd_info->minor_nr == minor ){ - strcpy(dev_path, prefix); - strcat(dev_path, gnbd_info->name); - - if ( lstat(dev_path, &statbuf) == 0 ){ - if ( S_ISBLK(statbuf.st_mode) ) - return 1; /* this is a valid block device */ - } else { - if ( errno != ENOENT ){ - printe("failed to stat device %s : %s\n", dev_path, strerror(errno)); - return 1; /* if stat on the device failed for some reason*/ - } - } - } - } - return 0; -} - -int uncached_imports_removed(){ - if (check_lock("gnbd_monitor.pid", NULL)){ - monitor_info_t *ptr, *devs; - int i, count; - - if (do_list_monitored_devs(&devs, &count) < 0){ - printe("unable to get monitored device list : %s\n", gstrerror(errno)); - return 1; - } - if ( count <= 0 ){ /* monitoring nothing */ - free(devs); - return 1; - } - - ptr = devs; - for (i = 0; i < count; i++, ptr++){ - if ( device_active(ptr->minor_nr) ){ - /* found an active device, bail */ - free(devs); - return 0; - } - } - free(devs); - return 1; /* No active devices found */ - } - return 0; -} - -void update_devs(void){ - int minor; - char path[LINE_MAX]; - gnbd_info_t *info; - mode_t mode; - - for(minor = 0; minor < MAX_GNBD; minor++){ - if (match_info_minor(minor)) - continue; - - info = (gnbd_info_t *)malloc(sizeof(gnbd_info_t)); - if (!info){ - printe("couldn't allocated space for device #%d information : %s\n", - minor, strerror(errno)); - exit(1); - } - memset(info, 0, sizeof(gnbd_info_t)); - - info->minor_nr = minor; - - get_info(info); - - if (IS_UNUSED(info)){ - free(info); - continue; - } - - snprintf(path, LINE_MAX, "/dev/gnbd/%s", info->name); - if (IS_READONLY(info)) - mode = S_IFBLK | S_IRUSR | S_IRGRP | S_IROTH; - else - mode = S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - if (mknod(path, mode, makedev(gnbd_major, minor)) < 0){ - if (errno == EEXIST){ - if (override){ - remove_gnbd(NULL, minor, info->pid); - printm("removed duplicate gnbd device %s\n", info->name); - free(info); - if (uncached_imports_removed()) - kill_gnbd_monitor(); - } - else { - printe("cannot create %s for gnbd device minor #%d, " - "name already used\n", path, minor); - exit(1); - } - } else { - printe("cannot create gnbd device file %s : %s\n", path, - strerror(errno)); - exit(1); - } - } else{ - printm("created gnbd device file %s\n", path); - info_add(info); - } - } -} - -void check_files(void) -{ - DIR *dp; - struct dirent *entry; - int i; - - dp = opendir("/dev/gnbd/"); - if (dp == NULL){ - printe("unable to open directory /dev/gnbd : %s", strerror(errno)); - exit(1); - } - while( (entry = readdir(dp)) != NULL){ - if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) - add_device(entry->d_name); - } - update_devs(); - closedir(dp); - for (i = 0; i <= maxminor; i++) - create_generic_gnbd_file(i); -} - -void remove_all(void){ - list_t *item; - gnbd_info_t *gnbd_info; - - list_foreach(item, &gnbd_list){ - gnbd_info = list_entry(item, gnbd_info_t, list); - remove_gnbd(gnbd_info->name, gnbd_info->minor_nr, gnbd_info->pid); - } - - if (uncached_imports_removed()) - kill_gnbd_monitor(); -} - -void remove_clients(char *names[], int num){ - list_t *item; - gnbd_info_t *gnbd_info; - int i; - - for (i = 0; i < num; i++){ - list_foreach(item, &gnbd_list){ - gnbd_info = list_entry(item, gnbd_info_t, list); - if(strncmp(gnbd_info->name, names[i], 32) == 0){ - remove_gnbd(gnbd_info->name, gnbd_info->minor_nr, gnbd_info->pid); - break; - } - } - if (item == &gnbd_list){ - printe("cannot find device '%s'\n", names[i]); - exit(1); - } - } - - if (uncached_imports_removed()) - kill_gnbd_monitor(); -} - -void fence(char *host, char *server, int is_fence) -{ - node_req_t node; - int sock_fd; - uint32_t msg; - int err = 0; - char *fence_str; - - if (is_fence) - fence_str = "fence"; - else - fence_str = "unfence"; - - if (strlen(host) > 64){ - printe("name of node to %s must be <= 64 characters\n", fence_str); - exit(1); - } - strncpy(node.node_name, host, 65); - sock_fd = connect_to_server(server, (uint16_t)server_port); - if (sock_fd < 0){ - printe("cannot connect to %s (%d) : %s\n", server, sock_fd, strerror(errno)); - exit(1); - } - if (is_fence) - err = send_u32(sock_fd, EXTERN_FENCE_REQ); - else - err = send_u32(sock_fd, EXTERN_UNFENCE_REQ); - if (err < 0){ - printe("cannot send %s request to server : %s\n", fence_str, - gstrerror(errno)); - exit(SERVER_ERR); - } - if (retry_write(sock_fd, &node, sizeof(node)) < 0){ - printe("cannot send %s node to server : %s\n", fence_str, - gstrerror(errno)); - exit(SERVER_ERR); - } - if (recv_u32(sock_fd, &msg) < 0){ - printe("cannot read %s reply from server : %s\n", fence_str, - gstrerror(errno)); - exit(SERVER_ERR); - } - close(sock_fd); - if (msg != EXTERN_SUCCESS_REPLY){ - printe("%s failed : %s\n", fence_str, strerror(msg)); - exit(SERVER_ERR); - } - printv("%s %sd\n", host, fence_str); -} - -int start_receiver(int minor_nr) -{ - int ret; - char cmd[256]; - - snprintf(cmd, 256, "gnbd_recvd %s -d %d", ((is_clustered)? "" : "-n"), minor_nr); - if( (ret = system(cmd)) < 0){ - printe("system() failed : %s\n", strerror(errno)); - return -1; - } - if (ret != 0){ - printe("gnbd_recvd failed\n"); - return -1; - } - return 0; -} - -int restart_device(gnbd_info_t *gnbd){ - char filename[32]; - - snprintf(filename, 32, "gnbd_recvd-%d.pid", gnbd->minor_nr); - if (gnbd->connected > 0) - return 0; - if (check_lock(filename, NULL)) - return 0; - /* - * If the device is flushed, you need to wait for all the current - * users to close it, before you reconnect - */ - if (gnbd->pid < 0 && gnbd->usage > 0) - return 0; - if (start_receiver(gnbd->minor_nr) == 0){ - printm("restarted gnbd_recvd for gnbd device %s\n", gnbd->name); - return 0; - } - printm("cannot restart server for gnbd device %s\n", gnbd->name); - return -1; -} - -void reimport_device(import_info_t *info, char *host, - gnbd_info_t *gnbd) -{ - if (check_lock("gnbd_monitor.pid", NULL)){ - monitor_info_t *ptr, *devs; - int i, count; - - if (do_list_monitored_devs(&devs, &count) < 0){ - printe("unable to get monitored device list. cannot reimport %s\n", - info->name); - return; - } - ptr = devs; - for (i = 0; i < count; i++, ptr++){ - if (ptr->minor_nr == gnbd->minor_nr){ - printe("cannot reimport monitored device %s\n", info->name); - return; - } - } - free(devs); - } - snprintf(sysfs_buf, 4096, "%s/%hx\n", host, server_port); - if (__set_sysfs_attr(gnbd->minor_nr, "server", sysfs_buf) < 0){ - if (errno == EBUSY) - printe("cannot reimport already connected device %s\n", info->name); - return; - } - printm("reimporting device %s on server %s, port %u\n", gnbd->name, - gnbd->server_name, gnbd->port); - restart_device(gnbd); -} - -int are_nodes_equal(char *node1, char *node2){ - struct addrinfo *ai1, *ai2; - int ret = 0; - - ret = getaddrinfo(node1, NULL, NULL, &ai1); - if (ret){ - printe("cannot get address info for %s : %s\n", node1, - (ret == EAI_SYSTEM)? strerror(errno) : gai_strerror(ret)); - exit(1); - } - ret = getaddrinfo(node2, NULL, NULL, &ai2); - if (ret){ - printe("cannot get address info for %s : %s\n", node2, - (ret == EAI_SYSTEM)? strerror(errno) : gai_strerror(ret)); - exit(1); - } - ret = check_addr_info(ai1, ai2); - - freeaddrinfo(ai1); - freeaddrinfo(ai2); - return ret; -} - -int create_device(import_info_t *info, char *host) -{ - int minor; - mode_t mode; - char path[LINE_MAX]; - gnbd_info_t *entry; - - entry = match_info_name(info->name); - if (entry){ - printv("There is already a GNBD with the name %s.", info->name); - if (server_port == entry->port && - are_nodes_equal(host, entry->server_name)){ - restart_device(entry); - return -1; - } - if (info->timeout){ - printe("cannot reimport uncached GNBD %s\n", info->name); - return -1; - } - if (entry->pid < 0 && entry->usage > 0){ - printe("Cannot reimport GNBD %s until all users have closed it\n", - info->name); - return -1; - } - reimport_device(info, host, entry); - return -1; - } - minor = find_empty_minor(); - set_sysfs_attr(minor, "name", info->name); - snprintf(sysfs_buf, 4096, "0x%hx", info->flags); - set_sysfs_attr(minor, "flags", sysfs_buf); - snprintf(sysfs_buf, 4096, "%s/%hx\n", host, server_port); - set_sysfs_attr(minor, "server", sysfs_buf); - if (info->flags & GNBD_READ_ONLY) - mode = S_IFBLK | S_IRUSR | S_IRGRP | S_IROTH; - else - mode = S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - snprintf(path, LINE_MAX, "/dev/gnbd/%s", info->name); - if (mknod(path, mode, makedev(gnbd_major, minor)) < 0 && - errno != EEXIST){ - printe("could not create block device file for %s : %s\n", - info->name, strerror(errno)); - exit(1); - } - if (minor > maxminor){ - maxminor = minor; - create_generic_gnbd_file(maxminor); - } - printm("created gnbd device %s\n", info->name); - return minor; -} - -void setclients(char *host) -{ - char *buf; - import_info_t *ptr; - int size; - int minor_nr; - size = read_from_server(host, EXTERN_NAMES_REQ, &buf); - if (!size) - return; - ptr = (import_info_t *)buf; - while ((char *)ptr < buf + size){ - if (ptr->timeout != 0 && is_clustered == 0){ - printe("cannot import uncached devices while using the -n option\n" MAN_MSG); - exit(1); - } - minor_nr = create_device(ptr, host); - if (minor_nr >= 0){ - if (start_gnbd_monitor(minor_nr, (int)ptr->timeout, host) < 0) - exit(1); - if (start_receiver(minor_nr)) - exit(1); - run_multipath_code(minor_nr, 1); - } - ptr++; - } -} - -void get_serv_list(char *host) -{ - char *buf; - import_info_t *ptr; - int size; - size = read_from_server(host, EXTERN_NAMES_REQ, &buf); - if (size) { - ptr = (import_info_t *)buf; - while ((char *)ptr < buf + size){ - printf("%s\n", ptr->name); - ptr++; - } - } - printf("\n"); - free(buf); -} - -void get_banned_list(char *host) -{ - char *buf; - node_req_t *ptr; - int size; - size = read_from_server(host, EXTERN_LIST_BANNED_REQ, &buf); - if (size) { - ptr = (node_req_t *)buf; - while ((char *)ptr < buf + size){ - printf("%s\n", ptr->node_name); - ptr++; - } - } - printf("\n"); - free(buf); -} - -void list(void){ - list_t *item; - gnbd_info_t *info; - - if (verbosity == QUIET) - return; - list_foreach(item, &gnbd_list){ - info = list_entry(item, gnbd_info_t, list); - printf("Device name : %s\n" - "----------------------\n" - " Minor # : %d\n" - " sysfs name : /block/gnbd%d\n" - " Server : %s\n" - " Port : %d\n" - " State : %s %s %s\n" - " Readonly : %s\n" - " Sectors : %llu\n\n", - info->name, - info->minor_nr, - info->minor_nr, - info->server_name, - info->port, - (info->usage > 0)? "Open" : "Close", - (info->connected > 0)? "Connected" : "Disconnected", - (info->waittime != -1)? "Pending" : "Clear", - IS_READONLY(info)? "Yes" : "No", - (unsigned long long)info->sectors); - } -} - -void get_uid(char *name){ - list_t *item; - gnbd_info_t *gnbd = NULL; - char *uid; - device_req_t req; - int minor_nr = -1; - - sscanf(name, "/block/gnbd%d", &minor_nr); - list_foreach(item, &gnbd_list){ - gnbd = list_entry(item, gnbd_info_t, list); - if (minor_nr >= 0 && minor_nr == gnbd->minor_nr) - break; - if (strncmp(gnbd->name, name, 32) == 0) - break; - gnbd = NULL; - } - if (!gnbd){ - printe("cannot find device '%s'\n", name); - exit(1); - } - strncpy(req.name, gnbd->name, 32); - req.name[31] = 0; - talk_to_server(gnbd->server_name, EXTERN_UID_REQ, &uid, &req, sizeof(req)); - if (uid) - printf("%s\n", uid); - free(uid); -} - -void validate_gnbds(void){ - list_t *item; - char filename[32]; - gnbd_info_t *gnbd; - - list_foreach(item, &gnbd_list){ - gnbd = list_entry(item, gnbd_info_t, list); - snprintf(filename, 32, "gnbd_recvd-%d.pid", gnbd->minor_nr); - if (restart_device(gnbd) == 0) - continue; - if (override == 1){ - int fd; - printm("removing device\n"); - if( (fd = open("/dev/gnbd_ctl", O_RDWR)) < 0){ - printe("cannot open /dev/gnbd_ctl : %s\n", strerror(errno)); - exit(1); - } - if (check_lock("gnbd_monitor.pid", NULL)){ - if (do_remove_monitored_dev(gnbd->minor_nr) < 0){ - printe("unable to stop monitoring device %s. removing anyway\n", - gnbd->name); - } - } - cleanup_device(gnbd->name, gnbd->minor_nr, fd); - close(fd); - } - } -} - -int main(int argc, char **argv) -{ - int action = 0; - char *host = NULL; - char *fence_server = NULL; - char *dev = NULL; - int c; - - list_init(&gnbd_list); - program_name = "gnbd_import"; - while( (c = getopt(argc, argv, "ac:e:hi:lnOp:qRrs:t:U:u:Vv")) != -1){ - switch(c){ - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - return 1; - case 'a': - set_action(ACTION_VALIDATE); - continue; - case 'c': - set_action(ACTION_LIST_BANNED); - host = optarg; - continue; - case 'e': - set_action(ACTION_LIST_EXPORTED); - host = optarg; - continue; - case 'h': - return usage(); - case 'i': - set_action(ACTION_IMPORT); - host = optarg; - continue; - case 'k': - set_action(ACTION_FAIL_SERVER); - host = optarg; - continue; - case 'l': - set_action(ACTION_LIST); - continue; - case 'n': - is_clustered = 0; - continue; - case 'O': - override = 1; - continue; - case 'p': - if (sscanf(optarg, "%u", &server_port) != 1){ - printe("invalid port number, %s\n" MAN_MSG, optarg); - exit(1); - } - continue; - case 'q': - if (verbosity == VERBOSE){ - printe("cannot use both -q and -v options\nPlease use '-h' for usage.\n"); - exit(1); - } - verbosity = QUIET; - continue; - case 'R': - set_action(ACTION_REMOVE_ALL); - continue; - case 'r': - set_action(ACTION_REMOVE); - continue; - case 's': - set_action(ACTION_FENCE); - host = optarg; - continue; - case 't': - fence_server = optarg; - continue; - case 'U': - set_action(ACTION_GET_UID); - dev = optarg; - continue; - case 'u': - set_action(ACTION_UNFENCE); - host = optarg; - continue; - case 'V': - printf("%s %s (built %s %s)\n", argv[0], - GNBD_RELEASE_NAME, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - return 0; - case 'v': - if (verbosity == QUIET){ - printe("cannot use both -q and -v options\nPlease use '-h' for usage.\n"); - exit(1); - } - verbosity = VERBOSE; - continue; - default: - printe("invalid option -- %c\n", c); - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(1); - } - } - if (!action) - action = ACTION_LIST; - if (get_my_nodename(node_name, is_clustered) < 0){ - printe("cannot get node name : %s\n", strerror(errno)); - if (is_clustered){ - if (errno == ESRCH) - printe("No cluster manager is running\n"); - if (errno == ELIBACC) - printe("cannot find magma plugins\n"); - printe("If you are not planning to use a cluster manager, use -n\n"); - } - return 1; - } - if (fence_server && action != ACTION_FENCE && action != ACTION_UNFENCE){ - printe("-t can only be used with -s or -u\n" MAN_MSG); - return 1; - } - if ((action == ACTION_FENCE || action == ACTION_UNFENCE) && - !strcmp(host, "localhost")){ - host = node_name; - } - if (argc != optind && action != ACTION_REMOVE){ - printe("extra operand for action: %s\n", argv[optind]); - fprintf(stderr, "please use '-h' for usage.\n"); - return 1; - } - if (action != ACTION_LIST_EXPORTED && action != ACTION_LIST_BANNED && - action != ACTION_FENCE && action != ACTION_UNFENCE){ - gnbd_major = get_major_nr(); - check_gnbd_ctl(); - create_gnbd_dir(); - check_files(); - } - switch(action){ - case ACTION_FENCE: - case ACTION_UNFENCE: - if (!fence_server){ - printe("you must use -t with %s\n" MAN_MSG, - (action == ACTION_FENCE)? "-s" : "-u"); - return 1; - } - fence(host, fence_server, (action == ACTION_FENCE)? 1 : 0); - return 0; - case ACTION_REMOVE: - if (argc == optind){ - printe("missing operand for remove action\n"); - fprintf(stderr, "please use '-h' for usage.\n"); - return 1; - } - remove_clients(argv + optind, argc - optind); - return 0; - case ACTION_REMOVE_ALL: - remove_all(); - return 0; - case ACTION_VALIDATE: - validate_gnbds(); - return 0; - case ACTION_LIST_EXPORTED: - get_serv_list(host); - return 0; - case ACTION_IMPORT: - setclients(host); - return 0; - case ACTION_LIST: - list(); - return 0; - case ACTION_LIST_BANNED: - get_banned_list(host); - return 0; - case ACTION_GET_UID: - get_uid(dev); - return 0; - default: - printe("unknown action %d\n", action); - return 1; - } -} diff --git a/gnbd/utils/gnbd_utils.c b/gnbd/utils/gnbd_utils.c deleted file mode 100644 index 422019b..0000000 --- a/gnbd/utils/gnbd_utils.c +++ /dev/null @@ -1,424 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <syslog.h> -#include <sys/utsname.h> -#include <string.h> -#include <errno.h> -#include <inttypes.h> - -#include "magma.h" -#include "gnbd_endian.h" -#include "gnbd_utils.h" - - -pid_t program_pid; -char *program_name; -verbosity_level verbosity = NORMAL; -char *program_dir = "/var/run/gnbd"; -int daemon_status; -char ip_str[16]; -char sysfs_buf[4096]; - - -char *beip_to_str(ip_t ip) -{ - int i; - char *p; - - p = ip_str; - ip = beip_to_cpu(ip); - - for (i = 3; i >= 0; i--) - { - p += sprintf(p, "%d", (ip >> (8 * i)) & 0xFF); - if (i > 0) - *(p++) = '.'; - } - return ip_str; -} - -static void sig_usr1(int sig) -{ - daemon_status = 0; -} - -static void sig_usr2(int sig) -{ - daemon_status = 1; -} - -/*buffer must be 65 charaters long */ -int get_my_nodename(char *buf, int is_clustered){ - struct utsname nodeinfo; - - if (is_clustered) { - int fd; - fd = clu_connect(NULL, 0); - if (fd < 0) - return -1; - if (clu_local_nodename(NULL, buf, 65)) - return -1; - clu_disconnect(fd); - return 0; - } - if (uname(&nodeinfo) < 0) - /*FIXME -- can I print something out here?? */ - return -1; - strcpy(buf, nodeinfo.nodename); - return 0; -} - - - -int __check_lock(char *file, int *pid){ - int fd; - char path[1024]; - struct flock lock; - - snprintf(path, 1024, "%s/%s", program_dir, file); - - if (pid) - *pid = 0; - - if( (fd = open(path, O_RDWR)) < 0){ - if (errno != ENOENT){ - return -1; - } - return 0; - } - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - if (fcntl(fd, F_GETLK, &lock) < 0) - goto fail; - - if (pid && lock.l_type != F_UNLCK){ - char pid_str[13]; - int count = 0; - int bytes; - - memset(pid_str, 0, 13); - while( (bytes = read(fd, &pid_str[count], 12 - count)) != 0){ - if (bytes <= 0 && errno != -EINTR) - goto fail; - if (bytes > 0) - count += bytes; - } - if (sscanf(pid_str, "%d\n", pid) != 1){ - errno = -EINVAL; - goto fail; - } - } - - close(fd); - - if (lock.l_type == F_UNLCK) - return 0; - return 1; - - fail: - close(fd); - return -1; -} - -int check_lock(char *file, int *pid){ - int ret; - - ret = __check_lock(file, pid); - if (ret < 0){ - printe("cannot check lock for %s/%s : %s\n", program_dir, file, - strerror(errno)); - exit(1); - } - return ret; -} - -/** - * pid_lock - there can be only one. - * returns 1 - you locked the file - * 0 - another process is already running - */ -int pid_lock(char *extra_info) -{ - struct flock lock; - char pid_str[12], path[1024]; - int fd, val; - - if (strncmp(program_dir, "/var/run/gnbd", 13) == 0){ - struct stat stat_buf; - - if (stat("/var/run/gnbd", &stat_buf) < 0){ - if (errno != ENOENT) - fail_startup("cannot stat lockfile dir : %s\n", strerror(errno)); - if(mkdir("/var/run/gnbd", S_IRWXU)) - fail_startup("cannot create lockfile directory : %s\n", - strerror(errno)); - } - else if(!S_ISDIR(stat_buf.st_mode)) - fail_startup("/var/run/gnbd is not a directory.\n" - "Cannot create lockfile.\n"); - } - - snprintf(path, 1024, "%s/%s%s.pid", program_dir, program_name, extra_info); - - if( (fd = open(path, O_WRONLY | O_CREAT, - (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) - fail_startup("cannot open lockfile '%s' : %s\n", path, strerror(errno)); - - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - if (fcntl(fd, F_SETLK, &lock) < 0) { - if (errno == EACCES || errno == EAGAIN){ - close(fd); - return 0; - } - else - fail_startup("cannot lock lockfile : %s\n", strerror(errno)); - } - - if (ftruncate(fd, 0) < 0) - fail_startup("cannot truncate lockfile : %s\n", strerror(errno)); - - snprintf(pid_str, 12, "%d\n", getpid()); - if (write(fd, pid_str, strlen(pid_str)) != strlen(pid_str)) - fail_startup("error writing to '%s' : %s\n", path, strerror(errno)); - - if ((val = fcntl(fd, F_GETFD, 0)) < 0) - fail_startup("cannot read close-on-exec flag : %s\n", strerror(errno)); - - val |= FD_CLOEXEC; - if (fcntl(fd, F_SETFD, val) < 0) - fail_startup("cannot set close-on-exec flag : %s\n", strerror(errno)); - return 1; -} - -/* This was gleaned from lock_gulmd */ -int daemonize(void) -{ - int pid, i; - - if( (pid = fork()) < 0){ - printe("Failed first fork: %s\n", strerror(errno)); - return -1; - } - else if (pid != 0){ - return pid; - } - - setsid(); - - if ( (pid = fork()) < 0){ - printe("Failed second fork: %s\n", strerror(errno)); - exit(1); - } - else if (pid != 0) - exit(0); - - chdir("/"); - umask(0); - /* leave default fds open until startup is completed */ - for(i = open_max()-1; i > 2; --i) - close(i); - openlog(program_name, LOG_PID, LOG_DAEMON); - return 0; -} - -void daemonize_and_exit_parent(void) -{ - int i_am_parent; - struct sigaction act; - - program_pid = getpid(); - memset(&act,0,sizeof(act)); - act.sa_handler = sig_usr1; - if (sigaction(SIGUSR1, &act, NULL) < 0){ - printe("cannot set a handler for SIGUSR1 : %s\n", strerror(errno)); - exit(1); - } - memset(&act,0,sizeof(act)); - act.sa_handler = sig_usr2; - if (sigaction(SIGUSR2, &act, NULL) < 0){ - printe("cannot set a handler for SIGUSR2 : %s\n", strerror(errno)); - exit(1); - } - daemon_status = -1; - i_am_parent = daemonize(); - if (i_am_parent < 0) - exit(1); - if (i_am_parent){ - while(daemon_status == -1) - sleep(10); - exit(daemon_status); - } - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - if (sigaction(SIGUSR1, &act, NULL) < 0) - fail_startup("cannot set default handler for SIGUSR1 : %s\n", - strerror(errno)); - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - if (sigaction(SIGUSR2, &act, NULL) < 0) - fail_startup("cannot set default handler for SIGUSR2 : %s\n", - strerror(errno)); -} - -int parse_server(char *buf, char *name, uint16_t *port) -{ - char *ptr; - - if (strlen(buf) == 0){ - strcpy(name, ""); - *port = 0; - return 0; - } - - ptr = strchr(buf, '/'); - if (!ptr) - return -1; - *ptr++ = 0; - strncpy(name, buf, 256); - if (sscanf(ptr, "%4hx", port) != 1) - return -1; - return 0; -} - -char *do_get_sysfs_attr(int minor, char *attr_name) -{ - int sysfs_fd; - int bytes; - int count = 0; - char sysfs_path[40]; - - snprintf(sysfs_path, 40, "/sys/class/gnbd/gnbd%d/%s", minor, attr_name); - if( (sysfs_fd = open(sysfs_path, O_RDONLY)) < 0) - return NULL; - while (count < 4095){ - bytes = read(sysfs_fd, &sysfs_buf[count], 4095 - count); - if (bytes < 0 && errno != EINTR){ - close (sysfs_fd); - return NULL; - } - if (bytes == 0) - break; - count += bytes; - } - /* overwrite the '\n' with '\0' */ - sysfs_buf[count - 1] = 0; - if (close(sysfs_fd) < 0) - return NULL; - return sysfs_buf; -} - -char *get_sysfs_attr(int minor, char *attr_name) -{ - char *buf; - buf = do_get_sysfs_attr(minor, attr_name); - if (buf == NULL){ - printe("cannot get /sys/class/gnbd/gnbd%d/%s value : %s\n", - minor, attr_name, strerror(errno)); - exit(1); - } - return buf; -} - -int do_set_sysfs_attr(int minor_nr, char *attribute, char *val) -{ - int sysfs_fd; - int bytes; - int count = 0; - char sysfs_path[40]; - int len; - - len = strlen(val); - if (len >= 4096) - return -1; - snprintf(sysfs_path, 40, "/sys/class/gnbd/gnbd%d/%s", minor_nr, attribute); - if( (sysfs_fd = open(sysfs_path, O_WRONLY)) < 0) - return -1; - while (count < len){ - bytes = write(sysfs_fd, &val[count], len - count); - if (bytes < 0 && errno != EINTR){ - close(sysfs_fd); - return -2; - } - if (bytes == 0){ - close(sysfs_fd); - return -1; - } - count += bytes; - } - if (close(sysfs_fd) < 0) - return -1; - return 0; -} - -/* This version allows writes to fail */ -int __set_sysfs_attr(int minor_nr, char *attribute, char *val) -{ - int err = do_set_sysfs_attr(minor_nr, attribute, val); - if (err == -1){ - printe("cannot set /sys/class/gnbd/gnbd%d/%s value : %s\n", minor_nr, - attribute, strerror(errno)); - exit(1); - } - return err; -} - -void set_sysfs_attr(int minor_nr, char *attribute, char *val) -{ - if (do_set_sysfs_attr(minor_nr, attribute, val) < 0){ - printe("cannot set /sys/class/gnbd/gnbd%d/%s value : %s\n", minor_nr, - attribute, strerror(errno)); - exit(1); - } -} - -#ifdef OPEN_MAX -static int openmax = OPEN_MAX; -#else -static int openmax = 0; -#endif /* OPEN_MAX */ - -#define OM_GUESS 256 -/** - * open_max - clacs max number of open files. - * Returns: the maximum number of file we can have open at a time. - * Or -1 for error. - */ -int open_max(void) -{ - if(openmax == 0) { - errno = 0; - if((openmax = sysconf(_SC_OPEN_MAX)) < 0) { - if( errno == 0) { - openmax = OM_GUESS; - }else{ - return -1; - } - } - } - return openmax; -} diff --git a/gnbd/utils/gnbd_utils.h b/gnbd/utils/gnbd_utils.h deleted file mode 100644 index ef535e8..0000000 --- a/gnbd/utils/gnbd_utils.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gnbd_utils_h__ -#define __gnbd_utils_h__ - -#include <stdio.h> -#include <signal.h> -#include <syslog.h> - -typedef enum {QUIET, NORMAL, VERBOSE} verbosity_level; - -extern verbosity_level verbosity; -extern char *program_name; -extern pid_t program_pid; -extern char *program_dir; -extern char sysfs_buf[4096]; - -#define printm(fmt, args...)\ -do{\ - if(verbosity != QUIET)\ - printf("%s: " fmt, program_name , ##args); \ -} while(0) - -#define printv(fmt, args...)\ -do{\ - if(verbosity == VERBOSE)\ - printf("%s: " fmt, program_name , ##args); \ -} while(0) - -#define printe(fmt, args...)\ -fprintf(stderr, "%s: ERROR " fmt, program_name , ##args) - -#define print_err(fmt, args...)\ -fprintf(stderr, "%s: ERROR [%s:%d] " fmt, program_name, \ - __FILE__, __LINE__ , ##args) - -#define log_msg(fmt, args...)\ -do{\ - if(verbosity != QUIET)\ - syslog(LOG_NOTICE, fmt, ## args);\ -} while(0) - -#define log_verbose(fmt, args...)\ -do{\ - if(verbosity == VERBOSE)\ - syslog(LOG_NOTICE, fmt, ## args);\ -} while(0) - -#define log_always(fmt, args...) syslog(LOG_NOTICE, fmt, ##args) - -#define log_warn(fmt, args...)\ -do{\ - if(verbosity != QUIET)\ - syslog(LOG_NOTICE, "WARNING " fmt, ##args);\ -} while(0) - -/* FIXME -- I need a log_fail, so that I can differentiate between errors - that shouldn't happen, and expected errors that I need to log */ -#define log_err(fmt, args...)\ -syslog(LOG_ERR, "ERROR [%s:%d] " fmt, __FILE__, __LINE__ , ##args) - -#define log_fail(fmt, args...)\ -syslog(LOG_ERR, "ERROR " fmt, ##args) - -#define fail_startup(fmt, args...)\ -do {\ - printe(fmt, ##args);\ - log_err(fmt, ##args);\ - kill(program_pid, SIGUSR2); \ - exit(1);\ -} while(0) - - -#define finish_startup(fmt, args...)\ -do {\ - printm(fmt, ##args);\ - log_msg(fmt, ##args);\ - kill(program_pid, SIGUSR1);\ - close(STDIN_FILENO);\ - close(STDOUT_FILENO);\ - close(STDERR_FILENO);\ -} while(0) - -typedef uint32_t ip_t; -#define beip_to_cpu be32_to_cpu -#define cpu_to_beip cpu_to_be32 -char *beip_to_str(ip_t ip); - - - -int daemonize(void); -int get_my_nodename(char *buf, int is_clustered); -int __check_lock(char *file, int *pid); -int check_lock(char *file, int *pid); -int pid_lock(char *extra_info); -void daemonize_and_exit_parent(void); -int open_max(void); -int parse_server(char *buf, char *name, uint16_t *port); -char *get_sysfs_attr(int minor, char *attr_name); -char *do_get_sysfs_attr(int minor, char *attr_name); -int do_set_sysfs_attr(int minor_nr, char *attribute, char *val); -int __set_sysfs_attr(int minor_nr, char *attribute, char *val); -void set_sysfs_attr(int minor_nr, char *attribute, char *val); - -#endif /* __gnbd_utils_h__ */ diff --git a/gnbd/utils/trans.c b/gnbd/utils/trans.c deleted file mode 100644 index 69c849f..0000000 --- a/gnbd/utils/trans.c +++ /dev/null @@ -1,328 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <inttypes.h> -#include <netinet/in.h> -#include <netdb.h> - -#include "trans.h" -#include "gnbd_utils.h" -#include "gnbd_endian.h" - -int got_sighup = 0; - -void sig_hup(int sig) -{ - got_sighup = 1; -} - -/* I better be able to get away without checking errors here, because - the code get's a lot uglier it these can fail */ -sigset_t block_sigchld(void) -{ - sigset_t set, old; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, &old); - return old; -} - -void unblock_sigchld(void) -{ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_UNBLOCK, &set, NULL); -} - -sigset_t block_sighup(void) -{ - sigset_t set, old; - sigemptyset(&set); - sigaddset(&set, SIGHUP); - sigprocmask(SIG_BLOCK, &set, &old); - return old; -} - -void unblock_sighup(void) -{ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGHUP); - sigprocmask(SIG_UNBLOCK, &set, NULL); -} - -char *gstrerror(int errcode) -{ - switch(errcode){ - case GNBD_GOT_SIGHUP: - return "interruped by SIGHUP"; - case GNBD_GOT_EOF: - return "unexpectly reached EOF"; - default: - return strerror(errcode); - } -} - -int retry_read(int fd, void *buf, size_t count) -{ - int bytes; - void *ptr = buf; - - got_sighup = 0; - while(count){ - if (got_sighup){ - errno = GNBD_GOT_SIGHUP; - return -1; - } - bytes = read(fd, ptr, count); - if (bytes < 0){ - if (errno != EINTR) - return -1; - continue; - } - if (bytes == 0){ - errno = GNBD_GOT_EOF; - return -1; - } - ptr += bytes; - count -= bytes; - } - return 0; -} - -int retry_write(int fd, void *buf, size_t count) -{ - int bytes; - void *ptr = buf; - - got_sighup = 0; - while(count){ - if (got_sighup){ - errno = GNBD_GOT_SIGHUP; - return -1; - } - bytes = write(fd, ptr, count); - if (bytes < 0){ - if (errno != EINTR) - return -1; - continue; - } - if (bytes == 0){ - errno = GNBD_GOT_EOF; - return -1; - } - ptr += bytes; - count -= bytes; - } - return 0; -} - -int start_comm_device(char *name){ - int sock; - struct sockaddr_un addr; - struct stat stat_buf; - - if( (sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){ - log_err("cannot create unix socket : %s\n", strerror(errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, 108, "%s/%s", program_dir, name); - - if (stat(addr.sun_path, &stat_buf) < 0){ - if (errno != ENOENT){ - log_err("cannot stat unix socket file '%s' : %s\n", - addr.sun_path, strerror(errno)); - goto fail; - } - } - else if (unlink(addr.sun_path) < 0){ - log_err("cannot remove unix socket file '%s' : %s\n", - addr.sun_path, strerror(errno)); - goto fail; - } - - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0){ - log_err("cannot bind unix socket to '%s' : %s\n", addr.sun_path, - strerror(errno)); - goto fail; - } - - if (chmod(addr.sun_path, S_IRUSR | S_IWUSR) < 0){ - log_err("cannot set file permissions on unix socket '%s' : %s\n", - addr.sun_path, strerror(errno)); - goto fail; - } - - if (listen(sock, 1) < 0){ - log_err("cannot listen on unix socket '%s' : %s\n", - addr.sun_path, strerror(errno)); - goto fail; - } - - return sock; - - fail: - close(sock); - return -1; -} - - - -/* FIXME -- Are you ever called from a process that has stdout/err closed */ -int connect_to_comm_device(char *name) -{ - struct sockaddr_un server; - int sock_fd; - - sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock_fd < 0){ - printe("error creating socket: %s\n", strerror(errno)); - return -1; - } - server.sun_family = AF_UNIX; - snprintf(server.sun_path, 108, "%s/%scomm", program_dir, name); - server.sun_path[107] = 0; - if (connect(sock_fd, (struct sockaddr *)&server, sizeof(server)) < 0){ - close(sock_fd); - printe("error connecting to %s: %s\n", name, strerror(errno)); - return -1; - } - return sock_fd; -} - -int do_ipv4_connect(struct in_addr addr, uint16_t port) -{ - struct sockaddr_in server; - int fd; - - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -1; - server.sin_family = AF_INET; - server.sin_port = htons(port); - memcpy(&server.sin_addr, &addr, sizeof(server.sin_addr)); - - if (connect(fd, (struct sockaddr *)&server, sizeof(server)) < 0){ - close(fd); - return -1; - } - return fd; -} - -int do_ipv6_connect(struct in6_addr addr, uint16_t port) -{ - struct sockaddr_in6 server; - int fd; - - fd = socket(PF_INET6, SOCK_STREAM, 0); - if (fd < 0) - return -1; - server.sin6_family = AF_INET6; - server.sin6_port = htons(port); - server.sin6_flowinfo = 0; - memcpy(&server.sin6_addr, &addr, sizeof(server.sin6_addr)); - - if (connect(fd, (struct sockaddr *)&server, sizeof(server)) < 0){ - close(fd); - return -1; - } - return fd; -} - -/* FIXME -- for non-blocking reasons, I need to be able to set a timeout - on connections */ -/* FIXME -- I really need some macros so that I can print out messages - in and out of daemons */ -int connect_to_server(char *hostname, uint16_t port) -{ - int ret; - struct addrinfo *ai, *tmp; - - ret = getaddrinfo(hostname, NULL, NULL, &ai); - if (ret) - return ret; - for (tmp = ai; tmp; tmp = tmp->ai_next){ - if (tmp->ai_family != AF_INET6) - continue; - if (tmp->ai_socktype != SOCK_STREAM) - continue; - ret = do_ipv6_connect(((struct sockaddr_in6 *)tmp->ai_addr)->sin6_addr, - port); - if (ret >= 0){ - freeaddrinfo(ai); - return ret; - } - } - for (tmp = ai; tmp; tmp = tmp->ai_next){ - if (tmp->ai_family != AF_INET) - continue; - if (tmp->ai_socktype != SOCK_STREAM) - continue; - ret = do_ipv4_connect(((struct sockaddr_in *)tmp->ai_addr)->sin_addr, - port); - if (ret >= 0){ - freeaddrinfo(ai); - return ret; - } - } - freeaddrinfo(ai); - return -1; -} - -int send_cmd(int fd, uint32_t cmd, char *type) -{ - if (retry_write(fd, &cmd, sizeof(cmd)) < 0) { - printe("sending %s command failed : %s\n", type, gstrerror(errno)); - return -1; - } - return 0; -} - -int recv_reply(int fd, char *type) -{ - uint32_t reply; - - if (retry_read(fd, &reply, sizeof(reply)) < 0) { - printe("reading %s reply failed : %s\n", type, gstrerror(errno)); - return -1; - } - if (reply) - printe("%s request failed : %s\n", type, strerror(reply)); - return -reply; -} - -int send_u32(int fd, uint32_t msg) -{ - msg = cpu_to_be32(msg); - return retry_write(fd, &msg, sizeof(msg)); -} - -int recv_u32(int fd, uint32_t *msg) -{ - if (retry_read(fd, msg, sizeof(uint32_t)) < 0) - return -1; - *msg = be32_to_cpu(*msg); - return 0; -} diff --git a/gnbd/utils/trans.h b/gnbd/utils/trans.h deleted file mode 100644 index e023d44..0000000 --- a/gnbd/utils/trans.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __trans_h__ -#define __trans_h__ - -#include <signal.h> - -extern int got_sighup; - -void sig_hup(int sig); -sigset_t block_sigchld(); -void unblock_sigchld(); -sigset_t block_sighup(); -void unblock_sighup(); -int retry_read(int fd, void *buf, size_t count); -int retry_write(int fd, void *buf, size_t count); -char *gstrerror(int errcode); -int connect_to_comm_device(char *name); -int connect_to_server(char *hostname, uint16_t port); -int send_cmd(int fd, uint32_t cmd, char *type); -int recv_reply(int fd, char *type); -int send_u32(int fd, uint32_t msg); -int recv_u32(int fd, uint32_t *msg); -int start_comm_device(char *name); - -/* FIXME -- there are errno values.. should I do this differently */ -#define GNBD_GOT_SIGHUP 254 -#define GNBD_GOT_EOF 253 - -#endif /* __trans_h__ */ diff --git a/gulm/COPYING b/gulm/COPYING deleted file mode 100644 index 5b6e7c6..0000000 --- a/gulm/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. -
- GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) -
-These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. -
- 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -
- 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/gulm/Makefile b/gulm/Makefile deleted file mode 100644 index 840f471..0000000 --- a/gulm/Makefile +++ /dev/null @@ -1,149 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -include make/defines.mk -UNINSTALL=scripts/uninstall.pl - -#source lists. -gulmd_src = \ - src/config_ccs.c \ - src/config_cmdline.c \ - src/config_main.c \ - src/core_fence.c \ - src/core_io.c \ - src/core_main.c \ - src/core_nodelists.c \ - src/core_resources.c \ - src/hash.c \ - src/hashn.c \ - src/log.c \ - src/lock_io.c \ - src/lock_main.c \ - src/lock_space.c \ - src/ltpx_io.c \ - src/ltpx_main.c \ - src/ltpx_map.c \ - src/main_main.c \ - src/myio.c \ - src/nodel.c \ - src/utils_crc.c \ - src/utils_dir.c \ - src/utils_ip.c \ - src/utils_tostr.c \ - src/utils_verb_flags.c \ - src/xdr_base.c \ - src/xdr_io.c \ - src/xdr_socket.c - -lib_src = \ - lib/lg_core.c \ - lib/lg_lock.c \ - lib/lg_main.c \ - src/xdr_base.c \ - src/xdr_io.c \ - src/xdr_socket.c - -tool_src = \ - src/gulm_tool.c \ - src/utils_ip.c \ - src/utils_tostr.c \ - src/utils_verb_flags.c \ - src/xdr_base.c \ - src/xdr_io.c \ - src/xdr_socket.c - -# For debugging what gulm does to each lock. This makes gulmd suck up -# memory like you cannot believe, since it is saving the last n requests on -# every lock it ever sees. Only set this if you know how to use it. -# lock history data is in the SIGUSR1 lock dumps. -#CFLAGS+=-DLOCKHISTORY=6 - -INCLUDE+= -Isrc -I${incdir} - -LDFLAGS+= -L${libdir} -#LDLIBS+= -lwrap -lnsl - -CFLAGS+=$(INCLUDE) -# this is mostly for the lib. Does it hurt any having it for everyone? -CFLAGS+=-D_REENTRANT -fPIC -CFLAGS+=-g -O -CFLAGS+=-DRELEASE="$(RELEASE)" - -####################################### -# build rules - -all: src/lock_gulmd src/gulm_tool lib/libgulm.a lib/libgulm.so lib/libgulm.so.$(RELEASE_MAJOR) - -src/lock_gulmd: $(gulmd_src:.c=.o) - ${CC} ${CFLAGS} ${LDFLAGS} $^ ${LDLIBS} -lccs -pthread -o $@ - -lib/libgulm.a: $(lib_src:.c=.o) - ${AR} cr $@ $^ - -lib/libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR): $(lib_src:.c=.o) - ${LD} -shared -soname libgulm.so.$(RELEASE_MAJOR) -o $@ $^ -lc - -lib/libgulm.so.$(RELEASE_MAJOR): lib/libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) $@ - -lib/libgulm.so: lib/libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) $@ - -src/gulm_tool: $(tool_src:.c=.o) - ${CC} ${CFLAGS} ${LDFLAGS} $^ ${LDLIBS} -o $@ - -.c.o: - ${CC} ${CFLAGS} ${LDFLAGS} -c -o $@ $< - -clean: - find ./ -name '*.o' -print | xargs rm -f dummy - rm -f src/lock_gulmd src/gulm_tool lib/libgulm.a lib/libgulm.so* - -distclean: clean - rm -f make/defines.mk cscope.files cscope.out - -install: all - install -d ${sbindir} - install -m755 src/lock_gulmd src/gulm_tool ${sbindir} - install -d ${mandir}/man5 - install man/lock_gulmd.5 ${mandir}/man5 - install -d ${mandir}/man8 - install man/lock_gulmd.8 man/gulm_tool.8 ${mandir}/man8 - install -d ${libdir} - install -m644 lib/libgulm.a ${libdir} - cd ${libdir}; ln -snf libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libgulm.so.$(RELEASE_MAJOR); cd - - cd ${libdir}; ln -snf libgulm.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libgulm.so; cd - - install -m644 lib/libgulm.so ${libdir} - install -d ${incdir} - install -m644 lib/libgulm.h ${incdir} - cd init.d && ${MAKE} install - - -uninstall: - ${UNINSTALL} lock_gulmd gulm_tool ${sbindir} - ${UNINSTALL} lock_gulmd.5 ${mandir}/man5 - ${UNINSTALL} lock_gulmd.8 gulm_tool.8 ${mandir}/man8 - ${UNINSTALL} libgulm.a ${libdir} - ${UNINSTALL} libgulm.h ${incdir} - cd init.d && ${MAKE} uninstall - rm -f /lib/libgulm.* - -cscope cscope.out: $(gulmd_src) $(tool_src) $(lib_src) - @find ./ -name '*.[chlyCGHL]' -type f -print > cscope.files - @cscope -b - -dep depends: - ${CC} ${CFLAGS} ${LDFLAGS} -MM $(tool_src) $(lib_src) $(gulmd_src) > depends - -ifeq (depends, $(wildcard depends)) -include depends -endif diff --git a/gulm/configure b/gulm/configure deleted file mode 100755 index dd4d532..0000000 --- a/gulm/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/gulm/glv/Makefile b/gulm/glv/Makefile deleted file mode 100644 index a64b858..0000000 --- a/gulm/glv/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -LEX=flex -YACC=bison - -INCLUDE=-I../lib -LIBS=-L../lib -lgulm - -CFLAGS+=-g -O $(INCLUDE) - -all: glvd glvc - -glvc: glvc.c - $(CC) $(CFLAGS) $(LIBS) $^ -o $@ - -glvd: glvd.c glvd_parser.c glvd_scanner.c - $(CC) $(CFLAGS) $(LIBS) $^ -o $@ - -parsetest: glvd_parser.c glvd_scanner.c - $(CC) $(CFLAGS) $(LIBS) -DPARSETEST $^ -o $@ - -glvd_parser.c: glvd_parser.y - $(YACC) -d -o $@ glvd_parser.y - -glvd_scanner.c: glvd_scanner.l - $(LEX) -i -t glvd_scanner.l > $@ - -clean: - rm -f glvd_parser.[ch] glvd_scanner.c parsetest glvd glvc - diff --git a/gulm/glv/README b/gulm/glv/README deleted file mode 100644 index 372b2f0..0000000 --- a/gulm/glv/README +++ /dev/null @@ -1,31 +0,0 @@ -glv = gulm lock verify - -This is a tool to verify that the lock state machine in gulm is working. -This tool has its own server client system. The clients of glv are also -gulm services. (they link against libgulm) The server is started with a -test file, and a list of nodes. It sends out a command to start the client -on these nodes, where gulm is already up and running. It then walks -through the test file, making sure that it sees the results it expects. - -Tests don't specifiy which nodes to run on, instead they specifiy how many -they need. Nodes are all referenced by an index number. Then for the -actual run, the real node names on on the cmdline. - -Running a test is mostly just picking the test to run. Making sure you have -the require number of nodes. Starting lock_gulmd on all of them. Copying -glvc to each. Then running glvd with the name of the testfile and the node -names. - -If a test fails, the reason is sent to stderr, and glvd returns with 1. -Otherwise a success message gets printed to stdout, and glvd returns 0. - -glv can only work with what is returned. To really know things are -working, you should know what residue a test leaves behind, and investigate -the lock dump from the server to make sure it is correct. With that in -mind, it is worth the effort to make all tests unlock everything before -finishing. That way, if nothing else is running, the lockspace will be -empty. - -Also, all tests assume a clean lock space. So if a test is failing, -restart the lock servers first. - diff --git a/gulm/glv/glv.language b/gulm/glv/glv.language deleted file mode 100644 index 054d5f0..0000000 --- a/gulm/glv/glv.language +++ /dev/null @@ -1,79 +0,0 @@ -# this isn't quite BNF, should fix that. - -file: <defines> <tests> - -defines: nodecount - -nodecount: nodecount <number> - -tests: test tests - | test - -test: test <action> <reactions> end - -reactions: noreaction - | <reaction> <reactions> - | <reaction> - -reaction: lrpl - | arpl - | drop - -action: lock - | act - | cancel - | dropexp - -lock: lock <nodeidx> <subid> <keyname> <state> <flags> <lvb> -lock: lock <nodeidx> <subid> <keyname> [<start> <stop>] <state> <flags> <lvb> - -act: action <nodeidx> <subid> <keyname> <actname> <lvb> - -cancel: cancel <nodeidx> <subid> <keyname> - -dropexp: dropexp <nodeidx> <string> <keyname> - -lrpl: lrpl <nodeidx> <subid> <keyname> <state> <flags> <error> <lvb> -lrpl: lrpl <nodeidx> <subid> <keyname> [<start> <stop>] <state> <flags> <error> <lvb> - -arpl: arpl <nodeidx> <subid> <keyname> <actname> <error> - -drop: drop <nodeidx> <subid> <keyname> <state> - -nodeidx: <number> - -subid: <number> - -keyname: <string> - -lvb: nolvb - |<string> - -state: exclusive - | shared - | deferred - | unlock - -actname: holdlvb - | unholdlvb - | synclvb - -flags: noflags - | <iflg> - -iflg: <flag>|<iflg> - | <flag> - -flag: docb - | try - | any - | ignoreexp - | cachable - | piority - -error: ok - | tryfailed - | badstate - | canceled - | alreadypending -# ?others? diff --git a/gulm/glv/glv.wireproto b/gulm/glv/glv.wireproto deleted file mode 100644 index 5a18bf7..0000000 --- a/gulm/glv/glv.wireproto +++ /dev/null @@ -1,33 +0,0 @@ - -Logging in is the only tightly bound request/response action. -glvc> Hello <name>\n -glvd> HI\n - - -All the rest are fairly free form. Since the client is mostly just a -pass-through for stuff to gulm. - -glvd sends: - lock <subid> <key> <rstart> <rstop> <state> <flags> <lvb>\n - action <subid> <key> <action> <lvb>\n - cancel <subid> <key>\n - dropexp <nodename> <mask>\n - GOODBYE\n - -glvc send: - lrpl <subid> <key> <rstart> <rstop> <state> <flags> <error> <lvb>\n - arpl <subid> <key> <action> <error>\n - drop <subid> <key> <state>\n - GOODBYE\n - - -<subid> is [0-9] -<key> is [a-zA-Z0-9_] -<state> is [0-9] -<action> is [0-9] -<flags> is [0-9] -<nodename> is [a-zA-Z0-9_] -<mask> is [a-zA-Z0-9_] -<lvb> is either 'nolvb' or [a-zA-Z0-9_] -<error> is [0-9] - diff --git a/gulm/glv/glvc.c b/gulm/glv/glvc.c deleted file mode 100644 index 8919ed3..0000000 --- a/gulm/glv/glvc.c +++ /dev/null @@ -1,341 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <getopt.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <poll.h> -#include <netdb.h> - -#include "libgulm.h" - -#define TRUE (1) -#define FALSE (0) - -#define die(msg, args...) {fprintf(stderr, msg, ## args);exit(1);} -#define perr(msg, args...) fprintf(stderr, msg, ## args) -#define verb(level, msg, args...) {if(verbing >= level) {printf(msg, ## args);}} -/*************************************************************************/ -/* sometimes, globals are just easier. */ -gulm_interface_p hookup; -int masterSK = -1; -int running = TRUE; -int verbing = 0; - -/*************************************************************************/ - -int glv_core_login_reply(void *misc, uint64_t gen, uint32_t error, - uint32_t rank, uint8_t corestate) -{ - int err; - - if( error != 0 ) - die("Failed to loginto core %d\n", error); - - if( (err=lg_lock_login(hookup, "glv ")) != 0 ) - die("Failed to call lock login. %d\n", err); - - return 0; -} - -int glv_core_logout_reply(void *misc) -{ - return 0; -} - -int glv_core_error(void *misc, uint32_t err) -{ - die("Weird error in core %d\n", err); - return 0; -} - -static lg_core_callbacks_t core_ops = { -login_reply: glv_core_login_reply, -logout_reply: glv_core_logout_reply, -error: glv_core_error -}; -/*************************************************************************/ -int glv_lock_login_reply(void *misc, uint32_t error, uint8_t which) -{ - if( error != 0 ) - die("Failed to loginto lock %d\n"); - return 0; -} - -int glv_lock_state(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, uint8_t state, - uint32_t flags, uint32_t error, uint8_t *LVB, uint16_t LVBlen) -{ - char buffy[160]; - int actual, sid = (int)subid; - /* kinda a cheet here. */ - if( strlen(LVB) == 0 ) LVBlen = 0; - - actual = snprintf(buffy, 160, "lrpl %d %s %u %u %d %d %d %s\n", sid, key, - (unsigned int)start, (unsigned int)stop, - state, flags, error, LVBlen==0?"nolvb":(char*)LVB); - verb(3, "Sending to glvd: %s", buffy); - send(masterSK, buffy, actual, 0); - return 0; -} - -int glv_lock_action(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t action, uint32_t error) -{ - char buffy[160]; - int actual, sid = (int)subid; - actual = snprintf(buffy, 160, "arpl %d %s %d %d\n", - sid, key, action, error); - verb(3, "Sending to glvd: %s", buffy); - send(masterSK, buffy, actual, 0); - return 0; -} - -int glv_lock_drop_lock_req(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t state) -{ - char buffy[160]; - int actual, sid = (int)subid; - actual = snprintf(buffy, 160, "drop %d %s %d\n", sid, key, state); - verb(3, "Sending to glvd: %s", buffy); - send(masterSK, buffy, actual, 0); - return 0; -} - -int glv_lock_error(void *misc, uint32_t err) -{ - die("Weird error in lock %d\n", err); - return 0; -} - -static lg_lockspace_callbacks_t lock_ops = { -login_reply: glv_lock_login_reply, -lock_state: glv_lock_state, -lock_action: glv_lock_action, -drop_lock_req: glv_lock_drop_lock_req, -error: glv_lock_error -}; -/*************************************************************************/ - -void parse_action(int sk) -{ - char buffy[160], *key=NULL, *lvb=NULL; - int cnt, state, flags, subid, start, stop; - - if( (cnt=recv(sk, buffy, 160, 0)) <0) - die("read failed. %d\n"); - if(cnt == 0 ) { - verb(1,"EOF from glvd\n"); - running = FALSE; - return; - } - buffy[cnt-1] = '\0'; - verb(3, "Got from glvd: %s\n", buffy); - - if(sscanf(buffy, "lock %d %as %u %u %d %d %as", - &subid, &key, &start, &stop, &state, &flags, &lvb) == 7) { - if( strcmp(lvb, "nolvb") == 0 ) {free(lvb); lvb=NULL;} - verb(3, "Matched lock.\n"); - lg_lock_state_req(hookup, key, strlen(key)+1, subid, start, stop, - state, flags, lvb, lvb==NULL?0:(strlen(lvb)+1) ); - }else - if(sscanf(buffy, "action %d %as %d %as", &subid, &key, &state, &lvb) == 4) { - if( strcmp(lvb, "nolvb") == 0 ) {free(lvb); lvb=NULL;} - verb(3, "Matched action.\n"); - lg_lock_action_req(hookup, key, strlen(key)+1, subid, state, lvb, - lvb==NULL?0:(strlen(lvb)+1) ); - }else - if(sscanf(buffy, "cancel %d %as", &subid, &key) == 2) { - verb(3, "Matched cancel.\n"); - lg_lock_cancel_req(hookup, key, strlen(key)+1, subid); - }else - if(sscanf(buffy, "dropexp %as %as", &lvb, &key) == 2) { - verb(3, "Matched dropexp.\n"); - /* lvb here is really node name */ - lg_lock_drop_exp(hookup, lvb, key, strlen(key)+1); - }else - if(strcmp(buffy, "GOODBYE") == 0) { - running = FALSE; - }else - { - verb(3, "Nothing matched\n"); - } - - if( key != NULL ) free(key); - if( lvb != NULL ) free(lvb); -} - - -/*************************************************************************/ -/** - * connect_to_serv - - * @h: - * @p: - * - * - * Returns: int - */ -int connect_to_serv(char *h, char *p) -{ - struct sockaddr_in adr; - unsigned short port=20016;/* default */ - struct hostent *hent; - int sock, trueval=TRUE; - - if( p != NULL ) port = atoi(p); - - hent = gethostbyname(h); - if(!hent) return -1; - if(! hent->h_addr_list ) return -1; - - adr.sin_family = AF_INET; - adr.sin_addr.s_addr = *((int*)(hent->h_addr_list[0]));/*eeewww*/ - adr.sin_port = htons( port ); - - if( (sock = socket(AF_INET, SOCK_STREAM, 0))<0) - die("Failed to get sockmonkey\n"); - if( connect(sock, (struct sockaddr*)&adr, sizeof(struct sockaddr_in))<0) - die("Failed to attach sockmonkey\n"); - - return sock; -} - -/** - * login - - * @sk: - * @name: - * - * - * Returns: void - */ -void login(int sk, char *name) -{ - char buffy[80]; - int actual; - - actual = snprintf(buffy, 80, "Hello %s\n", name); - verb(3, "Sending to glvd: %s", buffy); - send(sk, buffy, actual, 0); - - if( (actual=recv(sk, buffy, 80, 0)) <0) - die("Failed to recv login reply %d\n", errno); - buffy[actual-1] = '\0'; - verb(3, "Got from glvd: %s\n", buffy); - - if( strcmp(buffy, "HI") != 0 ) - die("Got weird login reply: %s\n", buffy); -} - -/** - * usage - - * @oid: - * - * - * Returns: void - */ -void usage(void) -{ - char *strings[] = { - "Usage:\n", - "glvc <server> [<port>]\n", - "\n" - }; - int i; - for(i=0; strings[i] != NULL; i++) - printf("%s", strings[i]); - exit(0); -} - -/** - * main - - * @argc: - * @argv: - * - * - * Returns: int - */ -int main(int argc, char **argv) -{ - char hostname[64]; - struct pollfd polls[3]; /* server, core, lock */ - int err; - - if( argc < 2 || argc > 3 ) - usage(); - - if(gethostname(hostname, 64) <0) strcpy(hostname,"NOPNOP"); - - if( lg_initialize(&hookup, "", "glv") != 0 ) - die("Failed to initialize libgulm\b"); - - /* daemonize (cuz ssh is a turd otherwise) */ - errno=0; - if(fork() == 0) exit(0); - if(errno != 0) exit(1); - - /* connect to server */ - polls[0].fd = masterSK = connect_to_serv(argv[1], argv[2]); - polls[0].events = POLLIN; - login(polls[0].fd, hostname); - - /* connect to gulm core */ - /* connect to gulm lock */ - if( lg_core_login(hookup, FALSE) != 0 ) - die("Failed to call login to core\n"); - - lg_core_handle_messages(hookup, &core_ops, NULL); - - - polls[1].fd = lg_core_selector(hookup); - polls[1].events = POLLIN; - polls[2].fd = lg_lock_selector(hookup); - polls[2].events = POLLIN; - - /*poll*/ - while(running) { - if( (err = poll(polls, 3, -1)) <0) { - perr("poll err %d\n", errno); - } - if( polls[0].revents & POLLHUP ) { - verb(1, "Lost glvd\n"); - break; - } - if( polls[0].revents & POLLIN ) { - parse_action(polls[0].fd); - } - if( polls[1].revents & POLLIN ) { - lg_core_handle_messages(hookup, &core_ops, NULL); - } - if( polls[2].revents & POLLIN ) { - lg_lock_handle_messages(hookup, &lock_ops, NULL); - } - } - - close(polls[0].fd); - - lg_lock_logout(hookup); - lg_lock_handle_messages(hookup, &lock_ops, NULL); - lg_core_logout(hookup); - lg_core_handle_messages(hookup, &core_ops, NULL); - lg_release(hookup); -} -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/glv/glvd.c b/gulm/glv/glvd.c deleted file mode 100644 index 39b2522..0000000 --- a/gulm/glv/glvd.c +++ /dev/null @@ -1,587 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <getopt.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <poll.h> - -#include "glvd.h" - -#define TRUE (1) -#define FALSE (0) - -#define die(msg, args...) {fprintf(stderr, msg, ## args);exit(1);} -#define perr(msg, args...) fprintf(stderr, msg, ## args) -#define verb(level, msg, args...) {if(verbing >= level) {printf(msg, ## args);}} -/*************************************************************************/ -/* some globals. */ -char hostname[64]="\0"; -uint16_t serv_port = 20016; -int test = FALSE; -int verbing = 0; - -char *TestFile=NULL; -struct glv_testfile *Tests=NULL; - -char **Nodes=NULL; -int *NodeSKs=NULL; -int NodeCount=0; - -struct pollfd *polls; - -/*************************************************************************/ -/*************************************************************************/ - -int nodeidx_from_fd(int fd) -{ - int i; - for(i=0;i<NodeCount;i++) { - if( NodeSKs[i] == fd ) return i; - } - return -1; -} - -/** - * verify_reaction - - * @in: - * @reactions: - */ -void verify_reaction(struct glv_reaction *in, struct glv_test *running) -{ - int allmatched = 1, found = 0, errors = FALSE; - struct glv_reaction *tmp; - for(tmp = running->react; tmp != NULL; tmp = tmp->next) { - if( tmp->matched == 0 && - in->nodeidx == tmp->nodeidx && - in->subid == tmp->subid && - in->react == tmp->react && - strcmp(in->key, tmp->key) == 0 ) { - /* ok, does the rest ok? */ - - if( in->error != tmp->error ) { - perr("Expected error(%s) is not what we got(%s) on line %d\n", - errstring(tmp->error), errstring(in->error), tmp->line); - errors = TRUE; - } - if( in->state != tmp->state ) { - /* print incomming */ - perr("Expected state(%s) is not what we got(%s) on line %d\n", - statestrings(tmp->state), statestrings(in->state), tmp->line); - errors = TRUE; - } - if( in->flags != tmp->flags ) { - char temp[60]; - strcpy(temp, flagsstr(in->flags)); - perr("Expected flags(%s %#x) is not what we got(%s %#x) on line %d\n", - flagsstr(tmp->flags), tmp->flags, - temp, in->flags, - tmp->line); - errors = TRUE; - } - if( in->start != tmp->start ) { - perr("Expected start range(%u) is not what we got(%u) on line%d\n", - tmp->start, in->start, tmp->line); - errors = TRUE; - } - if( in->stop != tmp->stop ) { - perr("Expected stop range(%u) is not what we got(%u) on line%d\n", - tmp->stop, in->stop, tmp->line); - errors = TRUE; - } - if( in->lvb == NULL && tmp->lvb == NULL ) { - /* both NULL, things are ok. so a nop. */ - }else - if( in->lvb == NULL && tmp->lvb != NULL ) { - /* die */ - perr("Expected lvb(%s) but got nothing on line %d\n", - tmp->lvb, tmp->line); - errors = TRUE; - }else - if( in->lvb != NULL && tmp->lvb == NULL ) { - /* die */ - perr("Expected no lvb, but got(%s) on line %d\n", - in->lvb, tmp->line); - errors = TRUE; - }else - if( strcmp(in->lvb, tmp->lvb) != 0 ) { - /* die */ - perr("Expected lvb(%s) is not what we got(%s) on line %d\n", - tmp->lvb, in->lvb, tmp->line); - errors = TRUE; - } - - if( errors ) exit(1); - - tmp->matched = 1; - found = 1; - verb(1, "Matched reaction.\n"); - } - if( tmp->matched == 0 ) allmatched = 0; - } - - running->allmatched = allmatched; - - if( found ) return; - - /* print incomming */ - print_reaction(stderr, in); - die("Failed to find matching reaction in test on line %d\n", - running->line); -} - -/** - * check_reactions - - * @sk: - * @reactions: - */ -void check_reactions(int sk, struct glv_test *running) -{ - char buffy[160], key[60], lvb[60]; - struct glv_reaction incomming; - int cnt; - - memset(&incomming, 0, sizeof(struct glv_reaction)); - incomming.nodeidx = nodeidx_from_fd(sk); - if( incomming.nodeidx < 0 ) die("Cannot find sk %d in NodeSKs!!!\n", sk); - - if( (cnt=recv(sk, buffy, 160, 0)) <0) { - perr("Failed to read data from %s (%d)\n", Nodes[incomming.nodeidx], - errno); - return; - } - if( cnt == 0 ) { - die("EOF from glvc[%d]\n", incomming.nodeidx); - return; - } - buffy[cnt-1] = '\0'; - verb(3, "Got from glvc[%d]: %s\n", incomming.nodeidx, buffy); - - if(sscanf(buffy, "lrpl %d %s %u %u %d %d %d %s", - &incomming.subid, - key, &incomming.start, &incomming.stop, - &incomming.state, &incomming.flags, - &incomming.error, lvb) == 8) { - if( strcmp(lvb, "nolvb") == 0 ) { - incomming.lvb = NULL; - }else{ - incomming.lvb = lvb; - } - incomming.react = glv_lrpl; - incomming.key = key; - verify_reaction(&incomming, running); - }else - if(sscanf(buffy, "arpl %d %s %d %d", - &incomming.subid, - key, &incomming.state, &incomming.error) == 4 ) { - incomming.react = glv_arpl; - incomming.key = key; - verify_reaction(&incomming, running); - }else - if(sscanf(buffy, "drop %d %s %d", - &incomming.subid, key, - &incomming.state) == 3 ) { - incomming.react = glv_drop; - incomming.key = key; - verify_reaction(&incomming, running); - }else - if(strcmp(buffy, "GOODBYE" ) == 0 ) { - }else - { - perr("Garbage buffer follows.\n%s\n", buffy); - } - -} - -/** - * do_action - - * @action: - */ -void do_action(struct glv_action *action) -{ - char buffy[160]; - int actual; - switch(action->action) { - case glv_lock: - actual = snprintf(buffy, 160, "lock %d %s %u %u %d %d %s\n", - action->subid, - action->key, action->start, action->stop, - action->state, action->flags, - action->lvb==NULL?"nolvb":action->lvb); - verb(3, "Sending to glvc[%d] %s", action->nodeidx, buffy); - send(NodeSKs[action->nodeidx], buffy, actual, 0); - break; - case glv_act: - actual = snprintf(buffy, 160, "action %d %s %d %s\n", - action->subid, action->key, action->state, - action->lvb==NULL?"nolvb":action->lvb); - verb(3, "Sending to glvc[%d] %s", action->nodeidx, buffy); - send(NodeSKs[action->nodeidx], buffy, actual, 0); - break; - case glv_cancel: - actual = snprintf(buffy, 160, "cancel %d %s\n", - action->subid, action->key); - verb(3, "Sending to glvc[%d] %s", action->nodeidx, buffy); - send(NodeSKs[action->nodeidx], buffy, actual, 0); - break; - case glv_dropexp: - actual = snprintf(buffy, 160, "dropexp %s %s\n", - action->lvb, /* lvb here is overloaded. */ - action->key); - verb(3, "Sending to glvc[%d] %s", action->nodeidx, buffy); - send(NodeSKs[action->nodeidx], buffy, actual, 0); - break; - } -} - -/** - * run_test_run - - */ -void run_test_run(void) -{ - struct glv_test *running; - int err, i; - /* - * Basic test pass: - * send action to node at idx. - * wait at poll() for reactions - * ?warn if taking too long? - * No wait if no actions. - * (still should wait at poll for a second. jic) - * Next test block - * - * Any unexpected actions are reported and test stops. - * (glvd and glvc all stop) - */ - - for(running = Tests->tests; running != NULL; running = running->next) { - do_action(running->action); - - if( running->react == NULL ) continue; - /* should really run through the poll at least once to see if - * anything shows up. - */ - - while(running->allmatched == 0) { - - if((err=poll(polls, NodeCount+3, 5000))<0) { - perr("poll err %d\n", errno); - } - if(err == 0 ) { - verb(0, "Still waiting for reactions. test on line: %d\n", - running->line); - } - for(i=1; i < NodeCount +3; i++) { - if( polls[i].fd < 0 ) continue; - if( polls[i].revents & POLLIN ) { - check_reactions(polls[i].fd, running); - } - if( polls[i].revents & POLLHUP ) { - die("Crap, HUP on fd %d\n", polls[i].fd); - } - } - }/*while(running->allmatched == 0)*/ - - }/*for(...)*/ - - /* wonder if it would be smarter to liner here a moment or three, just - * in case something comes back? - */ - - for(i=0; i < NodeCount; i++ ) { - if( NodeSKs[i] < 0 ) continue; - send(NodeSKs[i], "GOODBYE\n", 8, 0); - } - - verb(0, "All tests completed.\n"); - -} - -/*************************************************************************/ -/** - * serv_listen - start listening to a port. - * - * Returns: socket file descriptor - */ -int serv_listen(void) -{ - int sk, trueint=TRUE; - struct sockaddr_in adr; - - if( (sk = socket(AF_INET, SOCK_STREAM, 0)) <0) - die("Failed to create socket\n"); - - if( setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int)) <0) - die("Failed to set sock option SO_REUSEADDR\n"); - - adr.sin_family = AF_INET; - adr.sin_addr.s_addr = INADDR_ANY; - adr.sin_port = htons( serv_port ); - - if( bind(sk, (struct sockaddr *)&adr, sizeof(struct sockaddr_in)) <0) - die("Could not bind\n"); - - if( listen(sk, 5) <0) die("Someone ripped off my ears\n"); - - return sk; -} - -/** - * setup_poll - - */ -void setup_poll(void) -{ - int i; - - polls = malloc(sizeof(struct pollfd) * NodeCount +3); - memset(polls, 0, sizeof(struct pollfd) * NodeCount +3); - for(i=0; i < NodeCount +3; i++) polls[i].fd = -1; - - polls[0].fd = serv_listen(); - polls[0].events = POLLIN; - -} - -/** - * startup_clients - - * - * this function needs work like you can't believe. - * - * <GVL_RSH> [<user>] <node> <GLVC_PATH> <glvd-hostname> - */ -void startup_clients(void) -{ - char buffy[160], *rsh, *user, *glvc; - int i, err; - rsh = getenv("GLV_RSH"); - if(rsh == NULL ) rsh = "ssh"; - glvc = getenv("GLVC_PATH"); - if( glvc == NULL ) glvc = "/root/bin/glvc"; - for(i=0; i < NodeCount; i++) { - snprintf(buffy, 160, "%s %s %s %s &", - rsh, Nodes[i], glvc, hostname); - verb(2, "calling system on %s\n", buffy); - if((err=system(buffy)) != 0 ) - die("error starting glvc: %d\n", err); - } -} - -/** - * do_login - - * @sk: - * - * - * Returns: int - */ -int do_login(int sk) -{ - char ibuf[80]; - char name[64]; - int n; - - if((n = recv(sk, ibuf, 80, 0))<0){ - close(sk); - return -1; - } - ibuf[n-1]='\0'; - if((n=sscanf(ibuf, "Hello %s", name)) != 1) { - perr("Failed to scan login req.\n"); - close(sk); - return -1; - } - for(n=0;n<NodeCount;n++) { - if( strcmp(name, Nodes[n]) == 0) { - NodeSKs[n] = sk; - send(sk, "HI\n", 3, 0); - return 0; - } - } - - perr("Someone named "%s" wanted to login, but that's noone we're " - "waiting for\n", name); - - close(sk); - return -1; -} - -void wait_for_clients(void) -{ - int err, i, sk; - int loggedin=0; - struct sockaddr_in adr; - /* poll with accept. - * and check login. - * We stick in here until all of the clients we expect are logged in. - */ - - while( loggedin != NodeCount ) { - - if( (err=poll(polls, NodeCount +3, 5000)) <0) { - perr("poll err %d\n", errno); - } - if( err == 0 ) { - verb(0,"Still waiting for clients to login.\n"); - } - if( polls[0].revents & POLLIN ) { - i = sizeof(struct sockaddr_in); - if((sk = accept(polls[0].fd, (struct sockaddr*)&adr, &i)) <0) - die("accept error: %d\n", errno); - /* we need thier name from them. - * then match that in the Nodes[] and save in NodeSKs[] - * and increment loggedin - */ - if( do_login(sk) == 0 ) { - loggedin++; - for(i=1; i < NodeCount +3 && polls[i].fd >= 0; i++); - if( i >= NodeCount +3) { - perr("Now spaces left in poll!?!?\n"); - }else{ - polls[i].fd = sk; - polls[i].events = POLLIN; - } - } - } - - /* should not actually get anything here yet. */ - for(i=1; i < NodeCount +3; i++) { - if( polls[i].fd < 0 ) continue; - if( polls[i].revents & POLLHUP ) { - die("Crap, lost fd %d\n", polls[i].fd); - } - } - - } - /* don't care if there are any others trying to connect to us anymore */ - close(polls[0].fd); - polls[0].fd = -1; - polls[0].events = 0; - - verb(0, "Ok, All clients have logged in, starting tests.\n"); -} - - - -/*************************************************************************/ -void usage(void) -{ - char *strings[] = { - "Usage:\n", - "glvd [options] testfile <nodes>\n", - "Options:\n", - " --version -V version info\n", - " --help -h this.\n", - " --test -t make sure the testfile parses.\n", - "\n", - NULL - }; - int i; - for(i=0; strings[i] != NULL; i++) - printf("%s", strings[i]); - exit(0); -} -static struct option long_options[]={ - {"version", 0, 0, 'V'}, - {"help", 0, 0, 'h'}, - {"myname", 1, 0, 'm'}, - {"port", 1, 0, 'p'}, - {"test", 0, 0, 't'} -}; -int parse_cmdline(int argc, char **argv) -{ - int c; - int option_index = 0; - while(1) { - - c = getopt_long(argc, argv, "m:p:tVh", long_options, &option_index); - if( c == -1 ) break; - - switch(c) { - case 0: - fprintf(stderr,"Bad programmer! You forgot to catch '%s' \n", - long_options[option_index].name); - exit(1); - break; - case 'V': - printf("This is the first version.\n"); - break; - case 'm': - strcpy(hostname, optarg); - break; - case 'p': - serv_port = atoi(optarg); - break; - case 'h': - usage(); - break; - case 't': - test = TRUE; - break; - case ':': - case '?': - fprintf(stderr, "Ambiguous options, see --help\n"); - exit(1); - default: - fprintf(stderr,"Bad programmer! You forgot to catch the %c flag\n", - c); - exit(1); - break; - } - - } - /* testfile and nodes should be left. */ - TestFile = strdup(argv[optind++]); - /* rest are nodes. */ - Nodes = malloc( sizeof(char *) * (argc - optind +1)); - NodeSKs = malloc( sizeof(int) * (argc - optind +1)); - for(NodeCount=0; optind < argc; NodeCount++) { - Nodes[NodeCount] = strdup(argv[optind++]); - } - Nodes[NodeCount] = NULL; - return 0; -} - -int main(int argc, char **argv) -{ - if(gethostname(hostname, 64) <0) strcpy(hostname,"NOPNOP"); - - /* parse cmdline */ - parse_cmdline(argc, argv); - - /* parse testfile */ - Tests = parse_file(TestFile, test?5:0); - if( Tests == NULL ) exit(1); - if(test) exit(0); - - if( NodeCount != Tests->nodecount ) - die("This test needs %d nodes, you only supplied %d\n", - Tests->nodecount, NodeCount); - - setup_poll(); - /* startup clients */ - startup_clients(); - wait_for_clients(); - - /* run test */ - run_test_run(); - - return 0; -} diff --git a/gulm/glv/glvd.h b/gulm/glv/glvd.h deleted file mode 100644 index d1b2e69..0000000 --- a/gulm/glv/glvd.h +++ /dev/null @@ -1,66 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -** -******************************************************************************* -******************************************************************************/ -#ifndef __glvd_h__ -#define __glvd_h__ -struct glv_action { - unsigned int line; - enum {glv_lock, glv_act, glv_cancel, glv_dropexp} action; - int nodeidx; - int subid; - char *key; - unsigned int start; - unsigned int stop; - int state; - int flags; - char *lvb; -}; -struct glv_reaction { - unsigned int line; - enum {glv_lrpl, glv_arpl, glv_drop} react; - int nodeidx; - int subid; - char *key; - unsigned int start; - unsigned int stop; - int state; - int flags; - int error; - char *lvb; - - int matched; - struct glv_reaction *next; -}; -struct glv_test { - unsigned int line; - struct glv_action *action; - struct glv_reaction *react; - int allmatched; - - struct glv_test *next; -}; - -struct glv_testfile { - int nodecount; - struct glv_test *tests; -}; - - -struct glv_testfile *parse_file(char *fl, int verbosy); -char *statestrings(int s); -char *errstring(int e); -char *flagsstr(int f); -void print_action(FILE *fp, struct glv_action *action); -void print_reaction(FILE *fp, struct glv_reaction *ract); - -#endif /*__glvd_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/glv/glvd_parser.y b/gulm/glv/glvd_parser.y deleted file mode 100644 index 75f4871..0000000 --- a/gulm/glv/glvd_parser.y +++ /dev/null @@ -1,565 +0,0 @@ -%{ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -** -******************************************************************************* -******************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <stdint.h> -#include <netinet/in.h> - -#include "libgulm.h" -#include "glvd.h" - -extern char *yytext; -extern FILE *yyin; -extern int linenumber; -int errors=0; - -struct glv_testfile *root=NULL; - -int yyerror(char*); -int yylex(); - -%} - -%union -{ - int num; - char *str; - struct glv_test *test; - struct glv_action *action; - struct glv_reaction *react; -} - -%token NODECOUNT - -%token OK -%token TRYFAILED -%token CANCELED -%token BADSTATE -%token ALREADYPENDING - -%token TEST -%token END -%token LRPL -%token ARPL -%token DROPEXP -%token DROP -%token LOCK -%token ACTION -%token CANCEL -%token NOREACTION - -%token NOLVB - -%token EXCLUSIVE -%token SHARED -%token DEFERRED -%token UNLOCK - -%token HOLDLVB -%token UNHOLDLVB -%token SYNCLVB - -%token NOFLAGS -%token DOCB -%token NOCB -%token TRY -%token ANY -%token IGNOREEXP -%token CACHABLE -%token PIORITY -%token FLAGOR - -%token LSBRACE -%token RSBRACE - -%token <str> STRING -%token <num> NUMBER - -%type <test> test -%type <test> tests -%type <action> action -%type <react> reaction -%type <react> reactions -%type <num> nodeidx -%type <num> subid -%type <str> lvb -%type <num> state -%type <num> actname -%type <num> flags -%type <num> iflags -%type <num> flag -%type <num> errorcode - -%start testfile -%% - -testfile : defines tests - ; - -defines : defines define - | define - ; -define : nodecount - ; - -nodecount : NODECOUNT NUMBER - { root->nodecount = $2; } - ; - -/* chain these onto the end of the list. - * keeps the list in the same order as the file. - * which given what we're doing is rather important. - */ -tests : tests test - { - $1->next = $2; - $$ = $2; - } - | test - { root->tests = $1; } - ; - -test : TEST action reactions END - { struct glv_test *tmp; - tmp = malloc(sizeof(struct glv_test)); - tmp->line = linenumber; - tmp->action = $2; - tmp->react = $3; - tmp->allmatched = 0; - tmp->next = NULL; - $$ = tmp; - } - ; - -action : LOCK nodeidx subid STRING state flags lvb - { struct glv_action *tmp; - tmp = malloc(sizeof(struct glv_action)); - tmp->line = linenumber; - tmp->action = glv_lock; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = 0; - tmp->stop = ~0; - tmp->state = $5; - tmp->flags = $6; - tmp->lvb = $7; - $$ = tmp; - } - | LOCK nodeidx subid STRING LSBRACE NUMBER NUMBER RSBRACE state flags lvb - { struct glv_action *tmp; - tmp = malloc(sizeof(struct glv_action)); - tmp->line = linenumber; - tmp->action = glv_lock; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = $6; - tmp->stop = $7; - tmp->state = $9; - tmp->flags = $10; - tmp->lvb = $11; - $$ = tmp; - } - | ACTION nodeidx subid STRING actname lvb - { struct glv_action *tmp; - tmp = malloc(sizeof(struct glv_action)); - tmp->line = linenumber; - tmp->action = glv_act; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = 0; - tmp->stop = 0; - tmp->state = $5; - tmp->flags = 0; - tmp->lvb = $6; - $$ = tmp; - } - | CANCEL nodeidx subid STRING - { struct glv_action *tmp; - tmp = malloc(sizeof(struct glv_action)); - tmp->line = linenumber; - tmp->action = glv_cancel; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = 0; - tmp->stop = 0; - tmp->state = 0; - tmp->flags = 0; - tmp->lvb = NULL; - $$ = tmp; - } - | DROPEXP nodeidx STRING STRING - { struct glv_action *tmp; - tmp = malloc(sizeof(struct glv_action)); - tmp->line = linenumber; - tmp->action = glv_dropexp; - tmp->nodeidx = $2; - tmp->subid = 0; - tmp->key = $3; - tmp->start = 0; - tmp->stop = 0; - tmp->state = 0; - tmp->flags = 0; - tmp->lvb = $4; - $$ = tmp; - } - ; - -reactions : reactions reaction - { - $2->next = $1; - $$ = $2; - } - | reaction - | NOREACTION - { $$ = NULL; } - ; -reaction : LRPL nodeidx subid STRING state flags errorcode lvb - { struct glv_reaction *tmp; - tmp = malloc(sizeof(struct glv_reaction)); - tmp->line = linenumber; - tmp->react = glv_lrpl; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = 0; - tmp->stop = ~0; - tmp->state = $5; - tmp->flags = $6; - tmp->error = $7; - tmp->lvb = $8; - tmp->matched = 0; - tmp->next = NULL; - $$ = tmp; - } - | LRPL nodeidx subid STRING LSBRACE NUMBER NUMBER RSBRACE state flags errorcode lvb - { struct glv_reaction *tmp; - tmp = malloc(sizeof(struct glv_reaction)); - tmp->line = linenumber; - tmp->react = glv_lrpl; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = $6; - tmp->stop = $7; - tmp->state = $9; - tmp->flags = $10; - tmp->error = $11; - tmp->lvb = $12; - tmp->matched = 0; - tmp->next = NULL; - $$ = tmp; - } - | ARPL nodeidx subid STRING actname errorcode - { struct glv_reaction *tmp; - tmp = malloc(sizeof(struct glv_reaction)); - tmp->line = linenumber; - tmp->react = glv_arpl; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = 0; - tmp->stop = 0; - tmp->state = $5; - tmp->flags = 0; - tmp->error = $6; - tmp->lvb = NULL; - tmp->matched = 0; - tmp->next = NULL; - $$ = tmp; - } - | DROP nodeidx subid STRING state - { struct glv_reaction *tmp; - tmp = malloc(sizeof(struct glv_reaction)); - tmp->line = linenumber; - tmp->react = glv_drop; - tmp->nodeidx = $2; - tmp->subid = $3; - tmp->key = $4; - tmp->start = 0; - tmp->stop = 0; - tmp->state = $5; - tmp->flags = 0; - tmp->error = 0; - tmp->lvb = NULL; - tmp->matched = 0; - tmp->next = NULL; - $$ = tmp; - } - ; - -nodeidx : NUMBER - ; - -subid : NUMBER - ; - -state : EXCLUSIVE - { $$ = lg_lock_state_Exclusive; } - | SHARED - { $$ = lg_lock_state_Shared; } - | DEFERRED - { $$ = lg_lock_state_Deferred; } - | UNLOCK - { $$ = lg_lock_state_Unlock; } - ; - -actname : HOLDLVB - { $$ = lg_lock_act_HoldLVB; } - | UNHOLDLVB - { $$ = lg_lock_act_UnHoldLVB; } - | SYNCLVB - { $$ = lg_lock_act_SyncLVB; } - ; - -lvb : NOLVB - { $$ = NULL; } - | STRING - ; - -flags : NOFLAGS - { $$ = 0; } - | iflags - ; -iflags : iflags FLAGOR flag - { $$ = $1 | $3; } - | flag - ; -flag : DOCB - { $$ = lg_lock_flag_DoCB; } - | NOCB - { $$ = lg_lock_flag_NoCallBacks; } - | TRY - { $$ = lg_lock_flag_Try; } - | ANY - { $$ = lg_lock_flag_Any; } - | IGNOREEXP - { $$ = lg_lock_flag_IgnoreExp; } - | CACHABLE - { $$ = lg_lock_flag_Cachable; } - | PIORITY - { $$ = lg_lock_flag_Piority; } - ; - -errorcode : OK - { $$ = lg_err_Ok; } - | TRYFAILED - { $$ = lg_err_TryFailed; } - | BADSTATE - { $$ = lg_err_BadStateChg; } - | CANCELED - { $$ = lg_err_Canceled; } - | ALREADYPENDING - { $$ = lg_err_AlreadyPend; } - ; - -%% - -char *statestrings(int s) -{ - switch(s) { - case lg_lock_state_Exclusive: return "exclusive"; break; - case lg_lock_state_Shared: return "shared"; break; - case lg_lock_state_Deferred: return "deferred"; break; - case lg_lock_state_Unlock: return "unlock"; break; - case lg_lock_act_HoldLVB: return "holdlvb"; break; - case lg_lock_act_UnHoldLVB: return "unholdlvb"; break; - case lg_lock_act_SyncLVB: return "synclvb"; break; - } -} -char *errstring(int e) -{ - switch(e) { - case lg_err_Ok: return "ok"; break; - case lg_err_TryFailed: return "tryfailed"; break; - case lg_err_BadStateChg: return "badstate"; break; - case lg_err_Canceled: return "canceled"; break; - case lg_err_AlreadyPend: return "alreadypeding"; break; - } -} -char *flagsstr(int f) -{ - static char buffy[64]; - int l; - buffy[0] = '\0'; - if( f & lg_lock_flag_Try) strcat(buffy, "try|"); - if( f & lg_lock_flag_DoCB ) strcat(buffy, "docb|"); - if( f & lg_lock_flag_NoCallBacks) strcat(buffy, "nocb|"); - if( f & lg_lock_flag_Any) strcat(buffy, "any|"); - if( f & lg_lock_flag_IgnoreExp) strcat(buffy, "ignoreexp|"); - if( f & lg_lock_flag_Cachable) strcat(buffy, "cachable|"); - if( f & lg_lock_flag_Piority) strcat(buffy, "piority|"); - l = strlen(buffy); - if( l == 0 ) strcpy(buffy, "noflags"); - if( buffy[l-1] == '|' ) buffy[l-1] = '\0'; - - return buffy; -} - -void print_action(FILE *fp, struct glv_action *action) -{ - switch(action->action) { - case glv_lock: - if( action->start != 0 || action->stop != ~0 ) { - fprintf(fp, " lock %d %d %s [%u %u] %s %s %s\n", action->nodeidx, - action->subid, action->key, - action->start, action->stop, - statestrings(action->state), - flagsstr(action->flags), - action->lvb==NULL?"nolvb":action->lvb); - }else{ - fprintf(fp, " lock %d %d %s %s %s %s\n", action->nodeidx, - action->subid, - action->key, statestrings(action->state), - flagsstr(action->flags), - action->lvb==NULL?"nolvb":action->lvb); - } - break; - case glv_act: - fprintf(fp, " action %d %d %s %s %s\n", action->nodeidx, - action->subid, - action->key, statestrings(action->state), - action->lvb==NULL?"nolvb":action->lvb); - break; - case glv_cancel: - fprintf(fp, " cancel %d %d %s\n", action->nodeidx, - action->subid, action->key); - break; - case glv_dropexp: - fprintf(fp, " dropexp %d %s %s\n", action->nodeidx, - action->key, - action->lvb==NULL?"nolvb":action->lvb); - break; - } -} - -void print_reaction(FILE *fp, struct glv_reaction *ract) -{ - switch(ract->react) { - case glv_lrpl: - if( ract->start != 0 || ract->stop != ~0 ) { - fprintf(fp, " lrpl %d %d %s [%u %u] %s %s %s %s\n", ract->nodeidx, - ract->subid, ract->key, - ract->start, ract->stop, - statestrings(ract->state), - flagsstr(ract->flags), errstring(ract->error), - ract->lvb==NULL?"nolvb":ract->lvb); - }else{ - fprintf(fp, " lrpl %d %d %s %s %s %s %s\n", ract->nodeidx, - ract->subid, - ract->key, statestrings(ract->state), - flagsstr(ract->flags), errstring(ract->error), - ract->lvb==NULL?"nolvb":ract->lvb); - } - break; - case glv_arpl: - fprintf(fp, " arpl %d %d %s %s %s\n", ract->nodeidx, - ract->subid, - ract->key, statestrings(ract->state), - errstring(ract->error)); - break; - case glv_drop: - fprintf(fp, " drop %d %d %s %s\n", ract->nodeidx, - ract->subid, - ract->key, statestrings(ract->state)); - break; - } -} - -void show_it(void) -{ - struct glv_test *tst; - struct glv_reaction *ract; - - printf("nodecount %d\n", root->nodecount); - - for(tst=root->tests; tst != NULL; tst = tst->next) { - printf("test\n"); - print_action(stdout, tst->action); - if( tst->react == NULL ) { - printf(" noreaction\n"); - }else{ - for(ract=tst->react; ract != NULL; ract = ract->next ) { - print_reaction(stdout, ract); - } - } - printf("end\n\n"); - } -} - -#ifdef PARSETEST -int main(int argc, char **argv) -{ - argc--; argv++; - if (argc > 0) - yyin = fopen(argv[0],"r"); - else - yyin = stdin; - - root = malloc(sizeof(struct glv_testfile)); - root->nodecount = 0; - root->tests = NULL; - - yyparse(); - - fclose(yyin); - - if( errors != 0) - fprintf(stderr, "There were %d errors found in '%s'\n",errors,argv[0]); - else - show_it(); - - return 0; -} -#else /*PARSETEST*/ -struct glv_testfile *parse_file(char *fl, int verbosy) -{ - if(strncmp("-", fl, 1)==0) - yyin = stdin; - else - yyin = fopen(fl, "r"); - - root = malloc(sizeof(struct glv_testfile)); - root->nodecount = 0; - root->tests = NULL; - - yyparse(); - - fclose(yyin); - - if(errors != 0) { - fprintf(stderr," %d Errors were found.\n", errors); - return NULL; - }else { - if(verbosy > 4) show_it(); - return root; - } -} - -#endif /*PARSETEST*/ - -int yyerror (char *mesg) -{ - errors++; - fprintf(stderr,"Error found in line %d\n",linenumber); - fprintf(stderr," %s\n",mesg); - return 0; -} - -/* vim: set ai et sw=3 ts=3 : */ diff --git a/gulm/glv/glvd_scanner.l b/gulm/glv/glvd_scanner.l deleted file mode 100644 index 5d3e12c..0000000 --- a/gulm/glv/glvd_scanner.l +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -** -******************************************************************************* -******************************************************************************/ - -%{ -#include <stdio.h> -#include <string.h> -#include "glvd_parser.h" - int yyerror(char*); - void lex_cpy_lexme (void); - int linenumber=1; -#define YY_NO_UNPUT - -%} - -%x COMMENT - -%% - -# { BEGIN COMMENT; } -<COMMENT>\n { linenumber++; BEGIN 0; } -<COMMENT>. {} - -nodecount { return NODECOUNT; } - -ok { return OK; } -tryfailed { return TRYFAILED; } -canceled { return CANCELED; } -badstate { return BADSTATE; } -alreadypending { return ALREADYPENDING; } - -test { return TEST; } -end { return END; } -lrpl { return LRPL; } -arpl { return ARPL; } -dropexp { return DROPEXP; } -drop { return DROP; } -lock { return LOCK; } -action { return ACTION; } -cancel { return CANCEL; } -noreaction { return NOREACTION; } - -nolvb { return NOLVB; } - -exclusive { return EXCLUSIVE; } -shared { return SHARED; } -deferred { return DEFERRED; } -unlock { return UNLOCK; } -holdlvb { return HOLDLVB; } -unholdlvb { return UNHOLDLVB; } -synclvb { return SYNCLVB; } - -noflags { return NOFLAGS; } -docb { return DOCB; } -nocb { return NOCB; } -try { return TRY; } -any { return ANY; } -ignoreexp { return IGNOREEXP; } -cachable { return CACHABLE; } -piority { return PIORITY; } - -| { return FLAGOR; } - -[ { return LSBRACE; } -] { return RSBRACE; } - -[0-9]+ { yylval.num = atoi(yytext); return NUMBER; } - -[a-zA-Z0-9_]+ { yylval.str = strdup(yytext); return STRING; } -[ \t] {} -\n {linenumber++;} - -%% - -int yywrap(void) { return 1; } - diff --git a/gulm/glv/tests/anyflag.glv b/gulm/glv/tests/anyflag.glv deleted file mode 100644 index 1d4c78c..0000000 --- a/gulm/glv/tests/anyflag.glv +++ /dev/null @@ -1,51 +0,0 @@ -# grab shared -# ask for deferred with any -# unlock all -# grab deferred -# ask for shared with any -# unlock all - -nodecount 2 - - -test - lock 0 0 theanyflag shared noflags nolvb - lrpl 0 0 theanyflag shared cachable ok nolvb -end - -test - lock 1 0 theanyflag deferred any nolvb - lrpl 1 0 theanyflag shared any|cachable ok nolvb -end - -test - lock 1 0 theanyflag unlock noflags nolvb - lrpl 1 0 theanyflag unlock noflags ok nolvb -end - -test - lock 0 0 theanyflag unlock noflags nolvb - lrpl 0 0 theanyflag unlock noflags ok nolvb -end - -# -test - lock 0 0 theanyflag deferred noflags nolvb - lrpl 0 0 theanyflag deferred cachable ok nolvb -end - -test - lock 1 0 theanyflag shared any nolvb - lrpl 1 0 theanyflag deferred any|cachable ok nolvb -end - -test - lock 1 0 theanyflag unlock noflags nolvb - lrpl 1 0 theanyflag unlock noflags ok nolvb -end - -test - lock 0 0 theanyflag unlock noflags nolvb - lrpl 0 0 theanyflag unlock noflags ok nolvb -end - diff --git a/gulm/glv/tests/basiclockconflict.glv b/gulm/glv/tests/basiclockconflict.glv deleted file mode 100644 index 1e5156b..0000000 --- a/gulm/glv/tests/basiclockconflict.glv +++ /dev/null @@ -1,40 +0,0 @@ -# This test checks how two nodes asking for the same exlcusive lock with -# various flags and stuff. -nodecount 2 - -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - -test - lock 1 0 testlock exclusive try nolvb - lrpl 1 0 testlock exclusive try tryfailed nolvb -end - -test - lock 1 0 testlock exclusive try|docb nolvb - lrpl 1 0 testlock exclusive try|docb tryfailed nolvb - drop 0 0 testlock exclusive -end - -test - lock 1 0 testlock shared noflags nolvb - drop 0 0 testlock shared -end - -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb - lrpl 1 0 testlock shared cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -test - lock 1 0 testlock unlock noflags nolvb - lrpl 1 0 testlock unlock noflags ok nolvb -end diff --git a/gulm/glv/tests/basiclvb.glv b/gulm/glv/tests/basiclvb.glv deleted file mode 100644 index 89b8d28..0000000 --- a/gulm/glv/tests/basiclvb.glv +++ /dev/null @@ -1,57 +0,0 @@ -# just push a lvb around a bit - -nodecount 1 - -test - action 0 0 testlvb holdlvb nolvb - arpl 0 0 testlvb holdlvb ok -end - -# LVB is not writen here. -test - lock 0 0 testlvb exclusive noflags this_is_a_lvb - lrpl 0 0 testlvb exclusive cachable ok nolvb -end - -# But here. (when you *leave* exclusive.) -test - lock 0 0 testlvb unlock noflags this_is_a_lvb - lrpl 0 0 testlvb unlock noflags ok nolvb -end - -# so if we grab it again... -test - lock 0 0 testlvb shared noflags nolvb - lrpl 0 0 testlvb shared cachable ok this_is_a_lvb -end - -test - action 0 0 testlvb unholdlvb nolvb - arpl 0 0 testlvb unholdlvb ok -end - -test - lock 0 0 testlvb unlock noflags nolvb - lrpl 0 0 testlvb unlock noflags ok nolvb -end - -# now lets grab it, without the hold -test - lock 0 0 testlvb exclusive noflags nolvb - lrpl 0 0 testlvb exclusive cachable ok nolvb -end -# we can send a lvb, but it won't write. -test - lock 0 0 testlvb unlock noflags this_is_a_lvb - lrpl 0 0 testlvb unlock noflags ok nolvb -end -# so if we grab it again this way... -test - lock 0 0 testlvb shared noflags nolvb - lrpl 0 0 testlvb shared cachable ok nolvb -end - -test - lock 0 0 testlvb unlock noflags nolvb - lrpl 0 0 testlvb unlock noflags ok nolvb -end diff --git a/gulm/glv/tests/basicranges.glv b/gulm/glv/tests/basicranges.glv deleted file mode 100644 index 76b1618..0000000 --- a/gulm/glv/tests/basicranges.glv +++ /dev/null @@ -1,101 +0,0 @@ -# simple are ranges working test. -# shows that one node can do things and it all works. -# (grabbing sub ranges. mass unlocking. xmoting portions of locks.) -nodecount 1 - -test - lock 0 0 firstlock [0 2000] exclusive noflags nolvb - lrpl 0 0 firstlock [0 2000] exclusive cachable ok nolvb -end - -test - lock 0 0 firstlock [0 2000] unlock noflags nolvb - lrpl 0 0 firstlock [0 2000] unlock noflags ok nolvb -end - -# two seperate ranges -test - lock 0 0 seperateranges [0 200] exclusive noflags nolvb - lrpl 0 0 seperateranges [0 200] exclusive cachable ok nolvb -end - -test - lock 0 0 seperateranges [222 2000] exclusive noflags nolvb - lrpl 0 0 seperateranges [222 2000] exclusive cachable ok nolvb -end - -# single unlock -test - lock 0 0 seperateranges [0 2000] unlock noflags nolvb - lrpl 0 0 seperateranges [0 2000] unlock noflags ok nolvb -end - -# xmote the right side. -test - lock 0 0 rightside [0 2000] exclusive noflags nolvb - lrpl 0 0 rightside [0 2000] exclusive cachable ok nolvb -end - -test - lock 0 0 rightside [1000 3000] shared noflags nolvb - lrpl 0 0 rightside [1000 3000] shared cachable ok nolvb -end - -test - lock 0 0 rightside unlock noflags nolvb - lrpl 0 0 rightside unlock noflags ok nolvb -end - -# xmote the left side. -test - lock 0 0 leftside [0 2000] shared noflags nolvb - lrpl 0 0 leftside [0 2000] shared cachable ok nolvb -end - -test - lock 0 0 leftside [0 1000] exclusive noflags nolvb - lrpl 0 0 leftside [0 1000] exclusive cachable ok nolvb -end - -test - lock 0 0 leftside unlock noflags nolvb - lrpl 0 0 leftside unlock noflags ok nolvb -end - -# xmote the middle. -test - lock 0 0 themiddle [0 3000] deferred noflags nolvb - lrpl 0 0 themiddle [0 3000] deferred cachable ok nolvb -end - -test - lock 0 0 themiddle [500 2000] shared noflags nolvb - lrpl 0 0 themiddle [500 2000] shared cachable ok nolvb -end - -test - lock 0 0 themiddle unlock noflags nolvb - lrpl 0 0 themiddle unlock noflags ok nolvb -end - -# just for smiles. -test - lock 0 0 smiles [5 5] deferred noflags nolvb - lrpl 0 0 smiles [5 5] deferred cachable ok nolvb -end - -test - lock 0 0 smiles [10 10] shared noflags nolvb - lrpl 0 0 smiles [10 10] shared cachable ok nolvb -end - -test - lock 0 0 smiles [15 15] exclusive noflags nolvb - lrpl 0 0 smiles [15 15] exclusive cachable ok nolvb -end - -test - lock 0 0 smiles unlock noflags nolvb - lrpl 0 0 smiles unlock noflags ok nolvb -end - diff --git a/gulm/glv/tests/basicsubid.glv b/gulm/glv/tests/basicsubid.glv deleted file mode 100644 index 7b9fa1c..0000000 --- a/gulm/glv/tests/basicsubid.glv +++ /dev/null @@ -1,36 +0,0 @@ -# super simple test to show that we can grab locks with different subids. -# Then we show that we can grab the same lock twice just by changing the -# sub id. -nodecount 1 - -test - lock 0 42 testlock exclusive noflags nolvb - lrpl 0 42 testlock exclusive cachable ok nolvb -end - -test - lock 0 42 testlock unlock noflags nolvb - lrpl 0 42 testlock unlock noflags ok nolvb -end - -# ok, now multiple with diff sids. -test - lock 0 42 testlock shared noflags nolvb - lrpl 0 42 testlock shared cachable ok nolvb -end - -test - lock 0 66 testlock shared noflags nolvb - lrpl 0 66 testlock shared cachable ok nolvb -end - -test - lock 0 42 testlock unlock noflags nolvb - lrpl 0 42 testlock unlock noflags ok nolvb -end - -test - lock 0 66 testlock unlock noflags nolvb - lrpl 0 66 testlock unlock noflags ok nolvb -end - diff --git a/gulm/glv/tests/basicsubidconf.glv b/gulm/glv/tests/basicsubidconf.glv deleted file mode 100644 index 6cb6425..0000000 --- a/gulm/glv/tests/basicsubidconf.glv +++ /dev/null @@ -1,39 +0,0 @@ -# like basiclockconflict.glv, but with one node and subids. -nodecount 1 - -test - lock 0 42 testlock exclusive noflags nolvb - lrpl 0 42 testlock exclusive cachable ok nolvb -end - -test - lock 0 66 testlock exclusive try nolvb - lrpl 0 66 testlock exclusive try tryfailed nolvb -end - -test - lock 0 66 testlock exclusive try|docb nolvb - lrpl 0 66 testlock exclusive try|docb tryfailed nolvb - drop 0 42 testlock exclusive -end - -test - lock 0 66 testlock shared noflags nolvb - drop 0 42 testlock shared -end - -test - lock 0 42 testlock shared noflags nolvb - lrpl 0 42 testlock shared cachable ok nolvb - lrpl 0 66 testlock shared cachable ok nolvb -end - -test - lock 0 42 testlock unlock noflags nolvb - lrpl 0 42 testlock unlock noflags ok nolvb -end - -test - lock 0 66 testlock unlock noflags nolvb - lrpl 0 66 testlock unlock noflags ok nolvb -end diff --git a/gulm/glv/tests/basictest.glv b/gulm/glv/tests/basictest.glv deleted file mode 100644 index cca0333..0000000 --- a/gulm/glv/tests/basictest.glv +++ /dev/null @@ -1,35 +0,0 @@ -# nice simple one node test to make sure that glv isn't too far off. -# also nice for checking return flags of basic ops. -nodecount 1 - -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -test - lock 0 0 testlock deferred noflags nolvb - lrpl 0 0 testlock deferred cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - - diff --git a/gulm/glv/tests/basicxmote.glv b/gulm/glv/tests/basicxmote.glv deleted file mode 100644 index 2fdd466..0000000 --- a/gulm/glv/tests/basicxmote.glv +++ /dev/null @@ -1,100 +0,0 @@ -# how well do we move from one state to another. -nodecount 1 - -#exl => shr -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -#exl =>dfr -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - -test - lock 0 0 testlock deferred noflags nolvb - lrpl 0 0 testlock deferred cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -#dfr => shr -test - lock 0 0 testlock deferred noflags nolvb - lrpl 0 0 testlock deferred cachable ok nolvb -end - -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -#shr => dfr -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb -end - -test - lock 0 0 testlock deferred noflags nolvb - lrpl 0 0 testlock deferred cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -#shr => exl -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb -end - -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -#dfr => exl -test - lock 0 0 testlock deferred noflags nolvb - lrpl 0 0 testlock deferred cachable ok nolvb -end - -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - - diff --git a/gulm/glv/tests/mergecheck.glv b/gulm/glv/tests/mergecheck.glv deleted file mode 100644 index a9e639a..0000000 --- a/gulm/glv/tests/mergecheck.glv +++ /dev/null @@ -1,16 +0,0 @@ -# this leaves residue so I can see how merging is working by dumping out -# the lock state. -nodecount 1 -test - lock 0 0 leftside [500 2000] shared noflags nolvb - lrpl 0 0 leftside [500 2000] shared cachable ok nolvb -end - -test - lock 0 0 leftside [0 1000] shared noflags nolvb - lrpl 0 0 leftside [0 1000] shared cachable ok nolvb -end - -# Two possible results here -# True Merging: one shared holder from 0 to 2000 -# Lazy Merging: Two shared holders, [0 1000] and [1001 2000] diff --git a/gulm/glv/tests/nocbflag.glv b/gulm/glv/tests/nocbflag.glv deleted file mode 100644 index 1f5ad3b..0000000 --- a/gulm/glv/tests/nocbflag.glv +++ /dev/null @@ -1,33 +0,0 @@ -# This verifies that the NoCB flag is working. -nodecount 3 - -test - lock 0 0 testlock shared noflags nolvb - lrpl 0 0 testlock shared cachable ok nolvb -end - -test - lock 2 0 testlock shared nocb nolvb - lrpl 2 0 testlock shared cachable ok nolvb -end - -test - lock 1 0 testlock exclusive noflags nolvb - drop 0 0 testlock exclusive -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -test - lock 2 0 testlock unlock noflags nolvb - lrpl 2 0 testlock unlock noflags ok nolvb - lrpl 1 0 testlock exclusive cachable ok nolvb -end - -test - lock 1 0 testlock unlock noflags nolvb - lrpl 1 0 testlock unlock noflags ok nolvb -end diff --git a/gulm/glv/tests/onelock.glv b/gulm/glv/tests/onelock.glv deleted file mode 100644 index 0e188e9..0000000 --- a/gulm/glv/tests/onelock.glv +++ /dev/null @@ -1,8 +0,0 @@ - -nodecount 1 - -test - lock 0 0 testlock exclusive noflags nolvb - lrpl 0 0 testlock exclusive cachable ok nolvb -end - diff --git a/gulm/glv/tests/prioityflag.glv b/gulm/glv/tests/prioityflag.glv deleted file mode 100644 index 2e95fe8..0000000 --- a/gulm/glv/tests/prioityflag.glv +++ /dev/null @@ -1,52 +0,0 @@ -# grab couple shares -# ask for exclusive -# convert to exclusive with piority. -# unlock - -nodecount 3 - - -test - lock 0 0 sharedfun shared noflags nolvb - lrpl 0 0 sharedfun shared cachable ok nolvb -end - -test - lock 1 0 sharedfun shared noflags nolvb - lrpl 1 0 sharedfun shared cachable ok nolvb -end - -test - lock 2 0 sharedfun exclusive noflags nolvb - drop 0 0 sharedfun exclusive - drop 1 0 sharedfun exclusive -end - -# with the piority flag, this should jump in front of node2's request. -test - lock 1 0 sharedfun exclusive piority nolvb - drop 0 0 sharedfun exclusive -end - -test - lock 0 0 sharedfun unlock noflags nolvb - lrpl 0 0 sharedfun unlock noflags ok nolvb - lrpl 1 0 sharedfun exclusive piority ok nolvb - drop 1 0 sharedfun exclusive -end - -test - lock 1 0 sharedfun unlock noflags nolvb - lrpl 1 0 sharedfun unlock noflags ok nolvb - lrpl 2 0 sharedfun exclusive cachable ok nolvb -end - -test - lock 1 0 sharedfun unlock noflags nolvb - lrpl 1 0 sharedfun unlock noflags ok nolvb -end - -test - lock 2 0 sharedfun unlock noflags nolvb - lrpl 2 0 sharedfun unlock noflags ok nolvb -end diff --git a/gulm/glv/tests/rangeconflict.glv b/gulm/glv/tests/rangeconflict.glv deleted file mode 100644 index 206210d..0000000 --- a/gulm/glv/tests/rangeconflict.glv +++ /dev/null @@ -1,40 +0,0 @@ -# This test checks how two nodes asking for the same exlcusive lock with -# various flags and not quite the same ranges. -nodecount 2 - -test - lock 0 0 testlock [100 200] exclusive noflags nolvb - lrpl 0 0 testlock [100 200] exclusive cachable ok nolvb -end - -test - lock 1 0 testlock [150 250] exclusive try nolvb - lrpl 1 0 testlock [150 250] exclusive try tryfailed nolvb -end - -test - lock 1 0 testlock [150 250] exclusive try|docb nolvb - lrpl 1 0 testlock [150 250] exclusive try|docb tryfailed nolvb - drop 0 0 testlock exclusive -end - -test - lock 1 0 testlock [150 250] shared noflags nolvb - drop 0 0 testlock shared -end - -test - lock 0 0 testlock [150 200] shared noflags nolvb - lrpl 0 0 testlock [150 200] shared cachable ok nolvb - lrpl 1 0 testlock [150 250] shared cachable ok nolvb -end - -test - lock 0 0 testlock unlock noflags nolvb - lrpl 0 0 testlock unlock noflags ok nolvb -end - -test - lock 1 0 testlock unlock noflags nolvb - lrpl 1 0 testlock unlock noflags ok nolvb -end diff --git a/gulm/glv/tests/shared2exlcusive.glv b/gulm/glv/tests/shared2exlcusive.glv deleted file mode 100644 index 4da147a..0000000 --- a/gulm/glv/tests/shared2exlcusive.glv +++ /dev/null @@ -1,68 +0,0 @@ -# grab lock shared -# ask exclusive. -# convert a shared to exclusive -# unlock others. -# unlock exclusives. - -nodecount 4 - - -test - lock 0 0 sharedfun shared noflags nolvb - lrpl 0 0 sharedfun shared cachable ok nolvb -end - -test - lock 1 0 sharedfun shared noflags nolvb - lrpl 1 0 sharedfun shared cachable ok nolvb -end - -test - lock 2 0 sharedfun shared noflags nolvb - lrpl 2 0 sharedfun shared cachable ok nolvb -end - -test - lock 3 0 sharedfun exclusive try|docb nolvb - lrpl 3 0 sharedfun exclusive try|docb tryfailed nolvb - drop 0 0 sharedfun exclusive - drop 1 0 sharedfun exclusive - drop 2 0 sharedfun exclusive -end - -test - lock 3 0 sharedfun exclusive noflags nolvb - drop 0 0 sharedfun exclusive - drop 1 0 sharedfun exclusive - drop 2 0 sharedfun exclusive -end - -test - lock 2 0 sharedfun unlock noflags nolvb - lrpl 2 0 sharedfun unlock noflags ok nolvb - drop 0 0 sharedfun exclusive - drop 1 0 sharedfun exclusive -end - -test - lock 1 0 sharedfun exclusive noflags nolvb - drop 0 0 sharedfun exclusive -end - -test - lock 0 0 sharedfun unlock noflags nolvb - lrpl 0 0 sharedfun unlock noflags ok nolvb - lrpl 3 0 sharedfun exclusive cachable ok nolvb - drop 3 0 sharedfun exclusive -end - -test - lock 3 0 sharedfun unlock noflags nolvb - lrpl 3 0 sharedfun unlock noflags ok nolvb - lrpl 1 0 sharedfun exclusive noflags ok nolvb -end - -test - lock 1 0 sharedfun unlock noflags nolvb - lrpl 1 0 sharedfun unlock noflags ok nolvb -end diff --git a/gulm/init.d/Makefile b/gulm/init.d/Makefile deleted file mode 100644 index ec063f5..0000000 --- a/gulm/init.d/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= lock_gulmd - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -copytobin: - -clean: - -install: - install -d ${DESTDIR}/etc/init.d - install ${TARGET} ${DESTDIR}/etc/init.d - -uninstall: - ${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d diff --git a/gulm/init.d/lock_gulmd b/gulm/init.d/lock_gulmd deleted file mode 100755 index a8cc759..0000000 --- a/gulm/init.d/lock_gulmd +++ /dev/null @@ -1,408 +0,0 @@ -#!/bin/bash -# -# -# -# chkconfig: 345 22 78 -# description: start/stop the gulm lock daemon -# -# -### BEGIN INIT INFO -# Provides: -### END INIT INFO - -# GULM_QUORUM_TIMEOUT -- amount of time to wait for there to be a master -# before giving up. If GULM_QUORUM_TIMEOUT is positive, then we will -# wait GULM_QUORUM_TIMEOUT seconds before giving up and failing when -# a master server is not found. If GULM_QUORUM_TIMEOUT is zero, then -# wait indefinately for a master server. If GULM_QUORUM_TIMEOUT is -# negative, just start lock_gulmd and not worry about whether it is -# quorate. -GULM_QUORUM_TIMEOUT=300 - -. /etc/init.d/functions -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - - -# GULM_OPTS -- commandline areguments for lock_gulmd. If this parameter -# is not set, the it defaults to "-n $CLUSTER_NAME --use_ccs" if -# CLUSTER_NAME is defined, otherwise it just defaults to "--use_ccs" -if [ -z "$GULM_OPTS" ] -then - if [ -n "$CLUSTER_NAME" ] - then - GULM_OPTS="$GULM_OPTS -n $CLUSTER_NAME" - fi - - GULM_OPTS="$GULM_OPTS --use_ccs" -fi - - -gulm_shutdown() -{ - rtrn=1 - if gulm_tool shutdown localhost &> /dev/null - then - for sec in $(seq 1 10 ) - do - sleep 1 - if ! gulm_tool shutdown localhost &> /dev/null - then - rtrn=0 - break - fi - done - fi - return $rtrn -} - -# get the servers list and stuff them into $serverlist -get_serverlist() -{ - serverlist=$( gulm_tool config localhost 2>/dev/null | - grep "servernames" | sed "s/^.*= //;s/,/ /g" ) -} - -# get the nodelist names that have logged into the cluster -# and stuff them into $nodelist -get_nodelist() -{ - nodelist=$( gulm_tool nodelist localhost | - grep Name | sed "s/^.*Name: //" ) -} - -# find the master server and store the value in $gulm_master -# return: -# 0 - success -# 1 - no master found -# 2 - gulm_tool error -# 3 - we can not log in because we are expired -find_master() -{ - gulm_master="" - line=$(gulm_tool getstats localhost 2>/dev/null | - awk 'BEGIN{xit=1} - ($1 == "I_am"){xit=0} - ($0 ~ /^(I_am = Master|Master =)/) {print} - END{exit xit}') - [ $? -ne 0 ] && return 2 # gulm_tool error - - case $line in - I_am\ =\ Master) - gulm_master=$(hostname) - ;; - - Master\ =*) - server=${line#*= } - - if gulm_tool getstats $server 2>/dev/null | - grep -q "I_am = Master" - then - gulm_master=$server - fi - ;; - - *) # This might mean we are in the expired state - [ -z "$serverlist" ] && get_serverlist - - for server in $serverlist - do - if gulm_tool nodeinfo $server $(uname -n) 2>/dev/null | - grep -iq "^ *state = expired" - then - return 3 # fence error - fi - done - ;; - esac - - if [ -n "$gulm_master" ] - then - return 0 # master found - else - return 1 # master not found - fi -} - -wait_for_master() -{ - i=0 - rtrn=0 - stoptime=$(($SECONDS + $GULM_QUORUM_TIMEOUT)) - while [ $GULM_QUORUM_TIMEOUT -eq 0 -o $SECONDS -lt $stoptime ] - do - find_master - rtrn=$? - case $rtrn in - 0) break ;; # master was found - 1) ;; # master was not found - 2) break ;; # gulm_tool error - 3) break ;; # we are expired - esac - - sleep 5 - i=$(($i+1)) - done - - return $rtrn -} - - -start() -{ - echo -n "Starting lock_gulmd:" - - # If gulm is using ccs, then make sure that there is a gulm - # section in /etc/cluster/cluster.conf, otherwise abort. - # FIXME -- Should this be silent? I think users should get some - # feedback, but others might not want added verbosity to - # the boot process. Oh well... it's only one line :) - if echo "$GULM_OPTS" | grep -qE "(--use_ccs|[\t ]-[VhCed]*c)" - then - if ! [ -r /etc/cluster/cluster.conf ] - then - failure "/etc/cluster/cluster.conf was not detected" - echo - return 1 - elif ! grep -qE "<[[:space:]]*gulm([[:space:]]|[>]|$)" /etc/cluster/cluster.conf - then - warning "no <gulm> section detected in /etc/cluster/cluster.conf" - echo - return 0 - fi - fi - - sts=1 - - if gulm_tool getstats localhost &>/dev/null - then - success "startup" - echo - return 0 - fi - - # start lock_gulmd and wait for the ltpx process to fork and connect - # before continuing - if lock_gulmd $GULM_OPTS &> /dev/null - then - for i in $(seq 1 10) - do - sleep 1 - if gulm_tool getstats localhost:ltpx &> /dev/null - then - sts=0 - break - fi - done - fi - - # Wait for gulm to be quorate before continuing. If quorum is not - # achieved in a set period of time, then - if [ $sts -eq 0 ] - then - wait_for_master - rtrn=$? - if [ $rtrn = 0 ] - then - success "startup" - elif [ $rtrn = 3 ] - then - echo -n " waiting to be fenced " - gulm_shutdown - failure "startup" - sts=1 - else - echo -n " failed to login to master " - gulm_shutdown - failure "startup" - sts=1 - fi - else - echo -n " failed to start ltpx " - gulm_shutdown - failure "startup" - fi - echo - return $sts -} - -stop() -{ - if [ "$1" = "force" ] ; then force=0 ; else force=1 ; fi - - echo -n "Stopping lock_gulmd:" - - do_shutdown=0 - if gulm_tool servicelist localhost &> /dev/null - then - # ignore LTPX and LT000-LT999 and Magma services - if gulm_tool servicelist localhost | - grep -vE "^(LTPX|LT[0-9][0-9][0-9]|Magma::[0-9]*)$" - then - if [ $force -ne 0 ] - then - echo "lock_gulmd in use. failing to stop" - return 1 - else - echo "lock_gulmd in use. force shutdown in 5 seconds. " \ - "Ctrl-C to abort..." - sleep 5 - do_shutdown=1 - fi - fi - else - if pidof lock_gulmd &> /dev/null - then - failure "unable to comminucate to lock_gulmd" - echo - return 1 - else - success "shutdown" - echo - return 0 - fi - fi - - rank=$( gulm_tool getstats localhost | grep rank | sed "s/^ *rank = //") - - if [ $rank -ge 0 -a $force -ne 0 ] - then - # we are in the servers list - myname=$(uname -n) - my_gid=$(gulm_tool getstats localhost 2>/dev/null | grep GenerationID) - get_serverlist - warn_msg=" waiting for clients to logout " - - while [ $do_shutdown -eq 0 ] - do - get_nodelist - - # remove servers from nodelist - for server in $serverlist - do - nodelist=$( echo "$nodelist" | grep -v $server ) - done - - # check to see if there are any clients logged in. If there - # are not, we shutdown - cli_logged_in=0 - for client in $nodelist - do - node_gid=$( gulm_tool getstats $client 2>/dev/null | - grep GenerationID ) - if [ "$node_gid" = "$my_gid" ] - then - cli_logged_in=1 - break - fi - done - if [ $cli_logged_in -eq 0 ] - then - do_shutdown=1 - break - fi - - # check to see if there are servers logged in. If - # there are, then it is OK to shut down - srv_logged_in=0 - for server in $serverlist - do - [ $myname = $server ] && continue - - node_gid=$( gulm_tool getstats $server 2>/dev/null | grep GenerationID ) - - if [ "$node_gid" = "$my_gid" ] - then - srv_logged_in=1 - break - fi - done - if [ $srv_logged_in -eq 1 ] - then - do_shutdown=1 - break - fi - - if [ -n "$warn_msg" ] - then - echo -n "$warn_msg" - warn_msg="" - fi - - sleep 1 - done - else - do_shutdown=1 - fi - - if [ $do_shutdown -eq 1 ] && gulm_shutdown - then - success "shutdown" - echo - sts=0 - else - failure "shutdown" - echo - sts=1 - fi - return $sts -} - -rtrn=1 - -# See how we were called. -case "$1" in - start) - #> # Make sure that ccsd is running - #> FIXME -- ccs_read is no longer supported - #> ccs_read list &>/dev/null || exit 0 - - start - rtrn=$? - [ $rtrn -eq 0 ] && touch /var/lock/subsys/lock_gulmd - ;; - - stop) - stop - rtrn=$? - [ $rtrn -eq 0 ] && rm -f /var/lock/subsys/lock_gulmd - ;; - - forcestop) - stop force - rtrn=$? - [ $rtrn -eq 0 ] && rm -f /var/lock/subsys/lock_gulmd - ;; - - restart) - $0 stop - $0 start - rtrn=$? - ;; - - status) - if status lock_gulmd - then - if find_master - then - echo "gulm_master: $gulm_master is the master" - else - echo "gulm_master: gulm master not found" - fi - - if gulm_tool servicelist localhost &> /dev/null - then - echo "Services:" - gulm_tool servicelist localhost - fi - fi - - rtrn=0 - ;; - - *) - echo $"Usage: $0 {start|stop|restart|status|forcestop}" - ;; -esac - -exit $rtrn - diff --git a/gulm/lib/Makefile b/gulm/lib/Makefile deleted file mode 100644 index b0accf5..0000000 --- a/gulm/lib/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: libgulm.a - -.PHONY: libgulm.a clean dep depends - -libgulm.a: - cd .. && ${MAKE} lib/libgulm.a - -clean: - cd .. && ${MAKE} clean - -dep depends: - cd .. && ${MAKE} depends - diff --git a/gulm/lib/exported_symbols.sym b/gulm/lib/exported_symbols.sym deleted file mode 100644 index 6090c5f..0000000 --- a/gulm/lib/exported_symbols.sym +++ /dev/null @@ -1,25 +0,0 @@ -lg_initialize -lg_release -lg_set_core_port -lg_set_lock_port -lg_core_handle_messages -lg_core_selector -lg_core_login -lg_core_logout -lg_core_nodeinfo -lg_core_nodelist -lg_core_servicelist -lg_core_corestate -lg_core_shutdown -lg_core_forceexpire -lg_core_forcepending -lg_core_status -lg_lock_handle_messages -lg_lock_selector -lg_lock_login -lg_lock_logout -lg_lock_state_req -lg_lock_cancel_req -lg_lock_action_req -lg_lock_drop_exp -lg_lock_status diff --git a/gulm/lib/lg_core.c b/gulm/lib/lg_core.c deleted file mode 100644 index bf0a58b..0000000 --- a/gulm/lib/lg_core.c +++ /dev/null @@ -1,561 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* All of the core related functions for services are here. */ - -#include "lg_priv.h" - - -/** - * lg_core_selector - - * @ulm_interface_p: - * - * - * Returns: int - */ -xdr_socket lg_core_selector(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - /* make sure it is a gulm_interface_p. */ - if( lg == NULL || lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) -#ifdef __KERNEL__ - return NULL; -#else - return -EINVAL; -#endif - - return lg->core_fd; -} - -/** - * lg_core_handle_messages - - * @ulm_interface_p: - * @lg_core_callbacks_t: - * - * - * Returns: int - */ -int lg_core_handle_messages(gulm_interface_p lgp, lg_core_callbacks_t* ccbp, - void *misc) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_dec_t *dec; - int err = 0; - uint64_t x_gen; - uint32_t x_code, x_error, x_rank; - struct in6_addr x_ip; - uint8_t x_state, x_mode; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_enc == NULL || lg->core_dec == NULL) return -EBADR; - - lg_mutex_lock( &lg->core_recver ); - if( lg->in_core_hm ) return -EDEADLK; - lg->in_core_hm = TRUE; - lg_mutex_unlock( &lg->core_recver ); - - dec = lg->core_dec; - - err = xdr_dec_uint32(dec, &x_code); - if( err != 0 ) goto exit; - - if( gulm_core_login_rpl == x_code ) { - do{ - if((err = xdr_dec_uint64(dec, &x_gen))<0) break; - if((err = xdr_dec_uint32(dec, &x_error))<0) break; - if((err = xdr_dec_uint32(dec, &x_rank))<0) break; - if((err = xdr_dec_uint8(dec, &x_state))<0) break; - }while(0); - if( err != 0 ) goto exit; - if( ccbp->login_reply == NULL ) {err=0; goto exit;} - err = ccbp->login_reply(misc, x_gen, x_error, x_rank, x_state); - goto exit; - }else - if( gulm_core_logout_rpl == x_code ) { - if((err = xdr_dec_uint32(dec, &x_error)) != 0 ) goto exit; - if( ccbp->logout_reply != NULL ) { - err = ccbp->logout_reply(misc); - } - - xdr_close(&lg->core_fd); - xdr_enc_release(lg->core_enc); lg->core_enc = NULL; - xdr_dec_release(lg->core_dec); lg->core_dec = NULL; - - goto exit; - }else - if( gulm_core_mbr_lstrpl == x_code ) { - if( ccbp->nodelist != NULL ) { - err = ccbp->nodelist(misc, lglcb_start, NULL, 0, 0); - if( err != 0 ) goto exit; - } - do{ - if((err = xdr_dec_list_start(dec)) != 0 ) break; - while( xdr_dec_list_stop(dec) != 0 ) { - if((err = xdr_dec_string_ag(dec, &lg->cfba, &lg->cfba_len)) != 0 ) - break; - if((err = xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_mode)) != 0 ) break; /* skip over this... */ - if((err = xdr_dec_uint8(dec, &x_mode)) != 0 ) break; /* skip over this... */ - if((err = xdr_dec_uint32(dec, &x_rank)) != 0 ) break; /* skip over this... */ - if((err = xdr_dec_uint64(dec, &x_gen)) != 0 ) break; /* skip over this... */ - if((err = xdr_dec_uint64(dec, &x_gen)) != 0 ) break; /* skip over this... */ - if((err = xdr_dec_uint64(dec, &x_gen)) != 0 ) break; /* skip over this... */ - - if( ccbp->nodelist != NULL ) { - err = ccbp->nodelist(misc, lglcb_item, lg->cfba, &x_ip, x_state); - if( err != 0 ) goto exit; - } - - } - }while(0); - if( err != 0 ) { - goto exit; - } - if( ccbp->nodelist == NULL ) {err=0; goto exit;} - err = ccbp->nodelist(misc, lglcb_stop, NULL, 0, 0); - goto exit; - }else - if( gulm_core_state_chgs == x_code ) { - do{ - if((err = xdr_dec_uint8(dec, &x_state)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_mode)) != 0 ) break; - if( x_state == gio_Mbr_ama_Slave ) { - if((err = xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err = xdr_dec_string_ag(dec, &lg->cfba, &lg->cfba_len)) != 0 ) - break; - } - }while(0); - if( err != 0 ) { - goto exit; - } - if( ccbp->statechange == NULL ) { - err = 0; - goto exit; - } - err = ccbp->statechange(misc, x_state, x_mode, &x_ip, lg->cfba); - goto exit; - }else - if( gulm_core_mbr_updt == x_code ) { - do{ - if((err = xdr_dec_string_ag(dec, &lg->cfba, &lg->cfba_len)) != 0 ) - break; - if((err = xdr_dec_ipv6(dec, &x_ip)) != 0) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0 ) break; - }while(0); - if( err != 0 ) { - goto exit; - } - if( ccbp->nodechange == NULL ) { - err = 0; - goto exit; - } - err = ccbp->nodechange(misc, lg->cfba, &x_ip, x_state); - goto exit; - }else - if( gulm_core_res_list == x_code ) { - if( ccbp->service_list != NULL ) { - if((err = ccbp->service_list(misc, lglcb_start, NULL)) != 0 ) - goto exit; - } - do{ - if((err = xdr_dec_list_start(dec)) != 0) break; - while( xdr_dec_list_stop(dec) ) { - if((err = xdr_dec_string_ag(dec, &lg->cfba, &lg->cfba_len)) != 0) - break; - if( ccbp->service_list != NULL ) { - if((err = ccbp->service_list(misc, lglcb_item, lg->cfba)) != 0){ - goto exit; - } - } - } - }while(0); - if( err != 0 ) { - goto exit; - } - if( ccbp->service_list == NULL ) { - err = 0; - goto exit; - } - err = ccbp->service_list(misc, lglcb_stop, NULL); - goto exit; - }else - if( gulm_info_stats_rpl == x_code ) { - do{ - if((err = xdr_dec_list_start(dec)) != 0 ) break; - while( xdr_dec_list_stop(dec) != 0 ) { - if((err = xdr_dec_string_ag(dec, &lg->cfba, &lg->cfba_len)) != 0) - break; - if((err = xdr_dec_string_ag(dec, &lg->cfbb, &lg->cfbb_len)) != 0) - break; - } - }while(0); - goto exit; - }else - if( gulm_err_reply == x_code ) { - if((err = xdr_dec_uint32(dec, &x_code)) != 0 ) goto exit; - if((err = xdr_dec_uint32(dec, &x_error)) != 0 ) goto exit; - if( ccbp->error == NULL ) {err = 0; goto exit;} - err = ccbp->error(misc, x_error); - goto exit; - }else - { - /* unknown code. what to do? */ - err = -EPROTO; - goto exit; - } - -exit: - lg->in_core_hm = FALSE; - return err; -} - -/** - * lg_core_login - - * @lgp: - * @important: - * - * On any error, things are closed and released to the state of things - * before you called login. - * - * Returns: int - */ -int lg_core_login(gulm_interface_p lgp, int important) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct sockaddr_in6 adr; - int err; - xdr_socket cfd; - xdr_enc_t *enc; - xdr_dec_t *dec; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - adr.sin6_addr = in6addr_loopback; - adr.sin6_port = htons(lg->core_port); - - if( (err=xdr_open( &cfd ) ) <0) { - return err; - } - - if( (err=xdr_connect(&adr, cfd))<0) { - xdr_close(&cfd); - return err; - } - - enc = xdr_enc_init( cfd, 128 ); - if( enc == NULL ) { - xdr_close( &cfd ); - return -ENOMEM; - } - - dec = xdr_dec_init( cfd, 128 ); - if( enc == NULL ) { - xdr_enc_release(enc); - xdr_close( &cfd ); - return -ENOMEM; - } - - do{ - if((err = xdr_enc_uint32(enc, gulm_core_reslgn_req))<0) break; - if((err = xdr_enc_uint32(enc, GIO_WIREPROT_VERS))<0) break; - if((err = xdr_enc_string(enc, lg->clusterID))<0) break; - if((err = xdr_enc_string(enc, lg->service_name))<0) break; - if((err = xdr_enc_uint32(enc, important?gulm_svc_opt_important:0)) != 0 ) - break; - if((err = xdr_enc_flush(enc))<0) break; - }while(0); - if(err != 0 ) { - xdr_dec_release(dec); - xdr_enc_release(enc); - xdr_close( &cfd ); - return err; - } - - lg_mutex_lock( &lg->core_sender ); - lg->core_fd = cfd; - lg->core_enc = enc; - lg->core_dec = dec; - lg_mutex_unlock( &lg->core_sender ); - - return 0; -} - -/** - * lg_core_logout - - * @lgp: - * - * - * Returns: int - */ -int lg_core_logout(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_logout_req))!= 0 ) break; - if((err = xdr_enc_string(enc, lg->service_name))!= 0 ) break; - if((err = xdr_enc_uint8(enc, gio_Mbr_ama_Resource))!= 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - -/** - * lg_core_nodeinfo - - * @lgp: - * @nodename: - * - * - * Returns: int - */ -int lg_core_nodeinfo(gulm_interface_p lgp, char *nodename) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - if( nodename == NULL ) return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_mbr_req)) != 0 ) break; - if((err = xdr_enc_string(enc, nodename)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - -/** - * lg_core_nodelist - - * @lgp: - * - * - * Returns: int - */ -int lg_core_nodelist(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_mbr_lstreq)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - -/** - * lg_core_servicelist - - * @lgp: - * - * - * Returns: int - */ -int lg_core_servicelist(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_res_req)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - -/** - * lg_core_corestate - - * @lgp: - * - * - * Returns: int - */ -int lg_core_corestate(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_state_req)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - - -/** - * lg_core_shutdown - - * @lgp: - * - * - * Returns: int - */ -int lg_core_shutdown(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_shutdown)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - -/** - * lg_core_forceexpire - - * @lgp: - * @node_name: - * - * - * Returns: int - */ -int lg_core_forceexpire(gulm_interface_p lgp, char *nodename) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - if( nodename == NULL ) return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_mbr_force)) != 0 ) break; - if((err = xdr_enc_string(enc, nodename)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - -/** - * lg_core_forcepending - - * @lgp: - * - * - * Returns: int - */ -int lg_core_forcepending(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_fd < 0 || lg->core_enc == NULL || lg->core_dec == NULL) - return -EINVAL; - - enc = lg->core_enc; - - lg_mutex_lock( &lg->core_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_core_forcepend)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->core_sender ); - return err; -} - - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/lib/lg_lock.c b/gulm/lib/lg_lock.c deleted file mode 100644 index 218cb3e..0000000 --- a/gulm/lib/lg_lock.c +++ /dev/null @@ -1,543 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* all of the lock related fucntion are here. */ -#include "lg_priv.h" - -/** - * lg_lock_selector - - * @ulm_interface_p: - * - * - * Returns: int - */ -xdr_socket lg_lock_selector(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - /* make sure it is a gulm_interface_p. */ - if( lg == NULL || lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) -#ifdef __KERNEL__ - return NULL; -#else - return -EINVAL; -#endif - - return lg->lock_fd; -} - -/** - * lg_lock_handle_messages - - * @ulm_interface_p: - * @lg_lockspace_callbacks_t: - * - * Returns: int - */ -int lg_lock_handle_messages(gulm_interface_p lgp, lg_lockspace_callbacks_t* cbp, - void *misc) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_dec_t *dec; - int err = 0; - uint64_t x_subid, x_start, x_stop; - uint32_t x_code, x_error, x_flags; - uint16_t x_keylen, x_lvblen=0; - uint8_t x_state; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->core_enc == NULL || lg->core_dec == NULL) return -EBADR; - - lg_mutex_lock( &lg->lock_recver ); - if( lg->in_lock_hm ) return -EDEADLK; - lg->in_lock_hm = TRUE; - lg_mutex_unlock( &lg->lock_recver ); - - dec = lg->lock_dec; - - err = xdr_dec_uint32(dec, &x_code); - if( err != 0 ) goto exit; - - if( gulm_lock_login_rpl == x_code ) { - do{ - if((err = xdr_dec_uint32(dec, &x_error)) != 0) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0) break; - }while(0); - if( err != 0 ) goto exit; - if( cbp->login_reply == NULL ) {err = 0; goto exit;} - err = cbp->login_reply(misc, x_error, x_state); - goto exit; - }else - if( gulm_lock_logout_rpl == x_code ) { - if( cbp->logout_reply != NULL ) { - err = cbp->logout_reply(misc); - } - - xdr_close(&lg->lock_fd); - xdr_enc_release(lg->lock_enc); lg->lock_enc = NULL; - xdr_dec_release(lg->lock_dec); lg->lock_dec = NULL; - - goto exit; - }else - if( gulm_lock_state_rpl == x_code ) { - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&lg->lfba, &lg->lfba_len, - &x_keylen)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &x_start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &x_stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_flags)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0) break; - if( x_flags & gio_lck_fg_hasLVB) { - if((err = xdr_dec_raw_ag(dec, (void**)&lg->lfbb, - &lg->lfbb_len, &x_lvblen))!= 0) break; - } - }while(0); - if( err != 0 ){ - goto exit; - } - if( x_keylen <= 4 ) { - err = -EPROTO; /* or something */ - goto exit; - } - if( cbp->lock_state == NULL ) { - err = 0; - goto exit; - } - /* gio_lck_fg_hasLVB is an internal flag. so remove it before we show - * the user what we got. - */ - x_flags &= ~gio_lck_fg_hasLVB; - err = cbp->lock_state(misc, &lg->lfba[4], x_keylen-4, x_subid, - x_start, x_stop, x_state, x_flags, x_error, - lg->lfbb, x_lvblen); - goto exit; - }else - if( gulm_lock_action_rpl == x_code ) { - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&lg->lfba, &lg->lfba_len, - &x_keylen)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0) break; - }while(0); - if( err != 0 ) { - goto exit; - } - if( x_keylen <= 4 ) { - err = -EPROTO; /* or something */ - goto exit; - } - if( cbp->lock_action == NULL ) { - err = 0; - goto exit; - } - err = cbp->lock_action(misc, &lg->lfba[4], x_keylen-4, x_subid, - x_state, x_error); - goto exit; - }else - if( gulm_lock_cb_state == x_code ) { - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&lg->lfba, &lg->lfba_len, - &x_keylen)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0) break; - }while(0); - if( err != 0 ) { - goto exit; - } - if( cbp->drop_lock_req == NULL ) { - err = 0; - goto exit; - } - err = cbp->drop_lock_req(misc, &lg->lfba[4], x_keylen-4, - x_subid, x_state); - goto exit; - }else - if( gulm_lock_cb_dropall == x_code ) { - if( cbp->drop_all == NULL ) {err = 0; goto exit;} - err = cbp->drop_all(misc); - goto exit; - }else - if( gulm_info_stats_rpl == x_code ) { - do{ - if((err = xdr_dec_list_start(dec)) != 0 ) break; - while( xdr_dec_list_stop(dec) != 0 ) { - if((err = xdr_dec_string_ag(dec, &lg->lfba, &lg->lfba_len)) != 0) - break; - if((err = xdr_dec_string_ag(dec, &lg->lfbb, &lg->lfbb_len)) != 0) - break; - } - }while(0); - goto exit; - }else - if( gulm_err_reply == x_code ) { - do{ - if((err = xdr_dec_uint32(dec, &x_code)) != 0 ) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0 ) break; - }while(0); - if( err != 0 ) goto exit; - if( cbp->error == NULL ) {err = 0; goto exit;} - err = cbp->error(misc, x_error); - goto exit; - }else - { - err = -EPROTO; - goto exit; - } - -exit: - lg->in_lock_hm = FALSE; - return err; -} - - -/** - * lg_lock_login - - * @ulm_interface_p: - * @4: - * - * - * Returns: int - */ -int lg_lock_login(gulm_interface_p lgp, uint8_t lockspace[4] ) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct sockaddr_in6 adr; - int err; - xdr_socket cfd; - xdr_enc_t *enc; - xdr_dec_t *dec; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - adr.sin6_addr = in6addr_loopback; - adr.sin6_port = htons(lg->lock_port); - - if( (err = xdr_open( &cfd )) < 0 ) { - return err; - } - - if( (err=xdr_connect(&adr, cfd))<0) { - xdr_close(&cfd); - return err; - } - - enc = xdr_enc_init( cfd, 512 ); - if( enc == NULL ) { - xdr_close( &cfd ); - return -ENOMEM; - } - - dec = xdr_dec_init( cfd, 512 ); - if( enc == NULL ) { - xdr_enc_release(enc); - xdr_close( &cfd ); - return -ENOMEM; - } - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_login_req))<0) break; - if((err = xdr_enc_uint32(enc, GIO_WIREPROT_VERS))<0) break; - if((err =xdr_enc_string(enc, lg->service_name))<0) break; - if((err = xdr_enc_uint8(enc, gio_lck_st_Client))<0) break; - if((err = xdr_enc_flush(enc))<0) break; - - if((err = xdr_enc_uint32(enc, gulm_lock_sel_lckspc))<0) break; - if((err = xdr_enc_raw(enc, lockspace, 4))<0) break; - /* don't flush here. - * dumb programmer stunt. This way, the lockspace selection won't - * happen until the next thing the user of this lib sends. Which - * means it will be after we have received the login reply. - * - * Is there really a good reason not to flush here? - */ - }while(0); - if(err != 0 ) { - xdr_dec_release(dec); - xdr_enc_release(enc); - xdr_close( &cfd ); - return err; - } - - lg_mutex_lock( &lg->lock_sender ); - lg->lock_fd = cfd; - lg->lock_enc = enc; - lg->lock_dec = dec; - - memcpy(lg->lockspace, lockspace, 4); - lg_mutex_unlock( &lg->lock_sender ); - - return 0; -} - -/** - * lg_lock_logout - - * @ulm_interface_p: - * - * - * Returns: int - */ -int lg_lock_logout(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - lg_mutex_lock( &lg->lock_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_logout_req)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->lock_sender ); - return err; -} - -/** - * lg_lock_state_req - - * @lgp: - * @key: - * @keylen: - * @subid: - * @state: - * @flags: - * @LVB: - * @LVBlen: - * - * - * Returns: int - */ -int lg_lock_state_req(gulm_interface_p lgp, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, uint8_t state, - uint32_t flags, uint8_t *LVB, uint16_t LVBlen) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - if( state != lg_lock_state_Unlock && - state != lg_lock_state_Exclusive && - state != lg_lock_state_Deferred && - state != lg_lock_state_Shared ) - return -EINVAL; - - if( stop < start ) return -EINVAL; - - /* make sure only the accepted flags get passed through. */ - flags &= lg_lock_flag_DoCB|lg_lock_flag_Try|lg_lock_flag_Any| - lg_lock_flag_IgnoreExp|lg_lock_flag_Piority| - lg_lock_flag_NoCallBacks; - - enc = lg->lock_enc; - - if( LVB != NULL && LVBlen > 0) flags |= gio_lck_fg_hasLVB; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - lg_mutex_lock( &lg->lock_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_state_req)) != 0 ) break; - if((err = xdr_enc_raw_iov(enc, 2, iov)) != 0 ) break; - if((err = xdr_enc_uint64(enc, subid)) != 0) break; - if((err = xdr_enc_uint64(enc, start)) != 0) break; - if((err = xdr_enc_uint64(enc, stop)) != 0) break; - if((err = xdr_enc_uint8(enc, state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, flags)) != 0 ) break; - if( flags & gio_lck_fg_hasLVB ) - if((err = xdr_enc_raw(enc, LVB, LVBlen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->lock_sender ); - return err; -} - -/** - * lg_lock_cancel_req - - * @lgp: - * @key: - * @keylen: - * @subid: - * - * - * Returns: int - */ -int lg_lock_cancel_req(gulm_interface_p lgp, uint8_t *key, uint16_t keylen, - uint64_t subid) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - lg_mutex_lock( &lg->lock_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_action_req)) != 0 ) break; - if((err = xdr_enc_raw_iov(enc, 2, iov)) != 0 ) break; - if((err = xdr_enc_uint64(enc, subid)) != 0) break; - if((err = xdr_enc_uint8(enc, gio_lck_st_Cancel)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->lock_sender ); - return err; -} - -/** - * lg_lock_action_req - - * @lgp: - * @key: - * @keylen: - * @subid: - * @action: - * @LVB: - * @LVBlen: - * - * XXX - * I wonder if I should actually break this into three seperate calls for - * the lvb stuff. Does it really matter? - * - * Returns: int - */ -int lg_lock_action_req(gulm_interface_p lgp, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t action, uint8_t *LVB, uint16_t LVBlen) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - if( action != lg_lock_act_HoldLVB && - action != lg_lock_act_UnHoldLVB && - action != lg_lock_act_SyncLVB ) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = keylen; - - lg_mutex_lock( &lg->lock_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_action_req)) != 0 ) break; - if((err = xdr_enc_raw_iov(enc, 2, iov)) != 0 ) break; - if((err = xdr_enc_uint64(enc, subid)) != 0) break; - if((err = xdr_enc_uint8(enc, action)) != 0 ) break; - if( action == gio_lck_st_SyncLVB) - if((err = xdr_enc_raw(enc, LVB, LVBlen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->lock_sender ); - return err; -} - -/** - * lg_lock_drop_exp - - * @ulm_interface_p: - * @holder: - * @keymask: - * @kmlen: - * - * holder is the node name of the expired holder that you want to clear. - * Only locks matching the keymask will be looked at. (most of the time you - * will just set key to a bunch of 0xff to match all) The keymask lets you - * basically subdivide your lockspace into smaller seperate parts. - * (example, there is one gfs lockspace, but each filesystem gets its own - * subpart of that larger space) - * - * If holder is NULL, all expired holders in your lockspace will get - * dropped. - * - * Returns: int - */ -int lg_lock_drop_exp(gulm_interface_p lgp, uint8_t *holder, uint8_t *key, - uint16_t keylen) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - struct iovec iov[2]; - xdr_enc_t *enc; - int err; - - /* make sure it is a gulm_interface_p. */ - if( lg == NULL ) return -EINVAL; - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - if( lg->lock_fd < 0 || lg->lock_enc == NULL || lg->lock_dec == NULL) - return -EINVAL; - - enc = lg->lock_enc; - - iov[0].iov_base = lg->lockspace; - iov[0].iov_len = 4; - iov[1].iov_base = key; - iov[1].iov_len = (key!=NULL)?keylen:0; - - lg_mutex_lock( &lg->lock_sender ); - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_drop_exp)) != 0 ) break; - if((err = xdr_enc_string(enc, holder)) != 0 ) break; - if((err = xdr_enc_raw_iov(enc, 2, iov)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - lg_mutex_unlock( &lg->lock_sender ); - return err; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/lib/lg_main.c b/gulm/lib/lg_main.c deleted file mode 100644 index 04157ca..0000000 --- a/gulm/lib/lg_main.c +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* This is where all of the library specific functions exist. - * Not many, but keeps things clean. - */ - -#include "lg_priv.h" - -/** - * lg_initialize - - * @gulm_interface_p: - * @service_name: - * - * if returning an error, nothing was done to the value of gulm_interface_p - * - * Returns: gulm_interface_p - */ -int lg_initialize(gulm_interface_p *ret, char *cluster_name, char *service_name) -{ - gulm_interface_t *lg; - int err, len; - - lg = lg_malloc(sizeof(gulm_interface_t)); - if( lg == NULL ) return -ENOMEM; - - memset(lg, 0, sizeof(gulm_interface_t)); - lg->first_magic = LGMAGIC; - lg->last_magic = LGMAGIC; - lg->core_fd = XDR_SOCKET_INIT; - lg->lock_fd = XDR_SOCKET_INIT; - - if( cluster_name == NULL ) cluster_name = ""; - len = strlen(cluster_name) +1; - lg->clusterID = lg_malloc(len); - if( lg->clusterID == NULL ) {err = -ENOMEM; goto fail_nomem;} - memcpy(lg->clusterID, cluster_name, len); - - len = strlen(service_name) +1; - lg->service_name = lg_malloc(len); - if( lg->service_name == NULL ) {err = -ENOMEM; goto fail_nomem;} - memcpy(lg->service_name, service_name, len); - - /* set up flutter bufs. */ - lg->cfba_len = 64; - lg->cfba = lg_malloc(lg->cfba_len); - if( lg->cfba == NULL ) {err = -ENOMEM; goto fail_nomem;} - - lg->cfbb_len = 64; - lg->cfbb = lg_malloc(lg->cfbb_len); - if( lg->cfbb == NULL ) {err = -ENOMEM; goto fail_nomem;} - - lg->lfba_len = 128; - lg->lfba = lg_malloc(lg->lfba_len); - if( lg->lfba == NULL ) {err = -ENOMEM; goto fail_nomem;} - - lg->lfbb_len = 128; - lg->lfbb = lg_malloc(lg->lfbb_len); - if( lg->lfbb == NULL ) {err = -ENOMEM; goto fail_nomem;} - - /* setup mutexes */ - lg_mutex_init( &lg->core_sender ); - lg_mutex_init( &lg->core_recver ); - lg_mutex_init( &lg->lock_sender ); - lg_mutex_init( &lg->lock_recver ); - - lg->core_port = 40040; - lg->lock_port = 40042; - - *ret = lg; - return 0; -fail_nomem: - if( lg->clusterID != NULL ) lg_str_free(lg->clusterID); - if( lg->service_name != NULL ) lg_str_free(lg->service_name); - if( lg->cfba != NULL ) lg_free(lg->cfba, lg->cfba_len); - if( lg->cfbb != NULL ) lg_free(lg->cfbb, lg->cfbb_len); - if( lg->lfba != NULL ) lg_free(lg->lfba, lg->lfba_len); - if( lg->lfbb != NULL ) lg_free(lg->lfbb, lg->lfbb_len); - lg_free(lg, sizeof(gulm_interface_t)); - return err; -} - - -/** - * lg_release - - * @lg: - * - */ -void lg_release(gulm_interface_p lgp) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - if( lgp == NULL ) return; - /* make sure it is a gulm_interface_p. */ - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return; - - if( lg->service_name != NULL ) lg_str_free(lg->service_name); - if( lg->clusterID != NULL ) lg_str_free(lg->clusterID); - - /* wonder if I should send a logout packet? */ - if( lg->core_enc != NULL ) xdr_enc_release(lg->core_enc); - if( lg->core_dec != NULL ) xdr_dec_release(lg->core_dec); - xdr_close(&lg->core_fd); - - if( lg->lock_enc != NULL ) xdr_enc_release(lg->lock_enc); - if( lg->lock_dec != NULL ) xdr_dec_release(lg->lock_dec); - xdr_close(&lg->lock_fd); - - if( lg->cfba != NULL ) lg_free(lg->cfba, lg->cfba_len); - if( lg->cfbb != NULL ) lg_free(lg->cfbb, lg->cfbb_len); - if( lg->lfba != NULL ) lg_free(lg->lfba, lg->lfba_len); - if( lg->lfbb != NULL ) lg_free(lg->lfbb, lg->lfbb_len); - - lg_mutex_destroy( &lg->core_sender ); - lg_mutex_destroy( &lg->core_recver ); - lg_mutex_destroy( &lg->lock_sender ); - lg_mutex_destroy( &lg->lock_recver ); - - lg_free(lg, sizeof(gulm_interface_t)); -} - -/** - * lg_set_core_port - - * @lgp: - * @new: - * - * - * Returns: int - */ -int lg_set_core_port(gulm_interface_p lgp, uint16_t new) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - if( lgp == NULL ) return -EINVAL; - /* make sure it is a gulm_interface_p. */ - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - lg->core_port = new; - return 0; -} - -/** - * lg_set_ltpx_port - - * @lgp: - * @new: - * - * - * Returns: int - */ -int lg_set_lock_port(gulm_interface_p lgp, uint16_t new) -{ - gulm_interface_t *lg = (gulm_interface_t *)lgp; - if( lgp == NULL ) return -EINVAL; - /* make sure it is a gulm_interface_p. */ - if( lg->first_magic != LGMAGIC || lg->last_magic != LGMAGIC ) return -EINVAL; - - lg->lock_port = new; - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/lib/lg_priv.h b/gulm/lib/lg_priv.h deleted file mode 100644 index e7d1932..0000000 --- a/gulm/lib/lg_priv.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -/* private details that we don't want to give the users of this lib access - * to go here. - */ - -#ifdef __KERNEL__ - -#ifdef __linux__ -#include <linux/kernel.h> -#include <linux/sched.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> -#endif /*__linux__*/ - - -#define lg_malloc(y) kmalloc(y, GFP_KERNEL) -#define lg_free(x,y) kfree(x) -#define lg_str_free(x) kfree( (x) , strlen( x ) + 1 ) -#define lg_memcpy(x,y,l) memcpy(x,y,l) - -struct lg_mutex -{ - struct semaphore sema; -}; -typedef struct lg_mutex lg_mutex_t; - -#define lg_mutex_init(x) do { init_MUTEX(&(x)->sema); } while (0) -#define lg_mutex_destroy(x) - -#define lg_mutex_lock(x) do { down(&(x)->sema); } while (0) -#define lg_mutex_trylock(x) (!down_trylock(&(x)->sema)) -#define lg_mutex_unlock(x) do { up(&(x)->sema); } while (0) - -#else /*__KERNEL__*/ -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <pthread.h> -#include <stdint.h> - -#define lg_malloc(y) malloc(y) -#define lg_free(x,y) free(x) -#define lg_str_free(x) free(x) -#define lg_memcpy(x,y,l) memcpy(x,y,l) - -struct lg_mutex -{ - pthread_mutex_t lk; -}; -typedef struct lg_mutex lg_mutex_t; - -#define lg_mutex_init(x) do { pthread_mutex_init(&(x)->lk,NULL); } while(0) -#define lg_mutex_destroy(x) do { pthread_mutex_destroy(&(x)->lk); } while(0) - -#define lg_mutex_lock(x) do { pthread_mutex_lock(&(x)->lk); } while(0) -#define lg_mutex_trylock(x) do { pthread_mutex_trylock(&(x)->lk); } while(0) -#define lg_mutex_unlock(x) do { pthread_mutex_unlock(&(x)->lk); } while(0) - -#endif /*__KERNEL__*/ - -#include "xdr.h" -#include "gio_wiretypes.h" -#include "libgulm.h" - -#if !defined(TRUE) || !defined(FALSE) -#undef TRUE -#undef FALSE -#define TRUE (1) -#define FALSE (0) -#endif - -#define LGMAGIC (0x474d4354) - -struct gulm_interface_s { - /* since we've masked this to a void* to the users, it is a nice safty - * net to put a little magic in here so we know things stay good. - */ - uint32_t first_magic; - - /* WHAT IS YOUR NAME?!? */ - char *service_name; - - char *clusterID; - - uint16_t core_port; - xdr_socket core_fd; - xdr_enc_t *core_enc; - xdr_dec_t *core_dec; - lg_mutex_t core_sender; - lg_mutex_t core_recver; - int in_core_hm; - - uint16_t lock_port; - xdr_socket lock_fd; - xdr_enc_t *lock_enc; - xdr_dec_t *lock_dec; - lg_mutex_t lock_sender; - lg_mutex_t lock_recver; - int in_lock_hm; - uint8_t lockspace[4]; - - /* in the message recver func, we read data into these buffers and pass - * them to the callback function. This way we avoid doing mallocs and - * frees on every callback. - */ - uint16_t cfba_len; - uint8_t *cfba; - uint16_t cfbb_len; - uint8_t *cfbb; - uint16_t lfba_len; - uint8_t *lfba; - uint16_t lfbb_len; - uint8_t *lfbb; - - uint32_t last_magic; -}; -typedef struct gulm_interface_s gulm_interface_t; - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/lib/libgulm.h b/gulm/lib/libgulm.h deleted file mode 100644 index 671af12..0000000 --- a/gulm/lib/libgulm.h +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -** -******************************************************************************* -******************************************************************************/ -#ifndef __libgulm_h__ -#define __libgulm_h__ -#include <netinet/in.h> -/* bit messy, but we need this to be rather seemless in both kernel and - * userspace. and this seems the easiest way to do it. - */ -#ifdef __KERNEL__ - -#ifdef __linux__ -typedef struct socket* lg_socket; -#endif /*__linux__*/ -#else /*__KERNEL__*/ -typedef int lg_socket; -#endif /*__KERNEL__*/ - -typedef void * gulm_interface_p; - -/* mallocs the interface structure. - * cluster_name can be NULL. If NULL, its ignored. If not NULL, then it - * must be the same as what gulm is running with. Its just an extra, - * optional check if you want it. - * service_name is the unique (to this node) name of the service you're - * going to start. - * - * Both strings are not checked until you call lg_core_login() - */ -int lg_initialize(gulm_interface_p *, char *cluster_name, char *service_name); -/* frees struct. - */ -void lg_release(gulm_interface_p); - -/* if you need to use ports other than the defaults. */ -int lg_set_core_port(gulm_interface_p lgp, uint16_t new); -int lg_set_lock_port(gulm_interface_p lgp, uint16_t new); - -/* Determins where we are with a itemlist callback */ -typedef enum {lglcb_start, lglcb_item, lglcb_stop} lglcb_t; - -/****** Core specifics ******/ - -/* leaving a callback pointer as NULL, will cause that message type to - * be ignored. */ -typedef struct lg_core_callbacks_s { - int (*login_reply)(void *misc, uint64_t gen, uint32_t error, uint32_t rank, - uint8_t corestate); - int (*logout_reply)(void *misc); - int (*nodelist)(void *misc, lglcb_t type, char *name, - struct in6_addr *ip, uint8_t state); - int (*statechange)(void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr *masterip, char *mastername); - int (*nodechange)(void *misc, char *nodename, - struct in6_addr *nodeip, uint8_t nodestate); - int (*service_list)(void *misc, lglcb_t type, char *service); - int (*error)(void *misc, uint32_t err); -} lg_core_callbacks_t; - -/* this will trigger a callback from gulm_core_callbacks_t - * handles one message! Either stick this inside of a thread, - * or in a poll()/select() loop using the function below. - * This will block until there is a message sent from core. - */ -int lg_core_handle_messages(gulm_interface_p, lg_core_callbacks_t*, void *misc); - -/* this returns the filedescriptor that the library is using to - * communicate with the core. This is only for using in a poll() - * or select() call to avoid having the gulm_core_handle_messages() - * call block. - */ -lg_socket lg_core_selector(gulm_interface_p); - -/* Queue requests. */ -int lg_core_login(gulm_interface_p, int important); -int lg_core_logout(gulm_interface_p); -int lg_core_nodeinfo(gulm_interface_p, char *nodename); -int lg_core_nodelist(gulm_interface_p); -int lg_core_servicelist(gulm_interface_p); -int lg_core_corestate(gulm_interface_p); - -/* for completeness mostly. */ -int lg_core_shutdown(gulm_interface_p); -int lg_core_forceexpire(gulm_interface_p, char *node_name); -int lg_core_forcepending(gulm_interface_p); - -/* Node states - * First three are actual states, as well as changes. Last is only a node - * change message. - * */ -#define lg_core_Logged_in (0x05) -#define lg_core_Logged_out (0x06) -#define lg_core_Expired (0x07) -#define lg_core_Fenced (0x08) -/* Core states */ -#define lg_core_Slave (0x01) -#define lg_core_Master (0x02) -#define lg_core_Pending (0x03) -#define lg_core_Arbitrating (0x04) -#define lg_core_Client (0x06) - -/****** lock space specifics *****/ -/* note that this library masks out the lock table seperation. - */ - -typedef struct lg_lockspace_callbacks_s { - int (*login_reply)(void *misc, uint32_t error, uint8_t which); - int (*logout_reply)(void *misc); - int (*lock_state)(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint32_t error, - uint8_t *LVB, uint16_t LVBlen); - int (*lock_action)(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t action, uint32_t error); - int (*drop_lock_req)(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t state); - int (*drop_all)(void *misc); - int (*error)(void *misc, uint32_t err); -} lg_lockspace_callbacks_t; - -/* Like the core handle messages function, but for the lockspace. - * Handles one message, blocks. - */ - -int lg_lock_handle_messages(gulm_interface_p, lg_lockspace_callbacks_t*, - void *misc); - -/* this returns the filedescriptor that the library is using to - * communicate with the ltpx. This is only for using in a poll() - * or select() call to avoid having the gulm_lock_handle_messages() - * call block. - */ -lg_socket lg_lock_selector(gulm_interface_p); - -/* Lockspace request calls */ -int lg_lock_login(gulm_interface_p, uint8_t lockspace[4] ); -int lg_lock_logout(gulm_interface_p); -int lg_lock_state_req(gulm_interface_p, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, - uint8_t *LVB, uint16_t LVBlen); -/* cancel always works on your last pending request. You can only have one - * request pending per key,host,subid triplet. So you don't need to specify - * ranges for a cancel. (which would be confusing.) - */ -int lg_lock_cancel_req(gulm_interface_p, uint8_t *key, uint16_t keylen, - uint64_t subid); - -/* actions opertate on a lock, not sub ranges. */ -int lg_lock_action_req(gulm_interface_p, uint8_t *key, - uint16_t keylen, uint64_t subid, uint8_t action, - uint8_t *LVB, uint16_t LVBlen); -int lg_lock_drop_exp(gulm_interface_p, uint8_t *holder, - uint8_t *keymask, uint16_t kmlen); - -/* state requests */ -#define lg_lock_state_Unlock (0x00) -#define lg_lock_state_Exclusive (0x01) -#define lg_lock_state_Deferred (0x02) -#define lg_lock_state_Shared (0x03) - -/* actions */ -#define lg_lock_act_HoldLVB (0x0b) -#define lg_lock_act_UnHoldLVB (0x0c) -#define lg_lock_act_SyncLVB (0x0d) - -/* flags */ -#define lg_lock_flag_DoCB (0x00000001) -#define lg_lock_flag_Try (0x00000002) -#define lg_lock_flag_Any (0x00000004) -#define lg_lock_flag_IgnoreExp (0x00000008) -#define lg_lock_flag_Cachable (0x00000020) -#define lg_lock_flag_Piority (0x00000040) -#define lg_lock_flag_NoCallBacks (0x00000100) - - -/* These are the possible values that can be in the error fields. */ -#define lg_err_Ok (0) -#define lg_err_BadLogin (1001) -#define lg_err_BadCluster (1003) -#define lg_err_BadConfig (1004) -#define lg_err_BadGeneration (1005) -#define lg_err_BadWireProto (1019) - -#define lg_err_NotAllowed (1006) -#define lg_err_Unknown_Cs (1007) -#define lg_err_BadStateChg (1008) -#define lg_err_MemoryIssues (1009) - -#define lg_err_TryFailed (1011) -#define lg_err_AlreadyPend (1013) -#define lg_err_Canceled (1015) - -#define lg_err_NoSuchFS (1016) -#define lg_err_NoSuchJID (1017) -#define lg_err_NoSuchName (1018) - - -#endif /*__libgulm_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/lib/tests/Makefile b/gulm/lib/tests/Makefile deleted file mode 100644 index a71b9c0..0000000 --- a/gulm/lib/tests/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. - -CFLAGS+= -I${top_srcdir}/include \ - -I${top_srcdir}/lib - -#CFLAGS+=-DDEBUG -CFLAGS+=-g - -LDLIBS+= -lgulm -LOADLIBES += -L${top_srcdir}/lib - -all: coretest basiclocktest - -coretest: core_tests.c - ${CC} ${CFLAGS} ${LDFLAGS} $^ ${LOADLIBES} ${LDLIBS} -o $@ - -basiclocktest: basic_lock_test.c - ${CC} ${CFLAGS} ${LDFLAGS} $^ ${LOADLIBES} ${LDLIBS} -o $@ - - -clean: - rm -f coretest basiclocktest - - diff --git a/gulm/lib/tests/basic_lock_test.c b/gulm/lib/tests/basic_lock_test.c deleted file mode 100644 index 60f2cb9..0000000 --- a/gulm/lib/tests/basic_lock_test.c +++ /dev/null @@ -1,380 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdlib.h> -#include <unistd.h> -#include <stdint.h> -#include <stdio.h> -#include <signal.h> -#include <execinfo.h> -#include <errno.h> -#include <string.h> -#include <sys/poll.h> - -#include "libgulm.h" - -#define die(fmt, arg...) { fprintf(stderr, fmt , ## arg ); exit(1); } -#define TRUE (1) -#define FALSE (0) - -/** - * sigact_segv - - * @sig: - * - * try to get a backtrace before we puke out. - * This may not always work, but since I cannot get daemons to drop core - * files, trying this is better than nothing. - */ -static void sigact_segv(int sig) -{ - struct sigaction act; - void *array[200]; - size_t size,i; - char **strings; - - size = backtrace(array, 200); - strings = backtrace_symbols(array, size); - fprintf(stderr, "BACKTRACE\n"); - for(i=0;i<size; i++) - fprintf(stderr, " %s\n", strings[i]); - free(strings); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - sigaction(SIGSEGV, &act, NULL); - raise(SIGSEGV); -} - -/** - * setupsignals - set how we respond to signals. - */ -static void setupsignals(void) -{ - struct sigaction act; - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_segv; - if( sigaction(SIGSEGV, &act, NULL) <0) - die("Failed to install signal SIGSEGV handler: %s\n",strerror(errno)); - -} - -/** - * lkeytohex - - * @key: - * @keylen: - * - * Returns: char - */ -char *lkeytohex(uint8_t *key, uint8_t keylen) -{ - static uint8_t buf[1024]; - int i; - sprintf(buf, "0x"); - for(i=0; i < keylen && i < 510 ; i++) - sprintf(&buf[(i*2)+2], "%02x", (key[i])&0xff ); - - return buf; -} -char *lvbtohex(uint8_t *lvb, uint8_t lvblen) -{ - static uint8_t buf[1024]; - int i; - sprintf(buf, "0x"); - for(i=0; i < lvblen && i < 510 ; i++) - sprintf(&buf[(i*2)+2], "%02x", (lvb[i])&0xff ); - - return buf; -} -/*****************************************************************************/ -void act_logout_lock(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_lock_logout(hookup))!=0) - die("Error sending lock logout. %d\n", err); -} -void act_logout_core(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_core_logout(hookup))!=0) - die("Error sending core logout. %d\n", err); -} -void act_lock(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_lock_state_req(hookup, "justatest", 10, 0, 0, 0, - lg_lock_state_Exclusive, 0, "FOO!", 5))!=0) - die("Error sending lock request. %d\n", err); -} -void act_locksh(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_lock_state_req(hookup, "justatest", 10, 0, 0, 0, - lg_lock_state_Shared, 0, "BAR!", 5))!=0) - die("Error sending lock request. %d\n", err); -} -void act_unlock(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_lock_state_req(hookup, "justatest", 10, 0, 0, 0, - lg_lock_state_Unlock, 0, NULL, 0))!=0) - die("Error sending unlock request. %d\n", err); -} -void act_hold(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_lock_action_req(hookup, "justatest", 10, 0, - lg_lock_act_HoldLVB, NULL, 0))!=0) - die("Error sending hold request. %d\n", err); -} -void act_unhold(gulm_interface_p hookup, void *misc) -{ - int err; - if((err=lg_lock_action_req(hookup, "justatest", 10, 0, - lg_lock_act_UnHoldLVB, NULL, 0))!=0) - die("Error sending unhold request. %d\n", err); -} - -/*****************************************************************************/ -struct workstep_s { - /* what to do. */ - void (*action)(gulm_interface_p hookup, void *misc); - /* where are we? */ - enum { - ws_ready, - ws_pending, - ws_complete - } state; - /* what we expect. */ -}; - -int All_Done = FALSE; -unsigned int Current_Action = 0; -struct workstep_s Actions[] = { - { act_hold, ws_ready }, - { act_lock, ws_ready }, - { act_locksh, ws_ready }, - { act_unlock, ws_ready }, - { act_unhold, ws_ready }, - { act_logout_lock, ws_ready }, - { act_logout_core, ws_ready } -}; - -void do_action(gulm_interface_p hookup, void *misc) -{ - unsigned int maxact = sizeof(Actions)/sizeof(Actions[0]); - - if( Current_Action >= maxact ) { All_Done = TRUE; return; } - - if( Actions[Current_Action].state == ws_ready ) { - Actions[Current_Action].action(hookup, misc); - Actions[Current_Action].state = ws_pending; - }else - if( Actions[Current_Action].state == ws_pending ) { - /* nop. */ - }else - if( Actions[Current_Action].state == ws_complete ) { - Current_Action ++; - /* call into self. */ - do_action(hookup, misc); - } -} - -void complete_action(void) -{ - unsigned int maxact = sizeof(Actions)/sizeof(Actions[0]); - - if( Current_Action >= maxact ) { All_Done = TRUE; return; } - Actions[Current_Action].state = ws_complete; -} - -/*****************************************************************************/ -int cb_core_login_reply(void *misc, uint64_t gen, uint32_t err, uint32_t rank, uint8_t corestate) -{ - - printf("Got a Core Login reply. gen:%lld err:%d rank:%d corestate:%d\n", - gen, err, rank, corestate); - return 0; -} - -int cb_core_logout_reply(void *misc) -{ - printf("Got Core logout reply\n"); - complete_action(); - return 0; -} - -int cb_nodechange(void *misc, char *nodename, - struct in6_addr *nodeip, uint8_t nodestate) -{ - printf("Got Nodechange, node:%s ip:%#x state:%#x\n", - nodename, nodeip, nodestate); - return 0; -} - -int cb_core_error(void *misc, uint32_t err) -{ - die("Got error reply %d from core\n", err); - return 0; -} - - -/* - * The only thing we need from core is basic login. - */ -lg_core_callbacks_t gulm_core_cbs = { - login_reply: cb_core_login_reply, - logout_reply: cb_core_logout_reply, - nodelist: NULL, - statechange: NULL, - nodechange: cb_nodechange, - service_list: NULL, - error: cb_core_error -}; -/*****************************************************************************/ -int cb_lock_login_reply(void *misc, uint32_t error, uint8_t which) -{ - printf("Got lock login reply: err:%d which:%#x\n", error, which); - return 0; -} - -int cb_lock_logout_reply(void *misc) -{ - printf("Got Lock logout reply\n"); - complete_action(); - return 0; -} - -int cb_lock_drop_all(void *misc) -{ - printf("Got drop all request\n"); - return 0; -} - -int cb_lock_state(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint32_t error, - uint8_t *LVB, uint16_t LVBlen) -{ - if(LVB != NULL ) { - printf("Got lock reply: %s\n" - " state: %#x\n" - " flags: %#x\n" - " error: %d\n" - " lvblen: %d\n" - " lvb: %s\n", - lkeytohex(key, keylen), - state, flags, error, LVBlen, - lvbtohex(LVB, LVBlen) - ); - }else{ - printf("Got lock reply: %s\n" - " state: %#x\n" - " flags: %#x\n" - " error: %d\n" - " lvb: NULL\n", - lkeytohex(key, keylen), - state, flags, error - ); - } - complete_action(); - return 0; -} - -int cb_lock_action(void *misc, uint8_t *key, uint16_t keylen, uint64_t subid, - uint8_t action, uint32_t error) -{ - printf("Got lock reply: %s\n" - " action: %#x\n" - " error: %d\n", - lkeytohex(key, keylen), - action, error - ); - complete_action(); - return 0; -} - -int cb_lock_drop_req(void *misc, uint8_t *key, uint16_t keylen, uint64_t subid, - uint8_t state) -{ - printf("Lock servers wants us to drop lock %s into state %#x\n", - lkeytohex(key, keylen), state); - return 0; -} - -int cb_lock_error(void *misc, uint32_t err) -{ - die("Got error reply %d from lock\n", err); - return 0; -} - -lg_lockspace_callbacks_t gulm_lock_cbs = { - login_reply: cb_lock_login_reply, - logout_reply: cb_lock_logout_reply, - lock_state: cb_lock_state, - lock_action: cb_lock_action, - drop_lock_req: cb_lock_drop_req, - drop_all: cb_lock_drop_all, - error: cb_lock_error -}; -/*****************************************************************************/ - -int main(int argc, char **argv) -{ - int err, cnt; - gulm_interface_p hookup; - struct pollfd pls[2]; - - setupsignals(); - - printf("Starting TestBox For Lock\n"); - - if( (err = lg_initialize(&hookup, NULL, "TestBox For Lock")) != 0 ) { - die("Failed to lg_initialize() err:%d\n",err); - } - - if((err = lg_core_login(hookup, FALSE)) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - if((err = lg_lock_login(hookup, "TEST")) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - - pls[0].fd = lg_core_selector(hookup); - pls[0].events = POLLIN; - pls[1].fd = lg_lock_selector(hookup); - pls[1].events = POLLIN; - - while(!All_Done) { - if( (cnt = poll(pls, 2, 1000)) <= 0 ) { - fprintf(stderr, "poll error: %d\n", cnt); - } - if( pls[0].revents & POLLIN ) { - if((err = lg_core_handle_messages(hookup, &gulm_core_cbs, NULL))!= 0){ - die("Bad return from core handle messages err %d\n", err); - } - } - if( pls[1].revents & POLLIN ) { - if((err = lg_lock_handle_messages(hookup, &gulm_lock_cbs, NULL))!= 0){ - die("Bad return from lock handle messages err %d\n", err); - } - } - - - do_action(hookup, NULL); - } - - lg_release(hookup); - return 0; -} - diff --git a/gulm/lib/tests/core_tests.c b/gulm/lib/tests/core_tests.c deleted file mode 100644 index 6a1359d..0000000 --- a/gulm/lib/tests/core_tests.c +++ /dev/null @@ -1,222 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdlib.h> -#include <unistd.h> -#include <stdint.h> -#include <stdio.h> -#include <signal.h> -#include <execinfo.h> -#include <errno.h> -#include <string.h> -#include <sys/poll.h> - -#include "libgulm.h" - -#define die(fmt, arg...) { fprintf(stderr, fmt , ## arg ); exit(1); } - -/** - * sigact_segv - - * @sig: - * - * try to get a backtrace before we puke out. - * This may not always work, but since I cannot get daemons to drop core - * files, trying this is better than nothing. - */ -static void sigact_segv(int sig) -{ - struct sigaction act; - void *array[200]; - size_t size,i; - char **strings; - - size = backtrace(array, 200); - strings = backtrace_symbols(array, size); - fprintf(stderr, "BACKTRACE\n"); - for(i=0;i<size; i++) - fprintf(stderr, " %s\n", strings[i]); - free(strings); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - sigaction(SIGSEGV, &act, NULL); - raise(SIGSEGV); -} - -/** - * setupsignals - set how we respond to signals. - */ -static void setupsignals(void) -{ - struct sigaction act; - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_segv; - if( sigaction(SIGSEGV, &act, NULL) <0) - die("Failed to install signal SIGSEGV handler: %s\n",strerror(errno)); - -} -/*****************************************************************************/ -int cb_login_reply(void *misc, uint64_t gen, uint32_t err, uint32_t rank, uint8_t corestate) -{ - - printf("Got a Login reply. gen:%lld err:%d rank:%d corestate:%d\n", - gen, err, rank, corestate); - - return 0; -} - -int cb_logout_reply(void *misc) -{ - - printf("Got logout reply\n"); - - return 0; -} - -int cb_nodelist(void *misc, lglcb_t type, char *name, - struct in6_addr *ip, uint8_t state) -{ - if( lglcb_start == type ) { - printf("Got Nodelist, start\n"); - }else - if( lglcb_item == type ) { - printf("Got nodelist, item: %s, %#x, %#x\n", name, ip, state); - }else - if( lglcb_stop == type ) { - printf("Got Nodelist, stop\n"); - }else - { - printf("Unknown lglcb_t %#x\n", type); - } - return 0; -} - -int cb_statechange(void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr *masterip, char *mastername) -{ - printf("Got statechange corestate:%#x quorate:%s masterip:%#x mastername:%s\n", - corestate, quorate?"true":"false", masterip, mastername); - return 0; -} - -int cb_nodechange(void *misc, char *nodename, - struct in6_addr *nodeip, uint8_t nodestate) -{ - printf("Got Nodechange, node:%s ip:%#x state:%#x\n", - nodename, nodeip, nodestate); - return 0; -} - -int cb_service_list(void *misc, lglcb_t type, char *service) -{ - if( lglcb_start == type ) { - printf("Got service_list, start\n"); - }else - if( lglcb_item == type ) { - printf("Got service_list, item: %s\n", service); - }else - if( lglcb_stop == type ) { - printf("Got service_list, stop\n"); - }else - { - printf("Unknown lglcb_t %#x\n", type); - } - return 0; -} - -int cb_error(void *misc, uint32_t err) -{ - printf("Got error %d\n", err); - return 0; -} - - -int main(int argc, char **argv) -{ - int err; - gulm_interface_p hookup; - lg_core_callbacks_t lcb; -#if 0 - struct pollfd pls[2]; -#endif - setupsignals(); - - printf("Starting TestBox For Core\n"); - - if( (err = lg_initialize(&hookup, NULL, "TestBox For Core")) != 0 ) { - die("Failed to lg_initialize() err:%d\n",err); - } - - lcb.login_reply = cb_login_reply; - lcb.logout_reply = cb_logout_reply; - lcb.nodelist = cb_nodelist; - lcb.statechange = cb_statechange; - lcb.nodechange = cb_nodechange; - lcb.service_list = cb_service_list; - lcb.error = cb_error; - - - if((err = lg_core_login(hookup, 0)) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - - if((err = lg_core_handle_messages(hookup, &lcb, NULL)) != 0 ) { - die("Bad return from handle messages err %d\n", err); - } - - sleep(2); /* no real reason for this. */ - - if((err = lg_core_servicelist(hookup)) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - - if((err = lg_core_handle_messages(hookup, &lcb, NULL)) != 0 ) { - die("Bad return from handle messages err %d\n", err); - } - - sleep(2); /* no real reason for this. */ - - if((err = lg_core_nodelist(hookup)) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - - if((err = lg_core_handle_messages(hookup, &lcb, NULL)) != 0 ) { - die("Bad return from handle messages err %d\n", err); - } - - sleep(2); /* no real reason for this. */ - - if((err = lg_core_corestate(hookup)) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - - if((err = lg_core_handle_messages(hookup, &lcb, NULL)) != 0 ) { - die("Bad return from handle messages err %d\n", err); - } - - sleep(2); /* no real reason for this. */ - - - - if((err = lg_core_logout(hookup)) != 0 ) { - die("Failed to send login request to core. err %d\n", err); - } - - if((err = lg_core_handle_messages(hookup, &lcb, NULL)) != 0 ) { - die("Bad return from handle messages err %d\n", err); - } - - lg_release(hookup); - return 0; -} diff --git a/gulm/make/defines.mk.input b/gulm/make/defines.mk.input deleted file mode 100644 index 5182fdd..0000000 --- a/gulm/make/defines.mk.input +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}@SBINDIR@ -mandir ?= ${DESTDIR}@MANDIR@ -libdir ?= ${DESTDIR}@LIBDIR@ -incdir ?= ${DESTDIR}@INCDIR@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/gulm/make/release.mk.input b/gulm/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/gulm/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/gulm/man/Makefile b/gulm/man/Makefile deleted file mode 100644 index de89dc7..0000000 --- a/gulm/man/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd .. ; ${MAKE} - -clean: - cd .. ; ${MAKE} clean - diff --git a/gulm/man/gulm_tool.8 b/gulm/man/gulm_tool.8 deleted file mode 100644 index 71f989a..0000000 --- a/gulm/man/gulm_tool.8 +++ /dev/null @@ -1,171 +0,0 @@ -." -." Copyright 2001-2003 Sistina Software, Inc. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - - -." groff -t -e -mandoc -Tlatin1 gulm_tool.8 | less - -.tl 'gulm_tool(8)' 'gulm_tool(8)' - -\fBNAME\fP -.in +7 -gulm_tool - Interface to Grand Unified Lock Manager -.sp -.in -7 -\fBSYNOPSIS\fP -.in +7 -\fBgulm_tool\fP command [options] -.sp -.in -7 - -\fBDESCRIPTION\fP -.in +7 -\fBgulm_tool\fP is an interface to a variety of options available to -running \fBlock_gulmd\fP servers. - -The second parameter for most commands is the hostname or IP of the server -followed by the port at -which it runs. Keep in mind that in the simplest setup, there are three -servers running on a host. For this, there is a short hand for the default -server ports. So you can use "core", "ltpx", and "lt000" through "lt256" -for the port value instead of the actual number. If you are using -different ports for the \fBlock_gulmd\fP servers, you will need to use the -numbers. If you don't specify the port, "core" is assumed. - -.sp -.in -7 - -\fBCOMMANDS\fP -.in +7 - -."====================================== -\fBCommands that only core understands\fP -.in +7 - -\fBshutdown\fP \fIserver\fR:core -.in +7 -This command is use to stop a gulm server cleanly. This can only be sent -to the "core" port. - -The use of this command is the proper way to shutdown gulm servers. It is -preferred over the use of SIGTERM. Any other method will result in a -fencing action against the server node. -.sp -.in -7 - -\fBnodelist\fP \fIserver\fR:core -.in +7 -Get a list of the nodes currently logged into the master server. -.in -7 - -\fBnodeinfo\fP \fIserver\fR:core \fInode name\fR -.in +7 -Get information for a single node. -.in -7 - -\fBservicelist\fP \fIserver\fR:core -.in +7 -Get list of services connected to this node. -.in -7 - -\fBforeceexpire\fP \fIserver\fR:core \fInode name\fR -.in +7 -Force the node to move into the Expired State. This will cause the node to -be fenced. -.in -7 - - -.in -7 -."====================================== -\fBCommands that can be sent to any server\fP -.in +7 - -\fBgetstats\fP \fIserver:port\fR -.in +7 -This gets a list of whatever statistics the specified server carries. -.sp -.in -7 - -\fBsetverb\fP \fIserver:port\fR \fIverbose_flags\fR -.in +7 -Sets which types of messages can be logged. - -\fIverbose flags\fR is a comma separated list of the possible flags. If a -flag is prefixed with a '-', it is unset, other wise it is set. The -special flag 'clear' unsets all verbosity flags. Any flag that is not -recognized is ignored. - -The verbosity flags for gulm: - -.TS -l l. -Network Basic network related messages -Network2 T{ -More specific network messages -T} -Network3 A debug message for nearly every packet -Fencing T{ -When calling out to the fencing sub-system -T} -Heartbeat T{ -Every heartbeat sent and received -T} -Locking T{ -Various internal informational messages about the locks -T} -Forking T{ -Anytime a child processes is spawned -T} -ServerState T{ -Print out a message when ever the server changes state, saying what state -it is now in. -T} -JIDMap T{ -Details of each JID Mapping request -T} -LockUpdates T{ -Lock requests sent to slaves -T} -LoginLoops T{ -Messages related to searching for and becoming the Master -T} - -ReallyAll All messages above -Default same as -v "Network,Fencing,Forking" -All T{ -same as -v "ReallyAll,-Network3,-LockUpdates" -T} -.TE - -Since Network3, and LockUpdates are so verbose, and rarely -needed, they are excluded from the 'All' flag. - -Do not use ReallyAll unless you are willing to deal with 100M and larger -log files. A loaded system can produce up to a megabyte a minute with the -ReallyAll flag. - -.sp -.in -7 - -.in -7 -."====================================== -\fBCommands that only gulm_tool understands\fP -.in +7 - -\fBversion\fP or \fB-V\fP -.in +7 -Print out the version information of this program. -.in -7 - -\fB--help\fP or \fB-h\fP -.in +7 -Print out the commands with brief descriptions. -.in -7 - -.in -7 -.in -7 - -\fBSEE ALSO\fP -.in +7 -lock_gulmd(8) - diff --git a/gulm/man/lock_gulmd.5 b/gulm/man/lock_gulmd.5 deleted file mode 100644 index 19064e0..0000000 --- a/gulm/man/lock_gulmd.5 +++ /dev/null @@ -1,140 +0,0 @@ -." -." Copyright 2001-2003 Sistina Software, Inc. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -." groff -t -e -mandoc -Tlatin1 lock_gulmd.5 | less - -.tl 'lock_gulmd(5)' 'lock_gulmd(5)' - -\fBNAME\fP -.in +7 -lock_gulm - configuration section for lock_gulmd -.sp -.in -7 - - -\fBDESCRIPTION\fP -.in +7 -This is the subsection to the cluster section in the cluster.conf file for -configuring gulm (Which is both the server, lock_gulmd, and the kernel -module lock_gulm.o). - -Most configurations need only the servers key. All other keys are optional, -as the defaults work for nearly all cases. - -All gulm options are withing the <gulm></gulm> section, which should be placed -above the <clusternodes/> section. - -Most of the config keys are equal to the long options on the command line. - -\fIlockserver\fR -.in +7 -An IP or host name that is allowed to be a server. -This has no default value. You must supply 1, 3, 4, or 5 of these values, -and the nodes must be listed in the <clusternodes/> section. - -You can use either IPs or names. Either IPv4 or IPv6 addresses can be -used. Node names are looked up via libresolv into IPs. IPv6 addresses -will be used over IPv4 addresses. - -.in -7 - -\fIheartbeat_rate\fR -.in +7 -The rate at which the heartbeats are checked by the server in seconds. -Two-thirds of this time is the rate at which the heartbeats are sent. -Default is 15. -.in -7 - -\fIallowed_misses\fR -.in +7 -How many consecutive heartbeats can be missed before we mark the node -expired. -Default is 2. -.in -7 - -\fIcoreport\fR -.in +7 -The port used by the gulm core. -Default is 40040. -.in -7 - -\fIltpx_port\fR -.in +7 -The port used by the LTPX. -Default is 40042. -.in -7 - -\fIlt_port\fR -.in +7 -What port the first lock table uses. Each additional lock table will -increment this to get their port. (If you have lt_partitions greater than 1.) -Default is 41040. -.in -7 - -\fIlt_partitions\fR -.in +7 -How many partitions of the lock space should there be. Typically, one -partition per cpu on the server nodes seems to be the best. -Default is 1. -.in -7 - - -.sp -.in -7 - -\fBEXAMPLES\fP -.in +7 - -Using IPv4 addresses: - - <cluster name="example" config_version="1"> - - <gulm> - <lockserver name="192.168.1.1"/> - <lockserver name="192.168.1.2"/> - <lockserver name="192.168.1.3"/> - </gulm> - - <!-- other require sections covered elsewhere --> - - </cluster> - - -Using IPv6 addresses: (while still being on a IPv4 network) - - <cluster name="example" config_version="1"> - - <gulm> - <lockserver name="::ffff:192.168.1.1"/> - <lockserver name="::ffff:192.168.1.2"/> - <lockserver name="::ffff:192.168.1.3"/> - </gulm> - - <!-- other require sections covered elsewhere --> - - </cluster> - -Using node names, these are looked up with libresolv to get IPs: - - <cluster name="example" config_version="1"> - - <gulm> - <lockserver name="node01"/> - <lockserver name="node02"/> - <lockserver name="node03"/> - </gulm> - - <!-- other require sections covered elsewhere --> - - </cluster> - - - -.sp -.in -7 - -\fBSEE ALSO\fP -.in +7 -lock_gulmd(8), ccs(7) - diff --git a/gulm/man/lock_gulmd.8 b/gulm/man/lock_gulmd.8 deleted file mode 100644 index bb3ebc7..0000000 --- a/gulm/man/lock_gulmd.8 +++ /dev/null @@ -1,373 +0,0 @@ -." -." Copyright 2001-2003 Sistina Software, Inc. -." Copyright (C) 2004 Red Hat, Inc. All rights reserved. - -." groff -t -e -mandoc -Tlatin1 gulm.8 | less - -.tl 'lock_gulmd(8)' 'lock_gulmd(8)' - -\fBNAME\fP -.in +7 -lock_gulmd - Grand Unified Lock Manager -.sp -.in -7 -\fBSYNOPSIS\fP -.in +7 -\fBlock_gulmd\fP --cluster_name <string> [options] -.sp -.in -7 - -\fBDESCRIPTION\fP -.in +7 -\fBlock_gulmd\fP is a lock manager for \fBGFS\fP that was -designed to take advantage of the way \fBGFS\fP uses locks, and the way data -is transferred over TCP/IP. - -\fBlock_gulmd\fP supports failover so that your gfs cluster can keep -running if the lockserver machine dies (or if one machine of a lockserver -cluster dies). -You can also run \fBlock_gulmd\fP -on the same nodes that mount your gfs filesystem(s). - -\fBlock_gulmd\fP is really three servers in one: It contains the core, -locktable interface, -and locktable servers. Each of these gets its own process, and the -locktable server may get more than one process depending on your config. -Core is responsible for client membership and heartbeats. -Locktable and locktable interface handle the locking. -Multiple locktable processes can be run to improve performance on SMP systems -via the \fIlt_partitions\fR option in the configuration. - -.sp -.in -7 - -\fBOPTIONS\fP -.in +7 -You can completely configure gulm from the command line. If you do this, you -need to use the same options on every node in the cluster. You should -always specify the \fB--cluster_name\fP option, and then either the -\fB--use_ccs\fP or the \fB--servers\fP options. Then other options should -follow. - -\fB-h --help\fP -.in +7 -Print usage information, then exit. - -.sp -.in -7 -\fB-V --version\fP -.in +7 -Print version information, then exit. - -.sp -.in -7 -\fB-c --use_ccs\fP -.in +7 -Make the calls out to ccsd load config from cluster.conf. Will override any -previous options. Likewise, options that follow this will override settings -from ccs. - -.sp -.in -7 -\fB-v --verbosity\fP \fIverbose flags\fR -.in +7 -Sets which types of messages can be logged. - -\fIverbose flags\fR is a comma separated list of the possible flags. If a -flag is prefixed with a '-', it is unset, other wise it is set. The -special flag 'clear' unsets all verbosity flags. Any flag that is not -recognized is ignored. - -The verbosity flags for gulm: - -.TS -l l. -Network Basic network related messages -Network2 T{ -More specific network messages -T} -Network3 Nothing currently -Fencing T{ -When calling out to the fencing sub-system -T} -Heartbeat T{ -Every heartbeat sent and received -T} -Locking T{ -Various internal informational messages about the locks -T} -Forking T{ -Anytime a child processes is spawned -T} -ServerState T{ -Print out a message when ever the server changes state, saying what state -it is now in. -T} -JIDMap T{ -Details of each JID Mapping request -T} -JIDUpdates T{ -JID Mapping updates sent to slaves -T} -LockUpdates T{ -Lock requests sent to slaves -T} -LoginLoops T{ -Messages related to searching for and becoming the Master -T} - -ReallyAll All messages above -Default same as -v "Network,Fencing,Forking" -All T{ -same as -v "ReallyAll,-Network3,-JIDUpdates,-LockUpdates" -T} -.TE - -The verbose flags can be changed while \fBlock_gulmd\fP is running with -\fBgulm_tool\fP. - -Default is Default. (witty no?) - -.sp -.in -7 -\fB-s --servers\fP \fIserver list\fR -.in +7 -Comma seperated list of nodes that can be master servers. -No default. - -You can use either IPs or names. Either IPv4 or IPv6 addresses can be -used. Node names are looked up via libresolv into IPs. IPv6 addresses -will be used over IPv4 addresses. - -.sp -.in -7 -\fB-n --cluster_name\fP \fIstring\fR -.in +7 -The name of this cluster. -No default. - -.sp -.in -7 -\fB--heartbeat_rate\fP \fInumber\fR -.in +7 -Number of seconds to wait before checking for missed heartbeats. 2/3 of this -value is the rate at which nodes send heartbeats to the master server. You can -specify this as a floating point number to get less than a second times. - -Use subsecond values at your own risk, as varying network -loads can cause false node expirations. - -Default is 15. - -.sp -.in -7 -\fB--allowed_misses\fP \fInumber\fR -.in +7 -How many heartbeats can be missed before the node is considered to have expired. -Default is 2. - -.sp -.in -7 -\fB--new_connection_timeout\fP \fInumber\fR -.in +7 -How many seconds to wait before deciding a new socket is bogus and dropping it. -Can use floating point for sub second values. -Default is 15. - -.sp -.in -7 -\fB--master_scan_delay\fP \fInumber\fR -.in +7 -How many seconds between each probe for a new master server. -Can use floating point for sub second values. -Default is 1. - -.sp -.in -7 -\fB--coreport\fP \fInumber\fR -.in +7 -Which port does the core server listen on and connect to. -Default is 40040. - -.sp -.in -7 -\fB--ltpxport\fP \fInumber\fR -.in +7 -Which port does the ltpx server listen on and lock clients connect to. -Default is 40042. - -.sp -.in -7 -\fB--ltport\fP \fInumber\fR -.in +7 -Which port does the LT server listen on, and LT and LTPX clients connect to. -If you have multiple \fBlt_partitions\fP, the LT's id is added to this to get -its port. (Using the default, LT000 is at 41040, LT001 is at 41041, ect) -Default is 41040. - -.sp -.in -7 -\fB--fence_bin\fP \fIstring\fR -.in +7 -The name of the program that handles fencing nodes for gulm. This needs to be a -full path. - -The program takes a single argument, the name of the node to be fenced. If the -program returns an exit status of 0, then the fencing was succesful. Otherwise -gulm waits 5 seconds, and calls it again. - -Default is /sbin/fence_node - -.sp -.in -7 -\fB--run_as\fP \fIstring\fR -.in +7 -User to switch into and run as. Default is root. (which is not good.) - -.sp -.in -7 -\fB--lock_dir\fP \fIstring\fR -.in +7 -The directory to place and store the pid lock files. -Default is /var/run/sistina/ - -.sp -.in -7 -\fB--lt_partitions\fP \fInumber\fR -.in +7 -Number of Lock Tables to run. If more than one there will be -multiple LTs, and the LTPXes will stripe the locks across the LTs. This is for -preformance on servers with multiple CPUs. -Default is 1. - -.sp -.in -7 -\fB--name\fP \fIstring\fR -.in +7 -Set the name of this gulm server to \fIstring\fR instead of the default. -Default is output of `uname -n`. - -.sp -.in -7 -\fB--ip\fP \fIip addr\fR -.in +7 -Set the IP of this gulm server to \fIip addr\fR instead of trying to -resolve it from the name. -Default is to resolve this gulm servers name into an IP. - -.sp -.in -7 -\fB--ifdev\fP \fInetwork device name\fR -.in +7 -Use the IP that is configured for this \fInetwork device name\fR. If there -is an IPv6 address, that is used. Otherwise the IPv4 will be used. -No default. - -.sp -.in -7 -\fB-e\fP -.in +7 -When switching into daemon mode, leave stderr and stdout open. - -.sp -.in -7 -\fB-d\fP -.in +7 -Do not damonize. (will still fork each server.) - -.sp -.in -7 -\fB-C\fP -.in +7 -Load all config items (command line arguments and ccs data), and print -configuration as we see it and exit. - -.sp -.in -7 -.in -7 - -\fBSIGNALS\fP -.in +7 - -\fBSIGTERM\fP -.in +7 -This signal is ignored. To stop gulm you should use the shutdown command -to gulm_tool. - -.in -7 - -\fBSIGUSR1\fP -.in +7 -Dump out internal tables for debugging. This creates a bunch of files in -\fI/tmp\fR (or whatever you have TMPDIR set to). All of these start with -the prefix \fIGulm_\fR and will be appended to if the file already exists. - -Much of the information in these dump files is available via -\fBgulm_tool\fP, and \fBgulm_tool\fP is the preferred method of getting this -information; the action of dumping these tables out stops all other activity -and thus can have negative affects on the performance of \fBlock_gulmd\fP. You -should not send this signal unless you really want those dump files and -know what to do with them. -.in -7 - -.in -7 - - -\fBPRIVATE NETWORKS\fP -.in +7 - -Getting gulm to use a private network is a matter of not relying on IP -lookups. Sepcify all of the <lockserver/> entries with IP addresses. Then -when starting lock_gulmd, make use of either the --ip option or the --ifdev -option. - -.sp -.in -7 - - -\fBEXAMPLES\fP -.in +7 - -When using ccs to configure gulm, start the daemon with: - lock_gulmd --cluster_name foo --use_ccs - -or: - lock_gulmd -n foo -c - -\fBlock_gulmd\fP can be run without CCS: - lock_gulmd -n foo -s 192.168.1.1,192.168.1.2,192.168.1.3 - -This adds the following two verbose flags to the default set: - lock_gulmd -n foo -c -v "Heartbeat,Locking" - -Show only the Network messages: - lock_gulmd -n foo -c -v "clear,Network" - -Use the ip on the second ethernet device, and call me bar: - lock_gulmd -n foo -c --name bar --ifdev eth1 - -Stopping the server: - gulm_tool shutdown localhost - -.in -7 - -\fBFILES\fP -.in +7 -\fB/var/run/sistina/lock_gulmd_core.pid\fP - -\fB/var/run/sistina/lock_gulmd_LTPX.pid\fP - -\fB/var/run/sistina/lock_gulmd_LT000.pid\fP -.in +7 -These are the pid lock files to keep more than one instance of the servers -running per node. They can be put elsewhere via a configuration option. - -.in -7 -.in -7 - -\fBSEE ALSO\fP -.in +7 -gulm_tool(8), lock_gulmd(5), ccs(7) - -.in -7 - diff --git a/gulm/scripts/uninstall.pl b/gulm/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/gulm/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/gulm/src/LLi.h b/gulm/src/LLi.h deleted file mode 100644 index 836bd06..0000000 --- a/gulm/src/LLi.h +++ /dev/null @@ -1,114 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * circular linked list without mallocs. - * - * Now if I did this right, you should be able to put this into the middle - * of some other struct, and it will work. - * - * More importantly, you should be able to have that one larger struct be - * in the middle of two different LLi lists. - * - * It is generally a wise idea to set the data pointer for the list head to - * NULL. So wise, that we'll do it for you.(LLi_init_head) - * - */ -#ifndef __LLi_h__ -#define __LLi_h__ - -typedef struct LLi_s { - struct LLi_s *next; - struct LLi_s *prev; - void *data; -} LLi_t; - -/** - * LLi_init - initialize this list item to be useful. - */ -static void __inline__ LLi_init(LLi_t *i, void *d) -{ - i->next = i; - i->prev = i; - i->data = d; -} -#define LLi_init_head(i) LLi_init((i),NULL) -/* use this like: LLi_t Item = LLi_Static_init_head; */ -#define LLi_Static_init_head {&item,&item,NULL} -#define LLi_Static_head_init(a) LLi_t (a) = {&(a),&(a),NULL} - -/* - * LLi_unhook - reset the next and prev pointers. DONOT call this before - * calling LLi_del! - */ -static void __inline__ LLi_unhook(LLi_t *i) -{ - i->next = i; - i->prev = i; -} - -/* - * LLi_add_after - add item n after item c - */ -static void __inline__ LLi_add_after(LLi_t *c, LLi_t *n) -{ - n->next = c->next; - c->next = n; - n->prev = c; - n->next->prev = n; -} - -/* - * LLi_add_before - add item n before item c - */ -static void __inline__ LLi_add_before(LLi_t *c, LLi_t *n) -{ - n->prev = c->prev; - c->prev = n; - n->next = c; - n->prev->next = n; -} - -/* - * LLi_del - remove item from list. NOTE! item's pointers are still valid! - */ -static void __inline__ LLi_del(LLi_t *c) -{ - c->prev->next = c->next; - c->next->prev = c->prev; -} - -/* - * LLi_pop - pop an item off of the list. Useful for Queues and Stacks - */ -static LLi_t __inline__ *LLi_pop(LLi_t *c) -{ - LLi_t *t; - if( (c)->next == (c) ) return NULL; - t = c->next; - LLi_del(t); - LLi_unhook(t); - return t; -} - -/* try to always use these if you want "low level" access to the - * LinkedList. That way the details can change and you shouldn't need to - * fix your code. - */ -#define LLi_data(i) ((i)->data) -#define LLi_next(i) ((i)->next) -#define LLi_prev(i) ((i)->prev) - -#define LLi_empty(i) ((i)->next == (i)) - -#endif /*__LLi_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/Makefile b/gulm/src/Makefile deleted file mode 100644 index 99c9292..0000000 --- a/gulm/src/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: lock_gulmd gulm_tool - -.PHONY: lock_gulmd gulm_tool clean dep depends - -lock_gulmd: - cd .. && ${MAKE} src/lock_gulmd - -gulm_tool: - cd .. && ${MAKE} src/gulm_tool - -clean: - cd .. && ${MAKE} clean - -dep depends: - cd .. && ${MAKE} depends - diff --git a/gulm/src/Qu.h b/gulm/src/Qu.h deleted file mode 100644 index 4b3d25e..0000000 --- a/gulm/src/Qu.h +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2001 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * Queues! - * uses LLi for its dirty work - */ -#ifndef __Qu_h__ -#define __Qu_h__ - -#include "LLi.h" - -typedef LLi_t Qu_t; - -#define Qu_init(i,d) LLi_init((i),(d)) -#define Qu_init_head(i) LLi_init((i),NULL) -#define Qu_empty(Q) LLi_empty(Q) -#define Qu_data(i) LLi_data(i) -#define Qu_EnQu(Q,i) LLi_add_before((Q),(i)) -#define Qu_EnQu_Front(Q,i) LLi_add_after((Q),(i)) -#define Qu_DeQu(Q) LLi_pop(Q) -#define Qu_peek(Q) LLi_next(Q) - -#endif /*__Qu_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/config_ccs.c b/gulm/src/config_ccs.c deleted file mode 100644 index 397f195..0000000 --- a/gulm/src/config_ccs.c +++ /dev/null @@ -1,212 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "gulm_defines.h" -#include "config_gulm.h" -#include "config_priv.h" -#include "utils_ip.h" -#include "utils_verb_flags.h" -#include "ccs.h" - -/* Mostly, this is the extra functions I need to get stuff from the ccslib. - * And a few wrapper functions so things work cleanly with it. - */ - -/*****************************************************************************/ -/* First data that is stored in the main. */ - -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/* confed things. */ -extern gulm_config_t gulm_config; - -/*****************************************************************************/ - -void parse_serverlist(gulm_config_t *gf, int cd) -{ - char *tmp; - ip_name_t *in; - int first=TRUE; - - for(;;) { - if( ccs_get_list(cd, "/cluster/gulm/lockserver/@name", &tmp) != 0 ) - break; - if( first ) { - /* this `overwrites' previous entries so... */ - if( !LLi_empty(&gf->node_list) ) { - release_node_list(&gf->node_list); - gf->node_cnt = 0; - LLi_init_head(&gf->node_list); - } - first = FALSE; - } - if( tmp == NULL ) break; - in = get_ipname(tmp); - if( in == NULL || in->name == NULL ) { - fprintf(stderr, "Look up on "%s" failed. skipping\n", tmp); - }else{ - if( gf->node_cnt < 5 ) { - LLi_add_before( &gf->node_list, &in->in_list ); - gf->node_cnt ++; - }else{ - fprintf(stderr, "Skipping server entry "%s" since the max of five" - " has been reached.\n", tmp); - free(in); - } - } - free(tmp); - } -} - -/** - * parse_ccs - - * @gf: - * - * Returns: int - */ -int parse_ccs(gulm_config_t *gf) -{ - int cd; - uint64_t temp; - char *tmp; - - if( gf->clusterID == NULL ) { - fprintf(stderr, "Warning! You didn't specify a cluster name before " - "--use_ccs\n Letting ccsd choose which cluster we belong to.\n"); - } - - if( (cd=ccs_force_connect(gf->clusterID, 0)) < 0 ) { - fprintf(stderr, "No ccsd, checking for cmdline config. (%d:%s)\n", - cd, strerror(abs(cd))); - cd = -1; - return -1; - } - - if( ccs_get(cd, "/cluster/@name", &tmp) == 0 ) { - strdup_with_free((char**)&gf->clusterID, tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/servers", &tmp) == 0 ) { - parse_cmdline_servers(gf, tmp); - fprintf(stderr, "Warning, use of /cluster/gulm/servers is deprecated.\n"); - free(tmp); - } - - parse_serverlist(gf, cd); - - if( ccs_get(cd, "/cluster/gulm/@verbosity", &tmp) == 0 ) { - set_verbosity(tmp, &verbosity); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@heartbeat_rate", &tmp) == 0 ) { - temp = ft2uint64(atof(tmp)); - gf->heartbeat_rate = bound_to_uint64(temp, 75000, (uint64_t)~0); - /* min is 0.075 */ - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@allowed_misses", &tmp) == 0 ) { - gf->allowed_misses = bound_to_uint16(atoi(tmp), 1, 0xffff); - free(tmp); - } - - if( ccs_get(cd,"/cluster/gulm/@new_connection_timeout", &tmp)==0) { - temp = ft2uint64(atof(tmp)); - gf->new_con_timeout = bound_to_uint64(temp, 0, (uint64_t)~0); - /* min should be something bigger than zero... - * say 0.5? why? - */ - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@master_scan_delay", &tmp) == 0 ) { - temp = ft2uint64(atof(tmp)); - gf->master_scan_delay = bound_to_uint64(temp, 10, (uint64_t)~0); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@coreport", &tmp) == 0 ) { - gf->corePort = atoi(tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@ltpxport", &tmp) == 0 ) { - gf->ltpx_port = atoi(tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@ltport", &tmp) == 0 ) { - gf->lt_port = atoi(tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@fence_bin", &tmp) == 0 ) { - strdup_with_free((char**)&gf->fencebin, tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@run_as", &tmp) == 0 ) { - strdup_with_free((char**)&gf->run_as, tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@lock_dir", &tmp) == 0 ) { - strdup_with_free((char**)&gf->lock_file, tmp); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@lt_partitions", &tmp) == 0 ) { - gf->how_many_lts = bound_to_uint16(atoi(tmp), 1, 256); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@lt_high_locks", &tmp) == 0 ) { - gf->lt_maxlocks = bound_to_ulong(atoi(tmp), 10000, ~0UL); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@lt_drop_req_rate", &tmp) == 0 ) { - gf->lt_cf_rate = bound_to_uint(atoi(tmp), 5, ~0U); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@prealloc_locks", &tmp) == 0 ) { - gf->lt_prelocks = bound_to_uint(atoi(tmp), 0, ~0U); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@prealloc_holders", &tmp) == 0 ) { - gf->lt_preholds = bound_to_uint(atoi(tmp), 0, ~0U); - free(tmp); - } - - if( ccs_get(cd, "/cluster/gulm/@prealloc_lkrqs", &tmp) == 0 ) { - gf->lt_prelkrqs = bound_to_uint(atoi(tmp), 0, ~0U); - free(tmp); - } - - ccs_disconnect(cd); - cd = -1; - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/config_ccs.h b/gulm/src/config_ccs.h deleted file mode 100644 index f9b807d..0000000 --- a/gulm/src/config_ccs.h +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __config_ccs__ -#define __config_ccs__ -int verify_filesystemname(char *name); -#endif /*__config_ccs__*/ - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/config_cmdline.c b/gulm/src/config_cmdline.c deleted file mode 100644 index 8f251b0..0000000 --- a/gulm/src/config_cmdline.c +++ /dev/null @@ -1,340 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <getopt.h> - -#include "gulm_defines.h" -#include "config_gulm.h" -#include "config_priv.h" -#include "LLi.h" -#include "utils_ip.h" -#include "utils_dir.h" -#include "utils_crc.h" -#include "utils_verb_flags.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/*****************************************************************************/ - -void parse_cmdline_servers(gulm_config_t *gf, char *servers) -{ - char *workspace = NULL; - char *token, *next; - int wl, tl; - ip_name_t *in; - - if( servers == NULL ) goto exit; - - workspace = strdup(servers); - if( workspace == NULL ) goto exit; - - /* this `overwrites' previous entries so... */ - if( !LLi_empty(&gf->node_list) ) { - release_node_list(&gf->node_list); - gf->node_cnt = 0; - LLi_init_head(&gf->node_list); - } - - wl = strlen(workspace); - if( wl == 0 ) goto exit;/* right, so I'm not using strtok why? */ - for(token = workspace, tl=0; tl < wl && - token[tl] != ',' && - token[tl] != ' ' && - token[tl] != '\0'; - tl++); - token[tl] = '\0'; /* damn need to names to be terminated.*/ - next = token + tl + 1; - - for(;;) { - /* We can get empty tokens here given inlined spaces. - * so tl == 0, is skippable. - */ - if( tl > 0 ) { - /* figure out name and ip from whatever they gave us */ - in = get_ipname(token); - - if( in == NULL ) goto exit; - if( in->name == NULL ) { - fprintf(stderr, "I cannot find the name for ip "%s". Stopping.\n", - token); - goto exit; - } - - if( gf->node_cnt < 5 ) { - LLi_add_before( &gf->node_list, &in->in_list ); - gf->node_cnt ++; - }else{ - fprintf(stderr, "Skipping server entry "%s" since the max of five" - " has been reached.\n", token); - free(in); - } - - } - - if( next >= workspace + wl ) goto exit; - for(token = next, tl = 0; - tl < wl && - token[tl] != ',' && - token[tl] != ' ' && - token[tl] != '\0'; - tl++); - token[tl] = '\0'; - next = token + tl +1; - } - -exit: - if( workspace != NULL ) free(workspace); -} - -void usage(void) -{ - char *strings[] = { - "Usage:\n", - "\n", - "lock_gulmd [options]\n", - "Options:\n", - " --version -V Print the version and quit.\n", - " --help -h This text\n", - " -C Test config and stop.\n", - " -e Don't close stderr and stdout\n", - " -d Don't fork on daemonize\n", - " --verbosity <list> -v <list> List of flags.\n", - "\n", - " --name <name> Set my name to this.\n", - " --ip <ip address> Set my IP to this.\n", - " --ifdev <string> Use IP of this ifdev.\n", - "\n", - " --use_ccs -c Read config values from ccs.\n", - "\n", - " --servers <list> -s <list> List of names or IPs.\n", - " --cluster_name <name> -n <name> The name of this cluster\n", - "\n", - " --heartbeat_rate <time> How often to check heartbeats\n", - " --allowed_misses <number> How many concurrent missable\n", - " --new_connection_timeout <time> How long to wait on new sockets\n", - " --master_scan_delay <time> How long between probes.\n", - "\n", - " --coreport <port> Which port to use.\n", - " --ltpxport <port> Which port to use.\n", - " --ltport <port> Which port to use.\n", - "\n", - " --fence_bin <path> full path to fence binary\n", - " --run_as <user> User to switch into\n", - " --lock_dir <path> Where are pid lock files kept\n", - " --lt_partitions <number> How many Lock table partitions.\n", - NULL - }; - int i; - for(i=0; strings[i] != NULL; i++) - printf("%s", strings[i]); - exit(ExitGulm_Usage); -} - -enum { - forgotten_long_opt = 0, - coreport_opt = 1, - ltpxport_opt, - ltport_opt, - hbr_opt, - am_opt, - nct_opt, - msd_opt, - fb_opt, - ra_opt, - ld_opt, - lp_opt, - lhl_opt, - ldrr_opt, - pal_opt, - pah_opt, - par_opt, - name_opt, - ip_opt, - ifdev_opt -}; -static struct option long_options[] = { - {"version", 0, 0, 'V'}, - {"help", 0, 0, 'h'}, - - {"use_ccs", 0, 0, 'c'}, - - {"name", 1, 0, name_opt}, - {"ip", 1, 0, ip_opt}, - {"ifdev", 1, 0, ifdev_opt}, - - {"coreport", 1, 0, coreport_opt}, - {"ltpxport", 1, 0, ltpxport_opt}, - {"ltport", 1, 0, ltport_opt}, - - {"heartbeat_rate", 1, 0, hbr_opt}, - {"allowed_misses", 1, 0, am_opt}, - {"new_connection_timeout", 1, 0, nct_opt}, - {"master_scan_delay", 1, 0, msd_opt}, - - {"verbosity", 1, 0, 'v'}, - {"servers", 1, 0, 's'}, - {"cluster_name", 1, 0, 'n'}, - - {"fence_bin", 1, 0, fb_opt}, - {"run_as", 1, 0, ra_opt}, /* toss? */ - {"lock_dir", 1, 0, ld_opt}, - - {"lt_partitions", 1, 0, lp_opt}, - - {"lt_high_locks", 1, 0, lhl_opt}, /* toss? */ - {"lt_drop_req_rate", 1, 0, ldrr_opt}, /* toss? */ - - {"prealloc_locks", 1, 0, pal_opt}, /* toss? */ - {"prealloc_holders", 1, 0, pah_opt}, /* toss? */ - {"prealloc_lkrqs", 1, 0, par_opt}, /* toss? */ - - {0,0,0,0} -}; -int parse_cmdline(gulm_config_t *gf, int argc, char **argv) -{ - int c; - int option_index = 0; - uint64_t temp; - - while(1) { - - c = getopt_long(argc, argv, "v:s:n:ecdCVh", long_options,&option_index); - if( c == -1 ) break; - - switch(c) { - case forgotten_long_opt: - fprintf(stderr,"Bad programmer! You forgot to catch '%s' \n", - long_options[option_index].name); - exit(ExitGulm_BadOption); - break; - case coreport_opt: - gf->corePort = atoi(optarg); - break; - case ltpxport_opt: - gf->ltpx_port = atoi(optarg); - break; - case ltport_opt: - gf->lt_port = atoi(optarg); - break; - case hbr_opt: - temp = ft2uint64(atof(optarg)); - gf->heartbeat_rate = bound_to_uint64(temp, 75000, (uint64_t)~0); - /* min is 0.075 */ - break; - case am_opt: - gf->allowed_misses = bound_to_uint16(atoi(optarg), 1, 0xffff); - break; - case nct_opt: - temp = ft2uint64(atof(optarg)); - gf->new_con_timeout = bound_to_uint64(temp, 0, (uint64_t)~0); - /* min should be something bigger than zero... - * say 0.5? why? - */ - break; - case msd_opt: - temp = ft2uint64(atof(optarg)); - gf->master_scan_delay = bound_to_uint64(temp, 10, (uint64_t)~0); - break; - case fb_opt: - strdup_with_free((char**)&gf->fencebin, optarg); - break; - case ra_opt: - strdup_with_free((char**)&gf->run_as, optarg); - break; - case ld_opt: - strdup_with_free((char**)&gf->lock_file, optarg); - break; - case lp_opt: - gf->how_many_lts = bound_to_uint16(atoi(optarg), 1, 256); - break; - - case lhl_opt: - gf->lt_maxlocks = bound_to_ulong(atoi(optarg), 10000, ~0UL); - break; - case ldrr_opt: - gf->lt_cf_rate = bound_to_uint(atoi(optarg), 5, ~0U); - break; - case pal_opt: - gf->lt_prelocks = bound_to_uint(atoi(optarg), 0, ~0U); - break; - case pah_opt: - gf->lt_preholds = bound_to_uint(atoi(optarg), 0, ~0U); - break; - case par_opt: - gf->lt_prelkrqs = bound_to_uint(atoi(optarg), 0, ~0U); - break; - - case name_opt: - strdup_with_free((char**)&gf->name, optarg); - break; - case ip_opt: - get_ip_for_name(optarg, &gf->ip); - break; - case ifdev_opt: - strdup_with_free((char**)&gf->netdev, optarg); - break; - - case 'c': - parse_ccs(gf); - break; - case 'n': - strdup_with_free((char**)&gf->clusterID, optarg); - break; - case 's': - parse_cmdline_servers(gf, optarg); - break; - case 'v': - set_verbosity(optarg, &verbosity); - break; - case 'C': - gf->conf_test = TRUE; - break; - case 'e': - gf->leave_std_open = TRUE; - break; - case 'd': - gf->daemon_fork = FALSE; - break; - case 'V': - printf("%s %s (built " __DATE__ " " __TIME__ ")\n" - "Copyright (C) 2004 Red Hat, Inc. All rights reserved.\n", - ProgramName, RELEASE); - exit(ExitGulm_Usage); - break; - case 'h': - usage(); - case ':': - case '?': - fprintf(stderr, "Ambiguous options, see --help\n"); - exit(ExitGulm_BadOption); - default: - fprintf(stderr,"Bad programmer! You forgot to catch the %c flag\n", - c); - exit(ExitGulm_BadOption); - break; - } - - } - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/config_gulm.h b/gulm/src/config_gulm.h deleted file mode 100644 index 3fa1c61..0000000 --- a/gulm/src/config_gulm.h +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_config_h__ -#define __gulm_config_h__ -#include "LLi.h" -#include "xdr.h" -#include <netinet/in.h> - -/* I may want to add some kind of marker to every option that this holds. - * A couple of bits to store weither or not items are different than the - * default, and possibly other info. Mostly if I work up the live config - * modification changes that others have requested, it would be nice to be - * able to dump a live config that only contained what was needed, and not - * everything. - * - * I may be able to do this just by `diffing' against the defaults too. - * - * I should take the time and evaluate how much of this really truely needs - * to be tightly tied into gulm. - */ - -typedef struct { - uint32_t hashval;/* hash of the config. */ - uint8_t *clusterID; - uint8_t *fencebin; - uint8_t *run_as; - uint8_t *lock_file; - - uint16_t corePort; - uint64_t heartbeat_rate; /* milli-sec res, ignore the micro-secs. */ - uint64_t master_scan_delay; - uint64_t new_con_timeout; - uint16_t allowed_misses; - - uint16_t quorum; - - uint16_t fog; /* true || false */ - - uint16_t node_cnt; - LLi_t node_list; - - uint16_t how_many_lts; /* int */ - uint16_t lt_port; - uint16_t ltpx_port; - - unsigned int lt_cf_rate; - unsigned long lt_maxlocks; - unsigned int lt_hashbuckets; - unsigned int lt_prelocks; - unsigned int lt_prelkrqs; - unsigned int lt_preholds; - - /* */ - int conf_test; /* stop after processing config? */ - int leave_std_open; - int daemon_fork; - /* for overriding default node name and ip lookups. */ - uint8_t *name; - struct in6_addr ip; - uint8_t *netdev; - -} gulm_config_t; - - -/* prototypes */ -void release_gulm_config(gulm_config_t *gf); -void free_gulm_config(gulm_config_t *gf); -int rebuild_server_list(gulm_config_t *gf); -int parse_conf(gulm_config_t *gf, int argc, char **argv); -int build_argv(gulm_config_t *gf, char ***argv, int *argc); -void dump_conf(gulm_config_t *gf, int out); -int Can_I_be_a_master(gulm_config_t *gf, struct in6_addr *ip); -int get_lt_range(int which, int of, int *start, int *stop); -int verify_name_and_ip(char *name, struct in6_addr *ip); -void serialize_config(gulm_config_t *gf, xdr_enc_t *enc); -#endif /*__gulm_config_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/config_main.c b/gulm/src/config_main.c deleted file mode 100644 index 411b911..0000000 --- a/gulm/src/config_main.c +++ /dev/null @@ -1,738 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <argz.h> -#include <netdb.h> - -#include "gulm_defines.h" -#include "config_priv.h" -#include "LLi.h" -#include "hash.h" -#include "config_gulm.h" -#include "utils_ip.h" -#include "utils_dir.h" -#include "utils_crc.h" -#include "utils_verb_flags.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/*****************************************************************************/ - -/** - * release_node_list - - * @list: <> list to free up - * - * free up all of the elements in a LLi of ip_name_t. - * - * - * Returns: void - */ -void release_node_list(LLi_t *list) -{ - LLi_t *tmp, *nxt; - ip_name_t *in; - for(tmp = LLi_next(list); - NULL != LLi_data(tmp); - tmp = nxt ) { - nxt = LLi_next(tmp); - LLi_del(tmp); - in = LLi_data(tmp); - if( in->name != NULL ) free(in->name); - free(in); - } -} - -/** - * Can_I_be_a_master - - * or, am i in the servers list? - * Returns: TRUE or FALSE - */ -int Can_I_be_a_master(gulm_config_t *gf, struct in6_addr *ip) -{ - LLi_t *tmp; - ip_name_t *in; - if( LLi_empty(&gf->node_list) ) return FALSE; - for(tmp = LLi_next(&gf->node_list); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp)) { - in = LLi_data(tmp); - if( IN6_ARE_ADDR_EQUAL(in->ip.s6_addr32 , ip->s6_addr32) ) { - return TRUE; - } - } - return FALSE; -} - -/*****************************************************************************/ - -/* this really needs to be done better. */ -unsigned int calc_quorum(unsigned int quorum, unsigned int cnt) -{ - if( quorum > cnt ) { - return (cnt / 2 ) + 1; - }else if( quorum == 0 ) - return 1; - else - return quorum; -} - - -/*****************************************************************************/ - -/** - * hash_config - - * - * generate a hash key for this config. This is used to make sure all - * servers are using compatible configs. - * - * Note that only the important bits are hashed. Parts not hashed can - * differ on nodes, and not affect the cluster's ablity to run. fencebin - * is an example, as is the verbosity. - * - * Returns: uint32_t - */ -uint32_t hash_config(gulm_config_t *gf) -{ - register uint32_t hash = 0x6d696b65; - LLi_t *tmp; - ip_name_t *in; - - hash = crc32(gf->clusterID, strlen(gf->clusterID), hash); - hash = crc32((uint8_t*)&gf->corePort, sizeof(uint16_t), hash); - hash = crc32((uint8_t*)&gf->heartbeat_rate, sizeof(uint64_t), hash); - hash = crc32((uint8_t*)&gf->allowed_misses, sizeof(uint16_t), hash); - hash = crc32((uint8_t*)&gf->quorum, sizeof(uint16_t), hash); - /* hashing fog is redundent now that it is just (node_cnt > 1) */ - hash = crc32((uint8_t*)&gf->fog, sizeof(uint16_t), hash); - - hash = crc32((uint8_t*)&gf->node_cnt, sizeof(uint16_t), hash); - for(tmp = LLi_next(&gf->node_list); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - hash = crc32((uint8_t*)&in->ip, sizeof(uint32_t), hash); - } - - hash = crc32((uint8_t*)&gf->how_many_lts, sizeof(uint16_t), hash); - hash = crc32((uint8_t*)&gf->lt_port, sizeof(uint16_t), hash); - hash = crc32((uint8_t*)&gf->ltpx_port, sizeof(uint16_t), hash); - - return hash; -} - -/** - * dump_conf - - * - * This will change to match the new file format once that is decided and - * written. - * - */ -void dump_conf(gulm_config_t *gf, int out) -{ - FILE *fp; - int fd; - LLi_t *tmp; - ip_name_t *in; - uint64_t pf; - - if( out ) { - fp = stdout; - }else{ - if( (fd=open_tmp_file("Gulm_config")) < 0 ) return; - if((fp = fdopen(fd,"a")) == NULL ) return; - } - fprintf(fp,"#=======================================" - "========================================\n"); - - fprintf(fp, "# hashed: %#x\n", gf->hashval); - fprintf(fp, "/cluster/@name = "%s"\n", gf->clusterID); - pf = gf->heartbeat_rate / 1000; - fprintf(fp, "/cluster/gulm/heartbeat_rate = %.3f\n", pf / 1000.0 ); - fprintf(fp, "/cluster/gulm/allowed_misses = %d\n", gf->allowed_misses); - fprintf(fp, "/cluster/gulm/coreport = %d\n", gf->corePort); - pf = gf->new_con_timeout / 1000; - fprintf(fp, "/cluster/gulm/new_connection_timeout = %.3f\n", pf / 1000.0 ); - fprintf(fp, "# quorum = %d\n", gf->quorum); - fprintf(fp, "# server cnt: %d\n", gf->node_cnt); - - tmp = LLi_next(&gf->node_list); - in = LLi_data(tmp); - fprintf(fp, "# servers = %s", in->name); - for(tmp = LLi_next(tmp); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - fprintf(fp, " %s", in->name); - } - fprintf(fp, "\n"); - tmp = LLi_next(&gf->node_list); - in = LLi_data(tmp); - fprintf(fp, "/cluster/gulm/servers = %s", ip6tostr(&in->ip)); - for(tmp = LLi_next(tmp); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - fprintf(fp, " %s", ip6tostr(&in->ip)); - } - fprintf(fp, "\n"); - - fprintf(fp, "/cluster/gulm/lt_partitions = %d\n", gf->how_many_lts); - fprintf(fp, "/cluster/gulm/lt_base_port = %d\n", gf->lt_port); - fprintf(fp, "/cluster/gulm/lt_high_locks = %ld\n", gf->lt_maxlocks); - fprintf(fp, "/cluster/gulm/lt_drop_req_rate = %d\n", gf->lt_cf_rate); - fprintf(fp, "/cluster/gulm/prealloc_locks = %d\n", gf->lt_prelocks); - fprintf(fp, "/cluster/gulm/prealloc_holders = %d\n", gf->lt_preholds); - fprintf(fp, "/cluster/gulm/prealloc_lkrqs = %d\n", gf->lt_prelkrqs); - fprintf(fp, "/cluster/gulm/ltpx_port = %d\n", gf->ltpx_port); - - if( !out ) { - fclose(fp); - } -} - -/** - * get_lt_range - - * @which: - * @of: - * @start: - * @stop: - * - * Given which lt in a set, what would it's start stop range be? - * For example: which:3 of:10 => start:78 stop:103 - * - * Wonder if there is a way to do this with out the loop. probably. - * - * This should go into a different file. (seems only the ltpx uses it, so - * over there somewhere.) - * - */ -int get_lt_range(int which, int of, int *start, int *stop) -{ - int i, eg, lo, last=0; - - if( of > 256 ) return -EINVAL; - if( which > of ) return -EINVAL; - - eg = ( 256 - of ) / of; - lo = ( 256 - of ) % of; - - for(i = 0 ; i < of ; i++ ) { - *start = last; - last += eg; - if( lo > 0 ) { lo--; last ++; } - *stop = last; - last++; - - if( i == which ) break; - } - return 0; -} - -/** - * strdup_with_free - - * @dst: - * @src: - * - * - * Returns: void - */ -void strdup_with_free(char **dst, char *src) -{ - if( *dst != NULL ) free(*dst); - *dst = strdup(src); - if( *dst == NULL ) die(ExitGulm_NoMemory, "Out of Memory.\n"); -} - -/** - * bound_uint16 - - * @val: - * @min: - * @max: - * - * given an int, make sure it fits within the range given my the min and - * max. and return the value within a uin16_t - * - * do the compairs on ints, but return uint16 - * - * One of the big things I'm trying to do here, is that if given a -1, - * return the min value. If we convert to a unsigned first, we'll end up - * with the max value, and that isn't what we want. - * - * Returns: uint16_t - */ -uint16_t bound_to_uint16(int val, uint16_t min, uint16_t max) -{ - if( val < (int)min ) return min; - if( val > (int)max ) return max; - return val; -} - -unsigned int bound_to_uint(int val, unsigned int min, unsigned int max) -{ - if( val < min ) return min; - if( val > max ) return max; - return val; -} -unsigned long bound_to_ulong(int val, unsigned long min, unsigned long max) -{ - if( val < min ) return min; - if( val > max ) return max; - return val; -} -uint64_t bound_to_uint64(uint64_t val, uint64_t min, uint64_t max) -{ - if( val < min ) return min; - if( val > max ) return max; - return val; -} - -/** - * ft2uint64 - - * @time: < float in form <sec>.<millisec> - * - * - * Returns: uint64_t time in micro-seconds - */ -uint64_t ft2uint64(float time) -{ - return ((uint64_t)(time * 1000)) * 1000; -} - -/** - * uint642ft - - * @time: < uint64_t time in micro-seconds - * - * - * Returns: float in form <sec>.<millisec> - */ -float uint642ft(uint64_t time) -{ - return ((float)(time/1000)) / 1000.0; -} - -/** - * serialize_config - - * @gf: - * @enc: - * - * - * Returns: void - */ -void serialize_config(gulm_config_t *gf, xdr_enc_t *enc) -{ - char workspace[1024]; - char *sl=NULL; - size_t lsl=0; - LLi_t *tmp; - ip_name_t *in; - - xdr_enc_string(enc, "hashed"); - snprintf(workspace, 1024, "%#x", gf->hashval); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "cluster_name"); - xdr_enc_string(enc, gf->clusterID); - - xdr_enc_string(enc, "serverips"); - for(tmp = LLi_next(&gf->node_list); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - argz_add(&sl, &lsl, ip6tostr(&in->ip)); - } - argz_stringify(sl, lsl, ','); - xdr_enc_string(enc, sl); - free(sl);sl=NULL;lsl=0; - - xdr_enc_string(enc, "servernamess"); - for(tmp = LLi_next(&gf->node_list); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - argz_add(&sl, &lsl, in->name); - } - argz_stringify(sl, lsl, ','); - xdr_enc_string(enc, sl); - free(sl);sl=NULL; - - xdr_enc_string(enc, "heartbeat_rate"); - snprintf(workspace, 1024, "%.3f", uint642ft(gf->heartbeat_rate)); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "allowed_misses"); - snprintf(workspace, 1024, "%u", gf->allowed_misses); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "verbosity"); - get_verbosity_string(workspace, 1024, verbosity); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "lt_partitions"); - snprintf(workspace, 1024, "%u", gf->how_many_lts); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "new_connection_timeout"); - snprintf(workspace, 1024, "%.3f", uint642ft(gf->new_con_timeout)); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "master_scan_delay"); - snprintf(workspace, 1024, "%.3f", uint642ft(gf->master_scan_delay)); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "coreport"); - snprintf(workspace, 1024, "%u", gf->corePort); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "ltport"); - snprintf(workspace, 1024, "%u", gf->lt_port); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "ltpxport"); - snprintf(workspace, 1024, "%u", gf->ltpx_port); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "fence_bin"); - xdr_enc_string(enc, gf->fencebin); - - xdr_enc_string(enc, "run_as"); - xdr_enc_string(enc, gf->run_as); - - xdr_enc_string(enc, "lock_dir"); - xdr_enc_string(enc, gf->lock_file); - - xdr_enc_string(enc, "lt_drop_req_rate"); - snprintf(workspace, 1024, "%u", gf->lt_cf_rate); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "lt_high_locks"); - snprintf(workspace, 1024, "%lu", gf->lt_maxlocks); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "prealloc_locks"); - snprintf(workspace, 1024, "%u", gf->lt_prelocks); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "prealloc_lkrqs"); - snprintf(workspace, 1024, "%u", gf->lt_prelkrqs); - xdr_enc_string(enc, workspace); - - xdr_enc_string(enc, "prealloc_holders"); - snprintf(workspace, 1024, "%u", gf->lt_preholds); - xdr_enc_string(enc, workspace); - -} - -/** - * validate_config - - * @gf: - * - * - */ -void validate_config(gulm_config_t *gf) -{ - if( gf->clusterID == NULL ) { - fprintf(stderr, "Gulm requires a cluster name. You left it blank.\n"); - exit(ExitGulm_ParseFail); - } - if( !(gf->node_cnt > 0 && gf->node_cnt <= 5 && gf->node_cnt != 2) ) { - fprintf(stderr, "Gulm requires 1,3,4, or 5 nodes to be specified in " - "the servers list. You specified %d\n", gf->node_cnt); - exit(ExitGulm_ParseFail); - } -} - -/** - * default_config - - * @gf: - * - * - */ -void default_config(gulm_config_t *gf) -{ - char workspace[256]; - memset(gf, 0, sizeof(gulm_config_t)); - - gf->clusterID = NULL; //strdup("cluster"); - gf->fencebin = strdup("fence_node"); - gf->run_as = strdup("root"); - gf->lock_file = strdup("/var/run/sistina"); - gf->corePort = 40040; - gf->heartbeat_rate = ft2uint64(15.0); - gf->master_scan_delay = ft2uint64(1.0); - gf->new_con_timeout = ft2uint64(15.0); - gf->allowed_misses = 2; - - LLi_init_head( &gf->node_list ); - - gf->how_many_lts = 1; - gf->lt_port = 41040; - gf->ltpx_port = 40042; - - gf->lt_cf_rate = 10; - gf->lt_maxlocks = 1024 * 1024; - gf->lt_hashbuckets = 65536; - gf->lt_prelocks = 10; - gf->lt_prelkrqs = 10; - gf->lt_preholds = 10; - - gf->conf_test = FALSE; - gf->leave_std_open = FALSE; - gf->daemon_fork = TRUE; - gethostname(workspace, 256); - gf->name = strdup(workspace); - memcpy(&gf->ip, &in6addr_any, sizeof(struct in6_addr)); - gf->netdev = NULL; - -} - -/** - * build_argv - - * @gf: - * @argv: - * @argc: - * - * recreates the command line args needed to run gulm - * - * Returns: int - */ -int build_argv(gulm_config_t *gf, char ***argv, int *argc) -{ - char workspace[1024]; - char *argz=NULL, *sl=NULL; - size_t laz=0, lsl=0; - LLi_t *tmp; - ip_name_t *in; - - argz_add(&argz, &laz, ProgramName); - - /* Always have a name and servers list. */ - argz_add(&argz, &laz, "--cluster_name"); - argz_add(&argz, &laz, gf->clusterID); - - argz_add(&argz, &laz, "--servers"); - for(tmp = LLi_next(&gf->node_list); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - argz_add(&sl, &lsl, ip6tostr(&in->ip)); - } - argz_stringify(sl, lsl, ','); - argz_add(&argz, &laz, sl); - free(sl); - - /* now we get optionals */ - gethostname(workspace, 1024); - if( strcmp(gf->name, workspace) != 0 ) { - argz_add(&argz, &laz, "--name"); - argz_add(&argz, &laz, gf->name); - } - if( memcmp(&gf->ip, &in6addr_any, sizeof(struct in6_addr)) != 0 ) { - argz_add(&argz, &laz, "--ip"); - argz_add(&argz, &laz, ip6tostr(&gf->ip)); - } - if( gf->netdev != NULL ) { - argz_add(&argz, &laz, "--ifdev"); - argz_add(&argz, &laz, gf->netdev); - } - if( gf->conf_test ) { - argz_add(&argz, &laz, "-C"); - } - if( gf->leave_std_open ) { - argz_add(&argz, &laz, "-e"); - } - if( ! gf->daemon_fork ) { - argz_add(&argz, &laz, "-d"); - } - if( verbosity != (lgm_Network|lgm_Stomith|lgm_Forking) ) { - get_verbosity_string(workspace, 1024, verbosity); - argz_add(&argz, &laz, "--verbosity"); - argz_add(&argz, &laz, workspace); - } - if( gf->heartbeat_rate != ft2uint64(15.0) ) { - argz_add(&argz, &laz, "--heartbeat_rate"); - snprintf(workspace, 1024, "%.3f", uint642ft(gf->heartbeat_rate)); - argz_add(&argz, &laz, workspace); - } - if( gf->allowed_misses != 2 ) { - argz_add(&argz, &laz, "--allowed_misses"); - snprintf(workspace, 1024, "%u", gf->allowed_misses); - argz_add(&argz, &laz, workspace); - } - if( gf->how_many_lts != 1 ) { - argz_add(&argz, &laz, "--lt_partitions"); - snprintf(workspace, 1024, "%u", gf->how_many_lts); - argz_add(&argz, &laz, workspace); - } - if( gf->new_con_timeout != ft2uint64(15.0) ) { - argz_add(&argz, &laz, "--new_connection_timeout"); - snprintf(workspace, 1024, "%.3f", uint642ft(gf->new_con_timeout)); - argz_add(&argz, &laz, workspace); - } - if( gf->master_scan_delay != ft2uint64(1.0) ) { - argz_add(&argz, &laz, "--master_scan_delay"); - snprintf(workspace, 1024, "%.3f", uint642ft(gf->master_scan_delay)); - argz_add(&argz, &laz, workspace); - } - if( gf->corePort != 40040 ) { - argz_add(&argz, &laz, "--coreport"); - snprintf(workspace, 1024, "%u", gf->corePort); - argz_add(&argz, &laz, workspace); - } - if( gf->lt_port != 41040 ) { - argz_add(&argz, &laz, "--ltport"); - snprintf(workspace, 1024, "%u", gf->lt_port); - argz_add(&argz, &laz, workspace); - } - if( gf->ltpx_port != 40042 ) { - argz_add(&argz, &laz, "--ltpxport"); - snprintf(workspace, 1024, "%u", gf->ltpx_port); - argz_add(&argz, &laz, workspace); - } - if( strcmp(gf->fencebin, "fence_node") != 0 ) { - argz_add(&argz, &laz, "--fence_bin"); - argz_add(&argz, &laz, gf->fencebin); - } - if( strcmp(gf->run_as, "root") != 0 ) { - argz_add(&argz, &laz, "--run_as"); - argz_add(&argz, &laz, gf->run_as); - } - if( strcmp(gf->lock_file, "/var/run/sistina") != 0 ) { - argz_add(&argz, &laz, "--lock_dir"); - argz_add(&argz, &laz, gf->lock_file); - } - if( gf->lt_cf_rate != 10 ) { - argz_add(&argz, &laz, "--lt_drop_req_rate"); - snprintf(workspace, 1024, "%u", gf->lt_cf_rate); - argz_add(&argz, &laz, workspace); - } - if( gf->lt_maxlocks != 1024 * 1024 ) { - argz_add(&argz, &laz, "--lt_high_locks"); - snprintf(workspace, 1024, "%lu", gf->lt_maxlocks); - argz_add(&argz, &laz, workspace); - } - if( gf->lt_prelocks != 10 ) { - argz_add(&argz, &laz, "--prealloc_locks"); - snprintf(workspace, 1024, "%u", gf->lt_prelocks); - argz_add(&argz, &laz, workspace); - } - if( gf->lt_prelkrqs != 10 ) { - argz_add(&argz, &laz, "--prealloc_lkrqs"); - snprintf(workspace, 1024, "%u", gf->lt_prelkrqs); - argz_add(&argz, &laz, workspace); - } - if( gf->lt_preholds != 10 ) { - argz_add(&argz, &laz, "--prealloc_holders"); - snprintf(workspace, 1024, "%u", gf->lt_preholds); - argz_add(&argz, &laz, workspace); - } - - *argc = argz_count(argz, laz) + 1; - *argv = malloc(sizeof(char *) * (*argc)); - argz_extract(argz, laz, *argv); - - return 0; -} - -/** - * parse_conf - - * @gf: - * - * Now do heavy parsing. - * - * Returns: int - */ -int parse_conf(gulm_config_t *gf, int argc, char **argv) -{ - int err=0; - - /* should set defaults here. */ - default_config(gf); - - /* parse cmdline args */ - err = parse_cmdline(gf, argc, argv); - - /* ok, read from everywhere, Now make sure we have the bare minimum - * required to run - * - * actually, I think the only thing this currently needs to do is to make - * sure that there is a valid number of servers. (1,3,4,5) - */ - validate_config(gf); - - /* Now that we know what available, do some last minute adjustments. */ - - /* more than one server? then we must be foggy. */ - gf->fog = (gf->node_cnt > 1); - - /* calc quorum */ - gf->quorum = (gf->node_cnt / 2) +1; - - /* calc hash. */ - gf->hashval = hash_config(gf); - - if( gf->conf_test ) { - dump_conf(gf, TRUE); - exit(0); - } - - /* all done. */ - return err; -} - -/** - * verify_name_and_ip - - * @name: < name that this node is claiming. - * @ip: < ip from which this node came - * - * - * - * Returns: =0:Deny =1:Allow - */ -int verify_name_and_ip(char *name, struct in6_addr *ip) -{ - struct in6_addr testip; - - return 1; - - /* check with libresolv */ - if( get_ip_for_name(name, &testip) != 0 ) { - log_msg(lgm_Network2,"Failed to lookup ip for %s\n", name); - return 0; - } - if( !IN6_ARE_ADDR_EQUAL(testip.s6_addr32, ip->s6_addr32) ) { - log_msg(lgm_Network2,"For %s, ip %s doesn't match %s\n", name, - ip6tostr(ip), ip6tostr(&testip)); - /* XXX above print won't be right due to static bufs and inlining */ - return 0; - } - - /* if ccs, check with them too */ - if( verify_name_and_ip_ccs(name, ip) == 0 ) { - return 0; - } - - return 1; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/config_priv.h b/gulm/src/config_priv.h deleted file mode 100644 index ba41026..0000000 --- a/gulm/src/config_priv.h +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __config_priv_h__ -#define __config_priv_h__ -#include "config_gulm.h" -#include "LLi.h" -void release_node_list(LLi_t *list); -void strdup_with_free(char **dst, char *src); -uint16_t bound_to_uint16(int val, uint16_t min, uint16_t max); -unsigned int bound_to_uint(int val, unsigned int min, unsigned int max); -unsigned long bound_to_ulong(int val, unsigned long min, unsigned long max); -uint64_t bound_to_uint64(uint64_t val, uint64_t min, uint64_t max); -uint64_t ft2uint64(float time); - -void parse_cmdline_servers(gulm_config_t *gf, char *servers); -int parse_ccs(gulm_config_t *gf); -int parse_cmdline(gulm_config_t *gf, int argc, char **argv); -int verify_name_and_ip_ccs(char *name, struct in6_addr *ip); -#endif /*__config_priv_h__*/ - diff --git a/gulm/src/core.h b/gulm/src/core.h deleted file mode 100644 index 9f15ccb..0000000 --- a/gulm/src/core.h +++ /dev/null @@ -1,17 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_core_h__ -#define __gulm_core_h__ -int core_main(int argc, char **argv); -#endif /*__gulm_core_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/core_fence.c b/gulm/src/core_fence.c deleted file mode 100644 index c69476d..0000000 --- a/gulm/src/core_fence.c +++ /dev/null @@ -1,202 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "LLi.h" -#include "gio_wiretypes.h" -#include "core_priv.h" -#include "config_gulm.h" - - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -extern gulm_config_t gulm_config; -extern int I_am_the; - -LLi_t StomithPids; - -typedef struct pid_list_s { - LLi_t pid_list; - pid_t pid; - uint8_t *Name; -} pidlist_t; - -/*****************************************************************************/ - -void init_fence(void) -{ - LLi_init_head(&StomithPids); -} - -/** - * fence_node - call out to fence a missbeahved node - * @name: < the name of the node - * @pause: < seconds to wait before killing - * - * This passes a node name to a fence program. The fence program scans its - * own conffile file and decides how to do the fence action. - * - * Returns: pid_t - */ -pid_t fence_node(char *name, int pause) -{ - pid_t pid; - int i; - char *argv[4]; - - argv[0] = gulm_config.fencebin; - argv[1] = "-O"; - argv[2] = name; - argv[3] = NULL; - - if((pid=fork()) == 0) { - /* child */ - if( pause > 0) sleep(pause); - - log_msg(lgm_Forking, "Gonna exec %s %s %s\n", argv[0], argv[1], argv[2]); - - for(i=open_max()-1; i>=3; --i) close(i); /* close everything but stds */ - - execvp(argv[0], argv); - fprintf(stderr,"ERROR Failed to execvp. %d:%s\n", errno, strerror(errno)); - _exit(ExitGulm_ExecError);/*jic*/ - }else if(pid>0) { - /*parent*/ - log_msg(lgm_Forking, "Forked [%d] %s %s %s with a %d pause.\n", - pid, argv[0], argv[1], argv[2], pause); - }else{ - /*error*/ - log_err("Problems (%d:%s) trying to start: %s %s %s\n", - errno, strerror(errno), - argv[0], argv[1], argv[2]); - pid = -1; - } - return pid; -} - -/** - * queue_node_for_fencing - - * @Name: - * - * I only wonder if I should handle the ENOMEM differently.... - * YES. - * - */ -void queue_node_for_fencing(uint8_t *Name) -{ - pidlist_t *pdl; - - pdl = malloc(sizeof(pidlist_t)); - if( pdl == NULL ) die(ExitGulm_NoMemory,"Out of memory.\n"); - LLi_init(&pdl->pid_list, pdl); - /* we *MUST* get the fence bin forked off. So we try until we get it. - * This could be bad. But if you've used up that many resources all - * ready... - */ - while( (pdl->pid = fence_node(Name, 0)) < 0 ) sleep(1); - pdl->Name = strdup(Name); - if( pdl->Name == NULL ) die(ExitGulm_NoMemory,"Out of memory.\n"); - - LLi_add_after(&StomithPids, &pdl->pid_list); -} - - -/** - * check_for_zombied_stomiths - - * @pid: - * @status: - * - * Returns: =0: NotFound =1: Found - */ -int check_for_zombied_stomiths(pid_t pid, int status) -{ - LLi_t *tmp; - for(tmp = LLi_next(&StomithPids); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ){ - pidlist_t *pdl; - pdl = LLi_data(tmp); - if( pdl->pid == pid ) { - - if( I_am_the != gio_Mbr_ama_Master && - I_am_the != gio_Mbr_ama_Arbitrating) { - /* don't care how it returned, we're not supposed to be runnign - * fence actions anymore, so just eat it. - * How did this happen? If we were Slave, and Master - * died, and we got to Arbit, we would call out to fence - * oldMaster. But after we make that callout, we find - * another Arbitrator that ranks us, so we switch to Slave. - * And now we're Slave with a pending fence action. - */ - log_msg(lgm_Stomith, "found match on pid %d, ignoring since " - "we're not Master or Arbitrator.\n", pid); - LLi_del(tmp); - free(pdl->Name); - free(pdl); - }else - if( (WIFEXITED(status) && WEXITSTATUS(status) == 0) ) { - log_msg(lgm_Stomith,"found match on pid %d, marking node %s as " - "logged out.\n", pid, pdl->Name); - - Mark_lgout_from_Exp(pdl->Name); - - /* Bcast NodeX Killed to subscribers. - */ - send_mbrshp_to_slaves(pdl->Name, gio_Mbr_Killed); - send_mbrshp_to_children(pdl->Name, gio_Mbr_Killed); - - LLi_del(tmp); - free(pdl->Name); - free(pdl); - }else{ - if( WIFEXITED(status) ) { - log_msg(lgm_Stomith,"Fence failed. [%d] Exit code:%d " - "Running it again.\n", pid, WEXITSTATUS(status)); - }else - if( WIFSIGNALED(status) ) { - log_msg(lgm_Stomith,"Fence failed. [%d] Signal:%d " - "Running it again.\n", pid, WTERMSIG(status)); - }else - if( WIFSTOPPED(status) ) { - log_msg(lgm_Stomith,"Fence stopped. [%d] Signal:%d " - "Running it again.\n", pid, WSTOPSIG(status)); - }else - log_msg(lgm_Stomith, "Fence failed [%d] for unknown reason. " - "Running it again.\n", pid); - - pdl->pid = fence_node(pdl->Name, 5); - - } - return 1; /* found something. stop. */ - } - } - return 0; -} -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/core_io.c b/gulm/src/core_io.c deleted file mode 100644 index df21f84..0000000 --- a/gulm/src/core_io.c +++ /dev/null @@ -1,2133 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "myio.h" -#include "gio_wiretypes.h" -#include "xdr.h" -#include "core_priv.h" -#include "config_gulm.h" -#include "utils_ip.h" -#include "utils_tostr.h" -#include "utils_verb_flags.h" - -/*****************************************************************************/ -/* First data that is stored in the main. */ - -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/* signal checks. */ -extern int SIGCHLD_TRIPPED; -/* if a service locks us, we will not shutdown until they log out. */ -unsigned int shutdown_locked = 0; -static int running = TRUE; /* this daemon runs. */ -/* confed things. */ -extern gulm_config_t gulm_config; -extern char myName[256]; -extern struct in6_addr myIP; - -/* Then data that is private to this file */ -static uint64_t last_hb_reply = 0; -static int master_missed = 0; -static struct timeval Started_at; -static struct timeval NOW; - -static ip_name_t *MasterIN = NULL; -int I_am_the = gio_Mbr_ama_Pending;/* what state we are in */ -static int MyRank = -1; -static int quorumcount = 1; /* how many before we go. We count as one. */ -static uint8_t quorate = FALSE; -static uint64_t GenerationID = 0; - -typedef enum {poll_Closed = 0, - poll_Accepting, /* For new incomming sockets. */ - poll_Connecting, /* For new outgoing connecting sockets. */ - poll_Trying, /* For connected Outgoing sockets (not yet logged in). */ - poll_Open} poll_state; -typedef enum { - poll_Nothing = 0, /* Unused poller. */ - poll_New, /* New poller that we're not sure of the type yet. */ - poll_Internal, /* Listen socket for example */ - poll_Slave, /* Could be a Master someday */ - poll_Client, /* not in servers=[] */ - poll_Resource -}poll_type; -struct { - struct pollfd *polls; - xdr_enc_t **enc; - xdr_dec_t **dec; - poll_state *state; - poll_type *type; - uint64_t *times; - ip_name_t *ipn; - unsigned int maxi; - int listenFD; /* socket for new connections. */ - int listenIDX; /* mostly for if I am poking around with gdb. */ - int MasterIDX; /* If we're a slave, where the Master is. */ -} poller; - -/* On trying all of the possible master servers at once instead of single - * stepping through the list. - * - * i think if I turn this into an array of the masters, I could get things - * to query each one at the same time. - * - * some function to set all elements to starting state. Then call - * master_probe_top() on each element. - * master_probe_connected() get called, then maybe master_probe_middle() - * ending with master_probe_bottom() - * - * mpb() needs to mark this element as done. (no matter what state) - * then .... - * - * crappy. mpm() will do the slave login if it finds a master. So if that - * happens, we need to stop the others. But not just that, we need to pick - * the highest ranked one if there are multiple. oooooo evil. - * - * This may take a bit more work than I originally thought.... - */ -struct { - int try_again; - ip_name_t *LastMasterIN; - LLi_t *current; - int testing; - uint64_t lasttry; -} Login_state; - -/* This is only true when we are first starting up the server. This is - * because GenerationID miss-matches can be handled differently durring - * this time. Since we know that we have never had quorum and thus we've - * never had usable state; we can reset things without restarting the app. - * - * Once we are Slave or Master, we are no longer in startup. - */ -int startup = TRUE; - -/** - * login_setup - - * - * initialize the master scanning structs. Needs to be done when ever we - * enter the Pending state. - * - */ -void login_setup(void) -{ - Login_state.try_again = FALSE; - Login_state.LastMasterIN = MasterIN; - Login_state.current = NULL; - Login_state.testing = FALSE; - Login_state.lasttry = 0; - I_am_the = gio_Mbr_ama_Pending; - log_msg(lgm_ServerState, "In state: %s\n", gio_I_am_to_str(I_am_the)); - send_core_state_to_children(); - quorumcount = 1; - - Login_state.current = LLi_next(&gulm_config.node_list); -} - - -/** - * init_core_poller - - * - * Returns: int - */ -int init_core_poller(void) -{ - int i; - - memset(&poller, 0, sizeof(poller)); - - poller.polls = malloc(open_max() * sizeof(struct pollfd)); - if( poller.polls == NULL ) goto nomem; - memset(poller.polls, 0, (open_max() * sizeof(struct pollfd))); - - poller.type = malloc(open_max() * sizeof(poll_type)); - if( poller.type == NULL ) goto nomem; - - poller.state = malloc(open_max() * sizeof(poll_state)); - if( poller.state == NULL ) goto nomem; - - poller.times = malloc(open_max() * sizeof(uint64_t)); - if( poller.times == NULL ) goto nomem; - - poller.ipn = malloc(open_max() * sizeof(ip_name_t)); - if( poller.ipn == NULL ) goto nomem; - - poller.enc = malloc(open_max() * sizeof(xdr_enc_t*)); - if( poller.enc == NULL ) goto nomem; - - poller.dec = malloc(open_max() * sizeof(xdr_dec_t*)); - if( poller.dec == NULL ) goto nomem; - - for(i=0; i < open_max(); i++) { - poller.polls[i].fd = -1; - poller.polls[i].events = 0; - poller.state[i] = poll_Closed; - poller.type[i] = poll_Nothing; - poller.times[i] = 0; - memset(&poller.ipn[i].ip, 0, sizeof(struct in6_addr)); - poller.ipn[i].name = NULL; - poller.enc[i] = NULL; - poller.dec[i] = NULL; - } - - poller.maxi = 0; - poller.listenFD = -1; - poller.MasterIDX = -1; - - return 0; -nomem: - if(poller.polls) free(poller.polls); - if(poller.state) free(poller.state); - if(poller.type) free(poller.type); - if(poller.times) free(poller.times); - if(poller.ipn) free(poller.ipn); - if(poller.enc) free(poller.enc); - if(poller.dec) free(poller.dec); - return -ENOMEM; -} - -/** - * release_core_poller - - * @oid: - * - * - * Returns: void - */ -void release_core_poller(void) -{ - int i; - if(poller.polls) free(poller.polls); - if(poller.state) free(poller.state); - if(poller.type) free(poller.type); - if(poller.times) free(poller.times); - for(i=0; i < open_max(); i ++ ) { - if( poller.enc[i] != NULL ) - xdr_enc_release(poller.enc[i]); - if( poller.dec[i] != NULL ) - xdr_dec_release(poller.dec[i]); - if( poller.ipn[i].name != NULL ) - free(poller.ipn[i].name); - } - if(poller.ipn) free(poller.ipn); - if(poller.enc) free(poller.enc); - if(poller.dec) free(poller.dec); -} - -/** - * add_to_pollers - - * @fd: - * @state: - * @time: - * @name: - * @ip: - * - * - * Returns: int - */ -static int add_to_pollers(int fd, int state, uint64_t time, - const char *name, const struct in6_addr *ip) -{ - int i; - for(i=0; poller.polls[i].fd >=0 && i< open_max(); i++); - if( i>= open_max() ) return -1; - - if(fcntl(fd, F_SETFD, FD_CLOEXEC ) <0) return -1; /* close on exec. */ - - poller.polls[i].fd = fd; - poller.polls[i].events = POLLIN; - if(i> poller.maxi) poller.maxi = i; - poller.state[i] = state; - poller.type[i] = poll_New; - poller.times[i] = time; - memcpy(&poller.ipn[i].ip, ip, sizeof(struct in6_addr)); - if( name != NULL ) poller.ipn[i].name = strdup(name); - else poller.ipn[i].name = NULL; - poller.enc[i] = NULL; - poller.dec[i] = NULL; - /* you need to do the xdr seperate. */ - - return i; -} - -/** - * print_poller_entry - - * @idx: - * - * - */ -static void print_poller_entry(int idx) -{ - char *s=""; -#define CasedString(x) case (x): s = #x ; break; - log_msg(lgm_Always, "poller idx = %d\n", idx); - log_msg(lgm_Always, "polls[].fd = %d\n", poller.polls[idx].fd); - log_msg(lgm_Always, "polls[].events = %x\n", poller.polls[idx].events); - log_msg(lgm_Always, "polls[].revents = %x\n", poller.polls[idx].revents); - switch(poller.state[idx]){ - CasedString(poll_Closed); - CasedString(poll_Accepting); - CasedString(poll_Connecting); - CasedString(poll_Trying); - CasedString(poll_Open); - } - log_msg(lgm_Always, "state[] = %s\n", s); - switch(poller.type[idx]){ - CasedString(poll_Nothing); - CasedString(poll_New); - CasedString(poll_Internal); - CasedString(poll_Slave); - CasedString(poll_Client); - CasedString(poll_Resource); - } - log_msg(lgm_Always, "type[] = %s\n", s); - log_msg(lgm_Always, "times[] = %"PRId64"\n", poller.times[idx]); - log_msg(lgm_Always, "ipn[].name = %s\n", poller.ipn[idx].name); - log_msg(lgm_Always, "ipn[].ip = %s\n", - ip6tostr(&poller.ipn[idx].ip)); - log_msg(lgm_Always, "enc[] = %p\n", poller.enc[idx]); - log_msg(lgm_Always, "dec[] = %p\n", poller.dec[idx]); -#undef CasedString -} - -/** - * add_xdr_to_poller - - * @idx: - * - * - * Returns: int - */ -static int add_xdr_to_poller(int idx) -{ - if( idx < 0 ) return idx; - poller.enc[idx] = xdr_enc_init( poller.polls[idx].fd, 512); - if( poller.enc[idx] == NULL ) return -ENOMEM; - poller.dec[idx] = xdr_dec_init( poller.polls[idx].fd, 512); - if( poller.dec[idx] == NULL ) { - xdr_enc_release(poller.enc[idx]); - poller.enc[idx] = NULL; - return -ENOMEM; - } - return 0; -} - -/** - * in_servers_list_ip - - * @ip: - * - * - * Returns: int - */ -int in_servers_list_ip(struct in6_addr *ip) -{ - LLi_t *tmp; - ip_name_t *in; - - for(tmp=LLi_next(&gulm_config.node_list); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp) ) { - in = LLi_data(tmp); - if(IN6_ARE_ADDR_EQUAL(in->ip.s6_addr32 , ip->s6_addr32)) return TRUE; - } - return FALSE; -} - -/** - * decrement_quorumcount - - */ -void decrement_quorumcount(void) -{ - quorumcount --; - if( I_am_the == gio_Mbr_ama_Master && - quorumcount < gulm_config.quorum){ - log_msg(lgm_Network, "Core lost slave quorum. Have %d, need %d. " - "Switching to Arbitrating.\n", - quorumcount, gulm_config.quorum); - I_am_the = gio_Mbr_ama_Arbitrating; - quorate = FALSE; - log_msg(lgm_ServerState, "In state: %s\n", gio_I_am_to_str(I_am_the)); - send_quorum_to_slaves(); - send_core_state_to_children(); - set_nodes_mode(myName, I_am_the); - - } -} - -/** - * close_by_idx - - * @idx: - * - * - * Returns: - */ -void close_by_idx(int idx) -{ - if( idx < 0 || idx > open_max() ) return; - log_msg(lgm_Network2, "Closing connection idx:%d, fd:%d to %s\n", - idx, poller.polls[idx].fd, poller.ipn[idx].name); - /* If we just closed the connect to the Master, set things up to try to - * re-find it. - * gotta do this before we wipe out the info. - */ - - if( poller.MasterIDX != -1 && idx == poller.MasterIDX ) { - poller.MasterIDX = -1; - log_msg(lgm_Network2, "Connection to Master closed.\n"); - if( gulm_config.fog ) { - login_setup(); /* this sets I_am_the to Pending. */ - }else{ - /* not fog, we'll never get our lockstate back, so... */ - die(ExitGulm_SelfKill, - "Lost connection to SLM Master (%s), stopping. " - "node reset required to re-activate cluster operations.\n", - poller.ipn[idx].name); - } - } - GULMD_ASSERT( poller.polls[idx].fd != poller.listenFD, - print_poller_entry(idx); - ); - - if( poller.type[idx] == poll_Slave ) - decrement_quorumcount(); - if( poller.type[idx] == poll_Resource ) - release_resource(poller.ipn[idx].name); - - close( poller.polls[idx].fd ); - poller.polls[idx].fd = -1; - poller.polls[idx].revents = 0; /* clear any other events. */ - poller.state[idx] = poll_Closed; - poller.type[idx] = poll_Nothing; - poller.times[idx] = 0; - memset(&poller.ipn[idx].ip, 0, sizeof(struct in6_addr)); - if( poller.ipn[idx].name != NULL ) { - free(poller.ipn[idx].name); - poller.ipn[idx].name = NULL; - } - if( poller.enc[idx] != NULL ) { - xdr_enc_release(poller.enc[idx]); - poller.enc[idx] = NULL; - } - if( poller.dec[idx] != NULL ) { - xdr_dec_release(poller.dec[idx]); - poller.dec[idx] = NULL; - } -} - -/** - * close_slaves - - * - * This needs to close all connections to Slaves, and none else. - */ -void close_slaves(void) -{ - int i; - log_msg(lgm_Network2, "Closing any Slave connections.\n"); - for(i=0; i < open_max(); i++) { - if( poller.type[i] == poll_Slave || poller.type[i] == poll_Client ) - close_by_idx(i); - } -} - -/*****************************************************************************/ -/** - * send_io_stats - - * @enc: - * - * - * Returns: int - */ -static int send_io_stats(xdr_enc_t *enc) -{ - struct timeval tv; - char *s, tmp[256] = "1: Why are you looking in this binary?"; - - xdr_enc_string(enc, "I_am"); - xdr_enc_string(enc, gio_I_am_to_str(I_am_the)); - - if( MasterIN != NULL ) { - xdr_enc_string(enc, "Master"); - xdr_enc_string(enc, MasterIN->name); - }else{ - xdr_enc_string(enc, "quorum_has"); - snprintf(tmp, 256, "%d", quorumcount); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "quorum_needs"); - snprintf(tmp, 256, "%d", gulm_config.quorum); - xdr_enc_string(enc, tmp); - } - - xdr_enc_string(enc, "rank"); - snprintf(tmp, 256, "%d", MyRank); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "quorate"); - snprintf(tmp, 256, "%s", quorate?"true":"false"); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "GenerationID"); - snprintf(tmp, 256, "%"PRIu64, GenerationID); - xdr_enc_string(enc, tmp); - - gettimeofday(&tv, NULL); - xdr_enc_string(enc, "run time"); - snprintf(tmp, 256, "%lu", tv.tv_sec - Started_at.tv_sec ); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "pid"); - snprintf(tmp, 256, "%u", getpid()); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "verbosity"); - get_verbosity_string(tmp, 256, verbosity); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "failover"); - if( gulm_config.fog ) - s = "enabled"; - else - s = "disabled"; - xdr_enc_string(enc, s); - - - return 0; -} - -/** - * open_core_listener - - * @port: - * - * - * Returns: int - */ -int open_core_listener(int port) -{ - int i; - poller.listenFD = serv_listen(port); - if( poller.listenFD < 0 ) return -1; - i = add_to_pollers(poller.listenFD, poll_Open, 0, "_ listener _", - &in6addr_any); - poller.type[i] = poll_Internal; - poller.listenIDX = i; - /* no xdr on the listener socket. */ - return 0; -} - -/** - * accept_connection - - * - * Returns: int - */ -static int accept_connection(void) -{ - int clisk, i; - struct sockaddr_in6 adr; - - i = sizeof(struct sockaddr_in6); - if( (clisk = accept(poller.listenFD, (struct sockaddr*)&adr, &i)) <0) { - log_err("error in accept: %s", strerror(errno)); - return -1; - } - - if( set_opts(clisk) <0) { - log_err("Cannot set socket options for new connection. Killing it.\n"); - close(clisk); - return -1; - } - - i = add_to_pollers(clisk, poll_Accepting, tvs2uint64(NOW), - ip6tostr(&adr.sin6_addr), &adr.sin6_addr); - if( i < 0 ) { - log_err("Failed to add new socket to poller list. %s\n", strerror(errno)); - close(clisk); - return -1; - } - if( add_xdr_to_poller(i) != 0 ) { - log_err("Failed to attatch xdr to new socket due to lack of memory.\n"); - close_by_idx(i); - return -1; - } - - return 0; -} - -/** - * master_probe_top - - * - * - * Returns: int - */ -static int master_probe_top(void) -{ - struct sockaddr_in6 adr; - ip_name_t *in; - int idx, cmFD; - - Login_state.lasttry = tvs2uint64(NOW); - in = LLi_data(Login_state.current); - if( in == NULL ) return -1; - - /* don't try to loginto myself. */ - if( IN6_ARE_ADDR_EQUAL(in->ip.s6_addr32, myIP.s6_addr32) || - strcmp(in->name, myName) == 0 ) - return -1; - - log_msg(lgm_LoginLoops, "Looking for Master server at %s %#x\n", - print_ipname(in), gulm_config.corePort); - - /* socket connect to CM */ - if((cmFD = socket(AF_INET6, SOCK_STREAM, 0)) <0) return -1; - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - memcpy(&adr.sin6_addr, &in->ip, sizeof(struct in6_addr)); - adr.sin6_port = htons(gulm_config.corePort); - - idx = add_to_pollers(cmFD, poll_Connecting, tvs2uint64(NOW), - in->name, &in->ip); - if( idx < 0 ) { /* out of free FDs. */ - log_err("Failed to find unused poller space.\n"); - close(cmFD); - return -1; - } - - log_msg(lgm_LoginLoops, "Trying to connect to possible Master " - "%s idx:%d fd:%d\n", print_ipname(in), - idx, cmFD ); - - /* set socket to non-blocking */ - if(fcntl(cmFD, F_SETFL, O_NONBLOCK) < 0 ) { - log_err("Cannot set Nonblock on new socket. %d:%s\n", errno, - strerror(errno)); - close_by_idx(idx); - return -1; - } - - errno = 0; - connect(cmFD, (struct sockaddr*)&adr, sizeof(struct sockaddr_in6)); - if( errno != EINPROGRESS ) { - log_msg(lgm_LoginLoops, "Cannot connect to %s %d (%s)\n", - print_ipname(in), gulm_config.corePort, strerror(errno)); - close_by_idx(idx); - return -1; - } - - /* when we can write, there is a connect. */ - poller.polls[idx].events = POLLOUT; - - Login_state.testing = TRUE; - return 0; -} - -/** - * master_probe_connected - - * - * ok, we connected, so now send off login request. - * - * Returns: int - */ -static int master_probe_connected(int idx) -{ - int err; - int sock_error; - socklen_t solen = sizeof(int); - xdr_enc_t *xdr; - - /* check the error codes. */ - if( getsockopt(poller.polls[idx].fd, SOL_SOCKET, SO_ERROR, - &sock_error, &solen ) < 0) { - log_err("Failed to get socket error off of master connect %d:%s\n", - errno, strerror(errno)); - goto fail; - } - if( sock_error != 0 ) { - log_msg(lgm_LoginLoops, "Cannot connect to %s %d (%d:%s)\n", - print_ipname( &poller.ipn[idx]), - gulm_config.corePort, sock_error, strerror(sock_error)); - goto fail; - } - - /* set socket to blocking. */ - if(fcntl(poller.polls[idx].fd, F_SETFL, 0) < 0 ) { - log_err("Cannot set block on new socket. %d:%s\n", errno, - strerror(errno)); - goto fail; - } - - if( set_opts(poller.polls[idx].fd) <0) { - log_msg(lgm_LoginLoops, "Failed to set options (%s)\n", strerror(errno)); - goto fail; - } - - if( add_xdr_to_poller(idx) < 0 ) { - log_err("Failed to allocate memory for xdr.\n"); - goto fail; - } - xdr = poller.enc[idx]; - - /* send login request */ - log_msg(lgm_LoginLoops, "Sending login request to possible Master " - "%s idx:%d fd:%d\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - - do { - if((err = xdr_enc_uint32(xdr, gulm_core_login_req)) != 0) break; - if((err = xdr_enc_uint32(xdr, GIO_WIREPROT_VERS)) != 0) break; - if((err = xdr_enc_string(xdr, gulm_config.clusterID)) != 0) break; - if((err = xdr_enc_string(xdr, myName)) != 0) break; - if((err = xdr_enc_uint64(xdr, GenerationID)) != 0) break; - if((err = xdr_enc_uint32(xdr, gulm_config.hashval)) != 0) break; - if((err = xdr_enc_uint32(xdr, MyRank)) != 0) break; - if((err = xdr_enc_flush(xdr)) != 0) break; - }while(0); - if( err != 0 ) { - log_msg(lgm_LoginLoops, "Errors trying to send login request. %d:%s\n", - err, strerror(errno)); - goto fail; - } - - Login_state.testing = TRUE; - - /* now we want to know about data to read. */ - poller.polls[idx].events = POLLIN; - poller.state[idx] = poll_Trying; - poller.times[idx] = tvs2uint64(NOW); - - return 0; -fail: - Login_state.testing = FALSE; - close_by_idx(idx); - return -1; -} - -/** - * master_probe_bottom - - * - * - * Returns: int - */ -static int master_probe_bottom(void) -{ - Login_state.current = LLi_next(Login_state.current); - Login_state.testing = FALSE; - int err; - - if( LLi_data(Login_state.current) == NULL && - I_am_the == gio_Mbr_ama_Pending ) { - /* we have walked through the list. - * If MyRank == -1, then I cannot be a Master. - * */ - if( Login_state.try_again || MyRank == -1 ) { - Login_state.try_again = FALSE; - Login_state.current = LLi_next(&gulm_config.node_list); - return 0; - } - - /* Not trying again, so we must be the new master. */ - if( gulm_config.quorum == 1 ) { - I_am_the = gio_Mbr_ama_Master; - startup = FALSE; - log_msg(lgm_ServerState, "In state: %s\n", gio_I_am_to_str(I_am_the)); - log_msg(lgm_Network, - "I see no Masters, So I am becoming the Master.\n"); - quorate = TRUE; - }else{ - I_am_the = gio_Mbr_ama_Arbitrating; - log_msg(lgm_ServerState, "In state: %s\n", gio_I_am_to_str(I_am_the)); - log_msg(lgm_Network, - "I see no Masters, So I am Arbitrating until enough Slaves " - "talk to me.\n"); - quorate = FALSE; - } - send_quorum_to_slaves(); - send_core_state_to_children(); - MasterIN = NULL; /* we are the Master now */ - master_missed = 0; /* reset this, not that it should ever be looked - * at again. but hey, you never know. */ - last_hb_reply = 0; - - if( GenerationID == 0 ) { - /* Brand new instance of the servers. */ - GenerationID = tvs2uint64(NOW); /* ??good enough?? yes */ - log_msg(lgm_Network, "New generation of server state. (%"PRIu64")\n", - GenerationID); - } - - /* if there was an old master, fence them. */ - if( Login_state.LastMasterIN != NULL ) { - /* Need to mark old Master as Expired. */ - log_msg(lgm_Stomith, "LastMaster %s, is being marked Expired.\n", - print_ipname(Login_state.LastMasterIN)); - - err = Mark_Expired(Login_state.LastMasterIN->name); - if (err) - err = Mark_Expired_IP(&Login_state.LastMasterIN->ip); - if (err) - log_msg(lgm_Always, "Mark_Expired failed on %s-%s", - Login_state.LastMasterIN->name, - ip6tostr(&Login_state.LastMasterIN->ip)); - send_mbrshp_to_children(Login_state.LastMasterIN->name, - gio_Mbr_Expired); - send_mbrshp_to_slaves(Login_state.LastMasterIN->name, - gio_Mbr_Expired); - } - - /* kill all already expired nodes - * this could end up in a double fencing of some nodes, but that is - * perfered to not being fenced at all. - * (Master fences, and before the results are propigated to slaves, - * Master dies. Then the slave that becomes new master will call - * fence again.) - * */ - fence_all_expired(); - - /* keep from killing everyone because we didn't have valid heartbeat - * times. (heartbeat times are not tracked in slaves, so everything - * in the nodes list on a slave has 'timed out' when it first becomes - * arbit.) - */ - beat_all_once(); - - /* Need to make sure that we are not marked as expired. - * If we are marked as expired, just die. - */ - Die_if_expired(myName); - - /* Move all old Logins to the transisional logged in state. - * This is an inbetween state that lets a node that was logged in log - * back in. It is only needed for when a slave becomes Master, since - * all the nodes will be in the logged in state, and that isn't quite - * accurate anymore. So we put them into the "was logged in but lost - * connection but probably doesn't need fencing" state. (which is - * much harder to say than oldmaster state or transisional login) - */ - Mark_Old_Master_lgin(); - - /* Make sure we're logged in too. This is mostly just to get the - * Master node into the nodelist along with the others. - */ - add_node(myName, &myIP); - Mark_Loggedin(myName); - set_nodes_mode(myName, I_am_the); - - return 1; - } - return 0; -} - -/** - * master_probe_middle - - * @idx: - * - * - * Returns: int - */ -static int master_probe_middle(int idx) -{ - xdr_dec_t *xdr = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - uint64_t generation=0; - uint32_t code=0; - uint32_t rpl_err=1; /* if you ever see this, non of the recv got called. */ - uint32_t rpl_rank=0; - uint8_t rpl_ama=0; - int err; - - if(xdr == NULL ) return -1; - - /* recv login reply */ - do{ - if((err = xdr_dec_uint32(xdr, &code)) != 0) break; - if((err = xdr_dec_uint64(xdr, &generation)) != 0) break; - if((err = xdr_dec_uint32(xdr, &rpl_err)) != 0) break; - if((err = xdr_dec_uint32(xdr, &rpl_rank)) != 0) break; - if((err = xdr_dec_uint8(xdr, &rpl_ama)) != 0) break; - } while(0); - - if( rpl_err == 0 && err == 0 ) { - switch(rpl_ama) { - case gio_Mbr_ama_Slave: - log_msg(lgm_Network2, "mpm: they(%s) are a Slave.\n", - poller.ipn[idx].name); - close_by_idx(idx); - break; - case gio_Mbr_ama_Arbitrating: - if( MyRank < 0 ) { - /* I am in client only mode, and so cannot log into an - * Arbitrating server. - * - * TODO Thinking about changing this. Need to figure out - * everything first though. - * Thinking that it might be much wiser to let client cores - * connect to an arbit. they won't effect quorum, and if - * that arbit decides to become a slave, it will kick them - * all out and they will rescan anyways. - * - * well, core/jid is doing what I want, but the ltpx/lock - * stuff is flooding trying to loginto the master which - * isn't a master yet. So do I change that? or try - * something else? - * - * Still doesn't solve the case where for some other reason - * there are no clients logged in to recv the fenced - * messages to start journal replay. I Need some other - * method. - */ - log_msg(lgm_Network2, "mpm: they(%s) are Arbitrating. " - "I'll check them again later.\n", - poller.ipn[idx].name); - /* XXX bleh. should still deserialize node list. */ - close_by_idx(idx); - break; - }else - if( I_am_the == gio_Mbr_ama_Arbitrating ) { - /* if the node we connected to is Arbitrating, and we are also - * Arbitrating, we need to check to see if they rank us. If - * they do, we give up Arbit, and go Slave. - * Else continue on, and they'll do that soon enough. - */ - if( MyRank < rpl_rank ) break; - /* MyRank is smaller, thus I'm closer to the top of the - * list. Thus I out rank them. - */ - /* kick out any slaves that might be connected to me. - * Need to do a logout on them as well. - * - * We should not have any clients logged in, but might under - * some netsplit type conditions. Ok, but they need to be - * kicked out as well anyways. - * */ - /* gotta set type here quick, else this gets closed. */ - poller.type[idx] = poll_Internal; - close_slaves(); - release_nodelist();/*behaves the same as logging everyone out.*/ - /* XXX calling release here might be wrong. - * I think calling it here will prevent the tag_for_lost() - * from working. - * Need to investigate. - */ - } - - case gio_Mbr_ama_Master: - /* do generation checking here */ - if( GenerationID != 0 && GenerationID < generation ) { - /* if my genid is smaller, then we don't want to connect - * to this arbit/mast - * - * So keep searching. - */ - /* clients die when genids go bad. bug #173 */ - if( MyRank < 0 ) { - die(ExitGulm_SelfKill, - "GenerationID missmatch: " - "me:%"PRIu64" they:%"PRIu64"\n", - GenerationID, generation); - } - if( startup ) { - /* We have never had quorum and thus never had useable - * state. So we can flip back to pending with GenID 0 - * and keep going without issue. - */ - log_msg(lgm_Always, "GenerationID missmatch: " - "me:%"PRIu64" they:%"PRIu64" " - "In startup, reseting. Continuing to scan.\n", - GenerationID, generation); - GenerationID = 0; - I_am_the = gio_Mbr_ama_Pending; - Login_state.try_again = TRUE; - } else { - log_msg(lgm_Always, "GenerationID missmatch: " - "me:%"PRIu64" they:%"PRIu64" " - "Continuing to scan.\n", - GenerationID, generation); - } - - /* send logout */ - xdr_enc_uint32(enc, gulm_core_logout_req); - xdr_enc_string(enc, myName); - xdr_enc_uint8(enc, I_am_the); - xdr_enc_flush(enc); - close_by_idx(idx); - break; - } - /* - * The idea here is that we(the resources) really want to have - * the slave core tell us if a node was removed from the - * nodelist while it wasn't connected to a master. So when it - * reconncets to a Master node, it needs to see which nodes are - * not in the Master's list, but are still in its. and then - * tell us(the resources) about them. - * - * So it marks who is here. receives nodelist (overwrites), - * then checks who didn't get overwritten. - */ - tag_for_lost(); - if( (err = deserialize_node_list(xdr)) != 0 ) { - log_err("Failed to deserialize initial Node list from " - "Master %s (%d:%d:%s)\n", poller.ipn[idx].name, - err, errno, strerror(errno)); - close_by_idx(idx); - }else{ - /* Check for nodes that are tagged, these are the nodes that - * either died or logged out while we were Masterless. - * Remove them from our list, and tell our children they're - * gone. - * Also need to tell children about new nodes. - */ - Update_children_about_nodelist(); - - poller.MasterIDX = idx; - poller.state[idx] = poll_Open; - poller.type[idx] = poll_Internal; /* connection to Master. */ - poller.times[idx] = 0; - I_am_the = gio_Mbr_ama_Slave; - startup = FALSE; - log_msg(lgm_ServerState, "In state: %s\n", - gio_I_am_to_str(I_am_the)); - GenerationID = generation; /* slaves copy master's gen. */ - master_missed = 0; /* cannot have missed any if not there */ - last_hb_reply = NOW.tv_sec; - MasterIN = LLi_data(Login_state.current); - if( MyRank < 0 ) {/* mmmSugar */ - log_msg(lgm_Network, - "Found Master at %s, so I'm a Client.\n", - MasterIN->name); - }else{ - log_msg(lgm_Network, - "Found Master at %s, so I'm a Slave.\n", - MasterIN->name); - update_mru_list(); - } - send_core_state_to_children(); - /* TODO - * mostly a post 5.2 thing. - * Check to see if LastMaster is in the list. If it is not, - * send a Killed message to resources. - * umm, really? - * lets try. - * Uh, this looks like it conflicts with Logout_leftovers(). - */ - if( Login_state.LastMasterIN != NULL ) { - /* the lookup is just an easy test to see if the node is - * in our lists. - */ - send_mbrshp_to_children(Login_state.LastMasterIN->name, - gio_Mbr_Killed); - } - return 1; - } - break; - case gio_Mbr_ama_Pending: - - if( MyRank > rpl_rank ) Login_state.try_again = TRUE; - - log_msg(lgm_Network2, "mpm: They(%s) are Pending.\n", - poller.ipn[idx].name); - close_by_idx(idx); - break; - default: - log_msg(lgm_LoginLoops,"Unknown ama(%d) returned\n", rpl_ama); - close_by_idx(idx); - /* this is an error case. */ - break; - } - } else { - if( rpl_err != 0 ) { - log_err("Got error from reply: (%s) %d:%s\n", - print_ipname(&poller.ipn[idx]), - rpl_err, gio_Err_to_str(rpl_err)); - } - if( err < 0 ) { - log_err("Errors on xdr: (%s) %d:%d:%s\n", - print_ipname(&poller.ipn[idx]), - err, errno, strerror(errno)); - } - /* On some of these errors, should we die instead of trying again? - * Like the bad config crc... - * actually, any of the gio_Err_Bad* - * really? - */ - close_by_idx(idx); - Login_state.try_again = TRUE; - if( rpl_err == gio_Err_BadGeneration && startup ) { - /* In startup, we can recover from this without dieing. - */ - GenerationID = 0; - I_am_the = gio_Mbr_ama_Pending; - log_msg(lgm_Always, "In startup, reseting. Continuing to scan.\n"); - }else - if( rpl_err == gio_Err_BadGeneration || - rpl_err == gio_Err_BadCluster || - rpl_err == gio_Err_BadConfig - ) { - die(ExitGulm_SelfKill, "Error of type %d:%s encountered. " - "For the Sanity of the cluster I am stopping.\n", - rpl_err, gio_Err_to_str(rpl_err)); - } - } - - return master_probe_bottom(); -} - -/*****************************************************************************/ - -/** - * send_update - - * @enc: - * @name: - * @st: - * - * - * Returns: int - */ -int send_update(int poll_idx, char *name, int st, struct in6_addr *ip) -{ - int e; - xdr_enc_t *enc; - if( poll_idx < 0 || poll_idx > open_max() ) return -EINVAL; - enc = poller.enc[poll_idx]; - if( enc == NULL ) return -EINVAL; - - if((e = xdr_enc_uint32(enc, gulm_core_mbr_updt)) != 0) return e; - if((e = xdr_enc_string(enc, name)) != 0) return e; - if((e = xdr_enc_ipv6(enc, ip)) != 0) return e; - if((e = xdr_enc_uint8(enc, st)) != 0) return e; - if((e = xdr_enc_flush(enc)) != 0) return e; - return 0; -} - -/** - * send_quorum - - * @poll_idx: - * - * - * Returns: int - */ -int send_quorum(int poll_idx) -{ - int e; - xdr_enc_t *enc; - if( poll_idx < 0 || poll_idx > open_max() ) return -EINVAL; - enc = poller.enc[poll_idx]; - if( enc == NULL ) return -EINVAL; - - if((e = xdr_enc_uint32(enc, gulm_core_quorm_chgs)) != 0) return e; - if((e = xdr_enc_uint8(enc, quorate)) != 0) return e; - return 0; -} - -/** - * send_core_state_update - - * @enc: - * - * - * Returns: int - */ -int send_core_state_update(int poll_idx) -{ - int err; - xdr_enc_t *enc; - if( poll_idx < 0 || poll_idx > open_max() ) return -EINVAL; - enc = poller.enc[poll_idx]; - if( enc == NULL ) return -EINVAL; - - if((err=xdr_enc_uint32(enc, gulm_core_state_chgs)) !=0 ) return err; - if((err=xdr_enc_uint8(enc, I_am_the)) !=0 ) return err; - if((err=xdr_enc_uint8(enc, quorate)) != 0 ) return err; - if( I_am_the == gio_Mbr_ama_Slave ) { - if( MasterIN == NULL ) - log_err("MasterIN is NULL!!!!!!!\n"); - if((err=xdr_enc_ipv6(enc, &MasterIN->ip)) !=0 ) return err; - if((err=xdr_enc_string(enc, MasterIN->name)) !=0 ) return err; - } - if((err=xdr_enc_flush(enc)) !=0 ) return err; - return 0; -} - -/** - * switch_into_Pending - - * - * This is how we transition from any state into Pending. It is a reset of - * sorts. This should be able to take the server from any of S,A,M and - * move cleanly into Pending. - * - */ -void switch_into_Pending(void) -{ - switch(I_am_the) { - case gio_Mbr_ama_Master: - case gio_Mbr_ama_Arbitrating: - /* do logout. */ - send_mbrshp_to_slaves(myName, gio_Mbr_Logged_out); - release_nodelist();/*behaves the same as logging everyone out.*/ - close_slaves(); - login_setup();/* restart the Pending State */ - break; - case gio_Mbr_ama_Slave: - { - xdr_enc_t *enc; - enc = poller.enc[poller.MasterIDX]; - xdr_enc_uint32(enc, gulm_core_logout_req); - xdr_enc_string(enc, myName); - xdr_enc_uint8(enc, I_am_the); - xdr_enc_flush(enc); - } - release_nodelist(); - close_by_idx(poller.MasterIDX); - /* closing the masterIDX calls login_setup() - * which correctly switches our state to Pending. - * which also informs resources that we're in pending. - */ - break; - case gio_Mbr_ama_Pending: - /* umm, duh. */ - return; - default: - break; - } - /* we need to re-add ourself to the nodelist. */ - add_node(myName, &myIP); - Mark_Loggedin(myName); - set_nodes_mode(myName, I_am_the); -} - -/** - * do_resource_login - - * @idx: - * - * - * Returns: int - */ -static void do_resource_login(int idx) -{ - uint32_t x_proto, x_opt; - uint8_t *x_clusterID = NULL, *x_name = NULL; - int err = 0, e=0; - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - - do { /* recv rest of login request */ - if((err = xdr_dec_uint32(dec, &x_proto)) != 0) break; - if((err = xdr_dec_string(dec, &x_clusterID)) != 0) break; - if((err = xdr_dec_string(dec, &x_name)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_opt)) != 0) break; - if( x_proto != GIO_WIREPROT_VERS) { - err=gio_Err_BadWireProto; - log_err("Protocol Mismatch: We're %#x and They (%s) are %#x\n", - GIO_WIREPROT_VERS, x_name, x_proto); - break; - } - } while(0); - if( err != 0 ) { - log_err("Failed to recv all of the service login packet. %d:%s\n", - err, (err<1000)?strerror(err):gio_Err_to_str(err)); - close_by_idx(idx); - goto exit; - } - - err = gio_Err_Ok; - if( ! IN6_IS_ADDR_LOOPBACK(poller.ipn[idx].ip.s6_addr32) ) { - /* XXX will I have to check for v4 loopback as well? */ - log_err("Services cannot connect from anything other than localhost." - " You're from %s\n", - print_ipname(&poller.ipn[idx])); - err = gio_Err_NotAllowed; - }else - if( x_clusterID != NULL && strcmp(x_clusterID, gulm_config.clusterID)!=0) { - log_err("%s claims to be part of %s, but we are %s\n", - poller.ipn[idx].name, x_clusterID, gulm_config.clusterID); - err = gio_Err_BadCluster; - }else - if( add_resource(x_name, idx, x_opt) != 0 ) { - log_err("There is already a service named "%s" here.\n", x_name); - err = gio_Err_BadLogin; - } - - do{ - if((e = xdr_enc_uint32(enc, gulm_core_login_rpl)) != 0) break; - if((e = xdr_enc_uint64(enc, GenerationID)) != 0) break; - if((e = xdr_enc_uint32(enc, err)) != 0) break; - if((e = xdr_enc_uint32(enc, MyRank)) != 0) break; - if((e = xdr_enc_uint8(enc, I_am_the)) != 0) break; - if((e = xdr_enc_flush(enc)) != 0) break; - }while(0); - if( e != 0 ) { - log_err("Got %d sending reply to service %s\n", e, x_name); - close_by_idx(idx); - goto exit; - } - if( err == gio_Err_Ok ) { - log_msg(lgm_Network2, "New Service "%s" connected. idx:%d fd:%d\n", - x_name, idx, poller.polls[idx].fd); - - if( poller.ipn[idx].name != NULL ) free(poller.ipn[idx].name); - poller.ipn[idx].name = strdup(x_name); - poller.state[idx] = poll_Open; - poller.times[idx] = 0; - poller.type[idx] = poll_Resource; - - }else{ - log_msg(lgm_Network2, "We gave service (%s) an error (%d:%s).\n", - x_name, err, gio_Err_to_str(err)); - close_by_idx(idx); - } - -exit: - if( x_clusterID != NULL ) {free(x_clusterID); x_clusterID = NULL;} - if( x_name != NULL ) {free(x_name); x_name = NULL;} -} - -/** - * do_new_login - - * @idx: - * - */ -static void do_new_login(int idx) -{ - uint64_t x_generation; - uint32_t x_config_crc, x_rank, x_proto; - uint8_t *x_clusterID = NULL, *x_name = NULL; - int err = 0, e=0; - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - - do { /* recv rest of login request */ - if((err = xdr_dec_uint32(dec, &x_proto)) != 0) break; - if( x_proto != GIO_WIREPROT_VERS) { - err=gio_Err_BadWireProto; - log_err("Protocol Mismatch: We're %#x and They (%s) are %#x\n", - GIO_WIREPROT_VERS, print_ipname(&poller.ipn[idx]), x_proto); - break; - } - if((err = xdr_dec_string(dec, &x_clusterID)) != 0) break; - if((err = xdr_dec_string(dec, &x_name)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_generation)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_config_crc)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_rank)) != 0) break; - } while(0); - if( err != 0 ) { - log_err("Failed to recv all of the login packet. %d:%s\n", - err, (err<1000)?strerror(err):gio_Err_to_str(err)); - close_by_idx(idx); - goto exit; - } - - if( I_am_the == gio_Mbr_ama_Slave || - I_am_the == gio_Mbr_ama_Pending ) { - /* we don't let login, but a pender or arbitrater may be scanning us, - * so we need to tell them we are a slave. So we do the reply packet - * here, then just close the connection skipping the rest of the login. - */ - do { - if((e = xdr_enc_uint32(enc, gulm_core_login_rpl)) != 0) break; - if((e = xdr_enc_uint64(enc, GenerationID)) != 0) break; - if((e = xdr_enc_uint32(enc, 0)) != 0) break; - if((e = xdr_enc_uint32(enc, MyRank)) != 0) break; - if((e = xdr_enc_uint8(enc, I_am_the)) != 0) break; - if((e = xdr_enc_flush(enc)) != 0) break; - } while(0); - if( e != 0 ) { - log_err("Got %d sending slave reply to %s\n", e, x_name); - } - log_msg(lgm_Network2, "dnl: We are a %s. Telling %s to go away.\n", - gio_I_am_to_str(I_am_the), x_name); - close_by_idx(idx); - goto exit; - } - - /* compare name and ip. - * compare cluster ID - * if generation != 0, is it correct? - * compare config crc. - * add node to list. - * Mark logged in - * beat node. - * send reply - * adjust quorum if needed. - * bcast login - */ - if( verify_name_and_ip(x_name, &poller.ipn[idx].ip) == 0 ) { - err = gio_Err_NotAllowed; - log_err("Node (%s %s) has been denied from connecting here.\n", - x_name, ip6tostr(&poller.ipn[idx].ip)); - }else - if( strncmp(x_clusterID, gulm_config.clusterID, CLUSTERIDLEN) != 0 ) { - err = gio_Err_BadCluster; - log_msg(lgm_Always, "This is cluster "%s", not "%s"\n", - gulm_config.clusterID, x_clusterID); - }else - if( x_generation != 0 && x_generation > GenerationID ) { - /* iif genid is the realtime of when this started, - * then the smaller genid is the one that should win. - * XXX this may not be correct anymore. - */ - err = gio_Err_BadGeneration; - log_msg(lgm_Always, "Generation ID of client(%s) (%"PRIu64") is not " - "the same as ours (%"PRIu64")\n", x_name, - x_generation, GenerationID); -#if 0 - /* mantis thinks we should fence here. */ - queue_node_for_fencing(x_name); -#endif - }else - if( x_config_crc != 0 && x_config_crc != gulm_config.hashval ) { - err = gio_Err_BadConfig; - log_msg(lgm_Always, "Config CRC doesn't match. ( %u != %u )\n", - x_config_crc, gulm_config.hashval); - }else - if(0 != add_node(x_name, &poller.ipn[idx].ip)) { - err = gio_Err_MemoryIssues; - }else - if( (err=Mark_Loggedin(x_name)) != gio_Err_Ok ) { - log_msg(lgm_Network," (%s %s) Cannot login if you are expired.\n", - x_name, ip6tostr(&poller.ipn[idx].ip)); - }else - if( (err=beat_node(x_name, idx)) != gio_Err_Ok) { - log_err("Failed to heartbeat node. (%s %s)\n", - x_name, ip6tostr(&poller.ipn[idx].ip)); - } - - do { - if((e = xdr_enc_uint32(enc, gulm_core_login_rpl)) != 0) break; - if((e = xdr_enc_uint64(enc, GenerationID)) != 0) break; - if((e = xdr_enc_uint32(enc, err)) != 0) break; - if((e = xdr_enc_uint32(enc, MyRank)) != 0) break; - if((e = xdr_enc_uint8(enc, I_am_the)) != 0) break; - if((e = xdr_enc_flush(enc)) != 0) break; - } while(0); - - if( e != 0 ) { - log_err("Errors sending login reply! %d:%s\n", errno, strerror(errno)); - close_by_idx(idx); - goto exit; - } - /* if we returned an error to them, stop. */ - if( err != 0 ) { - log_msg(lgm_Network2, "We gave them(%s) an error (%d:%s).\n", - x_name, err, gio_Err_to_str(err)); - close_by_idx(idx); - goto exit; - } - - /* incr quorum if this client counts. - * set type too. - * and mode. (want mode before serialize...) - */ - if( in_servers_list_ip(&poller.ipn[idx].ip) ) { - poller.type[idx] = poll_Slave; - quorumcount ++; - set_nodes_mode(x_name, gio_Mbr_ama_Slave); - }else - { - poller.type[idx] = poll_Client; - set_nodes_mode(x_name, gio_Mbr_ama_Client); - } - - if( I_am_the == gio_Mbr_ama_Arbitrating ) { - if( quorumcount >= gulm_config.quorum ) { - log_msg(lgm_Network, "Now have Slave quorum, going full Master.\n"); - I_am_the = gio_Mbr_ama_Master; - startup = FALSE; - quorate = TRUE; - log_msg(lgm_ServerState, "In state: %s\n", gio_I_am_to_str(I_am_the)); - /* cannot send quorum to slaves here, must wait until after - * deserialize. - */ - send_core_state_to_children(); - set_nodes_mode(myName, I_am_the); - }else{ - log_msg(lgm_Network, "Still in Arbitrating: Have %d, need " - "%d for quorum.\n", quorumcount, gulm_config.quorum); - } - } - - /* If I am the master or arbitrating, send the serialization of the node - * list to the slave/client. - */ - if( serialize_node_list(enc) != 0 ) { - log_err("Failed to send serialization of node list.\n"); - - Mark_Loggedout(x_name); /* ? really do this here ? */ - - close_by_idx(idx); - goto exit; - } - - if( poller.ipn[idx].name != NULL ) free(poller.ipn[idx].name); - poller.ipn[idx].name = strdup(x_name); - poller.state[idx] = poll_Open; - poller.times[idx] = 0; - - /* If they are a client, and we are not Master, close it. - */ - if( I_am_the != gio_Mbr_ama_Master && poller.type[idx] == poll_Client ) { - Mark_Loggedout(x_name); - close_by_idx(idx); - goto exit; - } - - log_msg(lgm_Network,"New Client: idx:%d fd:%d from %s\n", - idx, poller.polls[idx].fd, - print_ipname(&poller.ipn[idx])); - - send_quorum_to_slaves(); - send_mbrshp_to_slaves(x_name, gio_Mbr_Logged_in); - send_mbrshp_to_children(x_name, gio_Mbr_Logged_in); - -exit: - if( x_clusterID != NULL ) {free(x_clusterID); x_clusterID = NULL;} - if( x_name != NULL ) {free(x_name); x_name = NULL;} -} - -/** - * recv_some_data - - * @idx: - * - */ -static void recv_some_data(int idx) -{ - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - uint32_t code=0; - uint32_t x_error; - uint8_t *x_name = NULL; - uint8_t x_ama; - int err; - - if( dec == NULL ) { - log_err("There is no Decoder on poller (%s idx:%d fd:%d)!!\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - return; - } - if( enc == NULL ) { - log_err("There is no Encoder on poller (%s idx:%d fd:%d)!!\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - return; - } - - errno = 0; - err = xdr_dec_uint32(dec, &code); - if( err == -EPROTO ) { - log_msg(lgm_Network, "EOF on xdr (%s idx:%d fd:%d)\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - - /* die in a way that this node will get fenced. - * I think i should be doing this check in other places.... XXX - * */ - if( poller.type[idx] == poll_Resource && - die_with_me(poller.ipn[idx].name) ) { - die(ExitGulm_SelfKill, "Cannot continue without "%s" " - "Node reset required to re-activate cluster operations.\n", - poller.ipn[idx].name); - } - close_by_idx(idx); - return; - } - if( err != 0 ) { - if( errno == 0 ) errno = err; - log_msg(lgm_Always, "Error on xdr (%s idx:%d fd:%d): (%d:%d:%s)\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd, err, errno, - strerror(abs(errno))); - close_by_idx(idx); - return; - } - - if( code == gulm_core_login_req ) { - do_new_login(idx); - }else - if( code == gulm_core_reslgn_req ) { - do_resource_login(idx); - }else - if( code == gulm_core_login_rpl ) { - uint64_t x_generation; - uint32_t x_rank; - xdr_dec_uint64(dec, &x_generation); - xdr_dec_uint32(dec, &x_error); - xdr_dec_uint32(dec, &x_rank); - xdr_dec_uint8(dec, &x_ama); - }else - if( code == gulm_core_logout_req ) { - do { - if((err=xdr_dec_string(dec, &x_name)) != 0) break; - if((err=xdr_dec_uint8(dec, &x_ama)) != 0) break; - }while(0); - if( err == 0 ) { - - if( x_ama == gio_Mbr_ama_Resource ) { - release_resource(x_name); - - /* reply */ - xdr_enc_uint32(enc, gulm_core_logout_rpl); - xdr_enc_uint32(enc, 0); - xdr_enc_flush(enc); - - log_msg(lgm_Network,""%s" is logged out. fd:%d\n", x_name, - poller.polls[idx].fd); - - if( x_name != NULL ) {free(x_name); x_name = NULL;} - - }else - { - - Mark_Loggedout(x_name); - - /* reply */ - xdr_enc_uint32(enc, gulm_core_logout_rpl); - xdr_enc_uint32(enc, 0); - xdr_enc_flush(enc); - - log_msg(lgm_Network,""%s" is logged out. fd:%d\n", x_name, - poller.polls[idx].fd); - send_mbrshp_to_slaves(x_name, gio_Mbr_Logged_out); - send_mbrshp_to_children(x_name, gio_Mbr_Logged_out); - - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - } - close_by_idx(idx); - }else - if( code == gulm_core_logout_rpl ) { - /* just eat it and toss. */ - xdr_dec_uint32(dec, &x_error); - }else - if( code == gulm_core_beat_req ) { - do { - if((err=xdr_dec_string(dec, &x_name)) != 0 ) break; - } while(0); - if( err == 0 ) { - - /* make sure that idx isn't the listener */ - GULMD_ASSERT( idx != poller.listenIDX , ); - x_error = beat_node(x_name, idx); - - xdr_enc_uint32(enc, gulm_core_beat_rpl); - xdr_enc_uint32(enc, x_error); - xdr_enc_flush(enc); - - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - }else - if( code == gulm_core_beat_rpl ) { - /* I ignore this field, so I'm ignoring the results of the xdr. */ - xdr_dec_uint32(dec, &x_error); - - last_hb_reply = tvs2uint64(NOW); - master_missed = 0; - - }else - if( code == gulm_core_state_req ) { - send_core_state_update(idx); - }else - if( code == gulm_core_res_req ) { - serialize_resources(enc); - }else - if( code == gulm_core_mbr_lstreq ) { - serialize_node_list(enc); - }else - if( code == gulm_core_quorm_chgs ) { - /* should only ever come from master socket */ - if( xdr_dec_uint8(dec, &quorate) == 0 ) { - send_core_state_to_children(); - } - }else - if( code == gulm_core_mbr_req ) { - if( xdr_dec_string(dec, &x_name) == 0 ) { - get_node(enc, x_name); - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - }else - if( code == gulm_core_mbr_force ) { - if( xdr_dec_string(dec, &x_name) == 0 ) { - if( gio_Mbr_ama_Slave == I_am_the ) { - /* forward to the master/arbit */ - if( poller.MasterIDX > 0 && poller.enc[poller.MasterIDX] != NULL ) { - do{ - xdr_enc_t *menc = poller.enc[poller.MasterIDX]; - if((err =xdr_enc_uint32(menc, gulm_core_mbr_force))!=0) break; - if((err = xdr_enc_string(menc, x_name)) != 0) break; - if((err = xdr_enc_flush(menc)) != 0) break; - }while(0); - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, gulm_core_mbr_force); - xdr_enc_uint32(enc, err); - xdr_enc_flush(enc); - }else{ - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, gulm_core_mbr_force); - xdr_enc_uint32(enc, EINVAL); - xdr_enc_flush(enc); - } - }else { - if( strcmp(x_name, myName) == 0 ) { - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, gulm_core_mbr_force); - xdr_enc_uint32(enc, gio_Err_Ok); - xdr_enc_flush(enc); - log_msg(lgm_Always, "Doing a self kill. Goodby.\n"); - exit(ExitGulm_SelfKill); - }else{ - err = Force_Node_Expire(x_name); - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, gulm_core_mbr_force); - xdr_enc_uint32(enc, err); - xdr_enc_flush(enc); - } - } - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - }else - if( code == gulm_core_mbr_updt ) { - struct in6_addr x_ip; - uint8_t x_cur_state; - do{ - if((err=xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err=xdr_dec_uint8(dec, &x_cur_state)) != 0 ) break; - }while(0); - if(err != 0 ) { - /* bad news here. - * Our connection to core is probably going bad. - * - * this might be a bit of an over-reaction... - * */ - close_by_idx(idx); - }else{ - - send_mbrshp_to_children(x_name, x_cur_state); - - if( I_am_the == gio_Mbr_ama_Slave ) { - /* record in case we become master someday. */ - if( x_cur_state == gio_Mbr_Logged_in) { - if( add_node(x_name, &x_ip) != 0 ) { - } - Mark_Loggedin(x_name); - if( in_servers_list_ip(&x_ip) ) { - set_nodes_mode(x_name, gio_Mbr_ama_Slave); - }else{ - set_nodes_mode(x_name, gio_Mbr_ama_Client); - } - }else - if( x_cur_state == gio_Mbr_Logged_out) { - Mark_Loggedout(x_name); - if( MasterIN != NULL && - ( IN6_ARE_ADDR_EQUAL(x_ip.s6_addr32, MasterIN->ip.s6_addr32) - || strcmp(MasterIN->name, x_name) == 0 ) - ) { - log_msg(lgm_Network, "Master Node has logged out.\n"); - send_mbrshp_to_children(MasterIN->name, gio_Mbr_Logged_out); - MasterIN = NULL; /* clear this so old Master isn't fenced. */ - close_by_idx(idx); - quorate = FALSE; - send_core_state_to_children(); - } - }else - if( x_cur_state == gio_Mbr_Expired) { - Mark_Expired(x_name); - }else - if( x_cur_state == gio_Mbr_Killed) { - Mark_lgout_from_Exp(x_name); - } - } - - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - }else - if( gulm_info_stats_req == code ) { - xdr_enc_uint32(enc, gulm_info_stats_rpl); - xdr_enc_list_start(enc); - send_io_stats(enc); - xdr_enc_list_stop(enc); - xdr_enc_flush(enc); - }else - if( gulm_info_set_verbosity == code ) { - if( xdr_dec_string(dec, &x_name) == 0 ) { - set_verbosity(x_name, &verbosity); - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - close_by_idx(idx); - }else - if( gulm_core_configreq == code ) { - xdr_enc_uint32(enc, gulm_core_configrpl); - xdr_enc_list_start(enc); - serialize_config(&gulm_config, enc); - xdr_enc_list_stop(enc); - xdr_enc_flush(enc); - }else - if( gulm_core_shutdown == code ) { - /* logout and sutdown. */ - log_msg(lgm_Network2, "Received Shutdown request.\n"); - if( shutdown_locked > 0 ) { - log_msg(lgm_Network, "Cannot shutdown, we are locked.\n"); - err = gio_Err_NotAllowed; - }else{ - running = FALSE; - err = gio_Err_Ok; - } - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, gulm_core_shutdown); - xdr_enc_uint32(enc, err); - xdr_enc_flush(enc); - }else - if( code == gulm_core_forcepend ) { - switch_into_Pending(); - }else - if( code == gulm_socket_close ) { - close_by_idx(idx); - }else - if( gulm_err_reply == code ) { - /* just eat it for now. */ - do{ - if((err = xdr_dec_uint32(dec, &x_error)) != 0 ) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0 ) break; - }while(0); - }else - { - log_err("Unexpected op code %#x (%s), on fd:%d name:%s\n", - code, gio_opcodes(code), - poller.polls[idx].fd, poller.ipn[idx].name); - close_by_idx(idx); - } - return; -} - -/** - * send_heartbeat - Send a heartbeat packet. - */ -int send_heartbeat() -{ - struct timeval tv; - static uint64_t lastrun=0; - uint64_t fulltime; - int err; - - gettimeofday(&tv,NULL); - fulltime = tvs2uint64(tv); - if( lastrun == 0 ) { - /* set up initial state */ - lastrun = last_hb_reply = fulltime; - }else - if( fulltime > lastrun + ((gulm_config.heartbeat_rate*2)/3) - 1 ) { - log_msg(lgm_Heartbeat, - "Sending heartbeat to Core Master at %"PRIu64", last was %"PRIu64 - "\n", - fulltime, lastrun); - lastrun = fulltime; - if( poller.MasterIDX == -1 ) { - log_msg(lgm_Network2, "No Master to send heartbeats to\n"); - return -1; - } - do { - xdr_enc_t *enc = poller.enc[poller.MasterIDX]; - if((err=xdr_enc_uint32(enc, gulm_core_beat_req)) !=0 ) break; - if((err=xdr_enc_string(enc, myName)) !=0 ) break; - if((err=xdr_enc_flush(enc)) !=0 ) break; - }while(0); - - if( err<0) { - log_msg(lgm_Network2, "Failed to send heartbeat\n"); - return -1; - } - } - /* Check to see if we're getting timely replies from the Master. */ - if( fulltime > last_hb_reply + gulm_config.heartbeat_rate ) { - master_missed++; - last_hb_reply = fulltime; /* gotta actually wait delay time before - * we can say we missed the next heartbeat - */ - log_msg(lgm_Network, - "Failed to receive a timely heartbeat reply from Master. " - "(t:%"PRIu64" mb:%d)\n", fulltime, master_missed); - - if( master_missed > gulm_config.allowed_misses ) { - /* Master must be dead. - * cute trick: since we only get these from the MasterFD, we - * return -1 here, and thing will properly behave as if the - * Master died. - * */ - master_missed = 0; - last_hb_reply = 0; - log_msg(lgm_Network2, "Failed to get timely heartbeat replies\n"); - return -1; - } - } - return 0; -} - -/** - * self_beat - - * - * Master calls this to keep itself alive. - */ -void self_beat(void) -{ - static uint64_t lastrun=0; - - if( lastrun == 0 ) { - lastrun = tvs2uint64(NOW); - }else - if( tvs2uint64(NOW) > lastrun + ((gulm_config.heartbeat_rate*2)/3) ) { - lastrun = tvs2uint64(NOW); - beat_node(myName, -1); - } -} - -/** - * do_logout - - * - * Returns: int - */ -int do_logout(void) -{ - /* tell children we're gonning byebye */ - send_mbrshp_to_children(myName, gio_Mbr_Logged_out); - - if( I_am_the == gio_Mbr_ama_Slave || poller.MasterIDX != -1) { - xdr_enc_t *enc; - enc = poller.enc[poller.MasterIDX]; - xdr_enc_uint32(enc, gulm_core_logout_req); - xdr_enc_string(enc, myName); - xdr_enc_uint8(enc, I_am_the); - xdr_enc_flush(enc); - return 0; - }else - if( I_am_the == gio_Mbr_ama_Master ) { - log_msg(lgm_Always, "Master Node Is Logging Out NOW!\n"); - send_mbrshp_to_slaves(myName, gio_Mbr_Logged_out); - }else - if( I_am_the == gio_Mbr_ama_Arbitrating ) { - log_msg(lgm_Always, "Arbitrating Node Is Logging Out NOW!\n"); - send_mbrshp_to_slaves(myName, gio_Mbr_Logged_out); - } - return 0; -} - -/** - * determin_MyRank - - * - * figure out my rank in the server list - * - * Returns: int - */ -int determin_MyRank(void) -{ - int i; - LLi_t *tmp; - ip_name_t *in; - - for(tmp = LLi_next(&gulm_config.node_list), i = 0; - NULL != LLi_data(tmp); - tmp = LLi_next(tmp), i++) { - in = LLi_data(tmp); - if( IN6_ARE_ADDR_EQUAL(in->ip.s6_addr32, myIP.s6_addr32) ) { - MyRank = i; - break; - } - } - return MyRank; -} - -/** - * scan_for_dead_children - - */ -void scan_for_dead_children(void) -{ - pid_t pid; - int status = 0; - - while( (pid=waitpid(-1, &status, WNOHANG)) > 0 ) {/* zombie scrubber. */ - /* scan for Stomith actions that have finished. */ - check_for_zombied_stomiths(pid, status); - } -} - -/** - * work_loop - - * - */ -void work_loop(void) -{ - int idx, cnt; - - gettimeofday(&Started_at, NULL); - gettimeofday(&NOW, NULL); - determin_MyRank(); - login_setup(); - add_node(myName, &myIP); /* for the sake of our services. */ - Mark_Loggedin(myName); - set_nodes_mode(myName, I_am_the); - - while( running ) { - - scan_for_dead_children(); - - if( I_am_the == gio_Mbr_ama_Slave) { - if( send_heartbeat() != 0) { - /* if we lost the tcp socket to the master, we need to do a - * rebuild. Note that it is possible that we will reconnect to - * the same node doing the master work. But because of the way - * tcp is designed, we need to destroy and rebuild the socket. - */ - if( MasterIN != NULL ) - send_mbrshp_to_children(MasterIN->name, gio_Mbr_Expired); - close_by_idx(poller.MasterIDX); - quorate = FALSE; - send_core_state_to_children(); - } - }else - if( I_am_the == gio_Mbr_ama_Master || - I_am_the == gio_Mbr_ama_Arbitrating ) { - /* update our own heartbeat. */ - self_beat(); - /* make sure eveyone is sending us heartbeats. */ - check_beats(); - } - - if( (cnt = poll(poller.polls, poller.maxi +1, 2)) <= 0) { - if( cnt < 0 && errno != EINTR ) - log_err("poll error: %s\n",strerror(errno)); - if(!running) return; - errno = 0; /* reset this. */ - } - gettimeofday(&NOW, NULL); - if( ( I_am_the == gio_Mbr_ama_Pending || - I_am_the == gio_Mbr_ama_Arbitrating ) && - ! Login_state.testing && - Login_state.lasttry + gulm_config.master_scan_delay <tvs2uint64(NOW)){ - if( master_probe_top() != 0 ) - master_probe_bottom(); - } - for( idx=0; idx <= poller.maxi ; idx++) { - if (poller.polls[idx].revents & POLLNVAL ) { - log_err("POLLNVAL on idx:%d fd:%d name:%s\n", idx, - poller.polls[idx].fd, poller.ipn[idx].name); - close_by_idx(idx); - } - if( poller.polls[idx].revents & POLLOUT ) { - if( poller.state[idx] == poll_Connecting ) { - master_probe_connected(idx); - } - } - if( poller.polls[idx].revents & POLLIN ) { - if( poller.polls[idx].fd == poller.listenFD ) { - accept_connection(); - }else{ - if( I_am_the == gio_Mbr_ama_Master || - I_am_the == gio_Mbr_ama_Slave ) { - /* should I check to make sure only poll_Open and - * poll_Accepting states at this point? - */ - recv_some_data(idx); - }else - if( I_am_the == gio_Mbr_ama_Arbitrating || - I_am_the == gio_Mbr_ama_Pending ) { - if( poller.state[idx] == poll_Accepting || - poller.state[idx] == poll_Open ) { - recv_some_data(idx); - /* For opened, or new connections, Arbit is the same - * as Master or Slave. - * It is just the Trying connection that need to be - * delt with differently. - */ - }else - if( poller.state[idx] == poll_Trying ) { - master_probe_middle(idx); - } - }else{ - /* I_am_the is in a weird state. */ - die(ExitGulm_Assertion, - "I_am_the(%#x) is in a weird state\n", I_am_the); - } - } - } - if( poller.polls[idx].revents & POLLHUP ) { - if( poller.state[idx] == poll_Connecting ) { - log_msg(lgm_LoginLoops, "No lock_gulmd listening at " - "%s idx:%d fd:%d\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - }else{ - log_err("POLLHUP on idx:%d fd:%d name:%s\n", idx, - poller.polls[idx].fd, poller.ipn[idx].name); - } - if( ( I_am_the == gio_Mbr_ama_Pending || - I_am_the == gio_Mbr_ama_Arbitrating ) && - ( poller.state[idx] == poll_Trying || - poller.state[idx] == poll_Connecting - ) ) master_probe_bottom(); - close_by_idx(idx); - } - if (poller.polls[idx].revents & POLLERR ) { - if( poller.state[idx] == poll_Connecting ) { - /* do I know what errors? */ - log_msg(lgm_LoginLoops, "Errors trying to get to Master at " - "%s idx:%d fd:%d\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - }else{ - log_err("An error on poller idx:%d fd:%d name:%s\n", idx, - poller.polls[idx].fd, poller.ipn[idx].name); - } - if( ( I_am_the == gio_Mbr_ama_Pending || - I_am_the == gio_Mbr_ama_Arbitrating ) && - ( poller.state[idx] == poll_Trying || - poller.state[idx] == poll_Connecting - ) ) master_probe_bottom(); - close_by_idx(idx); - } - - /* check for timed out pollers. */ - if( poller.times[idx] != 0 && - poller.times[idx] + gulm_config.new_con_timeout < tvs2uint64(NOW)){ - log_msg(lgm_Network, "Timeout (%"PRIu64") on fd:%d (%s)\n", - gulm_config.new_con_timeout, poller.polls[idx].fd, - print_ipname(&poller.ipn[idx])); - if( ( I_am_the == gio_Mbr_ama_Pending || - I_am_the == gio_Mbr_ama_Arbitrating ) && - ( poller.state[idx] == poll_Trying || - poller.state[idx] == poll_Connecting - ) ) - master_probe_bottom(); /* time out trying to connect to - * this Master. - */ - close_by_idx(idx); /* or something like this. */ - } - - if(!running) return; - }/*for( i=0; i <= poller.maxi ; i++) */ - }/* while() */ -} - -/* vim: set ai cin et sw=3 ts=3 : */ - diff --git a/gulm/src/core_main.c b/gulm/src/core_main.c deleted file mode 100644 index efdeae4..0000000 --- a/gulm/src/core_main.c +++ /dev/null @@ -1,229 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <pwd.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/mman.h> -#include <execinfo.h> - -#include "gulm_defines.h" -#include "myio.h" -#include "core_priv.h" -#include "config_gulm.h" -#include "utils_ip.h" -#include "utils_verb_flags.h" -#include "utils_tostr.h" -#include "utils_dir.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/* signal checks. */ -int SIGUSR1_TRIPPED = FALSE; -int SIGCHLD_TRIPPED = FALSE; - -extern gulm_config_t gulm_config; - -/* these are calculated at run time. - * I will need to do something in the future for nodes with multiple ips. - * */ -extern char myName[256]; -extern struct in6_addr myIP; - -/*****************************************************************************/ - -/** - * sigact_usr1 - Dump out internal tables. - * @sig: - */ -static void sigact_usr1(int sig) -{ - dump_nodes(); - dump_conf(&gulm_config, FALSE); - dump_resources(); -} - -/** - * sigact_chld - clear up exited children - * @sig: - * - */ -static void sigact_chld(int sig) -{ - SIGCHLD_TRIPPED = TRUE; -} - -/** - * sigact_segv - - * @sig: - * - * try to get a backtrace before we puke out. - * This may not always work, but since I cannot get daemons to drop core - * files, trying this is better than nothing. - */ -static void sigact_segv(int sig) -{ - struct sigaction act; - void *array[200]; - size_t size,i; - char **strings; - - size = backtrace(array, 200); - strings = backtrace_symbols(array, size); -#ifndef DEBUG - syslog(LOG_NOTICE, "BACKTRACE\n"); -#else - fprintf(stderr, "BACKTRACE\n"); -#endif - for(i=0;i<size; i++) -#ifndef DEBUG - syslog(LOG_NOTICE, " %s\n", strings[i]); -#else - fprintf(stderr, " %s\n", strings[i]); -#endif - free(strings); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - sigaction(SIGSEGV, &act, NULL); - raise(SIGSEGV); -} - - -/** - * setupsignals - set how we respond to signals. - */ -static void setupsignals(void) -{ - struct sigaction act; - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; /* use gulm_tool shutdown or kill -9 */ - if( sigaction(SIGTERM, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGTERM handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_usr1; - if( sigaction(SIGUSR1, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGUSR1 handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGUSR2, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGUSR2 handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGHUP, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGHUP handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGALRM, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGALRM handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN;/* don't die on broken pipes.*/ - if( sigaction(SIGPIPE, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGPIPE handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_chld; - act.sa_flags = SA_NOCLDSTOP; - if( sigaction(SIGCHLD, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGCHLD handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_segv; - if( sigaction(SIGSEGV, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGSEGV handler: %s\n",strerror(errno)); - -} - -static int gulm_mlockall(void) -{ - int res = mlockall(MCL_CURRENT | MCL_FUTURE); - if (res) - log_err("could not lock memory : %s\n", strerror(errno)); - return res; -} - -/** - * core_main - - * @argc: - * @argv: - * - * Returns: int - */ -int core_main(int argc, char **argv) -{ - /* set up other things. */ - setupsignals(); - -#ifndef DEBUG - pid_lock(gulm_config.lock_file, ProgramName); -#endif - - /* initialize memory structures. */ - if( init_nodes() != 0 ) - die(ExitGulm_InitFailed, "init nodelist failed.\n"); - init_fence(); - if( init_resources() != 0 ) - die(ExitGulm_InitFailed, "init services failed.\n"); - if( init_core_poller() != 0 ) - die(ExitGulm_InitFailed, "init poller failed.\n"); - if( open_core_listener(gulm_config.corePort) != 0 ) - die(ExitGulm_InitFailed, "open listener failed. %d:%s\n", - errno, strerror(errno)); - - if( gulm_mlockall() != 0 ) - die(ExitGulm_InitFailed, "could not lock memory.\n"); - log_init(0,0); - /* ok, Now get to work. */ - work_loop(); - - /* send logout to master node. */ - do_logout(); - - release_core_poller(); - - clear_pid(gulm_config.lock_file, ProgramName); - - log_msg(lgm_Network, "finished.\n"); - - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/core_nodelists.c b/gulm/src/core_nodelists.c deleted file mode 100644 index f22061c..0000000 --- a/gulm/src/core_nodelists.c +++ /dev/null @@ -1,1120 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "LLi.h" -#include "hash.h" -#include "myio.h" -#include "gio_wiretypes.h" -#include "core_priv.h" -#include "config_gulm.h" -#include "utils_dir.h" -#include "utils_ip.h" -#include "utils_tostr.h" - - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -extern gulm_config_t gulm_config; - -hash_t *Nodes_by_Name; -LLi_t heartbeat_lru; /* next is MRU, prev is LRU */ -/*****************************************************************************/ -typedef struct node_s { - LLi_t By_Name; - LLi_t lru; - - char *Name; - struct in6_addr ip; - - uint8_t State; - uint8_t last_state; - uint8_t mode; /* Slave, Pending, Arbitrating, Master, Client */ - uint8_t sweepcheck; -#define NLSC_Clear (0) -#define NLSC_Copied (66) -#define NLSC_New (69) -#define NLSC_Tagged (42) - - unsigned int missed_beats; - uint64_t last_beat; - uint64_t delay_avg; /*average amount of time between beats */ - uint64_t max_delay; - - /* stuff for sending data to nodes. */ - int poll_idx; - -} Node_t; - -/* selector functions for the hash tables. */ -unsigned char *getnodename(void *item) -{ - Node_t *n = (Node_t*)item; - return n->Name; -} -int getnodeNln(void *item) -{ - Node_t *n=(Node_t*)item; - return strlen(n->Name); -} - -/** - * move_to_mru - - * @n: - * - * - * Returns: void - */ -void move_to_mru(Node_t *n) -{ - LLi_del(&n->lru); - LLi_unhook(&n->lru); - LLi_add_after(&heartbeat_lru, &n->lru); -} - -/** - * remove_from_lru - - * @n: - * - * - * Returns: void - */ -void remove_from_lru(Node_t *n) -{ - if( ! LLi_empty(&n->lru) ) { /* not really empty, but same idea. */ - LLi_del(&n->lru); - LLi_unhook(&n->lru); - } -} - -/** - * init_nodes - - * - * Returns: int - */ -int init_nodes(void) -{ - LLi_init_head(&heartbeat_lru); - Nodes_by_Name = hash_create(256, getnodename, getnodeNln); - if( Nodes_by_Name == NULL ) return -1; - return 0; -} - -/** - * _release_nodelist_ - - * @item: - * @misc: - * - * innear working function. - * - * Returns: int - */ -int _release_nodelist_(LLi_t *item, void *misc) -{ - Node_t *n = LLi_data(item); - LLi_del(item); - remove_from_lru(n); - free(n->Name); - free(n); - return 0; -} -/** - * release_nodelist - - * - * free everything. - */ -void release_nodelist(void) -{ - hash_walk(Nodes_by_Name, _release_nodelist_, NULL); - LLi_init_head(&heartbeat_lru); -} - -/*****************************************************************************/ -struct _send_mbrshp_to_node_s { - char *name; - uint8_t st; - struct in6_addr ip; -}; - -/** - * _send_mbrshp_to_node - - * @item: - * @misc: - * - * - * Returns: int - */ -int _send_mbrshp_to_node(LLi_t *item, void *misc) -{ - Node_t *n; - struct _send_mbrshp_to_node_s *t = (struct _send_mbrshp_to_node_s *)misc; - int err; - n = LLi_data(item); - - if( n->mode == gio_Mbr_ama_Master || - n->mode == gio_Mbr_ama_Arbitrating ) - return 0; /* skip ourself */ - - if( n->State == gio_Mbr_Logged_in ) { - - log_msg(lgm_Subscribers, "Sending Membership update "%s" about %s " - "to slave %s\n", gio_mbrupdate_to_str(t->st), t->name, n->Name); - err=send_update(n->poll_idx, t->name, t->st, &t->ip); - if( err != 0 ) { - log_msg(lgm_Always,"Could not send membership update "%s" about %s " - "to slave %s\n", gio_mbrupdate_to_str(t->st), t->name, n->Name); - } - }else - if( n->State == gio_Mbr_OM_lgin ) { - log_msg(lgm_Always, "Member update message %s about %s to %s is lost " - "because node is in OM\n", - gio_mbrupdate_to_str(t->st), t->name, n->Name); - /* Note, as tempting as it maybe to put a queue here to hold onto - * these until the node reconnects, it typically doesn't do what you - * would expect. Why? Well because of the clients do not stay logged into - * Arbitrating nodes. What happens is that the node will try to - * login, see that we are Arbitrating, and then logout, lossing the - * queue. Yes the queued messages can get sent, but the client will - * have never left the Pending state, so in most cases it won't do - * anything. - * Of course sometimes things race differently and it will actually - * do what you expect. - * - * Races are like that. - */ - } - - return 0; -} - -/** - * send_mbrshp_to_slaves - - * @name: - * @st: - * - * send a membership update out to the slave cores. - * Only the Master should ever call this. - * - * Returns: int - */ -int send_mbrshp_to_slaves(char *name, int st) -{ - struct _send_mbrshp_to_node_s t; - - t.name = name; - t.st = st; - - if( lookup_nodes_ip(name, &t.ip) != 0 ) { - /* not in node list, use normal lookups. */ - if( get_ip_for_name(name, &t.ip) != 0 ) { - memset(&t.ip, 0, sizeof(struct in6_addr)); - /* we cannot find it, leave it zero. and let the receiver worry - * about it. - */ - } - } - - return hash_walk(Nodes_by_Name, _send_mbrshp_to_node, &t); -} - - -/** - * _send_quorum_to_slave_ - - * @item: - * @misc: - * - * - * Returns: int - */ -int _send_quorum_to_slave_(LLi_t *item, void *misc) -{ - Node_t *n; - int err; - n = LLi_data(item); - if( n->mode == gio_Mbr_ama_Master || - n->mode == gio_Mbr_ama_Arbitrating ) - return 0; /* skip ourself */ - if( n->State == gio_Mbr_Logged_in ) { - - log_msg(lgm_Subscribers, "Sending Quorum update to slave %s\n", n->Name); - err=send_quorum(n->poll_idx); - if( err != 0 ) { - log_msg(lgm_Always,"Could not send quorum update to slave %s\n", - n->Name); - } - } - return 0; -} - -/** - * send_quorum_to_slaves - - * @oid: - * - * - * Returns: int - */ -int send_quorum_to_slaves(void) -{ - return hash_walk(Nodes_by_Name, _send_quorum_to_slave_, NULL); -} -/*****************************************************************************/ -/** - * print_node - - * @FP: - * @n: - * - * Returns: void - */ -void print_node(FILE *FP, Node_t *n) -{ - struct timeval tv; - uint64_t fulltime; - gettimeofday(&tv, NULL); - fulltime = tvs2uint64(tv); - fprintf(FP, " name: %s\n", n->Name); - switch(n->State) { -#define CP(x) case (x): fprintf(FP," State: %s\n",#x); break - CP(gio_Mbr_Logged_in); - CP(gio_Mbr_Logged_out); - CP(gio_Mbr_Expired); - CP(gio_Mbr_OM_lgin); - default: fprintf(FP,"Unknown node state!!!! %d\n",n->State);break; -#undef CP - } - switch(n->last_state) { -#define CP(x) case (x): fprintf(FP,"lastState: %s\n",#x); break - CP(gio_Mbr_Logged_in); - CP(gio_Mbr_Logged_out); - CP(gio_Mbr_Expired); - CP(gio_Mbr_OM_lgin); - default: fprintf(FP,"Unknown node state!!!! %d\n",n->State);break; -#undef CP - } - fprintf(FP, " missed: %u\n",n->missed_beats); - fprintf(FP, " last: %"PRIu64"\n", n->last_beat); - fprintf(FP, " current: %"PRIu64"\n", fulltime); - fprintf(FP, " avg: %"PRIu64"\n", n->delay_avg); - fprintf(FP, " max: %"PRIu64"\n", n->max_delay); - -} - -int _print_one_node_(LLi_t *item, void *misc) -{ - Node_t *n; - FILE *FP; - n = LLi_data(item); - FP = (FILE*)misc; - print_node(FP,n); - fprintf(FP,"\n"); - return 0; -} -int fdump_nodes(FILE *f) -{return hash_walk(Nodes_by_Name, _print_one_node_, f);} - -/** - * list_heartbeat_lru - - * @fp: - */ -void list_heartbeat_lru(FILE *fp) -{ - LLi_t *tmp; - Node_t *n; - fprintf(fp,"======================\nheartbeat_lru\n"); - for(tmp = LLi_prev(&heartbeat_lru) ; - NULL != LLi_data(tmp) ; - tmp = LLi_prev(tmp)) { - n = LLi_data(tmp); - fprintf(fp," %s\n", n->Name); - } -} - -/** - * dump_nodes - - * - */ -void dump_nodes(void) -{ - FILE *fp; - int fd; - if( (fd=open_tmp_file("Gulm_Nodelist")) < 0 ) return; - if((fp = fdopen(fd, "a")) == NULL ) return; - fprintf(fp,"========================================" - "========================================\n"); - fdump_nodes(fp); - list_heartbeat_lru(fp); - fclose(fp); -} - -/** - * encode_one_node - - * @enc: - * @N: - * - * - * Returns: int - */ -int encode_one_node(xdr_enc_t *enc, Node_t *N) -{ - int err; - if((err=xdr_enc_string(enc, N->Name)) <0) return err; - if((err=xdr_enc_ipv6(enc, &N->ip)) <0) return err; - if((err=xdr_enc_uint8(enc, N->State)) <0) return err; - if((err=xdr_enc_uint8(enc, N->last_state)) <0) return err; - if((err=xdr_enc_uint8(enc, N->mode)) <0) return err; - if((err=xdr_enc_uint32(enc, N->missed_beats)) <0) return err; - if((err=xdr_enc_uint64(enc, N->last_beat)) <0) return err; - if((err=xdr_enc_uint64(enc, N->delay_avg)) <0) return err; - if((err=xdr_enc_uint64(enc, N->max_delay)) <0) return err; - - return 0; -} - -/** - * add_node - - * @name: - * @type: - * @ip: - * @stomith: - * - * - * Returns: int - */ -int add_node(char *name, struct in6_addr *ip) -{ - LLi_t *tmp; - Node_t *n; - int e=-3; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL ) { - n = malloc(sizeof(Node_t)); - if( n == NULL ) return -1; - memset(n,0,sizeof(Node_t)); - LLi_init(&n->By_Name, n); - LLi_init(&n->lru, n); - n->State = gio_Mbr_Logged_out; - n->last_state = gio_Mbr_Logged_out; - n->poll_idx = -1; - n->Name = strdup(name); - memcpy(&n->ip, ip, sizeof(struct in6_addr)); - if(n->Name == NULL) goto fail; - - e = hash_add(Nodes_by_Name, &n->By_Name); - if( e<0) { - log_err("Failed to add %s(%s) to Name hash. %s\n", name, ip6tostr(ip), - (e==-1)?"All ready in table":""); - goto fail; - } - }else{ - n = LLi_data(tmp); - } - - return 0; -fail: - if(n->Name != NULL) free(n->Name); - - free(n); - return e; -} - -/** - * get_node - - * @name: - * - * - * Returns: int - */ -int get_node(xdr_enc_t *enc, char *name) -{ - LLi_t *tmp = NULL; - int err = gio_Err_Ok; - - if( name != NULL ) - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - - do { - if((err=xdr_enc_uint32(enc, gulm_core_mbr_lstrpl)) <0) break; - if((err=xdr_enc_list_start(enc)) <0) break; - - if( tmp != NULL ) - if((err=encode_one_node(enc, LLi_data(tmp))) <0) break; - - if((err=xdr_enc_list_stop(enc)) <0) break; - if((err=xdr_enc_flush(enc)) <0) break; - }while(0); - - return err; -} - -/** - * _get_all_nodes_ - - * @item: - * @misc: - * - * - * Returns: int - */ -int _get_all_nodes_(LLi_t *item, void *misc) -{ - xdr_enc_t *enc = (xdr_enc_t*)misc; - Node_t *n = LLi_data(item); - return encode_one_node(enc, n); -} -/** - * serialize_node_list - - * @enc: - * - * - * Returns: int - */ -int serialize_node_list(xdr_enc_t *enc) -{ - int err = 0; - - do { - if((err=xdr_enc_uint32(enc, gulm_core_mbr_lstrpl)) <0) break; - if((err=xdr_enc_list_start(enc)) <0) break; - - if((err=hash_walk(Nodes_by_Name, _get_all_nodes_, enc)) <0) break; - - if((err=xdr_enc_list_stop(enc)) <0) break; - if((err=xdr_enc_flush(enc)) <0) break; - }while(0); - - return err; -} - -/** - * deserialize_node_list - - * @dec: - * - * - * Returns: int - */ -int deserialize_node_list(xdr_dec_t *dec) -{ - int err; - uint8_t *x_name; - uint32_t x_code; - LLi_t *tmp; - Node_t *n; - - if((err=xdr_dec_uint32(dec, &x_code)) < 0) return err; - if((err=xdr_dec_list_start(dec)) < 0) return err; - while( xdr_dec_list_stop(dec) != 0 ) { - - /* get name. check to see if it exists. */ - if((err=xdr_dec_string(dec, &x_name)) < 0) return err; - if( x_name == NULL ) {return -ENOMEM;} - - tmp = hash_find(Nodes_by_Name, x_name, strlen(x_name)); - if( tmp == NULL ) { - n = malloc(sizeof(Node_t)); - if( n == NULL ) return -ENOMEM; - memset(n, 0, sizeof(Node_t)); - n->Name = x_name; - LLi_init( &n->By_Name, n); - LLi_init(&n->lru, n); - n->poll_idx = -1; - err = hash_add(Nodes_by_Name, &n->By_Name); - if( err != 0 ) { - /* should not get here, since we just checked to see that this - * name was not in the hash. - */ - log_err("Failed to add %s to the Name hash.\n", x_name); - free(x_name); - free(n); - return err; - } - n->sweepcheck = NLSC_New; - } else { - n = LLi_data(tmp); - free(x_name); /* don't need this, as it is already in the struct */ - x_name = NULL; - /* we're not master if we're here, so we know there can be no - * connections. Mark as such. - */ - n->poll_idx = -1; - n->sweepcheck = NLSC_Copied; - } - - if((err=xdr_dec_ipv6(dec, &(n->ip) )) < 0) return err; - if((err=xdr_dec_uint8(dec, &(n->State) )) < 0) return err; - if((err=xdr_dec_uint8(dec, &(n->last_state) )) < 0) return err; - if((err=xdr_dec_uint8(dec, &(n->mode) )) < 0) return err; - if((err=xdr_dec_uint32(dec, &(n->missed_beats))) < 0) return err; - if((err=xdr_dec_uint64(dec, &(n->last_beat))) < 0) return err; - if((err=xdr_dec_uint64(dec, &(n->delay_avg))) < 0) return err; - if((err=xdr_dec_uint64(dec, &(n->max_delay))) < 0) return err; - - } - return 0; -} - -/** - * lookup_nodes_ip - - * @name: - * @ip: - * - * Gets the ip of a logged in node. - * - * Returns: int - */ -int lookup_nodes_ip(char *name, struct in6_addr *ip) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - memcpy(ip, &n->ip, sizeof(struct in6_addr)); - return 0; -} - -/** - * set_nodes_mode - - * @name: - * @mode: - * - * - * Returns: int - */ -int set_nodes_mode(char *name, int mode) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - n->mode = mode; - - return gio_Err_Ok; -} - -/** - * Mark_Loggedin - - * @name: - * - * - * Returns: =0:ok, !0:Error - */ -int Mark_Loggedin(char *name) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - if( n->State != gio_Mbr_Logged_out && - n->State != gio_Mbr_OM_lgin ) - return gio_Err_BadStateChg; - - n->last_state = n->State; - n->State = gio_Mbr_Logged_in; - - /* put onto MRU */ - move_to_mru(n); - - return gio_Err_Ok; -} - -/** - * Mark_Loggedout - - * @name: - * - * loggedout == deleted. - * - * Returns: =0:ok, !0:Error - */ -int Mark_Loggedout(char *name) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - remove_from_lru(n); - n->last_state = n->State; - n->State = gio_Mbr_Logged_out; - n->poll_idx = -1; - - return gio_Err_Ok; -} - -/** - * Mark_lgout_from_Exp - - * @name: - * - * full logout, so free struct. - * - * Returns: =0:ok, !0:Error - */ -int Mark_lgout_from_Exp(char *name) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - remove_from_lru(n); - n->last_state = n->State; - n->State = gio_Mbr_Logged_out; - n->poll_idx = -1; - return gio_Err_Ok; -} - -/** - * Mark_Expired - - * @name: - * - * for when slave gets updates from master. - * - * Returns: =0:ok, !0:Error - */ -int Mark_Expired(char *name) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - remove_from_lru(n); - - n->last_state = n->State; - n->State = gio_Mbr_Expired; - n->poll_idx = -1; - - return gio_Err_Ok; -} - -/** - * _find_matching_ip - - * @item: - * @misc: - * - * - * Returns: 0 if no match, 1 if there is a match. - */ -int _find_matching_ip(LLi_t *item, void *misc) -{ - Node_t *n; - n = LLi_data(item); - - - if(!memcmp(&n->ip, misc, sizeof(struct in6_addr))) { - remove_from_lru(n); - n->last_state = n->State; - n->State = gio_Mbr_Expired; - n->poll_idx = -1; - return 1; - } - - return 0; -} - -/** - * Mark_Expired_IP - - * @ip: - * - * for when slave gets updates from master. - * - * Returns: =0:ok, !0:Error - */ -int Mark_Expired_IP(struct in6_addr *ip) -{ - int tmp; - - tmp = hash_walk(Nodes_by_Name, _find_matching_ip, ip); - if( tmp == 0) return gio_Err_Unknown_Cs; - - return gio_Err_Ok; -} - -/* - * Die_if_expired - - * @name: - * - */ -void Die_if_expired(char *name) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return; - - n = LLi_data(tmp); - - if( n->State == gio_Mbr_Expired ) { - die(ExitGulm_BadLogic,"I cannot run when marked expired.\n"); - } - -} - -/** - * do_node_Expired - - * @n: - * - * - * Returns: void - */ -void do_node_Expired(Node_t *n) -{ - log_msg(lgm_Stomith,"Client (%s) expired\n", n->Name); - n->State = gio_Mbr_Expired; - - remove_from_lru(n); - - /* send first so that the expired msg can make it to the expired node if - * it happens to be in one of those messed up cases where it is still - * connected but actually expired. - */ - send_mbrshp_to_children(n->Name, gio_Mbr_Expired); - send_mbrshp_to_slaves(n->Name, gio_Mbr_Expired); - - close_by_idx(n->poll_idx); - - n->poll_idx = -1; - - queue_node_for_fencing(n->Name); -} - -/** - * Force_Node_Expire - - * @name: - * - * - * Returns: int - */ -int Force_Node_Expire(char *name) -{ - LLi_t *tmp; - Node_t *n; - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - if( n->State != gio_Mbr_Logged_in) return gio_Err_BadStateChg; - - do_node_Expired(n); - return gio_Err_Ok; -} - -/** - * beat_node - - * @name: < - * @poll_idx: < which entry in the pollers - * - * Returns: =0:Ok, !0:Error - */ -int beat_node(char *name, int poll_idx) -{ - LLi_t *tmp; - Node_t *n; - struct timeval tv; - uint64_t fulltime; - - gettimeofday(&tv, NULL); - fulltime = tvs2uint64(tv); - - tmp = hash_find(Nodes_by_Name, name, strlen(name)); - if( tmp == NULL) return gio_Err_Unknown_Cs; - - n = LLi_data(tmp); - - if( n->State != gio_Mbr_Logged_in && n->State != gio_Mbr_OM_lgin ) { - log_err("Cannot heartbeat if not logged in.\n"); - print_node(stderr,n); - return gio_Err_NotAllowed; - } - - log_msg(lgm_Heartbeat, "Got heartbeat from %s at %"PRIu64" " - "(last:%"PRIu64" max:%"PRIu64" avg:%"PRIu64")\n", - n->Name, fulltime, - (fulltime - n->last_beat), - n->max_delay, n->delay_avg); - - if( n->last_beat != 0 ) { - if( n->delay_avg != 0) - n->delay_avg = ( n->delay_avg + (fulltime - n->last_beat) ) /2; - else - n->delay_avg = fulltime - n->last_beat; - n->max_delay = MAX(n->max_delay, (fulltime - n->last_beat) ); - } - - n->last_beat = fulltime; - n->missed_beats = 0; - n->poll_idx = poll_idx; - move_to_mru(n); - - return gio_Err_Ok; -} - -/** - * check_beats - - * - * Returns: int - */ -int check_beats(void) -{ - static uint64_t lastrun=0; - uint64_t fulltime; - struct timeval tv; - LLi_t *tmp, *nxt; - Node_t *n; - - gettimeofday(&tv,NULL); - fulltime = tvs2uint64(tv); - - if( fulltime > lastrun + (gulm_config.heartbeat_rate/2) ) { - lastrun = fulltime; - - /* walk the lru until last_beat + timeout is more than current. */ - for(tmp = LLi_prev(&heartbeat_lru) ; - NULL != LLi_data(tmp) ; - tmp = nxt) { - nxt = LLi_prev(tmp); - - n = LLi_data(tmp); - - if( n->State == gio_Mbr_Logged_in || - n->State == gio_Mbr_OM_lgin ) { - - if( fulltime > n->last_beat + gulm_config.heartbeat_rate ) { - n->missed_beats++; - /* put current into last_beat so that we will wait the full - * timeout rate before incrementing the missed_beats again. - */ - n->last_beat = fulltime; - - /* since this is a virtual heartbeat of sorts, put onto MRU */ - move_to_mru(n); - - log_msg(lgm_Network, "%s missed a heartbeat (time:%"PRIu64 - " mb:%d)\n", - n->Name, fulltime, n->missed_beats); - }else{ - /* this node has heartbeated in time. - * Therefor, everyone else in this list has also sent - * heartbeats in time. - * So we're done scanning the list. - */ - break; - } - - if( n->missed_beats > gulm_config.allowed_misses ) { - do_node_Expired(n); - } - }/* logged in? */ - }/* for items in list */ - } - - return gio_Err_Ok; -} - - -/** - * _inner_beat_all_ - - * @item: - * @misc: - * - * - * Returns: int - */ -int _inner_beat_all_(LLi_t *item, void *misc) -{ - Node_t *n; - n = LLi_data(item); - - if( n->State == gio_Mbr_Logged_in || - n->State == gio_Mbr_OM_lgin) { - beat_node(n->Name, -1); - } - return 0; -} - -/** - * beat_all_once - - * - * This is for when Node was slave, and becomes Master. All of the Node - * entries have zeros in the time fields. So when we call check_beats() - * every node will get fenced. We need to give them time to get logged - * back in and start heartbeating again. And this is how we do it. - * - * Returns: int - */ -int beat_all_once(void) -{ - return hash_walk(Nodes_by_Name, _inner_beat_all_, NULL); -} - -int _inner_fence_expired (LLi_t *item, void *misc) -{ - Node_t *n; - n = LLi_data(item); - - if( n->State == gio_Mbr_Expired ) { - queue_node_for_fencing(n->Name); - } - return 0; -} -/** - * fence_all_expired - - * - * fences all expired nodes in the list - * - * Returns: int - */ -int fence_all_expired(void) -{ - return hash_walk(Nodes_by_Name, _inner_fence_expired, NULL); -} - - -/** - * _inner_Mark_Old_Master_lgin - - * @item: - * @misc: - * - * - * Returns: int - */ -int _inner_Mark_Old_Master_lgin(LLi_t *item, void *misc) -{ - Node_t *n; - n = LLi_data(item); - - if( n->State == gio_Mbr_Logged_in) { - n->last_state = n->State; - n->State = gio_Mbr_OM_lgin; - } - return 0; -} -int Mark_Old_Master_lgin(void) -{ - return hash_walk(Nodes_by_Name, _inner_Mark_Old_Master_lgin, NULL); -} - -/** - * _inner_Logout_leftovers - - * @item: - * @misc: - * - * - * Returns: int - */ -int _inner_ucan(LLi_t *item, void *misc) -{ - Node_t *n; - n = LLi_data(item); - - if( n->sweepcheck == NLSC_Tagged ) { - /* This node was logged in our old nodelist. If they got logged out - * since, we need to supply updates. - */ - if( n->State == gio_Mbr_Logged_out ) { - if( n->last_state == gio_Mbr_Logged_in ) { - log_msg(lgm_Always, "Node %s logged out while we were without a " - "Master.\n", n->Name); - send_mbrshp_to_children(n->Name, gio_Mbr_Logged_out); - }else - if( n->last_state == gio_Mbr_Expired ) { - log_msg(lgm_Always, "Node %s Expired and Fenced while we were " - "without a Master.\n", n->Name); - send_mbrshp_to_children(n->Name, gio_Mbr_Expired); - send_mbrshp_to_children(n->Name, gio_Mbr_Killed); - } - }else - if( n->State == gio_Mbr_Expired ) { - /* they haven't been killed yet. but soon.... */ - log_msg(lgm_Always, "Node %s Expired while we were " - "without a Master.\n", n->Name); - send_mbrshp_to_children(n->Name, gio_Mbr_Expired); - } - - remove_from_lru(n); - n->poll_idx = -1; - }else - if( n->sweepcheck == NLSC_New || n->sweepcheck == NLSC_Copied ) { - /* this node is new to us, children need to know that too. */ - send_mbrshp_to_children(n->Name, n->State); - } - - n->sweepcheck = NLSC_Clear; - return 0; -} -int Update_children_about_nodelist(void) -{ - return hash_walk(Nodes_by_Name, _inner_ucan, NULL); -} -int _inner_tag_for_lost(LLi_t *item, void *misc) -{ - Node_t *n; - n = LLi_data(item); - - if( n->State != gio_Mbr_Logged_out) - n->sweepcheck = NLSC_Tagged; - - return 0; -} -int tag_for_lost(void) -{ - return hash_walk(Nodes_by_Name, _inner_tag_for_lost, NULL); -} - -int _update_mru_list(LLi_t *item, void *misc) { - Node_t *n; - n = LLi_data(item); - - if (n->State == gio_Mbr_Logged_in) - move_to_mru(n); - return 0; -} - -void update_mru_list(void) -{ - hash_walk(Nodes_by_Name, _update_mru_list, NULL); - return; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/core_priv.h b/gulm/src/core_priv.h deleted file mode 100644 index 7f43c0d..0000000 --- a/gulm/src/core_priv.h +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_core_priv_h__ -#define __gulm_core_priv_h__ -#include "xdr.h" -#include <arpa/inet.h> -/* proto types for all funcs that cross files in core need to go here. - * If some non core_* file needs a prototype, it needs to get it from a - * different file! - */ -/* core_fence */ -void init_fence(void); -void queue_node_for_fencing(uint8_t *Name); -int check_for_zombied_stomiths(pid_t pid, int status); - -/* core_resources */ -int init_resources(void); -int send_mbrshp_to_children(char *name, int st); -int send_core_state_to_children(void); -void dump_resources(void); -void serialize_resources(xdr_enc_t *enc); -int add_resource(char *name, int poll_idx, uint32_t options); -int release_resource(char *name); -int die_with_me(char *name); - -/* core_nodelist */ -int init_nodes(void); -void release_nodelist(void); -int send_mbrshp_to_slaves(char *name, int st); -int send_quorum_to_slaves(void); -void dump_nodes(void); -int add_node(char *name, struct in6_addr *ip); -int lookup_nodes_ip(char *name, struct in6_addr *ip); -int set_nodes_mode(char *name, int mode); -int Mark_Loggedin(char *name); -int Mark_Loggedout(char *name); -int Mark_lgout_from_Exp(char *name); -int Mark_Expired(char *name); -int Mark_Expired_IP(struct in6_addr *ip); -void Die_if_expired(char *name); -int Force_Node_Expire(char *name); -int beat_node(char *name, int poll_idx); -int check_beats(void); -int beat_all_once(void); -int fence_all_expired(void); -int Mark_Old_Master_lgin(void); -int tag_for_lost(void); -int Update_children_about_nodelist(void); -int get_node(xdr_enc_t *enc, char *name); -int serialize_node_list(xdr_enc_t *enc); -int deserialize_node_list(xdr_dec_t *dec); - -/* core_io */ -int open_max(void); -char *get_Master_Name(void); -int init_core_poller(void); -int open_core_listener(int port); -void release_core_poller(void); -int do_logout(void); -void decrement_quorumcount(void); -int send_update(int poll_idx, char *name, int st, struct in6_addr *ip); -int send_quorum(int poll_idx); -int send_core_state_update(int poll_idx); -void switch_into_Pending(void); -void work_loop(void); - -void close_by_idx(int idx); -int add_resource_poller(int fd, char *name); - -#endif /*__gulm_core_priv_h__*/ - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/core_resources.c b/gulm/src/core_resources.c deleted file mode 100644 index 6d68095..0000000 --- a/gulm/src/core_resources.c +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "LLi.h" -#include "hash.h" -#include "myio.h" -#include "gio_wiretypes.h" -#include "xdr.h" -#include "core_priv.h" -#include "config_gulm.h" -#include "lock.h" -#include "utils_dir.h" -#include "utils_ip.h" -#include "utils_tostr.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; -extern unsigned int shutdown_locked; -extern char *myName; -extern struct in6_addr myIP; -extern int I_am_the; -extern gulm_config_t gulm_config; - - -typedef struct Resource_s { - LLi_t r_list; - char *name; - int poll_idx; - uint32_t options; -}Resource_t; - -hash_t *Resources; - -/* Key accessor functions for hashtable. */ -unsigned char *getresname(void *item) -{ - Resource_t *n = (Resource_t*)item; - return n->name; -} -int getresNln(void *item) -{ - Resource_t *n=(Resource_t*)item; - return strlen(n->name); -} - - -/*****************************************************************************/ -/** - * init_resources - - */ -int init_resources(void) -{ - Resources = hash_create(16, getresname, getresNln); - if( Resources == NULL ) return -1; - return 0; -} - -/** - * add_resoruce - - * @name: - * @poll_idx: - * - * - * Returns: int - */ -int add_resource(char *name, int poll_idx, uint32_t options) -{ - Resource_t *r; - - r = malloc(sizeof(Resource_t)); - if( r == NULL ) return -ENOMEM; - memset(r,0,sizeof(Resource_t)); - - LLi_init(&r->r_list, r); - - r->name = strdup(name); - if( r->name == NULL ) { - free(r); - return -ENOMEM; - } - - r->poll_idx = poll_idx; - r->options = options; - - if( r->options & gulm_svc_opt_locked ) shutdown_locked ++; - - return hash_add(Resources, &r->r_list); -} - -/** - * release_resource - - * @name: - * - * - * Returns: int - */ -int release_resource(char *name) -{ - LLi_t *tmp; - Resource_t *r; - - tmp = hash_del(Resources, name, strlen(name)); - if( tmp == NULL ) return -1; /* not found */ - r = LLi_data(tmp); - if( r->options & gulm_svc_opt_locked ) shutdown_locked --; - free(r->name); - free(r); - return 0; -} - -/** - * die_with_me - - * @name: - * - * returns true if important. - * - * Returns: TRUE or FALSE - */ -int die_with_me(char *name) -{ - LLi_t *tmp; - Resource_t *r; - - tmp = hash_find(Resources, name, strlen(name)); - if( tmp == NULL ) return FALSE; - r = LLi_data(tmp); - return r->options & gulm_svc_opt_important; -} - -/** - * _dump_resource_ - - * @item: - * @misc: - * - * - * Returns: int - */ -int _dump_resource_(LLi_t *item, void *misc) -{ - FILE *fp = (FILE*)misc; - Resource_t *r = LLi_data(item); - - fprintf(fp, "Service = %s\n", r->name); - fprintf(fp, "poller = %d\n", r->poll_idx); - fprintf(fp, "options = %#x\n\n", r->options); - - return 0; -} - -/** - * dump_resources - - */ -void dump_resources(void) -{ - FILE *fp; - int fd; - if( (fd=open_tmp_file("Gulm_Services")) < 0) return; - if((fp = fdopen(fd, "a")) == NULL ) return; - fprintf(fp,"========================================" - "========================================\n"); - hash_walk(Resources, _dump_resource_, fp); - fclose(fp); -} - -/** - * _send_one_ - - * @item: - * @misc: - * - * - * Returns: int - */ -int _send_one_(LLi_t *item, void *misc) -{ - int err; - xdr_enc_t *enc = (xdr_enc_t *)misc; - Resource_t *r = LLi_data(item); - - err = xdr_enc_string(enc, r->name); - - return err; -} - -/** - * serialize_resources - - * @enc: - * - */ -void serialize_resources(xdr_enc_t *enc) -{ - xdr_enc_uint32(enc, gulm_core_res_list); - xdr_enc_list_start(enc); - hash_walk(Resources, _send_one_, enc); - xdr_enc_list_stop(enc); - xdr_enc_flush(enc); -} - -/*****************************************************************************/ -typedef struct { - char *name; - uint8_t st; - struct in6_addr ip; -} smtc_t; -int _send_mbrshp_to_children_(LLi_t *item, void *misc) -{ - smtc_t *s = (smtc_t*)misc; - Resource_t *r = LLi_data(item); - - if( r->poll_idx > 0 ) { - /* if not valid, just skip. */ - log_msg(lgm_Subscribers, - "Sending Membership update "%s" about %s to child %s\n", - gio_mbrupdate_to_str(s->st), - s->name, r->name); - - if( send_update(r->poll_idx, s->name, s->st, &s->ip) < 0 ) { - log_err("Error sending sub info to child(%s). (%s)\n", - r->name, strerror(errno)); - /* really not sure how to handle errors from resources. */ - } - } - - return 0; -} - -/** - * send_mbrshp_to_children - - * @name: - * @st: - * - * passes the membership information up to the children processes. - * - * Returns: int - */ -int send_mbrshp_to_children(char *name, int st) -{ - smtc_t s; - - s.name = name; - s.st = st; - - if( lookup_nodes_ip(name, &s.ip) != 0 ) { - /* not in node list, use normal lookups. */ - if( get_ip_for_name(name, &s.ip) != 0 ) { - memset(&s.ip, 0, sizeof(struct in6_addr)); - /* we cannot find it, leave it zero. and let the receiver worry - * about it. - */ - } - } - - return hash_walk(Resources, _send_mbrshp_to_children_, &s); -} - -/** - * _send_core_state_to_children_ - - * @item: - * @misc: - * - * - * Returns: int - */ -int _send_core_state_to_children_(LLi_t *item, void *misc) -{ - Resource_t *r = LLi_data(item); - - if( r->poll_idx > 0 ) { - log_msg(lgm_Subscribers, - "Sending Core state %s to %s\n", - gio_I_am_to_str(I_am_the), r->name); - - if( send_core_state_update(r->poll_idx) != 0 ) - log_err("Error sending core state information to child %s: %s\n", - r->name, strerror(errno)); - } - - return 0; -} - -/** - * send_core_state_to_children - - * Returns: int - */ -int send_core_state_to_children(void) -{ - return hash_walk(Resources, _send_core_state_to_children_, NULL); -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/gio_wiretypes.h b/gulm/src/gio_wiretypes.h deleted file mode 100644 index 21b3b19..0000000 --- a/gulm/src/gio_wiretypes.h +++ /dev/null @@ -1,486 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gio_wiretypes_h__ -#define __gio_wiretypes_h__ - -/* an attempt to do something about tracking changes to the protocol over - * the wires. - * If I was really cute, this would be effectivily a checksum of this file. - */ -#define GIO_WIREPROT_VERS (0x67000015) - -/*****************Error codes. - * everyone uses these same error codes. - */ -#define gio_Err_Ok (0) -#define gio_Err_BadLogin (1001) -#define gio_Err_BadCluster (1003) -#define gio_Err_BadConfig (1004) -#define gio_Err_BadGeneration (1005) -#define gio_Err_BadWireProto (1019) - -#define gio_Err_NotAllowed (1006) -#define gio_Err_Unknown_Cs (1007) -#define gio_Err_BadStateChg (1008) -#define gio_Err_MemoryIssues (1009) - -#define gio_Err_TryFailed (1011) -#define gio_Err_AlreadyPend (1013) -#define gio_Err_Canceled (1015) - -/* next free error code: 1002 1010 1012 1014 1016 1017 1018 1020 */ - -/* - * Error: just sort of a generic error code thing. - * uint32: gERR - * uint32: opcode that this is in reply to. (can be zeros) - * uint32: error code - */ -#define gulm_err_reply (0x67455252) /* gERR */ - -#define gulm_nop (0x674e4f50) /* gNOP */ - -/********************* Core *****************/ -/* - * login request - * uint32: gCL0 - * uint32: proto version - * string: cluster ID - * string: My Name - * uint64: generation number - * uint32: config CRC - * uint32: rank - * login reply - * uint32: gCL1 - * uint64: generation number - * uint32: error code - * uint32: rank - * uint8: ama - * If I am the Master or Arbitrating and there are no errors, A - * serialization of the current nodelist follows. And a client or slave - * is connecting (not resources). - * - * logout request: - * uint32: gCL2 - * string: node name - * uint8: S/P/A/M/R - * logout reply: Don't seem to use this.... - * uint32: gCL3 - * uint32: error code - * - * resource login request: - * uint32: gCL4 - * uint32: proto version - * string: cluster ID - * string: resource name - * uint32: options - * login reply (gCL1) is sent in return. - * - * beat req - * uint32: gCB0 - * string: My Name - * beat rpl - * uint32: gCB1 - * uint32: error code - * - * Membership Request - * uint32: gCMA - * string: node name - * - * Membership update - * uint32: gCMU - * string: node name - * IPv6: IP - * uint8: Current State - * - * Membership list request info. - * uint32: gCMl - * - * Membership list info. - * uint32: gCML - * list_start_marker - * string: node name - * IPv6: IP - * uint8: state - * uint8: laststate - * uint8: mode (S/P/A/M/C) - * uint32: missed beats - * uint64: last beat - * uint64: delay avg - * uint64: max delay - * list_stop_marker - * - * Request Resource info - * uint32: gCR0 - * - * Resource list info - * uint32: gCR1 - * list_start_marker - * string: name - * list_stop_marker - * - * Force node into Expired: - * uint32: gCFE - * string: node name - * - * Core state request: - * uint32: gCSR - * - * Core state changes: - * uint32: gCSC - * uint8: state (slave, pending, arbitrating, master) - * uint8: quorate (true/false) - * If state == Slave, then the next two will follow. - * IPv6: MasterIP - * string: MasterName - * - * Quorum Change: - * uint32: gCQC - * uint8: quorate (true/false) - * - * Core shutdown req: - * uint32: gCSD - * - * Switch core from current state into Pending: - * uint32: gCSP - * - * Fetch the current config - * uint32: gCC0 - * Current Config Reply: - * uint32: gCC1 - * list start: - * string: key - * string: value - * list stop: - * - */ -#define gulm_core_login_req (0x67434c00) /* gCL0 */ -#define gulm_core_login_rpl (0x67434c01) /* gCL1 */ -#define gulm_core_logout_req (0x67434c02) /* gCL2 */ -#define gulm_core_logout_rpl (0x67434c03) /* gCL3 */ -#define gulm_core_reslgn_req (0x67434c04) /* gCL4 */ -#define gulm_core_beat_req (0x67434200) /* gCB0 */ -#define gulm_core_beat_rpl (0x67434201) /* gCB1 */ -#define gulm_core_mbr_req (0x67434d41) /* gCMA */ -#define gulm_core_mbr_updt (0x67434d55) /* gCMU */ -#define gulm_core_mbr_lstreq (0x67434d6c) /* gCMl */ -#define gulm_core_mbr_lstrpl (0x67434d4c) /* gCML */ -#define gulm_core_mbr_force (0x67434645) /* gCFE */ -#define gulm_core_res_req (0x67435200) /* gCR0 */ -#define gulm_core_res_list (0x67435201) /* gCR1 */ -#define gulm_core_state_req (0x67435352) /* gCSR */ -#define gulm_core_state_chgs (0x67435343) /* gCSC */ -#define gulm_core_quorm_chgs (0x67435143) /* gCSC */ -#define gulm_core_shutdown (0x67435344) /* gCSD */ -#define gulm_core_forcepend (0x67435350) /* gCSP */ -#define gulm_core_configreq (0x67434300) /* gCC0 */ -#define gulm_core_configrpl (0x67434301) /* gCC1 */ - -/* in the st field */ -#define gio_Mbr_Logged_in (0x05) -#define gio_Mbr_Logged_out (0x06) -#define gio_Mbr_Expired (0x07) -#define gio_Mbr_Killed (0x08) -#define gio_Mbr_OM_lgin (0x09) - -/* in the ama field */ -#define gio_Mbr_ama_Slave (0x01) -#define gio_Mbr_ama_Master (0x02) -#define gio_Mbr_ama_Pending (0x03) -#define gio_Mbr_ama_Arbitrating (0x04) -#define gio_Mbr_ama_Resource (0x05) -#define gio_Mbr_ama_Client (0x06) -/* the Client entery is ONLY for mode tracking. - * nodelist reply is the only place it is used. - */ - -/* options that affect behavors on services. (resources) */ -#define gulm_svc_opt_important (0x00000001) -#define gulm_svc_opt_locked (0x00000002) - -/********************* Info Traffic ***************** - * - * Note that for many of these, they can be sent to all of the servers and - * will get sane replies. Some of these can only be sent to specific - * servers. - * - * stats req: - * uint32: gIS0 - * stats rpl: - * uint32: gIS1 - * list start: - * string: key - * string: value - * list stop: - * Notes: - * The stats reply is a set of string pairs. This way the server can send - * whatever things it wants, and the same client code will work for - * anything. - * - * set verbosity: - * uint32: gIV0 - * string: verb flags (with -/+) to [un]set - * Note: - * We don't bother with a reply for this. If the server got it, it works. - * If it didn't, it cannot send an error back anyways. - * - * close socket: - * uint32: gSC0 - * Note: - * Tells the server to close this connection cleanly. We're done with - * it. This is *not* the same as loging out. You must login before you - * can logout. And many commands sent from gulm_tool happen without - * logging in. These commands would be useful for clients in many cases, - * so I don't want to put a close at the end of them, but if I don't, - * there will be error messages printed on the console when gulm_tool - * calls them. - * So we need a way to close a connection cleanly that has not been - * logged in. - * - * request slave list: - * uint32: gIL0 - * slave list replay: - * uint32: gIL1 - * list start: - * string: name - * uint32: poller idx - * list stop: - */ -#define gulm_info_stats_req (0x67495300) /* gIS0 */ -#define gulm_info_stats_rpl (0x67495301) /* gIS1 */ -#define gulm_info_set_verbosity (0x67495600) /* gIV0 */ -#define gulm_socket_close (0x67534300) /* gSC0 */ -#define gulm_info_slave_list_req (0x67494c00) /* gIL0 */ -#define gulm_info_slave_list_rpl (0x67494c01) /* gIL1 */ - -/********************* Lock Traffic ***************** - * All lock traffic. - * - * login req: - * uint32: gLL0 - * uint32: proto version - * string: node name - * uint8: Client/Slave - * login rpl: - * uint32: gLL1 - * uint32: error code - * uint8: Slave/Master - * xdr of current lock state if no errors and master sending reply - * and you're a slave. - * - * logout req: - * uint32: gLL2 - * logout rpl: - * uint32: gLL3 - * - * select lockspace: - * uint32: gLS0 - * raw: usually just four bytes for lockspace name. - * but can be most anything. - * uh, i think i assume that it is only four bytes in some places. - * Need to look into this... - * - * lock req: - * uint32: gLR0 - * raw: key - * uint64: sub id - * uint64: start - * uint64: stop - * uint8: state - * uint32: flags - * raw: lvb -- Only exists if hasLVB flag is true. - * lock rpl: - * uint32: gLR1 - * raw: key - * uint64: sub id - * uint64: start - * uint64: stop - * uint8: state - * uint32: flags - * uint32: error code - * raw: lvb -- Only exists if hasLVB flag is true. - * - * lock state update: - * uint32: gLRU - * string: node name - * uint64: sub id - * uint64: start - * uint64: stop - * raw: key - * uint8: state - * uint32: flags - * raw: lvb -- Only exists if hasLVB flag is true. - * - * Action req: - * uint32: gLA0 - * raw: key - * uint64: sub id - * uint8: action - * raw: lvb -- Only exists if action is SyncLVB - * Action Rpl: - * uint32: gLA1 - * raw: key - * uint64: sub id - * uint8: action - * uint32: error code - * - * Action update: - * uint32: gLAU - * string: node name - * uint64: sub id - * raw: key - * uint8: action - * raw: lvb -- Only exists if action is SyncLVB - * - * Slave Update Rply: -- for both actions and requests. - * uint32: gLUR - * raw: key - * - * Query Lock Request: - * uint32: gLQ0 - * raw: key - * uint64: subid - * uint64: start - * uint64: stop - * uint8: state - * - * Query Lock Reply: - * uint32: gLQ1 - * raw: key - * uint64: subid - * uint64: start - * uint64: stop - * uint8: state - * uint32: error - * list start mark - * string: node - * uint64: subid - * uint64: start - * uint64: stop - * uint8: state - * list stop mark - * - * Drop lock Callback: - * uint32: gLC0 - * raw: key - * uint64: subid - * uint8: state - * - * Drop all locks callback: This is the highwater locks thing - * uint32: gLC2 - * - * Drop expired locks: - * uint32: gLEO - * string: node name if NULL, then drop all exp for mask. - * raw: keymask if keymask & key == key, then dropexp on this lock. - * - * Expire Locks: - * uint32: gLEE - * string: node name cannot be NULL - * raw: keymask if keymask & key == key, then expire on this lock. - * - * Lock list req: - * uint32: gLD0 - * Lock list rpl: - * uint32: gLD1 - * list start mark - * uint8: key length - * raw: key - * uint8: lvb length - * if lvb length > 0, raw: LVB - * uint32: Holder count - * list start mark - * string: holders - * uint64: subid - * uint8: state - * uint64: start - * uint64: stop - * list stop mark - * uint32: LVB holder count - * list start mark - * string: LVB Holders - * uint64: subid - * list stop mark - * uint32: Expired holder count - * list start mark - * string: ExpHolders - * uint64: subid - * list stop mark - * list stop mark - * - */ -#define gulm_lock_login_req (0x674C4C00) /* gLL0 */ -#define gulm_lock_login_rpl (0x674C4C01) /* gLL1 */ -#define gulm_lock_logout_req (0x674C4C02) /* gLL2 */ -#define gulm_lock_logout_rpl (0x674C4C03) /* gLL3 */ -#define gulm_lock_sel_lckspc (0x674C5300) /* gLS0 */ -#define gulm_lock_state_req (0x674C5200) /* gLR0 */ -#define gulm_lock_state_rpl (0x674C5201) /* gLR1 */ -#define gulm_lock_state_updt (0x674C5255) /* gLRU */ -#define gulm_lock_action_req (0x674C4100) /* gLA0 */ -#define gulm_lock_action_rpl (0x674C4101) /* gLA1 */ -#define gulm_lock_action_updt (0x674C4155) /* gLAU */ -#define gulm_lock_update_rpl (0x674c5552) /* gLUR */ -#define gulm_lock_query_req (0x674c5100) /* gLQ0 */ -#define gulm_lock_query_rpl (0x674c5101) /* gLQ1 */ -#define gulm_lock_cb_state (0x674C4300) /* gLC0 */ -#define gulm_lock_cb_dropall (0x674C4302) /* gLC2 */ -#define gulm_lock_drop_exp (0x674C454F) /* gLEO */ -#define gulm_lock_expire (0x674C4545) /* gLEE */ -#define gulm_lock_dump_req (0x674c4400) /* gLD0 */ -#define gulm_lock_dump_rpl (0x674c4401) /* gLD1 */ -#define gulm_lock_rerunqueues (0x674c5251) /* gLRQ */ - -/* marks for the login */ -#define gio_lck_st_Slave (0x00) -#define gio_lck_st_Client (0x01) - -/* state change requests */ -#define gio_lck_st_Unlock (0x00) -#define gio_lck_st_Exclusive (0x01) -#define gio_lck_st_Deferred (0x02) -#define gio_lck_st_Shared (0x03) -/* actions */ -#define gio_lck_st_Cancel (0x09) -#define gio_lck_st_HoldLVB (0x0b) -#define gio_lck_st_UnHoldLVB (0x0c) -#define gio_lck_st_SyncLVB (0x0d) - -/* flags */ - /* only valid with Try. Tells server to send out a drop lock callback. */ -#define gio_lck_fg_Do_CB (0x00000001) - /* try to get, if there are conflicts, return error instead of blocking */ -#define gio_lck_fg_Try (0x00000002) - /* Either Shared or Deferred. Only valid when state is Shr or Dfr. */ -#define gio_lck_fg_Any (0x00000004) - /* Ignore any expired holders on lock. */ -#define gio_lck_fg_NoExp (0x00000008) - /* There is an LVB attached to this lock msg. */ -#define gio_lck_fg_hasLVB (0x00000010) - /* Only returned by server. There was no internal unlocking to grant req. */ -#define gio_lck_fg_Cachable (0x00000020) - /* Put this request onto the front of the request queues. */ -#define gio_lck_fg_Piority (0x00000040) - /* this is just an idea, but it might be useful. Basically just says to - * not keep the exp hold, just drop this hold like a shared would be. - * no idea if it would be useful or sane. (but its two lines of code) - */ -#define gio_lck_fg_DropOnExp (0x00000080) - /* this is saved on each holder, basically, you are gonna ignore any - * callbacks about this lock, so tell the server not to even bother - * sending them. A tiny performance boost by lowering the network load. - */ -#define gio_lck_fg_NoCallBacks (0x00000100) - -#endif /*__gio_wiretypes_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/gulm_defines.h b/gulm/src/gulm_defines.h deleted file mode 100644 index 3b71143..0000000 --- a/gulm/src/gulm_defines.h +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * "...`gulm' sounds like someone choking on a sardine..." - */ -#ifndef __gulm_defines_h__ -#define __gulm_defines_h__ - -#include <unistd.h> -#include <stdio.h> -#include <execinfo.h> -#include <stdint.h> -#include <inttypes.h> -#include "osi_endian.h" /* because cpu_to_beXX() is damn nice. */ -#include "log.h" - -#if !defined(TRUE) || !defined(FALSE) -#undef TRUE -#undef FALSE -#define TRUE (1) -#define FALSE (0) -#endif - -#undef MAX -#define MAX(a,b) ((a>b)?a:b) - -#undef MIN -#define MIN(a,b) ((a<b)?a:b) - -#define DIV_RU(x, y) (((x) + (y) - 1) / (y)) - -#define CLUSTERIDLEN (32) - -/* Exit codes. gulm process will exit with one of the following */ -#define ExitGulm_Ok (0) -#define ExitGulm_TestFlag (0) -#define ExitGulm_Usage (0) -#define ExitGulm_ParseFail (50) -#define ExitGulm_BadOption (51) -#define ExitGulm_ExecError (52) -#define ExitGulm_SelfKill (53) -#define ExitGulm_StopAllReq (54) -#define ExitGulm_LeftLoop (55) -#define ExitGulm_ShutDown (56) -#define ExitGulm_PidLock (57) -#define ExitGulm_InitFailed (58) -#define ExitGulm_NoMemory (59) -#define ExitGulm_BadLogic (60) -#define ExitGulm_Assertion (61) - - -#define GULMD_ASSERT(x, action) { if( ! (x) ) {\ - void *array[200]; \ - size_t size,i; \ - char **strings; \ - do { action }while(0); \ - size = backtrace(array, 200); \ - strings = backtrace_symbols(array, size); \ - log_msg(lgm_Always, "BACKTRACE\n"); \ - for(i=0;i<size;i++) \ - log_msg(lgm_Always, " %s\n", strings[i]); \ - free(strings); \ - die(ExitGulm_Assertion, "ASSERTION FAILED: %s\n", #x ); } } - -#define tvs2uint64(n) ((uint64_t)(n).tv_sec * 1000000 + (n).tv_usec) - -#endif /*__gulm_defines_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/gulm_log_msg_bits.h b/gulm/src/gulm_log_msg_bits.h deleted file mode 100644 index f94b00e..0000000 --- a/gulm/src/gulm_log_msg_bits.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_log_msg_bits_h__ -#define __gulm_log_msg_bits_h__ -/* log_msg bit flags - * These got thier own file so I can easily include them in both user and - * kernel space. - * */ -#define lgm_Always (0x00000000) /*Print Message no matter what */ -#define lgm_Network (0x00000001) -#define lgm_Network2 (0x00000002) -#define lgm_Stomith (0x00000004) -#define lgm_Heartbeat (0x00000008) -#define lgm_locking (0x00000010) -#define lgm_FuncDebug (0x00000020) -#define lgm_Forking (0x00000040) -#define lgm_JIDMap (0x00000080) -#define lgm_Subscribers (0x00000100) -#define lgm_LockUpdates (0x00000200) -#define lgm_LoginLoops (0x00000400) -#define lgm_Network3 (0x00000800) -#define lgm_JIDUpdates (0x00001000) -#define lgm_ServerState (0x00002000) -#define lgm_Parsing (0x00004000) - -#define lgm_ReallyAll (0xffffffff) - -#define lgm_BitFieldSize (32) - -#endif /*__gulm_log_msg_bits_h__*/ diff --git a/gulm/src/gulm_tool.c b/gulm/src/gulm_tool.c deleted file mode 100644 index 3a8f41c..0000000 --- a/gulm/src/gulm_tool.c +++ /dev/null @@ -1,869 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdint.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/ioctl.h> - -#include "gio_wiretypes.h" -#include "xdr.h" -#include "utils_ip.h" -#include "utils_tostr.h" -#include "utils_verb_flags.h" -#define DEBUG /* don't print errors here to syslog */ -#include "gulm_defines.h" -#undef DEBUG - -char *prog_name; - -const char *usage[] = -{ -"Print tool version information\n", -" gulm_tool version\n", -"\n", -"Commands that can be sent to any server:\n", -" Change verbose flags\n", -" gulm_tool setverb server:port <flags>\n", -"\n", -" Get server statistics\n", -" gulm_tool getstats server:port\n", -"\n", -" Unparsed server statistics (useful if you know the code)\n", -" gulm_tool rawstats server:port\n", -"\n", -"Commands that can only be sent to gulm_core:\n", -" Stop the server and its resources:\n", -" gulm_tool shutdown <server>:core\n", -"\n", -" Get the current nodelist\n", -" gulm_tool nodelist <server>:core\n", -"\n", -" Get a single node\n", -" gulm_tool nodeinfo <server>:core <node name>\n", -"\n", -" Get list of services connected to this node\n", -" gulm_tool servicelist <server>:core\n", -"\n", -" Force a node into the Expired state, causing it to be fenced:\n", -" gulm_tool forceexpire <server>:core <node name>\n", -"\n", -" Switch the core on a node into the pending state.\n", -" gulm_tool switchPending <server>:core\n", -"\n", -#if DEBUG -"Commands for debugging things:\n", -" Rerun wait queues for all locks.\n", -" gulm_tool rerunqueues <server>:lt000\n", -"\n", -" List the slaves connected to a JID or LT Master.\n", -" gulm_tool slavelist <server>:lt000\n", -"\n", -#endif -"" -}; -void print_usage(void) -{ - int i; - for(i=0; usage[i][0]; i++) - printf("%s", usage[i]); - exit(0); -} - -#define cpl_core (0x1) -#define cpl_lt (0x4) -#define cpl_ltpx (0x8) -#define cpl_all (cpl_core|cpl_lt|cpl_ltpx) -/** - * check_ports - - * @req: - * @allows: - * - * - * Returns: int - */ -int check_ports(char *req, int allows) -{ - int port; - if( sscanf(req, "%u", &port) == 1 ) return TRUE; /* numbers are valid */ - if( (allows & cpl_core) && strncasecmp(req, "core", 4) == 0 ) return TRUE; - if( (allows & cpl_ltpx) && strncasecmp(req, "ltpx", 4) == 0 ) return TRUE; - if( (allows & cpl_lt) && strncasecmp(req, "lt", 2) == 0 ) return TRUE; - return FALSE; -} - -/** - * connect_to_server - - * @where: - * @sport: - * @enc: - * @dec: - * - * Returns: int - */ -int connect_to_server(char *where, char *sport, int allows, - xdr_enc_t **enc, xdr_dec_t **dec) -{ - char *n=NULL, *p=NULL; - struct sockaddr_in6 adr; - ip_name_t *in; - int sk; - - /* pull apart server:port */ - adr.sin6_family = AF_INET6; - adr.sin6_port = htons(40040); - n = strdup(where); - if( n == NULL ) die(ExitGulm_NoMemory, "Out Of Memory.\n"); - p = strstr(n, ":"); - if( p != NULL ) { - *p++ = '\0'; - }else if( p == NULL ) { - p = sport; - } - if( p != NULL ) { - if( !check_ports(p, allows) ) { - return -2; - } - if( strncasecmp(p, "core", 5) == 0) { - adr.sin6_port = htons(40040); - }else - if( strncasecmp(p, "ltpx", 5) == 0) { - adr.sin6_port = htons(40042); - }else - if( strncasecmp(p, "LT", 2) == 0) { - int offset = 0; - if( strlen(p) > 2 ) offset = atoi( p + 2 ); - adr.sin6_port = htons( 41040 + offset ); - }else - { - adr.sin6_port = htons(atoi(p)); - } - } - if( strlen(n) <= 0 ) { - die(ExitGulm_BadOption, "No server name given in "%s"\n", where); - } - if( (in=get_ipname(n)) == NULL ) { - die(ExitGulm_ParseFail, "Failed to lookup ip_name for "%s"\n", n); - } - if( in->name == NULL ){ - die(ExitGulm_ParseFail, "Failed to lookup name for "%s"\n", n); - } - if(IN6_IS_ADDR_UNSPECIFIED(in->ip.s6_addr32)) { - die(ExitGulm_ParseFail, "Failed to lookup ip for "%s"\n", n); - } - free(n); - memcpy(&adr.sin6_addr, &in->ip, sizeof(struct in6_addr)); - free(in); - - if((sk = socket(AF_INET6, SOCK_STREAM, 0)) <0) { - fprintf(stderr, "Failed to create socket: %s\n", strerror(errno)); - return -1; - } - if( connect(sk, (struct sockaddr*)&adr, sizeof(struct sockaddr_in6))<0) { - fprintf(stderr, "Failed to connect to %s (%s %d) %s\n", - where, ip6tostr(&adr.sin6_addr), ntohs(adr.sin6_port), - strerror(errno)); - return -1; - } - - *enc = xdr_enc_init(sk,0); - if( *enc == NULL ) { - die(ExitGulm_NoMemory, "Couldn't set up xdr encoder\n"); - } - *dec = xdr_dec_init(sk,0); - if( *dec == NULL ) { - die(ExitGulm_NoMemory, "Couldn't set up xdr decoder\n"); - } - - return sk; -} - -/** - * do_set_verb - - * @argc: - * @argv: - * - * - * Returns: int - */ -int do_set_verb(int argc, char **argv) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 4 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - - if((sk = connect_to_server(argv[2], NULL, cpl_all, &enc, &dec)) < 0 ) { - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - xdr_enc_uint32(enc, gulm_info_set_verbosity); - xdr_enc_string(enc, argv[3]); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * dump_mbr_list - - * @dec: - * - * - * Returns: int - */ -int dump_mbr_list(xdr_dec_t *dec) -{ - int err; - uint32_t x_code, x_int; - uint8_t *x_name, x_st; - uint64_t x_time; - struct in6_addr x_ip; - - if((err=xdr_dec_uint32(dec, &x_code)) != 0 ) return err; - if( x_code != gulm_core_mbr_lstrpl ) return -EINVAL; - if((err=xdr_dec_list_start(dec)) != 0 ) return err; - while( xdr_dec_list_stop(dec) != 0 ) { - if((err=xdr_dec_string(dec, &x_name)) != 0 ) return err; - printf(" Name: %s\n", x_name); - free(x_name); - - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) return err; - printf(" ip = %s\n", ip6tostr(&x_ip)); - if((err=xdr_dec_uint8(dec, &x_st)) != 0 ) return err; - printf(" state = %s\n", gio_mbrupdate_to_str(x_st)); - if((err=xdr_dec_uint8(dec, &x_st)) != 0 ) return err; - printf(" last state = %s\n", gio_mbrupdate_to_str(x_st)); - if((err=xdr_dec_uint8(dec, &x_st)) != 0 ) return err; - printf(" mode = %s\n", gio_I_am_to_str(x_st)); - if((err=xdr_dec_uint32(dec, &x_int)) != 0 ) return err; - printf(" missed beats = %d\n", x_int); - if((err=xdr_dec_uint64(dec, &x_time)) != 0 ) return err; - printf(" last beat = %"PRIu64"\n", x_time); - if((err=xdr_dec_uint64(dec, &x_time)) != 0 ) return err; - printf(" delay avg = %"PRIu64"\n", x_time); - if((err=xdr_dec_uint64(dec, &x_time)) != 0 ) return err; - printf(" max delay = %"PRIu64"\n", x_time); - - printf("\n"); - } - return 0; -} - -/** - * do_get_one_mbr - - * @name: - * @enc: - * @dec: - * - * - * Returns: int - */ -int do_get_one_mbr(int argc, char **argv) -{ - int sk, err; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 4 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk = connect_to_server(argv[2], "core", cpl_core, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "nodeinfo only works to core\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - xdr_enc_uint32(enc, gulm_core_mbr_req); - xdr_enc_string(enc, argv[3]); - xdr_enc_flush(enc); - - if( (err = dump_mbr_list(dec)) != 0 ) - die(ExitGulm_BadLogic, "Error %d while reading reply.\n", err); - - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return err; -} -/** - * do_get_mbr_list - - * @enc: - * @dec: - * - * - * Returns: int - */ -int do_get_mbr_list(int argc, char **argv) -{ - int sk, err; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk = connect_to_server(argv[2], "core", cpl_core, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "nodelist only works to core.\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - xdr_enc_uint32(enc, gulm_core_mbr_lstreq); - xdr_enc_flush(enc); - - if( (err = dump_mbr_list(dec)) != 0 ) - die(ExitGulm_BadLogic, "Error %d while reading reply.\n", err); - - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return err; -} - -/** - * do_shutdown_core - - * @argc: - * @argv: - * - * - * Returns: int - */ -int do_shutdown_core(int argc, char **argv) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - uint32_t code, error; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk = connect_to_server(argv[2], "core", cpl_core, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "shutdown only works to core\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - xdr_enc_uint32(enc, gulm_core_shutdown); - xdr_enc_flush(enc); - - /* get reply */ - xdr_dec_uint32(dec, &code); - xdr_dec_uint32(dec, &code); - xdr_dec_uint32(dec, &error); - - /* tell server we're done. */ - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - if( error != 0 ) { - printf("Cannot shutdown %s. Maybe try unmounting gfs?\n", argv[2]); - exit(1); - } - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * do_switchtopending - - * @argc: - * @argv: - * - * - * Returns: int - */ -int do_switchtopending(int argc, char **argv) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk = connect_to_server(argv[2], "core", cpl_core, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "switchPending only works to core\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - xdr_enc_uint32(enc, gulm_core_forcepend); - xdr_enc_flush(enc); - - /* tell server we're done. */ - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * do_force_node_state - - * @argc: - * @argv: - * - * gulm_tool forceExpire <server> <node> - * - * Returns: int - */ -int do_force_node_state(int argc, char **argv) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - uint32_t code, error; - - if( argc != 4 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk = connect_to_server(argv[2], "core", cpl_core, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "forceExpire only works to core\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - /* send force state req */ - xdr_enc_uint32(enc, gulm_core_mbr_force); - xdr_enc_string(enc, argv[3] ); - xdr_enc_flush(enc); - - /* get reply */ - xdr_dec_uint32(dec, &code); - xdr_dec_uint32(dec, &code); - xdr_dec_uint32(dec, &error); - - /* tell server we're done. */ - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - if( error != gio_Err_Ok ) - die(ExitGulm_BadLogic, "Got Error: %d:%s\n", error, gio_Err_to_str(error)); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * do_raw_stats - - * - * - * Returns: int - */ -int do_raw_stats(int argc, char **argv) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - uint32_t x_code = -1; - uint8_t *x_key = NULL, *x_value = NULL; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk=connect_to_server(argv[2], NULL, cpl_all, &enc, &dec)) < 0 ) - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - - if(xdr_enc_uint32(enc, gulm_info_stats_req) != 0) return -1; - if(xdr_enc_flush(enc) != 0) return -1; - - if(xdr_dec_uint32(dec, &x_code) != 0) return -1; - if(xdr_dec_list_start(dec) != 0) return -1; - - while( xdr_dec_list_stop(dec) != 0 ) { - if(xdr_dec_string(dec, &x_key) != 0) return -1; - if(xdr_dec_string(dec, &x_value) != 0) return -1; - - printf("%s = %s\n", x_key, x_value); - - free(x_key); x_key = NULL; - free(x_value); x_value = NULL; - } - - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * statsfilter_client - - * @len: - * @keys: - * @values: - * - * If I_am == Slave and rank == -1; change I_am to Client/ - * - * Returns: void - */ -void statsfilter_client(int *len, uint8_t **keys, uint8_t **values) -{ - int i, iamat=-1, fiddle=FALSE; - int mat=-1, qut=FALSE; - - for(i=0; i < *len; i++ ) { - if( strcmp("I_am", keys[i]) == 0 ) { - iamat = i; - }else - if( strcmp("rank", keys[i]) == 0 ) { - if( strcmp("-1", values[i]) == 0 ) fiddle = TRUE; - }else - if( strcmp("Master", keys[i]) == 0 ) { - mat = i; - }else - if( strcmp("quorate", keys[i]) == 0 ) { - if( strcmp("false", values[i]) == 0) qut = TRUE; - } - } - - if( fiddle && iamat > -1 ) { - free(values[iamat]); - values[iamat] = strdup("Client"); - } - if( qut && mat > -1 ) { - free(keys[mat]); - keys[mat] = strdup("Arbitrator"); - } -} - -/** - * plain_print - - * @len: - * @keys: - * @values: - * - */ -void plain_print(int len, uint8_t **keys, uint8_t **values) -{ - int i; - for(i=0; i < len; i++ ) { - printf("%s = %s\n", keys[i], values[i]); - } -} - -/** - * xml_print - - * @len: - * @keys: - * @values: - * - * - * Returns: void - */ -void xml_print(int len, uint8_t **keys, uint8_t **values) -{ - int i; - printf("<resource>\n"); - for(i=0; i < len; i++ ) { - printf(" <property name="%s">%s</property>\n", keys[i], values[i]); - } - printf("</resource>\n"); -} - -/** - * do_get_stats - - * - * Returns: int - */ -int do_get_keys(int argc, char **argv, uint32_t request, - void (*filter)(int *, uint8_t **, uint8_t **), - void (*print)(int, uint8_t **, uint8_t **)) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - uint32_t x_code = -1; - uint8_t **keys=NULL, **values=NULL; - int length=0, size=0, i; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk=connect_to_server(argv[2], NULL, cpl_all, &enc, &dec)) < 0 ) - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - - if(xdr_enc_uint32(enc, request) != 0) return -1; - if(xdr_enc_flush(enc) != 0) return -1; - - if(xdr_dec_uint32(dec, &x_code) != 0) return -1; - if(xdr_dec_list_start(dec) != 0) return -1; - - /* load status key/values */ - while( xdr_dec_list_stop(dec) != 0 ) { - - if( length >= size ) { - /* grow */ - uint8_t **A, **B; - A = realloc(keys, (size + 10) * sizeof(uint8_t*) ); - if( A == NULL ) die(ExitGulm_NoMemory, "Out Of Memory.\n"); - B = realloc(values, (size + 10) * sizeof(uint8_t*) ); - if( B == NULL ) die(ExitGulm_NoMemory, "Out Of Memory.\n"); - - keys = A; - values = B; - size += 10; - } - - if(xdr_dec_string(dec, &keys[length]) != 0) return -1; - if(xdr_dec_string(dec, &values[length]) != 0) return -1; - - length++; - - } - - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - - /* process them */ - if( filter != NULL ) filter(&length, keys, values); - - /* print */ - print(length, keys, values); - - /* free */ - for(i=0; i < length; i++ ) { - free(keys[i]); - free(values[i]); - } - free(keys); - free(values); - - return 0; -} - -/** - * do_service_list - - * @argc: - * @argv: - * - * - * Returns: int - */ -int do_service_list(int argc, char **argv) -{ - int sk; - uint32_t x_int; - uint8_t x_name[1024]=""; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk=connect_to_server(argv[2], "core", cpl_core, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "servicelist only works to core\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - if(xdr_enc_uint32(enc, gulm_core_res_req)!=0) return -1; - if(xdr_enc_flush(enc)!=0) return -1; - - if(xdr_dec_uint32(dec, &x_int)!=0) return -1; - if( x_int != gulm_core_res_list) - die(ExitGulm_BadLogic, "Got strange replay %#x\n", x_int); - - if(xdr_dec_list_start(dec)!=0) return -1; - while( xdr_dec_list_stop(dec) != 0 ) { - if(xdr_dec_string_nm(dec, x_name, 1024)!=0) return -1; - - printf("%s\n", x_name); - } - - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * do_slave_list - - * @argc: - * @argv: - * - * - * Returns: int - */ -int do_slave_list(int argc, char **argv) -{ - int sk; - uint32_t x_int; - uint8_t x_name[1024]=""; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk=connect_to_server(argv[2], "lt", cpl_lt, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "slavelist only works to LTs\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - if(xdr_enc_uint32(enc, gulm_info_slave_list_req)!=0) return -1; - if(xdr_enc_flush(enc)!=0) return -1; - - if(xdr_dec_uint32(dec, &x_int)!=0) return -1; - if( x_int != gulm_info_slave_list_rpl ) - die(ExitGulm_BadLogic, "Got strange replay %#x\n", x_int); - - if(xdr_dec_list_start(dec)!=0) return -1; - while( xdr_dec_list_stop(dec) != 0 ) { - if(xdr_dec_string_nm(dec, x_name, 1024)!=0) return -1; - if(xdr_dec_uint32(dec, &x_int)!=0) return -1; - - printf("poller:%d name:%s\n", x_int, x_name); - } - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * do_rerun_queues - - * @argc: - * @argv: - * - * - * Returns: int - */ -int do_rerun_queues(int argc, char **argv) -{ - int sk; - xdr_enc_t *enc=NULL; - xdr_dec_t *dec=NULL; - - if( argc != 3 ) die(ExitGulm_BadOption, "Wrong number of arguments.\n"); - if((sk=connect_to_server(argv[2], "lt000", cpl_lt, &enc, &dec)) < 0 ) { - if( sk == -2 ) fprintf(stderr, "rerunqueues onlyworks to LTs\n"); - die(ExitGulm_InitFailed, "Failed to connect to server\n"); - } - - if(xdr_enc_uint32(enc, gulm_lock_rerunqueues)!=0) return -1; - if(xdr_enc_flush(enc)!=0) return -1; - - xdr_enc_uint32(enc, gulm_socket_close); - xdr_enc_flush(enc); - - xdr_enc_release(enc); - xdr_dec_release(dec); - close(sk); - return 0; -} - -/** - * sigalrm - - * @sig: - */ -void sigalrm(int sig) { - fprintf(stderr, "Command timed out.\n"); - exit(142); -} - -/** - * main - - * @argc: - * @argv: - * - * - * Returns: int - */ -int main(int argc, char **argv) -{ - prog_name = argv[0]; - - if( argc < 2) die(ExitGulm_ParseFail, "Wrong number of arguments.\n"); - - signal(SIGALRM, sigalrm); - alarm(10); - - if( strncasecmp(argv[1], "getstats", 9) == 0 ) { - do_get_keys(argc, argv, gulm_info_stats_req, - statsfilter_client, plain_print); - }else - if( strncasecmp(argv[1], "xmlstats", 9) == 0 ) { - do_get_keys(argc, argv, gulm_info_stats_req, - statsfilter_client, xml_print); - }else - if( strncasecmp(argv[1], "rawstats", 9) == 0 ) { - do_raw_stats(argc, argv); - }else - if( strncasecmp(argv[1], "config", 7) == 0 ) { - do_get_keys(argc, argv, gulm_core_configreq, NULL, plain_print); - }else - if( strncasecmp(argv[1], "slavelist", 10) == 0 ) { - do_slave_list(argc, argv); - }else - if( strncasecmp(argv[1], "servicelist", 10) == 0 ) { - do_service_list(argc, argv); - }else - if( strncasecmp(argv[1], "rerunqueues", 12) == 0 ) { - do_rerun_queues(argc, argv); - }else - if( strncasecmp(argv[1], "shutdown", 9) == 0 ) { - do_shutdown_core(argc, argv); - }else - if( strncasecmp(argv[1], "switchPending", 14) == 0 ) { - do_switchtopending(argc, argv); - }else - if( strncasecmp(argv[1], "nodelist", 9) == 0 ) { - do_get_mbr_list(argc, argv); - }else - if( strncasecmp(argv[1], "nodeinfo", 9) == 0 ) { - do_get_one_mbr(argc, argv); - }else - if( strncasecmp(argv[1], "forceExpire", 12) == 0 ) { - do_force_node_state(argc, argv); - }else - if( strncasecmp(argv[1], "setverb", 8) == 0 ) { - do_set_verb(argc, argv); - }else - if( strncasecmp(argv[1], "version", 8) == 0 || - strncmp(argv[1], "-V", 3) == 0 ) { - printf("%s %s (built " __DATE__ " " __TIME__ ")\n" - "Copyright (C) 2004 Red Hat, Inc. All rights reserved.\n", - argv[0], RELEASE); - }else - if( strncmp(argv[1], "-h", 3) == 0 || - strncmp(argv[1], "--help", 7) == 0 || - strncmp(argv[1], "help", 5) == 0 ) { - print_usage(); - }else - { - fprintf(stderr, "Unknown command "%s"\nPlease use '-h' for usage.\n", - argv[1]); - } - - return 0; -} -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/hash.c b/gulm/src/hash.c deleted file mode 100644 index 641b951..0000000 --- a/gulm/src/hash.c +++ /dev/null @@ -1,369 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * Hash table abstraction - * takes any lengthed keys. - * - */ -#include <stdlib.h> /* for malloc */ -#include <string.h> /* for memcmp */ -#include <stdint.h> - -#include "hash.h" - -#undef MIN -#define MIN(a,b) ((a<b)?a:b) - -struct hash_root_s { - LLi_t *buckets; - unsigned int numbkt; - unsigned char *(*getkey)(void *item); - int (*getkeylen)(void *item); -}; - -/* --------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. -For every delta with one or two bits set, and the deltas of all three - high bits or all three low bits, whether the original value of a,b,c - is almost all zero or is uniformly distributed, -* If mix() is run forward or backward, at least 32 bits in a,b,c - have at least 1/4 probability of changing. -* If mix() is run forward, every bit of c will change between 1/3 and - 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) -mix() takes 36 machine instructions, but only 18 cycles on a superscalar - machine (like a Pentium or a Sparc). No faster mixer seems to work, - that's the result of my brute-force search. There were about 2^^68 - hashes to choose from. I only tested about a billion of those. --------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ -} - -/* --------------------------------------------------------------------- -hash() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - len : the length of the key, counting by bytes - initval : can be any 4-byte value -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Every 1-bit and 2-bit delta achieves avalanche. -About 6*len+35 instructions. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (ub1 **)k, do it like this: - for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h); - -By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this -code any way you wish, private, educational, or commercial. It's free. - -See http://burtleburtle.net/bob/hash/evahash.html -Use for hash table lookup, or anything where one collision in 2^^32 is -acceptable. Do NOT use for cryptographic purposes. --------------------------------------------------------------------- -*/ - -/* XXX this thing doesn't appear to maintain results across - * cpu/libc/kernels So must use a real crc for that. - */ -uint32_t bob_hash( k, length, initval) -register uint8_t *k; /* the key */ -register uint32_t length; /* the length of the key */ -register uint32_t initval; /* the previous hash, or an arbitrary value */ -{ - register uint32_t a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while (len >= 12) - { - a += (k[0]+((uint32_t)k[1]<<8)+((uint32_t)k[2]<<16)+((uint32_t)k[3]<<24)); - b += (k[4]+((uint32_t)k[5]<<8)+((uint32_t)k[6]<<16)+((uint32_t)k[7]<<24)); - c += (k[8]+((uint32_t)k[9]<<8)+((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24)); - mix(a,b,c); - k += 12; len -= 12; - } - - /*------------------------------------- handle the last 11 bytes */ - c += length; - switch(len) /* all the case statements fall through */ - { - case 11: c+=((uint32_t)k[10]<<24); - case 10: c+=((uint32_t)k[9]<<16); - case 9 : c+=((uint32_t)k[8]<<8); - /* the first byte of c is reserved for the length */ - case 8 : b+=((uint32_t)k[7]<<24); - case 7 : b+=((uint32_t)k[6]<<16); - case 6 : b+=((uint32_t)k[5]<<8); - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3]<<24); - case 3 : a+=((uint32_t)k[2]<<16); - case 2 : a+=((uint32_t)k[1]<<8); - case 1 : a+=k[0]; - /* case 0: nothing left to add */ - } - mix(a,b,c); - /*-------------------------------------------- report the result */ - return c; -} -/* public functions */ -#define hash_init_val 0x6d696b65 -uint32_t gen_hash_key(uint8_t *a, uint32_t b, uint32_t c) -{return bob_hash(a, b, c);} - -/** - * hash_create - create a new hash table - * @table_size: < number of buckets to have - * @(*getkey): < function that gets the key out of an item - * @(*getkeylen): < function that gets the length of the key from an item - * - * This is the only place that memory is created. Mostly it just fills in - * the structure. - * - * Returns: hash_t - */ -hash_t *hash_create(unsigned int table_size, - unsigned char *(*getkey)(void *item), - int (*getkeylen)(void *item)) -{ - hash_t *h; - int i; - if( getkey == NULL )return NULL; - if( getkeylen == NULL) return NULL; - - h = malloc(sizeof(hash_t)); - if( h == NULL ) return NULL; - h->buckets = malloc(table_size * sizeof(LLi_t)); - if( h->buckets == NULL ) { free(h); return NULL; } - h->numbkt = table_size; - h->getkey = getkey; - h->getkeylen = getkeylen; - - for(i=0; i< table_size; i++) { - LLi_init_head(&h->buckets[i]); - } - - return h; -} - -/** - * hash_destroy - free up the memory - * @hsh: <> the hash table to die - * - * WARN! this does NOT free the items in the hash table! - * - * Returns: void - */ -void hash_destroy(hash_t *hsh) -{ - if(hsh==NULL) return; - if(hsh->buckets) free(hsh->buckets); - free(hsh); -} - -/** - * hash_find - Finds an element in the hash table - * @hsh: < the hash table - * @key: < key to search for - * @klen: < length of key - * - * - * Returns: LLi_t - */ -LLi_t *hash_find(hash_t *hsh, unsigned char *key, unsigned int klen) -{ - unsigned int hash = 0; - LLi_t *tmp; - - if( hsh == NULL || key == NULL || klen <= 0 ) { - return NULL; - } - - hash = bob_hash(key, klen, hash_init_val); - hash %= hsh->numbkt; - - tmp = &hsh->buckets[hash]; - if( ! LLi_empty( tmp ) ) { - /* have to skip over head, else the end condition will trigger right - * away. - */ - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = LLi_next(tmp)) { - if( klen == hsh->getkeylen(LLi_data(tmp)) ) { - if( memcmp(key, hsh->getkey(LLi_data(tmp)), klen) == 0) { - /* Found a match! */ - return tmp; - } - } - } - } - return NULL; -} - -/** - * hash_add - - * @hsh: - * @item: - * - * - * Returns: int - */ -int hash_add(hash_t *hsh, LLi_t *item) -{ - uint8_t *key; - unsigned int klen, hash; - LLi_t *tmp; - - if( hsh == NULL || item == NULL ) return -5; - - key = hsh->getkey(LLi_data(item)); - klen = hsh->getkeylen(LLi_data(item)); - hash = bob_hash(key, klen, hash_init_val); - hash %= hsh->numbkt; - - tmp = &hsh->buckets[hash]; - - /* jic: */ - LLi_unhook(item); - - /* The idea here is that since we have things in sorted order, (and - * hopefully the right order.) you just start walking through, and you - * will either first find a match. Or find the place where you belong. - * - * I could toss this, and just say that if you're dumb enough to insert - * multiple keys that are equal, you deserve what you'll get. - * i duno.... - */ - if( LLi_empty(tmp) ) { /* nothing else there. just add it.*/ - LLi_add_after(tmp, item); - return 0; - } - for(tmp = LLi_next(tmp); tmp->data != NULL; tmp = tmp->next) { - uint8_t *tmp_key; - unsigned int tmp_klen; - tmp_key = hsh->getkey(LLi_data(tmp)); - tmp_klen = hsh->getkeylen(LLi_data(tmp)); - - if( klen == tmp_klen ) { - if( memcmp(key, tmp_key, klen) == 0) { - return -1; /* all ready there. */ - } - if( memcmp( key, tmp_key, klen) < 0) { - LLi_add_before( tmp, item); - return 0; - } - } - if( memcmp(key, tmp_key, MIN(klen,tmp_klen)) < 0) { - LLi_add_before( tmp, item); - return 0; - } - } - LLi_add_before( &hsh->buckets[hash], item);/*bigger than everyone in list*/ - return 0;/* always gets added. */ -} - -/** - * hash_del - - * @hsh: - * @key: - * @klen: - * - * - * Returns: LLi_t - */ -LLi_t *hash_del(hash_t *hsh, unsigned char *key, unsigned int klen) -{ - unsigned int hash = 0; - LLi_t *tmp; - - if( hsh == NULL || key == NULL || klen <= 0 ) { - return NULL; - } - - hash = bob_hash(key, klen, hash_init_val); - hash %= hsh->numbkt; - - tmp = &hsh->buckets[hash]; - if( ! LLi_empty( tmp ) ) { - /* have to skip over head, else the end condition will trigger right - * away. - */ - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = LLi_next(tmp)) { - if( klen == hsh->getkeylen(LLi_data(tmp)) ) { - if( memcmp(key, hsh->getkey(LLi_data(tmp)), klen) == 0) { - /* Found a match! */ - LLi_del(tmp); - return tmp; /* caller still needs to free memory!!! */ - } - } - } - } - return NULL; -} - - -/** - * hash_walk - iterrate over every item in hash - * @hsh: <> hash table - * @on_each: < function to call on each item - * @misc: < misc data that you want available in the above function - * - * If the on_each function returns non-zero, the itterration is stopped - * immeaditily, and this funtion returns with that value. - * - * Returns: int - */ -int hash_walk(hash_t *hsh, int (*on_each)(LLi_t *item, void *misc), void *misc) -{ - unsigned int i; - int ret=0; - LLi_t *tmp,*next; - - if( hsh == NULL || on_each == NULL ) return -1; - - for(i=0; i < hsh->numbkt; i++) { - tmp = &hsh->buckets[i]; -#if 0 - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = LLi_next(tmp)) { - if( (ret=on_each(tmp, misc)) != 0 ) return ret; - } -#endif -/* code above will core if the on_each function makes a LLi_del call on - * item. So now we use below. - */ - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = next) { - next = LLi_next(tmp); - if( (ret=on_each(tmp, misc)) != 0 ) return ret; - } - } - return 0; -} -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/hash.h b/gulm/src/hash.h deleted file mode 100644 index bf239b3..0000000 --- a/gulm/src/hash.h +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * Hash table abstraction - */ -#ifndef __hash_h__ -#define __hash_h__ - -#include "LLi.h" - -typedef struct hash_root_s hash_t; - -hash_t *hash_create(unsigned int table_size, - unsigned char *(*getkey)(void *item), - int (*getkeylen)(void *item)); -void hash_destroy(hash_t *hsh); -LLi_t *hash_find(hash_t *hsh, unsigned char *key, unsigned int klen); -LLi_t *hash_del(hash_t *hsh, unsigned char *key, unsigned int klen); -int hash_add(hash_t *hsh, LLi_t *item); -int hash_walk(hash_t *hsh, int (*on_each)(LLi_t *item, void *misc), - void *misc); - -#endif /*__hash_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/hashn.c b/gulm/src/hashn.c deleted file mode 100644 index fd4d34c..0000000 --- a/gulm/src/hashn.c +++ /dev/null @@ -1,248 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * Hash table abstraction - * Doesn't do per-item allocs, expects things to come in as LLis. - * This differs from old in that it does not relie on memory buffers as - * keys. This allows one to use multiple fields in a structure to be the - * `key' for comparing and storing. - * - */ -#include <stdlib.h> /* for malloc */ -#include <string.h> /* for memcmp */ -#include <stdint.h> - -#include "hashn.h" - -struct hashn_root_s { - LLi_t *buckets; - unsigned int numbkt; - - int (*cmp)(void *a, void *b); - int (*hash)(void *a); -}; - -/** - * hash_create - create a new hash table - * @table_size: < number of buckets to have - * @(*cmp): < - * @(*hash): < - * - * cmp is a compare function that returns -1, 0, 1 if a is less than, - * equal to, or greather than b. - * hash is a function that returns a low collision digest of what you think - * is important of an item. - * For both funtions, generally they only operate on a single key field in - * the structures you store in this map. (though it can be the whole - * thing, or multiple parts if you want.) - * - * This is the only place that memory is created. Mostly it just fills in - * the structure. - * - * Returns: hash_t - */ -hashn_t *hashn_create(unsigned int table_size, - int (*cmp)(void *a, void *b), - int (*hash)(void *a)) -{ - hashn_t *h; - int i; - if( cmp == NULL )return NULL; - if( hash == NULL) return NULL; - - h = malloc(sizeof(hashn_t)); - if( h == NULL ) return NULL; - h->buckets = malloc(table_size * sizeof(LLi_t)); - if( h->buckets == NULL ) { free(h); return NULL; } - h->numbkt = table_size; - h->cmp = cmp; - h->hash = hash; - - for(i=0; i< table_size; i++) { - LLi_init_head(&h->buckets[i]); - } - - return h; -} - -/** - * hash_destroy - free up the memory - * @hsh: <> the hash table to die - * - * WARN! this does NOT free the items in the hash table! - * - * Returns: void - */ -void hashn_destroy(hashn_t *hsh) -{ - if(hsh==NULL) return; - if(hsh->buckets) free(hsh->buckets); - free(hsh); -} - -/** - * hash_find - Finds an element in the hash table - * @hsh: < the hash table - * @item: < LLi whose data points to a struct containing what to look for - * - * The only fields needed in item->data are those that your cmp function - * uses. Returns a different LLi - * - * Returns: LLi_t - */ -LLi_t *hashn_find(hashn_t *hsh, LLi_t *item) -{ - unsigned int bkt = 0; - LLi_t *tmp; - - if( hsh == NULL || item == NULL ) { - return NULL; - } - - bkt = hsh->hash(LLi_data(item)); - bkt %= hsh->numbkt; - - tmp = &hsh->buckets[bkt]; - if( ! LLi_empty( tmp ) ) { - /* have to skip over head, else the end condition will trigger right - * away. - */ - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = LLi_next(tmp)) { - if( hsh->cmp( LLi_data(item), LLi_data(tmp) ) == 0 ) { - /* Found a match! */ - return tmp; - } - } - } - return NULL; -} - -/** - * hash_add - - * @hsh: - * @item: - * - * - * Returns: int - */ -int hashn_add(hashn_t *hsh, LLi_t *item) -{ - unsigned int bkt; - int ret; - LLi_t *tmp; - - if( hsh == NULL || item == NULL ) return -5; - - bkt = hsh->hash(LLi_data(item)); - bkt %= hsh->numbkt; - - tmp = &hsh->buckets[bkt]; - - /* jic: */ - LLi_unhook(item); - - /* The idea here is that since we have things in sorted order, (and - * hopefully the right order.) you just start walking through, and you - * will either first find a match. Or find the place where you belong. - * - * I could toss this, and just say that if you're dumb enough to insert - * multiple keys that are equal, you deserve what you'll get. - * i duno.... - */ - if( LLi_empty(tmp) ) { /* nothing else there. just add it.*/ - LLi_add_after(tmp, item); - return 0; - } - for(tmp = LLi_next(tmp); tmp->data != NULL; tmp = tmp->next) { - ret = hsh->cmp(LLi_data(item), LLi_data(tmp)); - if( ret == 0 ) { - /* already exists */ - return -1; - }else - if( ret < 0 ) { - LLi_add_before( tmp, item); - return 0; - } - } - LLi_add_before( &hsh->buckets[bkt], item);/*bigger than everyone in list*/ - return 0;/* always gets added. */ -} - -/** - * hash_del - - * @hsh: - * @key: - * @klen: - * - * - * Returns: LLi_t - */ -LLi_t *hashn_del(hashn_t *hsh, LLi_t *item) -{ - unsigned int hash = 0; - LLi_t *tmp; - - if( hsh == NULL || item == NULL ) { - return NULL; - } - - hash = hsh->hash(LLi_data(item)); - hash %= hsh->numbkt; - - tmp = &hsh->buckets[hash]; - if( ! LLi_empty( tmp ) ) { - /* have to skip over head, else the end condition will trigger right - * away. - */ - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = LLi_next(tmp)) { - if( hsh->cmp(LLi_data(item), LLi_data(tmp)) == 0) { - /* Found a match! */ - LLi_del(tmp); - LLi_unhook(tmp); - return tmp; /* caller still needs to free memory!!! */ - } - } - } - return NULL; -} - - -/** - * hash_walk - iterrate over every item in hash - * @hsh: <> hash table - * @on_each: < function to call on each item - * @misc: < misc data that you want available in the above function - * - * If the on_each function returns non-zero, the itterration is stopped - * immeaditily, and this funtion returns with that value. - * - * Returns: int - */ -int hashn_walk(hashn_t *hsh, int (*on_each)(LLi_t *item, void *misc), void *misc) -{ - unsigned int i; - int ret=0; - LLi_t *tmp,*next; - - if( hsh == NULL || on_each == NULL ) return -1; - - for(i=0; i < hsh->numbkt; i++) { - tmp = &hsh->buckets[i]; - for(tmp = LLi_next(tmp); LLi_data(tmp) != NULL; tmp = next) { - next = LLi_next(tmp); - if( (ret=on_each(tmp, misc)) != 0 ) return ret; - } - } - return 0; -} -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/hashn.h b/gulm/src/hashn.h deleted file mode 100644 index 6b12777..0000000 --- a/gulm/src/hashn.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/****************************************************************************** - * Hash table abstraction - */ -#ifndef __hash_h__ -#define __hash_h__ - -#include "LLi.h" - -typedef struct hashn_root_s hashn_t; - -hashn_t *hashn_create(unsigned int table_size, - int (*cmp)(void *a, void *b), - int (*hash)(void *a)); -void hashn_destroy(hashn_t *hsh); -LLi_t *hashn_find(hashn_t *hsh, LLi_t *item); -int hashn_add(hashn_t *hsh, LLi_t *item); -LLi_t *hashn_del(hashn_t *hsh, LLi_t *item); -int hashn_walk(hashn_t *hsh, int (*on_each)(LLi_t *item, void *misc), void *misc); - -#endif /*__hash_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/lock.h b/gulm/src/lock.h deleted file mode 100644 index e24b8a5..0000000 --- a/gulm/src/lock.h +++ /dev/null @@ -1,17 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_lock_h__ -#define __gulm_lock_h__ -int lt_main(int argc, char **argv); -#endif /*__gulm_lock_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/lock_io.c b/gulm/src/lock_io.c deleted file mode 100644 index fa08a4b..0000000 --- a/gulm/src/lock_io.c +++ /dev/null @@ -1,2541 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "myio.h" -#include "LLi.h" -#include "Qu.h" -#include "hash.h" -#include "gio_wiretypes.h" -#include "xdr.h" -#include "config_gulm.h" -#include "lock_priv.h" -#include "nodel.h" -#include "utils_ip.h" -#include "utils_tostr.h" -#include "utils_verb_flags.h" - - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -extern struct in6_addr myIP; -extern char myName[]; - -/* confed things. */ -extern gulm_config_t gulm_config; -extern char *LTname; -extern int LTid; - -static int running = TRUE; -static struct timeval Started_at; -static struct timeval NOW; -static ip_name_t MasterIN = {{NULL,NULL,NULL},IN6ADDR_ANY_INIT,NULL}; -static int I_am_the = gio_Mbr_ama_Pending; -static hash_t *nodelists=NULL; -/* this is true after we send a login request to the master, and are - * waiting for the login reply from the master. - * it is so that we don't send multiple login requests without receiving a - * login reply first. - */ -static int logging_into_master = FALSE; -static int PartialLockspace = FALSE; - -/*****************************************************************************/ -#ifdef DEBUG_LVB -#define lvb_log_msg(fmt, args...) log_msg(lgm_Always , fmt , ## args ) -#else /*DEBUG_LVB*/ -#define lvb_log_msg(fmt, args...) -#endif /*DEBUG_LVB*/ -char __inline__ *lvbtohex(uint8_t *lvb, uint8_t lvblen); -/*****************************************************************************/ - - -/*****************************************************************************/ -/* Track which slaves are hooked to us - * - * There CANNOT be more than four slaves. Ever. There are bitmasks that - * map to this list, and they are only one byte big. - * - * I am so silly sometimes. a byte has eight bits, not four. - * - * Also, note that once entered, and name is never removed. Should not be - * an issue, since the servers list in the config cannot change either. - * - * but someday we do want to have that list change, which means this will - * need to as well. must think on this. - */ -typedef struct { - int live; /* are they logged into us right now? */ - int idx; /* the poller index */ - char *name; -}slst_t; -static slst_t Slaves[4]; -static int Slave_count = 0; -static uint8_t Slave_bitmask = 0; - -/* Drop requests to nodes that don't currently have a socket need to be - * saved until they reconenct. - */ -static LLi_Static_head_init(DropRequestPlaybackQueue); -unsigned long cnt_drpq = 0; - -/** - * init_lt_slave_list - - */ -void init_lt_slave_list(void) -{ - int i; - for(i=0;i<4;i++) { - Slaves[i].live = FALSE; - Slaves[i].name = NULL; - Slaves[i].idx = -1; - } -} - -/** - * add_to_slavelist - - * @fd: - * - * - * Returns: int - */ -static int add_to_slavelist(int idx, char *name) -{ - int i, empty=-1, found=FALSE; - - if( Slave_count == 4 ) return -EINVAL; - - for(i=0;i<4;i++) { - if( Slaves[i].name == NULL ) { - empty = i; - }else - if( strcmp(Slaves[i].name, name ) == 0 ) { - Slaves[i].live = TRUE; - Slaves[i].idx = idx; - Slave_bitmask |= 1 << (i & 0x7 ); - found = TRUE; - log_msg(lgm_Network2, "Added Slave %s to list at %d.\n", - Slaves[i].name, i); - Slave_count ++; - return 0; - } - } - if( ! found ) { - if( empty == -1 ) return -EINVAL; - Slaves[empty].name = strdup(name); - if( Slaves[empty].name == NULL ) return -ENOMEM; - Slaves[empty].live = TRUE; - Slaves[empty].idx = idx; - Slave_bitmask |= 1 << (empty & 0x7 ); - log_msg(lgm_Network2, "Added Slave %s to list at %d.\n", - Slaves[empty].name, empty); - Slave_count ++; - } - return 0; -} - -/** - * remove_slave_from_list - - * @idx: - * - */ -static void remove_slave_from_list(int idx) -{ - int i; - - for(i=0; i < 4; i++ ) { - if( Slaves[i].idx == idx ) { - log_msg(lgm_Network2, "Removed Slave %s from %d in list.\n", - Slaves[i].name, i); - Slaves[i].live = FALSE; - Slaves[i].idx = -1; - Slave_bitmask &= ~( 1 << (i & 0x7) ); - Slave_count --; - } - } -} - -/** - * remove_slave_from_list_by_name - - * @name: - */ -static void remove_slave_from_list_by_name(char *name) -{ - int i; - for(i =0; i < 4; i++ ) { - if( Slaves[i].name != NULL && - strcmp(Slaves[i].name, name) == 0 ) { - log_msg(lgm_Network2, "Removed Slave %s from %d in list.\n", - Slaves[i].name, i); - Slaves[i].live = FALSE; - Slaves[i].idx = -1; - Slave_bitmask &= ~( 1 << (i & 0x7) ); - Slave_count --; - } - } -} - -/** - * get_slave_idx - - * @name: - * - * - * Returns: int - */ -static int get_slave_idx(char *name) -{ - int i; - for(i=0;i<4;i++) { - if( Slaves[i].name != NULL && - strcmp(Slaves[i].name, name) == 0 ) { - return Slaves[i].idx; - } - } - return -1; -} - -static int get_slave_offset(int idx) -{ - int i; - for(i=0;i<4;i++) { - if( Slaves[i].idx == idx ) { - return i; - } - } - return -1; -} - -/** - * dump_slave_list - - * @enc: - * - * - * Returns: int - */ -static int dump_slave_list(xdr_enc_t *enc) -{ - int err, i; - if((err=xdr_enc_list_start(enc))!=0) return err; - for(i=0;i<4;i++) { - if( Slaves[i].name != NULL && Slaves[i].live ) { - if((err=xdr_enc_string(enc, Slaves[i].name))!=0) return err; - if((err=xdr_enc_uint32(enc, Slaves[i].idx))!=0) return err; - } - } - if((err=xdr_enc_list_stop(enc))!=0) return err; - return xdr_enc_flush(enc); -} - -/*****************************************************************************/ - -typedef enum {poll_Closed, poll_Accepting, poll_Trying, poll_Open} poll_state; -typedef enum {poll_Nothing, poll_Internal, poll_Slave, poll_Client} poll_type; -struct { - struct pollfd *polls; - xdr_enc_t **enc; - xdr_dec_t **dec; - poll_state *state; - poll_type *type; - uint64_t *times; - ip_name_t *ipn; - - Qu_t *outq; - uint32_t *outqlen; - - unsigned int maxi; - int coreIDX; /* link to core updates. */ - int listenFD; /* socket for new connections. */ - int MasterIDX; /* If we're a slave, where the Master is. */ -} poller; -unsigned long totaloutqlen = 0; - -int init_lt_poller(void) -{ - int i; - - memset(&poller, 0, sizeof(poller)); - - poller.polls = malloc(open_max() * sizeof(struct pollfd)); - if( poller.polls == NULL ) goto nomem; - memset(poller.polls, 0, (open_max() * sizeof(struct pollfd))); - - poller.state = malloc(open_max() * sizeof(poll_state)); - if( poller.state == NULL ) goto nomem; - - poller.type = malloc(open_max() * sizeof(poll_type)); - if( poller.type == NULL ) goto nomem; - - poller.times = malloc(open_max() * sizeof(uint64_t)); - if( poller.times == NULL ) goto nomem; - - poller.ipn = malloc(open_max() * sizeof(ip_name_t)); - if( poller.ipn == NULL ) goto nomem; - - poller.enc = malloc(open_max() * sizeof(xdr_enc_t*)); - if( poller.enc == NULL ) goto nomem; - - poller.dec = malloc(open_max() * sizeof(xdr_dec_t*)); - if( poller.dec == NULL ) goto nomem; - - poller.outq = malloc(open_max() * sizeof(Qu_t)); - if( poller.outq == NULL ) goto nomem; - - poller.outqlen = malloc(open_max() * sizeof(uint32_t)); - if( poller.outqlen == NULL ) goto nomem; - - for(i=0; i < open_max(); i++) { - poller.polls[i].fd = -1; - poller.state[i] = poll_Closed; - poller.type[i] = poll_Nothing; - poller.times[i] = 0; - memset(&poller.ipn[i].ip, 0, sizeof(struct in6_addr)); - poller.ipn[i].name = NULL; - poller.enc[i] = NULL; - poller.dec[i] = NULL; - Qu_init_head( &poller.outq[i] ); - poller.outqlen[i] = 0; - } - - poller.maxi = 0; - poller.coreIDX = -1; - poller.listenFD = -1; - poller.MasterIDX = -1; - - return 0; -nomem: - if(poller.polls) free(poller.polls); - if(poller.state) free(poller.state); - if(poller.type) free(poller.type); - if(poller.times) free(poller.times); - if(poller.ipn) free(poller.ipn); - if(poller.enc) free(poller.enc); - if(poller.dec) free(poller.dec); - if(poller.outq) free(poller.outq); - if(poller.outqlen) free(poller.outqlen); - return -ENOMEM; -} - -void release_lt_poller(void) -{ - if(poller.polls) free(poller.polls); - if(poller.state) free(poller.state); - if(poller.type) free(poller.type); - if(poller.times) free(poller.times); - if(poller.ipn) free(poller.ipn); - if(poller.enc) free(poller.enc); - if(poller.dec) free(poller.dec); - if(poller.outq) free(poller.outq); - if(poller.outqlen) free(poller.outqlen); -} - -static int add_to_pollers(int fd, poll_state p, uint64_t t, - const char *name, const struct in6_addr *ip) -{ - int i; - for(i=0; poller.polls[i].fd >=0 && i< open_max(); i++); - if( i>= open_max() ) return -1; - - if(fcntl(fd, F_SETFD, FD_CLOEXEC ) <0) return -1; /* close on exec. */ - - poller.polls[i].fd = fd; - poller.polls[i].events = POLLIN; - if(i> poller.maxi) poller.maxi = i; - poller.state[i] = p; - poller.times[i] = t; - memcpy(&poller.ipn[i].ip, ip, sizeof(struct in6_addr)); - if( name != NULL ) poller.ipn[i].name = strdup(name); - else poller.ipn[i].name = NULL; - poller.enc[i] = NULL; - poller.dec[i] = NULL; - /* you need to do the xdr seperate. */ - - return i; -} - -static int add_xdr_to_poller(int idx) -{ - if( idx < 0 ) return idx; - poller.enc[idx] = xdr_enc_init( poller.polls[idx].fd, 396); - if( poller.enc[idx] == NULL ) return -ENOMEM; - poller.dec[idx] = xdr_dec_init( poller.polls[idx].fd, 396); - if( poller.dec[idx] == NULL ) { - xdr_enc_release(poller.enc[idx]); - poller.enc[idx] = NULL; - return -ENOMEM; - } - return 0; -} - -/** - * close_by_idx - - * @idx: - * - * - */ -static void __inline__ close_by_idx(int idx) -{ - if( idx < 0 || idx > open_max() ) return; - log_msg(lgm_Network2, "Closing connection idx:%d, fd:%d to %s\n", - idx, poller.polls[idx].fd, poller.ipn[idx].name); - /* If we just closed the connect to the Master, set things up to try to - * re-find it. - * gotta do this before I wipe all the info out. - */ - if( poller.MasterIDX != -1 && idx == poller.MasterIDX ) { - poller.MasterIDX = -1; - log_msg(lgm_Network2, "Connection to Master closed.\n"); - } - - if( poller.coreIDX == idx ) - die(ExitGulm_Assertion, "Lost connection to core, cannot continue." - "node reset required to re-activate cluster operations.\n"); - - GULMD_ASSERT( poller.polls[idx].fd != poller.listenFD , ); - - /* if a slave connect, free that too. */ - if( poller.type[idx] == poll_Slave ) { - remove_slave_from_list(idx); - recheck_reply_waiters(Slave_bitmask, 0); - } - - close( poller.polls[idx].fd ); - poller.polls[idx].fd = -1; - poller.polls[idx].revents = 0; /* clear any other events. */ - poller.state[idx] = poll_Closed; - poller.type[idx] = poll_Nothing; - poller.times[idx] = 0; - memset(&poller.ipn[idx].ip, 0, sizeof(struct in6_addr)); - if( poller.ipn[idx].name != NULL ) { - free(poller.ipn[idx].name); - poller.ipn[idx].name = NULL; - } - if( poller.enc[idx] != NULL ) { - xdr_enc_release(poller.enc[idx]); - poller.enc[idx] = NULL; - } - if( poller.dec[idx] != NULL ) { - xdr_dec_release(poller.dec[idx]); - poller.dec[idx] = NULL; - } - delete_entire_waiters_list( &poller.outq[idx] ); - totaloutqlen -= poller.outqlen[idx]; - poller.outqlen[idx] = 0; - -} - -/** - * close_all_named - - * @name: - * - */ -static void close_all_named(char *name) -{ - int i; - log_msg(lgm_Network2, "Closing all named: %s\n", name); - for(i=0; i < open_max(); i++) { - if( poller.ipn[i].name != NULL && - strcmp(name, poller.ipn[i].name) == 0 ) { - close_by_idx(i); - } - } -} - -/** - * close_all_clients - - */ -static void close_all_clients(void) -{ - int i; - log_msg(lgm_Network2, "Closing all Clients\n"); - for(i=0; i < open_max(); i++) { - if( poller.type[i] == poll_Client ) { - close_by_idx(i); - } - } -} - -/** - * open_lt_listener - - * @port: - * - * - * Returns: int - */ -int open_lt_listener(int port) -{ - int idx; - poller.listenFD = serv_listen(port); - if( poller.listenFD < 0 ) return -1; - idx = add_to_pollers(poller.listenFD, poll_Open, 0, " _accepter_ ", - &in6addr_any); - poller.type[idx] = poll_Internal; - /* no xdr on the listener socket. */ - return 0; -} - -/** - * open_lt_to_core - - * @oid: - * - * - * Returns: int - */ -int open_lt_to_core(void) -{ - struct sockaddr_in6 adr; - int cfd, err, idx; - uint64_t x_gen; - uint32_t x_code, x_error, x_rank; - uint8_t x_ama; - int connection_attempts = 0; - - if((cfd = socket(AF_INET6, SOCK_STREAM, 0)) <0) { - log_err("Failed to create socket. %d:%s\n", errno, strerror(errno)); - return -1; - } - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - adr.sin6_addr = in6addr_loopback; - adr.sin6_port = htons(gulm_config.corePort); - - while ( connect(cfd, (struct sockaddr*)&adr, sizeof(struct sockaddr_in6))<0) { - close(cfd); - - connection_attempts++; - if (connection_attempts > 3) { - log_err("Failed to connect to core, shutting down lock_gulmd_LT."); - return -1; - } - if (connection_attempts > 1) - log_err("Failed to connect to core. %d:%s\n", errno, strerror(errno)); - - sleep(5); - - } - - idx = add_to_pollers(cfd, poll_Open, 0, "_ core _", &in6addr_loopback); - if( idx < 0 ) { - log_err("Failed to find unsed poller space.\n"); - close_by_idx(idx); - return -1; - } - if( add_xdr_to_poller(idx) < 0 ) { - log_err("Failed to allocate momeory for xdr.\n"); - close_by_idx(idx); - return -1; - } - - - do{ - if((err = xdr_enc_uint32(poller.enc[idx], gulm_core_reslgn_req))<0) break; - if((err = xdr_enc_uint32(poller.enc[idx], GIO_WIREPROT_VERS))<0) break; - if((err = xdr_enc_string(poller.enc[idx], gulm_config.clusterID))<0) - break; - if((err = xdr_enc_string(poller.enc[idx], LTname))<0) break; - if((err = xdr_enc_uint32(poller.enc[idx], gulm_svc_opt_important)) <0) - break; - if((err = xdr_enc_flush(poller.enc[idx]))<0) break; - }while(0); - if(err != 0 ) { - log_err("Failed to send login request to core. %d:%d:%s\n", err, errno, - strerror(errno)); - close_by_idx(idx); - return -1; - } - - /* poll loop is not yet active, so we do the read right here. */ - - do{ - if((err = xdr_dec_uint32(poller.dec[idx], &x_code))<0) break; - if((err = xdr_dec_uint64(poller.dec[idx], &x_gen))<0) break; - if((err = xdr_dec_uint32(poller.dec[idx], &x_error))<0) break; - if((err = xdr_dec_uint32(poller.dec[idx], &x_rank))<0) break; - if((err = xdr_dec_uint8(poller.dec[idx], &x_ama))<0) break; - }while(0); - if( err != 0 ) { - log_err("Failed to receive login reply. %d:%d:%s\n", err, errno, - strerror(errno)); - close_by_idx(idx); - return -1; - } - - if( x_code != gulm_core_login_rpl ) { - log_err("Did not get the expected packet in return. got %#x\n", x_code); - close_by_idx(idx); - return -1; - } - if( x_error != gio_Err_Ok ) { - log_err("Core returned error %d:%s.\n", x_error, gio_Err_to_str(x_error)); - close_by_idx(idx); - return -1; - } - - poller.coreIDX = idx; - /* yeah! we're hooked up. */ - return 0; -} - -/** - * find_and_cache_idx_for_holder - - * @h: <> Holder_t of client we want the poller idx for. - * - * Bit of a tricky stunt. Uses a spot in the Holders_t to cache the last - * idx that this holder had. Since in most cases this won't change, but - * since we do try to keep the state of a client and the state of a TCP/IP - * socket seperate, there is not a garuntee that this will not change. The - * only sane thing we have is the client's name. And doing a flat loop - * ssearch for the name *every* time a drop lock request is made (which is - * nearly every lock op with multiple clients) is unacceptable. So we - * search once and cache it. - * - * Returns: poller idx - */ -int find_and_cache_idx_for_holder(Holders_t *h) -{ - int i; - - GULMD_ASSERT( h != NULL, ); - if( h->idx < 0 || h->idx > open_max() ) h->idx = 0; - if( poller.type[h->idx] == poll_Client && - poller.ipn[h->idx].name != NULL && - strcmp(h->name, poller.ipn[h->idx].name) == 0 ) { - /* valid cached idx. */ - return h->idx; - }else{ - for(i=0; i < open_max(); i++) { - if( poller.type[i] == poll_Client && - poller.ipn[i].name != NULL && - strcmp(h->name, poller.ipn[i].name) == 0) { - return ( h->idx = i ); - } - } - } - return -1; -} - -/** - * find_idx_for_name - - * @name: - * - * Only finds Clients. - * - * Returns: int - */ -int find_idx_for_name(char *name) -{ - int i; - - for(i=0; i < open_max(); i ++ ) { - if( poller.type[i] != poll_Client ) continue; - if( poller.ipn[i].name != NULL && - strcmp(name, poller.ipn[i].name) == 0 ) { - if( i == get_slave_idx(name) ) continue; - return i; - } - } - return -1; -} - -/*****************************************************************************/ - -/* random floating prototype...*/ -char *lkeytob64(uint8_t *key, uint8_t keylen); - -/** - * queue_lkrq_for_sending - - * @idx: - * @lkrq: - * - * - * Returns: void - */ -void queue_lkrq_for_sending(int idx, Waiters_t *lkrq) -{ - /* really need these two? */ - LLi_del(&lkrq->wt_list); - LLi_unhook(&lkrq->wt_list); - - Qu_EnQu(&poller.outq[idx], &lkrq->wt_list); - poller.outqlen[idx] ++; - totaloutqlen ++; - poller.polls[idx].events |= POLLOUT; -} - -/** - * _send_req_update_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_req_update_(int idx, Waiters_t *lkrq) -{ - int e; - xdr_enc_t *enc = poller.enc[idx]; - do { - if((e=xdr_enc_uint32(enc, gulm_lock_state_updt)) != 0) break; - if((e=xdr_enc_string(enc, lkrq->name)) != 0) break; - if((e=xdr_enc_uint64(enc, lkrq->subid)) != 0 ) break; - if((e=xdr_enc_uint64(enc, lkrq->start)) != 0 ) break; - if((e=xdr_enc_uint64(enc, lkrq->stop)) != 0 ) break; - if((e=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0) break; - if((e=xdr_enc_uint8(enc, lkrq->state)) != 0) break; - if((e=xdr_enc_uint32(enc, lkrq->flags)) != 0) break; - if( lkrq->flags & gio_lck_fg_hasLVB ) { - if((e=xdr_enc_raw(enc, lkrq->LVB, lkrq->LVBlen)) != 0) break; - } - if((e=xdr_enc_flush(enc)) != 0) break; - }while(0); - - return e; -} - -/** - * send_update_to_slaves - - * @req: - * - */ -void send_req_update_to_slaves(Waiters_t *lkrq) -{ - int i; - Waiters_t *new; - - for(i=0;i<4;i++) { - if( ! Slaves[i].live ) continue; - - new = duplicate_lkrw(lkrq); - new->op = gulm_lock_state_updt; - queue_lkrq_for_sending(Slaves[i].idx, new); - - /* remember who we sent it to */ - lkrq->Slave_sent |= 1 << (i & 0x7 ); - } -} - -/** - * _send_act_update_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_act_update_(int idx, Waiters_t *lkrq) -{ - int e; - xdr_enc_t *enc = poller.enc[idx]; - - do { - if((e=xdr_enc_uint32(enc, gulm_lock_action_updt)) != 0) break; - if((e=xdr_enc_string(enc, lkrq->name)) != 0) break; - if((e=xdr_enc_uint64(enc, lkrq->subid)) != 0 ) break; - if((e=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0) break; - if((e=xdr_enc_uint8(enc, lkrq->state)) != 0) break; - if( lkrq->state == gio_lck_st_SyncLVB ) { - if((e=xdr_enc_raw(enc, lkrq->LVB, lkrq->LVBlen)) != 0) break; - } - if((e=xdr_enc_flush(enc)) != 0) break; - }while(0); - return e; -} - -/** - * send_act_update_to_slaves - - * @lkrq: - * - * - * Returns: void - */ -void send_act_update_to_slaves(Waiters_t *lkrq) -{ - int i; - Waiters_t *new; - - for(i=0;i<4;i++) { - if( ! Slaves[i].live ) continue; - log_msg(lgm_LockUpdates, "Gonna send lock action update to %s " - "about %s act:%#x\n", - poller.ipn[Slaves[i].idx].name, - lkeytob64(lkrq->key, lkrq->keylen), lkrq->state); - - new = duplicate_lkrw(lkrq); - new->op = gulm_lock_action_updt; - queue_lkrq_for_sending(Slaves[i].idx, new); - - /* remember who we sent it to */ - lkrq->Slave_sent |= 1 << (i & 0x7 ); - } -} - - -/** - * _send_update_reply_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_update_reply_(int idx, Waiters_t *lkrq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if( (err=xdr_enc_uint32(enc, gulm_lock_update_rpl)) != 0 ) break; - if( (err=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0 ) break; - if( (err=xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -/** - * send_update_reply_to_master - - * @lkrq: - * - * - * Returns: int - */ -void send_update_reply_to_master(Waiters_t *lkrq) -{ - Waiters_t *new; - - GULMD_ASSERT( poller.MasterIDX != -1 , ); - - log_msg(lgm_LockUpdates, "Gonna send update reply to Master %s " - "about %s\n", - poller.ipn[poller.MasterIDX].name, - lkeytob64(lkrq->key, lkrq->keylen)); - - new = duplicate_lkrw(lkrq); - new->op = gulm_lock_update_rpl; - queue_lkrq_for_sending(poller.MasterIDX, new); -} - -/** - * _send_drop_exp_to_slave_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_drop_exp_to_slave_(int idx, Waiters_t *lkrq) -{ - int e; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((e=xdr_enc_uint32(enc, gulm_lock_drop_exp)) != 0 ) break; - if((e=xdr_enc_string(enc, lkrq->name)) != 0 ) break; - if((e=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0 ) break; - if((e=xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return e; -} - -/** - * send_drop_exp_to_slaves - - * @name: - * - * FIXME Handle NULLs!!!! - * - * Returns: void - */ -static void send_drop_exp_to_slaves(char *name, uint8_t *mask, uint16_t len) -{ - int i; - Waiters_t *lkrq; - - for(i=0;i<4;i++) { - if( ! Slaves[i].live ) continue; - - lkrq = get_new_lkrq(); - GULMD_ASSERT( lkrq != NULL, ); - lkrq->op = gulm_lock_drop_exp; - if( name != NULL ) { - lkrq->name = strdup(name); - GULMD_ASSERT(lkrq->name != NULL , ); - } - else lkrq->name = NULL; - - if( mask != NULL ) { - lkrq->key = malloc(len); - GULMD_ASSERT(lkrq->key != NULL , ); - memcpy(lkrq->key, mask, len); - lkrq->keylen = len; - } else { - lkrq->key = NULL; - lkrq->keylen = 0; - } - - queue_lkrq_for_sending(Slaves[i].idx, lkrq); - - } -} - -/** - * _send_expire_to_slave_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_expire_to_slave_(int idx, Waiters_t *lkrq) -{ - int e; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((e=xdr_enc_uint32(enc, gulm_lock_expire)) != 0 ) break; - if((e=xdr_enc_string(enc, lkrq->name)) != 0 ) break; - if((e=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0 ) break; - if((e=xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return e; -} - -/** - * send_expire_to_slaves - - * @name: - * @mask: - * @len: - * - * - * Returns: void - */ -static void send_expire_to_slaves(char *name, uint8_t *mask, uint16_t len) -{ - int i; - Waiters_t *lkrq; - - for(i=0;i<4;i++) { - if( ! Slaves[i].live ) continue; - - lkrq = get_new_lkrq(); - GULMD_ASSERT( lkrq != NULL, ); - lkrq->op = gulm_lock_drop_exp; - lkrq->name = strdup(name); - GULMD_ASSERT(lkrq->name != NULL , ); - - if( mask != NULL ) { - lkrq->key = malloc(len); - GULMD_ASSERT(lkrq->key != NULL , ); - memcpy(lkrq->key, mask, len); - lkrq->keylen = len; - } else { - lkrq->key = NULL; - lkrq->keylen = 0; - } - - queue_lkrq_for_sending(Slaves[i].idx, lkrq); - - } -} - -/** - * _send_lk_act_reply_ - - * @idx: - * @lkrq: - * - * - * Returns: void - */ -static int _send_lk_act_reply_(int idx, Waiters_t *lkrq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err=xdr_enc_uint32(enc, gulm_lock_action_rpl)) != 0 ) break; - if((err=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->subid)) != 0 ) break; - if((err=xdr_enc_uint8(enc, lkrq->state)) != 0 ) break; - if((err=xdr_enc_uint32(enc, lkrq->ret)) != 0 ) break; - if((err=xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -/** - * send_act_lk_reply - - * @lkrq: - * @lk: - * @retcode: - * - * sends a reply to the proper client. Also determines if they need the - * LVB attached. - * - * XXX - * I think I'm losing the lkrq if there are errors. - * - * Returns: int - */ -int send_act_lk_reply(Waiters_t *lkrq, uint32_t retcode) -{ - /* - * Look up the idx in the pollers, and compair names to make sure this - * is the correct one. Then use that encoder. - * If not the correct one, scan the pollers for the correct one. - * If we don't find the correct one, then what? - */ - if( lkrq->idx < 0 || lkrq->idx > open_max() ) lkrq->idx = 0; - /* the strcmp slows things down a tiny bit. - * wonder if there is another way. - */ - if( poller.type[lkrq->idx] != poll_Client || - poller.ipn[lkrq->idx].name == NULL || - strcmp( lkrq->name, poller.ipn[lkrq->idx].name) != 0 ) { - if( (lkrq->idx = find_idx_for_name(lkrq->name)) < 0 ) { - log_err("No encoder for "%s"! lock:%s", - lkrq->name, lkeytob64(lkrq->key, lkrq->keylen)); - /* i *am* losing the replies here. FIXME - * shit. - * - * So I need to queue this somehow. - * - * bleh. Outgoing queue on each lock? icky. - * Normally, there will never be anything on this queue for any - * real length of time. So, I could have a single process wide - * outgoing queue. - * - * Work it like the dropreq queue, when the node gets logged in, - * flush. - * - * Umm, will that break ordering? - * - * Uh, where have I seen this when there have not been other - * errors? - */ - return -1; - } - } - - lkrq->ret = retcode; - lkrq->op = gulm_lock_action_rpl; - queue_lkrq_for_sending(lkrq->idx, lkrq); - - return 0; -} - -/** - * _send_lk_req_reply_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_lk_req_reply_(int idx, Waiters_t *lkrq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err=xdr_enc_uint32(enc, gulm_lock_state_rpl)) != 0 ) break; - if((err=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->subid)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->start)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->stop)) != 0 ) break; - if((err=xdr_enc_uint8(enc, lkrq->state)) != 0 ) break; - if((err=xdr_enc_uint32(enc, lkrq->flags)) != 0 ) break; - if((err=xdr_enc_uint32(enc, lkrq->ret)) != 0 ) break; - if( lkrq->flags & gio_lck_fg_hasLVB ) { - lvb_log_msg("For %s, Lock %s: Sent LVB (%d) %s\n", lkrq->name, - lkeytob64(lkrq->key, lkrq->keylen), lkrq->LVBlen, - lvbtohex(lkrq->LVB, lkrq->LVBlen)); - if((err=xdr_enc_raw(enc, lkrq->LVB, lkrq->LVBlen)) != 0 ) break; - } - if((err=xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -/** - * send_req_lk_reply - - * @lkrq: - * @lk: - * @retcode: - * - * sends a reply to the proper client. Also determines if they need the - * LVB attached. - * - * - * Returns: int - */ -int send_req_lk_reply(Waiters_t *lkrq, Lock_t *lk, uint32_t retcode) -{ - Waiters_t *new; - - /* - * Look up the idx in the pollers, and compair names to make sure this - * is the correct one. Then use that encoder. - * If not the correct one, scan the pollers for the correct one. - * If we don't find the correct one, then what? - */ - if( lkrq->idx < 0 || lkrq->idx > open_max() ) lkrq->idx = 0; - /* the strcmp slows things down a tiny bit. - * wonder if there is another way. - */ - if( poller.type[lkrq->idx] != poll_Client || - poller.ipn[lkrq->idx].name == NULL || - strcmp( lkrq->name, poller.ipn[lkrq->idx].name) != 0 ) { - if( (lkrq->idx = find_idx_for_name(lkrq->name)) < 0 ) { - log_err("No encoder for "%s"! lock:%s", - lkrq->name, lkeytob64(lkrq->key, lkrq->keylen)); - return -1; - } - } - - lkrq->ret = retcode; - - new = duplicate_lkrw(lkrq); - - /* ok, now package up the reply. */ - if( retcode == gio_Err_Ok && - lk != NULL && - lkrq->state != gio_lck_st_Unlock && - lk->LVBlen > 0 && - lk->LVB != NULL ) - { - new->flags |= gio_lck_fg_hasLVB; - if( new->LVB != NULL ) free(new->LVB); - new->LVB = malloc(lk->LVBlen); - memcpy(new->LVB, lk->LVB, lk->LVBlen); - new->LVBlen = lk->LVBlen; - } else { - /* no lvb. */ - new->flags &= ~gio_lck_fg_hasLVB; - } - - new->op = gulm_lock_state_rpl; - queue_lkrq_for_sending(lkrq->idx, new); - - /* all done with this. */ -#ifdef LOCKHISTORY - record_lkrq(lk, lkrq); -#else - recycle_lkrq(lkrq); -#endif - - return 0; -} - -/** - * _send_query_reply_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_query_reply_(int idx, Waiters_t *lkrq) -{ - int err; - LLi_t *tp; - Holders_t *h; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err=xdr_enc_uint32(enc, gulm_lock_query_rpl)) != 0 ) break; - if((err=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->subid)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->start)) != 0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->stop)) != 0 ) break; - if((err=xdr_enc_uint8(enc, lkrq->state)) != 0 ) break; - if((err=xdr_enc_uint32(enc, lkrq->ret)) != 0 ) break; - /* holder[s] info follows. */ - if((err = xdr_enc_list_start(enc)) != 0 ) return err; - for(tp = LLi_next(&lkrq->holders); - NULL != LLi_data(tp); - tp = LLi_next(tp) ) - { - h = LLi_data(tp); - if((err = xdr_enc_string(enc, h->name)) != 0 ) return err; - if((err = xdr_enc_uint64(enc, h->subid)) != 0 ) return err; - if((err = xdr_enc_uint64(enc, h->start)) != 0 ) return err; - if((err = xdr_enc_uint64(enc, h->stop)) != 0 ) return err; - if((err = xdr_enc_uint8(enc, h->state)) != 0 ) return err; - } - if((err = xdr_enc_list_stop(enc)) != 0 ) return err; - if((err=xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -/** - * send_query_reply - - * @lkrq: - * - * - * Returns: int - */ -int send_query_reply(Waiters_t *lkrq, uint32_t retcode) -{ - /* make sure the right poller is being used. */ - if( lkrq->idx < 0 || lkrq->idx > open_max() ) lkrq->idx = 0; - if( poller.type[lkrq->idx] != poll_Client || - poller.ipn[lkrq->idx].name == NULL || - strcmp( lkrq->name, poller.ipn[lkrq->idx].name) != 0 ) { - if( (lkrq->idx = find_idx_for_name(lkrq->name)) < 0 ) { - log_err("No encoder for "%s"! lock:%s", - lkrq->name, lkeytob64(lkrq->key, lkrq->keylen)); - return -1; - } - } - lkrq->ret = retcode; - lkrq->op = gulm_lock_query_rpl; - queue_lkrq_for_sending(lkrq->idx, lkrq); - return 0; -} - -/** - * _send_drp_req_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_drp_req_(int idx, Waiters_t *lkrq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; -#ifdef TIMECALLBACKS - struct timeval tv; - gettimeofday(&tv, NULL); - - /* TODO - * measure the amount of time between successive calls to this function. - * See if there is a delay there. Would imagin so. just want to check. - */ -#endif - do { - if((err=xdr_enc_uint32(enc, gulm_lock_cb_state)) !=0 ) break; - if((err=xdr_enc_raw(enc, lkrq->key, lkrq->keylen)) !=0 ) break; - if((err=xdr_enc_uint64(enc, lkrq->subid)) != 0 ) break; - if((err=xdr_enc_uint8(enc, lkrq->state)) !=0 ) break; -#ifdef TIMECALLBACKS - if((err=xdr_enc_uint64(enc, tvs2uint64(tv))) != 0) break; -#endif - if((err=xdr_enc_flush(enc)) !=0 ) break; - }while(0); - return err; -} - -/** - * send_drp_req - - * @Cname: < skip this one. - * @lk: < - * @DesireState: < - * - * - */ -void send_drp_req(Lock_t *lk, Waiters_t *lkrq) -{ - int idx; - LLi_t *tp; - Holders_t *h; - Waiters_t *new; - - if( ! LLi_empty( &lk->Holders ) ) { - for(tp=LLi_next(&lk->Holders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if( !(h->flags & gio_lck_fg_NoCallBacks) && - ! compare_holder_waiter_names(h, lkrq) ) { - - new = get_new_lkrq(); - GULMD_ASSERT( new != NULL, ); - new->op = gulm_lock_cb_state; - new->name = strdup(h->name); - GULMD_ASSERT( new->name != NULL, ); - new->subid = h->subid; - new->keylen = lk->keylen; - new->key = malloc(lk->keylen); - GULMD_ASSERT( new->key != NULL, ); - memcpy(new->key, lk->key, lk->keylen); - new->state = lkrq->state; /* which state we'd like */ - - if( (idx = find_and_cache_idx_for_holder(h)) > 0 ) { - queue_lkrq_for_sending(idx, new); - - }else{ - log_msg(lgm_locking, "Client Node %s not currently logged in. " - "Queuing Droplok Request for later.\n", h->name); - - LLi_add_after(&DropRequestPlaybackQueue, &new->wt_list); - cnt_drpq ++; - - } - - }/*if( strcmp(h->name, name) != 0 )*/ - }/*for()*/ - }/*if( ! LLi_empty( &lk->Holders ) )*/ -} - -/** - * playback_droprequests - - * @idx: - * @name: - * - * - * Returns: void - */ -void playback_droprequests(int idx, uint8_t *name) -{ - LLi_t *tmp, *nxt; - Waiters_t *lkrq; - - for(tmp = LLi_next(&DropRequestPlaybackQueue); - LLi_data(tmp) != NULL; - tmp = nxt) { - nxt = LLi_next(tmp); - lkrq = LLi_data(tmp); - if( strcmp(name, lkrq->name) == 0 ) { - LLi_del(tmp); - cnt_drpq --; - - log_msg(lgm_locking, "Playing back a drop lock request for new client" - " %s\n", lkrq->name); - - /* move from this list to the out queue. */ - queue_lkrq_for_sending(idx, lkrq); - } - } -} - -/** - * expire_queued_dropreqs - - * @name: - * - * if client expires, all of its locks will be freed. which will - * effectively do that same as handling these drop reqs. - * - */ -void expire_queued_dropreqs(uint8_t *name) -{ - LLi_t *tmp, *nxt; - Waiters_t *lkrq; - - for(tmp = LLi_next(&DropRequestPlaybackQueue); - LLi_data(tmp) != NULL; - tmp = nxt) { - nxt = LLi_next(tmp); - lkrq = LLi_data(tmp); - if( strcmp(name, lkrq->name) == 0 ) { - LLi_del(tmp); - cnt_drpq --; - /* now free it */ - recycle_lkrq(lkrq); - } - } -} - -/** - * _send_drop_all_req_ - - * @idx: - * @lkrq: - * - * - * Returns: int - */ -static int _send_drop_all_req_(int idx, Waiters_t *lkrq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_cb_dropall))!=0) break; - if((err = xdr_enc_flush(enc))!=0) break; - }while(0); - return err; -} - -/** - * send_drop_all_req - - * - * sends to all the currently connected clients. - */ -void send_drop_all_req(void) -{ - int idx; - Waiters_t *lkrq; - - for(idx=0; idx < poller.maxi; idx++ ) { - if( poller.type[idx] == poll_Client ) { - lkrq = get_new_lkrq(); - lkrq->op = gulm_lock_cb_dropall; - queue_lkrq_for_sending(idx, lkrq); - } - } -} - -/*****************************************************************************/ -static int send_io_stats(xdr_enc_t *enc) -{ - struct timeval tv; - char tmp[256] = "3: Well trust me, there is nothing in here."; - int err; - - if((err=xdr_enc_string(enc, "I_am")) != 0 ) return err; - if((err=xdr_enc_string(enc, gio_I_am_to_str(I_am_the))) != 0 ) return err; - - if( MasterIN.name != NULL ) { - if((err=xdr_enc_string(enc, "Master")) != 0 ) return err; - if((err=xdr_enc_string(enc, MasterIN.name)) != 0 ) return err; - - xdr_enc_string(enc, "login"); - if( poller.MasterIDX >=0 && logging_into_master ) { - xdr_enc_string(enc, "Trying"); - }else - if( poller.MasterIDX >= 0 ) { - xdr_enc_string(enc, "In"); - }else - { - xdr_enc_string(enc, "Out"); - } - - } - - gettimeofday(&tv, NULL); - xdr_enc_string(enc, "run time"); - snprintf(tmp, 256, "%lu", tv.tv_sec - Started_at.tv_sec ); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "pid"); - snprintf(tmp, 256, "%u", getpid()); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "verbosity"); - get_verbosity_string(tmp, 256, verbosity); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "id"); - snprintf(tmp, 256, "%u", LTid); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "partitions"); - snprintf(tmp, 256, "%u", gulm_config.how_many_lts); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "out_queue"); - snprintf(tmp, 256, "%lu", totaloutqlen); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "drpb_queue"); - snprintf(tmp, 256, "%lu", cnt_drpq); - xdr_enc_string(enc, tmp); - - /* xdr_enc_flush is called by this function's caller. */ - return 0; -} - - -static int accept_connection(void) -{ - int clisk, i; - struct sockaddr_in6 adr; - - i = sizeof(struct sockaddr_in6); - if( (clisk = accept(poller.listenFD, (struct sockaddr*)&adr, &i)) <0) { - log_err("error in accept: %s", strerror(errno)); - return -1; - } - - if( set_opts(clisk) <0) { - log_err("Cannot set socket options for new connection. Killing it.\n"); - close(clisk); - return -1; - } - - i = add_to_pollers(clisk, poll_Accepting, tvs2uint64(NOW), - ip6tostr(&adr.sin6_addr), &adr.sin6_addr); - if( i < 0 ) { - log_err("Failed to add new socket to poller list. %s\n", strerror(errno)); - close(clisk); - return -1; - } - if( add_xdr_to_poller(i) != 0 ) { - log_err("Failed to attatch xdr to new socket do to lack of memory.\n"); - close_by_idx(i); - return -1; - } - - return 0; -} - -/** - * logintoMaster - - * - * Returns: int - */ -static int logintoMaster(void) -{ - struct sockaddr_in6 adr; - int i,cmFD,err; - xdr_enc_t *xdr; - - log_msg(lgm_LoginLoops, "Trying to log into Master %s\n", - print_ipname(&MasterIN)); - - /* socket connect to CM */ - if((cmFD = socket(AF_INET6, SOCK_STREAM, 0)) <0){ - log_err("Failed to create socket. %s\n", strerror(errno)); - return -1; - } - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - memcpy(&adr.sin6_addr, &MasterIN.ip, sizeof(struct in6_addr)); - adr.sin6_port = htons( gulm_config.lt_port + LTid ); - - if( connect(cmFD, (struct sockaddr*)&adr, sizeof(struct sockaddr_in6))<0) { - close(cmFD); - log_msg(lgm_LoginLoops, "Cannot connect to %s (%s)\n", - print_ipname(&MasterIN), strerror(errno)); - return -1; - /* need to go to next here */ - } - - if( set_opts(cmFD) <0) { - close(cmFD); - log_msg(lgm_LoginLoops, "Failed to set options (%s)\n", strerror(errno)); - return -1; - } - - /* */ - i = add_to_pollers(cmFD, poll_Trying, tvs2uint64(NOW), - MasterIN.name, &MasterIN.ip); - if( i < 0 ) { /* out of free FDs. */ - log_err("Failed to find unused poller space.\n"); - close_by_idx(i); - return -1; - } - if( add_xdr_to_poller(i) < 0 ) { - log_err("Failed to allocate memory for xdr.\n"); - close_by_idx(i); - return -1; - } - - /* send login request */ - xdr = poller.enc[i]; - - do { - if((err = xdr_enc_uint32(xdr, gulm_lock_login_req)) != 0) break; - if((err = xdr_enc_uint32(xdr, GIO_WIREPROT_VERS)) != 0) break; - if((err = xdr_enc_string(xdr, myName)) != 0) break; - if((err = xdr_enc_uint8(xdr, gio_lck_st_Slave)) != 0) break; - if((err = xdr_enc_flush(xdr)) != 0) break; - }while(0); - if( err != 0 ) { - log_msg(lgm_LoginLoops, "Errors trying to send login request. %d:%s\n", - err, strerror(errno)); - close_by_idx(i); - return -1; - } - - logging_into_master = TRUE; - - return 0; -} - -/** - * recv_Masterlogin_reply - - * @idx: - * - * - * Returns: int - */ -static int recv_Masterlogin_reply(int idx) -{ - xdr_dec_t *xdr = poller.dec[idx]; - uint32_t code=~0; - uint32_t rpl_err=~0; - uint8_t rpl_ama=~0; - int err; - - /* recv login reply */ - do{ - if((err = xdr_dec_uint32(xdr, &code)) != 0) break; - if((err = xdr_dec_uint32(xdr, &rpl_err)) != 0) break; - if((err = xdr_dec_uint8(xdr, &rpl_ama)) != 0) break; - } while(0); - if( err != 0 ) { - log_err("Errors trying to login to Master: (%s idx:%d fd:%d) %d:%s\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd, - err, strerror(errno)); - goto exit; - } - - if( rpl_err != 0 ) { - log_err("Errors trying to login to Master: (%s) %d:%s\n", - print_ipname(&poller.ipn[idx]), - rpl_err, gio_Err_to_str(rpl_err)); - err = rpl_err; - goto exit; - } - - PartialLockspace = TRUE; - /* get current state */ - if( (err=deserialize_lockspace(poller.polls[idx].fd)) != 0 ) { - log_err("Failed to deserialize initial lockspace from Master" - " (%d:%d:%s)\n", err, errno, strerror(errno)); - goto exit; - } - PartialLockspace = FALSE; - - poller.MasterIDX = idx; - poller.state[idx] = poll_Open; - poller.type[idx] = poll_Internal;/*not really, but close enough*/ - poller.times[idx] = 0; - log_msg(lgm_Network, "Logged into Master at %s\n", print_ipname(&MasterIN)); - -exit: - logging_into_master = FALSE; - - return err; -} - -/*****************************************************************************/ - - -/** - * send_some_data - - * @idx: - * - * - * Returns: int - */ -int send_some_data(int idx) -{ - LLi_t *tmp; - Waiters_t *lkrq; - int err=0; - - if( !Qu_empty(&poller.outq[idx]) ) { - tmp = Qu_DeQu(&poller.outq[idx]); - lkrq = Qu_data(tmp); - poller.outqlen[idx] --; - totaloutqlen --; - switch(lkrq->op) { - case gulm_lock_state_updt: - err = _send_req_update_(idx, lkrq); - break; - case gulm_lock_action_updt: - err = _send_act_update_(idx, lkrq); - break; - case gulm_lock_update_rpl: - err = _send_update_reply_(idx, lkrq); - break; - case gulm_lock_drop_exp: - err = _send_drop_exp_to_slave_(idx, lkrq); - break; - case gulm_lock_expire: - err = _send_expire_to_slave_(idx, lkrq); - break; - case gulm_lock_action_rpl: - err = _send_lk_act_reply_(idx, lkrq); - break; - case gulm_lock_state_rpl: - err = _send_lk_req_reply_(idx, lkrq); - break; - case gulm_lock_cb_state: - err = _send_drp_req_(idx, lkrq); - break; - case gulm_lock_cb_dropall: - err = _send_drop_all_req_(idx, lkrq); - break; - case gulm_lock_query_rpl: - err = _send_query_reply_(idx, lkrq); - break; - - default: - log_err("Cannot send packet type %#x:%s !\n", - lkrq->op, gio_opcodes(lkrq->op)); - break; - } - if( err != 0 ) { - log_err("Warning! When trying to send a %#x:%s packet, we got a " - "%d:%d:%s\n", lkrq->op, gio_opcodes(lkrq->op), - err, errno, strerror(errno)); - } - recycle_lkrq(lkrq); - } - - if( Qu_empty(&poller.outq[idx]) ) poller.polls[idx].events &= ~POLLOUT; - return err; -} - -/*****************************************************************************/ - -/** - * pack_lkrq_from_io - - * @lkrq: - * @code: - * @dec: - * @enc: - * - * Returns: int - */ -int pack_lkrq_from_io(Waiters_t *lkrq, uint32_t code, - xdr_dec_t *dec, int idx) -{ - int err = 0; - uint8_t *x_name=NULL; - LLi_init( &lkrq->wt_list, lkrq); - lkrq->op = code; - lkrq->idx = idx; - if( gulm_lock_state_req == code ) { - do { - lkrq->name = strdup(poller.ipn[idx].name); - if( lkrq->name == NULL ) { err = -ENOMEM; break; } - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->key, &lkrq->keylen)) != 0 ) - break; - if((err = xdr_dec_uint64(dec, &lkrq->subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &lkrq->state)) != 0 ) break; - if((err = xdr_dec_uint32(dec, &lkrq->flags)) != 0 ) break; - if( lkrq->flags & gio_lck_fg_hasLVB ) { - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->LVB, &lkrq->LVBlen))!=0) - break; - }else{ - lkrq->LVB = NULL; - lkrq->LVBlen = 0; - } - }while(0); - }else - if( gulm_lock_state_updt == code ) { - do { - if((err = xdr_dec_string(dec, &lkrq->name)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->stop)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->key, &lkrq->keylen)) != 0 ) - break; - if((err = xdr_dec_uint8(dec, &lkrq->state)) != 0 ) break; - if((err = xdr_dec_uint32(dec, &lkrq->flags)) != 0 ) break; - if( lkrq->flags & gio_lck_fg_hasLVB ) { - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->LVB, &lkrq->LVBlen))!=0) - break; - }else{ - lkrq->LVB = NULL; - lkrq->LVBlen = 0; - } - }while(0); - }else - if( gulm_lock_action_req == code ) { - do { - lkrq->name = strdup(poller.ipn[idx].name); - if( lkrq->name == NULL ) { err = -ENOMEM; break; } - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->key, &lkrq->keylen)) != 0 ) - break; - if((err = xdr_dec_uint64(dec, &lkrq->subid)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &lkrq->state)) != 0 ) break; - if( lkrq->state == gio_lck_st_SyncLVB ) { - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->LVB, &lkrq->LVBlen))!=0) - break; - }else{ - lkrq->LVB = NULL; - lkrq->LVBlen = 0; - } - }while(0); - }else - if( gulm_lock_action_updt == code ) { - do { - if((err = xdr_dec_string(dec, &lkrq->name)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->subid)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->key, &lkrq->keylen)) != 0 ) - break; - if((err = xdr_dec_uint8(dec, &lkrq->state)) != 0 ) break; - if( lkrq->state == gio_lck_st_SyncLVB ) { - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->LVB, &lkrq->LVBlen))!=0) - break; - }else{ - lkrq->LVB = NULL; - lkrq->LVBlen = 0; - } - }while(0); - }else - if( gulm_lock_query_req == code ) { - do { - lkrq->name = strdup(poller.ipn[idx].name); - if( lkrq->name == NULL ) { err = -ENOMEM; break; } - if((err = xdr_dec_raw_m(dec, (void**)&lkrq->key, &lkrq->keylen)) != 0 ) - break; - if((err = xdr_dec_uint64(dec, &lkrq->subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lkrq->stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &lkrq->state)) != 0 ) break; - }while(0); - }else - { - err = -1; - log_err("Unrecognised packet code %#x\n", code); - } - if( x_name != NULL ) free(x_name); - return err; -} - -/** - * do_login - - * @idx: - * - * Slaves can connect to me when I am Master or Arbit. - * Clients can only connect when I am Master. - * - * Returns: void - */ -static void do_login(int idx) -{ - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - uint32_t x_proto; - uint8_t *x_name = NULL; - uint8_t x_ama; - int err, soff; - - do { - if((err = xdr_dec_uint32(dec, &x_proto)) != 0) break; - if(GIO_WIREPROT_VERS != x_proto) {err=gio_Err_BadWireProto; break;} - if((err = xdr_dec_string(dec, &x_name)) != 0) break; - if((err = xdr_dec_uint8(dec, &x_ama)) != 0) break; - }while(0); - if(err!=0) { - if( x_name != NULL ) {free(x_name); x_name = NULL;} - close_by_idx(idx); - return; - } - - if( !validate_nodel(nodelists, x_name, &poller.ipn[idx].ip) ) { - do{ - if(xdr_enc_uint32(enc, gulm_lock_login_rpl) != 0) break; - if(xdr_enc_uint32(enc, gio_Err_NotAllowed) != 0) break; - if(xdr_enc_uint8(enc, I_am_the) != 0) break; - if(xdr_enc_flush(enc) != 0) break; - }while(0); - log_msg(lgm_Network2, "Telling %s that they are Not Allowed to talk " - "to us because core said so.\n", - print_ipname(&poller.ipn[idx])); - close_by_idx(idx); - }else - if( gio_lck_st_Slave == x_ama ) { - if( gio_Mbr_ama_Master == I_am_the || - gio_Mbr_ama_Arbitrating == I_am_the ) { - if( add_to_slavelist(idx, x_name ) != 0 ) { - do { - if(xdr_enc_uint32(enc, gulm_lock_login_rpl) != 0) break; - if(xdr_enc_uint32(enc, gio_Err_MemoryIssues) != 0) break; - if(xdr_enc_uint8(enc, I_am_the) != 0) break; - if(xdr_enc_flush(enc) != 0) break; - }while(0); - close_by_idx(idx); - } else { - - do { - if((err=xdr_enc_uint32(enc, gulm_lock_login_rpl)) != 0) break; - if((err=xdr_enc_uint32(enc, gio_Err_Ok)) != 0) break; - if((err=xdr_enc_uint8(enc, I_am_the)) != 0) break; - if((err=xdr_enc_flush(enc)) != 0) break; - }while(0); - if(err != 0 ) { - log_msg(lgm_Network, - "Errors %d:%s trying to send login reply to fd:%d, %s\n", - err, strerror(errno), poller.polls[idx].fd, - poller.ipn[idx].name); - remove_slave_from_list(idx); - close_by_idx(idx); - if( x_name != NULL ) {free(x_name); x_name = NULL;} - return; - } - - if((err=serialize_lockspace( poller.polls[idx].fd )) != 0) { - log_msg(lgm_Network, - "Errors '%d:%d:%s' serializing lock space to idx:%d " - "fd:%d, %s\n", - err, errno, strerror(errno), idx, poller.polls[idx].fd, - poller.ipn[idx].name); - remove_slave_from_list(idx); - close_by_idx(idx); - if( x_name != NULL ) {free(x_name); x_name = NULL;} - return; - } - - if( poller.ipn[idx].name != NULL ) free( poller.ipn[idx].name ); - poller.ipn[idx].name = x_name; - poller.state[idx] = poll_Open; - poller.type[idx] = poll_Slave; - poller.times[idx] = 0; - soff = get_slave_offset(idx); - log_msg(lgm_Network, "Attached slave %s idx:%d fd:%d " - "(soff:%d connected:%#x)\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd, - soff, Slave_bitmask); - - recheck_reply_waiters(Slave_bitmask, 1<<soff ); - /* - * When Slave foo logs in, we scan lockspace - * and if we find any reply_waiters that claim to have sent to - * them, but have not received a reply, we mark that reply. - */ - return; - } - }else{ - do { - if(xdr_enc_uint32(enc, gulm_lock_login_rpl) != 0) break; - if(xdr_enc_uint32(enc, gio_Err_NotAllowed) != 0) break; - if(xdr_enc_uint8(enc, gio_Mbr_ama_Slave) != 0) break; - if(xdr_enc_flush(enc) != 0) break; - }while(0); - log_msg(lgm_Network2, "Telling %s Not Allowed because they are " - "a Slave but we're not Master or Arbitrator.\n", - print_ipname(&poller.ipn[idx])); - close_by_idx(idx); - } - }else - if( gio_lck_st_Client == x_ama ) { - if( gio_Mbr_ama_Master == I_am_the ) { - do { - if((err=xdr_enc_uint32(enc, gulm_lock_login_rpl)) != 0) break; - if((err=xdr_enc_uint32(enc, gio_Err_Ok)) != 0) break; - if((err=xdr_enc_uint8(enc, I_am_the)) != 0) break; - if((err=xdr_enc_flush(enc)) != 0) break; - }while(0); - if(err != 0 ) { - log_msg(lgm_Network, - "Errors %d:%s trying to send login reply to fd:%d, %s\n", - err, strerror(errno), poller.polls[idx].fd, - poller.ipn[idx].name); - close_by_idx(idx); - if( x_name != NULL ) {free(x_name); x_name = NULL;} - return; - } - - if( poller.ipn[idx].name != NULL ) free( poller.ipn[idx].name ); - poller.ipn[idx].name = x_name; - poller.state[idx] = poll_Open; - poller.type[idx] = poll_Client; - poller.times[idx] = 0; - log_msg(lgm_Network,"New Client: idx %d fd %d from %s\n", - idx, poller.polls[idx].fd, - print_ipname(&poller.ipn[idx])); - - /* play back any pending drop requests. */ - playback_droprequests(idx, x_name); - - return; - }else{ - do { - if(xdr_enc_uint32(enc, gulm_lock_login_rpl) != 0) break; - if(xdr_enc_uint32(enc, gio_Err_NotAllowed) != 0) break; - if(xdr_enc_uint8(enc, I_am_the) != 0) break; - if(xdr_enc_flush(enc) != 0) break; - }while(0); - log_msg(lgm_Network2, "Telling %s Not Allowed because they are a " - "Client but we're not Master.\n", - print_ipname(&poller.ipn[idx])); - close_by_idx(idx); - } - }else - { - do { - if(xdr_enc_uint32(enc, gulm_lock_login_rpl) != 0) break; - if(xdr_enc_uint32(enc, gio_Err_BadLogin) != 0) break; - if(xdr_enc_uint8(enc, I_am_the) != 0) break; - if(xdr_enc_flush(enc) != 0) break; - }while(0); - close_by_idx(idx); - } - free(x_name); x_name = NULL; -} - -/** - * recv_some_data - - * @idx: - * - * - */ -static void recv_some_data(int idx) -{ - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - uint32_t code=0; - uint8_t *x_name = NULL; - int err; - Waiters_t *lkrq; - - if( dec == NULL ) { - log_err("There is no Decoder on poller (%s idx:%d fd:%d)!!\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - return; - } - if( enc == NULL ) { - log_err("There is no Encoder on poller (%s idx:%d fd:%d)!!\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - return; - } - - errno=0; - err = xdr_dec_uint32(dec, &code); - if( err == -EPROTO ) { - log_msg(lgm_Network, "EOF on xdr (%s idx:%d fd:%d)\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - close_by_idx(idx); - return; - } - if( err != 0 ) { - log_msg(lgm_Always, "Error on xdr (%s): %d:%d:%s\n", - print_ipname(&poller.ipn[idx]), - err, errno, strerror(errno)); - /* err == -EPROTO from xdr_* means it read EOF. - */ - close_by_idx(idx); - return; - } - - if( gulm_lock_login_req == code ) { - do_login(idx); - }else - if( gulm_lock_logout_req == code ) { - /* gets closed right away, so we can ignore errors since that is - * exactly what we would do if we saw one. - */ - xdr_enc_uint32(enc, gulm_lock_logout_rpl); - xdr_enc_flush(enc); - close_by_idx(idx); - }else - if( code == gulm_socket_close ) { - close_by_idx(idx); - }else - if( gulm_core_mbr_updt == code ) { - struct in6_addr x_ip; - uint8_t x_cur_state=-1; - do { - if((err=xdr_dec_string(dec, &x_name)) != 0) break; - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err=xdr_dec_uint8(dec, &x_cur_state)) != 0) break; - }while(0); - if( err != 0 ) { - if(x_name!=NULL) {free(x_name); x_name = NULL;} - return; - } - - log_msg(lgm_Subscribers, "Recvd mbrupdt: %s, %s:%#x\n", - x_name, gio_mbrupdate_to_str(x_cur_state), x_cur_state); - - /* save it */ - update_nodel(nodelists, x_name, &x_ip, x_cur_state); - - if( I_am_the == gio_Mbr_ama_Slave ) { - if( x_cur_state == gio_Mbr_Expired || - x_cur_state == gio_Mbr_Logged_out ) { - if( MasterIN.name != NULL ) { - if(IN6_ARE_ADDR_EQUAL(x_ip.s6_addr32, MasterIN.ip.s6_addr32) || - strcmp(x_name, MasterIN.name) == 0 ) { - /* Master Died! */ - I_am_the = gio_Mbr_ama_Pending; - close_by_idx(poller.MasterIDX); - } - } - if( strcmp(myName, x_name) == 0 ) { - log_msg(lgm_Network, "Core is shutting down.\n"); - /* or should this get done differently? */ - running = FALSE; - } - } - }else - if( I_am_the == gio_Mbr_ama_Master || - I_am_the == gio_Mbr_ama_Arbitrating ) { - if( x_cur_state == gio_Mbr_Logged_out ) { - int t; - if( (t=get_slave_idx(x_name)) != -1 ) { - remove_slave_from_list_by_name(x_name); - close_by_idx(t); - } - if( strcmp(myName, x_name) == 0 ) { - log_msg(lgm_Network, "Core is shutting down.\n"); - /* or should this get done differently? */ - running = FALSE; - } - } - } - /* this is done no matter if it was kernel or userspace. */ - if( x_cur_state == gio_Mbr_Expired ) { - expire_locks(x_name, NULL, 0); - expire_queued_dropreqs(x_name); - remove_slave_from_list_by_name(x_name); - /* when expired, *everything* need to be closed out. */ - close_all_named(x_name); - } - free(x_name); x_name = NULL; - }else - if( gulm_core_mbr_lstrpl == code ) { - uint64_t x_x; - uint32_t x_y; - struct in6_addr x_ip; - uint8_t x_st, x_m; - do { - if((err=xdr_dec_list_start(dec)) != 0 ) break; - }while(0); - if( err != 0 ) { - return; - } - while( xdr_dec_list_stop(dec) != 0) { - do { - if((err=xdr_dec_string(dec, &x_name)) != 0) break; - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err=xdr_dec_uint8(dec, &x_st)) != 0) break; - if((err=xdr_dec_uint8(dec, &x_m)) != 0) break; - if((err=xdr_dec_uint8(dec, &x_m)) != 0) break; - if((err=xdr_dec_uint32(dec, &x_y)) != 0 ) break; - if((err=xdr_dec_uint64(dec, &x_x)) != 0 ) break; - if((err=xdr_dec_uint64(dec, &x_x)) != 0 ) break; - if((err=xdr_dec_uint64(dec, &x_x)) != 0 ) break; - }while(0); - if( err != 0 ) { - if(x_name!=NULL) {free(x_name); x_name = NULL;} - return; - } - update_nodel(nodelists, x_name, &x_ip, x_st); - if(x_name!=NULL) {free(x_name); x_name = NULL;} - } - }else - if( gulm_core_state_chgs == code ) { - uint8_t x_st, x_q; - struct in6_addr x_ip; - do { - if((err=xdr_dec_uint8(dec, &x_st)) != 0 ) break; - if((err=xdr_dec_uint8(dec, &x_q)) != 0 ) break; - if( x_st == gio_Mbr_ama_Slave ) { - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err=xdr_dec_string(dec, &x_name)) != 0 ) break; - } - }while(0); - if( err != 0 ) { - log_err("Failed to recv Core state update! %s\n", strerror(errno)); - }else{ - /* - * This could use a little clean up. - */ - if( x_st == gio_Mbr_ama_Slave ) { - if( I_am_the == gio_Mbr_ama_Slave ){ - /* nothing to change. - * Need to figure out why doubles come through. - * */ - }else{ - - /* if somehow still connected to a Master, drop it. */ - close_by_idx( poller.MasterIDX ); - - /* copy in master info. */ - if( MasterIN.name != NULL ) { - free(MasterIN.name); - MasterIN.name = NULL; - } - MasterIN.name = strdup(x_name); - if( MasterIN.name == NULL ) - die(ExitGulm_NoMemory, "Out of Memory.\n"); - memcpy(&MasterIN.ip, &x_ip, sizeof(struct in6_addr)); - log_msg(lgm_Always, "New Master at %s\n", - print_ipname(&MasterIN)); - - /* The if down in the lt_main_loop will detect that we need - * to loginto the master, and does that for us now. - */ - } - }else - if( x_st == gio_Mbr_ama_Master ) { - - if( I_am_the != gio_Mbr_ama_Master ) { - if( MasterIN.name != NULL ) { - free(MasterIN.name); - MasterIN.name = NULL; - } - memset(&MasterIN.ip, 0, sizeof(struct in6_addr)); - /* close connection */ - close_by_idx( poller.MasterIDX ); - } - }else - if( x_st == gio_Mbr_ama_Pending ) { - if( I_am_the != gio_Mbr_ama_Pending ) { - /* if the new state is Pending, and we weren't Pending - * before, we need to make sure that no clients are - * connected. Well behaved clients won't connect, but in the - * future when I'm not gonna be writing all of the clients, - * I cannot always rely on that. - */ - close_all_clients(); - - /* if we had been a slave, we don't want this info anymore. - */ - if( MasterIN.name != NULL ) { - free(MasterIN.name); - MasterIN.name = NULL; - } - memset(&MasterIN.ip, 0, sizeof(struct in6_addr)); - /* close connection */ - close_by_idx( poller.MasterIDX ); - } - }else - if( x_st == gio_Mbr_ama_Arbitrating ) { - if( I_am_the != gio_Mbr_ama_Arbitrating ) { - /* nothing here. */ - } - }else - { - log_msg(lgm_Always, "Wierd new server state %d\n", x_st); - } - - I_am_the = x_st; - log_msg(lgm_ServerState, "New State: %s\n", gio_I_am_to_str(x_st)); - } - if( x_name != NULL ) {free(x_name); x_name = NULL;} - }else - if( gulm_info_stats_req == code ) { - xdr_enc_uint32(enc, gulm_info_stats_rpl); - xdr_enc_list_start(enc); - send_io_stats(enc); - send_stats(enc); - xdr_enc_list_stop(enc); - xdr_enc_flush(enc); - }else - if( gulm_info_set_verbosity == code ) { - if( xdr_dec_string(dec, &x_name) == 0 ) { - set_verbosity(x_name, &verbosity); - if( x_name != NULL ) { free(x_name); x_name = NULL; } - } - close_by_idx(idx); - }else - if( gulm_info_slave_list_req == code ) { - xdr_enc_uint32(enc, gulm_info_slave_list_rpl); - dump_slave_list(enc); - close_by_idx(idx); - }else - if( gulm_lock_dump_req == code ) { - xdr_enc_uint32(enc, gulm_lock_dump_rpl); - xdr_enc_flush(enc); - serialize_lockspace( poller.polls[idx].fd ); - }else - if( gulm_lock_rerunqueues == code ) { - rerun_wait_queues(); - recheck_reply_waiters(Slave_bitmask, 0); - close_by_idx(idx); - }else - if( gulm_err_reply == code ) { - uint32_t xc,xe; - xdr_dec_uint32(dec, &xc); - xdr_dec_uint32(dec, &xe); - - log_msg(lgm_Always, - "%s Gave us a %#x:%s %d:%s, closing the connection.\n", - print_ipname(&poller.ipn[idx]), - xc, gio_opcodes(xc), - xe, gio_Err_to_str(xe)); - - close_by_idx(idx); - }else - if( gio_Mbr_ama_Slave == I_am_the ) { - /*************************************************************/ - if( gulm_lock_state_updt == code ) { - lkrq = get_new_lkrq(); - if( lkrq == NULL ) die(ExitGulm_NoMemory, "No memory.\n"); - - if(pack_lkrq_from_io(lkrq, code, dec, idx) == 0 ) - err = force_lock_state(lkrq); - }else - if( gulm_lock_action_updt == code ) { - lkrq = get_new_lkrq(); - if( lkrq == NULL ) die(ExitGulm_NoMemory, "No memory.\n"); - - if(pack_lkrq_from_io(lkrq, code, dec, idx) == 0 ) - err = force_lock_action(lkrq); - }else - if( gulm_lock_drop_exp == code ) { - uint8_t *x_mask = NULL; - uint16_t x_len=0; - do { - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&x_mask, &x_len)) != 0 ) break; - }while(0); - if( err == 0 ) { - drop_expired(x_name, x_mask, x_len); - if( x_name == NULL ) { - log_msg(lgm_locking,"Dropped expired locks for NULL\n"); - }else{ - log_msg(lgm_locking,"Dropped expired locks for %s\n", x_name); - } - } - if(x_name != NULL ) {free(x_name); x_name = NULL;} - if(x_mask != NULL ) {free(x_mask); x_mask = NULL;} - }else - if( gulm_lock_expire == code ) { - uint8_t *x_mask = NULL; - uint16_t x_len=0; - do { - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&x_mask, &x_len)) != 0 ) break; - }while(0); - if( err == 0 ) { - expire_locks(x_name, x_mask, x_len); - log_msg(lgm_locking,"Expired locks for %s\n", x_name); - } - if(x_name != NULL ) {free(x_name); x_name = NULL;} - if(x_mask != NULL ) {free(x_mask); x_mask = NULL;} - }else - { - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, code); - xdr_enc_uint32(enc, gio_Err_NotAllowed); - xdr_enc_flush(enc); - } - }else - if( gio_Mbr_ama_Master == I_am_the || - gio_Mbr_ama_Arbitrating == I_am_the ) { - /*************************************************************/ - if( gulm_lock_drop_exp == code ) { - uint8_t *x_mask = NULL; - uint16_t x_len=0; - do { - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&x_mask, &x_len)) != 0 ) break; - }while(0); - if( err == 0 ) { - drop_expired(x_name, x_mask, x_len); - if( x_name == NULL ) { - log_msg(lgm_locking,"Dropped expired locks for NULL\n"); - }else{ - log_msg(lgm_locking,"Dropped expired locks for %s\n", x_name); - } - send_drop_exp_to_slaves(x_name, x_mask, x_len); - } - if(x_name != NULL ) {free(x_name); x_name = NULL;} - if(x_mask != NULL ) {free(x_mask); x_mask = NULL;} - }else - if( gulm_lock_expire == code ) { - uint8_t *x_mask = NULL; - uint16_t x_len=0; - do { - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&x_mask, &x_len)) != 0 ) break; - }while(0); - if( err == 0 ) { - expire_locks(x_name, x_mask, x_len); - log_msg(lgm_locking,"Expired locks for %s\n", x_name); - send_expire_to_slaves(x_name, x_mask, x_len); - } - if(x_name != NULL ) {free(x_name); x_name = NULL;} - if(x_mask != NULL ) {free(x_mask); x_mask = NULL;} - }else - if( gulm_lock_update_rpl == code ) { - uint8_t *x_key=NULL; - uint16_t x_len; - int soff; - if( (err = xdr_dec_raw_m(dec, (void**)&x_key, &x_len)) == 0 ) { - - /* find slave_index for this slave. */ - if( (soff = get_slave_offset(idx)) == -1 ) { - /* ERROR! */ - log_err("CANNOT FIND SLAVE %s !!!!!\n", poller.ipn[idx].name); - } else { - log_msg(lgm_LockUpdates, - "Slave reply from %s so:%d for lock %s\n", - poller.ipn[idx].name, soff, lkeytob64(x_key, x_len)); - increment_slave_update_replies(x_key, x_len, soff,Slave_bitmask); - } - }else{ - log_err("xdr_dec error %d\n", err); - } - - if( x_key != NULL ) {free(x_key); x_key = NULL;} - }else - if( (lkrq = get_new_lkrq()) == NULL ) { - log_err("Out Of Memory!\n"); - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, code); - xdr_enc_uint32(enc, gio_Err_MemoryIssues); - xdr_enc_flush(enc); - }else - if( pack_lkrq_from_io(lkrq, code, dec, idx) != 0) { - log_err("Out Of Memory!\n"); - xdr_enc_uint32(enc, gulm_err_reply); - xdr_enc_uint32(enc, code); - xdr_enc_uint32(enc, gio_Err_MemoryIssues); - xdr_enc_flush(enc); - }else - if( gulm_lock_state_req == code ) { - err = do_lock_state(lkrq); - /* the lkrq will be freed up after the slave update replies have - * been recved. - */ - }else - if( gulm_lock_action_req == code ) { - err = do_lock_action(lkrq); - /* the lkrq will be freed up after the slave update replies have - * been recved. - */ - }else - if( gulm_lock_query_req == code ) { - err = do_lock_query(lkrq); - }else - { - log_err("Unexpected op code %#x (%s), on fd:%d name:%s\n", - code, gio_opcodes(code), - poller.polls[idx].fd, poller.ipn[idx].name); - - close_by_idx(idx); - } - }else - { - log_err("Unexpected op code %#x (%s), on fd:%d name:%s\n", - code, gio_opcodes(code), - poller.polls[idx].fd, poller.ipn[idx].name); - - close_by_idx(idx); - } - -} - -/** - * get_core_state - - * - * Returns: int - */ -static int get_core_state(void) -{ - int err; - xdr_enc_t *enc = poller.enc[poller.coreIDX]; - if((err=xdr_enc_uint32(enc, gulm_core_state_req))!=0) return err; - if((err=xdr_enc_flush(enc))!=0) return err; - - /* grab nodelist too while we're at it. */ - if((err=xdr_enc_uint32(enc, gulm_core_mbr_lstreq))!=0) return err; - if((err=xdr_enc_flush(enc))!=0) return err; - return 0; -} - -/** - * lt_main_loop - - * - * This loop handles incommings. - * - * Returns: int - */ -void lt_main_loop(void) -{ - int cnt, idx; - extern unsigned long cnt_replyq; - - init_lt_slave_list(); - if((nodelists = initialize_nodel())==NULL) - die(ExitGulm_NoMemory, "Out of memory.\n"); - gettimeofday(&Started_at, NULL); - gettimeofday(&NOW, NULL); - get_core_state(); - - while( running ) { - - /* We're supposed to be connected to a Master server, but we seem not - * to be at the moment. So try again. - * Actually, if this works out, I may leave this to be the perferred - * method of logging into the server. - * it does. - */ - if( I_am_the == gio_Mbr_ama_Slave && - MasterIN.name != NULL && - !IN6_IS_ADDR_UNSPECIFIED(MasterIN.ip.s6_addr32) && - poller.MasterIDX == -1 && - logging_into_master == FALSE ) - logintoMaster(); - - if( (cnt = poll(poller.polls, poller.maxi +1, 1000)) <= 0) { - if( cnt < 0 && errno != EINTR ) - log_err("poll error: %s\n",strerror(errno)); - if(!running) return; - } - gettimeofday(&NOW, NULL); - - /* for shits and giggles. - * if reply_waiters > 3000 skip clients with data. - * should protect against spikes pretty well. - * sustained load will kill. - */ - - for( idx=0; idx <= poller.maxi ; idx++) { - if( poller.polls[idx].fd < 0) continue; - if( poller.polls[idx].revents & POLLHUP ) { - remove_slave_from_list(idx); - close_by_idx(idx); - } - if (poller.polls[idx].revents & POLLNVAL ) { - remove_slave_from_list(idx); - close_by_idx(idx); - } - if( poller.polls[idx].revents & POLLOUT ) { - send_some_data(idx); - } - if( poller.polls[idx].revents & POLLIN ) { - poller.polls[idx].revents &= ~POLLIN; /*clear in case of swap*/ - if( poller.polls[idx].fd == poller.listenFD ) { - accept_connection(); - }else - { - if( poller.state[idx] == poll_Trying ) { - /* we're trying to loginto the master and become a slave. */ - if( recv_Masterlogin_reply(idx) != 0 ) - close_by_idx(idx); - /* should retry the login too. */ - }else{ - if( poller.type[idx] != poll_Client || - cnt_replyq < 3000 ) - recv_some_data(idx); - } - } - } - /* check for timed out pollers. */ - if( poller.times[idx] != 0 && - poller.times[idx]+ gulm_config.new_con_timeout < tvs2uint64(NOW)) { - log_msg(lgm_Network, "Timeout (%"PRIu64") on idx: %d fd:%d " - "(%s)\n", - gulm_config.new_con_timeout, idx, poller.polls[idx].fd, - print_ipname(&poller.ipn[idx])); - if( poller.state[idx] == poll_Trying ) logging_into_master = FALSE; - remove_slave_from_list(idx); - close_by_idx(idx); - } - if(!running) return; - }/*for( i=0; i <= poller.maxi ; i++)*/ - - }/* while(running) */ -} - - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/lock_main.c b/gulm/src/lock_main.c deleted file mode 100644 index 467c5ac..0000000 --- a/gulm/src/lock_main.c +++ /dev/null @@ -1,226 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <signal.h> -#include <execinfo.h> - -#include "gulm_defines.h" -#include "lock_priv.h" -#include "config_gulm.h" -#include "utils_dir.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; -/* other bits of interest */ -extern gulm_config_t gulm_config; -extern int I_am_the; -extern struct in6_addr myIP; -/* */ -char *LTname = NULL; -int LTid = 0; - -/*****************************************************************************/ - -/** - * sigact_usr1 - - * @sig: - * - */ -static void sigact_usr1(int sig) -{ - /* dump LockTables */ - dump_locks(); -} - -/** - * sigact_segv - - * @sig: - * - * try to get a backtrace before we puke out. - * This may not always work, but since I cannot get daemons to drop core - * files, trying this is better than nothing. - */ -static void sigact_segv(int sig) -{ - struct sigaction act; - void *array[200]; - size_t size,i; - char **strings; - - size = backtrace(array, 200); - strings = backtrace_symbols(array, size); -#ifndef DEBUG - syslog(LOG_NOTICE, "BACKTRACE\n"); -#else - fprintf(stderr, "BACKTRACE\n"); -#endif - for(i=0;i<size; i++) -#ifndef DEBUG - syslog(LOG_NOTICE, " %s\n", strings[i]); -#else - fprintf(stderr, " %s\n", strings[i]); -#endif - free(strings); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - sigaction(SIGSEGV, &act, NULL); - raise(SIGSEGV); -} - -/** - * setupsignals - set how we respond to signals. - */ -static void setupsignals(void) -{ - struct sigaction act; - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; /* use gulm_tool shutdown or kill -9 */ - if( sigaction(SIGTERM, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGTERM handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_usr1; - if( sigaction(SIGUSR1, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGUSR1 handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGUSR2, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGUSR2 handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGHUP, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGHUP handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN;/* don't die on broken pipes.*/ - if( sigaction(SIGPIPE, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGPIPE handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGALRM, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGALRM handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_segv; - if( sigaction(SIGSEGV, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGSEGV handler: %s\n",strerror(errno)); - -} - -/** - * twistName - Append '_LTxxx' to our name for logging. - */ -static void twistName(void) -{ - int l; - char *c; - - LTname = malloc(6); - if( LTname == NULL ) die(ExitGulm_NoMemory, "Out of Memory.\n"); - snprintf(LTname, 6, "LT%03d", LTid); - - l = strlen(ProgramName) + 8; - c = realloc(ProgramName, l); - if( c != NULL ) { - ProgramName = c; - strcat(ProgramName, LTname+2); /* 000 */ - } -#ifndef DEBUG - openlog(ProgramName, LOG_PID, LOG_DAEMON); -#endif /*DEBUG*/ -} - -/** - * lt_main - - * @argc: - * @argv: - * - * - * Returns: int - */ -int lt_main(int argc, char **argv) -{ - int i; - pid_t pid; - - /* running a server here? */ - if( ! Can_I_be_a_master(&gulm_config, &myIP) ) { - twistName(); - log_msg(lgm_Always, "Not serving locks from this node.\n"); - return 0; - } - - if( gulm_config.how_many_lts >= 2 ) { - for(i = 1; i < gulm_config.how_many_lts ; i++) { - if((pid=fork()) == 0 ) { - /* child */ - LTid = i; /* which are we? */ - break; - }else if(pid > 0 ) { - /* parent */ - }else { - /* error */ - } - } - } - - /* twist the logging a wee bit. Mostly just get the letters LT into - * the name. - */ - twistName(); - -#ifndef DEBUG - pid_lock(gulm_config.lock_file, ProgramName); -#endif - - log_init(0,0); - log_msg(lgm_Network2, "Locktable %d started.\n", LTid); - - /* we're the child of a daemon, so we've been daemonized. - * set up signal handlers. - */ - setupsignals(); - - init_lt_poller(); - open_lt_listener( gulm_config.lt_port + LTid ); - if( open_lt_to_core() != 0 ) return -1; - init_lockspace(gulm_config.lt_maxlocks, gulm_config.lt_hashbuckets); - - /* handling incomming packets */ - lt_main_loop(); - - clear_pid(gulm_config.lock_file, ProgramName); - - log_msg(lgm_Network, "finished.\n"); - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/lock_priv.h b/gulm/src/lock_priv.h deleted file mode 100644 index f2571ee..0000000 --- a/gulm/src/lock_priv.h +++ /dev/null @@ -1,186 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_lock_priv_h__ -#define __gulm_lock_priv_h__ -#include "LLi.h" -#include "Qu.h" -#include "xdr.h" -/* these get used in both io and space, so we'll drop them here. */ -typedef struct waiters_s { - Qu_t wt_list; - uint8_t *name; - uint64_t subid; - uint8_t *key; - uint16_t keylen; - uint32_t op; - uint8_t state; - uint32_t flags; - uint64_t start; - uint64_t stop; - uint8_t *LVB; - uint16_t LVBlen; - /* stuff for replies.*/ - uint8_t Slave_rpls; /* bitmask of which slaves have replied */ - uint8_t Slave_sent; /* which slaves we sent the update to */ - int idx; /* where to send replies. (index into the pollers) */ - int ret; /* what was the result code of this request? */ - - LLi_t holders; /* Some replies have holders attached. This is - * where they end up. - * Very little uses this right now. - */ - - /* track a couple of extra things when we're keeping history. */ -#ifdef LOCKHISTORY - uint64_t starttime; /* when did we get this request? */ - uint64_t stoptime; /* when did we make it history? */ -#endif -}Waiters_t; -/* uses 83 bytes on 32bits - * 127 bytes on 64bits - * with history on: - * 99 bytes on 32bits - * 143 bytes on 64bits - */ - -typedef struct Holders_s { - LLi_t cl_list; - uint8_t *name; - uint64_t subid; - uint8_t state; - uint64_t start; /* range start */ - uint64_t stop; /* range stop */ - uint32_t flags; - int idx; /* used by the send_drp_req() function. It is a caching of - * the idx offset into the pollers. It is checked to be - * valid before use, and if wrong updated. As such, it - * should be inited to 0 and ignored by others. - */ -} Holders_t; -/* uses 45 on 32bits - * 61 on 64bits - */ - -typedef struct Lock_s { - LLi_t lk_list; - uint8_t *key; - uint8_t keylen; - uint8_t LVBlen; - uint8_t *LVB; - - uint32_t HolderCount; - LLi_t Holders; - uint32_t LVB_holder_cnt; - LLi_t LVB_holders; /* have rights to LVB, mayormaynot have lock state*/ - - uint32_t ExpiredCount; - LLi_t ExpHolders; - - Qu_t Waiters; /* how big this list is depends on lock state */ - Qu_t High_Waiters; /* these have a higher priority than normal reqs.*/ - - Qu_t Action_Waiters; /* Actions sit here until reply_waiter is open */ - Qu_t State_Waiters; - - Waiters_t *reply_waiter; /*where lkrq sit until they get all slave replies.*/ - - -#ifdef LOCKHISTORY - uint32_t Histlen; - Qu_t History; /* If active, we keep the last couple of request - * structs here. for debugging stuff. - * sucks memory like you cannot believe. - */ -#endif - -} Lock_t; -/* uses 122 on 32bits - * 230 on 64bits - * with history on: - * 138 bytes on 32bits - * 258 bytes on 64bits - */ - -/* About the queues in Lock_t - * Yeah, there are a bunch of them. In basic form, there are three queues. - * These are then broken into sub parts, to provide specific features - * within each of the queues. - * - * At the top level: - * The reply_waiter queue. Cleverly disguised as a single pointer. - * This is where a request sits until all of the slave nodes have - * acked that request. - * The Incomming Queue. - * Action_waiters and State_Waiters. - * New requests are put here. No processing of any kind has been done - * yet. (save for a few special cases.) - * The Conflict Queue. - * The Waiters and High_Waiters. - * If the lock request is incompatible with the current state of the - * lock, and must wait for a change before it can be completed, it is - * placed onto this queue. - * - * Then if you are in for some major debugging, you can turn on the History - * queue. This just saves the last couple of lock requests so you can see - * what is happening on the lock. (do a lock dump to see.) This really - * sucks up memory, so you don't want it around unless you are debugging - * something deep. - * - * - */ - -/* from io */ -int init_lt_poller(void); -int open_lt_listener(int port); -int open_lt_to_core(void); -int send_req_lk_reply(Waiters_t *lkrq, Lock_t *lk, uint32_t retcode); -int send_act_lk_reply(Waiters_t *lkrq, uint32_t retcode); -int send_query_reply(Waiters_t *lkrq, uint32_t retcode); -void send_req_update_to_slaves(Waiters_t *lkrq); -void send_act_update_to_slaves(Waiters_t *lkrq); -void send_update_reply_to_master(Waiters_t *lkrq); -void send_drp_req(Lock_t *lk, Waiters_t *lkrq); -void send_drop_all_req(void); -void lt_main_loop(void); - -/* from space */ -int init_lockspace(unsigned long maxlocks, unsigned int hashbuckets); -void dump_locks(void); -int send_stats(xdr_enc_t *enc); -void check_fullness(void); -Waiters_t *get_new_lkrq(void); -void recycle_lkrq(Waiters_t *lkrq); -Waiters_t *duplicate_lkrw(Waiters_t *old); -#ifdef LOCKHISTORY -void record_lkrq(Lock_t *lk, Waiters_t *lkrq); -#endif -void delete_entire_waiters_list( Qu_t *q); -int force_lock_state(Waiters_t *lkrq); -int force_lock_action(Waiters_t *lkrq); -int update_lock_state(Waiters_t *lkrq); -int do_lock_state(Waiters_t *lkrq); -int do_lock_action(Waiters_t *lkrq); -int do_lock_query(Waiters_t *lkrq); -int increment_slave_update_replies(uint8_t *key, uint16_t len, - int slave, uint8_t smask); -void recheck_reply_waiters(uint8_t Slave_bits, uint8_t onlogin); -void expire_locks(uint8_t *name, uint8_t *mask, uint16_t len); -void drop_expired(uint8_t *name, uint8_t *, uint16_t); -void __inline__ rerun_wait_queues(void); -int serialize_lockspace(int fd); -int deserialize_lockspace(int fd); -int list_expired_holders(xdr_enc_t *enc); -int __inline__ compare_holder_waiter_names(Holders_t *h, Waiters_t *w); - -#endif /*__gulm_lock_priv_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/lock_space.c b/gulm/src/lock_space.c deleted file mode 100644 index be78159..0000000 --- a/gulm/src/lock_space.c +++ /dev/null @@ -1,3154 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> -#include <signal.h> - -#include "gulm_defines.h" -#include "hash.h" -#include "LLi.h" -#include "Qu.h" -#include "gio_wiretypes.h" -#include "xdr.h" -#include "lock_priv.h" -#include "utils_tostr.h" -#include "utils_dir.h" -#include "config_gulm.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -extern char *LTname; -extern gulm_config_t gulm_config; - -/*****************************************************************************/ -#ifdef DEBUG_LVB -#define lvb_log_msg(fmt, args...) log_msg(lgm_Always , fmt , ## args ) -#else /*DEBUG_LVB*/ -#define lvb_log_msg(fmt, args...) -#endif /*DEBUG_LVB*/ -/*****************************************************************************/ -/* Not a true maximum. This is actually just the point where we start - * sending dropall requests to the clients. - */ -unsigned long max_locks = 1024 * 1024; - -/* these count the number of holders in each state or type. */ -unsigned long cnt_exl_holds = 0; -unsigned long cnt_shd_holds = 0; -unsigned long cnt_dfr_holds = 0; -unsigned long cnt_lvb_holds = 0; -unsigned long cnt_exp_holds = 0; - -unsigned long cur_lops = 0; -unsigned long cnt_conflicts = 0; - -unsigned long cnt_inq = 0; -unsigned long cnt_confq = 0; -unsigned long cnt_replyq = 0; - -unsigned long cnt_locks = 0; /* aka used_locks */ -unsigned long free_locks = 0; -unsigned long free_lkrqs = 0; -unsigned long used_lkrqs = 0; -unsigned long free_holders = 0; -unsigned long used_holders = 0; -/*****************************************************************************/ -/* global lock store */ -hash_t *AllLocks=NULL; -/* accessors. */ -unsigned char *getlkname(void *item) { - Lock_t *c = (Lock_t*)item; - return c->key; -} -int getlknlen(void *item) { - Lock_t *c = (Lock_t*)item; - return c->keylen; -} - -/* the empties list. - * We keep empties around instead of freeing them. - * Saves mallocs. - */ -LLi_t Free_lkrq; -LLi_t Free_lock; -LLi_t Free_Holders; - -/** - * prealloc_holders - - * Returns: =0:Ok, !0:Error - */ -int prealloc_holders(void) -{ - int i; - Holders_t *h; - for(i=0; i < gulm_config.lt_preholds; i++ ) { - h = malloc(sizeof(Holders_t)); - if( h == NULL ) return -ENOMEM; - LLi_init( &h->cl_list, h ); - LLi_add_after( &Free_Holders, &h->cl_list ); - free_holders ++; - } - return 0; -} - -/** - * prealloc_locks - - * Returns: =0:Ok, !0:Error - */ -int prealloc_locks(void) -{ - int i; - Lock_t *lk; - for(i=0; i < gulm_config.lt_prelocks; i ++ ) { - lk = malloc(sizeof(Lock_t)); - if( lk == NULL ) return -ENOMEM; - LLi_init( &lk->lk_list, lk); - LLi_add_after( &Free_lock, &lk->lk_list ); - free_locks ++; - } - return 0; -} - -/** - * prealloc_lkrq - - * Returns: =0:Ok, !0:Error - */ -int prealloc_lkrqs(void) -{ - int i; - Waiters_t *lkrq; - for(i=0; i < gulm_config.lt_prelkrqs; i++ ) { - lkrq = malloc(sizeof(Waiters_t)); - if( lkrq == NULL ) return -ENOMEM; - LLi_init( &lkrq->wt_list, lkrq ); - LLi_add_after( &Free_lkrq, &lkrq->wt_list ); - free_lkrqs ++; - } - return 0; -} - -/** - * init_lockspace - - * - * Should the size of the locktable hash be configuriable? - * - * Returns: int - */ -int init_lockspace(unsigned long maxlocks, unsigned int hashbuckets) -{ - LLi_init_head(&Free_lkrq); - LLi_init_head(&Free_lock); - LLi_init_head(&Free_Holders); - max_locks = maxlocks; - AllLocks = hash_create(hashbuckets, getlkname, getlknlen); - if( AllLocks == NULL ) return -ENOMEM; - if( prealloc_locks() != 0 ) return -ENOMEM; - if( prealloc_lkrqs() != 0 ) return -ENOMEM; - if( prealloc_holders() != 0 ) return -ENOMEM; - return 0; -} - -/*****************************************************************************/ -/** - * buftob64 - - * @ibuf: - * @ilen: - * @obuf: - * @olen: - * - * - * Returns: char - */ -char *buftob64(uint8_t *ibuf, uint8_t ilen, uint8_t *obuf, uint8_t olen) -{ - static char *b64string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int c; - int i, b=0; - - for(i=0; i < ilen; i++ ) { - c = (ibuf[i] >> 2) & 0x3f; - obuf[b++] = b64string[c]; - c = (ibuf[i] << 4) & 0x3f; - if( ++i < ilen) { - c |= (ibuf[i] >> 4) & 0x0f; - } - obuf[b++] = b64string[c]; - - if( i < ilen ) { - c = (ibuf[i] << 2) & 0x3f; - if( ++i < ilen) { - c |= (ibuf[i] >> 6) & 0x03; - } - obuf[b++] = b64string[c]; - }else{ - ++i; - obuf[b++] = '='; - } - - if( i < ilen ) { - c = ibuf[i] & 0x3f; - obuf[b++] = b64string[c]; - }else{ - obuf[b++] = '='; - } - } - - obuf[b] = '\0'; - - return obuf; -} - -char *lkeytob64(uint8_t *key, uint8_t keylen) -{ - static char buf[256]; - return buftob64(key, keylen, buf, (uint8_t)256); -} - -char *lvbtob64(uint8_t *key, uint8_t keylen) -{ - static char buf[256]; - return buftob64(key, keylen, buf, (uint8_t)256); -} - -/** - * print_wait_queue - - * @FP: - * @w: - */ -void print_waiter(FILE *FP, Waiters_t *w) -{ - fprintf(FP," - key : '%s'\n", lkeytob64(w->key, w->keylen)); - fprintf(FP," name : %s\n", w->name); - fprintf(FP," subid : %"PRIu64"\n", w->subid); - switch(w->state) { -#define CasePrint(x) case (x): fprintf(FP," state : %s\n",#x); break - CasePrint(gio_lck_st_Unlock); - CasePrint(gio_lck_st_Exclusive); - CasePrint(gio_lck_st_Deferred); - CasePrint(gio_lck_st_Shared); -#undef CasePrint - default: fprintf(FP," state : %d(unknown)\n",w->state);break; - } - fprintf(FP," flags : %#x\n", w->flags); - fprintf(FP," start : %"PRIu64"\n", w->start); - fprintf(FP," stop : %"PRIu64"\n", w->stop); - if( w->LVB == NULL ) { - fprintf(FP," LVB :\n"); - }else{ - fprintf(FP," LVB : '%s'\n", lvbtob64(w->LVB, w->LVBlen)); - } - fprintf(FP," Slave_rply : 0x%x\n", w->Slave_rpls); - fprintf(FP," Slave_sent : 0x%x\n", w->Slave_sent); - fprintf(FP," idx : %d\n", w->idx); -#ifdef LOCKHISTORY - fprintf(FP," ret : %d\n", w->ret); - fprintf(FP," starttime : %"PRIu64"\n", w->starttime); - fprintf(FP," stoptime : %"PRIu64"\n", w->stoptime); -#endif -} - -/** - * print_wait_queue - - * @FP: - * @list: - */ -void print_wait_queue(FILE *FP, LLi_t *list) -{ - LLi_t *tp; - Waiters_t *w; - if( ! LLi_empty(list) ) { - for(tp=LLi_next(list);LLi_data(tp) != NULL;tp=LLi_next(tp)){ - w = LLi_data(tp); - print_waiter(FP, w); - } - } -} - -/** - * print_holder - - * @FP: - * @h: - */ -void print_holder(FILE *FP, Holders_t *h) -{ - fprintf(FP," - name : %s\n", h->name); - fprintf(FP," subid : %"PRIu64"\n", h->subid); - fprintf(FP," state : "); - switch(h->state) { -#define CasePrint(x) case (x): fprintf(FP,"%s\n",#x); break - CasePrint(gio_lck_st_Unlock); - CasePrint(gio_lck_st_Exclusive); - CasePrint(gio_lck_st_Deferred); - CasePrint(gio_lck_st_Shared); -#undef CasePrint - default: fprintf(FP,"%d(unknown)\n", h->state); break; - } - fprintf(FP," start : %"PRIu64"\n", h->start); - fprintf(FP," stop : %"PRIu64"\n", h->stop); - fprintf(FP," flags : %#x\n", h->flags); - fprintf(FP," idx : %d\n", h->idx); -} - -/** - * print_holder_list - - * @FP: - * @list: - */ -void print_holder_list(FILE *FP, LLi_t *list) -{ - LLi_t *tp; - Holders_t *h; - - if( ! LLi_empty( list ) ) { - for(tp=LLi_next(list); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - print_holder(FP, h); - } - } -} - -/** - * print_lock - print out a lock - * @lk: < lock struct - * - * for debuggen - * - * output is valid yaml (for parsen) - * - */ -void print_lock(FILE *FP, Lock_t *lk) -{ - fprintf(FP,"---\nkey : '%s'\n", lkeytob64(lk->key, lk->keylen)); - fprintf(FP,"LVBlen : %d\n", lk->LVBlen); - if( lk->LVB == NULL ) { - fprintf(FP,"LVB :\n"); - }else{ - fprintf(FP,"LVB : '%s'\n", lvbtob64(lk->LVB, lk->LVBlen)); - } - fprintf(FP,"HolderCount : %d\n", lk->HolderCount); - - fprintf(FP,"Holders :\n"); - print_holder_list(FP, &lk->Holders); - - fprintf(FP,"LVBHolderCount : %d\n", lk->LVB_holder_cnt); - fprintf(FP,"LVBHolders :\n"); - print_holder_list(FP, &lk->LVB_holders ); - - fprintf(FP,"ExpiredCount : %d\n", lk->ExpiredCount); - fprintf(FP,"ExpiredHolders :\n"); - print_holder_list(FP, &lk->ExpHolders ); - - if( lk->reply_waiter == NULL ) { - fprintf(FP,"reply_waiter :\n"); - }else{ - fprintf(FP, "reply_waiter :\n"); - print_waiter(FP, lk->reply_waiter); - } - - fprintf(FP,"Waiters :\n"); - print_wait_queue(FP, &lk->Waiters); - - fprintf(FP,"High_Waiters :\n"); - print_wait_queue(FP, &lk->High_Waiters); - - fprintf(FP,"Action_Waiters :\n"); - print_wait_queue(FP, &lk->Action_Waiters); - - fprintf(FP,"State_Waiters :\n"); - print_wait_queue(FP, &lk->State_Waiters); - -#ifdef LOCKHISTORY - fprintf(FP,"History :\n"); - print_wait_queue(FP, &lk->History); -#endif -} - -/** - * _dump_locks_ - - * @item: - * @d: - * - * - * Returns: int - */ -int _dump_locks_(LLi_t *item, void *d) -{ - Lock_t *lk; - FILE* fp = (FILE*)d; - - lk = LLi_data(item); - print_lock(fp, lk); - fprintf(fp, "#=================\n"); - return 0; -} - -/** - * dump_locks - - * - * open log file. dump entire locktable out. - * - * Returns: void - */ -void dump_locks(void) -{ - char *c; - FILE *fp; - int fd; - - c = malloc(19 + strlen(LTname) +2); - if( c == NULL ) return; - strcpy(c, "Gulm_LT_Lock_Dump."); - strcat(c, LTname); - - if( (fd=open_tmp_file(c)) < 0 ) return; - if( (fp = fdopen(fd,"a")) == NULL) {free(c); return;} - - fprintf(fp, "# BEGIN LOCK DUMP\n"); - - hash_walk(AllLocks, _dump_locks_, fp); - - fprintf(fp, "# END LOCK DUMP\n"); - fprintf(fp, "#=======================================" - "========================================\n"); - fclose(fp); - free(c); -} - -void dump_holders(char *s, LLi_t *list) -{ - LLi_t *tp; - Holders_t *h; - if( ! LLi_empty( list ) ) { - for(tp=LLi_next(list); LLi_data(tp)!= NULL; tp=LLi_next(tp)){ - h = LLi_data(tp); -#ifdef DEBUG - fprintf(stderr,"EXTRA %s name = %s\n", s, h->name); -#else - syslog(LOG_NOTICE,"EXTRA %s name = %s\n", s, h->name); -#endif - } - } -} - -/** - * estimate_lockspace_size - - * - * kernel ppl don't seem to be interested in maintaining the memory fields - * in getrusage, so we have to estimate this. - * - * It is rather painful to try and get everything, so this is just the - * lockspace. - * - * This does not include space used by io buffers, stacks, keynames, LVBs, - * or holder names. Making it a rather poor estimate. - * - * Returns: long - */ -unsigned long estimate_lockspace_size(void) -{ - unsigned long acc; - acc = sizeof(Lock_t) * cnt_locks; - acc += sizeof(Lock_t) * free_locks; - acc += sizeof(Waiters_t) * used_lkrqs; - acc += sizeof(Waiters_t) * free_lkrqs; - acc += sizeof(Holders_t) * used_holders; - acc += sizeof(Holders_t) * free_holders; - return acc; -} - -/** - * send_stats - - * @enc: - * - * The reply code and list start are sent before this function is called. - * And the list stop will be sent when after this returns. - * - * Returns: int - */ -int send_stats(xdr_enc_t *enc) -{ - int err; - char tmp[256]; - - if((err = xdr_enc_string(enc, "exclusive")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_exl_holds); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "shared")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_shd_holds); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "deferred")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_dfr_holds); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "lvbs")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_lvb_holds); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "expired")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_exp_holds); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "lock ops")) != 0) return err; - snprintf(tmp, 256, "%lu", cur_lops); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "conflicts")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_conflicts); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "incomming_queue")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_inq); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "conflict_queue")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_confq); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "reply_queue")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_replyq); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "free_locks")) != 0) return err; - snprintf(tmp, 256, "%lu", free_locks); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "used_locks")) != 0) return err; - snprintf(tmp, 256, "%lu", cnt_locks); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "free_lkrqs")) != 0) return err; - snprintf(tmp, 256, "%lu", free_lkrqs); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "used_lkrqs")) != 0) return err; - snprintf(tmp, 256, "%lu", used_lkrqs); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "free_holders")) != 0) return err; - snprintf(tmp, 256, "%lu", free_holders); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "used_holders")) != 0) return err; - snprintf(tmp, 256, "%lu", used_holders); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "elss")) != 0) return err; - snprintf(tmp, 256, "%lu", estimate_lockspace_size()); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - if((err = xdr_enc_string(enc, "highwater")) != 0) return err; - snprintf(tmp, 256, "%lu", max_locks); - if((err = xdr_enc_string(enc, tmp)) != 0) return err; - - return 0; -} - -/*****************************************************************************/ -/** - * count_list - - * @l: - * - * count how many items there are in a LLi list. - * Needed so I can add some checks to try and find out when the list and - * the counters I maintain get out of sync. - * - * Returns: int - */ -int count_list(LLi_t *l) -{ - LLi_t *tp; - int cnt=0; - for(tp=LLi_next(l); LLi_data(tp) != NULL; tp=LLi_next(tp)) cnt++; - return cnt; -} -/*****************************************************************************/ -/* there are three lists that are made of Holders_t elements. Here is one - * set of base functions to manipulate those lists, with some thin wrappers - * to twist the other bits. (counts, and lvb buffer.) - */ - -/** - * get_new_holder - - * - * Returns: Holders_t - */ -Holders_t *get_new_holder(void) -{ - Holders_t *h; - if( LLi_empty( &Free_Holders ) ) { - h = malloc(sizeof(Holders_t)); - }else{ - LLi_t *tmp; - tmp = LLi_pop( &Free_Holders ); - LLi_unhook( tmp ); - h = LLi_data(tmp); - free_holders --; - } - if( h == NULL ) return NULL; - memset(h, 0, sizeof(Holders_t)); - used_holders ++; - return h; -} - -/** - * recycle_holder - - * @h: - */ -void recycle_holder(Holders_t *h) -{ - LLi_t *tp; - if( h->name != NULL ) {free(h->name); h->name = NULL;} - LLi_unhook(&h->cl_list); - LLi_add_before( &Free_Holders, &h->cl_list ); - used_holders --; - free_holders ++; - /* only keep a limited number of free holders around */ - if(free_holders > gulm_config.lt_preholds) { - tp = LLi_prev(&Free_Holders); - LLi_del(tp); - h = LLi_data(tp); - free(h); - free_holders --; - } -} - -/** - * duplicate_holder - - * @old: - * - * - * Returns: Holders_t - */ -Holders_t *duplicate_holder(Holders_t *old) -{ - Holders_t *new; - new = get_new_holder(); - if( new == NULL ) return NULL; - LLi_init( &new->cl_list, new ); - new->name = strdup(old->name); - if( new->name == NULL ) { recycle_holder(new); return NULL; } - new->subid = old->subid; - new->state = old->state; - new->start = old->start; - new->stop = old->stop; - new->flags = old->flags; - new->idx = old->idx; - return new; -} - -/** - * compare_names_subids - - * @nA: - * @sA: - * @nB: - * @sB: - * - * compares the names, including the optional subid - * - * if names are equal - * and - * subids are NULL - * or - * both subids are not null - * and - * subids match - * - * Returns: TRUE if equal, FALSE if not - */ -int __inline__ compare_names_subids(uint8_t *nA, uint64_t sA, uint8_t *nB, uint64_t sB) -{ - return ( strcmp(nA, nB) == 0 && sA == sB ); -} -int __inline__ compare_holder_waiter_names(Holders_t *h, Waiters_t *w) -{ - return compare_names_subids(h->name, h->subid, w->name, w->subid); -} -int __inline__ compare_waiter_waiter_names(Waiters_t *h, Waiters_t *w) -{ - return compare_names_subids(h->name, h->subid, w->name, w->subid); -} -int __inline__ compare_holder_holder_names(Holders_t *h, Holders_t *w) -{ - return compare_names_subids(h->name, h->subid, w->name, w->subid); -} - -/** - * add_holder_to_list - - * @name: - * @list: - * - * - * Returns: 0:Ok, <0:Error; - */ -int add_holder_to_list(uint8_t *name, LLi_t *list) -{ - Holders_t *h; - - h = get_new_holder(); - if( h == NULL ) return -1; - - LLi_init( &h->cl_list, h ); - h->name = strdup(name); - h->idx = 0; - if( h->name == NULL ) { - recycle_holder(h); - return -1; - } - - LLi_add_after( list, &h->cl_list); - return 0; -} - -/** - * have_holder_in_list - - * @name: - * @list: - * - * - * Returns: TRUE or FALSE - */ -int have_holder_in_list(uint8_t *name, LLi_t *list) -{ - LLi_t *tp; - Holders_t *h; - - if( ! LLi_empty( list ) ) { - for(tp=LLi_next(list); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if( strcmp(h->name, name) == 0 ) { - return TRUE; - } - } - } - return FALSE; -} - -/** - * remove_holder_from_list - - * @name: - * @list: - * - * returns TRUE if name was in list. - * - * Returns: TRUE or FALSE - */ -int remove_holder_from_list(uint8_t *name, LLi_t *list) -{ - LLi_t *tp; - Holders_t *h; - - if( ! LLi_empty( list ) ) { - for(tp=LLi_next(list); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if( strcmp(h->name, name) == 0 ) { - LLi_del(tp); - recycle_holder(h); - return TRUE; - } - } - } - return FALSE; -} - -/** - * delete_entire_holder_list - - * @list: - */ -void delete_entire_holder_list(LLi_t *list) -{ - Holders_t *h; - while( ! LLi_empty( list ) ) { - h = LLi_data( LLi_next( list ) ); - LLi_del( LLi_next( list ) ); - recycle_holder(h); - } -} - -/*****************************************************************************/ -/** - * increment_global_state_counters - - * @state: - * - * - * Returns: void - */ -void increment_global_state_counters(int state) -{ - switch(state) { - case gio_lck_st_Exclusive: cnt_exl_holds++; break; - case gio_lck_st_Deferred: cnt_dfr_holds++; break; - case gio_lck_st_Shared: cnt_shd_holds++; break; - } -} -/** - * decrement_global_state_counters - - * @state: - * - * - * Returns: void - */ -void decrement_global_state_counters(int state) -{ - switch(state) { - case gio_lck_st_Exclusive: cnt_exl_holds--; break; - case gio_lck_st_Deferred: cnt_dfr_holds--; break; - case gio_lck_st_Shared: cnt_shd_holds--; break; - } -} -/*****************************************************************************/ - - -/** - * add_to_holders - - * @lk: - * @lkrq: - * - * - * Returns: int - */ -int add_to_holders(Lock_t *lk, Waiters_t *lkrq) -{ - Holders_t *h; - - h = get_new_holder(); - if( h == NULL ) return -1; - LLi_init( &h->cl_list, h ); - h->name = strdup(lkrq->name); - if( h->name == NULL ) { - recycle_holder(h); - return -1; - } - h->subid = lkrq->subid; - h->idx = lkrq->idx; - h->state = lkrq->state; - h->start = lkrq->start; - h->stop = lkrq->stop; - h->flags = lkrq->flags; - - increment_global_state_counters(h->state); - - LLi_add_after( &lk->Holders, &h->cl_list); - lk->HolderCount++; - return 0; -} - -/** - * check_for_holder - - * @lk: - * @lkrq: - * - * - * Returns: int - */ -int check_for_holder(Lock_t *lk, Waiters_t *lkrq) -{ - LLi_t *tp; - Holders_t *h; - - if( ! LLi_empty( &lk->Holders ) ) { - for(tp=LLi_next(&lk->Holders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if( compare_holder_waiter_names(h, lkrq) ) { - return TRUE; - } - } - } - return FALSE; -} - -/** - * drop_holder - - * @lk: - * @lkrq: - * - * - * Returns: int - */ -int drop_holder(Lock_t *lk, Waiters_t *lkrq) -{ - LLi_t *tp; - Holders_t *h; - - if( ! LLi_empty( &lk->Holders ) ) { - for(tp=LLi_next(&lk->Holders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if( compare_holder_waiter_names(h, lkrq) ) { - LLi_del(tp); - lk->HolderCount--; - decrement_global_state_counters(h->state); - recycle_holder(h); - return 0; - } - } - } - return -1; -} - - -/*****************************************************************************/ -/** - * move_to_Expholders - - * @h: - * @lk: - * - * Move Holder h, to the Expired list. - * - * Returns: int - */ -int move_to_Expholders(Holders_t *h, Lock_t *lk) -{ - LLi_unhook(&h->cl_list); - LLi_add_after( &lk->ExpHolders, &h->cl_list ); - lk->ExpiredCount++; - cnt_exp_holds ++; - return 0; -} - -/** - * check_for_expholder - - * @hld: - * @lk: - * - * - * Returns: int - */ -int check_for_expholder(Holders_t *hld, Lock_t *lk) -{ - LLi_t *tp; - Holders_t *h; - - if( ! LLi_empty( &lk->ExpHolders ) ) { - for(tp=LLi_next(&lk->ExpHolders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if( compare_holder_holder_names(h, hld) ) { - return TRUE; - } - } - } - return FALSE; -} - -/** - * drop_expholders - - * @name: - * @lk: - * - * This drops every exp holder with matching name. - * subids are ignored here. - * - * Returns: int - */ -int drop_expholders(uint8_t *name, Lock_t *lk) -{ - LLi_t *tmp,*next; - Holders_t *h; - int ret = FALSE; - - for(tmp = LLi_next(&lk->ExpHolders); LLi_data(tmp) != NULL; tmp = next) { - next = LLi_next(tmp); - h = LLi_data(tmp); - if( strcmp(name, h->name) == 0) { - LLi_del(tmp); - recycle_holder(h); - lk->ExpiredCount--; - cnt_exp_holds --; - ret = TRUE; - } - } - return ret; -} - -/*****************************************************************************/ -/** - * add_to_LVB_holders - - * @name: - * @lk: - * - * - * Returns: int - */ -int add_to_LVB_holders(uint8_t *name, Lock_t *lk) -{ -#define FIRST_LVB_SIZE (32) /* gotta start somewhere. */ - lvb_log_msg("Adding %s to LVB holders for lock (%s)\n", - name, lkeytob64(lk->key, lk->keylen)); - - if( add_holder_to_list(name, &lk->LVB_holders) != 0 ) - return -1; - - lk->LVB_holder_cnt++; - cnt_lvb_holds++; - if( lk->LVB_holder_cnt == 1 ) { /* first lvb hold */ - lk->LVBlen = FIRST_LVB_SIZE; - if( lk->LVB == NULL ) { - lk->LVB = malloc(FIRST_LVB_SIZE); - if( lk->LVB == NULL ) die(ExitGulm_NoMemory, "No memory left."); - } - memset( lk->LVB, 0, FIRST_LVB_SIZE); - lvb_log_msg( "Zeroing LVB (%s) First holder, for %s\n", - lkeytob64(lk->key, lk->keylen), name); - } - return 0; -#undef FIRST_LVB_SIZE -} - -/** - * check_for_LVB_holder - - * @name: - * @lk: - * - * - * Returns: TRUE or FALSE - */ -int __inline__ check_for_LVB_holder(uint8_t *name, Lock_t *lk) -{ return have_holder_in_list(name, &lk->LVB_holders); } - -/** - * drop_LVB_holder - - * @name: - * @lk: - * - * - * Returns: int - */ -int drop_LVB_holder(uint8_t *name, Lock_t *lk) -{ - lvb_log_msg("Dropping %s from LVB holders for lock (%s)\n", - name, lkeytob64(lk->key, lk->keylen)); - - if(remove_holder_from_list(name, &lk->LVB_holders)) { - lk->LVB_holder_cnt--; - cnt_lvb_holds--; - if( lk->LVB_holder_cnt == 0) { - lk->LVBlen = 0; /* no more lvb holders */ - if( lk->LVB != NULL ) {free(lk->LVB); lk->LVB = NULL;} - } - return 0; - } - return -1; -} - -/** - * lvbcpy - - * @lk: - * @lkrq: - * - * This copies a LVB into a Lock struct from the request struct. Since - * this action could cause the resizing of the LVB in the lock struct, we - * need to make sure of a few things. - * - */ -void lvbcpy(Lock_t *lk, Waiters_t *lkrq) -{ - if( lk->LVB == NULL || lkrq->LVB == NULL || lkrq->LVBlen == 0 ) { - /* skip */ - return; - }else - if( lk->LVBlen == lkrq->LVBlen ) { - memcpy(lk->LVB, lkrq->LVB, lk->LVBlen); - }else - if( lk->LVBlen != lkrq->LVBlen ) { /* handle grows or shrinks. */ - uint8_t *c; - c = realloc(lk->LVB, lkrq->LVBlen); - if( c == NULL ) { - die(ExitGulm_NoMemory, "Out of memory in LVB resize\n"); - } - lk->LVB = c; - lk->LVBlen = lkrq->LVBlen; - memcpy(lk->LVB, lkrq->LVB, lk->LVBlen); - } - lvb_log_msg("For %s, Lock %s: Saved LVB %s\n", - lkrq->name, lkeytob64(lk->key,lk->keylen), - lvbtohex(lk->LVB, lk->LVBlen)); -} - -/*****************************************************************************/ - -/** - * find_lock - - * @key: - * - * Should always return a lock. If its not in the tables, adds it. - * - * This should be designed such that it always works. (pre-allocate and - * stuff.) someday, maybe... - * - * Returns: Lock_t - */ -Lock_t *find_lock(uint8_t *key, uint8_t keylen) -{ - LLi_t *tmp; - Lock_t *lk; - int ret; - -#if 0 - log_bug("Searching for key %s \n", lkeytob64(key)); -#endif - - tmp = hash_find(AllLocks, key, keylen); - if( tmp == NULL ) { - if( LLi_empty( &Free_lock ) ) { - lk = malloc(sizeof(Lock_t)); - }else{ - tmp = LLi_pop( &Free_lock ); - LLi_unhook( tmp ); - lk = LLi_data( tmp ); - free_locks --; - } - if( lk == NULL ) - die(ExitGulm_NoMemory, - "Failed to malloc new lock.\n"); - memset(lk, 0, sizeof(Lock_t)); - lk->key = malloc(keylen); - if( lk->key == NULL ) - die(ExitGulm_NoMemory, - "Failed to malloc new key.\n"); - memcpy(lk->key, key, keylen); - lk->keylen = keylen; - lk->LVBlen = 0; - lk->LVB = NULL; - lk->HolderCount = 0; - lk->ExpiredCount = 0; - lk->LVB_holder_cnt = 0; - lk->reply_waiter = NULL; - - LLi_init( &lk->lk_list, lk); - LLi_init_head( &lk->Holders ); - LLi_init_head( &lk->ExpHolders ); - LLi_init_head( &lk->LVB_holders ); - Qu_init_head( &lk->Waiters ); - Qu_init_head( &lk->High_Waiters ); - Qu_init_head( &lk->Action_Waiters ); - Qu_init_head( &lk->State_Waiters ); - -#ifdef LOCKHISTORY - lk->Histlen = 0; - Qu_init_head( &lk->History ); -#endif - - if( (ret=hash_add(AllLocks, &lk->lk_list)) <0) { - dump_locks(); - die(ExitGulm_NoMemory, - "Failed to add new key(%s). Should never happen.(%d)\n", - lkeytob64(key, keylen), ret); - } - cnt_locks++; - } else { - lk = LLi_data(tmp); - } - - return lk; -} - -/** - * check_for_recycle - if no refs left, free. - * @lk: - * - * It is quite wise to run the wait Qu **before** you call this. - * - * Returns: void - */ -void check_for_recycle(Lock_t *lk) -{ - LLi_t *temp; - Lock_t *chck; - - GULMD_ASSERT( lk != NULL , ); - GULMD_ASSERT( lk->key != NULL , ); - - if( lk->HolderCount == 0 && - lk->ExpiredCount == 0 && - lk->LVB_holder_cnt == 0 && - Qu_empty( &lk->Waiters ) && - Qu_empty( &lk->High_Waiters ) && - Qu_empty( &lk->Action_Waiters ) && - Qu_empty( &lk->State_Waiters ) && -#ifdef LOCKHISTORY - Qu_empty( &lk->History ) && -#endif - lk->reply_waiter == NULL ) - { - /* Should I die here? Or should I print out warnings, and just - * stop the recycle? - * If these fail, you have memory problems. we will die. - */ - - dump_holders("Holder", &lk->Holders); - dump_holders("ExpHolder", &lk->ExpHolders); - dump_holders("LVBHolder", &lk->LVB_holders); - - GULMD_ASSERT( LLi_empty( &lk->Holders ), - log_msg(lgm_Always, "lk: %s\n", lkeytob64(lk->key, lk->keylen)); - dump_locks(); - ); - GULMD_ASSERT( LLi_empty( &lk->ExpHolders ), - log_msg(lgm_Always, "lk: %s\n", lkeytob64(lk->key, lk->keylen)); - dump_locks(); - ); - GULMD_ASSERT( LLi_empty( &lk->LVB_holders ), - log_msg(lgm_Always, "lk: %s\n", lkeytob64(lk->key, lk->keylen)); - dump_locks(); - ); - - temp = hash_del(AllLocks, lk->key, lk->keylen); - chck = LLi_data(temp); - GULMD_ASSERT( chck == lk, ); - - /* everything is as it should be. */ - if( lk->LVB ) {free( lk->LVB ); lk->LVB = NULL;} - free(lk->key); - lk->key = NULL; - /* stick it onto the free lock list */ - LLi_unhook( &lk->lk_list ); - LLi_add_before( &Free_lock, &lk->lk_list ); - cnt_locks--; - free_locks ++; - - /* only keep a limited number of free structs around. */ - if(free_locks > gulm_config.lt_prelocks) { - temp = LLi_prev(&Free_lock); - LLi_del(temp); - chck = LLi_data(temp); - free(chck); - free_locks --; - } - } -} - -/** - * get_new_lkrq - - * - * - * Returns: Waiter_t - */ -Waiters_t *get_new_lkrq(void) -{ - Waiters_t *lkrq; - LLi_t *tmp; - if( LLi_empty(&Free_lkrq) ) { - lkrq = malloc(sizeof(Waiters_t)); - if( lkrq == NULL ) return NULL; - }else{ - tmp = LLi_pop(&Free_lkrq); - LLi_unhook( tmp ); - lkrq = LLi_data(tmp); - free_lkrqs --; - } - used_lkrqs ++; - memset(lkrq, 0, sizeof(Waiters_t)); /* HAS to be 0 !!! */ - LLi_init( &lkrq->wt_list, lkrq); - LLi_init_head( &lkrq->holders ); - lkrq->idx = -1; -#ifdef LOCKHISTORY - { - struct timeval tv; - gettimeofday(&tv, NULL); - lkrq->starttime = tvs2uint64(tv); - } -#endif - - return lkrq; -} - -/** - * recycle_lkrq - - * @lkrq: - */ -void recycle_lkrq(Waiters_t *lkrq) -{ - LLi_unhook( &lkrq->wt_list ); - if( lkrq->name != NULL ) {free(lkrq->name);lkrq->name = NULL;} - if( lkrq->key != NULL ) {free(lkrq->key);lkrq->key = NULL;} - lkrq->keylen = 0; - if( lkrq->LVB != NULL ) {free(lkrq->LVB);lkrq->LVB = NULL;} - lkrq->LVBlen = 0; - lkrq->idx = -1; - - delete_entire_holder_list(&lkrq->holders); - - LLi_add_before( &Free_lkrq, &lkrq->wt_list ); - used_lkrqs --; - free_lkrqs ++; - - /* don't keep too many free structs around. */ - if( free_lkrqs > gulm_config.lt_prelkrqs ) { - LLi_t *tmp; - Waiters_t *l; - tmp = LLi_prev(&Free_lkrq); - LLi_del(tmp); - l = LLi_data(tmp); - free(l); - free_lkrqs --; - } -} - -/** - * duplicate_lkrw - - * @old: - * - * creates a new chunk of memory that is an excate copy of the lkrq passed - * in. - * - * Because sometimes, you need to take both forks in the road. - * - * Returns: Waiters_t - */ -Waiters_t *duplicate_lkrw(Waiters_t *old) -{ - Waiters_t *new; - new = get_new_lkrq(); - if( new == NULL ) return NULL; - new->name = strdup( old->name ); - if( new->name == NULL ) goto fail; - new->key = malloc(old->keylen); - if( new->key == NULL ) goto fail; - memcpy(new->key, old->key, old->keylen); - new->keylen = old->keylen; - new->subid = old->subid; - new->op = old->op; - new->state = old->state; - new->start = old->start; - new->stop = old->stop; - new->flags = old->flags; - new->LVB = malloc(old->LVBlen); - if( new->LVB == NULL ) goto fail; - memcpy(new->LVB, old->LVB, old->LVBlen); - new->LVBlen = old->LVBlen; - new->Slave_rpls = old->Slave_rpls; - new->Slave_sent = old->Slave_sent; - new->idx = old->idx; - new->ret = old->ret; - - /* we don't dup holders right now. Current usage of the holders on lkrq - * doesn't need it. If things need it later, it can be added then. - * (get_new_lkrq() initialized that field to empty, so we can just leave - * it.) - */ - - return new; -fail: - recycle_lkrq(new); - return NULL; -} - -#ifdef LOCKHISTORY -/** - * record_lkrq - - * @lk: - * @lkrq: - * - * record this lock req in this lock's history. - * typically, this should get called instead of recycle_lkrq() when you - * want to save lock history. - * - * Arranged, so that the dumps show the most current request at the top of - * the dump. - * - * Returns: void - */ -void record_lkrq(Lock_t *lk, Waiters_t *lkrq) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - - LLi_unhook( &lkrq->wt_list ); - lkrq->stoptime = tvs2uint64(tv); - LLi_add_after( &lk->History, &lkrq->wt_list ); - lk->Histlen ++; - - /* keep it from getting too long */ - if( lk->Histlen > LOCKHISTORY ) { - LLi_t *tmp; - Waiters_t *w; - - tmp = LLi_prev( &lk->History ); - LLi_del(tmp); - LLi_unhook(tmp); - lk->Histlen --; - w = LLi_data(tmp); - recycle_lkrq(w); - } -} -#endif /*LOCKHISTORY*/ - -/** - * delete_entire_waiters_list - - * @q: - * - * blindly wipes out a waiters queue. - * - */ -void delete_entire_waiters_list( Qu_t *q) -{ - Waiters_t *w; - while( !Qu_empty( q ) ) { - w = Qu_data( Qu_DeQu( q ) ); - recycle_lkrq(w); - } -} - -/** - * reset_lockstruct - - * @lk: - * - * makes an existing lock struct look like a freshly allocated one. - * basically clear everything except the key. - * - */ -void reset_lockstruct(Lock_t *lk) -{ - lk->LVBlen = 0; - if( lk->LVB != NULL ) {free(lk->LVB);lk->LVB=NULL;} - lk->HolderCount = 0; - lk->ExpiredCount = 0; - lk->LVB_holder_cnt = 0; - - delete_entire_holder_list( &lk->Holders ); - delete_entire_holder_list( &lk->ExpHolders ); - delete_entire_holder_list( &lk->LVB_holders ); - - delete_entire_waiters_list( &lk->Waiters ); - delete_entire_waiters_list( &lk->High_Waiters ); - delete_entire_waiters_list( &lk->Action_Waiters ); - delete_entire_waiters_list( &lk->State_Waiters ); - -#ifdef LOCKHISTORY - lk->Histlen = 0; - delete_entire_waiters_list( &lk->History ); -#endif - - if( lk->reply_waiter != NULL ) { - recycle_lkrq(lk->reply_waiter); - lk->reply_waiter = NULL; - } - -} - -/** - * _clear_lockspace_ - - * @item: - * @misc: - * - * delete a lock using previously written functions. - * - * Returns: int - */ -int _clear_lockspace_(LLi_t *item, void *misc) -{ - Lock_t * lk = LLi_data(item); - reset_lockstruct(lk); - check_for_recycle(lk); - return 0; -} - -/** - * clear_lockspace - - * - * wipe out all locks and reset counters and such. - * - */ -void clear_lockspace(void) -{ - /* empty lock space. */ - hash_walk(AllLocks, _clear_lockspace_, NULL); - - /* reset counters. */ - cnt_locks = 0; - cnt_exl_holds = 0; - cnt_shd_holds = 0; - cnt_dfr_holds = 0; - cnt_lvb_holds = 0; - cnt_exp_holds = 0; - cnt_inq = 0; - cnt_confq = 0; - cnt_replyq = 0; -} - -/** - * check_fullness - - */ -void check_fullness(void) -{ - static unsigned long last_secs = 0; - struct timeval tv; - if( cnt_locks > max_locks ) { - gettimeofday(&tv, NULL); - if( last_secs + gulm_config.lt_cf_rate < tv.tv_sec ) { - log_msg(lgm_Always, - "Lock count is at %ld which is more than the max %ld. " - "Sending Drop all req to clients\n", cnt_locks, max_locks); - send_drop_all_req(); - last_secs = tv.tv_sec; - } - } -} - -/*****************************************************************************/ -/** - * drop_holder_by_range - - * @lk: - * @lkrq: - * - * For every holder that matches name, shrink/split/drop - * - * Note that the order of the range check below is important. Certain - * cases are know not to exist as things fall down the checks. (for - * example, we know that by the time we get the the shrink operations, that - * we won't be setting a holder to have a start after its stop. Because if - * it was that close, it got matched above by a drop.) - * - * This may not be the most efficent impementation, but we can always fix - * that later. - * - * Returns: int - */ -int drop_holder_by_range(Lock_t *lk, Waiters_t *lkrq) -{ - LLi_t *tp,*nxt; - Holders_t *h; - int ret = -1; - - if( ! LLi_empty( &lk->Holders ) ) { - for(tp=LLi_next(&lk->Holders); LLi_data(tp) != NULL; tp = nxt ) { - nxt = LLi_next(tp); - h = LLi_data(tp); - if( compare_holder_waiter_names(h, lkrq) ) { - /* alright, matching name. now, does it over lap? */ - - /* Drop holder */ - /* |-- lkrq --| - * |- h -| - */ - if( lkrq->start < h->start && - lkrq->start < h->stop && - lkrq->stop > h->start && - lkrq->stop > h->stop ) { - LLi_del(tp); - lk->HolderCount--; - decrement_global_state_counters(h->state); - recycle_holder(h); - ret = 0; - }else - /* |- lkrq -| - * |-- h ---| - */ - if( lkrq->start == h->start && - lkrq->stop == h->stop ) { - LLi_del(tp); - lk->HolderCount--; - decrement_global_state_counters(h->state); - recycle_holder(h); - ret = 0; - }else - /* |- lkrq -| - * |- h -| - */ - if( lkrq->start < h->start && - lkrq->start < h->stop && - lkrq->stop > h->start && - lkrq->stop == h->stop ) { - LLi_del(tp); - lk->HolderCount--; - decrement_global_state_counters(h->state); - recycle_holder(h); - ret = 0; - }else - /* |- lkrq -| - * |- h -| - */ - if( lkrq->start == h->start && - lkrq->start < h->stop && - lkrq->stop > h->start && - lkrq->stop > h->stop ) { - LLi_del(tp); - lk->HolderCount--; - decrement_global_state_counters(h->state); - recycle_holder(h); - ret = 0; - }else - - /* Shrink holder */ - /* |-- lkrq --| - * |---------- h -| - */ - /* |-- lkrq --| - * |- h -| - */ - if( lkrq->start <= h->start && - lkrq->start < h->stop && - lkrq->stop > h->start && - lkrq->stop < h->stop ) { - h->start = lkrq->stop + 1; - ret = 0; - }else - /* |-- lkrq --| - * |- h -------| - */ - /* |-- lkrq --| - * |- h -| - */ - if( lkrq->start > h->start && - lkrq->start < h->stop && - lkrq->stop > h->start && - lkrq->stop >= h->stop ) { - h->stop = lkrq->start - 1; - ret = 0; - }else - - /* Split Holder */ - /* |- lkrq -| - * |----- h -----| - * N O - */ - if( lkrq->start > h->start && - lkrq->start < h->stop && - lkrq->stop > h->start && - lkrq->stop < h->stop ) { - Holders_t *new; - new = get_new_holder(); - LLi_init( &new->cl_list, new); - new->name = strdup(h->name); - GULMD_ASSERT(new->name != NULL, ); - new->subid = h->subid; - new->idx = h->idx; - new->state = h->state; - new->flags = h->flags; - new->start = h->start; - new->stop = lkrq->start - 1; - - increment_global_state_counters(new->state); - LLi_add_before( &h->cl_list, &new->cl_list); - lk->HolderCount++; - - h->start = lkrq->stop + 1; - ret = 0; - } - - /* No overlap */ - /* |-- lkrq --| - * |- h -| - */ - /* |-- lkrq --| - * |- h -| - */ - /* Don't need to actually match these, just let things cycle to - * the next in the list. - */ - - }/*compare_holder_waiter_names(h, lkrq)*/ - }/*for()*/ - }/*! LLi_empty( &lk->Holders )*/ - return ret; -} - -/** - * conflict_queue_empty - - * @lk: - * - * - * Returns: TRUE or FALSE - */ -int __inline__ conflict_queue_empty(Lock_t *lk) -{ - return Qu_empty(&lk->Waiters) && Qu_empty(&lk->High_Waiters); -} - -/* State conflict table. - * is A compatible with B? - * (sct[A] >> B) & 0x1 - */ -uint32_t state_conflict_table[] = { - /* unlock */ 0xffffffff, /* unlock is compatible with everything. */ - /* exl */ 0x00000000, /* not compat with anyone. */ - /* shr */ 0x00000004, /* only with other shares */ - /* dfr */ 0x00000008 /* only with other defers */ -}; - -/** - * Do_Holder_Waiter_conflict - - * @h: - * @w: - * - * - * Returns: TRUE if conflict, FALSE if compatible. - */ -int Do_Holder_Waiter_conflict(Holders_t *h, Waiters_t *w) -{ - /* if ranges do not over lap, no conflict. */ - if( h->start > w->stop || h->stop < w->start ) return FALSE; - - /* if overlap, and same name, no conflict */ /* its a xmot */ - if( compare_holder_waiter_names(h,w) ) return FALSE; - - /* if overlap, different names, but compatible states, no conflict */ - if( (state_conflict_table[h->state] >> w->state) & 0x1 ) return FALSE; - - return TRUE; -} - -/** - * check_for_conflict - - * @lk: - * @lkrq: - * - * does this lock request conflist with any existing holders? - * - * stop after first found. Only need one conflict for this check. - * - * Returns: TRUE if conflict, FALSE if compatible. - */ -int check_for_conflict(Lock_t *lk, Waiters_t *lkrq) -{ - LLi_t *tp; - Holders_t *h; - - if( !LLi_empty(&lk->Holders) ) { - for(tp = LLi_next(&lk->Holders); - NULL != LLi_data(tp); - tp = LLi_next(tp)) { - h = LLi_data(tp); - if( Do_Holder_Waiter_conflict(h,lkrq) ) return TRUE; - } - } - - return FALSE; /* no conflicts. */ -} - -/** - * send_lock_success - - * @lk: - * @lkrq: - * - * - * Returns: void - */ -int send_lock_success(Lock_t *lk, Waiters_t *lkrq) -{ - if( gulm_config.fog ) { - lk->reply_waiter = lkrq; - cnt_replyq ++; - send_req_update_to_slaves(lkrq); - return 1; /* gotta wait for the reply_waiter to get flushed. */ - }else{ - send_req_lk_reply(lkrq, lk, gio_Err_Ok); - } - return 0; -} - -/** - * send_Try_Failed - - * @lk: - * @lkrq: - * - * - * Returns: void - */ -void send_Try_Failed(Lock_t *lk, Waiters_t *lkrq) -{ - lkrq->flags &= ~gio_lck_fg_Cachable; - if( lkrq->flags & gio_lck_fg_Do_CB ) - send_drp_req(lk, lkrq); - send_req_lk_reply(lkrq, lk, gio_Err_TryFailed); -} - -/** - * put_onto_conflict_queue - - * @lk: - * @lkrq: - * - * - * Returns: void - */ -void put_onto_conflict_queue(Lock_t *lk, Waiters_t *lkrq) -{ - if( lkrq->flags & gio_lck_fg_NoExp || lkrq->flags & gio_lck_fg_Piority ) { - Qu_EnQu(&lk->High_Waiters, &lkrq->wt_list); - }else{ - Qu_EnQu(&lk->Waiters, &lkrq->wt_list); - } - cnt_confq ++; - cnt_conflicts ++; -} - -/** - * requeue_conflict - - * @lk: - * @lkrq: - * - * - * Returns: void - */ -void requeue_conflict(Lock_t *lk, Waiters_t *lkrq) -{ - /* push back onto front. We'll try again later. */ - if((lkrq->flags & gio_lck_fg_Piority) || (lkrq->flags & gio_lck_fg_NoExp)){ - Qu_EnQu_Front( &lk->High_Waiters, &lkrq->wt_list ); - }else{ - Qu_EnQu_Front( &lk->Waiters, &lkrq->wt_list ); - } - cnt_confq++; - /* Next lock on Qu is incompatible. - * Send a drop request to the current holder. - */ - /* send drop reqs may have to change to work with ranges. XXX */ - send_drp_req(lk, lkrq); -} - -/** - * check_for_any_flag - - * @lk: - * @lkrq: - * - * Handle the Any flag. Very much a GFS-ism. - * - * this may have to change to work with ranges. XXX - * - * Jon had a neat idea for something that would replace the anyflag. - * Basically, lock states/modes are now a bit field. And you can ask for - * multiple modes at once. What it means is 'give me the best mode of the - * ones I asked for' So any would be replaced with (shr|dfr), more - * interesting is the cases where things like (exl|shr|dfr). And even more - * so if more states are added. - * - * Implementing this idea would replace this funtion. The whole concept of - * the any flag would get dropped. (maybe kept in libgulm, which would just - * change it to this.) - * - * I think the code in check_for_conflict() would only really need to - * change. check_for_conflict() could return either a failure (eveything - * asked for conflicts.) or the best mode that would let the request - * succede. - * - * damn, if that is all that it is, that would be way cleaner than this - * icky anyflag code. - * - * its not just that. basicly, conflict check returns a bit field that - * describes which states are held by all holders of this lock. (it also - * returns true/false if the req is compatible.) there needs to be another - * function, that takes this bit field and the req states field, and - * determins which state this req will get. - * - * still not too bad. Only major part is going through everything to - * change the states from indexes to bits. - * - * Not quite sure that doing that is really worth the gain. I may have to - * play with some forked code later. - * - */ -void check_for_any_flag(Lock_t *lk, Waiters_t *lkrq) -{ - Holders_t *h; - - if( lkrq->flags & gio_lck_fg_Any && - (lkrq->state == gio_lck_st_Deferred || - lkrq->state == gio_lck_st_Shared) ) { - /* ok, lkrq meets any preqs. does the lock? */ - /* We're taking a short cut here, Assuming if the first holder is Shd - * or Dfr then all are. - * If new lock states are added in the future that are compat with - * Shd or Dfr, then this function will need to be revisited. - */ - if( lk->HolderCount > 0 && - (h=LLi_data(LLi_next(&lk->Holders))) != NULL && - (h->state == gio_lck_st_Deferred || - h->state == gio_lck_st_Shared) ) { - /* lock meets preqs too, rewrite the request's state. */ - lkrq->state = h->state; - } - } -} - -/** - * lkrq_onto_lock - - * @lk: - * @lkrq: < the lock req to handle. Should NOT be on any queues! - * @incomming: < TRUE if this is called from the incomming Queue. - * - * this is called by both incomming queue runer and conflict queue runner. - * - * Returns: =0:Queue Emptied !0:Items still in Queue. - */ -int lkrq_onto_lock(Lock_t *lk, Waiters_t *lkrq, int incomming) -{ - int saveLVB=FALSE, ret=0, singleExl=FALSE; - Holders_t *h; - - check_for_any_flag(lk, lkrq); - - /* Do I have the Exclusive hold on this lock? - * knowing this lets us do demotes without going through unlock. - */ - singleExl = lk->HolderCount == 1 && - !LLi_empty(&lk->Holders) && - (h=LLi_data(LLi_next(&lk->Holders))) != NULL && - h->state == gio_lck_st_Exclusive; - - /* the decision to save the LVB or not needs to be made before we - * actually change the state of the lock and holders. - * So 'if we will save this LVB' is decided here, but not done until - * after this req gets the lock. - */ - saveLVB = lkrq->state != gio_lck_st_Exclusive && - (lkrq->flags & gio_lck_fg_hasLVB) && - singleExl && - check_for_LVB_holder(lkrq->name, lk); - /* don't need to cmp name, since if holder is exl and if we - * get it below, we're obiviously the holder. - */ - - if( lkrq->state == gio_lck_st_Unlock ) { - /* do unlock */ - ret = drop_holder_by_range(lk, lkrq); - lkrq->flags &= ~gio_lck_fg_Cachable; - /* check lvb save */ - if( saveLVB && ret == 0 ) lvbcpy(lk, lkrq); - ret = send_lock_success(lk, lkrq); - }else - if( lk->ExpiredCount > 0 && !(lkrq->flags & gio_lck_fg_NoExp ) ) { - if( incomming ) { - put_onto_conflict_queue(lk, lkrq); - }else - { - requeue_conflict(lk, lkrq); - ret = 1; - } - }else - if( incomming && !singleExl && !conflict_queue_empty(lk) ) { - if( lkrq->flags & gio_lck_fg_Try ) { - send_Try_Failed(lk, lkrq); - }else - { - if( check_for_holder(lk, lkrq) ) { - /* I hold lock, I want to convert. but others in way. */ - /* Internal Unlock */ - drop_holder_by_range(lk, lkrq); - lkrq->flags &= ~gio_lck_fg_Cachable; - } - - /* then queue me on conflict. */ - put_onto_conflict_queue(lk, lkrq); - } - }else - if( check_for_conflict(lk, lkrq) ) { - if( lkrq->flags & gio_lck_fg_Try ) { - send_Try_Failed(lk, lkrq); - }else - { - if( incomming ) { - put_onto_conflict_queue(lk, lkrq); - }else - { - requeue_conflict(lk, lkrq); - ret = 1; - } - } - }else - { - /* Lazy merging. - * Basically we don't bother merging at all. To add a new range - * holder, we first clearout the area we want to add the new range, - * then just add the new range. - * - * The up side is that the code is a lot cleaner. - * The down side is that certain range activity will end up with a - * lot more memory used than if real merges happened. - */ - if( lk->HolderCount != 0 ) { - /* maybe stuff to drop. */ - drop_holder_by_range(lk, lkrq); - } - add_to_holders(lk, lkrq); - - /* check lvb save */ - if( saveLVB ) lvbcpy(lk, lkrq); - - /* send lock success reply */ - ret = send_lock_success(lk, lkrq); - } - - return ret; -} - -/** - * check_for_waiter - is foo pending here? - * @Cname: - * @lk: - * - * - * Returns: TRUE or FALSE - */ -int check_for_waiter(Lock_t *lk, Waiters_t *lkrq) -{ - LLi_t *tp; - Waiters_t *w; - - /* XXX Add Action waiters here? */ - if( ! LLi_empty( &lk->High_Waiters ) ) { - for(tp=LLi_next(&lk->High_Waiters);LLi_data(tp) != NULL;tp=LLi_next(tp)) { - w = LLi_data(tp); - if( compare_waiter_waiter_names(lkrq, w) ) { - return TRUE; - } - } - } - if( ! LLi_empty( &lk->Waiters ) ) { - for(tp=LLi_next(&lk->Waiters); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - w = LLi_data(tp); - if( compare_waiter_waiter_names(lkrq, w) ) { - return TRUE; - } - } - } - return FALSE; -} - -/** - * inner_cancel_waiting_lkrq - - * @list: - * @name: - * @inexp: - * - * - * Returns: int - */ -int inner_cancel_waiting_lkrq(LLi_t *list, Waiters_t *lkrq, Lock_t *lk) -{ - LLi_t *tp, *next; - Waiters_t *w; - int found = FALSE; - if( ! LLi_empty( list ) ) { - for(tp=LLi_next(list); - LLi_data(tp) != NULL; - tp = next) - { - next = LLi_next(tp); - w = LLi_data(tp); - /* do not cancel unlocks. */ - if( w->state != gio_lck_st_Unlock && - compare_waiter_waiter_names(lkrq, w) ) { - LLi_del(tp); - send_req_lk_reply(w, lk, gio_Err_Canceled); - found = TRUE; - } - } - } - return found; -} - -/** - * cancel_waiting_lkrq - Cancel a pending lock request. - * @Cname: - * @lk: - * @inexp: - * - * Returns: TRUE or FALSE - */ -int cancel_waiting_lkrq(Lock_t *lk, Waiters_t *lkrq) -{ - int found=FALSE,A,B,C,D; - - /* we do not support canceling reply_waiters - * maybe in the future, but not now. - */ - - /* this is done the following because if we chained the function calls - * together with || things won't behave the way we want it to. - * (and if you don't know why that would be different, go back to - * school.) - */ - A = inner_cancel_waiting_lkrq(&lk->State_Waiters, lkrq, lk); - if( A ) cnt_inq --; - B = inner_cancel_waiting_lkrq(&lk->Action_Waiters, lkrq, lk); - if( B ) cnt_inq --; - C = inner_cancel_waiting_lkrq(&lk->High_Waiters, lkrq, lk); - if( C ) cnt_confq --; - D = inner_cancel_waiting_lkrq(&lk->Waiters, lkrq, lk); - if( D ) cnt_confq --; - return found || A || B || C || D; -} - -/** - * Run_Action_Incomming_Queue - - * @CurrentQu: - * @lk: - * - * Returns: =0:Queue Emptied !0:Items still in Queue. - */ -int Run_Action_Incomming_Queue(Qu_t *CurrentQu, Lock_t *lk) -{ - Qu_t *tmp; - Waiters_t *lkrq; - Holders_t *h; - int err=0; - - while( !Qu_empty( CurrentQu ) ) { - tmp = Qu_DeQu( CurrentQu ); - lkrq = Qu_data(tmp); - - if( lkrq->state == gio_lck_st_HoldLVB ) { - if( check_for_LVB_holder(lkrq->name, lk) ) { - err = gio_Err_Ok; /* or should it be gio_Err_NotAllowed? */ - }else - if( add_to_LVB_holders(lkrq->name, lk) <0) { - err = gio_Err_MemoryIssues; - }else - { - err = gio_Err_Ok; - } - }else - if( lkrq->state == gio_lck_st_UnHoldLVB ) { - drop_LVB_holder(lkrq->name, lk); - err = gio_Err_Ok; - }else - if( lkrq->state == gio_lck_st_SyncLVB ) { - if( lk->HolderCount == 1 && - !LLi_empty(&lk->Holders) && - (h=LLi_data(LLi_next(&lk->Holders))) != NULL && - h->state == gio_lck_st_Exclusive && - lk->LVB != NULL && lkrq->LVB != NULL && - check_for_LVB_holder(lkrq->name, lk) ) { - lvbcpy(lk, lkrq); - err = gio_Err_Ok; - }else{ - err = gio_Err_NotAllowed; - log_msg(lgm_Always, - "lk->LVB:%p lkrq->LVB:%p lvbholder:%s holder:%s\n", - lk->LVB, lkrq->LVB, - check_for_LVB_holder(lkrq->name, lk)?"true":"false", - check_for_holder(lk, lkrq)?"true":"false" ); - } - }else - { - log_err("Unknown action:%#x name:%s lock:%s \n", lkrq->state, - lkrq->name, lkeytob64(lkrq->key, lkrq->keylen)); - err = gio_Err_BadStateChg; - } - - cnt_inq --; - /* now handle error */ - if( err == gio_Err_Ok ) { - if( gulm_config.fog ) { - lk->reply_waiter = lkrq; - cnt_replyq ++; - send_act_update_to_slaves(lkrq); - return 1; - }else{ - send_act_lk_reply(lkrq, gio_Err_Ok); - } - }else - { - send_act_lk_reply(lkrq, err); - } - - }/* while( !Qu_empty( CurrentQu ) ) */ - - return 0; -} - -/** - * Run_state_Conflict_Queue - checks wait queue - * - * Returns: =0:Queue Emptied !0:Items still in Queue. - */ -int Run_state_Conflict_Queue(Qu_t *CurrentQu, Lock_t *lk) -{ - Qu_t *tmp; - Waiters_t *lkrq; - - while( !Qu_empty( CurrentQu ) ) { - /* need to take the req we're processing off the qu since the lock - * state functions make decisions based on if there is reqs waiting - * in the Qu. - */ - tmp = Qu_DeQu( CurrentQu ); - lkrq = Qu_data(tmp); - cnt_confq --; - - if( lkrq_onto_lock(lk, lkrq, FALSE) != 0 ) return 1; - - }/* while( !Qu_empty( CurrentQu ) ) */ - - return 0; -} - -/** - * Run_state_Incomming_Queue - - * @CurrentQu: - * @lk: - * - * The only reason to leave an item on the incomming queue is because there - * is an item in the reply_waiter. Other wise the handling an item on the - * head of the Incomming queue will ALWAYS pull it off. Items are NEVER - * requeued here. They must either have an error sent back to the client, - * send success and mod the lock, or push the item on the Conflict queue. - * - * Returns: int - */ -int Run_state_Incomming_Queue(Qu_t *CurrentQu, Lock_t *lk) -{ - Qu_t *tmp; - Waiters_t *lkrq; - - while( !Qu_empty( CurrentQu ) ) { - tmp = Qu_DeQu( CurrentQu ); - lkrq = Qu_data(tmp); - cnt_inq--; - - if( lkrq_onto_lock(lk, lkrq, TRUE) != 0 ) return 1; - - }/* while( !Qu_empty( CurrentQu ) ) */ - - return 0; -} - -/** - * Run_WaitQu - - * @lk: - */ -void Run_WaitQu(Lock_t *lk) -{ - /* when ever enough replies come back, this gets called again. */ - if( lk->reply_waiter != NULL ) return; - - if( Run_Action_Incomming_Queue( &lk->Action_Waiters, lk) != 0 ) return; - if( Run_state_Incomming_Queue( &lk->State_Waiters, lk) != 0 ) return; - - if( Run_state_Conflict_Queue( &lk->High_Waiters, lk) != 0 ) return; - if( Run_state_Conflict_Queue( &lk->Waiters, lk) != 0 ) return; -} - -/** - * check_lists_for_desyncs - - * @lk: - * - */ -void check_lists_for_desyncs(Lock_t *lk) -{ - int i; - /* check lists. - * can probably remove these, the problem they were detecting is long - * fixed. - * */ - i = count_list( &lk->Holders ); - if( i != lk->HolderCount ) { - die(ExitGulm_Assertion, - "Holder list count desynced ( %d != %d ) on lock %s.\n", - i, lk->HolderCount, lkeytob64(lk->key, lk->keylen)); - } - i = count_list( &lk->ExpHolders ); - if( i != lk->ExpiredCount ) { - die(ExitGulm_Assertion, - "Exp list count desynced ( %d != %d ) on lock %s.\n", - i, lk->ExpiredCount, lkeytob64(lk->key, lk->keylen)); - } - i = count_list( &lk->LVB_holders ); - if( i != lk->LVB_holder_cnt ) { - die(ExitGulm_Assertion, - "LVB Holder list count desynced ( %d != %d ) on lock %s.\n", - i, lk->LVB_holder_cnt, lkeytob64(lk->key, lk->keylen)); - } - -} - -/** - * force_lock_state - - * @lkrq: - * - * forciably set this lock to the state. Used in updates we get when in - * slave mode. - * - * Returns: int - */ -int force_lock_state(Waiters_t *lkrq) -{ - Lock_t *lk; - Holders_t *h; - - lk = find_lock( lkrq->key, lkrq->keylen ); - - cur_lops++; - - check_lists_for_desyncs(lk); - - /* copy the LVB if we need to. */ - if(lkrq->state != gio_lck_st_Exclusive && - (lkrq->flags & gio_lck_fg_hasLVB) && - lk->HolderCount == 1 && - !LLi_empty(&lk->Holders) && - (h=LLi_data(LLi_next(&lk->Holders))) != NULL && - h->state == gio_lck_st_Exclusive && - lk->LVB != NULL && lkrq->LVB != NULL && - check_for_LVB_holder(lkrq->name, lk) - ) { - lvbcpy(lk, lkrq); - } - - if( lkrq->state == gio_lck_st_Unlock ) { - drop_holder_by_range(lk, lkrq); - check_for_recycle(lk); - }else - { - if( lk->HolderCount != 0 ) - drop_holder_by_range(lk, lkrq); - add_to_holders(lk, lkrq); - } - - /* tell the master we got it. */ - send_update_reply_to_master(lkrq); - - /* all done. */ - recycle_lkrq(lkrq); - - return 0; -} - -/** - * do_lock_state - - * @lkrq: - * - * Handles Lock Transitions (changing the state of the lock) - * - * Returns: =0: Ok, <0: socketError - */ -int do_lock_state(Waiters_t *lkrq) -{ - int err = 0; - Lock_t *lk; - - check_fullness(); - lk = find_lock( lkrq->key, lkrq->keylen ); - - check_lists_for_desyncs(lk); - - cur_lops++; - /* unless we're proven otherwise later, assume that this lock represents - * cachable data. - * This is purely an extra thing that gfs uses. - */ - lkrq->flags |= gio_lck_fg_Cachable; - - /* check to see if they have an activity already. Only one action can be - * pending per client per lock. - * this should NEVER happen. It violates how the IO works. - * */ - if( check_for_waiter(lk, lkrq) ) { - log_msg(lgm_locking, - "Warning! Duplicate lock requests, using first one. %s %s\n", - lkrq->name, lkeytob64(lk->key, lk->keylen)); - return gio_Err_AlreadyPend;/* wait for a reply first dolt.*/ - } - - /* don't think this ever happens, but.... */ - if( lkrq->state == gio_lck_st_Unlock && - lkrq->flags & gio_lck_fg_Try ) { - lkrq->flags &= ~gio_lck_fg_Try; /* do or donot! There is no try. */ - } - - /* stick onto the State_Waiters and run queues. */ - if( lkrq->state == gio_lck_st_Unlock || - lkrq->flags & gio_lck_fg_Piority ) { - /* do unlocks, and piorities first. */ - Qu_EnQu_Front(&lk->State_Waiters, &lkrq->wt_list); - }else{ - Qu_EnQu(&lk->State_Waiters, &lkrq->wt_list); - } - cnt_inq ++; - - Run_WaitQu(lk); - check_for_recycle(lk); - return err; -} - -/** - * do_lock_query - - * @lkrq: - * - * - * Returns: int - */ -int do_lock_query(Waiters_t *lkrq) -{ - Lock_t *lk; - LLi_t *tp; - Holders_t *new, *h; - - lk = find_lock( lkrq->key, lkrq->keylen ); - cur_lops ++; - - /* check lock for conflicts. */ - if( !LLi_empty(&lk->Holders) ) { - for(tp = LLi_next(&lk->Holders); - NULL != LLi_data(tp); - tp = LLi_next(tp)) { - h = LLi_data(tp); - if( Do_Holder_Waiter_conflict(h,lkrq) ) { - new = duplicate_holder(h); - LLi_add_after( &lkrq->holders, &new->cl_list ); - break; - } - } - } - - return send_query_reply(lkrq, 0); -} - -/** - * force_lock_action - - * @lkrq: - * - * - * Returns: int - */ -int force_lock_action(Waiters_t *lkrq) -{ - Lock_t *lk; - Holders_t *h; - - lk = find_lock( lkrq->key, lkrq->keylen); - - cur_lops ++; - - if( lkrq->state == gio_lck_st_Cancel ) { - /* no cancel in force. */ - log_err("Slave got a cancel request!\n"); - }else - if( lkrq->state == gio_lck_st_HoldLVB ) { - if( ! check_for_LVB_holder(lkrq->name, lk) ) - add_to_LVB_holders(lkrq->name, lk); - }else - if( lkrq->state == gio_lck_st_UnHoldLVB ) { - drop_LVB_holder(lkrq->name, lk); - check_for_recycle(lk); - }else - if( lkrq->state == gio_lck_st_SyncLVB ) { - if( lk->HolderCount == 1 && - !LLi_empty(&lk->Holders) && - (h=LLi_data(LLi_next(&lk->Holders))) != NULL && - h->state == gio_lck_st_Exclusive && - lk->LVB != NULL && lkrq->LVB != NULL && - check_for_LVB_holder(lkrq->name, lk) ) { - lvbcpy(lk, lkrq); - } - }else - { - log_err("Unknown force action:%#x name:%s lock:%s \n", lkrq->state, - lkrq->name, lkeytob64(lkrq->key, lkrq->keylen)); - } - - send_update_reply_to_master(lkrq); - recycle_lkrq(lkrq); - return 0; -} - -/** - * do_lock_action - - * @lkrq: - * - * Handles lock Actions (stuff to do on locks) - * - * Returns: int - */ -int do_lock_action(Waiters_t *lkrq) -{ - int ret = 0; - Lock_t *lk; - - check_fullness(); - lk = find_lock( lkrq->key, lkrq->keylen ); - - cur_lops++; - - if( lkrq->state == gio_lck_st_Cancel ) { - ret = cancel_waiting_lkrq(lk, lkrq); - Run_WaitQu(lk); - check_for_recycle(lk); - return 0; - } - - /* stick it on the queue */ - Qu_EnQu(&lk->Action_Waiters, &lkrq->wt_list); - cnt_inq ++; - Run_WaitQu(lk); - check_for_recycle(lk); - - return 0; -} - -/** - * increment_slave_update_replies - - * @key: < key for the lock this affects - * @len: < how long that key is - * @slave: < which slave sent this reply - * @smask: < bitmask of the connected slaves. - * - * - * Returns: int - */ -int increment_slave_update_replies(uint8_t *key, uint16_t len, - int slave, uint8_t smask) -{ - Lock_t *lk; - Waiters_t *lkrq; - - lk = find_lock(key, len); - - if( lk->reply_waiter == NULL ) { - log_msg(lgm_Always, "There is no reply waiter on lock %s\n", - lkeytob64(key,len)); - return -1; - } - lkrq = lk->reply_waiter; - - /* set bit */ - lkrq->Slave_rpls |= 1 << slave; - - /* check mask - * there can be more bits set in the Slave_rpls than in smask - * if every bit in smask is in Slave_rpls, then send client reply. - * - * First, if everyone we sent it to has replied, then we're good. - * If not everyone we sent it to has replied; has everone that is alive - * replied? If so, we're good. - * - * mmmmShortCircuitLogic... - * */ - if( (lkrq->Slave_rpls & lkrq->Slave_sent) == lkrq->Slave_sent || - (lkrq->Slave_rpls & smask) == smask ) { - log_msg(lgm_LockUpdates, "Got all update replies for %s.\n", - lkeytob64(lk->key, lk->keylen)); - /* all slaves have reported in. send reply to client. */ - lk->reply_waiter = NULL; - cnt_replyq --; - if(lkrq->op == gulm_lock_action_req ) { - send_act_lk_reply(lkrq, gio_Err_Ok); - }else - if( lkrq->op == gulm_lock_state_req ) { - send_req_lk_reply(lkrq, lk, gio_Err_Ok); - } - - /* since that reply might have been blocking */ - Run_WaitQu(lk); - check_for_recycle(lk); - } - - return 0; -} - -struct recheck_reply_waiters_s { - uint8_t sms; - uint8_t onlogin; -}; -/** - * _recheck_reply_waiters_ - - * @item: - * @d: - * - * - * Returns: int - */ -int _recheck_reply_waiters_(LLi_t *item, void *d) -{ - struct recheck_reply_waiters_s *rrw = (struct recheck_reply_waiters_s *)d; - Lock_t *lk; - Waiters_t *lkrq; - - lk = LLi_data(item); - if( lk->reply_waiter != NULL ) { - lkrq = lk->reply_waiter; - - if( rrw->onlogin != 0 ) { - /* This slave just logged in, so they just grabbed the entire - * lockspace. - * So if there are any reply_waiters waiting on a reply from them, - * they'll not get it, but it has effectively happened. - * So we set reply bit. - */ - if( (lkrq->Slave_sent & rrw->onlogin) == rrw->onlogin ) { - log_msg(lgm_locking, "%s Sent but not recved on Slave login. Marking.\n", - lkeytob64(lkrq->key, lkrq->keylen)); - lkrq->Slave_rpls |= rrw->onlogin; - } - } - - if( (lkrq->Slave_rpls & lkrq->Slave_sent) == lkrq->Slave_sent || - (lkrq->Slave_rpls & rrw->sms) == rrw->sms ) { - log_msg(lgm_LockUpdates, "Recheck scan cleared reply for %s.\n", - lkeytob64(lk->key, lk->keylen)); - /* all slaves have reported in. send reply to client. */ - lk->reply_waiter = NULL; - cnt_replyq --; - if(lkrq->op == gulm_lock_action_req ) { - send_act_lk_reply(lkrq, gio_Err_Ok); - }else - if( lkrq->op == gulm_lock_state_req ) { - send_req_lk_reply(lkrq, lk, gio_Err_Ok); - } - - /* since that reply might have been blocking */ - Run_WaitQu(lk); - check_for_recycle(lk); - } - - } - return 0; -} - -/** - * recheck_reply_waiters - - * - * Need something here to scan over the locks so that when a slave - * dies/logs out we can send off any waiting locks replies that were - * waiting for the slave. - */ -void recheck_reply_waiters(uint8_t Slave_bits, uint8_t onlogin) -{ - struct recheck_reply_waiters_s rrw; - rrw.sms = Slave_bits; - rrw.onlogin = onlogin; - hash_walk(AllLocks, _recheck_reply_waiters_, &rrw); -} - -/** - * inner_expire_from_waiters - - * @list: - * @name: - * @lk: - * - * - * Returns: int - */ -int inner_expire_from_waiters(LLi_t *list, uint8_t *name, Lock_t *lk) -{ - LLi_t *tp, *next; - Waiters_t *w; - int found = FALSE; - if( ! LLi_empty( list ) ) { - for(tp=LLi_next(list); - LLi_data(tp) != NULL; - tp = next) - { - next = LLi_next(tp); - w = LLi_data(tp); - if( w->name != NULL && strcmp(w->name, name) == 0 ) { - LLi_del(tp); - recycle_lkrq(w); - found = TRUE; - } - } - } - return found; -} - -/** - * expire_from_waiters - - * @name: - * @lk: - * - * - * Returns: int - */ -int expire_from_waiters(uint8_t *name, Lock_t *lk) -{ - Waiters_t *w; - int A,B,C,D,E; - - A=B=C=D=E=FALSE; - - if( (w = lk->reply_waiter) != NULL && - w->name != NULL && - strcmp(w->name, name) == 0 ) { - lk->reply_waiter = NULL; - cnt_replyq --; - recycle_lkrq(w); - A = TRUE; - } - - /* this is done the following because if we chained the function calls - * together with || things won't behave the way we want it to. - * (and if you don't know why that would be different, go back to - * school.) - */ - B = inner_expire_from_waiters(&lk->State_Waiters, name, lk); - if( B ) cnt_inq --; - C = inner_expire_from_waiters(&lk->Action_Waiters, name, lk); - if( C ) cnt_inq --; - D = inner_expire_from_waiters(&lk->High_Waiters, name, lk); - if( D ) cnt_confq --; - E = inner_expire_from_waiters(&lk->Waiters, name, lk); - if( E ) cnt_confq --; - - return A || B || C || D || E; -} - -/** - * cmp_lock_mask - - * @mask: - * @masklen: - * @key: - * @keylen: - * - * See if a key fits with the mask. - * - * ADD: if mask is sorter than key, ``extend'' mask with 0xff - * - * Returns: TRUE || FALSE - */ -int cmp_lock_mask(uint8_t *mask, int masklen, uint8_t *key, int keylen) -{ - int i; - for(i=0; i < masklen && i < keylen; i++ ) { - /* mask byte == 0xff, matches everything - * mask byte == rest, must == key byte. - */ - if( mask[i] == 0xff ) continue; - if( mask[i] != key[i] ) return FALSE; - } - /* key shorter than mask, doesn't match. */ - if( keylen < masklen ) return FALSE; - /* key longer than mask, and prev bytes match, then all matches. */ - - /* key fits within mask. */ - return TRUE; -} - -typedef struct _drop_locks_s { - uint8_t *name; - uint8_t *mask; - uint16_t mlen; -} _drop_locks_t; -/** - * _expire_locks_ - The actual work to expire a lock - * @item: - * @d: - * - * this function could probably stand to be rewritten. - * - * Returns: int - */ -int _expire_locks_(LLi_t *item, void *d) -{ - _drop_locks_t *dl = (_drop_locks_t*)d; - uint8_t *name = dl->name; - Lock_t *lk; - int modQ=FALSE; - LLi_t *tp,*nxt; - Holders_t *h; - - lk = LLi_data(item); - - /* If there is a mask, and then if it doesn't match, skip this lock. - * If there isn't a mask, or if the mask matches, expire this lock. - */ - if( dl->mlen > 0 && ! cmp_lock_mask(dl->mask, dl->mlen, lk->key, lk->keylen)) - return 0; - - /* drop from wait queue */ - if( expire_from_waiters(name, lk) ) modQ = TRUE; - if( drop_LVB_holder(name, lk) == 0 ) { - modQ = TRUE; - } - - for(tp=LLi_next(&lk->Holders); LLi_data(tp) != NULL; tp=nxt) { - nxt = LLi_next(tp); - h = LLi_data(tp); - if( strcmp(h->name, name) == 0 ) { - LLi_del(tp); - lk->HolderCount --; - decrement_global_state_counters(h->state); - switch(h->state) { - case gio_lck_st_Exclusive: - /* move to exp list */ - if( !check_for_expholder(h, lk ) ) { - move_to_Expholders(h, lk); - } - /* reset LVB */ - if( lk->LVB != NULL ) memset( lk->LVB, 0, lk->LVBlen); - break; - case gio_lck_st_Shared: - case gio_lck_st_Deferred: - /* just drop it... */ - modQ = TRUE; - recycle_holder(h); - break; - } - } - } - - if( modQ ) { - /* a change that might let queued requests advance */ - Run_WaitQu(lk); - check_for_recycle(lk); - } - return 0; -} - -/** - * expire_locks - - * @Cname: < Name of Client who's locks we're expiring - */ -void expire_locks(uint8_t *name, uint8_t *mask, uint16_t len) -{ - int e; - _drop_locks_t dl; - uint8_t *shortname, *dotindex; - -#ifdef TIME_RECOVERY_PARTS - struct timeval tva, tvb; - gettimeofday(&tva, NULL); -#endif - - /* Extra code to strip of everything after first "." */ - shortname = strdup(name); - if (shortname == NULL) die(ExitGulm_NoMemory, "No memory left."); - if ((dotindex = index(shortname, '.'))) { - *dotindex = '\0'; - } - - dl.name = shortname; - dl.mask = mask; - dl.mlen = len; - e = hash_walk(AllLocks, _expire_locks_, &dl); - if(e!=0) log_err("Got %d, trying to expire locks for %s\n",e,shortname); - - dl.name = name; - dl.mask = mask; - dl.mlen = len; - e = hash_walk(AllLocks, _expire_locks_, &dl); - if(e!=0) log_err("Got %d, trying to expire locks for %s\n",e,name); - -#ifdef TIME_RECOVERY_PARTS - gettimeofday(&tvb, NULL); - log_bug("It took %ld sec and %ld micro sec to expire all locks.\n", - (tvb.tv_sec - tva.tv_sec), (tvb.tv_usec - tva.tv_usec)); -#endif -} - -/** - * _drop_locks_ - The actual work to drop a lock - * @item: - * @d: - * - * - * Returns: int - */ -int _drop_locks_(LLi_t *item, void *d) -{ - _drop_locks_t *dl = (_drop_locks_t*)d; - Lock_t *lk; - lk = LLi_data(item); - - if( dl->name != NULL ) { - if( lk->ExpiredCount > 0 ) { - if( cmp_lock_mask(dl->mask, dl->mlen, lk->key, lk->keylen) ) { - drop_expholders(dl->name, lk); /* decrements counters for us */ - - Run_WaitQu(lk); - check_for_recycle(lk); - } - } - }else{ /* doing a drop all exp */ - if( lk->ExpiredCount > 0 ) { - if( cmp_lock_mask(dl->mask, dl->mlen, lk->key, lk->keylen) ) { - delete_entire_holder_list( &lk->ExpHolders ); - cnt_exp_holds -= lk->ExpiredCount; - lk->ExpiredCount = 0; - - Run_WaitQu(lk); - check_for_recycle(lk); - } - } - } - - return 0; -} - - -/** - * drop_expired - - * @name: < Name of Client whose locks we're flushing. - * @mask: < key mask. Only drop exp on locks that match this mask. - * @len: < length of mask - * - */ -void drop_expired(uint8_t *name, uint8_t *mask, uint16_t len) -{ - int e; - _drop_locks_t dl; -#ifdef TIME_RECOVERY_PARTS - struct timeval tva, tvb; - gettimeofday(&tva, NULL); -#endif - - dl.name = name; - dl.mask = mask; - dl.mlen = len; - - e = hash_walk(AllLocks, _drop_locks_, &dl); - if(e!=0) log_err("Got %d, trying to drop locks for %s\n",e,name); - -#ifdef TIME_RECOVERY_PARTS - gettimeofday(&tvb, NULL); - log_bug("It took %ld sec and %ld micro sec to drop exp locks.\n", - (tvb.tv_sec - tva.tv_sec), (tvb.tv_usec - tva.tv_usec)); -#endif -} - -/** - * _rerun_wait_queues_ - - * @item: - * @d: - * - * - * Returns: int - */ -int _rerun_wait_queues_(LLi_t *item, void *d) -{ - Lock_t *lk; - lk = LLi_data(item); - Run_WaitQu(lk); - check_for_recycle(lk); - return 0; -} - -/** - * rerun_wait_queues - - */ -void __inline__ rerun_wait_queues(void) -{ -#ifdef TIME_RECOVERY_PARTS - struct timeval tva, tvb; - gettimeofday(&tva, NULL); -#endif - hash_walk(AllLocks, _rerun_wait_queues_, NULL); - -#ifdef TIME_RECOVERY_PARTS - gettimeofday(&tvb, NULL); - log_bug("It took %ld sec and %ld micro sec to rerun wait queues.\n", - (tvb.tv_sec - tva.tv_sec), (tvb.tv_usec - tva.tv_usec)); -#endif -} - -/*****************************************************************************/ -/** - * _serialize_lockspace_ - - * @item: - * @d: - * - * - * Returns: int - */ -int _serialize_lockspace_(LLi_t *item, void *d) -{ - xdr_enc_t *xdr = (xdr_enc_t*)d; - Lock_t *lk; - LLi_t *tp; - Holders_t *h; - int err; - - lk = LLi_data(item); - - if((err = xdr_enc_uint8(xdr, lk->keylen)) != 0 ) return err; - if((err = xdr_enc_raw(xdr, lk->key, lk->keylen)) != 0 ) return err; - if((err = xdr_enc_uint8(xdr, lk->LVBlen)) != 0 ) return err; - if( lk->LVBlen > 0 ) { - if((err = xdr_enc_raw(xdr, lk->LVB, lk->LVBlen)) != 0 ) return err; - } - - if((err = xdr_enc_uint32(xdr, lk->HolderCount)) != 0 ) return err; - if((err = xdr_enc_list_start(xdr)) != 0 ) return err; - for(tp=LLi_next(&lk->Holders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if((err = xdr_enc_string(xdr, h->name)) != 0 ) return err; - if((err = xdr_enc_uint64(xdr, h->subid)) != 0 ) return err; - if((err = xdr_enc_uint8(xdr, h->state)) != 0 ) return err; - if((err = xdr_enc_uint64(xdr, h->start)) != 0 ) return err; - if((err = xdr_enc_uint64(xdr, h->stop)) != 0 ) return err; - } - if((err = xdr_enc_list_stop(xdr)) != 0 ) return err; - - if((err = xdr_enc_uint32(xdr, lk->LVB_holder_cnt)) != 0 ) return err; - if((err = xdr_enc_list_start(xdr)) != 0 ) return err; - for(tp=LLi_next(&lk->LVB_holders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if((err = xdr_enc_string(xdr, h->name)) != 0 ) return err; - if((err = xdr_enc_uint64(xdr, h->subid)) != 0 ) return err; - } - if((err = xdr_enc_list_stop(xdr)) != 0 ) return err; - - if((err = xdr_enc_uint32(xdr, lk->ExpiredCount)) != 0 ) return err; - if((err = xdr_enc_list_start(xdr)) != 0 ) return err; - for(tp=LLi_next(&lk->ExpHolders); LLi_data(tp) != NULL; tp=LLi_next(tp)) { - h = LLi_data(tp); - if((err = xdr_enc_string(xdr, h->name)) != 0 ) return err; - if((err = xdr_enc_uint64(xdr, h->subid)) != 0 ) return err; - } - if((err = xdr_enc_list_stop(xdr)) != 0 ) return err; - - /* we don't track the waiter queues. so we're done with this lock. */ - return 0; -} - -/** - * serialize_lockspace - - * @fd: - * - * - * Returns: int - */ -int serialize_lockspace(int fd) -{ - xdr_enc_t *xdr; - int err; - - xdr = xdr_enc_init(fd, (1024*1024) ); /* 1M buffer */ - if( xdr == NULL ) return -ENOMEM; - - xdr_enc_list_start(xdr); - - if(hash_walk(AllLocks, _serialize_lockspace_, xdr) != 0 ) { - xdr_enc_force_release(xdr); - return -1; - } - - xdr_enc_list_stop(xdr); - - err = xdr_enc_flush(xdr); - xdr_enc_force_release(xdr); - return err; -} - - -/** - * deserialize_lockspace - - * @fd: - * - * - * Returns: int - */ -int deserialize_lockspace(int fd) -{ - xdr_dec_t *xdr; - uint8_t key[1024], *name, keylen; - uint16_t len; - int counter,err; - Lock_t *lk; - Holders_t *h; - - clear_lockspace(); - - xdr = xdr_dec_init(fd, 0); /* just use defaults here. */ - if( xdr == NULL ) return -ENOMEM; - - if( (err=xdr_dec_list_start(xdr)) != 0 ) goto fail; - - while( xdr_dec_list_stop(xdr) != 0 ) { - if( (err=xdr_dec_uint8(xdr, &keylen)) != 0 ) goto fail; - len = keylen; - if( (err=xdr_dec_raw(xdr, key, &len)) != 0 ) goto fail; - lk = find_lock(key, keylen); - - if( (err=xdr_dec_uint8(xdr, &lk->LVBlen)) != 0 ) goto fail; - if( lk->LVBlen > 0 ) { - lk->LVB = malloc(lk->LVBlen); - if( lk->LVB == NULL ) {err=-ENOMEM;goto fail;} - len = lk->LVBlen; - if( (err=xdr_dec_raw(xdr, lk->LVB, &len)) != 0 ) goto fail; - }else{ - lk->LVB = NULL; - } - - if( (err=xdr_dec_uint32(xdr, &lk->HolderCount)) != 0 ) goto fail; - counter = 0; - if( (err=xdr_dec_list_start(xdr)) != 0 ) goto fail; - while( xdr_dec_list_stop(xdr) != 0 ) { - if( (err=xdr_dec_string(xdr, &name)) != 0 ) goto fail; - h = get_new_holder(); - if( h == NULL ) {err=-ENOMEM;goto fail;} - LLi_init(&h->cl_list, h); - h->name = name; - h->idx = 0; - if( (err=xdr_dec_uint64(xdr, &h->subid)) != 0 ) goto fail; - if( (err=xdr_dec_uint8(xdr, &h->state)) != 0 ) goto fail; - increment_global_state_counters(h->state); - if( (err=xdr_dec_uint64(xdr, &h->start)) != 0 ) goto fail; - if( (err=xdr_dec_uint64(xdr, &h->stop)) != 0 ) goto fail; - LLi_add_after( &lk->Holders, &h->cl_list); - counter ++; - } - if( counter != lk->HolderCount ) { - log_msg(lgm_Always,"AH! counter != lk->HolderCount %d != %d " - "Using counter.\n", counter, lk->HolderCount); - lk->HolderCount = counter; - } - - if( (err=xdr_dec_uint32(xdr, &lk->LVB_holder_cnt)) != 0 ) goto fail; - counter = 0; - if( (err=xdr_dec_list_start(xdr)) != 0 ) goto fail; - while( xdr_dec_list_stop(xdr) != 0 ) { - if( (err=xdr_dec_string(xdr, &name)) != 0 ) goto fail; - h = get_new_holder(); - if( h == NULL ) {err=-ENOMEM;goto fail;} - LLi_init(&h->cl_list, h); - h->name = name; - h->idx = 0; - if( (err=xdr_dec_uint64(xdr, &h->subid)) != 0 ) goto fail; - LLi_add_after( &lk->LVB_holders, &h->cl_list); - counter ++; - cnt_lvb_holds ++; - } - if( counter != lk->LVB_holder_cnt ) { - log_msg(lgm_Always,"AH! counter != lk->LVB_holder_cnt %d != %d " - "Using counter.\n", counter, lk->LVB_holder_cnt); - lk->LVB_holder_cnt = counter; - } - - if( (err=xdr_dec_uint32(xdr, &lk->ExpiredCount)) != 0 ) goto fail; - counter = 0; - if( (err=xdr_dec_list_start(xdr)) != 0 ) goto fail; - while( xdr_dec_list_stop(xdr) != 0 ) { - if( (err=xdr_dec_string(xdr, &name)) != 0 ) goto fail; - h = get_new_holder(); - if( h == NULL ) {err=-ENOMEM;goto fail;} - LLi_init(&h->cl_list, h); - h->name = name; - h->idx = 0; - if( (err=xdr_dec_uint64(xdr, &h->subid)) != 0 ) goto fail; - LLi_add_after( &lk->ExpHolders, &h->cl_list); - counter ++; - cnt_exp_holds ++; - - } - if( counter != lk->ExpiredCount ) { - log_msg(lgm_Always,"AH! counter != lk->ExpiredCount %d != %d " - "Using counter.\n", counter, lk->ExpiredCount); - lk->ExpiredCount = counter; - } - } - - xdr_dec_release(xdr); - return 0; -fail: - xdr_dec_release(xdr); - return err; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/log.c b/gulm/src/log.c deleted file mode 100644 index eaecb30..0000000 --- a/gulm/src/log.c +++ /dev/null @@ -1,259 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2006 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <pthread.h> - -#include "gulm_defines.h" - -int log_running = 0; -static unsigned int log_size; -static char *log; -char *syslog_msg; -unsigned int syslog_max_size; -static pthread_t log_thr; -static pthread_mutex_t log_wake_lock; -static pthread_cond_t log_wake_cond; -static char *head, *tail, *last; - -/* - The log is a circular buffer to hold syslog messages. The messages - are stored as with a numeric char holding the priority followed by the - message will a NULLs seperating the messages. Messages are allowed - to wrap around the end. The last byte in the buffer will always be - NULL. This makes printing wraparound messages easier. The log - is never allowed to get so full that head wraps all the way around - and is equal to tail. There will always be at least a one byte space. - This is so that you do not need another value to determine whether the log - is totally full or totally empty. - - Message - ------- - Hddddddddddddddd0 - - H: Message header byte (see below) - d: Variable length text data, up to max_size - 1 in length - 0: NULL - - - Message header byte (bits) - -------------------------- - tlwuhppp - - t: truncated flag. set if the message has been truncated - l: lost messages flag. set if a lost message counter follows. - w: wrap flag. set if the message wraps around the end of the log. - u: unused flag - h: header flag. This is set on all headers. Its job is to keep header - bytes from ever being equal to 0, so that I can use 0s to pad the log - without them being confused for headers. - p: priority bit. - - - detail of tail end of log - ------------------------- - ffffffrrHut - - f: Variable length free log space - r: restricted log space. messages can finish in the space, but no - new messages are allowed to start here. (see explanation below) - H: lost message header byte. - u: unused space. This is the location of the header when messages have been - lost. - f: tail pointer - - - The restricted space is necessary becauase a log message needs at least - three bytes. So if the head ptr is within 4 bytes of the tail, it is - impossible to write a message and still have the space necessary for the - lost message header. If a message comes it when the head ptr is within - 4 bytes of the tail, a couple of things can happen. - - If the head is at (tail - 1), then there must be a lost message header at - (head - 1). There is nothing more to do. - If the head is at (tail - 2), you write out a lost message header and - increment the head to (tail - 1) - if the head is at (tail - 3) or (tail - 4), you pad with NULLs until - (tail - 2) and then you write out a lost message header, and increment head to - (tail - 1) - -*/ -#define DEFAULT_MAX_MSG_SIZE 1024 -#define DEFAULT_LOG_SIZE 8192 - -#define TRUNCATED_FLAG 0x80 -#define LOST_MSGS_FLAG 0x40 -#define WRAPPED_FLAG 0x20 -#define HEADER_FLAG 0x08 - -#define LOST_MSGS_PRIO LOG_WARNING - -#define log_empty (head == tail) - -#define get_priority(x) ((int)(0x07 & *(unsigned char *)(x))) - -#define truncated_flag(x) (TRUNCATED_FLAG & *(x)) - -#define lost_msgs_flag(x) (LOST_MSGS_FLAG & *(x)) - -#define wrapped_flag(x) (WRAPPED_FLAG & *(x)) - -#define inc(x) increment_ptr(&(x), 1) - - -/* This is written so that head and tail never point to an invalid - address. There is no need to lock access to head or tail, as long as - 1. They never try to look or move backwards. 2. They always change from - valid value to valid value. */ -static void increment_ptr(char **ptr, unsigned int size) -{ - if (*ptr + size >= last) - *ptr += (size - log_size); - else - *ptr += size; -} - -static int get_free_space() -{ - int dist = tail - head; - if (dist <= 0) - dist += log_size; - return dist; -} - -/* This is called after the caller writes the message int the syslog_msg - buffer. */ -void log_to_buffer(int priority) -{ - char header = (char)(priority & 0x07) | HEADER_FLAG; - int free_space = get_free_space(); - syslog_msg[syslog_max_size] = 0; /* just to be paranoid */ - int len = strlen(syslog_msg) + 2; /* text + header + NULL */ - - if (free_space == 1) - return; - - /* If there's not enough room to write a message, write a - lost message header */ - if (free_space <= 4){ - while(free_space > 2){ - *head = 0; - inc(head); - free_space--; - } - header = LOST_MSGS_FLAG | HEADER_FLAG | LOST_MSGS_PRIO; - *head = header; - inc(head); - goto wake_up; - } - - if (len > free_space - 2){ - header |= TRUNCATED_FLAG; - syslog_msg[free_space - 4] = 0; - len = free_space - 2; - } - - if (len > last - head){ - char *ptr = &syslog_msg[last - (head + 1)]; - header |= WRAPPED_FLAG; - *head = header; - memcpy(head + 1, syslog_msg, last - (head + 1)); - len -= last - head; - memcpy(log, ptr, len); - head = log + len; - } - else { - *head = header; - memcpy(head + 1, syslog_msg, len - 1); - increment_ptr(&head, len); - } -wake_up: - pthread_mutex_lock(&log_wake_lock); - pthread_cond_signal(&log_wake_cond); - pthread_mutex_unlock(&log_wake_lock); -} - - -static void process_message(void) -{ - if (*tail == 0){ - inc(tail); - return; - } - if (lost_msgs_flag(tail)){ - syslog(get_priority(tail), "**Log buffer out of space. Messages lost**\n"); - inc(tail); - return; - } - syslog(get_priority(tail), "%s%s%s", tail + 1, wrapped_flag(tail)? log : "", truncated_flag(tail)? " ... **Log buffer out of space. Message truncated**\n" : ""); - if (wrapped_flag(tail)) - tail = strchr(log, 0) + 1; - else { - char *tmp = strchr(tail, 0) + 1; - if (tmp == last) - tail = log; - else - tail = strchr(tail, 0) + 1; - } -} - -static void *log_thread(void *unused) -{ - while (1) { - pthread_mutex_lock(&log_wake_lock); - if (log_empty) - pthread_cond_wait(&log_wake_cond, &log_wake_lock); - pthread_mutex_unlock(&log_wake_lock); - - while (!log_empty) - process_message(); - } - return (void *) 0; -} - -void log_init(unsigned int my_log_size, unsigned int my_max_size) -{ - pthread_attr_t attr; - - log_size = (my_log_size)? my_log_size : DEFAULT_LOG_SIZE; - syslog_max_size = (my_max_size)? my_max_size : DEFAULT_MAX_MSG_SIZE; - - log = malloc(log_size); - if (log == NULL) - die(ExitGulm_InitFailed, "Failed to allocate memory for log ring buffer: %s\n", strerror(errno)); - syslog_msg = malloc(syslog_max_size); - if (syslog_msg == NULL) - die(ExitGulm_InitFailed, "Failed to allocate memory for log messages: %s\n", strerror(errno)); - head = tail = log; - syslog_max_size--; /* You don't use the last byte of the msg. It's - always set to NULL to make printing easier */ - log_size--; /* You don't use the last byte of the log. It's always set - to NULL to make printing easier */ - *(syslog_msg + syslog_max_size) = 0; - last = log + log_size; - *last = 0; - - if (pthread_attr_init(&attr) != 0) - die(ExitGulm_InitFailed, "Failed to initialize logging thread attribute structure: %s\n", strerror(errno)); - if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) - die(ExitGulm_InitFailed, "Failed to set logging thread detachstate attribute: %s\n", strerror(errno)); - pthread_mutex_init(&log_wake_lock, NULL); - pthread_cond_init(&log_wake_cond, NULL); - - if (pthread_create(&log_thr, &attr, log_thread, NULL) != 0) - die(ExitGulm_InitFailed, "Failed to start logging thread: %s\n", strerror(errno)); - log_running = 1; -} diff --git a/gulm/src/log.h b/gulm/src/log.h deleted file mode 100644 index 46b4dcc..0000000 --- a/gulm/src/log.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) 2006 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __gulm_log_h__ -#define __gulm_log_h__ - -/* do not access these variables directly */ -extern int log_running; -extern char *syslog_msg; -extern unsigned int syslog_max_size; - -#include "gulm_log_msg_bits.h" - -/* no syslog if debugging. */ -#ifndef DEBUG -#include <syslog.h> -#define log_msg(v, fmt, args...) if(((v)&verbosity)==(v)||(v)==lgm_Always) {\ - syslog(LOG_NOTICE, fmt , ## args );} -#define log_err(fmt, args...){ \ - syslog(LOG_ERR, "ERROR [%s:%d] " fmt , __FILE__ , __LINE__ , ## args ); } -#define log_bug(fmt, args...) { \ - syslog(LOG_NOTICE, "BUG[%s:%d] " fmt , __FILE__ , __LINE__ , ## args ); } -#define die(ext, fmt, args...) { \ - fprintf(stderr, "In %s:%d (%s) death by:\n" fmt , __FILE__ , \ - __LINE__ , RELEASE , ## args ); \ - syslog(LOG_ERR, "In %s:%d (%s) death by:\n" fmt , __FILE__ , \ - __LINE__ , RELEASE , ## args ); exit(ext);} -#define TICK log_bug("TICK.\n") -#else /*DEBUG*/ -#define log_msg(v, fmt, args...) if(((v)&verbosity)==(v)||(v)==lgm_Always){ \ - fprintf(stdout, "%s: " fmt , ProgramName , ## args ); } -#define log_err(fmt, args...) {\ - fprintf(stderr, "ERROR [%s:%s:%d] " fmt , ProgramName , __FILE__ , \ - __LINE__ , ## args ); } -#define log_bug(fmt, args...) {\ - fprintf(stderr, "[bug:%s:%s:%d] " fmt , ProgramName , __FILE__ , \ - __LINE__ , ## args ); } -#define die(ext, fmt, args...) {\ - fprintf(stderr, "In %s:%d (%s) death by:\n" fmt , __FILE__ , \ - __LINE__ , RELEASE , ## args ); exit(ext);} -#define TICK log_bug("TICK.\n") -#endif /*DEBUG*/ - -void log_init(unsigned int log_size, unsigned int max_size); - -/* do not access this function directly */ -void log_to_buffer(int priority); - -#endif /* __gulm_log_h__ */ diff --git a/gulm/src/ltpx.h b/gulm/src/ltpx.h deleted file mode 100644 index 7c31272..0000000 --- a/gulm/src/ltpx.h +++ /dev/null @@ -1,17 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_ltpx_h__ -#define __gulm_ltpx_h__ -int ltpx_main(int argc, char **argv); -#endif /*__gulm_ltpx_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/ltpx_io.c b/gulm/src/ltpx_io.c deleted file mode 100644 index 7bea296..0000000 --- a/gulm/src/ltpx_io.c +++ /dev/null @@ -1,2403 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/poll.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "myio.h" -#include "LLi.h" -#include "Qu.h" -#include "hashn.h" -#include "gio_wiretypes.h" -#include "xdr.h" -#include "ltpx_priv.h" -#include "config_gulm.h" -#include "utils_crc.h" -#include "utils_ip.h" -#include "utils_tostr.h" -#include "utils_verb_flags.h" - - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/* stuff from config. */ -extern gulm_config_t gulm_config; -extern struct in6_addr myIP; -extern char myName[256]; - -/*****************************************************************************/ -/*****************************************************************************/ -static int running = TRUE; -static struct timeval Started_at; -static struct timeval NOW; - -static ip_name_t MasterIN = {{NULL,NULL,NULL},IN6ADDR_ANY_INIT,NULL}; -static int I_am_the = gio_Mbr_ama_Pending;/* what state we are in */ -static unsigned long totaloutqueue = 0; - -typedef struct lsfilter_s { - uint8_t *key; - uint16_t len; -} ls_filter_t; - -typedef enum {poll_Closed, poll_Accepting, poll_Trying, poll_Open} poll_state; -typedef enum {poll_Unknown, poll_Client, poll_Master} poll_type; -struct { - struct pollfd *polls; - xdr_enc_t **enc; - xdr_dec_t **dec; - poll_state *state; - poll_type *type; - uint64_t *times; - ip_name_t *ipn; - ls_filter_t *space; - - Qu_t *outq; - uint32_t *outqlen; - - unsigned int maxi; - int coreIDX; - int listenFD; /* socket for new connections. */ -} poller; - -typedef struct { - int poll_idx; - int logging_in; - uint8_t start; - uint8_t stop; - hashn_t *pending_reqs; - Qu_t senderlist; - uint32_t senderlistlen; - uint32_t pendreqcnt; - uint64_t lastsentat; -} Masters_t; -Masters_t MastersList[256]; -/* index in array == lt_id */ - -char *lkeytob64(uint8_t *key, uint8_t keylen); -#if 0 -static void print_master_entry(int ltid) -{ - log_msg(lgm_Always, "poll_idx = %d\n", MastersList[ltid].poll_idx); - log_msg(lgm_Always, "logging_in = %d\n", MastersList[ltid].logging_in); - log_msg(lgm_Always, "start = %d\n", MastersList[ltid].start); - log_msg(lgm_Always, "stop = %d\n", MastersList[ltid].stop); - log_msg(lgm_Always, "pending_reqs = %p\n", MastersList[ltid].pending_reqs); -} -/** - * print_poller_entry - - * @idx: - * - * - */ -static void print_poller_entry(int idx) -{ - char *s; -#define CasedString(x) case (x): s = #x ; break; - log_msg(lgm_Always, "poller idx = %d\n", idx); - log_msg(lgm_Always, "polls[].fd = %d\n", poller.polls[idx].fd); - log_msg(lgm_Always, "polls[].events = %x\n", poller.polls[idx].events); - log_msg(lgm_Always, "polls[].revents = %x\n", poller.polls[idx].revents); - switch(poller.state[idx]){ - CasedString(poll_Closed); - CasedString(poll_Accepting); - CasedString(poll_Trying); - CasedString(poll_Open); - } - log_msg(lgm_Always, "state[] = %s\n", s); - switch(poller.type[idx]){ - CasedString(poll_Unknown); - CasedString(poll_Client); - CasedString(poll_Master); - } - log_msg(lgm_Always, "type[] = %s\n", s); - log_msg(lgm_Always, "times[] = %"PRId64"\n", poller.times[idx]); - log_msg(lgm_Always, "ipn[].name = %s\n", poller.ipn[idx].name); - log_msg(lgm_Always, "ipn[].ip = %s\n",iptostr(poller.ipn[idx].ip)); - log_msg(lgm_Always, "enc[] = %p\n", poller.enc[idx]); - log_msg(lgm_Always, "dec[] = %p\n", poller.dec[idx]); -#undef CasedString -} -#endif - -/** - * initialize_MastersList - - * - */ -void initialize_MastersList(void) -{ - int i; - for(i=0; i < 256; i++ ) { - MastersList[i].poll_idx = -1; - MastersList[i].logging_in = FALSE; - MastersList[i].pending_reqs = NULL; - MastersList[i].start = 0; - MastersList[i].stop = 0; - MastersList[i].senderlistlen = 0; - MastersList[i].pendreqcnt = 0; - Qu_init_head( &MastersList[i].senderlist ); - } - for(i=0; i < gulm_config.how_many_lts; i ++ ) { - int a,b; - get_lt_range(i, gulm_config.how_many_lts, &a, &b); - MastersList[i].start = a; - MastersList[i].stop = b; - MastersList[i].pending_reqs = create_new_req_map(); - } -} - -/** - * init_ltpx_poller - - * - * Returns: int - */ -int init_ltpx_poller(void) -{ - int i; - - memset(&poller, 0, sizeof(poller)); - - poller.polls = malloc(open_max() * sizeof(struct pollfd)); - if( poller.polls == NULL ) goto nomem; - memset(poller.polls, 0, (open_max() * sizeof(struct pollfd))); - - poller.type = malloc(open_max() * sizeof(poll_type)); - if( poller.type == NULL ) goto nomem; - - poller.state = malloc(open_max() * sizeof(poll_state)); - if( poller.state == NULL ) goto nomem; - - poller.times = malloc(open_max() * sizeof(uint64_t)); - if( poller.times == NULL ) goto nomem; - - poller.ipn = malloc(open_max() * sizeof(ip_name_t)); - if( poller.ipn == NULL ) goto nomem; - - poller.space = malloc(open_max() * sizeof(ls_filter_t)); - if( poller.space == NULL ) goto nomem; - - poller.enc = malloc(open_max() * sizeof(xdr_enc_t*)); - if( poller.enc == NULL ) goto nomem; - - poller.dec = malloc(open_max() * sizeof(xdr_dec_t*)); - if( poller.dec == NULL ) goto nomem; - - poller.outq = malloc(open_max() * sizeof(Qu_t)); - if( poller.outq == NULL ) goto nomem; - - poller.outqlen = malloc(open_max() * sizeof(uint32_t)); - if( poller.outqlen == NULL ) goto nomem; - - for(i=0; i < open_max(); i++) { - poller.polls[i].fd = -1; - poller.state[i] = poll_Closed; - poller.type[i] = poll_Unknown; - poller.times[i] = 0; - memset(&poller.ipn[i].ip, 0, sizeof(struct in6_addr)); - poller.ipn[i].name = NULL; - poller.enc[i] = NULL; - poller.dec[i] = NULL; - Qu_init_head( &poller.outq[i] ); - poller.outqlen[i] = 0; - } - - poller.maxi = 0; - poller.coreIDX = -1; - poller.listenFD = -1; - - return 0; -nomem: - if(poller.polls) free(poller.polls); - if(poller.state) free(poller.state); - if(poller.type) free(poller.type); - if(poller.times) free(poller.times); - if(poller.space) free(poller.space); - if(poller.ipn) free(poller.ipn); - if(poller.enc) free(poller.enc); - if(poller.dec) free(poller.dec); - return -ENOMEM; -} - -void release_ltpx_poller(void) -{ - if(poller.polls) free(poller.polls); - if(poller.state) free(poller.state); - if(poller.type) free(poller.type); - if(poller.times) free(poller.times); - if(poller.space) free(poller.space); - if(poller.ipn) free(poller.ipn); - if(poller.enc) free(poller.enc); - if(poller.dec) free(poller.dec); -} - -static int add_to_pollers(int fd, poll_state p, uint64_t t, - const char *name, const struct in6_addr *ip) -{ - int i; - for(i=0; poller.polls[i].fd >=0 && i< open_max(); i++); - if( i>= open_max() ) return -1; - - if(fcntl(fd, F_SETFD, FD_CLOEXEC ) <0) return -1; /* close on exec. */ - - poller.polls[i].fd = fd; - poller.polls[i].events = POLLIN; - if(i> poller.maxi) poller.maxi = i; - poller.state[i] = p; - poller.type[i] = poll_Unknown; - poller.times[i] = t; - memcpy(&poller.ipn[i].ip, ip, sizeof(struct in6_addr)); - if( name != NULL ) poller.ipn[i].name = strdup(name); - else poller.ipn[i].name = NULL; - poller.space[i].key = NULL; /* space of NULL is same as all */ - poller.space[i].len = 0; - poller.enc[i] = NULL; - poller.dec[i] = NULL; - /* you need to do the xdr seperate. */ - - return i; -} - -static int add_xdr_to_poller(int idx) -{ - if( idx < 0 ) return idx; - poller.enc[idx] = xdr_enc_init( poller.polls[idx].fd, 396); - if( poller.enc[idx] == NULL ) return -ENOMEM; - poller.dec[idx] = xdr_dec_init( poller.polls[idx].fd, 396); - if( poller.dec[idx] == NULL ) { - xdr_enc_release(poller.enc[idx]); - poller.enc[idx] = NULL; - return -ENOMEM; - } - return 0; -} - -/** - * get_ltid_from_poller_idx - - * @idx: - * - * - * Returns: int - */ -static int get_ltid_from_poller_idx(int idx) -{ - int lt_id; - for(lt_id = 0; lt_id < 256; lt_id ++) { - if( MastersList[lt_id].poll_idx == idx ) { - return lt_id; - } - } - return -1; -} - -int reset_master_login(int poll_idx) -{ - int lt_id; - if( (lt_id = get_ltid_from_poller_idx(poll_idx)) < 0 ) return -1; - MastersList[lt_id].poll_idx = -1; - MastersList[lt_id].logging_in = FALSE; - return 0; -} - -static void __inline__ close_by_idx(int idx) -{ - if( idx < 0 || idx > open_max() ) return; - log_msg(lgm_Network2, "Closing connection idx:%d, fd:%d to %s\n", - idx, poller.polls[idx].fd, poller.ipn[idx].name); - /* If we just closed the connect to the Master, set things up to try to - * re-find it. - * gotta do this before I wipe all the info out. - */ - if( poller.type[idx] == poll_Master ) { - int m; - m = reset_master_login(idx); - log_msg(lgm_Network2, "Connection to Master %d closed.\n", m); - } - - if( poller.coreIDX == idx ) - die(ExitGulm_Assertion, "Lost connection to core, cannot continue. " - "node reset required to re-activate cluster operations.\n" ); - GULMD_ASSERT( poller.polls[idx].fd != poller.listenFD , ); - - close( poller.polls[idx].fd ); - poller.polls[idx].fd = -1; - poller.polls[idx].revents = 0; /* clear any other events. */ - poller.state[idx] = poll_Closed; - poller.type[idx] = poll_Unknown; - poller.times[idx] = 0; - memset(&poller.ipn[idx].ip, 0, sizeof(struct in6_addr)); - if( poller.ipn[idx].name != NULL ) { - free(poller.ipn[idx].name); - poller.ipn[idx].name = NULL; - } - if( poller.space[idx].key != NULL ) { - free( poller.space[idx].key ); - poller.space[idx].key = NULL; - } - poller.space[idx].len = 0; - if( poller.enc[idx] != NULL ) { - xdr_enc_release(poller.enc[idx]); - poller.enc[idx] = NULL; - } - if( poller.dec[idx] != NULL ) { - xdr_dec_release(poller.dec[idx]); - poller.dec[idx] = NULL; - } -} - -void close_all_masters(void) -{ - int ltid; - log_msg(lgm_Network2, "Closing all Master connections\n"); - for(ltid=0; ltid < 256; ltid ++ ) { - if( MastersList[ltid].poll_idx >= 0 ) { - log_msg(lgm_Network2, "Closing Master ltid:%d pollidx:%d lgin:%d\n", - ltid, MastersList[ltid].poll_idx, MastersList[ltid].logging_in); - /* so close_by_idx() doesn't call reset_master_login(); */ - poller.type[MastersList[ltid].poll_idx] = poll_Unknown; - /* close it */ - close_by_idx(MastersList[ltid].poll_idx); - MastersList[ltid].poll_idx = -1; - MastersList[ltid].logging_in = FALSE; - } - } -} - -/** - * dump_all_master_tables - - * @oid: - * - * - * Returns: void - */ -void dump_all_master_tables(void) -{ - int ltid; - for(ltid=0; ltid < gulm_config.how_many_lts; ltid ++ ) { - dump_ltpx_stuff(&MastersList[ltid].senderlist, - MastersList[ltid].pending_reqs, ltid); - } -} - -int open_ltpx_listener(int port) -{ - poller.listenFD = serv_listen(port); - if( poller.listenFD < 0 ) return -1; - add_to_pollers(poller.listenFD, poll_Open, 0, "_ listener _", &in6addr_any); - /* no xdr on the listener socket. */ - return 0; -} - -/** - * open_jid_to_core - - * - * - * Returns: int - */ -int open_ltpx_to_core(void) -{ - struct sockaddr_in6 adr; - int cfd, err, idx; - uint64_t x_gen; - uint32_t x_code, x_error, x_rank; - uint8_t x_ama; - int connection_attempts = 0; - - if((cfd = socket(AF_INET6, SOCK_STREAM, 0)) <0) { - log_err("Failed to create socket. %d:%s\n", errno, strerror(errno)); - return -1; - } - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - adr.sin6_addr = in6addr_loopback; - adr.sin6_port = htons(gulm_config.corePort); - - while ( connect(cfd, (struct sockaddr*)&adr, sizeof(struct sockaddr_in6))<0) { - close(cfd); - - connection_attempts++; - if (connection_attempts > 3) { - log_err("Failed to connect to core, shutting down lock_gulmd_LTPX."); - return -1; - } - if (connection_attempts > 1) - log_err("Failed to connect to core. %d:%s\n", errno, strerror(errno)); - - sleep(5); - } - - idx = add_to_pollers(cfd, poll_Open, 0, "_ core _", &in6addr_loopback); - if( idx < 0 ) { - log_err("Failed to find unsed poller space.\n"); - close_by_idx(idx); - return -1; - } - if( add_xdr_to_poller(idx) < 0 ) { - log_err("Failed to allocate momeory for xdr.\n"); - close_by_idx(idx); - return -1; - } - - - do{ - if((err = xdr_enc_uint32(poller.enc[idx], gulm_core_reslgn_req))<0) break; - if((err = xdr_enc_uint32(poller.enc[idx], GIO_WIREPROT_VERS))<0) break; - if((err = xdr_enc_string(poller.enc[idx], gulm_config.clusterID))<0) - break; - if((err = xdr_enc_string(poller.enc[idx], "LTPX"))<0) break; - if((err = xdr_enc_uint32(poller.enc[idx], gulm_svc_opt_important)) <0) - break; - if((err = xdr_enc_flush(poller.enc[idx]))<0) break; - }while(0); - if(err != 0 ) { - log_err("Failed to send login request to core. %d:%d:%s\n", err, errno, - strerror(errno)); - close_by_idx(idx); - return -1; - } - - /* poll loop is not yet active, so we do the read right here. */ - - do{ - if((err = xdr_dec_uint32(poller.dec[idx], &x_code))<0) break; - if((err = xdr_dec_uint64(poller.dec[idx], &x_gen))<0) break; - if((err = xdr_dec_uint32(poller.dec[idx], &x_error))<0) break; - if((err = xdr_dec_uint32(poller.dec[idx], &x_rank))<0) break; - if((err = xdr_dec_uint8(poller.dec[idx], &x_ama))<0) break; - }while(0); - if( err != 0 ) { - log_err("Failed to receive login reply. %d:%d:%s\n", err, errno, - strerror(errno)); - close_by_idx(idx); - return -1; - } - - if( x_code != gulm_core_login_rpl ) { - log_err("Did not get the expected packet in return. got %#x\n", x_code); - close_by_idx(idx); - return -1; - } - if( x_error != gio_Err_Ok ) { - log_err("Core returned error %d:%s.\n", x_error, gio_Err_to_str(x_error)); - close_by_idx(idx); - return -1; - } - - poller.coreIDX = idx; - /* yeah! we're hooked up. */ - return 0; -} - -/*****************************************************************************/ -static int send_io_stats(xdr_enc_t *enc) -{ - struct timeval tv; - int ltid; - char tmp[256] = "4: There is no goat."; - - xdr_enc_string(enc, "I_am"); - xdr_enc_string(enc, gio_I_am_to_str(I_am_the)); - - if( MasterIN.name != NULL ) { - xdr_enc_string(enc, "Master"); - xdr_enc_string(enc, MasterIN.name); - } - - gettimeofday(&tv, NULL); - xdr_enc_string(enc, "run time"); - snprintf(tmp, 256, "%lu", tv.tv_sec - Started_at.tv_sec ); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "pid"); - snprintf(tmp, 256, "%u", getpid()); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "verbosity"); - get_verbosity_string(tmp, 256, verbosity); - xdr_enc_string(enc, tmp); - - xdr_enc_string(enc, "clientoutqueue"); - snprintf(tmp, 256, "%lu", totaloutqueue); - xdr_enc_string(enc, tmp); - - for(ltid=0; ltid < gulm_config.how_many_lts; ltid ++ ) { - snprintf(tmp, 256, "Master.%d.senderlistlen", ltid); - xdr_enc_string(enc, tmp); - snprintf(tmp, 256, "%u", MastersList[ltid].senderlistlen); - xdr_enc_string(enc, tmp); - - snprintf(tmp, 256, "Master.%d.pendreqcnt", ltid); - xdr_enc_string(enc, tmp); - snprintf(tmp, 256, "%u", MastersList[ltid].pendreqcnt); - xdr_enc_string(enc, tmp); - } - - return 0; -} - -/*****************************************************************************/ -static int accept_connection(void) -{ - int clisk, i; - struct sockaddr_in6 adr; - - i = sizeof(struct sockaddr_in6); - if( (clisk = accept(poller.listenFD, (struct sockaddr*)&adr, &i)) <0) { - log_err("error in accept: %s", strerror(errno)); - return -1; - } - - if( set_opts(clisk) <0) { - log_err("Cannot set socket options for new connection. Killing it.\n"); - close(clisk); - return -1; - } - - i = add_to_pollers(clisk, poll_Accepting, tvs2uint64(NOW), - ip6tostr(&adr.sin6_addr), &adr.sin6_addr); - if( i < 0 ) { - log_err("Failed to add new socket to poller list. %s\n", strerror(errno)); - close(clisk); - return -1; - } - if( add_xdr_to_poller(i) != 0 ) { - log_err("Failed to attatch xdr to new socket do to lack of memory.\n"); - close_by_idx(i); - return -1; - } - - log_msg(lgm_Network2, "Accepted Connection idx:%d, fd:%d to %s\n", - i, poller.polls[i].fd, poller.ipn[i].name); - return 0; -} - -/*****************************************************************************/ -/** - * send_lk_st_req - - * @ltid: - * @lq: - * - * FIXME Things can get stuck here if this was writing to the master when - * it died. Evilly is that even though core is quick about figuring and - * broadcasting that out, we're stuck in our single thread behind a write. - * - * Returns: int - */ -int send_lk_st_req(int ltid, lock_req_t *lq) -{ - int err=0; - xdr_enc_t *enc; - if(ltid > 255 || ltid < 0 ) { - return -EINVAL; - } - if( MastersList[ltid].poll_idx < 0 || - MastersList[ltid].poll_idx > open_max() ) { - /* master has gone away, don't try to send to them. This will end up - * just queuing the req for later. - */ - return -EINVAL; - } - enc = poller.enc[MastersList[ltid].poll_idx]; - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_state_req)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, lq->flags)) != 0 ) break; - if( lq->flags & gio_lck_fg_hasLVB ) - if((err = xdr_enc_raw(enc, lq->lvb, lq->lvblen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s sending to lt%03d\n", - err, strerror(abs(err)), ltid); - } - return err; -} - -/** - * send_lk_act_req - - * @ltid: - * @lq: - * - * - * Returns: int - */ -int send_lk_act_req(int ltid, lock_req_t *lq) -{ - int err=0; - xdr_enc_t *enc; - if(ltid > 255 || ltid < 0 ) { - return -EINVAL; - } - if( MastersList[ltid].poll_idx < 0 || - MastersList[ltid].poll_idx > open_max() ) { - /* master has gone away, don't try to send to them. This will end up - * just queuing the req for later. - */ - return -EINVAL; - } - enc = poller.enc[MastersList[ltid].poll_idx]; - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_action_req)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if( lq->state == gio_lck_st_SyncLVB ) - if((err = xdr_enc_raw(enc, lq->lvb, lq->lvblen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s sending to lt%03d\n", - err, strerror(err), ltid); - } - return err; -} - -/** - * send_lk_drop_req - - * @ltid: - * @lq: - * - * - * Returns: int - */ -int send_lk_drop_req(int ltid, lock_req_t *lq) -{ - int err=0; - xdr_enc_t *enc; - if(ltid > 255 || ltid < 0 ) { - return -EINVAL; - } - if( MastersList[ltid].poll_idx < 0 || - MastersList[ltid].poll_idx > open_max() ) { - /* master has gone away, don't try to send to them. This will end up - * just queuing the req for later. - */ - return -EINVAL; - } - enc = poller.enc[MastersList[ltid].poll_idx]; - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_drop_exp)) != 0 ) break; - if((err = xdr_enc_string(enc, lq->lvb)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s sending to lt%03d\n", - err, strerror(err), ltid); - } - return err; -} - -/** - * send_lk_expire - - * @ltid: - * @lq: - * - * - * Returns: int - */ -int send_lk_expire(int ltid, lock_req_t *lq) -{ - int err=0; - xdr_enc_t *enc; - if(ltid > 255 || ltid < 0 ) { - return -EINVAL; - } - if( MastersList[ltid].poll_idx < 0 || - MastersList[ltid].poll_idx > open_max() ) { - /* master has gone away, don't try to send to them. This will end up - * just queuing the req for later. - */ - return -EINVAL; - } - enc = poller.enc[MastersList[ltid].poll_idx]; - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_expire)) != 0 ) break; - if((err = xdr_enc_string(enc, lq->lvb)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s sending to lt%03d\n", - err, strerror(err), ltid); - } - return err; -} - -/** - * send_lk_query_req - - * @ltid: - * @lq: - * - * - * Returns: int - */ -int send_lk_query_req(int ltid, lock_req_t *lq) -{ - int err=0; - xdr_enc_t *enc; - if(ltid > 255 || ltid < 0 ) { - return -EINVAL; - } - if( MastersList[ltid].poll_idx < 0 || - MastersList[ltid].poll_idx > open_max() ) { - /* master has gone away, don't try to send to them. This will end up - * just queuing the req for later. - */ - return -EINVAL; - } - enc = poller.enc[MastersList[ltid].poll_idx]; - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_query_req)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s sending to lt%03d\n", - err, strerror(abs(err)), ltid); - } - return err; -} -/*****************************************************************************/ - -/** - * find_in_senders_list - - * @ltid: - * @lock_req_t: - * - * gross, but I don't know where else to look. - * - * Returns: int - */ -int find_in_senders_list(int ltid, lock_req_t *search) -{ - lock_req_t *lq; - LLi_t *q; - - for( q = LLi_next(&MastersList[ltid].senderlist); - NULL != LLi_data(q); - q = LLi_next(q) ) - { - lq = LLi_data(q); - if( search->subid == lq->subid && - memcmp(search->key, lq->key, MIN(search->keylen, lq->keylen)) == 0 ) { - log_msg(lgm_Always, "XXX Found in senders %s\n", - lkeytob64(search->key, search->keylen)); - return TRUE; - } - } - return FALSE; -} - -/** - * resend_reqs - - * @item: - * @misc: - * - * - * Returns: int - */ -int resend_reqs(LLi_t *item, void *misc) -{ - lock_req_t *lq = LLi_data(item); - int ltid = *((int*)misc); - - find_in_senders_list(ltid, lq); - /* move to sender queue */ - LLi_del(item); - LLi_unhook(item); - Qu_EnQu_Front(&MastersList[ltid].senderlist, item); - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - MastersList[ltid].senderlistlen ++; - MastersList[ltid].pendreqcnt --; - - return 0; -} - -/*****************************************************************************/ -/** - * logintoMaster - - * - * Returns: int - */ -static int logintoMaster(int lt_id) -{ - struct sockaddr_in6 adr; - int idx,cmFD,err; - xdr_enc_t *xdr; - - /* socket connect to CM */ - if((cmFD = socket(AF_INET6, SOCK_STREAM, 0)) <0){ - log_err("Failed to create socket. %s\n", strerror(errno)); - return -1; - } - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - memcpy(&adr.sin6_addr, &MasterIN.ip, sizeof(struct in6_addr)); - adr.sin6_port = htons(gulm_config.lt_port + lt_id); - - if( connect(cmFD, (struct sockaddr*)&adr, sizeof(struct sockaddr_in6))<0) { - close(cmFD); - log_msg(lgm_LoginLoops, "Cannot connect %s (%s)\n", - print_ipname(&MasterIN), strerror(errno)); - return -1; - /* need to go to next here */ - } - - if( set_opts(cmFD) <0) { - close(cmFD); - log_msg(lgm_LoginLoops, "Failed to set options (%s)\n", strerror(errno)); - return -1; - } - - /* */ - idx = add_to_pollers(cmFD, poll_Trying, tvs2uint64(NOW), - MasterIN.name, &MasterIN.ip); - - MastersList[lt_id].poll_idx = idx; - - if( idx < 0 ) { /* out of free FDs. */ - log_err("Failed to find unused poller space.\n"); - close_by_idx(idx); - return -1; - } - poller.type[idx] = poll_Master; - if( add_xdr_to_poller(idx) < 0 ) { - log_err("Failed to allocate memory for xdr.\n"); - close_by_idx(idx); - return -1; - } - - /* send login request */ - xdr = poller.enc[idx]; - - do { - if((err = xdr_enc_uint32(xdr, gulm_lock_login_req)) != 0) break; - if((err = xdr_enc_uint32(xdr, GIO_WIREPROT_VERS)) != 0) break; - if((err = xdr_enc_string(xdr, myName)) != 0) break; - if((err = xdr_enc_uint8(xdr, gio_lck_st_Client)) != 0) break; - if((err = xdr_enc_flush(xdr)) != 0) break; - }while(0); - if( err != 0 ) { - log_msg(lgm_LoginLoops, "Errors trying to send login request. %d:%s\n", - err, strerror(errno)); - close_by_idx(idx); - return -1; - } - - MastersList[lt_id].logging_in = TRUE; - - return 0; -} - -/** - * recv_Masterlogin_reply - - * @idx: - * - * - * Returns: int - */ -static int recv_Masterlogin_reply(int idx) -{ - int err, ltid=-1; - uint32_t code=0; - uint32_t rpl_err=1; - uint8_t rpl_ama=0; - xdr_dec_t *dec = poller.dec[idx]; - - /* recv login reply */ - do { - if((err = xdr_dec_uint32(dec, &code)) != 0) break; - if( code != gulm_lock_login_rpl ) {err=-1; errno=EPROTO; break;} - if((err = xdr_dec_uint32(dec, &rpl_err)) != 0) break; - if((err = xdr_dec_uint8(dec, &rpl_ama)) != 0) break; - } while(0); - if( err != 0 ) { - log_err("Errors trying to login to LockTable Master: " - "(%s idx:%d fd:%d) %d:%s\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd, - err, strerror(errno)); - goto exit; - } - - if( (ltid = get_ltid_from_poller_idx(idx)) < 0 ) { - log_err("Got reply from a LockTable Master that we cannot match an " - "ltid too. (%s idx:%d fd:%d)\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - err = -EAGAIN; - goto exit; - } - - if( rpl_err != 0 ) { - log_msg(lgm_Always, - "Errors trying to login to LT%03d: (%s) %d:%s\n", - ltid, - print_ipname(&poller.ipn[idx]), - rpl_err, gio_Err_to_str(rpl_err)); - err = rpl_err; - goto exit; - } - - if( rpl_ama != gio_Mbr_ama_Master ) { - log_msg(lgm_Always, "Node %s is not a LockTable Master server.\n", - print_ipname(&poller.ipn[idx])); - err = -EAGAIN; - goto exit; - } - - poller.state[idx] = poll_Open; - poller.times[idx] = 0; - log_msg(lgm_Network, "Logged into LT%03d at %s\n", ltid, - print_ipname(&MasterIN)); - - if( MastersList[ltid].pending_reqs == NULL ) { - log_err("Totally not good, we'll attempt to savlage" - "But this ship is probably leaking.\n"); - MastersList[ltid].pending_reqs = create_new_req_map(); - }else - { - err = hashn_walk(MastersList[ltid].pending_reqs, resend_reqs, <id); - if( err != 0 ) { - log_err("%d trying to resend requsts to LT%03d\n", err, ltid); - } - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - - } - - log_msg(lgm_Network, "Finished resending to LT%03d\n", ltid); - -exit: - if(ltid >= 0) MastersList[ltid].logging_in = FALSE; - return err; -} - -/** - * checkup_masters - - * - * Restart the log in if it isn't there for one of the masters. - */ -void checkup_masters(void) -{ - int ltid; - - for(ltid=0; ltid < gulm_config.how_many_lts; ltid++) { - if( MastersList[ltid].poll_idx < 0 && - MastersList[ltid].logging_in == FALSE ) { - logintoMaster(ltid); - } - } -} - - -/** - * logout_of_Masters - - */ -void logout_of_Masters(void) -{ - int ltid, err; - xdr_enc_t *xdr; - - for(ltid=0; ltid < gulm_config.how_many_lts; ltid++) { - if( MastersList[ltid].poll_idx != -1 ) { - xdr = poller.enc[MastersList[ltid].poll_idx]; - - do { - if((err = xdr_enc_uint32(xdr, gulm_lock_logout_req)) != 0) break; - if((err = xdr_enc_flush(xdr)) != 0) break; - }while(0); - if(err != 0 ) { - log_err("couldn't send logout request. %d:%s\n", - err, strerror(err)); - } - } - } -} - -/*****************************************************************************/ -/** - * send_senderlist - - * @ltid: - * - * Returns: int - */ -int send_senderlist(int ltid) -{ - int err = 0; - lock_req_t *lq; - Qu_t *q; - - /* only run one item at a time. - * need to get back to poll(). - * */ - if( !Qu_empty( &MastersList[ltid].senderlist ) ) { - /* send next. */ - q = Qu_DeQu(&MastersList[ltid].senderlist); - MastersList[ltid].senderlistlen --; - LLi_unhook(q); - lq = Qu_data(q); - switch(lq->code) { - case gulm_lock_state_req: - err = send_lk_st_req(ltid, lq); - break; - case gulm_lock_action_req: - err = send_lk_act_req(ltid, lq); - break; - case gulm_lock_drop_exp: - err = send_lk_drop_req(ltid, lq); - break; - case gulm_lock_expire: - err = send_lk_expire(ltid, lq); - break; - case gulm_lock_query_req: - err = send_lk_query_req(ltid, lq); - break; - default: - log_err("Unexpected opcode (%x:%s) on lock %s\n", - lq->code, gio_opcodes(lq->code), - lkeytob64(lq->key, lq->keylen)); - break; - } - if( err != 0 ) { - log_err("Got a %d:%s trying to send packet to Master %d on %s\n", - err, strerror(abs(err)), ltid, - lkeytob64(lq->key, lq->keylen)); - /* stick it back on the queue. else we loose it. */ - Qu_EnQu_Front(&MastersList[ltid].senderlist, q); - MastersList[ltid].senderlistlen ++; - goto exit; - } - - if( lq->code == gulm_lock_drop_exp || lq->code == gulm_lock_expire ) { - /* no replies for drop exp requests. */ - recycle_lock_req(lq); - }else - { - err = hashn_add( MastersList[ltid].pending_reqs, &lq->ls_list); - if( err != 0 ) { - log_err("AH! Postponed Dup Entries! Horror! Horror!\n"); - } - MastersList[ltid].pendreqcnt ++; - } - } - - if( Qu_empty( &MastersList[ltid].senderlist ) ) - poller.polls[MastersList[ltid].poll_idx].events &= ~POLLOUT; - -exit: - return err; -} - -/*****************************************************************************/ - -/* fixed 12byte-to-1byte hash. - * given everything is fixed lengths, I should be able to make a nice fast - * one. (/should/...) - * - * I hope this works well enough..... This should show how little I know - * about hash functions.... (tests show it to seemingly work well enough.) - */ -uint8_t __inline__ fourtoone(uint32_t bighash) -{ - uint8_t hash; - hash = (bighash >> 0); - hash ^= (bighash >> 8); - hash ^= (bighash >> 16); - hash ^= (bighash >> 24); - return hash; -} - -/** - * select_master_server - - * @key: - * @keylen: - * - * returns ltid of the master this key goes to. - * - * Returns: int - */ -int select_master_server(uint8_t *key, uint16_t keylen) -{ - uint8_t tblkey; - int ltid; - - /* If there is only one locktable, we don't need to do the math below to - * know that this lock will go onto that locktable. - */ - if( gulm_config.how_many_lts == 1 ) return 0; - - /* look into some other way of deciding which table gets which keys. */ - tblkey = fourtoone(crc32(key, keylen, 0x6d696b65)); - - for(ltid=0; ltid < gulm_config.how_many_lts; ltid ++) { - if( tblkey >= MastersList[ltid].start && - tblkey < MastersList[ltid].stop ) { - break; - } - } - /* now, since the loop above avoids overlap, it also missed anyone with - * a tblkey of 255, so that is still wrong. It is one more than it - * should be. But we'll just generalize the whole thing and do a MIN(). - */ - return MIN(ltid, (gulm_config.how_many_lts - 1)); -} - -/** - * store_and_forward_lock_state - - * @idx: - * - * from a client to a master lt - * - * Returns: int - */ -int store_and_forward_lock_state(int idx) -{ - int err, ltid; - uint8_t *x_name=NULL; - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - lock_req_t *lq; - - if( (lq=get_new_lock_req()) == NULL ) { - die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->code = gulm_lock_state_req; - lq->poll_idx = idx; - - do{ - if((err = xdr_dec_raw_m(dec, (void**)&lq->key, &lq->keylen)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &lq->state)) != 0 ) break; - if((err = xdr_dec_uint32(dec, &lq->flags)) != 0 ) break; - if( lq->flags & gio_lck_fg_hasLVB ) { - if((err = xdr_dec_raw_m(dec, (void**)&lq->lvb, &lq->lvblen)) != 0 ) - break; - }else{ - lq->lvb = NULL; - lq->lvblen = 0; - } - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - - /* which master gets it? */ - ltid = select_master_server(lq->key, lq->keylen); - - /* check for duplicates */ - if( hashn_find(MastersList[ltid].pending_reqs, &lq->ls_list)!=NULL || - find_in_senders_list(ltid, lq) ){ - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_state_rpl)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, lq->flags & ~gio_lck_fg_hasLVB)) != 0 ) - break; - if((err = xdr_enc_uint32(enc, gio_Err_AlreadyPend)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - recycle_lock_req(lq); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - goto exit; - } - - /* add it to the sender list. */ - Qu_EnQu( &MastersList[ltid].senderlist, &lq->ls_list); - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - MastersList[ltid].senderlistlen ++; - -exit: - if( x_name != NULL) free(x_name); - return 0; -} - -/** - * store_and_forward_lock_action - - * @idx: - * - * from a client to a master lt - * - * Returns: int - */ -int store_and_forward_lock_action(int idx) -{ - int err, ltid; - uint8_t *x_name=NULL; - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - lock_req_t *lq; - - if( (lq=get_new_lock_req()) == NULL ) { - die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->code = gulm_lock_action_req; - lq->poll_idx = idx; - - do{ - if((err = xdr_dec_raw_m(dec, (void**)&lq->key, &lq->keylen)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->subid)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &lq->state)) != 0 ) break; - if( lq->state == gio_lck_st_SyncLVB ) { - if((err = xdr_dec_raw_m(dec, (void**)&lq->lvb, &lq->lvblen)) != 0 ) - break; - }else{ - lq->lvb = NULL; - lq->lvblen = 0; - } - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - - /* which master gets it? */ - ltid = select_master_server(lq->key, lq->keylen); - - /* Cancels don't have replies, so don't bother storing it. - * besides, the request they're canceling is already there and would - * cause a hash key collision. - * */ - if( lq->state == gio_lck_st_Cancel) { - send_lk_act_req(ltid, lq); - recycle_lock_req(lq); - goto exit; - } - - /* check for dups. */ - if( hashn_find( MastersList[ltid].pending_reqs, &lq->ls_list)!=NULL || - find_in_senders_list(ltid, lq) ) { - /* send dup error */ - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_action_rpl)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, gio_Err_AlreadyPend)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - recycle_lock_req(lq); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - goto exit; - } - - /* add it to the sender list. */ - Qu_EnQu( &MastersList[ltid].senderlist, &lq->ls_list); - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - MastersList[ltid].senderlistlen ++; - -exit: - if( x_name != NULL) free(x_name); - return 0; -} - -/** - * store_and_forward_lock_query - - * @idx: - * - * - * Returns: int - */ -int store_and_forward_lock_query(int idx) -{ - int err, ltid; - uint8_t *x_name=NULL; - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - lock_req_t *lq; - - if( (lq=get_new_lock_req()) == NULL ) { - die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->code = gulm_lock_query_req; - lq->poll_idx = idx; - - do{ - if((err = xdr_dec_raw_m(dec, (void**)&lq->key, &lq->keylen)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &lq->stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &lq->state)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - - /* which master gets it? */ - ltid = select_master_server(lq->key, lq->keylen); - - /* check for dups. */ - if( hashn_find( MastersList[ltid].pending_reqs, &lq->ls_list)!=NULL || - find_in_senders_list(ltid, lq) ) { - /* send dup error */ - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_action_rpl)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, gio_Err_AlreadyPend)) != 0 ) break; - if((err = xdr_enc_list_start(enc)) != 0 ) return err; - /* no holders on error. */ - if((err = xdr_enc_list_stop(enc)) != 0 ) return err; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - recycle_lock_req(lq); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - goto exit; - } - - /* add it to the sender list. */ - Qu_EnQu( &MastersList[ltid].senderlist, &lq->ls_list); - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - MastersList[ltid].senderlistlen ++; - -exit: - if( x_name != NULL) free(x_name); - return 0; -} -/** - * forward_drop_exp - - * @idx: - * - * from a client to all Master LTs - * - * Returns: int - */ -int forward_drop_exp(int idx) -{ - int err, ltid; - xdr_dec_t *dec = poller.dec[idx]; - lock_req_t *lq; - uint8_t *x_name=NULL, *x_mask=NULL; - uint16_t x_ml; - - do{ - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&x_mask, &x_ml)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - - for(ltid = 0; ltid < gulm_config.how_many_lts; ltid++) { - /* create a request for each Master. */ - if( (lq=get_new_lock_req()) == NULL ) { - die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->code = gulm_lock_drop_exp; - lq->poll_idx = idx; - - /* copy copy copy */ - if( x_name == NULL ) { - lq->lvb = NULL; - }else{ - lq->lvb = strdup(x_name); - if( lq->lvb == NULL ) die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->key = malloc(x_ml); - if( lq->key == NULL ) die(ExitGulm_NoMemory, "Out of memory\n"); - memcpy(lq->key, x_mask, x_ml); - lq->keylen = x_ml; - - Qu_EnQu( &MastersList[ltid].senderlist, &lq->ls_list); - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - MastersList[ltid].senderlistlen ++; - } - - if(x_name != NULL ) free(x_name); - if(x_mask != NULL ) free(x_mask); - return 0; -} - -/** - * forward_expire - - * @idx: - * - * - * Returns: int - */ -int forward_expire(int idx) -{ - int err, ltid; - xdr_dec_t *dec = poller.dec[idx]; - lock_req_t *lq; - uint8_t *x_name=NULL, *x_mask=NULL; - uint16_t x_ml; - - do{ - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_raw_m(dec, (void**)&x_mask, &x_ml)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - - for(ltid = 0; ltid < gulm_config.how_many_lts; ltid++) { - /* create a request for each Master. */ - if( (lq=get_new_lock_req()) == NULL ) { - die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->code = gulm_lock_expire; - lq->poll_idx = idx; - - /* copy copy copy */ - if( x_name == NULL ) { - lq->lvb = NULL; - }else{ - lq->lvb = strdup(x_name); - if( lq->lvb == NULL ) die(ExitGulm_NoMemory, "Out of memory\n"); - } - lq->key = malloc(x_ml); - if( lq->key == NULL ) die(ExitGulm_NoMemory, "Out of memory\n"); - memcpy(lq->key, x_mask, x_ml); - lq->keylen = x_ml; - - Qu_EnQu( &MastersList[ltid].senderlist, &lq->ls_list); - poller.polls[MastersList[ltid].poll_idx].events |= POLLOUT; - MastersList[ltid].senderlistlen ++; - } - - if(x_name != NULL ) free(x_name); - if(x_mask != NULL ) free(x_mask); - return 0; -} - -/****************************************************************************/ -int send_lock_state_rpl(int idx, lock_req_t *lq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_state_rpl)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, lq->flags)) != 0 ) break; - if((err = xdr_enc_uint32(enc, lq->error)) != 0 ) break; - if( lq->flags & gio_lck_fg_hasLVB) - if((err = xdr_enc_raw(enc, lq->lvb, lq->lvblen)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -int send_lock_action_rpl(int idx, lock_req_t *lq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_action_rpl)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, lq->error)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -int send_lock_cb_state(int idx, lock_req_t *lq) -{ - int err; - xdr_enc_t *enc = poller.enc[idx]; - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_cb_state)) != 0 ) break; - if((err = xdr_enc_raw(enc, lq->key, lq->keylen)) != 0 ) break; - if((err = xdr_enc_uint64(enc, lq->subid)) != 0 ) break; - if((err = xdr_enc_uint8(enc, lq->state)) != 0 ) break; - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - return err; -} - -static void send_some_data(int idx) -{ - LLi_t *tmp; - lock_req_t *lq; - int err=0; - - if( !Qu_empty(&poller.outq[idx]) ) { - tmp = Qu_DeQu(&poller.outq[idx]); - lq = Qu_data(tmp); - totaloutqueue --; - poller.outqlen[idx] --; - switch(lq->code) { - case gulm_lock_state_rpl: - err = send_lock_state_rpl(idx, lq); - break; - case gulm_lock_action_rpl: - err = send_lock_action_rpl(idx, lq); - break; - case gulm_lock_cb_state: - err = send_lock_cb_state(idx, lq); - break; - default: - log_msg(lgm_Network, "Cannot send packet type %#x:%s !\n", - lq->code, gio_opcodes(lq->code)); - break; - } - recycle_lock_req(lq); - } - - if( Qu_empty(&poller.outq[idx]) ) poller.polls[idx].events &= ~POLLOUT; -} - -void queue_send_lock_req(int idx, lock_req_t *lq) -{ - /* really need these two? */ - LLi_del(&lq->ls_list); - LLi_unhook(&lq->ls_list); - - Qu_EnQu(&poller.outq[idx], &lq->ls_list); - poller.outqlen[idx] ++; - totaloutqueue ++; - poller.polls[idx].events |= POLLOUT; -} -/****************************************************************************/ -/** - * forward_drop_all - - * @idx: - * - * From a Master LT to all clients. - * - * Returns: int - */ -int forward_drop_all(int idx) -{ - int i, err; - xdr_enc_t *enc; - for(i=0; i <= poller.maxi; i++ ) { - if( poller.polls[i].fd < 0 ) continue; - if( poller.type[i] != poll_Client ) continue; - enc = poller.enc[i]; - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_cb_dropall)) != 0) break; - if((err = xdr_enc_flush(enc)) != 0) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - } - } - return 0; -} - -char *lkeytob64(uint8_t *key, uint8_t keylen); - -/** - * retrive_and_relpy_lock_state - - * @idx: - * - * from master to client - * - * Returns: int - */ -int retrive_and_relpy_lock_state(int idx) -{ - int err, ltid=-1; - uint32_t x_error; - uint16_t x_kl, x_ll; - LLi_t *tmp; - xdr_dec_t *dec = poller.dec[idx]; - lock_req_t searchkey; - /* keep these around. Fewer mallocs == faster */ - static uint8_t *x_key=NULL, *x_lvb=NULL; - static uint16_t x_kbl=0, x_lbl=0; - - ltid = get_ltid_from_poller_idx(idx); - if( ltid < 0 ) { - log_err("Theres not master lt id for poller %d\n", idx); - goto exit; - } - - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&x_key, &x_kbl, &x_kl)) != 0) break; - if((err = xdr_dec_uint64(dec, &searchkey.subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &searchkey.start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &searchkey.stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &searchkey.state)) != 0) break; - if((err = xdr_dec_uint32(dec, &searchkey.flags)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0) break; - if( searchkey.flags & gio_lck_fg_hasLVB) - if((err = xdr_dec_raw_ag(dec, (void**)&x_lvb, &x_lbl, &x_ll)) != 0) - break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - goto exit; - } - - /* lookup/delete from hashmap. - * if not there, drop. - * if there, forward reply to lq->poll_idx - */ - LLi_init( &searchkey.ls_list, &searchkey); - searchkey.key = x_key; - searchkey.keylen = x_kl; - - tmp = hashn_del(MastersList[ltid].pending_reqs, &searchkey.ls_list); - - MastersList[ltid].pendreqcnt --; - if( tmp != NULL ) { - lock_req_t *lq; - lq = LLi_data(tmp); - /* copy in LVB */ - if( searchkey.flags & gio_lck_fg_hasLVB ) { - uint8_t *tmp; - tmp = realloc(lq->lvb, x_ll); - if( tmp == NULL ) die(ExitGulm_NoMemory,"Out of Memory.\n"); - lq->lvb = tmp; - lq->lvblen = x_ll; - memcpy(lq->lvb, x_lvb, x_ll); - } - - lq->code = gulm_lock_state_rpl; - lq->error = x_error; - queue_send_lock_req(lq->poll_idx, lq); - } - -exit: - return 0; -} - - -/** - * retrive_and_relpy_lock_action - - * @idx: - * - * from master to client - * - * Returns: int - */ -int retrive_and_relpy_lock_action(int idx) -{ - int err, ltid; - uint64_t x_subid; - uint32_t x_error; - uint16_t x_kl; - uint8_t x_st; - LLi_t *tmp; - xdr_dec_t *dec = poller.dec[idx]; - lock_req_t searchkey; - static uint8_t *x_key=NULL; - static uint16_t x_kbl=0; - - ltid = get_ltid_from_poller_idx(idx); - if( ltid < 0 ) { - log_err("Theres not master lt id for poller %d\n", idx); - goto exit; - } - - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&x_key, &x_kbl, &x_kl)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_st)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - goto exit; - } - - /* lookup/delete from hashmap. - * if not there, drop. - * if there, forward reply to lq->poll_idx - */ - LLi_init( &searchkey.ls_list, &searchkey); - searchkey.key = x_key; - searchkey.keylen = x_kl; - searchkey.subid = x_subid; - tmp = hashn_del(MastersList[ltid].pending_reqs, &searchkey.ls_list); - MastersList[ltid].pendreqcnt --; - if( tmp != NULL ) { - lock_req_t *lq = LLi_data(tmp); - lq->code = gulm_lock_action_rpl; - lq->error = x_error; - queue_send_lock_req(lq->poll_idx, lq); - } - -exit: - return 0; -} - -/** - * retrive_and_relpy_lock_query - - * @idx: - * - * - * Returns: int - */ -int retrive_and_relpy_lock_query(int idx) -{ - int err, ltid=-1; - uint32_t x_error; - uint16_t x_kl; - LLi_t *tmp; - xdr_dec_t *dec = poller.dec[idx]; - lock_req_t searchkey; - uint64_t x_subid=0, x_start=0, x_stop=0; - uint8_t x_state=0; - /* keep these around. Fewer mallocs == faster */ - static uint8_t *x_key=NULL, *x_nn=NULL; - static uint16_t x_kbl=0, x_nbl=0; - - ltid = get_ltid_from_poller_idx(idx); - if( ltid < 0 ) { - log_err("There is no master lt id for poller %d\n", idx); - goto exit; - } - - if( x_nn != NULL && x_nbl > 0 ) x_nn[0] = '\0'; - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&x_key, &x_kbl, &x_kl)) != 0) break; - if((err = xdr_dec_uint64(dec, &searchkey.subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &searchkey.start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &searchkey.stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &searchkey.state)) != 0) break; - if((err = xdr_dec_uint32(dec, &x_error)) != 0) break; - - /* XXX XXX Kludge warning! - * damn lazy programmer wrote this to only work for one holder. so - * all but the last are passed on. - * - * This will bite me in the ass later. - */ - if((err = xdr_dec_list_start(dec)) != 0) break; - while( xdr_dec_list_stop(dec) != 0 ) { - if((err = xdr_dec_string_ag(dec, &x_nn, &x_nbl)) != 0) break; - if((err = xdr_dec_uint64(dec, &x_subid)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &x_start)) != 0 ) break; - if((err = xdr_dec_uint64(dec, &x_stop)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_state)) != 0) break; - } - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - goto exit; - } - - /* lookup/delete from hashmap. - * if not there, drop. - * if there, forward reply to lq->poll_idx - */ - LLi_init( &searchkey.ls_list, &searchkey); - searchkey.key = x_key; - searchkey.keylen = x_kl; - - tmp = hashn_del(MastersList[ltid].pending_reqs, &searchkey.ls_list); - - MastersList[ltid].pendreqcnt --; - if( tmp != NULL ) { - lock_req_t *lq; - xdr_enc_t *enc; - - lq = LLi_data(tmp); - enc = poller.enc[ lq->poll_idx ]; - if( enc == NULL ) { - /* FIXME Ummm, what to do here? */ - log_err("Client left before getting reply.\n"); - recycle_lock_req(lq); - goto exit; - } - - do{ - if((err = xdr_enc_uint32(enc, gulm_lock_query_rpl)) != 0 ) break; - if((err = xdr_enc_raw(enc, x_key, x_kl)) != 0 ) break; - if((err = xdr_enc_uint64(enc, searchkey.subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, searchkey.start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, searchkey.stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, searchkey.state)) != 0 ) break; - if((err = xdr_enc_uint32(enc, x_error)) != 0 ) break; - - /* XXX XXX The Kludge continues! - * yeah, so again, only one holder is passed through. - * - * If you change this, You need to fix the library interface too. - */ - if((err = xdr_enc_list_start(enc)) != 0 ) return err; - if((err = xdr_enc_string(enc, x_nn)) != 0 ) break; - if((err = xdr_enc_uint64(enc, x_subid)) != 0 ) break; - if((err = xdr_enc_uint64(enc, x_start)) != 0 ) break; - if((err = xdr_enc_uint64(enc, x_stop)) != 0 ) break; - if((err = xdr_enc_uint8(enc, x_state)) != 0 ) break; - if((err = xdr_enc_list_stop(enc)) != 0 ) return err; - - if((err = xdr_enc_flush(enc)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - goto exit; - } - - recycle_lock_req(lq); - } - -exit: - return 0; -} - - -/** - * forward_cb_to_some_clients - - * @idx: - * - * from master to clients - * - * this function will not work if this get threaded. (so don't do that.) - * - * Returns: int - */ -int forward_cb_to_some_clients(int idx) -{ - int i, err; - uint64_t x_sbd; - uint16_t x_kl; - uint8_t x_st; - xdr_dec_t *dec = poller.dec[idx]; - lock_req_t *lq; - - /* keep these around. Fewer mallocs == faster */ - static uint8_t *x_key=NULL; - static uint16_t x_kbl=0; - - do{ - if((err = xdr_dec_raw_ag(dec, (void**)&x_key, &x_kbl, &x_kl)) != 0 ) - break; - if((err = xdr_dec_uint64(dec, &x_sbd)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_st)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("XDR error %d:%s\n", err, strerror(err)); - goto exit; - } - - /* should look into ways of making this loop faster. - * maybe it shouldn't be a loop? - */ - for(i=0; i <= poller.maxi; i++) { - if( poller.polls[i].fd < 0 ) continue; - if( poller.type[i] != poll_Client ) continue; - if( poller.space[i].key != NULL && - /* this cmp is not correct. or is it? seems to be ok */ - memcmp(poller.space[i].key, x_key, MIN(poller.space[i].len,x_kl))!=0 - ) { - log_msg(lgm_locking, "Skipping client %s for lock %s\n", - poller.ipn[i].name, lkeytob64(x_key, x_kl)); - continue; - } - - lq = get_new_lock_req(); - if( lq == NULL ) die(ExitGulm_NoMemory,"Out of Memory.\n"); - lq->code = gulm_lock_cb_state; - lq->key = malloc(x_kl); - if( lq->key == NULL ) die(ExitGulm_NoMemory,"Out of Memory.\n"); - lq->keylen = x_kl; - memcpy(lq->key, x_key, x_kl); - lq->subid = x_sbd; - lq->state = x_st; - queue_send_lock_req(i, lq); - } - -exit: - return 0; -} - -/*****************************************************************************/ - -/** - * do_login - - * @idx: - * - */ -static void do_login(int idx) -{ - int err; - uint32_t x_vers, rpl_err=gio_Err_Ok; - uint8_t *x_name, x_ama; - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - - do{ - if((err = xdr_dec_uint32(dec, &x_vers)) != 0 ) break; - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_ama)) != 0 ) break; - }while(0); - if( err != 0 ) { - log_err("xdr error %d while trying to read login\n", err); - close_by_idx(idx); - goto exit; - } - - if( ! IN6_IS_ADDR_LOOPBACK(poller.ipn[idx].ip.s6_addr32) ) { - log_err("Only connections from localhost are allowed." - " You're from %s\n", - print_ipname(&poller.ipn[idx])); - err = gio_Err_NotAllowed; - }else - if( GIO_WIREPROT_VERS != x_vers) { - log_msg(lgm_Network, "Wrong protocol version\n"); - rpl_err = gio_Err_BadWireProto; - }else - if( gio_lck_st_Client != x_ama ) { - log_err(" Only clients are allowed to connect here.\n"); - rpl_err = gio_Err_BadLogin; - } - - do{ - if((err=xdr_enc_uint32(enc, gulm_lock_login_rpl)) != 0 ) break; - if((err=xdr_enc_uint32(enc, rpl_err)) != 0 ) break; - /* always return Master here, even though that is not true. - * this is residue from the old way of things. Once everything gets - * more stablaized in the new way, this will goaway or get replaced. - */ - if((err=xdr_enc_uint8(enc, gio_Mbr_ama_Master)) != 0 ) break; - err = xdr_enc_flush(enc); - }while(0); - if( err != 0 ) { - log_err("Got %d sending reply to new login %s\n", err, x_name); - close_by_idx(idx); - goto exit; - }else - if( rpl_err == gio_Err_Ok ) { - log_msg(lgm_Network2, "New Locker "%s" connected. idx:%d fd:%d\n", - x_name, idx, poller.polls[idx].fd); - - if( poller.ipn[idx].name != NULL ) free(poller.ipn[idx].name); - poller.ipn[idx].name = strdup(x_name); - poller.state[idx] = poll_Open; - poller.times[idx] = 0; - poller.type[idx] = poll_Client; - }else - { - log_msg(lgm_Network2, "We gave %s an error (%d:%s)\n", x_name, - rpl_err, gio_Err_to_str(rpl_err)); - close_by_idx(idx); - } - - -exit: - if( x_name != NULL ) {free(x_name); x_name = NULL;} -} - -/** - * recv_some_data - - * @idx: - * - * - */ -static void recv_some_data(int idx) -{ - xdr_dec_t *dec = poller.dec[idx]; - xdr_enc_t *enc = poller.enc[idx]; - uint32_t code=0; - uint8_t *x_name = NULL; - int err; - - if( dec == NULL ) { - log_err("There is no Decoder on poller (%s idx:%d fd:%d)!!\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - return; - } - if( enc == NULL ) { - log_err("There is no Encoder on poller (%s idx:%d fd:%d)!!\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - return; - } - - - errno = 0; - err = xdr_dec_uint32(dec, &code); - if( err == -EPROTO ) { - log_msg(lgm_Network, "EOF on xdr (%s idx:%d fd:%d)\n", - print_ipname(&poller.ipn[idx]), - idx, poller.polls[idx].fd); - close_by_idx(idx); - return; - } - if( err != 0 ) { - if( errno == 0 ) errno = err; - log_msg(lgm_Always, "Error on xdr (%s): %d:%d:%s\n", - print_ipname(&poller.ipn[idx]), - err, errno, strerror(abs(errno))); - close_by_idx(idx); - return; - } - - /* from local clients. */ - if( gulm_lock_login_req == code ) { - do_login(idx); - }else - if( gulm_lock_logout_req == code ) { - xdr_enc_uint32(enc, gulm_lock_logout_rpl); - xdr_enc_flush(enc); - close_by_idx(idx); - }else - if( gulm_lock_sel_lckspc == code ) { - if( poller.space[idx].key != NULL ) { - free(poller.space[idx].key); - poller.space[idx].key = 0; - } - err = xdr_dec_raw_m(dec, (void**)&poller.space[idx].key, - &poller.space[idx].len); - if( err != 0 ) { - poller.space[idx].key = NULL; - poller.space[idx].len = 0; - log_err("Got xdr error %d reading lockspace filter\n", err); - } - }else - if( gulm_lock_state_req == code ) { - store_and_forward_lock_state(idx); - }else - if( gulm_lock_action_req == code ) { - store_and_forward_lock_action(idx); - }else - if( gulm_lock_query_req == code ) { - store_and_forward_lock_query(idx); - }else - if( gulm_lock_drop_exp == code ) { - forward_drop_exp(idx); - }else - if( gulm_lock_expire == code ) { - forward_expire(idx); - }else - /* from the masters */ - if( gulm_lock_state_rpl == code ) { - retrive_and_relpy_lock_state(idx); - }else - if( gulm_lock_action_rpl == code ) { - retrive_and_relpy_lock_action(idx); - }else - if( gulm_lock_query_rpl == code ) { - retrive_and_relpy_lock_query(idx); - }else - if( gulm_lock_cb_state == code ) { - forward_cb_to_some_clients(idx); - }else - if( gulm_lock_cb_dropall == code ) { - forward_drop_all(idx); - }else - /* from our core */ - if( gulm_core_mbr_updt == code ) { - struct in6_addr x_ip; - uint8_t x_cur_state=-1; - do { - if((err = xdr_dec_string(dec, &x_name)) != 0 ) break; - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err = xdr_dec_uint8(dec, &x_cur_state)) != 0 ) break; - }while(0); - if( err == 0 ) { - log_msg(lgm_Subscribers, "Recvd mbrupdt: %s, %s:%#x\n", - x_name, gio_mbrupdate_to_str(x_cur_state), x_cur_state); - - if( x_cur_state == gio_Mbr_Expired || - x_cur_state == gio_Mbr_Logged_out ) { - if( MasterIN.name != NULL ) { - if(IN6_ARE_ADDR_EQUAL(x_ip.s6_addr32, MasterIN.ip.s6_addr32) || - strcmp(x_name, MasterIN.name) == 0 ) { - /* Master Died! */ - log_msg(lgm_Network2, "Master node reported dead.\n"); - close_all_masters(); - I_am_the = gio_Mbr_ama_Pending; - } - } - if( strcmp(myName, x_name) == 0 ) { - log_msg(lgm_Network2, "Core is shutting down.\n"); - /* or should this get done differently? */ - running = FALSE; - } - } - - } - if( x_name != NULL ) {free(x_name); x_name = NULL;} - }else - if( gulm_core_state_chgs == code ) { - uint8_t x_st, x_q; - struct in6_addr x_ip; - do { - if((err=xdr_dec_uint8(dec, &x_st)) != 0 ) break; - if((err=xdr_dec_uint8(dec, &x_q)) != 0 ) break; - if( x_st == gio_Mbr_ama_Slave ) { - if((err=xdr_dec_ipv6(dec, &x_ip)) != 0 ) break; - if((err=xdr_dec_string(dec, &x_name)) != 0 ) break; - } - }while(0); - if( err != 0 ) { - log_err("Failed to recv Core state update! %s\n", strerror(errno)); - }else{ - log_msg(lgm_ServerState, "New State: %s\n", gio_I_am_to_str(x_st)); - - if( x_st == gio_Mbr_ama_Slave ) { - if( I_am_the == gio_Mbr_ama_Slave ){ - /* nothing to change. - * Need to figure out why doubles come through. - * */ - }else{ - if(!IN6_ARE_ADDR_EQUAL(x_ip.s6_addr32, MasterIN.ip.s6_addr32)) { - /* drop possible previous connection to master. */ - close_all_masters(); - - /* copy in master info. */ - if( MasterIN.name != NULL ) { - free(MasterIN.name); - MasterIN.name = NULL; - } - MasterIN.name = strdup(x_name); - if( MasterIN.name == NULL ) - die(ExitGulm_NoMemory,"Out of Memory.\n"); - memcpy(&MasterIN.ip, &x_ip, sizeof(struct in6_addr)); - log_msg(lgm_Always, "New Master at %s\n", - print_ipname(&MasterIN)); - - /* in the main loop, it will detect that this needs to - * loginto the Master, and will start the dirty work there. - */ - } - } - }else - if( x_st == gio_Mbr_ama_Pending ) { - /* sit idle. */ - close_all_masters(); - }else - { /* x_st == gio_Mbr_ama_Master || gio_Mbr_ama_Arbitrating */ - /* not slave, so the master is on us. */ - if( x_st != I_am_the ) { /* only if the state changed. */ - if(!IN6_ARE_ADDR_EQUAL(myIP.s6_addr32, MasterIN.ip.s6_addr32)) { - /* drop possible previous connection to master. */ - close_all_masters(); - - if( MasterIN.name != NULL ) { - free(MasterIN.name); - MasterIN.name = NULL; - } - MasterIN.name = strdup(myName); - if( MasterIN.name == NULL ) - die(ExitGulm_NoMemory,"Out of Memory.\n"); - memcpy(&MasterIN.ip, &myIP, sizeof(struct in6_addr)); - log_msg(lgm_Always, "New Master at %s\n", - print_ipname(&MasterIN)); - } - } - } - - I_am_the = x_st; - } - if( x_name != NULL ) {free(x_name); x_name = NULL;} - }else - /* from gulm_tool */ - if( gulm_info_stats_req == code ) { - xdr_enc_uint32(enc, gulm_info_stats_rpl); - xdr_enc_list_start(enc); - send_io_stats(enc); - xdr_enc_list_stop(enc); - xdr_enc_flush(enc); - }else - if( gulm_info_set_verbosity == code ) { - /* wiether this xdr fails or succeds, the socket is closed, so we do - * not need to check its error code. - */ - if( xdr_dec_string(dec, &x_name) == 0 ) { - set_verbosity(x_name, &verbosity); - if( x_name != NULL ) {free(x_name); x_name = NULL;} - } - close_by_idx(idx); - }else - if( gulm_socket_close == code ) { - close_by_idx(idx); - }else - /* from the wrong place. */ - if( gulm_err_reply == code ) { - uint32_t x_nc, x_err; - do{ - if((err=xdr_dec_uint32(dec, &x_nc))!=0) break; - if((err=xdr_dec_uint32(dec, &x_err))!=0) break; - }while(0); - if( err != 0 ) { - } - log_err("We got an error code %d:%s on command %#x;%s from %s\n", - x_err, gio_Err_to_str(x_err), - x_nc, gio_opcodes(x_nc), - print_ipname(&poller.ipn[idx]) - ); - }else - { - log_err("Unexpected op code %#x (%s), on fd:%d name:%s\n", - code, gio_opcodes(code), poller.polls[idx].fd, - print_ipname(&poller.ipn[idx])); - - close_by_idx(idx); - } - -} - -/** - * get_core_state - - * - * Returns: int - */ -static int get_core_state(void) -{ - int err; - xdr_enc_t *enc = poller.enc[poller.coreIDX]; - if((err=xdr_enc_uint32(enc, gulm_core_state_req))!=0) return err; - if((err=xdr_enc_flush(enc))!=0) return err; - return 0; -} - -/** - * ltpx_main_loop - - * - * This loop handles incommings. - * - * Returns: int - */ -void ltpx_main_loop(void) -{ - int cnt,i; - int NoRead = FALSE; - uint64_t tryskip = 0; - - initialize_MastersList(); - gettimeofday(&Started_at, NULL); - gettimeofday(&NOW, NULL); - get_core_state(); - - while( running ) { - - /* If we're not logged into a Master, and we're supposed to be, - * better get our butts hooked up. - */ - if( MasterIN.name != NULL && - !IN6_IS_ADDR_UNSPECIFIED(MasterIN.ip.s6_addr32) && - tryskip + 1000000 < tvs2uint64(NOW) && - ( I_am_the == gio_Mbr_ama_Slave || - I_am_the == gio_Mbr_ama_Master ) ) { - tryskip = tvs2uint64(NOW); - checkup_masters(); - } - - if( (cnt = poll(poller.polls, poller.maxi +1, 1000)) <= 0) { - if( cnt < 0 && errno != EINTR ) - log_err("poll error: %s\n",strerror(errno)); - if(!running) return; - } - gettimeofday(&NOW, NULL); - - for( i=0; i <= poller.maxi ; i++) { - if( poller.polls[i].fd < 0) continue; - if( poller.polls[i].revents & POLLHUP ) { - close_by_idx(i); - } - if (poller.polls[i].revents & POLLNVAL ) { - close_by_idx(i); - } - if( poller.polls[i].revents & POLLIN ) { - if( poller.polls[i].fd == poller.listenFD ) { - accept_connection(); - }else - { - if( poller.state[i] == poll_Trying ) { - if( recv_Masterlogin_reply(i) != 0 ) - close_by_idx(i); - }else { - /* ok, when the senderlist gets to a certain fullness, - * need to stop reading from clients. - */ - if( poller.type[i] != poll_Client || - NoRead == FALSE ) - recv_some_data(i); - } - } - } - if( poller.polls[i].revents & POLLOUT && - poller.type[i] == poll_Client ) { - send_some_data(i); - } - - /* check for timed out pollers. */ - if( poller.times[i] != 0 && - poller.times[i]+ gulm_config.new_con_timeout < tvs2uint64(NOW)) { - log_msg(lgm_Network, "Timeout (%"PRIu64") on fd:%d (%s)\n", - gulm_config.new_con_timeout, poller.polls[i].fd, - print_ipname(&poller.ipn[i])); - close_by_idx(i); - } - if(!running) return; - }/*for( i=0; i <= poller.maxi ; i++)*/ - - /* send things out. */ - NoRead = FALSE; - for(i=0; i < gulm_config.how_many_lts; i++ ) { - if( MastersList[i].poll_idx > -1 && - poller.state[MastersList[i].poll_idx] == poll_Open && - poller.polls[MastersList[i].poll_idx].revents & POLLOUT ) { - /* inspect senderslist, if over certain amount, set NoRead - * - * Should work such that any Master's sender list gets too full - * and all reading from all clients stops. - */ - if( MastersList[i].senderlistlen > 1000 ) { - NoRead = TRUE; - } - send_senderlist(i); - } - } /*for(i=0; i < gulm_config.how_many_lts; i++ )*/ - - }/* while(running) */ -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/ltpx_main.c b/gulm/src/ltpx_main.c deleted file mode 100644 index e80e6bd..0000000 --- a/gulm/src/ltpx_main.c +++ /dev/null @@ -1,171 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <signal.h> -#include <execinfo.h> - -#include "gulm_defines.h" -#include "config_gulm.h" -#include "ltpx_priv.h" -#include "ltpx.h" -#include "utils_dir.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; -/* other bits of interest */ -extern gulm_config_t gulm_config; -extern int I_am_the; -/* */ - -/*****************************************************************************/ - -/** - * sigact_usr1 - - * @sig: - * - */ -static void sigact_usr1(int sig) -{ - /* dump Lock Queues */ - dump_all_master_tables(); -} - -/** - * sigact_segv - - * @sig: - * - * try to get a backtrace before we puke out. - * This may not always work, but since I cannot get daemons to drop core - * files, trying this is better than nothing. - */ -static void sigact_segv(int sig) -{ - struct sigaction act; - void *array[200]; - size_t size,i; - char **strings; - - size = backtrace(array, 200); - strings = backtrace_symbols(array, size); -#ifndef DEBUG - syslog(LOG_NOTICE, "BACKTRACE\n"); -#else - fprintf(stderr, "BACKTRACE\n"); -#endif - for(i=0;i<size; i++) -#ifndef DEBUG - syslog(LOG_NOTICE, " %s\n", strings[i]); -#else - fprintf(stderr, " %s\n", strings[i]); -#endif - free(strings); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - sigaction(SIGSEGV, &act, NULL); - raise(SIGSEGV); -} - -/** - * setupsignals - set how we respond to signals. - */ -static void setupsignals(void) -{ - struct sigaction act; - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; /* use gulm_tool shutdown or kill -9 */ - if( sigaction(SIGTERM, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGTERM handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_usr1; - if( sigaction(SIGUSR1, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGUSR1 handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGUSR2, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGUSR2 handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGHUP, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGHUP handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN;/* don't die on broken pipes.*/ - if( sigaction(SIGPIPE, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGPIPE handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_IGN; - if( sigaction(SIGALRM, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGALRM handler: %s\n",strerror(errno)); - - memset(&act,0,sizeof(act)); - act.sa_handler = sigact_segv; - if( sigaction(SIGSEGV, &act, NULL) <0) - die(ExitGulm_InitFailed, - "Failed to install signal SIGSEGV handler: %s\n",strerror(errno)); - -} - -/** - * ltxp_main - - * @argc: - * @argv: - * - * - * Returns: int - */ -int ltpx_main(int argc, char **argv) -{ - setupsignals(); - -#ifndef DEBUG - pid_lock(gulm_config.lock_file, ProgramName); -#endif - - log_init(0,0); - log_msg(lgm_Network2, "ltpx started.\n"); - - init_ltpx_poller(); - /* proxy port should be in the config. */ - open_ltpx_listener( gulm_config.ltpx_port ); - if( open_ltpx_to_core() != 0 ) return -1; - - initialize_ltpx_maps(); - - /* handling incomming packets */ - ltpx_main_loop(); - - clear_pid(gulm_config.lock_file, ProgramName); - - log_msg(lgm_Network, "finished.\n"); - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/ltpx_map.c b/gulm/src/ltpx_map.c deleted file mode 100644 index fb0835f..0000000 --- a/gulm/src/ltpx_map.c +++ /dev/null @@ -1,313 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> - -#include "gulm_defines.h" -#include "hashn.h" -#include "LLi.h" -#include "ltpx_priv.h" -#include "config_gulm.h" -#include "utils_dir.h" -#include "utils_crc.h" -#include "utils_tostr.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; -extern gulm_config_t gulm_config; - -unsigned long free_reqs = 0; -unsigned long used_reqs = 0; - -/*****************************************************************************/ -/** - * lq_cmp - - * @a: - * @b: - * - * -1 if a < b - * 0 if a == b - * 1 if a > b - * Returns: int - */ -int lq_cmp(void *a, void *b) -{ - lock_req_t *lqA = (lock_req_t *)a; - lock_req_t *lqB = (lock_req_t *)b; - - if( lqA->subid == lqB->subid ) { - return memcmp(lqA->key, lqB->key, MIN(lqA->keylen, lqB->keylen)); - }else - if( lqA->subid < lqB->subid ) { - return -1; - }else - { - return 1; - } -} -/** - * lq_hash - - * @a: - * - * - * Returns: int - */ -int lq_hash(void *a) -{ - lock_req_t *lqA = (lock_req_t *)a; - int ck; - ck = crc32(lqA->key, lqA->keylen, lqA->keylen); - ck = crc32((uint8_t*)&lqA->subid, sizeof(uint64_t), ck); - return ck; -} - -/*****************************************************************************/ -/* Free pool */ -LLi_t Free_lock_reqs; - -/** - * prealloc_reqs - - * @oid: - * - * - * Returns: int - */ -int prealloc_reqs(void) -{ - int i; - lock_req_t *lq; - for(i = 0; i < 90000; i++) { - lq = malloc(sizeof(lock_req_t)); - memset(lq, 0, sizeof(lock_req_t)); - LLi_init(&lq->ls_list, lq); - LLi_add_after(&Free_lock_reqs, &lq->ls_list); - free_reqs ++; - } - return 0; -} - -int initialize_ltpx_maps(void) -{ - LLi_init_head( &Free_lock_reqs ); - prealloc_reqs(); - return 0; -} - -/** - * get_new_lock_req - - * @oid: - * - * - * Returns: lock_req_t - */ -lock_req_t *get_new_lock_req(void) -{ - lock_req_t *lq; - - if( !LLi_empty(&Free_lock_reqs) ) { - LLi_t *tmp; - tmp = LLi_pop(&Free_lock_reqs); - lq = LLi_data(tmp); - free_reqs --; - }else{ - lq = malloc(sizeof(lock_req_t)); - if( lq == NULL ) die(ExitGulm_NoMemory, "Out of memory.\n"); - memset(lq, 0, sizeof(lock_req_t)); - } - used_reqs ++; - LLi_init( &lq->ls_list, lq); - lq->code = 0; - lq->subid = 0; - lq->key = NULL; - lq->keylen = 0; - lq->state = 0; - lq->flags = 0; - lq->lvb = NULL; - lq->lvblen = 0; - lq->poll_idx = -1; - - return lq; -} - -/** - * recycle_lock_req - - * @lq: - * - * - * Returns: void - */ -void recycle_lock_req(lock_req_t *lq) -{ - - if( lq->key != NULL ) { - free(lq->key); - lq->key = NULL; - } - if( lq->lvb != NULL ) { - free(lq->lvb); - lq->lvb = NULL; - } - lq->code = 0; - lq->keylen = 0; - lq->state = 0; - lq->flags = 0; - lq->lvblen = 0; - lq->poll_idx = -1; - - LLi_unhook(&lq->ls_list); - - LLi_add_after(&Free_lock_reqs, &lq->ls_list); - used_reqs --; - free_reqs ++; - - /* get this into config too. */ - if( free_reqs > 90000 ) { - LLi_t *tmp; - tmp = LLi_prev(&Free_lock_reqs); - LLi_del(tmp); - lq = LLi_data(tmp); - free(lq); - free_reqs --; - } -} - -lock_req_t *duplicate_lock_req(lock_req_t *old) -{ - lock_req_t *new; - new = get_new_lock_req(); - new->code = old->code; - new->subid = old->subid; - new->keylen = old->keylen; - new->state = old->state; - new->flags = old->flags; - new->lvblen = old->lvblen; - new->poll_idx = old->poll_idx; - new->key = malloc(new->keylen); - if( new->key == NULL ) { - recycle_lock_req(new); - return NULL; - } - memcpy(new->key, old->key, new->keylen); - if( new->lvblen > 0 ) { - new->lvb = malloc(new->lvblen); - if( new->lvb == NULL ) { - recycle_lock_req(new); - return NULL; - } - memcpy(new->lvb, old->lvb, new->lvblen); - } - return new; -} - - -/** - * create_new_req_map - - * - * Returns: hash_t - */ -hashn_t *create_new_req_map(void) -{ - /* ??other thigns to init?? */ - return hashn_create(gulm_config.lt_hashbuckets, lq_cmp, lq_hash); -} - -/** - * release_req_map - - * @map: - * - * mostly just here for completeness. duno if i'll use it. - * - */ -void release_req_map(hashn_t *map) -{ - hashn_destroy(map); -} - -/* add item */ - -/* find/remove item */ - -/* walk over all items */ - -char *lkeytob64(uint8_t *key, uint8_t keylen); -char *lvbtob64(uint8_t *lvb, uint8_t lvblen); - -static void print_lock_req(FILE *FP, lock_req_t *lq) -{ - fprintf(FP, "%s : \n", lkeytob64(lq->key, lq->keylen)); - fprintf(FP, " subid : %"PRIu64"\n", lq->subid); - fprintf(FP, " code : %s\n", gio_opcodes(lq->code)); - fprintf(FP, " state : %#x\n", lq->state); - fprintf(FP, " flags : %#x\n", lq->flags); - fprintf(FP, " lvb : %s\n", lvbtob64(lq->lvb, lq->lvblen)); - fprintf(FP, " poll_idx : %d\n", lq->poll_idx); -} - -static int _dump_lqs_(LLi_t *item, void *d) -{ - lock_req_t *lq; - FILE* fp; - - lq = LLi_data(item); - fp = (FILE*)d; - fprintf(fp, "#=======================================" - "========================================\n"); - print_lock_req(fp, lq); - return 0; -} - -void dump_ltpx_stuff(Qu_t *head, hashn_t *map, int ltid) -{ - int fd; - FILE *fp; - LLi_t *tmp; - lock_req_t *lq; - - if( (fd=open_tmp_file("Gulm_LTPX_Req_Dump")) < 0 ) return; - - if( (fp = fdopen(fd,"a")) == NULL) return; - - fprintf(fp, "---\n# BEGIN LTPX REQ SENDERS DUMP FOR %d\n", ltid); - - for(tmp = LLi_next(head); - NULL != LLi_data(tmp); - tmp = LLi_next(tmp)) - { - lq = LLi_data(tmp); - print_lock_req(fp, lq); - } - - fprintf(fp, "#=======================================" - "========================================\n"); - fprintf(fp, "# END LTPX REQ SENDERS DUMP FOR %d\n", ltid); - fprintf(fp, "#=======================================" - "========================================\n"); - fprintf(fp, "---\n# BEGIN LTPX REQ HASH DUMP FOR %d\n", ltid); - - if( map != NULL ) hashn_walk(map, _dump_lqs_, fp); - - fprintf(fp, "#=======================================" - "========================================\n"); - fprintf(fp, "# END LTPX REQ HASH DUMP FOR %d\n", ltid); - fprintf(fp, "#=======================================" - "========================================\n"); - fclose(fp); -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/ltpx_priv.h b/gulm/src/ltpx_priv.h deleted file mode 100644 index 5aaac1e..0000000 --- a/gulm/src/ltpx_priv.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __ltpx_priv_h__ -#define __ltpx_priv_h__ -#include "hashn.h" -#include "Qu.h" - -typedef struct lock_req_s { - LLi_t ls_list; - - uint32_t code; /* gulm_lock_state_req or gulm_lock_action_req */ - uint8_t *key; - uint16_t keylen; - uint64_t subid; - uint64_t start; - uint64_t stop; - uint8_t state; /* or action if this is an action req */ - uint32_t flags; - uint8_t *lvb; /* drop overloads this to be name as well */ - uint16_t lvblen; - - int poll_idx;/* who made this request. */ - - int error; - -} lock_req_t; - -int init_ltpx_poller(void); -int open_ltpx_listener(int port); -int open_ltpx_to_core(void); -void ltpx_main_loop(void); - - -/* these will move/change here once i figure out exactly how i want to - * orginise the code. - */ -int initialize_ltpx_maps(void); -lock_req_t *get_new_lock_req(void); -void recycle_lock_req(lock_req_t *lq); -lock_req_t *duplicate_lock_req(lock_req_t *old); -hashn_t * create_new_req_map(void); -void dump_all_master_tables(void); -void dump_ltpx_stuff(Qu_t *head, hashn_t *map, int ltid); - -#endif /*__ltpx_priv_h__*/ diff --git a/gulm/src/main_main.c b/gulm/src/main_main.c deleted file mode 100644 index 237cba6..0000000 --- a/gulm/src/main_main.c +++ /dev/null @@ -1,279 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <fcntl.h> -#include <errno.h> -#include <execinfo.h> -#include <pwd.h> -#include <syslog.h> -#include <libgen.h> - -#include "gulm_defines.h" -#include "config_gulm.h" -#include "myio.h" -#include "utils_ip.h" -#include "utils_verb_flags.h" -#include "utils_tostr.h" -#include "lock.h" -#include "core.h" -#include "ltpx.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -uint32_t verbosity=0; /* default is set below in the cmdline args parsing. */ -char *ProgramName; - -gulm_config_t gulm_config; - -/* these are calculated at run time. - * I will need to do something in the future for nodes with multiple ips. - * */ -char myName[256] = "\0"; -struct in6_addr myIP = IN6ADDR_ANY_INIT; - -/*****************************************************************************/ - -/** - * forker - - * @name: - * - * Returns: int - */ -int forker(char *name) -{ - pid_t pid; - char *old; - char **argv; - int argc; - - if((pid=fork()) == 0) { - /* child */ - - build_argv(&gulm_config, &argv, &argc); - - old = argv[0]; /* exec this. */ - argv[0] = name; /* but be called this */ - - execvp(old, argv); - - printf("%s Should not be here. %s %m\n", ProgramName, name); - - }else if( pid > 0 ) { - /* parent */ - log_msg(lgm_Forking, "Forked %s.\n", name); - }else{ - /*error*/ - log_err("Failed to fork %s. %d:%s\n", name, errno, strerror(errno)); - } - return 0; -} - -/** - * my_daemonize - - */ -void my_daemonize(void) -{ - pid_t pid; - int fd, i; - - if( gulm_config.daemon_fork ) { - if((pid=fork())<0) - { die(ExitGulm_ExecError, - "Failed to fork off of parent: %s\n",strerror(errno)); } - else if(pid!=0) exit(ExitGulm_Ok); - } - - setsid(); - chdir("/"); - umask(0); - - if( gulm_config.leave_std_open ) { - for(i=open_max()-1; i>=3; --i) close(i); /* close nearly everything */ - close(0); /* close stdin */ - fd = open("/dev/null", O_RDWR ); /* stdin */ - /* stdout and stderr should still be open to the terminal for debug - * output. - */ - }else{ - for(i=open_max()-1; i>=0; --i) close(i); /* close everything */ - fd = open("/dev/null", O_RDWR ); /*stdin*/ - dup(fd); /*stdout*/ - dup(fd); /*stderr*/ - } - fprintf(stderr, "stderr was left open.\n"); - printf("stdout was left open.\n"); - - openlog(ProgramName, LOG_PID, LOG_DAEMON); -} - -/** - * become_nobody - root is bad. - * - * we don't need to be root, so don't. - * well, switch to the user that the config says. try atleast. - * - */ -void become_nobody(void) -{ - struct passwd *pw=NULL; - if( getuid() == 0 ) { /* we are root */ - nice(-10); /* while we're here.... */ - /* is run_as root? */ - if( strcmp(gulm_config.run_as, "root") == 0) return; - if( (pw = getpwnam(gulm_config.run_as)) != NULL ) { - setuid(pw->pw_uid); - setgid(pw->pw_gid); - }else - { - die(ExitGulm_InitFailed, - "There is no user id "%s", cannot continue.\n", - gulm_config.run_as); - } - } -} - -/** - * set_myID - Determin who I am. - * - */ -void set_myID(void) -{ - /* cute tricks to set the default name and IP. */ - if( gulm_config.name == NULL ) gethostname(myName, 256); - else strcpy(myName, gulm_config.name); - /* lookup my ip from my full name. */ - if( IN6_IS_ADDR_UNSPECIFIED(&gulm_config.ip) ) { - if( gulm_config.netdev != NULL ) { - if( get_ip_from_netdev(gulm_config.netdev, &myIP) != 0 ) - die(ExitGulm_InitFailed, "Cannot find ifdev %s, or device has " - "no ip configured\n", gulm_config.netdev); - }else - if( get_ip_for_name(myName, &myIP) != 0 ) - die(ExitGulm_InitFailed, "Failed to find IP for my name (%s)\n", - myName); - }else{ - memcpy(&myIP, &gulm_config.ip, sizeof(struct in6_addr)); - } -} - -/** - * banner_msg - - * - * Prints out a bunch of things, mostly stuff so users and support can see - * right away what's going on. Or something like that. - * - * wonder if i should banner each part of gulm? - */ -void banner_msg(void) -{ - log_msg(lgm_Always, "Starting %s %s. (built " __DATE__" " __TIME__ ")\n" - "Copyright (C) 2004 Red Hat, Inc. All rights reserved.\n", - ProgramName, RELEASE); - log_msg(lgm_Always, "I am running in %s mode.\n", - gulm_config.fog?"Fail-over":"Standard" ); - log_msg(lgm_Always, "I am (%s) with ip (%s)\n", myName, ip6tostr(&myIP)); - log_msg(lgm_Always, "This is cluster %s\n", gulm_config.clusterID); -} - - - -static int set_limits(void) -{ - int res; - struct rlimit rlimit; - - rlimit.rlim_cur = RLIM_INFINITY; - rlimit.rlim_max = RLIM_INFINITY; - res = setrlimit (RLIMIT_MEMLOCK, &rlimit); - if (res) - fprintf(stderr, "cannot set RLIMIT_MEMLOCK: %s\n", strerror(errno)); - return res; -} - -/** - * main - - * @argc: - * @argv: - * - * - * Returns: int - */ -int main(int argc, char **argv) -{ - - ProgramName = strdup(basename(argv[0])); - if( ProgramName == NULL ) die(ExitGulm_NoMemory, "Out of Memory.\n"); - set_verbosity("Default", &verbosity); - - /* parse cmdline (and config) */ - if( parse_conf(&gulm_config, argc, argv) != 0 ) return -1; - - /*splits*/ - if( strcmp("lock_gulmd", ProgramName) == 0 ) { - openlog("lock_gulmd_main", LOG_PID, LOG_DAEMON); - - /* make pid dir */ - mkdir(gulm_config.lock_file, S_IRUSR|S_IWUSR|S_IXUSR); - - /* fork core */ - forker("lock_gulmd_core"); - - /* just a moment...*/ - sleep(1); - - /* fork lt */ - forker("lock_gulmd_LT"); - - /* just a moment...*/ - sleep(1); - - /* fork ltproxy */ - forker("lock_gulmd_LTPX"); - - return 0; - } - - /* daemonize ourselves here */ - - if (set_limits() != 0) return -1; - - become_nobody(); - - set_myID(); - - my_daemonize(); - banner_msg(); - - if( strcmp("lock_gulmd_core", ProgramName) == 0 ) { - return core_main(argc, argv); - }else - if( strcmp("lock_gulmd_LTPX", ProgramName) == 0 ) { - return ltpx_main(argc, argv); - }else - if( strcmp("lock_gulmd_LT", ProgramName) == 0 ) { - return lt_main(argc, argv); - } - - /* all done. */ - - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/myio.c b/gulm/src/myio.c deleted file mode 100644 index 3b6a3db..0000000 --- a/gulm/src/myio.c +++ /dev/null @@ -1,202 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2004 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -/*****************************************************************************/ -#ifdef OPEN_MAX -static int openmax = OPEN_MAX; -#else -static int openmax = 0; -#endif /* OPEN_MAX */ - -#define OM_GUESS 256 -/** - * open_max - clacs max number of open files. - * Returns: the maximum number of file we can have open at a time. - * Or -1 for error. - */ -int open_max(void) -{ - if(openmax == 0) { - errno =0; - if((openmax = sysconf(_SC_OPEN_MAX)) < 0) { - if( errno == 0) { - openmax = OM_GUESS; - }else{ - return -1; - } - } - } - return openmax; -} - -/*****************************************************************************/ -/* wrapped up io */ -ssize_t my_recv(int fd, void *buf, size_t len) -{ - ssize_t cnt=0; - size_t ttl=0; - while(len > 0) { - if( (cnt=read(fd, buf, len)) <=0) return cnt; - len -= cnt; - buf += cnt; - ttl += cnt; - } - return ttl; -} - -ssize_t my_send(int fd, void *buf, size_t len) -{ - ssize_t cnt=0; - size_t ttl=0; - while(len > 0) { - if( (cnt=write(fd, buf, len)) <=0) return cnt; - len -= cnt; - buf += cnt; - ttl += cnt; - } - return ttl; -} - -ssize_t my_recv_iov(int fd, struct iovec *iov, size_t iov_size) -{ - size_t byte_cnt=0; - ssize_t cnt; - - while(iov_size > 0) { - if( (cnt = readv(fd, iov, iov_size)) <=0) - return cnt; - byte_cnt += cnt; - while (cnt >= iov->iov_len) { - cnt -= iov->iov_len; - iov++; - iov_size--; - } - if(iov_size <=0) break; - iov->iov_base += cnt; - iov->iov_len -= cnt; - } - return byte_cnt; -} - -ssize_t my_send_iov(int fd, struct iovec *iov, size_t iov_size) -{ - size_t byte_cnt=0; - ssize_t cnt; - - while(iov_size > 0) { - if( (cnt = writev(fd, iov, iov_size)) <=0) - return cnt; - byte_cnt += cnt; - while (cnt >= iov->iov_len) { - cnt -= iov->iov_len; - iov++; - iov_size--; - } - if(iov_size <=0) break; - iov->iov_base += cnt; - iov->iov_len -= cnt; - } - return byte_cnt; -} - - -/*****************************************************************************/ -/** - * socket_free_send_space - how much buffer space is there left? - * @sk: - * - * - * Returns: int - */ -int socket_free_send_space(int sk) -{ - int unsent, total, len=sizeof(int); - - if( getsockopt(sk, SOL_SOCKET, SO_SNDBUF, &total, &len)<0) return -1; - - /* TIOCOUTQ is documented as SIOCOUTQ */ - if( ioctl(sk, TIOCOUTQ, &unsent) < 0 ) return -1; - - return total - unsent; -} - -/*****************************************************************************/ -/* nice abstraction for getting a socket for listening. */ -/** - * set_opts - set some line options. - * @sk: < socket descriptor - * - * Returns: err if any - */ -int __inline__ set_opts(int sk) -{ - /* leaving this function here even though it is empty. - * I may have soem option I want to sent in the future this way, and - * this leaves all the hooks in place. - */ -#if 0 - int trueint=1; - - if(setsockopt(sk, SOL_SOCKET, SO_KEEPALIVE, &trueint, sizeof(int)) <0) - return -1; -#endif - - return 0; -} -/** - * serv_listen - start listening to a port. - * @port: < Port to bind to in Host Byte Order. - * - * Returns: socket file descriptor - */ -int serv_listen(unsigned int port) -{ - int sk, trueint=1; - struct sockaddr_in6 adr; - - if( (sk = socket(AF_INET6, SOCK_STREAM, 0)) <0) - return -1; - - if( setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &trueint, sizeof(int)) <0) - goto error_exit; - - if( set_opts(sk) <0) - goto error_exit; - - memset(&adr, 0, sizeof(struct sockaddr_in6)); - adr.sin6_family = AF_INET6; - adr.sin6_addr = in6addr_any; - adr.sin6_port = htons( port ); - - if( bind(sk, (struct sockaddr *)&adr, sizeof(struct sockaddr_in6)) <0) - goto error_exit; - - if( listen(sk, 5) <0) - goto error_exit; - - return sk; -error_exit: - close(sk); - return -1; -} - -/* vim: set ai cin et sw=3 ts=3: */ diff --git a/gulm/src/myio.h b/gulm/src/myio.h deleted file mode 100644 index 08605a3..0000000 --- a/gulm/src/myio.h +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2004 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __myio_h__ -#define __myio_h__ -#include <sys/uio.h> -int open_max(void); -ssize_t my_recv(int fd, void *buf, size_t len); -ssize_t my_send(int fd, void *buf, size_t len); -ssize_t my_recv_iov(int fd, struct iovec *iov, size_t iov_size); -ssize_t my_send_iov(int fd, struct iovec *iov, size_t iov_size); - -int socket_free_send_space(int sk); -int set_opts(int sk); -int serv_listen(unsigned int port); - -#endif /*__myio_h__*/ - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/nodel.c b/gulm/src/nodel.c deleted file mode 100644 index a54a869..0000000 --- a/gulm/src/nodel.c +++ /dev/null @@ -1,133 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include "gulm_defines.h" -#include "gio_wiretypes.h" -#include "LLi.h" -#include "hash.h" -#include "config_gulm.h" - -/*****************************************************************************/ -/* bits of data used by the log_*() and die() functions. */ -extern uint32_t verbosity; -extern char *ProgramName; - -/*****************************************************************************/ - -struct nodel_s { - LLi_t nl_list; - char *name; - struct in6_addr ip; - uint8_t state; -}; -typedef struct nodel_s nodel_t; - -/* selector functions for the hash tables. */ -unsigned char *getnodelname(void *item) -{ - nodel_t *n = (nodel_t*)item; - return n->name; -} -int getnodelnamelen(void *item) -{ - nodel_t *n=(nodel_t*)item; - return strlen(n->name); -} - -/** - * initialize_nodel - - * - * Returns: hash_t - */ -hash_t *initialize_nodel(void) -{ - return hash_create(256, getnodelname, getnodelnamelen); -} - - -/** - * update_nodel - - * @hsh: - * @name: - * @ip: - * @state: - * - * updates the state for nodel. - * adds it if it wasn't all ready there. - * - * should i remove on logged out and killed? - * - * Returns: int - */ -int update_nodel(hash_t *hsh, char *name, struct in6_addr *ip, uint8_t state) -{ - LLi_t *tmp; - nodel_t *n; - - tmp = hash_find(hsh, name, strlen(name)); - if( tmp == NULL ) { - n = malloc(sizeof(nodel_t)); - if( n == NULL ) return -ENOMEM; - memset(n, 0, sizeof(nodel_t)); - LLi_init(&n->nl_list, n); - n->name = strdup(name); - if( n->name == NULL ) { - free(n); - return -ENOMEM; - } - memcpy(&n->ip, ip, sizeof(struct in6_addr)); - n->state = state; - - hash_add(hsh, &n->nl_list); - }else{ - n = LLi_data(tmp); - n->state = state; - } - return 0; -} - - -/** - * validate_nodel - - * @hsh: - * @name: - * @ip: - * - * make sure that name matches ip AND state is logged in. - * - * Returns: TRUE || FALSE - */ -int validate_nodel(hash_t *hsh, char *name, struct in6_addr *ip) -{ - LLi_t *tmp; - nodel_t *n; - - tmp = hash_find(hsh, name, strlen(name)); - if( tmp == NULL ) return FALSE; - n = LLi_data(tmp); - - if( !IN6_ARE_ADDR_EQUAL(ip->s6_addr32, n->ip.s6_addr32) ) return FALSE; - - if( n->state != gio_Mbr_Logged_in ) return FALSE; - - return TRUE; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/nodel.h b/gulm/src/nodel.h deleted file mode 100644 index 75dd4e8..0000000 --- a/gulm/src/nodel.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __nodel_h__ -#define __nodel_h__ -#include "hash.h" -#include <netinet/in.h> -hash_t *initialize_nodel(void); -int update_nodel(hash_t *hsh, char *name, struct in6_addr *ip, uint8_t state); -int validate_nodel(hash_t *hsh, char *name, struct in6_addr *ip); -#endif /*__nodel_h__*/ - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/osi_endian.h b/gulm/src/osi_endian.h deleted file mode 100644 index fdcbab2..0000000 --- a/gulm/src/osi_endian.h +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OSI_ENDIAN_DOT_H__ -#define __OSI_ENDIAN_DOT_H__ - - -#ifdef __linux__ - -#ifdef __KERNEL__ -#error "don't use osi_endian.h in kernel space under Linux" -#endif - -#include <endian.h> -#include <byteswap.h> - -/* I'm not sure which versions of alpha glibc/gcc are broken, - so fix all of them. */ -#ifdef __alpha__ -#undef bswap_64 -static __inline__ unsigned long bswap_64(unsigned long x) -{ - unsigned int h = x >> 32; - unsigned int l = x; - - h = bswap_32(h); - l = bswap_32(l); - - return ((unsigned long)l << 32) | h; -} -#endif /* __alpha__ */ - -#endif /* __linux__ */ - - -#ifdef __FreeBSD__ - -#include <machine/endian.h> -#include <sys/types.h> - -#define __BIG_ENDIAN BIG_ENDIAN -#define __LITTLE_ENDIAN LITTLE_ENDIAN -#define __BYTE_ORDER BYTE_ORDER - -#define bswap_16 __byte_swap_word -#define bswap_32 __byte_swap_long - -/* There is no 64 bit swap operation in FreeBSD, so define bswap_64 the - same as the alpha fix for linux */ -static __inline__ unsigned long long bswap_64(unsigned long long x) -{ - unsigned int h = x >> 32; - unsigned int l = x; - - h = bswap_32(h); - l = bswap_32(l); - - return ((unsigned long long)l << 32) | h; -} - -#endif /* __FreeBSD__ */ - - -#if __BYTE_ORDER == __BIG_ENDIAN - -#define osi_be16_to_cpu(x) (x) -#define osi_be32_to_cpu(x) (x) -#define osi_be64_to_cpu(x) (x) - -#define osi_cpu_to_be16(x) (x) -#define osi_cpu_to_be32(x) (x) -#define osi_cpu_to_be64(x) (x) - -#define osi_le16_to_cpu(x) (bswap_16((x))) -#define osi_le32_to_cpu(x) (bswap_32((x))) -#define osi_le64_to_cpu(x) (bswap_64((x))) - -#define osi_cpu_to_le16(x) (bswap_16((x))) -#define osi_cpu_to_le32(x) (bswap_32((x))) -#define osi_cpu_to_le64(x) (bswap_64((x))) - -#endif /* __BYTE_ORDER == __BIG_ENDIAN */ - - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -#define osi_be16_to_cpu(x) (bswap_16((x))) -#define osi_be32_to_cpu(x) (bswap_32((x))) -#define osi_be64_to_cpu(x) (bswap_64((x))) - -#define osi_cpu_to_be16(x) (bswap_16((x))) -#define osi_cpu_to_be32(x) (bswap_32((x))) -#define osi_cpu_to_be64(x) (bswap_64((x))) - -#define osi_le16_to_cpu(x) (x) -#define osi_le32_to_cpu(x) (x) -#define osi_le64_to_cpu(x) (x) - -#define osi_cpu_to_le16(x) (x) -#define osi_cpu_to_le32(x) (x) -#define osi_cpu_to_le64(x) (x) - -#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ - - -#endif /* __OSI_ENDIAN_DOT_H__ */ diff --git a/gulm/src/utils_crc.c b/gulm/src/utils_crc.c deleted file mode 100644 index e50cd30..0000000 --- a/gulm/src/utils_crc.c +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifdef __KERNEL__ -#include "osi.h" -#else /*__KERNEL__*/ -#include <stdint.h> -#endif /*__KERNEL__*/ - -static const uint32_t crc_32_tab[] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - - -/** - * crc32 - hash an array of data - * @data: the data to be hashed - * @len: the length of data to be hashed - * - * completely copied from GFS/src/fs.c - * - * Take some data and convert it to a 32-bit hash. - * - * The hash function is a 32-bit CRC of the data. The algorithm uses - * the crc_32_tab table above. - * - * This may not be the fastest hash function, but it does a fair bit better - * at providing uniform results than the others I've looked at. That's - * really important for efficient directories. - * - * Returns: the hash - */ - -uint32_t crc32(const char *data, int len, uint32_t init) -{ - uint32_t hash = init; - - for (; len--; data++) - hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); - - hash = ~hash; - - return hash; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_crc.h b/gulm/src/utils_crc.h deleted file mode 100644 index 50b4ffc..0000000 --- a/gulm/src/utils_crc.h +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __utils_crc_h__ -#define __utils_crc_h__ -uint32_t crc32(const char *data, int len, uint32_t init); -#endif /*__utils_crc_h__*/ - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_dir.c b/gulm/src/utils_dir.c deleted file mode 100644 index 0022b6b..0000000 --- a/gulm/src/utils_dir.c +++ /dev/null @@ -1,111 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "gulm_defines.h" -#include "utils_dir.h" - -/** - * open_tmp_file - - * @file: - * @path: - * - * get a unique tmp file for dumping to. - * also opens it. - * - * Returns: int - */ -int open_tmp_file(char *file) -{ - int fd=-1; - char *tmp, *p; - tmp = getenv("TMPDIR"); - if(tmp == NULL ) tmp = "/tmp"; - p = malloc( strlen(tmp) + strlen(file) + 2 + 8); - if( p == NULL ) return -ENOMEM; - strcpy(p, tmp); - strcat(p, "/"); - strcat(p, file); - strcat(p, ".XXXXXX"); - fd = mkstemp(p); - free(p); - return fd; -} - -/** - * pid_lock - only one. - */ -void pid_lock(char *path, char *lf) -{ - struct flock lock; - char buf[12], plf[1024]; - int fd, val; - - snprintf(plf, 1024, "%s/%s.pid", path, lf); - - if( (fd = open(plf, O_WRONLY | O_CREAT, - (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) { - die(ExitGulm_PidLock, "open error on "%s": %s\n", - plf, strerror(errno)); - } - - lock.l_type = F_WRLCK; - lock.l_start = 0; - lock.l_whence = SEEK_SET; - lock.l_len = 0; - - if (fcntl(fd, F_SETLK, &lock) < 0) { - if (errno == EACCES || errno == EAGAIN) { - die(ExitGulm_PidLock, "%s already running\n", lf); - } else { - die(ExitGulm_PidLock, "fcntl F_SETLK error: %s\n", strerror(errno)); - } - } - - if (ftruncate(fd, 0) < 0) { - die(ExitGulm_PidLock, "ftruncate error: %s\n", strerror(errno)); - } - - snprintf(buf, 12, "%d\n", getpid()); - if (write(fd, buf, strlen(buf)) != strlen(buf)) { - die(ExitGulm_PidLock, - "write error to "%s": %s\n", plf, strerror(errno)); - } - - if ((val = fcntl(fd, F_GETFD, 0)) < 0) { - die(ExitGulm_PidLock, "fcntl F_GETFD error: %s\n", strerror(errno)); - } - - val |= FD_CLOEXEC; - if (fcntl(fd, F_SETFD, val) < 0) { - die(ExitGulm_PidLock, "fcntl F_SETFD error: %s\n", strerror(errno)); - } -} - -/** - * clear_pid - - */ -void clear_pid(char *path, char *lf) -{ - char plf[1024]; - snprintf(plf, 1024, "%s/%s.pid", path, lf); - unlink(plf); -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_dir.h b/gulm/src/utils_dir.h deleted file mode 100644 index 04e6911..0000000 --- a/gulm/src/utils_dir.h +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __utils_dir_h__ -#define __utils_dir_h__ -int open_tmp_file(char *file); -void pid_lock(char *path, char *lf); -void clear_pid(char *path, char *lf); -#endif /*__utils_dir_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_ip.c b/gulm/src/utils_ip.c deleted file mode 100644 index 0a05972..0000000 --- a/gulm/src/utils_ip.c +++ /dev/null @@ -1,251 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include "utils_ip.h" - -/** - * map_v4_to_v6 - - * @ip4: - * @ip6: - * - */ -void __inline__ map_v4_to_v6(struct in_addr *ip4, struct in6_addr *ip6) -{ - ip6->s6_addr32[0] = 0; - ip6->s6_addr32[1] = 0; - ip6->s6_addr32[2] = htonl(0xffff); - ip6->s6_addr32[3] = ip4->s_addr; -} - -/** - * iptostr - print a dottedQuad from a 32bit int - * @ip: < IP, in network byte order. - * - * quick abstraction since inet_ntoa takes a slightly strange structure. - * - * Returns: dotted Quad string - */ -__inline__ char *iptostr(uint32_t ip) -{ - struct in_addr in; - in.s_addr = ip; - return inet_ntoa(in); -} -__inline__ const char *ip6tostr(struct in6_addr *ip) -{ - static char t[80]; - return inet_ntop(AF_INET6, ip, t, 80); -} - -/** - * get_ip_from_netdev - - * @har: - * @ip6: - * - * - * Returns: int - */ -int get_ip_from_netdev(char *name, struct in6_addr *ip6) -{ - struct ifconf ifc; - struct ifreq *ifr=NULL; - int i, sock, err=0; - int num_ifrs=20; - ifc.ifc_buf = NULL; - - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) - return -1; - - /* Borrowed from the ifconfig code */ - for(;;) { - ifc.ifc_len = num_ifrs * sizeof(struct ifreq); - if ((ifc.ifc_buf=malloc(num_ifrs * sizeof(struct ifreq)))==NULL) { - err = -ENOMEM; - goto exit; - } - - if (ioctl(sock,SIOCGIFCONF,&ifc)<0) {err=errno; goto exit;} - - if (ifc.ifc_len == (num_ifrs * sizeof(struct ifreq))) { - free(ifc.ifc_buf); - num_ifrs += 10; - continue; - } - break; - } - - err = -1; /* default not found */ - ifr = ifc.ifc_req; - for (i=0; i < ifc.ifc_len; i+= sizeof (struct ifreq), ifr++) { - if( strcmp(ifr->ifr_name, name) == 0 ) { - if (ifr->ifr_addr.sa_family == AF_INET6 ) { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ifr->ifr_addr; - memcpy(&ip6, &sin->sin6_addr, sizeof(struct in6_addr)); - err = 0; - break; - } - if (ifr->ifr_addr.sa_family == AF_INET ) { - struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr; - map_v4_to_v6(&sin->sin_addr, ip6); - err = 0; - break; - } - } - } - -exit: - if(ifc.ifc_buf!=NULL) free(ifc.ifc_buf); - close(sock); - return err; -} - -/** - * get_ip_for_name - - * @name: < - * @ip: > - * - * Returns: int - */ -int get_ip_for_name(char *name, struct in6_addr *ip6) -{ - struct hostent *he; - struct in_addr ip4; - - if( ip6 == NULL ) return -1; - - he = gethostbyname2(name, AF_INET6); - if( he == NULL ) { - he = gethostbyname2(name, AF_INET); - if( he != NULL ) { - memcpy(&ip4, he->h_addr_list[0], sizeof(struct in_addr)); - map_v4_to_v6(&ip4, ip6); - }else{ - return -1; - } - }else{ - memcpy(&ip6, he->h_addr_list[0], sizeof(struct in6_addr)); - } - return 0; -} - -/** - * get_name_for_ip - - * @name: <> buffer to store name in - * @nlen: < max len for name - * @ip: < ip in Be32. - * - * - * Returns: int - */ -int get_name_for_ip(char *name, size_t nlen, uint32_t ip) -{ - struct hostent *he; - - he = gethostbyaddr((const char *)&ip, sizeof(uint32_t), AF_INET); - if( he == NULL ) { - strncpy(name, iptostr(ip), nlen); - return 0; - } - if( he->h_name == NULL ) { - strncpy(name, iptostr(ip), nlen); - return 0; - } - strncpy(name, he->h_name, nlen); - return 0; -} - -/** - * get_ipname - - * @str: - * - * Given a string, which can be a host name, or an ip in v4 or v6 - * return a ip_name_t - * - * May need to have a pref to force name lookups towards ipv4 - * - * Returns: ip_name_t - */ -ip_name_t *get_ipname(char *str) -{ - ip_name_t *in; - struct in_addr ip4; - struct in6_addr ip6; - struct hostent *he; - - in = malloc(sizeof(ip_name_t)); - if( in == NULL ) return NULL; - LLi_init( &in->in_list, in); - - /* try ipv6, - * if fails, try ipv4 - * if fails, try ipv6 name lookup - * if fails, try ipv4 name lookup - * if fails, report error. - */ - if( inet_pton(AF_INET6, str, &ip6) <=0 ) { - if( inet_pton(AF_INET, str, &ip4) <=0 ) { - he = gethostbyname2(str, AF_INET6); - if( he == NULL ) { - he = gethostbyname2(str, AF_INET); - if( he != NULL ) { - memcpy(&ip4, he->h_addr_list[0], sizeof(struct in_addr)); - map_v4_to_v6(&ip4, &ip6); - } - }else{ - memcpy(&ip6, he->h_addr_list[0], sizeof(struct in6_addr)); - } - }else{ - map_v4_to_v6(&ip4, &ip6); - he = gethostbyaddr((const char*)&ip4, sizeof(struct in_addr), AF_INET); - } - }else{ - he = gethostbyaddr((const char*)&ip6, sizeof(struct in6_addr), AF_INET6); - } - - if( he == NULL ) in->name = NULL; - else if( he->h_name == NULL ) in->name = NULL; - else in->name = strdup(he->h_name); - memcpy(&in->ip, &ip6, sizeof(struct in6_addr)); - - return in; - -} - -/** - * print_ipname - - * @in: - * - * - * Returns: char - */ -const char *print_ipname(ip_name_t *in) -{ - static char obuf[160]; - char t[80]; - inet_ntop(AF_INET6, &in->ip, t, 80); - snprintf(obuf, 160, "%s %s", in->name, t); - return obuf; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_ip.h b/gulm/src/utils_ip.h deleted file mode 100644 index dfd8d61..0000000 --- a/gulm/src/utils_ip.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __utils_ip_h__ -#define __utils_ip_h__ -#include "LLi.h" -typedef struct { - LLi_t in_list; - struct in6_addr ip; - uint8_t *name; -} ip_name_t; - -int get_ip_from_netdev(char *name, struct in6_addr *ip6); -int get_name_for_ip(char *name, size_t nlen, uint32_t ip); -int get_ip_for_name(char *name, struct in6_addr *ip); - -__inline__ char *iptostr(uint32_t ip); -__inline__ const char *ip6tostr(struct in6_addr *ip); - -ip_name_t *get_ipname(char *str); -const char *print_ipname(ip_name_t *in); - -#endif /*__utils_ip_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_tostr.c b/gulm/src/utils_tostr.c deleted file mode 100644 index e4243b0..0000000 --- a/gulm/src/utils_tostr.c +++ /dev/null @@ -1,131 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#include "gio_wiretypes.h" - -char *gio_Err_to_str(int x) -{ - char *t="Unknown GULM Err"; - switch(x) { - case gio_Err_Ok: t = "Ok"; break; - - case gio_Err_BadLogin: t = "Bad Login"; break; - case gio_Err_BadCluster: t = "Bad Cluster ID"; break; - case gio_Err_BadConfig: t = "Incompatible configurations"; break; - case gio_Err_BadGeneration: t = "Bad Generation ID"; break; - case gio_Err_BadWireProto: t = "Bad Wire Protocol Version"; break; - - case gio_Err_NotAllowed: t = "Not Allowed"; break; - case gio_Err_Unknown_Cs: t = "Uknown Client"; break; - case gio_Err_BadStateChg: t = "Bad State Change"; break; - case gio_Err_MemoryIssues: t = "Memory Problems"; break; - - case gio_Err_TryFailed: t = "Try Failed"; break; - case gio_Err_AlreadyPend: t = "Request Already Pending"; break; - case gio_Err_Canceled: t = "Request Canceled"; break; - } - return t; -} - -char *gio_mbrupdate_to_str(int x) -{ - char *t="Unknown Membership Update"; - switch(x){ - case gio_Mbr_Logged_in: t = "Logged in"; break; - case gio_Mbr_Logged_out: t = "Logged out"; break; - case gio_Mbr_Expired: t = "Expired"; break; - case gio_Mbr_Killed: t = "Fenced"; break; - case gio_Mbr_OM_lgin: t = "Was Logged in"; break; - } - return t; -} - -char *gio_I_am_to_str(int x) -{ - switch(x){ - case gio_Mbr_ama_Slave: return "Slave"; break; - case gio_Mbr_ama_Pending: return "Pending"; break; - case gio_Mbr_ama_Arbitrating: return "Arbitrating"; break; - case gio_Mbr_ama_Master: return "Master"; break; - case gio_Mbr_ama_Resource: return "Service"; break; - case gio_Mbr_ama_Client: return "Client"; break; - default: return "Unknown I_am state"; break; - } -} - -char *gio_license_states(int x) -{ - switch(x) { - case 0: return "valid"; break; - case 1: return "expired"; break; - case 2: return "invalid"; break; - default: return "unknown"; break; - } -} - - -char *gio_opcodes(int x) -{ - switch(x) { -#define CP(x) case (x): return #x ; break - CP(gulm_err_reply); - - CP(gulm_core_login_req); - CP(gulm_core_login_rpl); - CP(gulm_core_logout_req); - CP(gulm_core_logout_rpl); - CP(gulm_core_reslgn_req); - CP(gulm_core_beat_req); - CP(gulm_core_beat_rpl); - CP(gulm_core_mbr_req); - CP(gulm_core_mbr_updt); - CP(gulm_core_mbr_lstreq); - CP(gulm_core_mbr_lstrpl); - CP(gulm_core_mbr_force); - CP(gulm_core_res_req); - CP(gulm_core_res_list); - CP(gulm_core_state_req); - CP(gulm_core_state_chgs); - CP(gulm_core_shutdown); - CP(gulm_core_forcepend); - - CP(gulm_info_stats_req); - CP(gulm_info_stats_rpl); - CP(gulm_info_set_verbosity); - CP(gulm_socket_close); - CP(gulm_info_slave_list_req); - CP(gulm_info_slave_list_rpl); - - CP(gulm_lock_login_req); - CP(gulm_lock_login_rpl); - CP(gulm_lock_logout_req); - CP(gulm_lock_logout_rpl); - CP(gulm_lock_state_req); - CP(gulm_lock_state_rpl); - CP(gulm_lock_state_updt); - CP(gulm_lock_action_req); - CP(gulm_lock_action_rpl); - CP(gulm_lock_action_updt); - CP(gulm_lock_update_rpl); - CP(gulm_lock_cb_state); - CP(gulm_lock_cb_dropall); - CP(gulm_lock_drop_exp); - CP(gulm_lock_expire); - CP(gulm_lock_dump_req); - CP(gulm_lock_dump_rpl); - CP(gulm_lock_rerunqueues); - -#undef CP - default: return "Unknown Op Code"; break; - } -} -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_tostr.h b/gulm/src/utils_tostr.h deleted file mode 100644 index f5a8afe..0000000 --- a/gulm/src/utils_tostr.h +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __utils_tostr_h__ -#define __utils_tostr_h__ -char *gio_Err_to_str(int x); -char *gio_mbrupdate_to_str(int x); -char *gio_mbrama_to_str(int x); -char *gio_I_am_to_str(int x); -char *gio_license_states(int x); -char *gio_opcodes(int x); -#endif /*__utils_tostr_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_verb_flags.c b/gulm/src/utils_verb_flags.c deleted file mode 100644 index b1447fb..0000000 --- a/gulm/src/utils_verb_flags.c +++ /dev/null @@ -1,256 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifdef __KERNEL__ - -#include "osi.h" - -#ifdef __linux__ -#include <linux/kernel.h> -#include <linux/sched.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> -#endif /*__linux__*/ - -#else /*__KERNEL__*/ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdint.h> -#include "utils_verb_flags.h" - -#define osi_malloc(s) malloc(s) -#define osi_free(p,s) free(p) -#define osi_memset memset -#define osi_strlen strlen -#define osi_memcpy memcpy -#define osi_strdup strdup -#define osi_strtok strtok -#define osi_strncasecmp strncasecmp -#endif /*__KERNEL__*/ - -#include "gulm_log_msg_bits.h" - -static int bit_array[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; - -#define BITCOUNT(x) (bit_array[x & 0x000F] + \ - bit_array[(x >> 4) & 0x000F] + \ - bit_array[(x >> 8) & 0x000F] + \ - bit_array[(x >> 12) & 0x000F] + \ - bit_array[(x >> 16) & 0x000F] + \ - bit_array[(x >> 20) & 0x000F] + \ - bit_array[(x >> 24) & 0x000F] + \ - bit_array[(x >> 28) & 0x000F]) - - - -struct { - char * name; - uint32_t val; -} verbose_flags[] = { - {"Network", lgm_Network, }, - {"Network2", lgm_Network2, }, - {"Network3", lgm_Network3, }, - {"Fencing", lgm_Stomith, }, - {"Heartbeat", lgm_Heartbeat, }, - {"Locking", lgm_locking, }, - {"Forking", lgm_Forking, }, - {"JIDMap", lgm_JIDMap, }, - {"JIDUpdates", lgm_JIDUpdates, }, - {"Subscribers", lgm_Subscribers, }, - {"LockUpdates", lgm_LockUpdates, }, - {"LoginLoops", lgm_LoginLoops, }, - {"ServerState", lgm_ServerState, }, - {"Default", lgm_Network|lgm_Stomith|lgm_Forking, }, -/* Since I really don't want people really doing *all* flags with all, - * there is AlmostAll, which users really get, and ReallyAll, which is all - * bits on. - * This is mostly due to Network3, which dumps messages on nearly - * every packet. (should actually be every packet.) - * Also drop the slave updates, since that is on every packet as well. - */ - {"All", (lgm_ReallyAll & ~(lgm_Network3|lgm_JIDUpdates|lgm_LockUpdates)), }, - {"AlmostAll",lgm_ReallyAll & ~(lgm_Network3|lgm_JIDUpdates|lgm_LockUpdates), }, - {"ReallyAll", lgm_ReallyAll, } -}; - -static int add_string(char *name, size_t *cur, char *str, size_t slen) -{ - size_t nl; - - nl = osi_strlen(name); - if( *cur + nl > slen ) { - osi_memcpy(str + *cur, "...", 3); - cur += 3; - str[*cur] = '\0'; - return -1; - } - osi_memcpy(str+*cur, name, nl ); - *cur += nl; - str[*cur] = ','; - *cur += 1; - - return 0; -} - -/** - * get_verbosity_string - - * @str: - * @verb: - * - * - * Returns: int - */ -int get_verbosity_string(char *str, size_t slen, uint32_t verb) -{ - int i, vlen = sizeof(verbose_flags)/sizeof(verbose_flags[0]); - size_t cur=0; - int combo_match = -1, error = 0; - - osi_memset(str, 0, slen); - slen -= 4; /* leave room for dots and null */ - - if(verb == 0) { - error = add_string("Quiet", &cur, str, slen); - goto end; - } - - /* Combo verb flag phase */ - for(i=0;i<vlen; i++) { - if(BITCOUNT(verbose_flags[i].val) > 1) { - /* check to see if this flag matches exclusively */ - if((verbose_flags[i].val ^ verb) == 0) { - error = add_string(verbose_flags[i].name, &cur, str, slen); - goto end; - } - - if((verbose_flags[i].val & verb) == verbose_flags[i].val) { - if(combo_match < 0) { - combo_match = i; - } - else { - /* Compare this combo with the one in combo_match */ - if(BITCOUNT(verbose_flags[i].val) > - BITCOUNT(verbose_flags[combo_match].val)) { - combo_match = i; - } - } - - } - } - } - /* Add the best combo to the string */ - if(combo_match > -1) { - if (add_string(verbose_flags[combo_match].name, &cur, str, slen) == -1) { - error = -1; - goto end; - } - } - - /* Single verb flag phase */ - for(i=0;i<vlen; i++) { - if(BITCOUNT(verbose_flags[i].val) == 1) { - if(combo_match > -1) { - if((verbose_flags[combo_match].val & verbose_flags[i].val) == - verbose_flags[i].val) { - continue; - } - } - - if((verbose_flags[i].val & verb) == verbose_flags[i].val) { - if(add_string(verbose_flags[i].name, &cur, str, slen) == -1) { - error = -1; - goto end; - } - } - } - } - end: - /* Clear trailing ',' */ - if(str[cur-1] == ',') { - str[cur-1] = '\0'; - } - return error; -} -/** - * set_verbosity - - * @str: - * @verb: - * - * toggle bits according to the `rules' in the str. - * str is a list of verb flags. can be prefexed with '+' or '-' - * No prefix is the same as '+' prefix - * '+' sets bits - * '-' unsets bits. - * special 'clear' unsets all. - */ -void set_verbosity(char *str, uint32_t *verb) -{ - char *token, *next; - int i, wl, tl, len = sizeof(verbose_flags)/sizeof(verbose_flags[0]); - - if( str == NULL ) return; - - wl = osi_strlen(str); - if( wl == 0 ) return; - for(token = str, tl=0; tl < wl && - token[tl] != ',' && - token[tl] != ' ' && - token[tl] != '|' && - token[tl] != '\0'; - tl ++ ); - next = token + tl + 1; - - for(;;) { - if( token[0] == '-' ) { - token++; - for(i=0; i < len; i++ ) { - if(osi_strncasecmp(token, verbose_flags[i].name, tl) == 0 ) { - (*verb) &= ~(verbose_flags[i].val); - } - } - }else if( token[0] == '+' ) { - token++; - for(i=0; i < len; i++ ) { - if(osi_strncasecmp(token, verbose_flags[i].name, tl) == 0 ) { - (*verb) |= verbose_flags[i].val; - } - } - }else{ - if( osi_strncasecmp(token, "clear", tl) == 0 ) { - (*verb) = 0; - } else { - for(i=0; i < len; i++ ) { - if(osi_strncasecmp(token, verbose_flags[i].name, tl) == 0 ) { - (*verb) |= verbose_flags[i].val; - } - } - } - } - - if( next >= str + wl ) return; - for(token = next, tl = 0; - tl < wl && - token[tl] != ',' && - token[tl] != ' ' && - token[tl] != '|' && - token[tl] != '\0'; - tl ++ ); - next = token + tl + 1; - - } -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/utils_verb_flags.h b/gulm/src/utils_verb_flags.h deleted file mode 100644 index 2d646a1..0000000 --- a/gulm/src/utils_verb_flags.h +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __utils_verb_flags_h__ -#define __utils_verb_flags_h__ -int get_verbosity_string(char *str, size_t slen, uint32_t verb); -void set_verbosity(char *str, uint32_t *verb); -#endif /*__utils_verb_flags_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/xdr.h b/gulm/src/xdr.h deleted file mode 100644 index bcf82f2..0000000 --- a/gulm/src/xdr.h +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -#ifndef __gulm_xdr_h__ -#define __gulm_xdr_h__ -typedef struct xdr_enc_s xdr_enc_t; -typedef struct xdr_dec_s xdr_dec_t; - -/* sockets in kernel space are done a bit different than socket in - * userspace. But we need to have them appear to be the same. - */ -#ifdef __KERNEL__ - -#ifdef __linux__ -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <net/sock.h> - -typedef struct socket* xdr_socket; -#endif /*__linux__*/ -#else /*__KERNEL__*/ -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <unistd.h> -#include <errno.h> -typedef int xdr_socket; -#endif /*__KERNEL__*/ - -/* start things up */ -int xdr_open(xdr_socket *sk); -int xdr_connect(struct sockaddr_in6 *adr, xdr_socket sk); -void xdr_close(xdr_socket *sk); - -/* deep, basic io */ -#ifdef __KERNEL__ -#ifdef __linux__ -#define XDR_SOCKET_INIT (NULL) -size_t xdr_send(struct socket *sock, void *buf, size_t size); -size_t xdr_recv(struct socket *sock, void *buf, size_t size); -#endif /*__linux__*/ -#else /*__KERNEL__*/ -#define XDR_SOCKET_INIT (-1) -ssize_t xdr_recv(int fd, void *buf, size_t len); -ssize_t xdr_send(int fd, void *buf, size_t len); -#endif /*__KERNEL__*/ - -xdr_enc_t* xdr_enc_init(xdr_socket sk, int buffer_size); -xdr_dec_t* xdr_dec_init(xdr_socket sk, int buffer_size); -int xdr_enc_flush(xdr_enc_t *xdr); -int xdr_enc_release(xdr_enc_t *xdr); /* calls xdr_enc_flush() */ -void xdr_enc_force_release(xdr_enc_t *xdr); /* doesn't call xdr_enc_flush() */ -void xdr_dec_release(xdr_dec_t *xdr); -/* xdr_enc_force_release() is for when you get and error sending and you - * want to free that stuff up right away. If you use the regular release - * for enc, it will fail if it cannot send data over the filedesciptor. - */ - -/* encoders add to a stream */ -int __inline__ xdr_enc_uint64(xdr_enc_t *xdr, uint64_t i); -int __inline__ xdr_enc_uint32(xdr_enc_t *xdr, uint32_t i); -int __inline__ xdr_enc_uint16(xdr_enc_t *xdr, uint16_t i); -int __inline__ xdr_enc_uint8(xdr_enc_t *xdr, uint8_t i); -int __inline__ xdr_enc_ipv6(xdr_enc_t *enc, struct in6_addr *ip); -int xdr_enc_raw(xdr_enc_t *xdr, void *pointer, uint16_t len); -int xdr_enc_raw_iov(xdr_enc_t *xdr, int count, struct iovec *iov); -int xdr_enc_string(xdr_enc_t *xdr, uint8_t *s); -int xdr_enc_list_start(xdr_enc_t *xdr); -int xdr_enc_list_stop(xdr_enc_t *xdr); - -/* decoders remove from stream */ -int xdr_dec_uint64(xdr_dec_t *xdr, uint64_t *i); -int xdr_dec_uint32(xdr_dec_t *xdr, uint32_t *i); -int xdr_dec_uint16(xdr_dec_t *xdr, uint16_t *i); -int xdr_dec_uint8(xdr_dec_t *xdr, uint8_t *i); -int xdr_dec_ipv6(xdr_dec_t *xdr, struct in6_addr *ip); -int xdr_dec_raw(xdr_dec_t *xdr, void *p, uint16_t *l); /* no malloc */ -int xdr_dec_raw_m(xdr_dec_t *xdr, void **p, uint16_t *l); /* mallocs p */ -int xdr_dec_raw_ag(xdr_dec_t *xdr, void **p, uint16_t *bl, uint16_t *rl); -int xdr_dec_string(xdr_dec_t *xdr, uint8_t **strp); /* mallocs s */ -int xdr_dec_string_nm(xdr_dec_t *xdr, uint8_t *strp, size_t l); /* no malloc */ -int xdr_dec_string_ag(xdr_dec_t *xdr, uint8_t **s, uint16_t *bl); -int xdr_dec_list_start(xdr_dec_t *xdr); -int xdr_dec_list_stop(xdr_dec_t *xdr); - -#endif /*__gulm_xdr_h__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/xdr_base.c b/gulm/src/xdr_base.c deleted file mode 100644 index fbd94d1..0000000 --- a/gulm/src/xdr_base.c +++ /dev/null @@ -1,823 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/* - * This is a bit of an abstraction layer to get this working in both kernel - * and userspace. - */ -#define MIN(a,b) ((a<b)?a:b) - -#ifdef __KERNEL__ - -#include "osi.h" - -#ifdef __linux__ -#include <linux/kernel.h> -#include <linux/sched.h> -#define __KERNEL_SYSCALLS__ -#include <linux/unistd.h> -#endif /*__linux__*/ - -#define xdr_malloc(y) kmalloc(y, GFP_KERNEL) -#define xdr_free(x,y) kfree(x) -#define xdr_memcpy(x,y,l) memcpy(x,y,l) - -/** - * xdr_realloc - a realloc for kernel space. - * @a: < pointer to realloc - * @nl: < desired new size - * @ol: < current old size - * - * Not as good as the real realloc, since it always moves memory. But good - * enough for as little as it will get used here. - * - * XXX this is broken. - * - * Returns: void* - */ -static void *xdr_realloc(void *a, size_t nl, size_t ol) -{ - if( nl == ol ) { - return a; - }else - if( nl == 0 ) { - xdr_free(a, ol); - return NULL; - }else - if( a == NULL && nl > 0 ) { - return xdr_malloc(nl); - }else - { - void *tmp; - tmp = xdr_malloc(nl); - if( tmp == NULL ) return NULL; - xdr_memcpy(tmp, a, MIN(nl,ol)); - xdr_free(a,ol); - return tmp; - } -} - -#else /*__KERNEL__*/ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/poll.h> -#include <sys/uio.h> - -#include "osi_endian.h" - -#define xdr_malloc(y) malloc(y) -#define xdr_free(x,y) free(x) -#define xdr_realloc(p,n,o) realloc(p,n) -#define xdr_memcpy(x,y,l) memcpy(x,y,l) - -#endif /*__KERNEL__*/ - -#include "xdr.h" - -typedef enum {xdr_enc, xdr_dec} xdr_type; - -/* encoders have this sorta non-blocking, growing buffering stunt. - * makes them a bit different from the decoders now. - */ -struct xdr_enc_s { - size_t default_buf_size; - xdr_socket fd; - xdr_type type; - size_t length; - size_t curloc; - uint8_t *stream; -}; - -/* decoders only pull a single item off of the socket at a time. - * so this is all they need. - */ -struct xdr_dec_s { - size_t length; /* total byte length of the stream */ - size_t curloc; /* current byte offset from start */ - uint8_t *stream; /* start of the encoded stream. */ - xdr_socket fd; - xdr_type type; -}; - -/* the types of data we support. */ - -#define XDR_NULL 0x00 /* NOT A VALID TAG!!! used in dec code. */ -#define XDR_LIST_START 0x01 -#define XDR_LIST_STOP 0x02 -/* list is a variable length device. It is a start tag, some number of - * xdr_enc_*, then an stop tag. It's main purpose is to provide a method - * of encasing data. - * */ -#define XDR_STRING 0x04 -/* string tag is followed by a uint16 which is the byte length */ -#define XDR_RAW 0x05 -/* raw tag is followed by a uint16 which is the byte length - * if 65535 bytes isn't enough, split your data and put multiples of these - * back to back. (idea of xdr is to avoid this twit.) - * */ - -/* note, if the size of these should variate, I'm screwed. Should consider - * changing this all to the bit shift and array access to be more concrete. - * later. - */ -#define XDR_UINT64 0x06 -#define XDR_UINT32 0x07 -#define XDR_UINT16 0x08 -#define XDR_UINT8 0x09 -/* should add signed ints */ - -#define XDR_IPv6 0x0a /* 16 bytes, IPv6 address */ - -/* any other base types? - */ - -#define XDR_DEFAULT_BUFFER_SIZE 4096 -/*****************************************************************************/ - -/** - * xdr_enc_init - - * @fd: - * @buffer_size: - * - * - * Returns: xdr_enc_t* - */ -xdr_enc_t* xdr_enc_init(xdr_socket fd, int buffer_size) -{ - xdr_enc_t *xdr; - - if( buffer_size <=0 ) buffer_size = XDR_DEFAULT_BUFFER_SIZE; - - xdr = xdr_malloc(sizeof(xdr_enc_t)); - if( xdr == NULL ) return NULL; - xdr->stream = xdr_malloc(buffer_size); - if( xdr->stream == NULL ) { - xdr_free(xdr, sizeof(xdr_enc_t)); - return NULL; - } - xdr->fd = fd; - xdr->type = xdr_enc; - xdr->default_buf_size = buffer_size; - xdr->length = buffer_size; - xdr->curloc = 0; - - return xdr; -} - -/** - * xdr_dec_init - - * @fd: - * @buffer_size: - * - * - * Returns: xdr_dec_t* - */ -xdr_dec_t* xdr_dec_init(xdr_socket fd, int buffer_size) -{ - xdr_dec_t *xdr; - - if( buffer_size <=0 ) buffer_size = XDR_DEFAULT_BUFFER_SIZE; - - xdr = xdr_malloc(sizeof(xdr_dec_t)); - if( xdr == NULL ) return NULL; - xdr->length = buffer_size; - xdr->curloc = 0; - xdr->stream = xdr_malloc(buffer_size); - xdr->fd = fd; - xdr->type = xdr_dec; - if( xdr->stream == NULL ) { - xdr_free(xdr, sizeof(xdr_dec_t)); - return NULL; - } - *(xdr->stream) = XDR_NULL; /* so the first dec_call will call get_next */ - return xdr; -} - -/*****************************************************************************/ -/** - * xdr_enc_flush - - * @xdr: - * - * Returns: int - */ -int xdr_enc_flush(xdr_enc_t *xdr) -{ - int err; - if( xdr == NULL ) return -EINVAL; - if( xdr->type != xdr_enc) return -EINVAL; - if( xdr->curloc == 0 ) return 0; - - err = xdr_send(xdr->fd, xdr->stream, xdr->curloc); - if( err < 0 ) return err; - if( err == 0 ) return -EPROTO; /* why? */ - xdr->curloc = 0; - - return 0; -} - -/** - * xdr_release - - * @xdr: - * - * Free the memory, losing whatever may be there. - */ -void xdr_dec_release(xdr_dec_t *xdr) -{ - if( xdr == NULL ) return; - xdr_free(xdr->stream, xdr->length); - xdr_free(xdr, sizeof(xdr_dec_t)); -} - -/** - * xdr_enc_force_release - - * @xdr: - * - * Free the memory, losing whatever may be there. - */ -void xdr_enc_force_release(xdr_enc_t *xdr) -{ - if( xdr == NULL ) return; - if( xdr->stream != NULL ) xdr_free(xdr->stream, xdr->length); - xdr_free(xdr, sizeof(xdr_enc_t)); -} - -/** - * xdr_enc_release - - * @xdr: - * - * Free things up, trying to send any possible leftover data first. - * - * Returns: int - */ -int xdr_enc_release(xdr_enc_t *xdr) -{ - int e; - if( xdr == NULL ) return -EINVAL; - if((e=xdr_enc_flush(xdr)) != 0 ) return e; - xdr_enc_force_release(xdr); - return 0; -} - -/*****************************************************************************/ -/** - * grow_stream - - * @xdr: - * @len: - * - * each single encoded call needs to fit within a buffer. So we make sure - * the buffer is big enough. - * - * If the buffer is big enough, but just doesn't have room, we send the - * data in the buffer, emptying it, first. - * - * Returns: int - */ -static int grow_stream(xdr_enc_t *enc, size_t len) -{ - int err; - uint8_t *c; - - /* buffer must be big enough for one type entry. */ - if( len > enc->length ) { - c = xdr_realloc(enc->stream, len, enc->length); - if( c == NULL ) return -ENOMEM; - enc->stream = c; - enc->length = len; - } - - /* if there isn't room on the end of this chunk, - * try sending what we've got. - */ - if( enc->curloc + len > enc->length ) { - err = xdr_enc_flush(enc); - if(err != 0 ) { - /* error, better pass this up. */ - return err; - } - } - - return 0; -} - - -/** - * append_bytes - - * @xdr: - * @xdr_type: - * @bytes: - * @len: - * - * - * Returns: int - */ -static int append_bytes(xdr_enc_t *xdr, uint8_t xdr_type, void *bytes, size_t len) -{ - int e; - if( xdr == NULL ) return -EINVAL; - if( xdr->type != xdr_enc ) return -EINVAL; - - /* len + 1; need the one byte for the type code. */ - if((e=grow_stream(xdr, len + 1)) != 0) return e; - *(xdr->stream + xdr->curloc) = xdr_type; - xdr->curloc += 1; - xdr_memcpy((xdr->stream + xdr->curloc), bytes, len); - xdr->curloc += len; - - return 0; -} - -int __inline__ xdr_enc_uint64(xdr_enc_t *xdr, uint64_t i) -{ - uint64_t b = osi_cpu_to_be64(i); - return append_bytes(xdr, XDR_UINT64, &b, sizeof(uint64_t)); -} - -int __inline__ xdr_enc_uint32(xdr_enc_t *xdr, uint32_t i) -{ - uint32_t b = osi_cpu_to_be32(i); - return append_bytes(xdr, XDR_UINT32, &b, sizeof(uint32_t)); -} - -int __inline__ xdr_enc_uint16(xdr_enc_t *xdr, uint16_t i) -{ - uint16_t b = osi_cpu_to_be16(i); - return append_bytes(xdr, XDR_UINT16, &b, sizeof(uint16_t)); -} - -int __inline__ xdr_enc_uint8(xdr_enc_t *xdr, uint8_t i) -{ - return append_bytes(xdr, XDR_UINT8, &i, sizeof(uint8_t)); -} - -/* or should i add the headers, and pass this a struct in6_addr? */ -int __inline__ xdr_enc_ipv6(xdr_enc_t *xdr, struct in6_addr *ip) -{ /* bytes should already be in the right order. */ - return append_bytes(xdr, XDR_IPv6, ip->s6_addr, 16); -} - -int xdr_enc_raw(xdr_enc_t *xdr, void *p, uint16_t len) -{ - int e; - uint16_t temp; - if( xdr == NULL ) return -EINVAL; - if((e=grow_stream(xdr, len + 3)) != 0) return e; - *(xdr->stream + xdr->curloc) = XDR_RAW; - xdr->curloc +=1; - temp = osi_cpu_to_be16(len); - xdr_memcpy((xdr->stream + xdr->curloc), &temp, 2); - xdr->curloc += 2; - xdr_memcpy((xdr->stream + xdr->curloc), p, len); - xdr->curloc += len; - return 0; -} - -int xdr_enc_raw_iov(xdr_enc_t *xdr, int count, struct iovec *iov) -{ - size_t total=0; - int i,err; - uint16_t temp; - if( xdr == NULL || count < 1 || iov == NULL ) return -EINVAL; - for(i=0; i<count; i++) total += iov[i].iov_len; - /* make sure it fits in a uint16_t */ - if( total > 0xffff ) return -EFBIG; - /* grow to fit */ - if((err = grow_stream(xdr, total + 3)) != 0 ) return err; - /* copy in header and size */ - *(xdr->stream + xdr->curloc) = XDR_RAW; - xdr->curloc +=1; - temp = osi_cpu_to_be16(total); - xdr_memcpy((xdr->stream + xdr->curloc), &temp, 2); - xdr->curloc += 2; - /* copy in all iovbufs */ - for(i=0; i < count; i++) { - if(iov[i].iov_base == NULL ) continue; - xdr_memcpy((xdr->stream + xdr->curloc), iov[i].iov_base, iov[i].iov_len); - xdr->curloc += iov[i].iov_len; - } - return 0; -} - -int xdr_enc_string(xdr_enc_t *xdr, uint8_t *s) -{ - int len,e; - uint16_t temp; - if( xdr == NULL ) return -EINVAL; - if(s == NULL ) len = 0; - else len = strlen(s); - if((e=grow_stream(xdr, len + 3)) != 0) return e; - *(xdr->stream + xdr->curloc) = XDR_STRING; - xdr->curloc +=1; - temp = osi_cpu_to_be16(len); - xdr_memcpy((xdr->stream + xdr->curloc), &temp, 2); - xdr->curloc += 2; - if( len > 0 ) { - xdr_memcpy((xdr->stream + xdr->curloc), s, len); - xdr->curloc += len; - } - return 0; -} - -int xdr_enc_list_start(xdr_enc_t *xdr) -{ - int e; - if( xdr == NULL ) return -EINVAL; - if( (e=grow_stream(xdr, 1)) != 0) return e; - *(xdr->stream + xdr->curloc) = XDR_LIST_START; - xdr->curloc +=1; - return 0; -} -int xdr_enc_list_stop(xdr_enc_t *xdr) -{ - int e; - if( xdr == NULL ) return -EINVAL; - if( (e=grow_stream(xdr, 1)) != 0) return e; - *(xdr->stream + xdr->curloc) = XDR_LIST_STOP; - xdr->curloc +=1; - return 0; -} - -/*****************************************************************************/ - -/** - * get_next - - * @xdr: - * - * get what ever may be next, and put it into the buffer. - * - * Returns: int - */ -static int get_next(xdr_dec_t *xdr) -{ - int err; - uint16_t len; - if( (err = xdr_recv(xdr->fd, xdr->stream, 1)) < 0 ) return err; - if( err == 0 ) return -EPROTO; - xdr->curloc = 1; - if( *(xdr->stream) == XDR_UINT64 ) { - len = sizeof(uint64_t); - }else - if( *(xdr->stream) == XDR_UINT32 ) { - len = sizeof(uint32_t); - }else - if( *(xdr->stream) == XDR_UINT16 ) { - len = sizeof(uint16_t); - }else - if( *(xdr->stream) == XDR_UINT8 ) { - len = sizeof(uint8_t); - }else - if( *(xdr->stream) == XDR_IPv6 ) { - len = 16; - }else - if( *(xdr->stream) == XDR_STRING ) { - if( (err = xdr_recv(xdr->fd, (xdr->stream+1), 2)) < 0 ) return err; - if( err == 0 ) return -EPROTO; - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc += 2; - }else - if( *(xdr->stream) == XDR_RAW ) { - if( (err = xdr_recv(xdr->fd, (xdr->stream+1), 2)) < 0 ) return err; - if( err == 0 ) return -EPROTO; - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc += 2; - }else - if( *(xdr->stream) == XDR_LIST_START ) { - xdr->curloc = 0; - return 0; - }else - if( *(xdr->stream) == XDR_LIST_STOP ) { - xdr->curloc = 0; - return 0; - }else - { - return -1; - } - - /* grow buffer if need be. */ - if( xdr->curloc + len > xdr->length ) { - uint8_t *c; - c = xdr_realloc(xdr->stream, xdr->curloc + len, xdr->length ); - if( c == NULL ) return -ENOMEM; - xdr->stream = c; - xdr->length = xdr->curloc + len; - } - - if( len > 0 ) { - if((err=xdr_recv(xdr->fd, (xdr->stream + xdr->curloc), len)) < 0 ) - return err; - if( err == 0 ) return -EPROTO; - } - xdr->curloc = 0; - return 0; -} - -int xdr_dec_uint64(xdr_dec_t *xdr, uint64_t *i) -{ - int err; - if( xdr == NULL || i == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_UINT64 ) return -ENOMSG; - *i = osi_be64_to_cpu( *((uint64_t*)(xdr->stream + 1)) ); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int xdr_dec_uint32(xdr_dec_t *xdr, uint32_t *i) -{ - int err; - if( xdr == NULL || i == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_UINT32 ) return -ENOMSG; - *i = osi_be32_to_cpu( *((uint32_t*)(xdr->stream + 1)) ); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int xdr_dec_uint16(xdr_dec_t *xdr, uint16_t *i) -{ - int err; - if( xdr == NULL || i == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_UINT16 ) return -ENOMSG; - *i = osi_be16_to_cpu( *((uint16_t*)(xdr->stream + 1)) ); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int xdr_dec_uint8(xdr_dec_t *xdr, uint8_t *i) -{ - int err; - if( xdr == NULL || i == NULL ) return -EINVAL; - - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_UINT8 ) return -ENOMSG; - *i = *((uint8_t*)(xdr->stream + 1)); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int xdr_dec_ipv6(xdr_dec_t *xdr, struct in6_addr *ip) -{ - int err; - if( xdr == NULL || ip == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_IPv6 ) return -ENOMSG; - memcpy(ip, xdr->stream + 1, 16); - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* mallocing version */ -int xdr_dec_raw_m(xdr_dec_t *xdr, void **p, uint16_t *l) -{ - int len; - void *str; - int err; - - if( xdr == NULL || p == NULL || l == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_RAW ) return -ENOMSG; - xdr->curloc = 1; - - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc +=2; - - str = xdr_malloc(len); - if( str == NULL ) return -ENOMEM; - xdr_memcpy(str, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *p = str; - *l = len; - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* non-mallocing version */ -int xdr_dec_raw(xdr_dec_t *xdr, void *p, uint16_t *l) -{ - int len; - int err; - - if( xdr == NULL || p == NULL || l == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_RAW ) return -ENOMSG; - xdr->curloc = 1; - - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc +=2; - - if( len > *l ) return -1; - - xdr_memcpy(p, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *l = len; - - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/** - * xdr_dec_raw_ag - auto-growing version - * @xdr: - * @p: <> pointer to buffer - * @bl: <> size of the buffer - * @rl: > size of data read from stream - * - * This form of xdr_dec_raw will increase the size of a pre-malloced buffer - * to fit the data it is reading. It is kind of a merger of the - * non-mallocing and mallocing versions. - * - * Returns: int - */ -int xdr_dec_raw_ag(xdr_dec_t *xdr, void **p, uint16_t *bl, uint16_t *rl) -{ - int len; - int err; - - if( xdr == NULL || p == NULL || bl == NULL || rl == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_RAW ) return -ENOMSG; - xdr->curloc = 1; - - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc +=2; - - if( len > *bl ) { /* grow p */ - void *temp; - temp = xdr_realloc( *p, len, *bl ); - if( temp == NULL ) return -ENOMEM; - *bl = len; - *p = temp; - } - - xdr_memcpy( *p, (xdr->stream + xdr->curloc), len); - xdr->curloc += len; - - *rl = len; - - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* mallocing version */ -int xdr_dec_string(xdr_dec_t *xdr, uint8_t **strp) -{ - int len; - char *str; - int err; - if( xdr == NULL || strp == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_STRING ) return -ENOMSG; - xdr->curloc = 1; - - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc +=2; - - if( len > 0 ) { - str = xdr_malloc(len+1); - if( str == NULL ) return -ENOMEM; - xdr_memcpy(str, (xdr->stream + xdr->curloc), len); - str[len] = '\0'; - xdr->curloc += len; - - *strp = str; - }else{ - *strp = NULL; - } - - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* non-mallocing version */ -int xdr_dec_string_nm(xdr_dec_t *xdr, uint8_t *string, size_t l) -{ - int len; - int err; - if( xdr == NULL || string == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_STRING ) return -ENOMSG; - xdr->curloc =1; - - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc +=2; - - if( len > 0 ) { - xdr_memcpy(string, (xdr->stream + xdr->curloc), MIN(len, l )); - if( l > len ) { - string[len] = '\0'; - } - string[l-1] = '\0'; - }else{ - string[0] = '\0'; - } - - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -int xdr_dec_string_ag(xdr_dec_t *xdr, uint8_t **s, uint16_t *bl) -{ - int len; - int err; - if( xdr == NULL || s == NULL || bl == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_STRING ) return -ENOMSG; - xdr->curloc =1; - - len = osi_be16_to_cpu(*((uint16_t*)(xdr->stream + xdr->curloc))); - xdr->curloc +=2; - - if( len == 0 ) { /* empty string */ - if( *s != NULL ) **s = '\0'; - *(xdr->stream) = XDR_NULL; - return 0; - } - - if( len >= *bl ) { /* grow s */ - void *temp; - temp = xdr_realloc( *s, len + 1, *bl ); - if( temp == NULL ) return -ENOMEM; - *bl = len + 1; - *s = temp; - } - - xdr_memcpy( *s, (xdr->stream + xdr->curloc), len); - (*s)[len] = '\0'; - - *(xdr->stream) = XDR_NULL; - return 0; -} - -int xdr_dec_list_start(xdr_dec_t *xdr) -{ - int err; - if( xdr == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_LIST_START ) return -ENOMSG; - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} -int xdr_dec_list_stop(xdr_dec_t *xdr) -{ - int err; - if( xdr == NULL ) return -EINVAL; - if( *(xdr->stream) == XDR_NULL ) { - if( (err=get_next(xdr)) != 0 ) return err; - } - if( *(xdr->stream) != XDR_LIST_STOP ) return -ENOMSG; - /* read the item out, mark that */ - *(xdr->stream) = XDR_NULL; - return 0; -} - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/xdr_io.c b/gulm/src/xdr_io.c deleted file mode 100644 index 7efedb0..0000000 --- a/gulm/src/xdr_io.c +++ /dev/null @@ -1,176 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/* - * does the lowest level of reads and writes. - * In kernel and/or userspace. - */ - -#include "xdr.h" - -#ifdef __KERNEL__ -#ifdef __linux__ -#include <linux/net.h> -#include <linux/in.h> -#include <linux/socket.h> -#include <net/sock.h> -#include "asm/uaccess.h" - - -/** - * do_tfer - transfers data over a socket - * @sock: < socket - * @iov: <> iovec of buffers - * @n: < how many iovecs - * @size: < total data size to send/recv - * @dir: < send or recv - * @timeout: < how many sec to wait. 0 == forever. - * - * Returns: <0: Error - * >=0: Bytes transfered - */ -static int do_tfer(struct socket *sock, struct iovec *iov, int n, int size, - int dir, int timeout) -{ - unsigned long flags; - sigset_t oldset; - struct msghdr m; - mm_segment_t fs; - int rv, moved = 0; - - fs = get_fs(); - set_fs(get_ds()); - - /* XXX do I still want the signal stuff? */ - spin_lock_irqsave(¤t->sigmask_lock, flags); - oldset = current->blocked; - siginitsetinv(¤t->blocked, - sigmask(SIGKILL)|sigmask(SIGTERM) ); - recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); - - if( timeout > 0 ) { - if( dir ) - sock->sk->sndtimeo = ( timeout * HZ ); - else - sock->sk->rcvtimeo = ( timeout * HZ ); - }else{ - if( dir ) - sock->sk->sndtimeo = MAX_SCHEDULE_TIMEOUT; - else - sock->sk->rcvtimeo = MAX_SCHEDULE_TIMEOUT; - } - - memset(&m, 0, sizeof(struct msghdr)); - for (;;) - { - m.msg_iov = iov; - m.msg_iovlen = n; - m.msg_flags = MSG_NOSIGNAL; - - if (dir) - rv = sock_sendmsg(sock, &m, size - moved); - else - rv = sock_recvmsg(sock, &m, size - moved, 0); - - if (rv <= 0) - goto out_err; - moved += rv; - - if (moved >= size) - break; - - /* adjust iov's for next transfer */ - while (iov->iov_len == 0) - { - iov++; - n--; - } - - } - rv = moved; -out_err: - spin_lock_irqsave(¤t->sigmask_lock, flags); - current->blocked = oldset; - recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); - - set_fs(fs); - - return rv; -} - -size_t xdr_send(struct socket *sock, void *buf, size_t size) -{ - struct iovec iov; - int res; - - iov.iov_base = buf; - iov.iov_len = size; - - res = do_tfer(sock, &iov, 1, size, 1, 0); - - return res; -} - -size_t xdr_recv(struct socket *sock, void *buf, size_t size) -{ - struct iovec iov; - int res; - - iov.iov_base = buf; - iov.iov_len = size; - - res = do_tfer(sock, &iov, 1, size, 0, 0); - - return res; -} - -#endif /*__linux__*/ -#else /*__KERNEL__*/ - -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> - -ssize_t xdr_recv(int fd, void *buf, size_t len) -{ - ssize_t cnt=0; - size_t ttl=0; - while(len > 0) { - cnt = recv(fd, buf, len, 0); - if( cnt == 0 ) return 0; - if( cnt < 0 ) return -errno; - len -= cnt; - buf += cnt; - ttl += cnt; - } - return ttl; -} - -ssize_t xdr_send(int fd, void *buf, size_t len) -{ - ssize_t cnt=0; - size_t ttl=0; - while(len > 0) { - cnt = send(fd, buf, len, 0); - if( cnt == 0 ) return 0; - if( cnt < 0 ) return -errno; - len -= cnt; - buf += cnt; - ttl += cnt; - } - return ttl; -} - -#endif /*__KERNEL__*/ -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/gulm/src/xdr_socket.c b/gulm/src/xdr_socket.c deleted file mode 100644 index b1f8073..0000000 --- a/gulm/src/xdr_socket.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ -/* - * This file opens and closes a socket. - * userspace only now. - * which mostly makes this file extra abstraction. maybe some other day if - * i find free time i'll remove it. - */ - -#include "xdr.h" - -int xdr_open(xdr_socket *xsk) -{ - int sk; - sk = socket(AF_INET6, SOCK_STREAM, 0); - if( sk < 0 ) {*xsk = -1; return -errno;} - *xsk = sk; - return 0; -} - -int xdr_connect(struct sockaddr_in6 *adr, xdr_socket xsk) -{ - int err; - err = connect(xsk, (struct sockaddr*)adr, sizeof(struct sockaddr_in6)); - if( err < 0 ) return -errno; - return 0; -} - -void xdr_close(xdr_socket *xsk) -{ - if( *xsk < 0 ) return; - close(*xsk); - *xsk = -1; -} - - -/* vim: set ai cin et sw=3 ts=3 : */ diff --git a/iddev/Makefile b/iddev/Makefile deleted file mode 100644 index 907fefd..0000000 --- a/iddev/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd lib && ${MAKE} all - -clean: - cd lib && ${MAKE} clean - -distclean: clean - rm -f make/defines.mk - -install: - cd lib && ${MAKE} install - -uninstall: - cd lib && ${MAKE} uninstall diff --git a/iddev/configure b/iddev/configure deleted file mode 100755 index dd4d532..0000000 --- a/iddev/configure +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/iddev/include/global.h b/iddev/include/global.h deleted file mode 100644 index 2c44365..0000000 --- a/iddev/include/global.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __GLOBAL_DOT_H__ -#define __GLOBAL_DOT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(__KERNEL__) || defined(_KERNEL) -#error "don't use global.h in kernel space" -#endif - - - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - - - -#include <inttypes.h> - -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; - - - -#ifdef __cplusplus -} -#endif - -#endif /* __GLOBAL_H__ */ diff --git a/iddev/include/osi_endian.h b/iddev/include/osi_endian.h deleted file mode 100644 index 17d1343..0000000 --- a/iddev/include/osi_endian.h +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __OSI_ENDIAN_DOT_H__ -#define __OSI_ENDIAN_DOT_H__ - - -#ifdef __linux__ - -#ifdef __KERNEL__ -#error "don't use osi_endian.h in kernel space under Linux" -#endif - -#include <endian.h> -#include <byteswap.h> - -/* I'm not sure which versions of alpha glibc/gcc are broken, - so fix all of them. */ -#ifdef __alpha__ -#undef bswap_64 -static __inline__ unsigned long bswap_64(unsigned long x) -{ - unsigned int h = x >> 32; - unsigned int l = x; - - h = bswap_32(h); - l = bswap_32(l); - - return ((unsigned long)l << 32) | h; -} -#endif /* __alpha__ */ - -#endif /* __linux__ */ - - -#ifdef __FreeBSD__ - -#include <machine/endian.h> -#include <sys/types.h> - -#define __BIG_ENDIAN BIG_ENDIAN -#define __LITTLE_ENDIAN LITTLE_ENDIAN -#define __BYTE_ORDER BYTE_ORDER - -#define bswap_16 __byte_swap_word -#define bswap_32 __byte_swap_long - -/* There is no 64 bit swap operation in FreeBSD, so define bswap_64 the - same as the alpha fix for linux */ -static __inline__ unsigned long long bswap_64(unsigned long long x) -{ - unsigned int h = x >> 32; - unsigned int l = x; - - h = bswap_32(h); - l = bswap_32(l); - - return ((unsigned long long)l << 32) | h; -} - -#endif /* __FreeBSD__ */ - - -#if __BYTE_ORDER == __BIG_ENDIAN - -#define osi_be16_to_cpu(x) (x) -#define osi_be32_to_cpu(x) (x) -#define osi_be64_to_cpu(x) (x) - -#define osi_cpu_to_be16(x) (x) -#define osi_cpu_to_be32(x) (x) -#define osi_cpu_to_be64(x) (x) - -#define osi_le16_to_cpu(x) (bswap_16((x))) -#define osi_le32_to_cpu(x) (bswap_32((x))) -#define osi_le64_to_cpu(x) (bswap_64((x))) - -#define osi_cpu_to_le16(x) (bswap_16((x))) -#define osi_cpu_to_le32(x) (bswap_32((x))) -#define osi_cpu_to_le64(x) (bswap_64((x))) - -#endif /* __BYTE_ORDER == __BIG_ENDIAN */ - - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -#define osi_be16_to_cpu(x) (bswap_16((x))) -#define osi_be32_to_cpu(x) (bswap_32((x))) -#define osi_be64_to_cpu(x) (bswap_64((x))) - -#define osi_cpu_to_be16(x) (bswap_16((x))) -#define osi_cpu_to_be32(x) (bswap_32((x))) -#define osi_cpu_to_be64(x) (bswap_64((x))) - -#define osi_le16_to_cpu(x) (x) -#define osi_le32_to_cpu(x) (x) -#define osi_le64_to_cpu(x) (x) - -#define osi_cpu_to_le16(x) (x) -#define osi_cpu_to_le32(x) (x) -#define osi_cpu_to_le64(x) (x) - -#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ - - -#endif /* __OSI_ENDIAN_DOT_H__ */ diff --git a/iddev/lib/Makefile b/iddev/lib/Makefile deleted file mode 100644 index e17ea61..0000000 --- a/iddev/lib/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -INCLUDE= -I${top_srcdir}/include -TARGET=libiddev.a -CFLAGS= ${INCLUDE} -Wall -O2 -D_FILE_OFFSET_BITS=64 -DHELPER_PROGRAM - -all: ${TARGET} - -libiddev.o: iddev.o size.o iddev.h - ${LD} -o $@ -r ${LDFLAGS} iddev.o size.o ${LOADLIBES} ${LDLIBS} --retain-symbols-file=exported_symbols.sym - -libiddev.a: libiddev.o - ${AR} cr $@ libiddev.o - -identify_device: libiddev.a identify_device.o - ${CC} -o $@ identify_device.o libiddev.a - -copytobin: all - -clean: - rm -f *.o *.po *.a *~ ${TARGET} identify_device - -install: libiddev.a iddev.h - install -d ${libdir} - install -m644 libiddev.a ${libdir} - install -d ${incdir} - install -m644 iddev.h ${incdir} - -uninstall: - ${UNINSTALL} iddev.h ${incdir} - ${UNINSTALL} libiddev.a ${libdir} diff --git a/iddev/lib/exported_symbols.sym b/iddev/lib/exported_symbols.sym deleted file mode 100644 index e7df9db..0000000 --- a/iddev/lib/exported_symbols.sym +++ /dev/null @@ -1,2 +0,0 @@ -identify_device -device_size diff --git a/iddev/lib/iddev.c b/iddev/lib/iddev.c deleted file mode 100644 index fa4eca9..0000000 --- a/iddev/lib/iddev.c +++ /dev/null @@ -1,522 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - -#include "global.h" -#include "osi_endian.h" - -#include "iddev.h" - - - - - -/** - * check_for_gfs - check to see if GFS is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * An EINVAL returned from lseek means that the device was too - * small -- at least on Linux. - * - * Returns: -1 on error (with errno set), 1 if not GFS, - * 0 if GFS found (with type set) - */ - -static int check_for_gfs(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - uint32 *p = (uint32 *)buf; - int error; - - error = lseek(fd, 65536, SEEK_SET); - if (error < 0) - return (errno == EINVAL) ? 1 : error; - else if (error != 65536) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 8) - return 1; - - if (osi_be32_to_cpu(*p) != 0x01161970 || osi_be32_to_cpu(*(p + 1)) != 1) - return 1; - - snprintf(type, type_len, "GFS filesystem"); - - return 0; -} - - -/** - * check_for_pool - check to see if Pool is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not Pool, - * 0 if Pool found (with type set) - */ - -static int check_for_pool(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - uint64 *p = (uint64 *)buf; - int error; - - error = lseek(fd, 0, SEEK_SET); - if (error < 0) - return error; - else if (error != 0) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 8) - return 1; - - if (osi_be64_to_cpu(*p) != 0x11670) - return 1; - - snprintf(type, type_len, "Pool subdevice"); - - return 0; -} - - -/** - * check_for_paritition - check to see if Partition is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not Partition, - * 0 if Partition found (with type set) - */ - -static int check_for_partition(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - int error; - - error = lseek(fd, 0, SEEK_SET); - if (error < 0) - return error; - else if (error != 0) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 512) - return 1; - - if (buf[510] != 0x55 || buf[511] != 0xAA) - return 1; - - snprintf(type, type_len, "partition information"); - - return 0; -} - - -/** - * check_for_ext23 - check to see if EXT23 is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * An EINVAL returned from lseek means that the device was too - * small -- at least on Linux. - * - * Returns: -1 on error (with errno set), 1 if not EXT23, - * 0 if EXT23 found (with type set) - */ - -static int check_for_ext23(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - uint16 *p = (uint16 *)buf; - int error; - - error = lseek(fd, 1024, SEEK_SET); - if (error < 0) - return (errno == EINVAL) ? 1 : error; - else if (error != 1024) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 58) - return 1; - - if (osi_le16_to_cpu(p[28]) != 0xEF53) - return 1; - - snprintf(type, type_len, "EXT2/3 filesystem"); - - return 0; -} - - -/** - * check_for_swap - check to see if SWAP is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not SWAP, - * 0 if SWAP found (with type set) - */ - -static int check_for_swap(int fd, char *type, unsigned type_len) -{ - unsigned char buf[8192]; - int error; - - error = lseek(fd, 0, SEEK_SET); - if (error < 0) - return error; - else if (error != 0) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 8192); - if (error < 0) - return error; - else if (error < 4096) - return 1; - - if (memcmp(buf + 4086, "SWAP-SPACE", 10) && memcmp(buf + 4086, "SWAPSPACE2", 10)) - return 1; - - snprintf(type, type_len, "swap device"); - - return 0; -} - - -/** - * check_for_lvm1 - check to see if LVM1 is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not LVM1, - * 0 if LVM1 found (with type set) - */ - -static int check_for_lvm1(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - int error; - - error = lseek(fd, 0, SEEK_SET); - if (error < 0) - return error; - else if (error != 0) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 2) - return 1; - - if (buf[0] != 'H' || buf[1] != 'M') - return 1; - - snprintf(type, type_len, "lvm1 subdevice"); - - return 0; -} - - -/** - * check_for_lvm2 - check to see if LVM2 is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not LVM2, - * 0 if LVM1 found (with type set) - */ - -static int check_for_lvm2(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - int error; - int i; - - /* LVM 2 labels can start in sectors 1-4 */ - - for (i = 1; i < 5; i++) - { - error = lseek(fd, 512 * i, SEEK_SET); - if (error < 0) - return (errno == EINVAL) ? 1 : error; - else if (error != 512 * i) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 32) - return 1; - - if (strncmp(buf, "LABELONE", 8) != 0) - continue; - if (((uint64_t *)buf)[1] != i) - continue; - /* FIXME: should check the CRC of the label here */ - if (strncmp(&buf[24], "LVM2 001", 8) != 0) - continue; - - snprintf(type, type_len, "lvm2 subdevice"); - - return 0; - } - - return 1; -} - - -/** - * check_for_cidev - check to see if CIDEV is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not CIDEV, - * 0 if CIDEV found (with type set) - */ - -static int check_for_cidev(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - uint32 *p = (uint32 *)buf; - int error; - - error = lseek(fd, 0, SEEK_SET); - if (error < 0) - return error; - else if (error != 0) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 4) - return 1; - - if (osi_be32_to_cpu(*p) != 0x47465341) - return 1; - - snprintf(type, type_len, "CIDEV"); - - return 0; -} - - -/** - * check_for_cca - check to see if CCA is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not CCA, - * 0 if CCA found (with type set) - */ - -static int check_for_cca(int fd, char *type, unsigned type_len) -{ - unsigned char buf[512]; - uint32 *p = (uint32 *)buf; - int error; - - error = lseek(fd, 0, SEEK_SET); - if (error < 0) - return error; - else if (error != 0) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 4) - return 1; - - if (osi_be32_to_cpu(*p) != 0x122473) - return 1; - - snprintf(type, type_len, "CCA device"); - - return 0; -} - - -/** - * check_for_reiserfs - check to see if reisterfs is on this device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * Returns: -1 on error (with errno set), 1 if not reiserfs, - * 0 if CCA found (with type set) - */ - -static int check_for_reiserfs(int fd, char *type, unsigned type_len) -{ - unsigned int pass; - uint64 offset; - unsigned char buf[512]; - int error; - - for (pass = 0; pass < 2; pass++) - { - offset = (pass) ? 65536 : 8192; - - error = lseek(fd, offset, SEEK_SET); - if (error < 0) - return (errno == EINVAL) ? 1 : error; - else if (error != offset) - { - errno = EINVAL; - return -1; - } - - error = read(fd, buf, 512); - if (error < 0) - return error; - else if (error < 62) - return 1; - - if (strncmp(buf + 52, "ReIsErFs", 8) == 0 || - strncmp(buf + 52, "ReIsEr2Fs", 9) == 0 || - strncmp(buf + 52, "ReIsEr3Fs", 9) == 0) - { - snprintf(type, type_len, "Reiserfs filesystem"); - return 0; - } - } - - return 1; -} - - -/** - * identify_device - figure out what's on a device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * The offset of @fd will be changed by this function. - * This routine will not write to the device. - * - * Returns: -1 on error (with errno set), 1 if unabled to identify, - * 0 if device identified (with type set) - */ - -int identify_device(int fd, char *type, unsigned type_len) -{ - int error; - - if (!type || !type_len) - { - errno = EINVAL; - return -1; - } - - error = check_for_pool(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_lvm1(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_lvm2(fd, type, type_len); - if(error <= 0) - return error; - - error = check_for_cidev(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_cca(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_gfs(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_ext23(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_reiserfs(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_swap(fd, type, type_len); - if (error <= 0) - return error; - - error = check_for_partition(fd, type, type_len); - if (error <= 0) - return error; - - return 1; -} - - diff --git a/iddev/lib/iddev.h b/iddev/lib/iddev.h deleted file mode 100644 index 8bc59f9..0000000 --- a/iddev/lib/iddev.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#ifndef __IDDEV_DOT_H__ -#define __IDDEV_DOT_H__ - - -/** - * indentify_device - figure out what's on a device - * @fd: a file descriptor open on a device open for (at least) reading - * @type: a buffer that contains the type of filesystem - * @type_len: the amount of space pointed to by @type - * - * The offset of @fd will be changed by the function. - * This routine will not write to this device. - * - * Returns: -1 on error (with errno set), 1 if unabled to identify, - * 0 if device identified (with @type set) - */ - -int identify_device(int fd, char *type, unsigned type_len); - - -/** - * device_size - figure out a device's size - * @fd: the file descriptor of a device - * @bytes: the number of bytes the device holds - * - * Returns: -1 on error (with errno set), 0 on success (with @bytes set) - */ - -int device_size(int fd, uint64 *bytes); - - -#endif /* __IDDEV_DOT_H__ */ - diff --git a/iddev/lib/identify_device.c b/iddev/lib/identify_device.c deleted file mode 100644 index 74318fc..0000000 --- a/iddev/lib/identify_device.c +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - -#include "global.h" - -#include "iddev.h" - - - -#define die(fmt, args...) \ -do \ -{ \ - fprintf(stderr, "%s: ", prog_name); \ - fprintf(stderr, fmt, ##args); \ - exit(EXIT_FAILURE); \ -} \ -while (0) - - - -#define BUFSIZE (1024) - - - -char *prog_name; - - - - - -int main(int argc, char *argv[]) -{ - int fd; - char buf[BUFSIZE]; - uint64 bytes; - int error; - - prog_name = argv[0]; - - if (argc != 2) - die("Usage: %s devicename\n", prog_name); - - fd = open(argv[1], O_RDONLY); - if (fd < 0) - die("can't open %s: %s\n", argv[1], strerror(errno)); - - error = identify_device(fd, buf, BUFSIZE); - if (error < 0) - die("error identifying the contents of %s: %s\n", argv[1], strerror(errno)); - else if (error) - strcpy(buf, "unknown"); - - error = device_size(fd, &bytes); - if (error < 0) - die("error determining the size of %s: %s\n", argv[1], strerror(errno)); - - printf("%s:\n%-15s%s\n%-15s%"PRIu64"\n", - argv[1], " contents:", buf, " bytes:", bytes); - - close(fd); - - exit(EXIT_SUCCESS); -} - diff --git a/iddev/lib/size.c b/iddev/lib/size.c deleted file mode 100644 index e7f1692..0000000 --- a/iddev/lib/size.c +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** -******************************************************************************* -** -** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004 Red Hat, Inc. All rights reserved. -** -** This copyrighted material is made available to anyone wishing to use, -** modify, copy, or redistribute it subject to the terms and conditions -** of the GNU General Public License v.2. -** -******************************************************************************* -******************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/mount.h> - -#include "global.h" -#include "iddev.h" - -#ifndef BLKGETSIZE64 -#define BLKGETSIZE64 _IOR(0x12, 114, size_t) -#endif - - - - - -/** - * do_device_size - determine the size of a Linux block device - * @device: the path to the device node - * - * Returns: the size of the device in bytes - */ - -static int do_device_size(int fd, uint64 *bytes) -{ - unsigned long size; - off_t off; - int error; - - error = ioctl(fd, BLKGETSIZE64, bytes); /* Size in bytes */ - if (!error) - return 0; - - error = ioctl(fd, BLKGETSIZE, &size); /* Size in 512-byte blocks */ - if (!error) - { - *bytes = ((uint64)size) << 9; - return 0; - } - - off = lseek(fd, 0, SEEK_END); - if (off >= 0) { - *bytes = off; - return 0; - } - - return -1; -} - - -/** - * device_size - figure out a device's size - * @fd: the file descriptor of a device - * @bytes: the number of bytes the device holds - * - * Returns: -1 on error (with errno set), 0 on success (with @bytes set) - */ - -int device_size(int fd, uint64 *bytes) -{ - struct stat st; - int error; - - error = fstat(fd, &st); - if (error) - return error; - - if (S_ISREG(st.st_mode)) { - *bytes = st.st_size; - return 0; - } - else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) - return do_device_size(fd, bytes); - else if (S_ISDIR(st.st_mode)) - errno = EISDIR; - else - errno = EINVAL; - - return -1; -} - - - - diff --git a/iddev/make/defines.mk.input b/iddev/make/defines.mk.input deleted file mode 100644 index 289f33f..0000000 --- a/iddev/make/defines.mk.input +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/iddev/make/release.mk.input b/iddev/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/iddev/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/iddev/scripts/uninstall.pl b/iddev/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/iddev/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/magma-plugins/Makefile b/magma-plugins/Makefile deleted file mode 100644 index 22711aa..0000000 --- a/magma-plugins/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -all: - cd cman && ${MAKE} all - cd dumb && ${MAKE} all - cd gulm && ${MAKE} all - cd sm && ${MAKE} all - -clean: - cd cman && ${MAKE} clean - cd dumb && ${MAKE} clean - cd gulm && ${MAKE} clean - cd sm && ${MAKE} clean - -install: - cd cman && ${MAKE} install - cd dumb && ${MAKE} install - cd gulm && ${MAKE} install - cd sm && ${MAKE} install - -uninstall: - cd cman && ${MAKE} uninstall - cd dumb && ${MAKE} uninstall - cd gulm && ${MAKE} uninstall - cd sm && ${MAKE} uninstall - rm -rf /lib/magma - -distclean: clean - rm -f make/defines.mk diff --git a/magma-plugins/cman/Makefile b/magma-plugins/cman/Makefile deleted file mode 100644 index 1096497..0000000 --- a/magma-plugins/cman/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -INCLUDES+= -I. -I${incdir} -LIBS += -L${libdir} -ldlm_lt -CFLAGS += -D_CLUSTER_ -OBJS = cman.o -TARGETS = magma_cman.so - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDES += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -INCLUDES += -I${incdir}/cluster -endif - -all: $(TARGETS) - -install: all - # Use the SM plugin for now; don't install CMAN - #install -d ${libdir}/magma - #install -m 0755 $(TARGETS) ${libdir}/magma - -uninstall: - ${UNINSTALL} ${TARGETS} ${libdir}/magma - -magma_cman.so: buildtest $(OBJS) - $(CC) -o $@ $(OBJS) -shared $(CFLAGS) $(LIBS) - -buildtest: $(OBJS) - echo "int main(void) { return 0; }" > _buildtest.c - $(CC) -c _buildtest.c - $(CC) -o $@ _buildtest.o $(OBJS) $(LIBS) - rm -f _buildtest* - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDES) -fPIC $(CFLAGS) - -clean: - rm -f *o *~ *.so buildtest - diff --git a/magma-plugins/cman/cman-plugin.h b/magma-plugins/cman/cman-plugin.h deleted file mode 100644 index d7fb38e..0000000 --- a/magma-plugins/cman/cman-plugin.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _CMAN_PLUGIN_H -#define _CMAN_PLUGIN_H - -typedef struct { - int sockfd; - int quorum_state; - int memb_count; - uint64_t memb_sum; - dlm_lshandle_t ls; -} cman_priv_t; - -#endif /* _CMAN_PLUGIN_H */ diff --git a/magma-plugins/cman/cman.c b/magma-plugins/cman/cman.c deleted file mode 100644 index 44fadba..0000000 --- a/magma-plugins/cman/cman.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * CMAN/DLM Driver - Uses locking to synchronize recovery. - */ -#include <stdint.h> -#include <magma.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/socket.h> -#include <assert.h> -#include <sys/ioctl.h> -#include <cnxman-socket.h> -#include <libdlm.h> -#include "cman-plugin.h" - -#define MODULE_DESCRIPTION "CMAN/DLM Plugin v1.1" -#define MODULE_AUTHOR "Lon Hohberger" - -#define DLM_LS_NAME "Magma" - -static int cman_lock(cluster_plugin_t *self, char *resource, int flags, - void **lockpp); -static int cman_unlock(cluster_plugin_t * __attribute__ ((unused)) self, - char *__attribute__((unused)) resource, void *lockp); -/* - * Grab the version from the header file so we don't cause API problems - */ -IMPORT_PLUGIN_API_VERSION(); - - -static int -cman_null(cluster_plugin_t *self) -{ - //printf("CMAN: %s called\n", __FUNCTION__); - printf(MODULE_DESCRIPTION " NULL function called\n"); - return 0; -} - - -static cluster_member_list_t * -cman_member_list(cluster_plugin_t *self, - char __attribute__ ((unused)) *groupname) -{ - cluster_member_list_t *foo = NULL; - struct cl_cluster_nodelist cman_nl = { 0, NULL }; - cman_priv_t *p; - int x; - size_t sz; - - //printf("CMAN: %s called\n", __FUNCTION__); - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - assert(p->sockfd >= 0); - - do { - /* Clean up if necessary */ - if (cman_nl.nodes) - free(cman_nl.nodes); - if (foo) - /* Don't need to cml_free - we know we didn't - resolve anything */ - free(foo); - - x = ioctl(p->sockfd, SIOCCLUSTER_GETMEMBERS, NULL); - if (x <= 0) - return NULL; - - cman_nl.max_members = x; - - /* BIG malloc here */ - sz = sizeof(struct cl_cluster_node) * cman_nl.max_members; - cman_nl.nodes = malloc(sz); - assert(cman_nl.nodes != NULL); - - /* Another biggie */ - foo = cml_alloc(cman_nl.max_members); - assert(foo != NULL); - - } while (ioctl(p->sockfd, SIOCCLUSTER_GETMEMBERS, &cman_nl) != - cman_nl.max_members); - - /* Store count in our internal structure */ - p->memb_count = cman_nl.max_members; - - /* Recalc. member checksum */ - p->memb_sum = 0; - foo->cml_count = p->memb_count; - for (x = 0; x < p->memb_count; x++) { - - /* Copy the data to the lower layer */ - foo->cml_members[x].cm_addrs = NULL; - foo->cml_members[x].cm_id = (uint64_t)cman_nl.nodes[x].node_id; - p->memb_sum += foo->cml_members[x].cm_id; - - switch(cman_nl.nodes[x].state) { - case NODESTATE_MEMBER: - foo->cml_members[x].cm_state = STATE_UP; - break; - case NODESTATE_JOINING: - case NODESTATE_DEAD: - foo->cml_members[x].cm_state = STATE_DOWN; - break; - default: - foo->cml_members[x].cm_state = STATE_INVALID; - break; - } - - strncpy(foo->cml_members[x].cm_name, cman_nl.nodes[x].name, - sizeof(foo->cml_members[x].cm_name)); - } - - free(cman_nl.nodes); - - return foo; -} - - -static int -cman_quorum_status(cluster_plugin_t *self, char *groupname) -{ - int qs; - cman_priv_t *p; - - //printf("CMAN: %s called\n", __FUNCTION__); - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - assert(p->sockfd >= 0); - - qs = ioctl(p->sockfd, SIOCCLUSTER_ISQUORATE, NULL); - - switch(qs) { - case 0: - default: - p->quorum_state = 0; - break; - case 1: - p->quorum_state = QF_QUORATE | (groupname?QF_GROUPMEMBER:0); - break; - } - - return p->quorum_state; -} - - -static char * -cman_version(cluster_plugin_t *self) -{ - //printf("CMAN: %s called\n", __FUNCTION__); - return MODULE_DESCRIPTION; -} - - -static int -cman_open(cluster_plugin_t *self) -{ - cman_priv_t *p; - - //printf("CMAN: %s called\n", __FUNCTION__); - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - - if (p->sockfd >= 0) - close(p->sockfd); - - p->sockfd = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (p->sockfd >= 0) - cman_quorum_status(self, NULL); - - return p->sockfd; -} - - -static int -cman_close(cluster_plugin_t *self, int fd) -{ - int ret; - cman_priv_t *p; - - //printf("CMAN: %s called\n", __FUNCTION__); - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - assert(fd == p->sockfd); - - if (p->ls) - dlm_release_lockspace(DLM_LS_NAME, p->ls, 0); - p->ls = NULL; - - ret = close(fd); - p->sockfd = -1; - - return ret; -} - - -static int -cman_fence(cluster_plugin_t *self, cluster_member_t *node) -{ - int nodeid; - cman_priv_t *p; - - //printf("CMAN: %s called\n", __FUNCTION__); - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - - nodeid = (int)node->cm_id; - - return ioctl(p->sockfd, SIOCCLUSTER_KILLNODE, nodeid); -} - - -static int -cman_get_event(cluster_plugin_t *self, int fd) -{ - cluster_member_list_t *tmp; - char lockname[64]; - void *lockp = NULL; - cman_priv_t *p; - int old, new; - uint64_t oldsum; - struct cl_portclosed_oob msg; - - new = recv(fd, &msg, sizeof(msg), MSG_OOB); - - /* Socket closed. */ - if (new == 0) - return CE_SHUTDOWN; - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - assert(fd == p->sockfd); - - /* - * Check for Quorum transition. - */ - old = p->quorum_state; - new = cman_quorum_status(self, NULL); - - if (is_quorate(new) != is_quorate(old)) - return (is_quorate(new) ? CE_QUORATE : CE_INQUORATE); - - /* - * No quorum transition? Check for a membership transition. - */ - oldsum = p->memb_sum; - old = p->memb_count; - tmp = cman_member_list(self, NULL); - - /* If the count has changed or the sum has changed but not the count, - then we've got a membership transition. */ - if (tmp && ((old != p->memb_count) || (oldsum != p->memb_sum))) { - - free(tmp); - snprintf(lockname, sizeof(lockname), "magma::lock%d\n", - getpid()); - - /* - * Take a DLM lock and release it so that we know fencing - * is complete. The GDLM recovery happens after fencing; - * locks requests will block until the GDLM has recovered. - */ - while (cman_lock(self, lockname, CLK_EX, &lockp) != 0) - usleep(100000); - if (cman_unlock(self, lockname, lockp) != 0) - return CE_NULL; - - return CE_MEMB_CHANGE; - } - - return CE_NULL; -} - - -static void -ast_function(void * __attribute__ ((unused)) arg) -{ -} - - -static int -wait_for_dlm_event(dlm_lshandle_t *ls) -{ - fd_set rfds; - int fd = dlm_ls_get_fd(ls); - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - if (select(fd + 1, &rfds, NULL, NULL, NULL) == 1) - return dlm_dispatch(fd); - - return -1; -} - - -static int -cman_lock(cluster_plugin_t *self, - char *resource, - int flags, - void **lockpp) -{ - cman_priv_t *p; - int mode = 0, options = 0, ret = 0; - struct dlm_lksb *lksb; - - if (!self || !lockpp) { - errno = EINVAL; - return -1; - } - - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - - /* - * per pjc: create/open lockspace when first lock is taken - */ - if (!p->ls) - p->ls = dlm_open_lockspace(DLM_LS_NAME); - if (!p->ls) - p->ls = dlm_create_lockspace(DLM_LS_NAME, 0644); - if (!p->ls) { - ret = errno; - close(p->sockfd); - errno = ret; - return -1; - } - - if (flags & CLK_EX) { - mode = LKM_EXMODE; - } else if (flags & CLK_READ) { - mode = LKM_PRMODE; - } else if (flags & CLK_WRITE) { - mode = LKM_PWMODE; - } else { - errno = EINVAL; - return -1; - } - - if (flags & CLK_NOWAIT) - options = LKF_NOQUEUE; - - /* Allocate our lock structure. */ - lksb = malloc(sizeof(*lksb)); - assert(lksb); - memset(lksb, 0, sizeof(*lksb)); - - ret = dlm_ls_lock(p->ls, mode, lksb, options, resource, - strlen(resource), 0, ast_function, lksb, NULL, - NULL); - if (ret != 0) { - free(lksb); - return ret; - } - - if (wait_for_dlm_event(p->ls) < 0) { - free(lksb); - return -1; - } - - switch(lksb->sb_status) { - case 0: - *lockpp = (void *)lksb; - return 0; - case EAGAIN: - free(lksb); - errno = EAGAIN; - return -1; - default: - ret = lksb->sb_status; - free(lksb); - errno = ret; - return -1; - } - - /* Not reached */ - return -1; -} - - - -static int -cman_unlock(cluster_plugin_t *self, char *__attribute__((unused)) resource, - void *lockp) -{ - cman_priv_t *p; - dlm_lshandle_t ls; - struct dlm_lksb *lksb = (struct dlm_lksb *)lockp; - int ret; - - assert(self); - p = (cman_priv_t *)self->cp_private.p_data; - assert(p); - ls = p->ls; - assert(ls); - - if (!lockp) { - errno = EINVAL; - return -1; - } - - ret = dlm_ls_unlock(ls, lksb->sb_lkid, 0, lksb, NULL); - - if (ret != 0) - return ret; - - /* lksb->sb_status should be EINPROG at this point */ - - if (wait_for_dlm_event(p->ls) < 0) { - errno = lksb->sb_status; - return -1; - } - - free(lksb); - - return ret; -} - - -int -cluster_plugin_load(cluster_plugin_t *driver) -{ - //printf("CMAN: %s called\n", __FUNCTION__); - - if (!driver) { - errno = EINVAL; - return -1; - } - - driver->cp_ops.s_null = cman_null; - driver->cp_ops.s_member_list = cman_member_list; - driver->cp_ops.s_quorum_status = cman_quorum_status; - driver->cp_ops.s_plugin_version = cman_version; - driver->cp_ops.s_get_event = cman_get_event; - driver->cp_ops.s_open = cman_open; - driver->cp_ops.s_close = cman_close; - driver->cp_ops.s_fence = cman_fence; - driver->cp_ops.s_lock = cman_lock; - driver->cp_ops.s_unlock = cman_unlock; - - return 0; -} - - -int -cluster_plugin_init(cluster_plugin_t *driver, void *priv, - size_t privlen) -{ - cman_priv_t *p = NULL; - //printf("CMAN: %s called\n", __FUNCTION__); - - if (!driver) { - errno = EINVAL; - return -1; - } - - if (!priv) { - p = malloc(sizeof(*p)); - assert(p); - } else { - assert(privlen >= sizeof(*p)); - - p = malloc(sizeof(*p)); - assert(p); - memcpy(p, priv, sizeof(*p)); - } - - p->sockfd = -1; - p->quorum_state = 0; - p->memb_count = 0; - - driver->cp_private.p_data = (void *)p; - driver->cp_private.p_datalen = sizeof(*p); - - return 0; -} - - -/* - * Clear out the private data, if it exists. - */ -int -cluster_plugin_unload(cluster_plugin_t *driver) -{ - cman_priv_t *p = NULL; - - //printf("CMAN: %s called\n", __FUNCTION__); - - if (!driver) { - errno = EINVAL; - return -1; - } - - assert(driver); - p = (cman_priv_t *)driver->cp_private.p_data; - assert(p); - - /* You did log out, right? */ - assert(p->sockfd == -1); - free(p); - driver->cp_private.p_data = NULL; - driver->cp_private.p_datalen = 0; - - return 0; -} diff --git a/magma-plugins/configure b/magma-plugins/configure deleted file mode 100755 index 1eeb076..0000000 --- a/magma-plugins/configure +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - slibdir => $slibdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - plugindir => $plugindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'slibdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'plugindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--slibdir=\tthe base directory for static libraries. (Default: /usr/lib\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--plugindir=\tthe directory to search for plugins. (Default: {libdir}/magma\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$slibdir) { - $slibdir="${libdir}"; -} -if (!$plugindir) { - $plugindir="${libdir}/magma"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@SLIBDIR@/$slibdir/; - $_ =~ s/@PLUGINDIR@/$plugindir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/magma-plugins/doc/COPYING b/magma-plugins/doc/COPYING deleted file mode 100644 index ebaa528..0000000 --- a/magma-plugins/doc/COPYING +++ /dev/null @@ -1,851 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. -
- Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. -
- GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. -
- 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. -
- Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. -
- 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. -
- 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. -
- 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. -
- 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - ----------------------------------------------------------------------- -
-http://www.fsf.org/copyleft/gpl.txt - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. -
- GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) -
-These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. -
- 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -
- 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - ----------------------------------------------------------------------- diff --git a/magma-plugins/dumb/Makefile b/magma-plugins/dumb/Makefile deleted file mode 100644 index 47b4f2c..0000000 --- a/magma-plugins/dumb/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk - -INCLUDES+= -I. -I${incdir} -LIBS = -L${libdir} -CFLAGS += -D_CLUSTER_ -OBJS = dumb.o -TARGETS = magma_dumb.so - -all: $(TARGETS) - -install: all - - -uninstall: - -magma_dumb.so: buildtest $(OBJS) - $(CC) -o $@ $(OBJS) -shared $(CFLAGS) $(LIBS) - -buildtest: $(OBJS) - echo "int main(void) { return 0; }" > _buildtest.c - $(CC) -c _buildtest.c - $(CC) -o $@ _buildtest.o $(OBJS) $(LIBS) - rm -f _buildtest* - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDES) -fPIC $(CFLAGS) - -clean: - rm -f *o *~ *.so buildtest - diff --git a/magma-plugins/dumb/dumb.c b/magma-plugins/dumb/dumb.c deleted file mode 100644 index 7fef795..0000000 --- a/magma-plugins/dumb/dumb.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Dumb test "Driver" - * - * Well, it's really not very dumb anymore. This provides a single - * machine access to the magma APIs without configuring other cluster - * infrastructures. - */ -#include <magma.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/fcntl.h> -#include <netinet/in.h> -#include <assert.h> - -#define MODULE_DESCRIPTION "Dumb Plugin v1.1.1" -#define MODULE_AUTHOR "Lon Hohberger" -#define DUMB_LOCK_PATH "/tmp/magma-dumb" - -/* - * Grab the version from the header file so we don't cause API problems - */ -IMPORT_PLUGIN_API_VERSION(); - - -static int -dumb_null(cluster_plugin_t * __attribute__ ((unused)) self) -{ - printf("DUMB: %s called\n", __FUNCTION__); - printf(MODULE_DESCRIPTION " NULL function called\n"); - return 0; -} - - -static cluster_member_list_t * -dumb_member_list(cluster_plugin_t * __attribute__ ((unused)) self, - char __attribute__ ((unused)) *groupname) -{ - cluster_member_list_t *foo; - - //printf("DUMB: %s called\n", __FUNCTION__); - foo = malloc(sizeof(cluster_member_list_t) + - sizeof(cluster_member_t)); - memset(foo, 0, sizeof(cluster_member_list_t) + sizeof(cluster_member_t)); - - /* Store our info. We're up, node ID 0. */ - foo->cml_count = 1; - - /* XXX should check for errors. */ - gethostname(foo->cml_members[0].cm_name, - sizeof(foo->cml_members[0].cm_name)); - foo->cml_members[0].cm_state = STATE_UP; - foo->cml_members[0].cm_id = (uint64_t)0; - return foo; -} - - -static int -dumb_quorum_status(cluster_plugin_t * __attribute__ ((unused)) self, - char __attribute__ ((unused)) *groupname) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - - /* Make believe there's a group and we're a member */ - return QF_QUORATE | QF_GROUPMEMBER; -} - - -static char * -dumb_version(cluster_plugin_t * __attribute__ ((unused)) self) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - return MODULE_DESCRIPTION; -} - - -static int -dumb_open(cluster_plugin_t * __attribute__ ((unused)) self) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - - /* Make believe there's a real need for this fd */ - return socket(AF_INET, SOCK_DGRAM, 0); -} - - -static int -dumb_login(cluster_plugin_t * __attribute__ ((unused)) self, - int __attribute__ ((unused)) fd, - char __attribute__ ((unused)) *groupname) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - - /* Make believe there's a group */ - return 0; -} - - -static int -dumb_logout(cluster_plugin_t * __attribute__ ((unused)) self, - int __attribute__((unused)) fd) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - - /* Make believe there's a group */ - return 0; -} - - -static int -dumb_close(cluster_plugin_t * __attribute__ ((unused)) self, int fd) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - return close(fd); -} - - -static int -dumb_fence(cluster_plugin_t __attribute__ ((unused)) *self, - cluster_member_t __attribute__((unused)) *node) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - errno = ENOSYS; - return -1; -} - - -static int -dumb_lock(cluster_plugin_t * __attribute__ ((unused)) self, - char *resource, int flags, void **lockpp) -{ - struct flock fl; - int *fdp; - int esv; - char pathname[1024]; - - //printf("DUMB: %s called\n", __FUNCTION__); - - if ((flags & CLK_EX) == 0) { - /* NULL lock not supported */ - errno = EINVAL; - return -1; - } - - fdp = malloc(sizeof(int)); - if (!fdp) - return -1; - - /* - * File system based locks using fcntl. - */ - snprintf(pathname, sizeof(pathname), "%s/%s", - DUMB_LOCK_PATH, resource); - - *fdp = open(pathname, O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR|S_IWUSR); - if (*fdp == -1) { - esv = errno; - free(fdp); - errno = esv; - return -1; - } - - memset(&fl, 0, sizeof(fl)); - fl.l_type = (flags & CLK_WRITE) ? F_WRLCK : F_RDLCK; - - if (fcntl(*fdp, (flags & CLK_NOWAIT) ? F_SETLKW : F_SETLK, &fl) == -1){ - esv = errno; - free(fdp); - errno = esv; - return -1; - } - - *lockpp = (void *)fdp; - return 0; -} - - -static int -dumb_unlock(cluster_plugin_t * __attribute__ ((unused)) self, - char *resource, void *lockp) -{ - char pathname[1024]; - //printf("DUMB: %s called\n", __FUNCTION__); - - assert(resource); - assert(lockp); - assert(*((int *)lockp) >= 0); - - snprintf(pathname, sizeof(pathname), "%s/%s", - DUMB_LOCK_PATH, resource); - - close(*((int *)lockp)); - free(lockp); - unlink(pathname); - return 0; -} - - -static int -dumb_get_event(cluster_plugin_t * __attribute__ ((unused)) self, - int __attribute__((unused)) fd) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - - /* Never a real event */ - return CE_NULL; -} - - -int -cluster_plugin_load(cluster_plugin_t *driver) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - - if (!driver) { - errno = EINVAL; - return -1; - } - - driver->cp_ops.s_null = dumb_null; - driver->cp_ops.s_member_list = dumb_member_list; - driver->cp_ops.s_quorum_status = dumb_quorum_status; - driver->cp_ops.s_plugin_version = dumb_version; - driver->cp_ops.s_get_event = dumb_get_event; - driver->cp_ops.s_open = dumb_open; - driver->cp_ops.s_close = dumb_close; - driver->cp_ops.s_fence = dumb_fence; - driver->cp_ops.s_login = dumb_login; - driver->cp_ops.s_logout = dumb_logout; - driver->cp_ops.s_lock = dumb_lock; - driver->cp_ops.s_unlock = dumb_unlock; - - return 0; -} - - -int -cluster_plugin_init(cluster_plugin_t *driver, - void *__attribute__((unused)) priv, - size_t __attribute__((unused)) privlen) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - if (!driver) { - errno = EINVAL; - return -1; - } - - //printf("DUMB: Plugin API version: %f\n", cluster_plugin_version()); - if (mkdir(DUMB_LOCK_PATH, 0700)) { - if (errno == EEXIST) { - if (chmod(DUMB_LOCK_PATH, 0700)) - return -1; - return 0; - } - return -1; - } - - return 0; -} - - -/* - * Clear out the private data, if it exists. - */ -int -cluster_plugin_unload(cluster_plugin_t *driver) -{ - //printf("DUMB: %s called\n", __FUNCTION__); - if (driver->cp_private.p_data) - free(driver->cp_private.p_data); - - return 0; -} diff --git a/magma-plugins/gulm/Makefile b/magma-plugins/gulm/Makefile deleted file mode 100644 index cc308c9..0000000 --- a/magma-plugins/gulm/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -INCLUDES+= -I. -I${incdir} -LIBS += -L${libdir} -lgulm -CFLAGS += -D_CLUSTER_ -D_REENTRANT -ggdb -OBJS = gulm.o gulm-lock.o -TARGETS = magma_gulm.so - -all: $(TARGETS) - -install: all - mkdir -p ${plugindir} - install -m 0755 $(TARGETS) ${plugindir} - -uninstall: - ${UNINSTALL} ${TARGETS} ${plugindir} - -magma_gulm.so: buildtest $(OBJS) - $(CC) -o $@ $(OBJS) -shared $(CFLAGS) $(LIBS) - -buildtest: $(OBJS) - echo "int main(void) { return 0; }" > _buildtest.c - $(CC) -c _buildtest.c - $(CC) -o $@ _buildtest.o $(OBJS) $(LIBS) - rm -f _buildtest* - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDES) -fPIC $(CFLAGS) - -clean: - rm -f *o *~ *.so buildtest - diff --git a/magma-plugins/gulm/gulm-lock.c b/magma-plugins/gulm/gulm-lock.c deleted file mode 100644 index 5bc5a92..0000000 --- a/magma-plugins/gulm/gulm-lock.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * GuLM lock/unlock functions - */ -#include <magma.h> -#include <netinet/in.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <libgulm.h> -#include <assert.h> -#include <signal.h> -#include <fcntl.h> -#include "gulm-plugin.h" - -#define GULM_USRM_LVB "usrm::gulm" -#define GULM_USRM_LVB_LEN 10 - - -/** - * GuLM lock no-ops protos - */ -static int null_lk_login_reply(void *misc, uint32_t error, uint8_t which); -static int null_lk_logout_reply(void *misc); -static int null_lk_lock_state(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, uint32_t flags, uint32_t error, - uint8_t *LVB, uint16_t LVBlen); -static int null_lk_lock_action(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t action, uint32_t error); -static int null_lk_drop_lock_req(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t state); -static int null_lk_drop_all(void *misc); -static int null_lk_error(void *misc, uint32_t err); - - -static lg_lockspace_callbacks_t lock_callbacks_initializer = { - null_lk_login_reply, - null_lk_logout_reply, - null_lk_lock_state, - null_lk_lock_action, - null_lk_drop_lock_req, - null_lk_drop_all, - null_lk_error -}; - - -/** - * GuLM lock reply-no-ops - */ -static int -null_lk_login_reply(void *misc, uint32_t error, uint8_t which) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -static int -null_lk_logout_reply(void *misc) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -static int -null_lk_lock_state(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, uint8_t state, - uint32_t flags, uint32_t error, uint8_t *LVB, - uint16_t LVBlen) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -static int -null_lk_lock_action(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t action, uint32_t error) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -static int -null_lk_drop_lock_req(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint8_t state) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -static int -null_lk_drop_all(void *misc) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -static int -null_lk_error(void *misc, uint32_t err) -{ - /*printf("GuLM Lock: %s called\n", __FUNCTION__);*/ - return 0; -} - - -/** - * GuLM lock Login/logout functions - */ -static int -gulm_lk_login_reply(void *misc, uint32_t error, uint8_t which) -{ - int *flagp = (int *)misc; - - if (flagp) - *flagp = 1; - - return error; -} - - -static int -gulm_lk_logout_reply(void *misc) -{ - int *flagp = (int *)misc; - - if (flagp) - *flagp = 1; - - return 0; -} - - -/** - * Login - */ -int -gulm_lock_login(gulm_interface_p pg) -{ - int flag = 0, ret; - lg_lockspace_callbacks_t cb = lock_callbacks_initializer; - - cb.login_reply = gulm_lk_login_reply; - - if (lg_lock_login(pg, "usrm") != 0) { - errno = ENOLCK; - return -1; - } - - do { - ret = lg_lock_handle_messages(pg, &cb, &flag); - } while (!flag); - - return ret; -} - - -/** - * Logout - */ -int -gulm_lock_logout(gulm_interface_p pg) -{ - int flag = 0, ret; - lg_lockspace_callbacks_t cb = lock_callbacks_initializer; - - cb.logout_reply = gulm_lk_logout_reply; - - /* Ruh roh */ - ret = lg_lock_logout(pg); - if (ret != 0) - return ret; - - do { - ret = lg_lock_handle_messages(pg, &cb, &flag); - } while (!flag); - - return ret; -} - - -/** - * - */ -int -gulm_lk_lock_state(void *misc, uint8_t *key, uint16_t keylen, - uint64_t subid, uint64_t start, uint64_t stop, - uint8_t state, - uint32_t flags, uint32_t error, uint8_t *LVB, - uint16_t LVBlen) -{ - int *flagp = (int *)misc; - - *flagp = 1; - - if (!LVB) { - printf("No LVB in lock reply. Oddness.\n"); - } - - switch(error) { - case lg_err_Ok: - return 0; - case lg_err_NotAllowed: - return -EPERM; - case lg_err_Unknown_Cs: - return -EFAULT; - case lg_err_TryFailed: - case lg_err_Canceled: - return -EAGAIN; - case lg_err_AlreadyPend: - return -EINPROGRESS; - } - - printf("Unhandled lock error code: %d\n", error); - return -1; -} - - - -/** - * - */ -int -gulm_lock(cluster_plugin_t *self, - char *resource, - int flags, - void **lockpp) -{ - lg_lockspace_callbacks_t cb = lock_callbacks_initializer; - uint16_t reslen; - uint8_t state; - uint32_t lkflags = 0; - int ret, flag = 0; - uint64_t pid; - gulm_interface_p pg; - gulm_priv_t *priv; - - assert(self); - priv = (gulm_priv_t *)self->cp_private.p_data; - assert(priv); - pg = priv->interface; - assert(resource); - reslen = (uint16_t)strlen(resource); - assert(reslen); - - *lockpp = NULL; - - if ((flags & CLK_EX) == CLK_EX) { - state = lg_lock_state_Exclusive; - } else if (flags & CLK_READ) { - state = lg_lock_state_Shared; - } else if (flags & CLK_WRITE) { - state = lg_lock_state_Exclusive; - } else { - /* NULL Locks not supported on GULM */ - errno = EINVAL; - return -1; - } - - pid = getpid(); - - if (flags & CLK_NOWAIT) - lkflags |= lg_lock_flag_Try; - - do { - /* - * Send lock request to GuLM. - */ - ret = lg_lock_state_req(pg, (uint8_t *)resource, reslen, - pid, 0, ~0ULL, - state, - lkflags, GULM_USRM_LVB, GULM_USRM_LVB_LEN); - - if (ret != 0) - return ret; - - cb.lock_state = gulm_lk_lock_state; - - /* Wait for response from GuLM */ - do { - ret = lg_lock_handle_messages(pg, &cb, &flag); - } while (!flag); - - switch(ret) { - case -EINPROGRESS: - lg_lock_cancel_req(pg, resource, reslen, pid); - errno = EINPROGRESS; - return -1; - case -EAGAIN: - if (!(lkflags & lg_lock_flag_Try)) - break; - errno = EAGAIN; - return -1; - case 0: - return 0; - default: - errno = (-ret); - return -1; - } - - usleep(250000); - } while (1); - - return ret; -} - - -/** - * - */ -int -gulm_unlock(cluster_plugin_t *self, - char *resource, - void *lockp) -{ - lg_lockspace_callbacks_t cb = lock_callbacks_initializer; - uint16_t reslen; - int ret, flag = 0; - uint64_t pid; - gulm_interface_p pg; - gulm_priv_t *priv; - - assert(self); - priv = (gulm_priv_t *)self->cp_private.p_data; - assert(priv); - pg = priv->interface; - assert(resource); - reslen = (uint16_t)strlen(resource); - assert(reslen); - pid = getpid(); - - /* - * Send lock request to GuLM. - */ - ret = lg_lock_state_req(pg, (uint8_t *)resource, reslen, - pid, 0, ~0ULL, - lg_lock_state_Unlock, - 0, GULM_USRM_LVB, GULM_USRM_LVB_LEN); - - if (ret != 0) - return ret; - - cb.lock_state = gulm_lk_lock_state; - - /* Wait for response from GuLM */ - do { - ret = lg_lock_handle_messages(pg, &cb, &flag); - } while (!flag); - - return ret; -} diff --git a/magma-plugins/gulm/gulm-plugin.h b/magma-plugins/gulm/gulm-plugin.h deleted file mode 100644 index 221ebbc..0000000 --- a/magma-plugins/gulm/gulm-plugin.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -*/ -#ifndef _GULM_PLUGIN_H -#define _GULM_PLUGIN_H - -#include <libgulm.h> - -typedef struct { - gulm_interface_p interface; - int quorum_state; - int memb_count; - uint64_t memb_sum; -} gulm_priv_t; - -struct nodelist_misc { - char ret; - cluster_member_list_t *members; -}; - -int gulm_lock_login(gulm_interface_p pg); -int gulm_lock_logout(gulm_interface_p pg); - -int gulm_lock(cluster_plugin_t *self, char *resource, int flags, - void **lockpp); -int gulm_unlock(cluster_plugin_t *self, char *resource, void *lockp); - - -#endif /* _GULM_PLUGIN_H */ diff --git a/magma-plugins/gulm/gulm.c b/magma-plugins/gulm/gulm.c deleted file mode 100644 index cc3d866..0000000 --- a/magma-plugins/gulm/gulm.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -*/ -/** @file - * GuLM membership/quorum functions & driver load - */ -#include <magma.h> -#include <netinet/in.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <libgulm.h> -#include <assert.h> -#include <signal.h> -#include "gulm-plugin.h" - -#include <sys/types.h> -#include <linux/unistd.h> - -#define MODULE_DESCRIPTION "GuLM Plugin v1.0.5" -#define MODULE_AUTHOR "Lon Hohberger" - - -/* - * Grab the version from the header file so we don't cause API problems - */ -IMPORT_PLUGIN_API_VERSION(); - -/** - * GuLM no-ops protos - */ -static int null_login_reply(void *misc, uint64_t gen, uint32_t error, - uint32_t rank, uint8_t corestate); -static int null_logout_reply(void *misc); -static int null_nodelist(void *misc, lglcb_t type, char *name, - struct in6_addr *ip, uint8_t state); -static int null_statechange(void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr *masterip, char *mastername); -static int null_nodechange(void *misc, char *nodename, - struct in6_addr *nodeip, uint8_t nodestate); -static int null_service_list(void *misc, lglcb_t type, char *service); -static int null_error(void *misc, uint32_t err); - -static lg_core_callbacks_t gulm_callbacks_initializer = { - null_login_reply, - null_logout_reply, - null_nodelist, - null_statechange, - null_nodechange, - null_service_list, - null_error -}; - - -/* - * Patch from Adam Conrad / Ubuntu: Don't use _syscall macro - */ -#ifdef __NR_gettid -pid_t gettid (void) -{ - return syscall(__NR_gettid); -} -#else - -#warn "gettid not available -- substituting with pthread_self()" - -#include <pthread.h> -pid_t gettid (void) -{ - return (pid_t)pthread_self(); -} -#endif - - -/** - * GuLM reply-no-ops - */ -static int -null_login_reply(void *misc, uint64_t gen, uint32_t error, uint32_t rank, - uint8_t corestate) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -static int -null_logout_reply(void *misc) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -static int -null_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *ip, - uint8_t state) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -static int -null_statechange(void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr *masterip, char *mastername) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -static int -null_nodechange(void *misc, char *nodename, struct in6_addr *nodeip, - uint8_t nodestate) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -static int -null_service_list(void *misc, lglcb_t type, char *service) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -static int -null_error(void *misc, uint32_t err) -{ -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - return 0; -} - - -/** - * No-op function. - */ -static int -gulm_null(cluster_plugin_t *self) -{ - printf(MODULE_DESCRIPTION " NULL function called\n"); - return 0; -} - - - -/* - * Function called back by lg_core_handle_messages - */ -int -gulm_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *ip, - uint8_t state) -{ - int idx; - struct nodelist_misc *nm = (struct nodelist_misc *)misc; - cluster_member_list_t *mlp; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - assert(misc); - mlp = nm->members; - assert(mlp); - - switch(type) { - case lglcb_start: - nm->ret = 0; - return 0; - - case lglcb_item: - nm->ret = 1; - - idx = mlp->cml_count; - mlp->cml_count++; - mlp = realloc(mlp, sizeof(cluster_member_list_t) + - sizeof(cluster_member_t) * - mlp->cml_count); - assert(mlp); - - /* Reassign in case pointer changed */ - ((struct nodelist_misc *)misc)->members = mlp; - - strncpy(mlp->cml_members[idx].cm_name, name, - sizeof(mlp->cml_members[idx].cm_name)); - - mlp->cml_members[idx].cm_id = - ((uint64_t)(ip->s6_addr32[2]) << 32) | - (uint64_t)ip->s6_addr32[3]; - mlp->cml_members[idx].cm_addrs = NULL; - - if (state == lg_core_Logged_in) - mlp->cml_members[idx].cm_state = STATE_UP; - else - mlp->cml_members[idx].cm_state = STATE_DOWN; - - return 0; - - case lglcb_stop: - nm->ret = 2; - return 0; - } - - return 1; -} - - -static cluster_member_list_t * -gulm_member_list(cluster_plugin_t *self, - char __attribute__ ((unused)) *groupname) -{ - int ret; - gulm_interface_p pg; - gulm_priv_t *p; - lg_core_callbacks_t cb = gulm_callbacks_initializer; - struct nodelist_misc nm; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - cb.nodelist = gulm_nodelist; - - assert(self); - p = (gulm_priv_t *)self->cp_private.p_data; - assert(p); - pg = p->interface; - assert(pg); - - if (lg_core_nodelist(pg) != 0) - return NULL; - - memset(&nm, 0, sizeof(nm)); - nm.members = malloc(sizeof(cluster_member_list_t)); - if (!nm.members) - return NULL; - - memset(nm.members,0,sizeof(*nm.members)); - - do { - ret = lg_core_handle_messages(pg, &cb, (void *)&nm); - } while (nm.ret != 2 && (ret >= 0)); - - p->memb_count = nm.members->cml_count; - - /* pointer can change from realloc */ - return nm.members; -} - - -static int -gulm_statechange(void *misc, uint8_t corestate, uint8_t quorate, - struct in6_addr *masterip, char *mastername) -{ - int *ret = (int *)misc; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - *ret = CE_NULL; - - if (quorate) - *ret = CE_QUORATE; - else - *ret = CE_INQUORATE; - - return 0; -} - - -static int -gulm_quorum_status(cluster_plugin_t *self, - char *groupname) -{ - int ret = 0, flag = -1; - gulm_interface_p pg; - lg_core_callbacks_t cb = gulm_callbacks_initializer; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - cb.statechange = gulm_statechange; - - assert(self); - pg = ((gulm_priv_t *)self->cp_private.p_data)->interface; - assert(pg); - - if (lg_core_corestate(pg) != 0) - return -1; - - /* - * gulm_login_reply modifies ret. WATCH SIZING conflicts for - * ret here and *ret in gulm_login_reply above!!! - */ - do { - lg_core_handle_messages(pg, &cb, (void *)&flag); - } while (ret == 0 && flag == -1); - - if (flag == CE_QUORATE) - return QF_QUORATE | (groupname?QF_GROUPMEMBER:0); - if (flag == CE_INQUORATE) - return 0; - - return -1; -} - - -static char * -gulm_version(cluster_plugin_t *self) -{ - return MODULE_DESCRIPTION; -} - - -/* - * Pulled from gulm-stonith bridge. - */ -static int -gulm_login_reply(void *misc, uint64_t gen, uint32_t error, uint32_t rank, - uint8_t corestate) -{ - int *flag = (int *)misc; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - *flag = 1; - - switch(error) { - case lg_err_Ok: - return 0; - - case lg_err_BadConfig: -#ifdef DEBUG - printf("GuLM: Bad config\n"); -#endif - return -1; - - case lg_err_BadLogin: -#ifdef DEBUG - printf("GuLM: Bad login\n"); -#endif - return 1; - } - -#ifdef DEBUG - printf("GuLM: Error %d\n", error); -#endif - return -1; -} - - -static int -gulm_open(cluster_plugin_t *self) -{ - int flag = 0, ret = -1; - gulm_interface_p pg; - lg_core_callbacks_t cb = gulm_callbacks_initializer; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - cb.login_reply = gulm_login_reply; - - assert(self); - pg = ((gulm_priv_t *)self->cp_private.p_data)->interface; - assert(pg); - - if (lg_core_login(pg, 0) != 0) - return -1; - - /* - * gulm_login_reply modifies ret. WATCH SIZING conflicts for - * ret here and *ret in gulm_login_reply above!!! - */ - ret = lg_core_handle_messages(pg, &cb, (void *)&flag); - if ((ret != 0) || !flag) - /* Should NEVER be reached; gulm returns the login reply - first - this is guaranteed */ - return -1; - - /* Log in to the lock subsys */ - ret = gulm_lock_login(pg); - if (ret != 0) - return ret; - - /* Give back our file descriptor to listen on. */ - ret = lg_core_selector(pg); - - return ret; -} - - -static int -gulm_logout_reply(void *misc) -{ - int *flag = (int *)misc; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - /* - * Ok, we got our logout message. - */ - *flag = 1; - return 0; -} - - -static int -gulm_close(cluster_plugin_t *self, int __attribute__((unused)) fd) -{ - gulm_interface_p pg; - lg_core_callbacks_t cb = gulm_callbacks_initializer; - int flag = 0, ret; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - cb.logout_reply = gulm_logout_reply; - - assert(self); - pg = ((gulm_priv_t *)self->cp_private.p_data)->interface; - assert(pg); - - ret = gulm_lock_logout(pg); - if (ret != 0) - return ret; - - ret = lg_core_logout(pg); - if (ret != 0) - return ret; - - while (flag == 0) { - /* - * Chew up messages. - */ - lg_core_handle_messages(pg, &cb, (void *)&flag); - } - - return 0; -} - - -static int -gulm_fence(cluster_plugin_t *self, cluster_member_t *node) -{ - gulm_interface_p pg; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - assert(self); - pg = ((gulm_priv_t *)self->cp_private.p_data)->interface; - assert(pg); - - if (lg_core_forceexpire(pg, (char *)node->cm_name) != 0) - return -1; - return 0; -} - - -/** - * See if we have a membership change event. - */ -static int -gulm_nodechange(void *misc, char *nodename, struct in6_addr *nodeip, - uint8_t nodestate) -{ - int *event = (int *)misc; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - - /* If we get multiple, ignore the membership changes */ - switch (*event) { - case CE_QUORATE: - case CE_INQUORATE: - case CE_SHUTDOWN: - return 0; - } - - switch(nodestate) { - case lg_core_Logged_in: - case lg_core_Logged_out: - case lg_core_Fenced: - *event = CE_MEMB_CHANGE; - break; - default: - *event = CE_NULL; - break; - } - - return 0; -} - - -static int -gulm_get_event(cluster_plugin_t *self, int fd) -{ - gulm_interface_p pg; - struct timeval tv; - fd_set rfds; - lg_core_callbacks_t cb = gulm_callbacks_initializer; - int ret, event = CE_NULL; - -#ifdef DEBUG - printf("GuLM: %s called\n", __FUNCTION__); -#endif - cb.nodechange = gulm_nodechange; - cb.statechange = gulm_statechange; - - assert(self); - pg = ((gulm_priv_t *)self->cp_private.p_data)->interface; - assert(pg); - - /* - XXX The gulm core statechange is delivered after the - membership transitions; but very shortly after. So, we - allow 1/4 second. This seems to work ;) - */ - tv.tv_sec = 0; - tv.tv_usec = 250000; - do { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - if (select(fd + 1, &rfds, NULL, NULL, &tv) == 0) - return event; - - /* - * Chew up messages. - */ - ret = lg_core_handle_messages(pg, &cb, (void *)&event); - - } while (ret >= 0); - - if (ret < 0) { - /* Broken pipe/shutdown. At this point, we need to kill - the lock file descriptor too. */ - close(lg_lock_selector(pg)); - return CE_SHUTDOWN; - } - - return event; -} - - -int -cluster_plugin_load(cluster_plugin_t *driver) -{ - if (!driver) { - errno = EINVAL; - return -1; - } - - driver->cp_ops.s_null = gulm_null; - driver->cp_ops.s_member_list = gulm_member_list; - driver->cp_ops.s_quorum_status = gulm_quorum_status; - driver->cp_ops.s_plugin_version = gulm_version; - driver->cp_ops.s_get_event = gulm_get_event; - driver->cp_ops.s_open = gulm_open; - driver->cp_ops.s_close = gulm_close; - driver->cp_ops.s_fence = gulm_fence; - driver->cp_ops.s_lock = gulm_lock; - driver->cp_ops.s_unlock = gulm_unlock; - - return 0; -} - - -int -cluster_plugin_init(cluster_plugin_t *driver, void *__attribute__((unused))priv, - size_t __attribute__((unused)) privlen) -{ - char myname[256]; - int ret; - gulm_interface_p pg; - gulm_priv_t *gp; - - if (!driver) { - errno = EINVAL; - return -1; - } - - snprintf(myname, sizeof(myname), "Magma::%d", - gettid()); - - ret = lg_initialize(&pg, "", myname); - if (ret != 0) - return -1; - - assert(pg); - gp = malloc(sizeof(gulm_priv_t)); - assert(gp); - - gp->interface = pg; - gp->quorum_state = 0; - - driver->cp_private.p_data = (void *)gp; - - return 0; -} - - -/* - * Clear out the private data, if it exists. - */ -int -cluster_plugin_unload(cluster_plugin_t *driver) -{ - gulm_interface_p pg; - - assert(driver); - pg = ((gulm_priv_t *)driver->cp_private.p_data)->interface; - assert(pg); - lg_release(pg); - free(driver->cp_private.p_data); - driver->cp_private.p_data = NULL; - - return 0; -} diff --git a/magma-plugins/make/defines.mk.input b/magma-plugins/make/defines.mk.input deleted file mode 100644 index 84dc8e9..0000000 --- a/magma-plugins/make/defines.mk.input +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}@SBINDIR@ -mandir ?= ${DESTDIR}@MANDIR@ -libdir ?= ${DESTDIR}@LIBDIR@ -slibdir ?= ${DESTDIR}@SLIBDIR@ -plugindir ?= ${DESTDIR}@PLUGINDIR@ -incdir ?= ${DESTDIR}@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/magma-plugins/make/release.mk.input b/magma-plugins/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/magma-plugins/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/magma-plugins/scripts/uninstall.pl b/magma-plugins/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/magma-plugins/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/magma-plugins/sm/Makefile b/magma-plugins/sm/Makefile deleted file mode 100644 index f3b11d2..0000000 --- a/magma-plugins/sm/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -INCLUDES+= -I. -I${incdir} -LIBS += -L${libdir} -ldlm_lt -CFLAGS += -D_CLUSTER_ -ggdb -OBJS = sm.o services.o -TARGETS = magma_sm.so - -ifneq (${KERNEL_SRC}, ) -# Use the kernel tree if patched, otherwise, look where cluster headers -# should be installed -INCLUDES += $(shell if [ -d ${KERNEL_SRC}/include/cluster ]; then \ - echo '-I${KERNEL_SRC}/include/cluster'; else \ - echo '-I${incdir}/cluster'; fi) -else -INCLUDES += -I${incdir}/cluster -endif - -all: $(TARGETS) - -install: all - mkdir -p ${plugindir} - install -m 0755 $(TARGETS) ${plugindir} - -uninstall: - ${UNINSTALL} ${TARGETS} ${plugindir} - -magma_sm.so: buildtest $(OBJS) - $(CC) -o $@ $(OBJS) -shared $(CFLAGS) $(LIBS) - -buildtest: $(OBJS) - echo "int main(void) { return 0; }" > _buildtest.c - $(CC) -c _buildtest.c - $(CC) -o $@ _buildtest.o $(OBJS) $(LIBS) -lpthread - rm -f _buildtest* - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDES) -fPIC $(CFLAGS) - -clean: - rm -f *o *~ *.so buildtest - diff --git a/magma-plugins/sm/services.c b/magma-plugins/sm/services.c deleted file mode 100644 index 0a5ce93..0000000 --- a/magma-plugins/sm/services.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -#include <stdio.h> -#include <magma.h> -#include <fcntl.h> -#include <cnxman-socket.h> -#include <assert.h> -#include <stdint.h> -#include <linux/ioctl.h> -#include <string.h> -#include <unistd.h> -#include <sys/ioctl.h> - -#ifndef SERVICE_FILE -#define SERVICE_FILE "/proc/cluster/services" -#endif - -#define TEST \ -"Service Name GID LID State Code\n" \ -"User: "Test" 6 6 run -\n" \ -"[1 2 3 4 5 6]\n" \ -"User: "Test2" 6 6 run -\n" \ -"[1 2 3]\n" \ -"User: "Test3" 6 6 run -\n" \ -"[2 3]\n" - - -static uint32_t -_group_member_ids(char *groupname, char *buffer, size_t bufferlen, - uint64_t **ids) -{ - int x; - int state = 0; - uint32_t ret = 0; - char *start = NULL; - char *end = NULL; - - *ids = NULL; - - for (x = 0; x < bufferlen ; x++) { - - switch(state) { - case 0: - if (buffer[x] == '\n' || buffer[x] == '\r') - state = 1; - continue; - case 1: - if ((bufferlen - x) < 5) - return 0; - - if (!strncmp(&buffer[x], "User:", 5)) { - x += 5; - state = 2; /* User found */ - } - continue; - - case 2: /* Open quote found */ - if (buffer[x] == '"') { - state = 3; - } - continue; - - case 3: - start = &buffer[x]; - state = 4; - continue; - - case 4: /* Close quote found */ - if (buffer[x] != '"') - continue; - end = &buffer[x]; - - if ((strlen(groupname) == (end - start)) && - (!strncmp(start, groupname, end - start))) { - /* Skip group name */ - x += (end - start); - state = 5; - } else { - state = 0; - } - continue; - - case 5: /* Open bracket found */ - if (buffer[x] == '[') - state = 6; - continue; - - case 6: - if (buffer[x] >= '0' && buffer[x] <= '9') { - state = 7; - start = &buffer[x]; - } - continue; - - case 7: /* Store ID & Close bracket check */ - if (buffer[x] != ' ' && buffer[x] != ']') - continue; - - /* End of a node ID */ - ret++; - if (*ids) - *ids = realloc(*ids, - sizeof(uint64_t) * ret); - else - *ids = malloc(sizeof(uint64_t) * ret); - - (*ids)[ret - 1] = atoi(start); - start = NULL; - state = 6; - - if (buffer[x] == ']') - return ret; - continue; - - default: - printf("Invalid state: %d\n", state); - return 0; - } - - /* No match. */ - state = 0; - } - - return 0; -} - - -static size_t -_read_services(char **buffer) -{ - int fd, ret = 0, nread, bufsz = 0; - char *buf, *ptr; - int blksz; - - blksz = sysconf(_SC_PAGESIZE); - buf = malloc(blksz); - bufsz = blksz; - fd = open(SERVICE_FILE, O_RDONLY); - - while (1) { - ptr = buf + ret; - nread = read(fd, ptr, blksz); - - if (nread <= 0) - break; - - ret += nread; - - if ((bufsz - ret) < blksz) { - bufsz += blksz; - buf = realloc(buf, bufsz); - } - } - - close(fd); - - if (nread < 0) { - if (buf) { - free(buf); - } - *buffer = NULL; - - return 0; - } - - *buffer = buf; - return ret; -} - - -static int -_is_member(uint64_t *member_ids, int idlen, uint64_t nodeid) -{ - int x; - - for (x = 0; x < idlen; x++) { - if (nodeid == member_ids[x]) - return 1; - } - - return 0; -} - - -cluster_member_list_t * -service_group_members(int sockfd, char *groupname) -{ - cluster_member_list_t *foo = NULL; - struct cl_cluster_nodelist cman_nl = { 0, NULL }; - int x, y, group_count; - size_t sz = 0; - char *buf = NULL; - uint64_t *member_ids = NULL; - - do { - /* Clean up if necessary */ - if (cman_nl.nodes) - free(cman_nl.nodes); - if (foo) - /* Don't need to cml_free - we know we didn't - resolve anything */ - free(foo); - - x = ioctl(sockfd, SIOCCLUSTER_GETMEMBERS, NULL); - if (x <= 0) - return NULL; - - cman_nl.max_members = x; - - /* BIG malloc here */ - sz = sizeof(struct cl_cluster_node) * cman_nl.max_members; - cman_nl.nodes = malloc(sz); - assert(cman_nl.nodes != NULL); - - /* Another biggie */ - foo = cml_alloc(cman_nl.max_members); - assert(foo != NULL); - - } while (ioctl(sockfd, SIOCCLUSTER_GETMEMBERS, &cman_nl) != - cman_nl.max_members); - - assert(foo != NULL); - strncpy(foo->cml_groupname, groupname, sizeof(foo->cml_groupname)); - - sz = _read_services(&buf); - if (sz <= 0) { - free(cman_nl.nodes); - free(foo); - return NULL; - } - - group_count = _group_member_ids(groupname, buf, sz, &member_ids); - if (group_count <= 0) { - free(cman_nl.nodes); - free(foo); - return NULL; - } - - foo->cml_count = group_count < cman_nl.max_members ? - group_count : cman_nl.max_members; - for (x = 0, y = 0; (x < cman_nl.max_members) && - (y < foo->cml_count); x++) { - if (!_is_member(member_ids, group_count, - cman_nl.nodes[x].node_id)) - continue; - - foo->cml_members[y].cm_addrs = NULL; - foo->cml_members[y].cm_id = cman_nl.nodes[x].node_id; - - switch(cman_nl.nodes[x].state) { - case NODESTATE_MEMBER: - foo->cml_members[y].cm_state = STATE_UP; - break; - case NODESTATE_JOINING: - case NODESTATE_DEAD: - foo->cml_members[y].cm_state = STATE_DOWN; - break; - default: - foo->cml_members[y].cm_state = STATE_INVALID; - break; - } - - strncpy(foo->cml_members[y].cm_name, cman_nl.nodes[x].name, - sizeof(foo->cml_members[y].cm_name)); - ++y; - } - - if (buf) - free(buf); - if (member_ids) - free(member_ids); - if (cman_nl.nodes) - free(cman_nl.nodes); - return foo; -} - - -/* -int -main(int argc, char **argv) -{ - uint64_t *member_id = NULL; - uint32_t count, x; - char *buf = NULL; - size_t len = 0; - -#if 0 - printf("***\n"); - printf(TEST); - printf("***\n"); -#endif - len = _read_services(&buf); - count = _group_member_ids(argv[1], buf, len, &member_id); - - printf("Count = %d\n", count); - - for (x = 0; x < count; x++) { - printf("member_id[%d] = %ld\n", x, member_id[x]); - } - - if (buf) - free(buf); - - if (member_id) - free(member_id); -} -*/ - diff --git a/magma-plugins/sm/sm-plugin.h b/magma-plugins/sm/sm-plugin.h deleted file mode 100644 index 92d7716..0000000 --- a/magma-plugins/sm/sm-plugin.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - Plugin header for SM plugin - */ -#ifndef _SM_PLUGIN_H -#define _SM_PLUGIN_H - -#define SMS_NONE 0 -#define SMS_JOINING 1 -#define SMS_JOINED 2 -#define SMS_LEAVING 3 -#define SMS_LEFT 4 - -#include <libdlm.h> - -typedef struct { - int sockfd; - int quorum_state; - int memb_count; - int state; - char *groupname; - dlm_lshandle_t ls; - struct dlm_lksb lsholder; -} sm_priv_t; - -#endif /* _SM_PLUGIN_H */ diff --git a/magma-plugins/sm/sm.c b/magma-plugins/sm/sm.c deleted file mode 100644 index 3503d16..0000000 --- a/magma-plugins/sm/sm.c +++ /dev/null @@ -1,990 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * SM test "Driver" - */ -#include <magma.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <sys/socket.h> -#include <assert.h> -#include <sys/ioctl.h> -#include <cnxman-socket.h> -#include <libdlm.h> -#include "sm-plugin.h" -#include <signal.h> -#include <sys/types.h> -#include <sys/select.h> -#include <sys/stat.h> - -#define MODULE_DESCRIPTION "CMAN/SM Plugin v1.1.7.7" -#define MODULE_AUTHOR "Lon Hohberger" - -#define DLM_LS_NAME "Magma" -#define DLM_LSHOLDER_NAME "__ref_lck" -#define LOCKINFO_MAX 16 - -/* From services.c */ -cluster_member_list_t *service_group_members(int sockfd, char *groupname); - -/* Internal */ -static inline int _dlm_release_lockspace(sm_priv_t *p); -static inline int _dlm_unlock(sm_priv_t *p, struct dlm_lksb *lksb); - - -/* - * Grab the version from the header file so we don't cause API problems - */ -IMPORT_PLUGIN_API_VERSION(); - -static int -sm_null(cluster_plugin_t *self) -{ - printf(MODULE_DESCRIPTION " NULL function called\n"); - return 0; -} - - -static cluster_member_list_t * -sm_member_list(cluster_plugin_t *self, char *groupname) -{ - cluster_member_list_t *foo = NULL; - struct cl_cluster_nodelist sm_nl = { 0, NULL }; - int op = SIOCCLUSTER_SERVICE_GETMEMBERS; - sm_priv_t *p; - int x; - size_t sz; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - assert(p->sockfd >= 0); - - if (!p->groupname && !groupname) { - /* - * No group name at all? - * Default group if unjoined = all members - */ - op = SIOCCLUSTER_GETMEMBERS; - } else { - /* - * External call; not logged in. Read from - * /proc/cluster/services - */ - if ((groupname && !p->groupname) || - (groupname && strcmp(p->groupname, groupname))) - return service_group_members(p->sockfd, groupname); - - if (p->state != SMS_JOINED) - return NULL; - } - - do { - /* Clean up if necessary */ - if (sm_nl.nodes) - free(sm_nl.nodes); - if (foo) - /* Don't need to cml_free - we know we didn't - resolve anything */ - free(foo); - - x = ioctl(p->sockfd, op, NULL); - if (x <= 0) - return NULL; - - sm_nl.max_members = x; - - /* BIG malloc here */ - sz = sizeof(struct cl_cluster_node) * sm_nl.max_members; - sm_nl.nodes = malloc(sz); - assert(sm_nl.nodes != NULL); - - /* Another biggie */ - foo = cml_alloc(sm_nl.max_members); - assert(foo != NULL); - - } while (ioctl(p->sockfd, op, &sm_nl) != sm_nl.max_members); - - /* Store count in our internal structure */ - p->memb_count = sm_nl.max_members; - - foo->cml_count = p->memb_count; - for (x = 0; x < p->memb_count; x++) { - /* Copy the data to the lower layer */ - foo->cml_members[x].cm_addrs = NULL; - foo->cml_members[x].cm_id = (uint64_t)sm_nl.nodes[x].node_id; - - switch(sm_nl.nodes[x].state) { - case NODESTATE_MEMBER: - foo->cml_members[x].cm_state = STATE_UP; - break; - case NODESTATE_JOINING: - case NODESTATE_DEAD: - foo->cml_members[x].cm_state = STATE_DOWN; - break; - default: - foo->cml_members[x].cm_state = STATE_INVALID; - break; - } - - strncpy(foo->cml_members[x].cm_name, sm_nl.nodes[x].name, - sizeof(foo->cml_members[x].cm_name)); - } - - free(sm_nl.nodes); - - return foo; -} - - -/** - * Determine Quorum & Group membership status. - * - * @param self Instance of plugin - * @param groupname Node/Service Group name - */ -static int -sm_quorum_state(cluster_plugin_t *self, char *groupname) -{ - int qs; - sm_priv_t *p; - cluster_member_list_t *tmp; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - assert(p->sockfd >= 0); - - p->quorum_state = 0; - qs = ioctl(p->sockfd, SIOCCLUSTER_ISQUORATE, NULL); - - if ((!groupname && !p->groupname) || - (p->groupname && !groupname) || - (p->groupname && !strcmp(p->groupname, groupname) && - p->state == SMS_JOINED)) { - /* - * We're a group member of the given group if we are logged - * in to the group from this instance of the SM plugin. - * A given SM plugin instance can only be used with a single - * group. If we're given NULL, check our logged-in group, - * if one exists. - */ - p->quorum_state |= QF_GROUPMEMBER; - } else { - /* - * Don't know if we're a group member -- we're not logged - * in to the group. So try to find out from the member - * list. CMAN/SM guarantees that we won't get a membership - * list if we're not a member of that group, so we'll - * use it to our advantage. - */ - if ((tmp = service_group_members(p->sockfd, groupname))) { - p->quorum_state |= QF_GROUPMEMBER; - free(tmp); - } - } - - switch(qs) { - case 1: - p->quorum_state |= QF_QUORATE; - break; - case 0: - default: - p->quorum_state &= ~QF_QUORATE; - break; - } - - return p->quorum_state; -} - - -static char * -sm_version(cluster_plugin_t *self) -{ - return MODULE_DESCRIPTION; -} - - -static void -sm_wait_join_complete(sm_priv_t *p) -{ - struct cl_service_event ev; - fd_set rfds; - struct cl_portclosed_oob msg; - - if (p->state != SMS_JOINING) { - /* XXX */ - } - - while (p->state != SMS_JOINED) { - - FD_ZERO(&rfds); - FD_SET(p->sockfd, &rfds); - - select(p->sockfd+1, &rfds, NULL, NULL, NULL); - - /* Snag the OOB message */ - if (recv(p->sockfd, &msg, sizeof(msg), MSG_OOB) < sizeof(msg)) - continue; - - if (ioctl(p->sockfd, SIOCCLUSTER_SERVICE_GETEVENT, - &ev) <= 0) - continue; - - if (ev.type == SERVICE_EVENT_START) { - ioctl(p->sockfd, SIOCCLUSTER_SERVICE_STARTDONE, - ev.event_id); - /* XXX what if this fails? */ - } - - if (ev.type == SERVICE_EVENT_FINISH) - p->state = SMS_JOINED; - } - -} - - -static void -sm_wait_leave_complete(sm_priv_t *p) -{ - struct cl_service_event ev; - fd_set rfds; - struct cl_portclosed_oob msg; - - if (p->state != SMS_LEAVING) { - /* XXX */ - } - - /* Can't log out if login is not complete... */ - while (p->state != SMS_LEFT) { - - FD_ZERO(&rfds); - FD_SET(p->sockfd, &rfds); - - select(p->sockfd+1, &rfds, NULL, NULL, NULL); - - /* Snag the OOB message */ - if (recv(p->sockfd, &msg, sizeof(msg), MSG_OOB) < sizeof(msg)) - continue; - - if (ioctl(p->sockfd, SIOCCLUSTER_SERVICE_GETEVENT, - &ev) <= 0) - continue; - - if (ev.type == SERVICE_EVENT_LEAVEDONE) - p->state = SMS_LEFT; - - /* - * Handle member transitions during shutdown. - */ - if (ev.type == SERVICE_EVENT_START) { - ioctl(p->sockfd, SIOCCLUSTER_SERVICE_STARTDONE, - ev.event_id); - /* XXX what if this fails? */ - //printf("SERVICE_EVENT_START during leave\n"); - } - } -} - - -/** - * Log in to CMAN/SM and become a group member of the specified group name. - * - * @param self Plugin instance - * @param fd File descriptor to use for login. - * @param groupname Name of group to become member of. - */ -static int -sm_login(cluster_plugin_t *self, int fd, char *groupname) -{ - int q; - int err; - sm_priv_t *p; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - assert(p->sockfd >= 0); - assert(p->sockfd == fd); - - if (!groupname) { - errno = EINVAL; - return -1; - } - - if (p->groupname) { - errno = EBUSY; - return -1; - } - - p->groupname = strdup(groupname); - - q = sm_quorum_state(self, NULL); - while (!is_quorate(q)) { - q = sm_quorum_state(self, NULL); - sleep(2); - } - - if (ioctl(p->sockfd, SIOCCLUSTER_SERVICE_REGISTER, p->groupname) < 0) { - err = errno; - free(p->groupname); - p->groupname = NULL; - return -err; - } - - if (ioctl(p->sockfd, SIOCCLUSTER_SERVICE_JOIN, p->groupname) < 0) { - err = errno; - free(p->groupname); - p->groupname = NULL; - return -err; - } - - p->state = SMS_JOINING; - - sm_wait_join_complete(p); - return 0; -} - - -static int -sm_open(cluster_plugin_t *self) -{ - sm_priv_t *p; - struct stat st; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - - /* Check for existince of dlm control file so we don't - hang in dlm_acquire_lockspace */ - if (stat("/dev/misc/dlm-control", &st) < 0 && - stat("/dev/dlm-control", &st) < 0) - return -1; - - if (p->sockfd >= 0) - close(p->sockfd); - - p->sockfd = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT); - if (p->sockfd < 0) - return -1; - - return p->sockfd; -} - - -static int -sm_logout(cluster_plugin_t *self, int fd) -{ - sm_priv_t *p; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - assert(fd == p->sockfd); - - if (p->state == SMS_NONE) - return 0; - - if (p->state == SMS_JOINED) { - - if (ioctl(p->sockfd, SIOCCLUSTER_SERVICE_LEAVE, NULL)) - return -errno; - - p->state = SMS_LEAVING; - - sm_wait_leave_complete(p); - } - - /* Unregister. */ - ioctl(p->sockfd, SIOCCLUSTER_SERVICE_UNREGISTER, NULL); - - if (p->groupname) { - free(p->groupname); - p->groupname = NULL; - } - - return 0; -} - - -static int -sm_close(cluster_plugin_t *self, int fd) -{ - int ret; - sm_priv_t *p; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - assert(fd == p->sockfd); - - if (p->ls) { - _dlm_release_lockspace(p); - } - p->ls = NULL; - - ret = close(fd); - p->sockfd = -1; - - return ret; -} - - -static int -sm_fence(cluster_plugin_t *self, cluster_member_t *node) -{ - int nodeid; - sm_priv_t *p; - - //printf("SM: %s called\n", __FUNCTION__); - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - - nodeid = (int)node->cm_id; - - return ioctl(p->sockfd, SIOCCLUSTER_KILLNODE, nodeid); -} - - -static int -sm_get_event(cluster_plugin_t *self, int fd) -{ - sm_priv_t *p; - struct cl_service_event ev; - int n, o; - struct cl_portclosed_oob msg; - - memset(&msg, 0, sizeof(msg)); - n = recv(fd, &msg, sizeof(msg), MSG_OOB); - - /* Socket closed. */ - if (n == 0) - return CE_SHUTDOWN; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - assert(fd == p->sockfd); - - /* - * Check for quorum transition. - */ - if (msg.cmd == CLUSTER_OOB_MSG_STATECHANGE) { - o = p->quorum_state; - n = sm_quorum_state(self, NULL); - - if (is_quorate(o) && !is_quorate(n)) { - return CE_INQUORATE; - } else if (!is_quorate(o) && is_quorate(n)) { - return CE_QUORATE; - } - } - - /* - * Otherwise, only handle it if it's a service event - */ - if (msg.cmd != CLUSTER_OOB_MSG_SERVICEEVENT) - return CE_NULL; - - if (ioctl(p->sockfd, SIOCCLUSTER_SERVICE_GETEVENT, &ev) < 0) { - /* XXX */ - //printf("ioctl() failed: %s\n", strerror(errno)); - return CE_NULL; - } - - if (ev.type == SERVICE_EVENT_STOP) { - /* We don't actually do anything. See below. */ - return CE_SUSPEND; - } - - /* - * Begin member transition. USRM recovery happens asynchronously - * from the kernel; it's not proper to suspend the kernel waiting - * for userland to complete. Userland uses the DLM; it should use - * it for synchronization of recovery within other userland processes - */ - if (ev.type == SERVICE_EVENT_START) { - ioctl(p->sockfd, SIOCCLUSTER_SERVICE_STARTDONE, ev.event_id); - /* XXX what if this fails? */ - return CE_NULL; - } - - /* - * Group membership transition complete. - */ - if (ev.type == SERVICE_EVENT_FINISH) - return CE_MEMB_CHANGE; - - return CE_NULL; -} - - -static void -ast_function(void * __attribute__ ((unused)) arg) -{ -} - - -static int -wait_for_dlm_event(dlm_lshandle_t *ls) -{ - fd_set rfds; - int fd = dlm_ls_get_fd(ls); - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - if (select(fd + 1, &rfds, NULL, NULL, NULL) == 1) { - return dlm_dispatch(fd); - } - - return -1; -} - - -static inline int -_dlm_lock(sm_priv_t *p, int mode, struct dlm_lksb *lksb, int options, - char *resource) -{ - int ret; - - /* Ok, we have the NL lock. Now convert it. */ - /* Check for EINTR returned from write() in libdlm.c */ - do { - ret = dlm_ls_lock(p->ls, mode, lksb, options, - resource, strlen(resource), 0, ast_function, - lksb, NULL, NULL); - - if (ret < 0) { - if (errno == EINTR) - continue; - return -1; - } - } while (0); - - while (lksb->sb_status == EINPROG) { - if (wait_for_dlm_event(p->ls) < 0) { - if (lksb->sb_status == EINPROG) - continue; - errno = lksb->sb_status; - return -1; - } - } - - /* Got the lock ! */ - return 0; -} - - - -static inline int -_dlm_acquire_lockspace(sm_priv_t *p, const char *lsname) -{ - dlm_lshandle_t ls = NULL; - struct dlm_lksb lksb; - int ret; - -retry: - while (!ls) { - ls = dlm_open_lockspace(lsname); - if (ls) - break; - - ls = dlm_create_lockspace(lsname, 0644); - if (ls) - break; - - /* Work around race: Someone was closing lockspace as - we were trying to open it. Retry. */ - if (errno == ENOENT) - continue; - - fprintf(stderr, "failed acquiring lockspace: %s\n", - strerror(errno)); - - return -1; - } - - p->ls = ls; - memset(&lksb,0,sizeof(lksb)); - - ret = _dlm_lock(p, LKM_NLMODE, &lksb, 0, DLM_LSHOLDER_NAME); - if (ret != 0) { - dlm_release_lockspace(DLM_LS_NAME, ls, 0); - p->ls = NULL; - if (errno == ENOENT) - /* Lockspace freed under us? :( */ - goto retry; - } - - memcpy(&p->lsholder, &lksb, sizeof(p->lsholder)); - - return 0; -} - - - -static inline int -_dlm_unlock(sm_priv_t *p, struct dlm_lksb *lksb) -{ - int ret; - - /* Check for EINTR returned from write() in libdlm.c */ - do { - ret = dlm_ls_unlock(p->ls, lksb->sb_lkid, 0, lksb, NULL); - - if (ret < 0) { - if (errno == EINTR) - continue; - return -1; - } - } while (0); - - /* lksb->sb_status should be EINPROG at this point */ - while (lksb->sb_status == EINPROG) { - if (wait_for_dlm_event(p->ls) < 0) { - if (lksb->sb_status == EINPROG) - continue; - errno = lksb->sb_status; - return -1; - } - } - - return 0; -} - - -static inline int -_dlm_release_lockspace(sm_priv_t *p) -{ - _dlm_unlock(p, &p->lsholder); - return dlm_release_lockspace(DLM_LS_NAME, p->ls, 0); -} - - -/** - * Ugly routine to figure out what node has a given lock. - */ -static inline int -_get_holder(char *lk, sm_priv_t *p, int mode, uint64_t *holderid) -{ - struct dlm_lksb lksb; - struct dlm_lockinfo li[LOCKINFO_MAX]; - struct dlm_resinfo ri; - struct dlm_queryinfo qi; - int query = 0, x; - int ret; - - /* - * Take a null lock so we can query the DLM and find out who - * is holding the lock we're after. - */ - query = DLM_QUERY_QUEUE_GRANTED | DLM_QUERY_LOCKS_ALL; - - memset(&lksb, 0, sizeof(lksb)); - ret = _dlm_lock(p, LKM_NLMODE, &lksb, 0, lk); - if (ret < 0) - return -1; - - memset(&qi, 0, sizeof(qi)); - memset(&ri, 0, sizeof(ri)); - - qi.gqi_resinfo = &ri; - qi.gqi_lockinfo = &li[0]; - qi.gqi_locksize = LOCKINFO_MAX; - qi.gqi_lockcount = 0; - - /* Query based on our null lock */ - ret = dlm_ls_query(p->ls, &lksb, query, &qi, - ast_function, NULL); - - if (ret != 0) - return ret; - - while (lksb.sb_status == EINPROG) { - if (wait_for_dlm_event(p->ls) < 0) { - if (lksb.sb_status == EINPROG) - continue; - return -1; - } - } - - ret = -1; - for (x = 0; x < qi.gqi_lockcount; x++) { - if (li[x].lki_lkid == lksb.sb_lkid) - continue; - - /* XXX what symbol is state 2?! */ - if (li[x].lki_state != 2) - continue; - - if (li[x].lki_rqmode != 255) - continue; - - if (li[x].lki_grmode == 0) - continue; - - *holderid = (uint64_t)(li[x].lki_node); - ret = 0; - break; - - usleep(100000); - } - - /* XXX check return value?! */ - - _dlm_unlock(p, &lksb); - - return ret; - -} - - -static int -sm_lock(cluster_plugin_t *self, - char *resource, - int flags, - void **lockpp) -{ - sm_priv_t *p; - int mode = 0, options = 0, ret = 0; - struct dlm_lksb *lksb; - size_t sz; - uint64_t holder; - - if (!self || !lockpp) { - errno = EINVAL; - return -1; - } - - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - - if ((flags & CLK_EX) == CLK_EX) { - mode = LKM_EXMODE; - } else if (flags & CLK_READ) { - mode = LKM_PRMODE; - } else if (flags & CLK_WRITE) { - mode = LKM_PWMODE; - } else if ((flags & CLK_EX) == 0){ - mode = LKM_NLMODE; - } - - if (flags & CLK_NOWAIT) - options = LKF_NOQUEUE; - if (flags & CLK_CONVERT) - flags &= ~CLK_HOLDER; /* CLK_HOLDER mutually exclusive with - CLK_CONVERT */ - - /* Allocate our lock structure. */ - sz = (sizeof(*lksb) > sizeof(uint64_t) ? sizeof(*lksb) : - sizeof(uint64_t)); - - while(!p->ls) - _dlm_acquire_lockspace(p, DLM_LS_NAME); - assert(p->ls); - - /* If we've got a non-zero pointer and we're being called with - the CLK_CONVERT flag, then assume it's a previous lksb with - a held lock. */ - if ((flags & CLK_CONVERT) && *lockpp) { - lksb = (struct dlm_lksb *)(*lockpp); - options |= LKF_CONVERT; - } else { - lksb = malloc(sz); - assert(lksb); - memset(lksb, 0, sz); - } - - /* Take the real lock, or at least, try to. */ - ret = _dlm_lock(p, mode, lksb, options, resource); - - /* Got the lock? */ - if (ret == 0) { - if (lksb->sb_status == 0) { - *lockpp = (void *)lksb; - return 0; - } - - /* Flip errno so we only have one switch statement */ - errno = lksb->sb_status; - } - - switch(errno) { - case EAGAIN: - if (flags & CLK_CONVERT) { - *lockpp = (void *)lksb; - /* Nothing special here */ - /* Lock is busy */ - } else if ((flags & CLK_HOLDER) && - (_get_holder(resource, p, mode, &holder) == 0)) { - memset(lksb, 0, sz); - *((uint64_t *)lksb) = holder; - *lockpp = (void *)lksb; - } else { - free(lksb); - } - errno = EAGAIN; - return -1; - default: - /* Other error conditions: Pass back to caller. - * Note that 'ret' is still the indicator for a - * successful call to dlm_ls_lock. So, in the - * successful case, we want to pass the - * lock state back, otherwise errno in the event - * of a failed call. */ - if (ret == 0) { - ret = lksb->sb_status; - } else { - ret = errno; - } - free(lksb); - errno = ret; - return -1; - } - - /* Not reached */ - fprintf(stderr, "code path error @ %s:%d\n", __FILE__, __LINE__); - return -1; -} - - -static int -sm_unlock(cluster_plugin_t *self, char *__attribute__((unused)) resource, - void *lockp) -{ - sm_priv_t *p; - dlm_lshandle_t ls; - struct dlm_lksb *lksb = (struct dlm_lksb *)lockp; - int ret; - - assert(self); - p = (sm_priv_t *)self->cp_private.p_data; - assert(p); - ls = p->ls; - assert(ls); - - if (!lockp) { - errno = EINVAL; - return -1; - } - - ret = _dlm_unlock(p, lksb); - - if (ret != 0) - return ret; - - free(lksb); - - return ret; -} - - -int -cluster_plugin_load(cluster_plugin_t *driver) -{ - if (!driver) { - errno = EINVAL; - return -1; - } - - driver->cp_ops.s_null = sm_null; - driver->cp_ops.s_member_list = sm_member_list; - driver->cp_ops.s_quorum_status = sm_quorum_state; - driver->cp_ops.s_plugin_version = sm_version; - driver->cp_ops.s_get_event = sm_get_event; - driver->cp_ops.s_open = sm_open; - driver->cp_ops.s_login = sm_login; - driver->cp_ops.s_logout = sm_logout; - driver->cp_ops.s_close = sm_close; - driver->cp_ops.s_fence = sm_fence; - driver->cp_ops.s_lock = sm_lock; - driver->cp_ops.s_unlock = sm_unlock; - - return 0; -} - - -int -cluster_plugin_init(cluster_plugin_t *driver, void *priv, - size_t privlen) -{ - sm_priv_t *p = NULL; - - if (!driver) { - errno = EINVAL; - return -1; - } - - if (!priv) { - p = malloc(sizeof(*p)); - assert(p); - } else { - assert(privlen >= sizeof(*p)); - - p = malloc(sizeof(*p)); - assert(p); - memcpy(p, priv, sizeof(*p)); - } - - p->sockfd = -1; - p->quorum_state = 0; - p->memb_count = 0; - p->state = SMS_NONE; - p->groupname = NULL; - p->ls = NULL; - - driver->cp_private.p_data = (void *)p; - driver->cp_private.p_datalen = sizeof(*p); - - return 0; -} - - -/* - * Clear out the private data, if it exists. - */ -int -cluster_plugin_unload(cluster_plugin_t *driver) -{ - sm_priv_t *p = NULL; - - if (!driver) { - errno = EINVAL; - return -1; - } - - assert(driver); - p = (sm_priv_t *)driver->cp_private.p_data; - assert(p); - - /* You did log out, right? */ - assert(p->sockfd < 0); - free(p); - driver->cp_private.p_data = NULL; - driver->cp_private.p_datalen = 0; - - return 0; -} diff --git a/magma/Doxyfile b/magma/Doxyfile deleted file mode 100644 index 12648c8..0000000 --- a/magma/Doxyfile +++ /dev/null @@ -1,187 +0,0 @@ -# Doxyfile 1.2.17 - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = "Magma Cluster API" -PROJECT_NUMBER = 01 -OUTPUT_DIRECTORY = ./magma-api -OUTPUT_LANGUAGE = English -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -BRIEF_MEMBER_DESC = NO -REPEAT_BRIEF = YES -ALWAYS_DETAILED_SEC = YES -INLINE_INHERITED_MEMB = YES -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -INTERNAL_DOCS = NO -STRIP_CODE_COMMENTS = NO -CASE_SENSE_NAMES = YES -SHORT_NAMES = NO -HIDE_SCOPE_NAMES = NO -VERBATIM_HEADERS = YES -SHOW_INCLUDE_FILES = YES -JAVADOC_AUTOBRIEF = YES -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 8 -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ALIASES = -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -SHOW_USED_FILES = YES -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ./ -FILE_PATTERNS = *.c \ - *.h -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = ./build/* -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_SCHEMA = -XML_DTD = -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -TEMPLATE_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/magma/Makefile b/magma/Makefile deleted file mode 100644 index 9cdbca7..0000000 --- a/magma/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd lib && ${MAKE} all - cd tests && ${MAKE} all - -clean: - rm -f *~ - cd lib && ${MAKE} clean - cd tests && ${MAKE} clean - -install: - cd lib && ${MAKE} install - cd man && ${MAKE} install - cd tests && ${MAKE} install - -uninstall: - cd lib && ${MAKE} uninstall - cd man && ${MAKE} uninstall - cd tests && ${MAKE} uninstall - -distclean: clean - rm -f make/defines.mk diff --git a/magma/configure b/magma/configure deleted file mode 100755 index 1eeb076..0000000 --- a/magma/configure +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - slibdir => $slibdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - plugindir => $plugindir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'slibdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'plugindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--slibdir=\tthe base directory for static libraries. (Default: /usr/lib\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /sbin)\n"; - print "--plugindir=\tthe directory to search for plugins. (Default: {libdir}/magma\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$slibdir) { - $slibdir="${libdir}"; -} -if (!$plugindir) { - $plugindir="${libdir}/magma"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@SLIBDIR@/$slibdir/; - $_ =~ s/@PLUGINDIR@/$plugindir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/magma/doc/COPYING-libmagma b/magma/doc/COPYING-libmagma deleted file mode 100644 index ebaa528..0000000 --- a/magma/doc/COPYING-libmagma +++ /dev/null @@ -1,851 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. -
- Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. -
- GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. -
- 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. -
- Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. -
- 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. -
- 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. -
- 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. -
- 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - ----------------------------------------------------------------------- -
-http://www.fsf.org/copyleft/gpl.txt - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. -
- GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) -
-These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. -
- 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -
- 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - ----------------------------------------------------------------------- diff --git a/magma/doc/COPYING-libmagmamsg b/magma/doc/COPYING-libmagmamsg deleted file mode 100644 index d60c31a..0000000 --- a/magma/doc/COPYING-libmagmamsg +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. -
- GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) -
-These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. -
- 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -
- 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/magma/doc/TODO b/magma/doc/TODO deleted file mode 100644 index c114b6e..0000000 --- a/magma/doc/TODO +++ /dev/null @@ -1,3 +0,0 @@ -(1) Manpages -(2) Better Doxygen-formatted comments -(3) Spec file diff --git a/magma/doc/magma.txt b/magma/doc/magma.txt deleted file mode 100644 index 96a0f52..0000000 --- a/magma/doc/magma.txt +++ /dev/null @@ -1,247 +0,0 @@ -Outline - Magma/CAL - Cluster Abstraction Library - -Section One: Plugin Design considerations. - -I. Required/recommended plugin functions - A. All plugins must provide the following functions: - 1. s_member_list - 2. s_quorum_status - 3. s_get_event - 4. s_open - 5. s_close - - B. All plugins should provide the following functions: - 1. s_null - 2. s_plugin_version - 3. s_fence - - C. Plugins which support locking should provide the following - functions: - 1. s_lock - 2. s_unlock - - D. Plugins which support service groups or node groups should - provide the following functions: - 1. s_login - 2. s_logout - - E. All plugins must provide the following dl-mappable functions - (these are checked by cp_load() using dlsym()): - 1. cluster_plugin_load - 2. cluster_plugin_init - 3. cluster_plugin_unload - 4. cluster_plugin_version - i. This can be inherited by placing: - "IMPORT_PLUGIN_API_VERSION()" near the top - of your source code. - - F. Plugins which do not implement a given function should leave - them alone; cp_load() maps all functions in a given - cluster_plugin_t object to be "unimplemented" versions, so - there is no danger of dereferencing NULL function pointers - when cp_load() is used. - - G. When the caller calls cp_unload on your object, it must be - fully cleaned up, logged out, and have all resources cleaned - up without further intervention of the caller. - -II. Plugin coding style. - A. Please use Linux-Kernel Coding Style. - -III. Plugin Design Considerations. - A. Plugins should be designed as re-entrant entities - 1. This means no internal pthread_* locking calls - 2. They should use private data structures. - i. Avoids need for internally-global symbols - ii. Prevents need for internal locking, making - each object internally thread-safe. - - -Section Two: What magma provides for you - -I. High-level cluster connection functions - A. clu_connect(char *group, int login) - 1. Connects to underlying cluster infrastructure and - logs in to the group specified by <group>(if - <login> is nonzero) - 2. Loads/unloads plugins and tries to log in until one - succeeds. - 3. Returns a select(2)able file descriptor on which you - may look for events. - - B. clu_disconnect(int fd) - 1. Disconnects from underlying infrastructure and logs - out. - - C. clu_member_list(char *group) - 1. Returns a "cluster_member_list_t *" structure (see - src/magma.h) containing members of the given <group>. - 2. Does not require being logged in to <group>. - - D. clu_quorum_status(char *group) - 1. Returns a set of flags showing quorum & group state - for <group> - i. QF_QUORATE -> Node is quorate - ii. QF_GROUPMEMBER -> Node is member of - specified group. - 2. Does not require being logged in to <group>. - - E. clu_fence(cluster_member_t *node) [NEW] - 1. Fences or marks <node> expired. - 2. User then waits for an event to be returned from the - cluster; this function is asynchronous. - - F. clu_get_event(int fd) - 1. Retrieve an event from <fd> - 2. Returns one of: - i. CE_NULL - Ignore this event. - ii. CE_MEMB_CHANGE - Membership change - iii. CE_SUSPEND - pause until next - CE_MEMB_CHANGE event is received - iv. CE_QUORATE - Cluster quorum formed - v. CE_INQUORATE - Cluster quorum dissolved - vi. CE_SHUTDOWN - Local node is leaving the - cluster. Clean up and exit immediately. - - -II. Local node identification information - A. clu_local_nodename(char *group, char *buf, int buflen) - 1. Copies the local node name from membership list - of <group> into <buf> - 2. <buf> is pre-allocated of size <buflen>. - - B. clu_local_nodeid(char *group, uint64_t *nodeid) - 1. Copies the local node ID from membership list of - <group> into <nodeid> - 2. <nodeid> is a pre-allocated 64-bit integer. - -III. Membership list manipulation and querying - A. clu_members_gained(cluster_member_list_t *old, - cluster_member_list_t *new) - 1. Returns list of members which are now present or - otherwise online in <new> which were not present or - were offline in <old>. - 2. User must call cml_free() to free returned structure - - B. clu_members_lost(cluster_member_list_t *old, - cluster_member_list_t *new) - 1. Returns list of members which are no longer present - or are otherwise offline in <new> which were present - or were online in <old>. - 2. User must call cml_free() to free returned structure - - C. memb_online(cluster_member_list_t *nodes, uint64_t nodeid) - 1. Returns 1 if <nodeid> is present and/or online in - <nodes>. - - D. memb_name_to_id(cluster_member_list_t *nodes, char *name) - 1. Returns 64-bit node ID of the member named <name>. - - E. memb_name_to_p(cluster_member_list_t *nodes, char *name) - 1. Returns (cluster_member_t *) structure to node - in <nodes> named <name>. - - F. memb_id_to_name(cluster_member_list_t *nodes, uint64_t - nodeid) - 1. Returns (char *) corresponding to node ID <nodeid> - if it exists in <nodes>. - - G. memb_id_to_p(cluster_member_list_t *nodes, uint64_t nodeid) - 1. Returns (cluster_member_t *) structure to node - in <nodes> with id <nodeid>. - - H. memb_resolve(cluster_member_t *member) - 1. Resolves using getaddrinfo(); stores result in - member->cm_addrs. - - I. memb_resolve_list(cluster_member_list_t *new, - cluster_member_list_t *old) - 1. Moves all existing cm_addrs pointers from <old> - to <new>. - 2. Resolves any previously unresolved nodes in - <old> and stores them in <new>. - - J. cml_free(cluster_member_list_t *dead) - 1. Cleans up all cm_addrs fields (using freeaddrinfo) - 2. Frees <dead> structure. - 3. ALWAYS use this to free cluster_member_list_t - structures - - K. print_member_list(cluster_member_list_t *list, int verbose - 1. Dumps all member names, IDs, and their addresses - to stdout. - -IV. IPv4 / IPv6 abstracted TCP messaging functions - A. msg_update(cluster_member_list_t *new_membership) - 1. Frees previously allocated/updated membership list - replaces with new one. - 2. Resolves all members using memb_resolve_list. - 3. Should be called whenever you receive a new - membership list from the cluster infrastructure. - - B. msg_listen(uint16_t baseport, int *fds, int fds_len) - 1. Sets up listening sockets on baseport (IPv4) - and baseport+IPV6_PORT_OFFSET (IPv6) - 2. Stores file descriptors in <fds>. - 3. Returns number of listening sockets. - - C. msg_open(uint64_t nodeid, uint16_t baseport) - 1. Connects to <nodeid> via <baseport>. First tries - IPv6; falls back to IPv4. - - D. msg_send(int fd, void *buf, size_t buflen) - 1. Sends <buf> to <fd>; size = <buflen> - 2. <buf> is prepended with a count and a 32-bit CRC - which aids in detection of lost data. - - E. msg_receive(int fd, void *buf, size_t buflen) - 1. Receives <buflen> bytes from <fd>; stores in <buf> - 2. Contents returned are checked against a 32-bit CRC - for basic integrity - - F. msg_receive_timeout(int fd, void *buf, size_t buflen, - int timeout) - 1. Receives <buflen> bytes from <fd>; stores in <buf> - 2. Aborts after <timeout> seconds. - 3. Contents returned are checked against a 32-bit CRC - for basic integrity - - G. msg_close(int fd) - 1. Closes <fd> - -V. Cluster Locking API - A. clu_lock(char *resource, int flags, void **lockpp) - 1. Obtains a cluster-wide lock for <resource> - 2. <*(lockpp)> is allocated; a plugin-specific - lock handle is stored inside. - 3. The same lock handle should be passed back to - clu_unlock() - 4. Lock flags - i. CLK_NOWAIT - return EAGAIN if unavailable - ii. CLK_WRITE - Write lock - iii. CLK_READ - Read lock - iv. CLK_EX - Exclusive lock - - B. clu_unlock(char *resource, void *lockp) - 1. Releases cluster-wide lock for <resource> - 2. <lockp> is freed. - - -Section Three: Notes on included plugins - -I. GuLM - The Grand Unified Lock Manager (gulm.so) - A. This plugin does not have a notion of node groups. - B. The locking system does not support multiple process-locks - on the same node. To get around this, we take a POSIX lock - on a file prior to asking for a lock from GuLM. - -II. CMAN - Using DLM to sync after transition (cman.so) - A. This plugin does not have a notion of node groups. - -III. CMAN - Using Kernel Service Manager (sm.so) - A. This plugin uses two different methods to query node group - information. - B. This is the only plugin which returns the CE_SUSPEND event. - Applications intending to use it should also be able to - operate without it. - diff --git a/magma/lib/Makefile b/magma/lib/Makefile deleted file mode 100644 index f18c1f0..0000000 --- a/magma/lib/Makefile +++ /dev/null @@ -1,119 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -TARGETS=libmagma.a \ - libmagma_nt.a \ - libmagmamsg.a \ - libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) \ - libmagma.so.$(RELEASE_MAJOR) \ - libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) \ - libmagma_nt.so.$(RELEASE_MAJOR) \ - libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) \ - libmagmamsg.so.$(RELEASE_MAJOR) \ - libmagma.so \ - libmagma_nt.so \ - libmagmamsg.so - -INCLUDE=-I. -CFLAGS+=-g -Werror -Wstrict-prototypes -Wshadow \ - -fPIC -DPLUGINDIR="${plugindir}" \ - -D_GNU_SOURCE - -all: $(TARGETS) - -clean: - rm -f *o *~ *.a $(TARGETS) - -install: all - install -d $(libdir) - install -d $(slibdir) - - # - # Install high level magma libraries - # - install -m 0644 libmagma.a $(slibdir) - install -m 0755 libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) $(libdir) - cd $(libdir); ln -snf libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libmagma.so.$(RELEASE_MAJOR); cd - - cd $(libdir); ln -snf libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libmagma.so; cd - - - # - # Install low-overhead, non-pthread magma libraries - # - install -m 0644 libmagma_nt.a $(slibdir) - install -m 0755 libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) $(libdir) - cd $(libdir); ln -snf libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libmagma_nt.so.$(RELEASE_MAJOR); cd - - cd $(libdir); ln -snf libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libmagma_nt.so; cd - - - # - # Install high level TCP messaging libraries - # - install -m 0644 libmagmamsg.a $(slibdir) - install -m 0755 libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) $(libdir) - cd $(libdir); ln -snf libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libmagmamsg.so.$(RELEASE_MAJOR); cd - - cd $(libdir); ln -snf libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) libmagmamsg.so; cd - - - # - # Install headers for magma, magma_nt, and magmamsg - # - install -d ${incdir} - install -m 0644 magma.h $(incdir) - install -m 0644 magmamsg.h $(incdir) - install -m 0644 magma-build.h $(incdir) - -uninstall: - ${UNINSTALL} ${TARGETS} ${libdir} - ${UNINSTALL} magma.h magmamsg.h magma-build.h ${incdir} - -libmagma.so: libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf $^ $@ - -libmagma_nt.so: libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf $^ $@ - -libmagmamsg.so: libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf $^ $@ - -libmagma.so.$(RELEASE_MAJOR): libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf $^ $@ - -libmagma_nt.so.$(RELEASE_MAJOR): libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf $^ $@ - -libmagmamsg.so.$(RELEASE_MAJOR): libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR) - ln -snf $^ $@ - -libmagma.so.$(RELEASE_MAJOR).$(RELEASE_MINOR): global.o plugin.o \ - localinfo.o ip_lookup.o memberlist.o clist.o - ${CC} -shared -o $@ $^ -lpthread -ldl -Wl,-soname,libmagma.so.$(RELEASE_MAJOR) - -libmagma_nt.so.$(RELEASE_MAJOR).$(RELEASE_MINOR): plugin.o localinfo.o \ - ip_lookup.o memberlist.o - ${CC} -shared -o $@ $^ -ldl -Wl,-soname,libmagma_nt.so.$(RELEASE_MAJOR) - -libmagmamsg.so.$(RELEASE_MAJOR).$(RELEASE_MINOR): message.o fdops.o libmagma.so - ${CC} -shared -o $@ $^ -Wl,-Bdynamic,-soname,libmagmamsg.so.$(RELEASE_MAJOR) -L. -lmagma -lpthread -ldl - -libmagma.a: global.o plugin.o localinfo.o ip_lookup.o \ - memberlist.o clist.o - ${AR} cr $@ $^ - -libmagma_nt.a: plugin.o localinfo.o ip_lookup.o memberlist.o - ${AR} cr $@ $^ - -libmagmamsg.a: message.o fdops.o - ${AR} cr $@ $^ - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDE) $(CFLAGS) -D_CLUSTER_ diff --git a/magma/lib/clist.c b/magma/lib/clist.c deleted file mode 100644 index fc0ef34..0000000 --- a/magma/lib/clist.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - Copyright Red Hat, Inc. 2003-2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Connection list handling routines. - */ -#include <sys/queue.h> -#include <pthread.h> -#include <sys/select.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdint.h> -#include <magmamsg.h> -#include <stdio.h> -#include <unistd.h> - -static inline int clist_delete_nt(int fd); - -/** - * Node in connection list. - */ -typedef struct _conn_node { - TAILQ_ENTRY(_conn_node) cn_entries; /**< sys/queue tailq entri */ - int cn_fd; /**< File descriptor */ - int cn_flags; /**< Info about file descriptor */ - int cn_purpose; /**< Application-specific purpose */ -} conn_node_t; - -typedef TAILQ_HEAD(_conn_list_head, _conn_node) conn_list_head_t; - -static pthread_mutex_t conn_list_mutex = PTHREAD_MUTEX_INITIALIZER; -static conn_list_head_t conn_list_head = { NULL, &(conn_list_head.tqh_first) }; - -static inline conn_node_t *locate_node(int fd); - - -/** - * Insert a file descriptor with the given flags into our list. - * - * @param fd File descriptor to add - * @param flags Flags. Application specific. - * @see fdlist_add - * @return 0 - */ -int -clist_insert(int fd, int flags) -{ - conn_node_t *node; - - node = malloc(sizeof(*node)); - /* ASSERT(node); */ - memset(node,0,sizeof(*node)); - - node->cn_fd = fd; - node->cn_flags = flags; - node->cn_purpose = 0; - - pthread_mutex_lock(&conn_list_mutex); - clist_delete_nt(fd); - TAILQ_INSERT_HEAD(&conn_list_head, node, cn_entries); - pthread_mutex_unlock(&conn_list_mutex); - - return 0; -} - - -static inline int -clist_delete_nt(int fd) -{ - conn_node_t *curr; - - if ((curr = locate_node(fd))) { - TAILQ_REMOVE(&conn_list_head, curr, cn_entries); - free(curr); - return 0; - } - - return 1; -} - - -/** - * Delete a file descriptor from our connection list. - * - * @param fd The file descriptor to delete. - * @return 1 if not found, 0 if successful. - */ -int -clist_delete(int fd) -{ - int rv; - - pthread_mutex_lock(&conn_list_mutex); - rv = clist_delete_nt(fd); - pthread_mutex_unlock(&conn_list_mutex); - - return rv; -} - - -/** - Purge all entries in the connection list - */ -void -clist_purgeall(void) -{ - conn_node_t *curr; - - pthread_mutex_lock(&conn_list_mutex); - - while ((curr = conn_list_head.tqh_first)) { - TAILQ_REMOVE(&conn_list_head, curr, cn_entries); - close(curr->cn_fd); - free(curr); - } - - pthread_mutex_unlock(&conn_list_mutex); -} - - -/** - * Set all file descriptors in the connection list in a given fd_set. - * We close any file descriptors which have gone bad for any reason and remove - * them from our list. - * - * @param set The file descriptor set to modify. - * @param flags Flags to look for. - * @param purpose User or application-defined purpose to look for. - * @return Max file descriptor to pass to select. - */ -inline int -clist_fill_fdset(fd_set *set, int flags, int purpose) -{ - conn_node_t *curr; - fd_set test_fds; - struct timeval tv; - int max = -1; - - pthread_mutex_lock(&conn_list_mutex); - -top: - for (curr = conn_list_head.tqh_first; curr; - curr = curr->cn_entries.tqe_next) { - - if (flags && ((curr->cn_flags & flags) != flags)) - continue; - - if ((purpose != MSGP_ALL) && (curr->cn_purpose != purpose)) - continue; - - FD_ZERO(&test_fds); - FD_SET(curr->cn_fd, &test_fds); - tv.tv_sec = 0; - tv.tv_usec = 0; - if (select(curr->cn_fd + 1, &test_fds, &test_fds, NULL, - &tv) == -1) { - if (errno == EBADF || errno == EINVAL) { - clist_delete_nt(curr->cn_fd); - goto top; - } - } - - if (curr->cn_fd >= max) - max = curr->cn_fd; - - FD_SET(curr->cn_fd, set); - } - - pthread_mutex_unlock(&conn_list_mutex); - - return max; -} - - -/** - Locate a connection node. - - @param fd File descriptor to locate - @return Connection node correspond to fd or NULL - */ -static inline conn_node_t * -locate_node(int fd) -{ - conn_node_t *curr; - - for (curr = conn_list_head.tqh_first; curr; - curr = curr->cn_entries.tqe_next) { - - if (curr->cn_fd == fd) { - /* Move FD to front of list; lru file descriptors - move to end. */ - TAILQ_REMOVE(&conn_list_head, curr, cn_entries); - TAILQ_INSERT_HEAD(&conn_list_head, curr, cn_entries); - return curr; - } - } - - return NULL; -} - - -/** - * Determine the next set file descriptor in our connection list, given a - * set of file descriptors. O(n), but works. - * - * @param set File descriptor set to check into. - * @return -1 on failure or the number of the next set file - * descriptor if successful. - */ -inline int -clist_next_set(fd_set *set) -{ - int rv; - conn_node_t *curr; - - pthread_mutex_lock(&conn_list_mutex); - - for (curr = conn_list_head.tqh_first; curr; - curr = curr->cn_entries.tqe_next) { - - if (FD_ISSET(curr->cn_fd, set)) { - FD_CLR(curr->cn_fd, set); - rv = curr->cn_fd; - pthread_mutex_unlock(&conn_list_mutex); - return rv; - } - } - - pthread_mutex_unlock(&conn_list_mutex); - - return -1; -} - - -/** - * Set a given file descriptor's purpose. - * - * @param fd File descriptor. - * @param purpose Application specific purpose ID - * @return -1 if not found, or 0 on success. - */ -inline int -clist_set_purpose(int fd, int purpose) -{ - int rv = -1; - conn_node_t *curr; - - pthread_mutex_lock(&conn_list_mutex); - - if ((curr = locate_node(fd))) { - curr->cn_purpose = purpose; - rv = 0; - } - - pthread_mutex_unlock(&conn_list_mutex); - - return rv; -} - - -/** - * Get a given file descriptor's purpose. - * - * @param fd File descriptor. - * @return -1 if not found, the purpose id. - */ -inline int -clist_get_purpose(int fd) -{ - int rv = -1; - conn_node_t *curr; - - pthread_mutex_lock(&conn_list_mutex); - - if ((curr = locate_node(fd))) - rv = curr->cn_purpose; - - pthread_mutex_unlock(&conn_list_mutex); - - return rv; -} - - -/** - * Get a given file descriptor's purpose. - * - * @param fd File descriptor. - * @return -1 if not found, the purpose id. - */ -inline int -clist_get_flags(int fd) -{ - int rv = 0; - conn_node_t *curr; - - pthread_mutex_lock(&conn_list_mutex); - - if ((curr = locate_node(fd))) - rv = curr->cn_flags; - - pthread_mutex_unlock(&conn_list_mutex); - - return rv; -} - - -/** - Dump our list to stdout - */ - -#define printifflag(flag) if (curr->cn_flags & flag) printf(" " #flag) -void -clist_dump(void) -{ - conn_node_t *curr; - pthread_mutex_lock(&conn_list_mutex); - - for (curr = conn_list_head.tqh_first; curr; - curr = curr->cn_entries.tqe_next) { - - printf("File Descriptor %d:\n", curr->cn_fd); - if (curr->cn_flags) { - printf("* Flags: 0x%08x", curr->cn_flags); - - printifflag(MSG_OPEN); - printifflag(MSG_LISTEN); - printifflag(MSG_CONNECTED); - printifflag(MSG_WRITE); - printifflag(MSG_READ); - - printf("\n"); - } - - if (curr->cn_purpose != -1) - printf("* Purpose ID: %d\n", curr->cn_purpose); - printf("\n"); - } - - pthread_mutex_unlock(&conn_list_mutex); -} diff --git a/magma/lib/clist.h b/magma/lib/clist.h deleted file mode 100644 index 65d13c9..0000000 --- a/magma/lib/clist.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -*/ -/** @file - * Header for clist.c - */ -#ifndef _CLIST_H -#define _CLIST_H - -#include <sys/select.h> - -int clist_insert(int fd, int flags); -int clist_delete(int fd); -void clist_purgeall(void); -int clist_fill_fdset(fd_set *set, int flags, int purpose); -int clist_next_set(fd_set *set); -int clist_set_purpose(int fd, int purpose); -int clist_get_purpose(int fd); -int clist_get_flags(int fd); -int clist_multicast(void *msg, int len, int purpose); - -#endif diff --git a/magma/lib/fdops.c b/magma/lib/fdops.c deleted file mode 100644 index d98877f..0000000 --- a/magma/lib/fdops.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Wrapper functions around read/write/select to retry in the event - * of interrupts. - */ -#include <unistd.h> -#include <sys/types.h> -#include <fcntl.h> -#include <errno.h> - -/** - * This is a wrapper around select which will retry in the case we receive - * EINTR. This is necessary for _read_retry, since it wouldn't make sense - * to have _read_retry terminate if and only if two EINTRs were received - * in a row - one during the read() call, one during the select call... - * - * @see select(2) - */ -int -_select_retry(int fdmax, fd_set * rfds, fd_set * wfds, fd_set * xfds, - struct timeval *timeout) -{ - int rv; - - while (1) { - rv = select(fdmax, rfds, wfds, xfds, timeout); - if ((rv == -1) && (errno == EINTR)) - /* return on EBADF/EINVAL/ENOMEM; continue on EINTR */ - continue; - return rv; - } -} - -/** - * Retries a write in the event of a non-blocked interrupt signal. - * - * @param fd File descriptor to which we are writing. - * @param buf Data buffer to send. - * @param count Number of bytes in buf to send. - * @param timeout (struct timeval) telling us how long we should retry. - * @return The number of bytes written to the file descriptor, - * or -1 on error (with errno set appropriately). - */ -ssize_t -_write_retry(int fd, void *buf, int count, struct timeval * timeout) -{ - int n, total = 0, remain = count, rv = 0; - fd_set wfds, xfds; - - while (total < count) { - - /* Create the write FD set of 1... */ - FD_ZERO(&wfds); - FD_SET(fd, &wfds); - FD_ZERO(&xfds); - FD_SET(fd, &xfds); - - /* wait for the fd to be available for writing */ - rv = _select_retry(fd + 1, NULL, &wfds, &xfds, timeout); - if (rv == -1) - return -1; - else if (rv == 0) { - errno = ETIMEDOUT; - return -1; - } - - if (FD_ISSET(fd, &xfds)) { - errno = EPIPE; - return -1; - } - - /* - * Attempt to write to fd - */ - n = write(fd, buf + (off_t) total, remain); - - /* - * When we know our fd was select()ed and we receive 0 bytes - * when we write, the fd was closed. - */ - if ((n == 0) && (rv == 1)) { - errno = EPIPE; - return -1; - } - - if (n == -1) { - if ((errno == EAGAIN) || (errno == EINTR)) { - /* - * Not ready? - */ - continue; - } - - /* Other errors: EIO, EINVAL, etc */ - return -1; - } - - total += n; - remain -= n; - } - - return total; -} - -/** - * Retry reads until we (a) time out or (b) get our data. Of course, if - * timeout is NULL, it'll wait forever. - * - * @param sockfd File descriptor we want to read from. - * @param buf Preallocated buffer into which we will read data. - * @param count Number of bytes to read. - * @param timeout (struct timeval) describing how long we should retry. - * @return The number of bytes read on success, or -1 on failure. - Note that we will always return (count) or (-1). - */ -ssize_t -_read_retry(int sockfd, void *buf, int count, struct timeval * timeout) -{ - int n, total = 0, remain = count, rv = 0; - fd_set rfds, xfds; - - while (total < count) { - FD_ZERO(&rfds); - FD_SET(sockfd, &rfds); - FD_ZERO(&xfds); - FD_SET(sockfd, &xfds); - - /* - * Select on the socket, in case it closes while we're not - * looking... - */ - rv = _select_retry(sockfd + 1, &rfds, NULL, &xfds, timeout); - if (rv == -1) - return -1; - else if (rv == 0) { - errno = ETIMEDOUT; - return -1; - } - - if (FD_ISSET(sockfd, &xfds)) { - errno = EPIPE; - return -1; - } - - /* - * Attempt to read off the socket - */ - n = read(sockfd, buf + (off_t) total, remain); - - /* - * When we know our socket was select()ed and we receive 0 bytes - * when we read, the socket was closed. - */ - if ((n == 0) && (rv == 1)) { - errno = EPIPE; - return -1; - } - - if (n == -1) { - if ((errno == EAGAIN) || (errno == EINTR)) { - /* - * Not ready? Wait for data to become available - */ - continue; - } - - /* Other errors: EPIPE, EINVAL, etc */ - return -1; - } - - total += n; - remain -= n; - } - - return total; -} diff --git a/magma/lib/global.c b/magma/lib/global.c deleted file mode 100644 index 3d06d18..0000000 --- a/magma/lib/global.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * High level Magma APIs - */ -#include <stdio.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <stdint.h> -#include <dirent.h> -#include <magma.h> -#include <pthread.h> -#include <errno.h> -#include <magmamsg.h> -#include <unistd.h> -#include "clist.h" - -static cluster_plugin_t *_cpp = NULL; /** Default cluster plugin pointer */ -static char _connected = 0; /** Did we connect? */ -static pthread_rwlock_t dflt_lock = PTHREAD_RWLOCK_INITIALIZER; -static void _clu_set_default(cluster_plugin_t *cpp); -static void _clu_clear_default(void); - - -/** - Thread-safe wrapper using default plugin around cp_connect. - - @param groupname Node group to connect to. - @param login If set to nonzero, actually try to log in to the - node or service group. - @return A file descriptor on success; -1 on failure. - select(2) may be used to wait for events on this - file descriptor. - @see clu_disconnect - */ -int -clu_connect(char *groupname, int login) -{ - int e; - int fd; - - pthread_rwlock_wrlock(&dflt_lock); - if (_cpp) { - pthread_rwlock_unlock(&dflt_lock); - return -1; - } - - fd = cp_connect(&_cpp, groupname, login); - e = errno; - if (fd >= 0) { - _clu_set_default(_cpp); - _connected = 1; - } - - pthread_rwlock_unlock(&dflt_lock); - - /* Don't allow msg_close() to close this socket */ - /* XXX this should probably be removed and have the app do it */ - if (fd >= 0) - clist_insert(fd, MSG_CONNECTED); - else - errno = e; - return fd; -} - - -/** - Returns nonzero if the default plugin is initialized and we are connected - to a cluster infrastructure (or we think we are). - - @return 0 for not connected, 1 for connected. - */ -int -clu_connected(void) -{ - int ret; - - pthread_rwlock_rdlock(&dflt_lock); - ret = !!_connected; - pthread_rwlock_unlock(&dflt_lock); - - return ret; -} - - -/** - Disconnects from the cluster, cleans up, and unloads the default cluster - plugin. - - @return Should always return 0, but implementation dependent - based on the cluster plugin. - @see clu_connect - */ -int -clu_disconnect(int fd) -{ - int e, rv; - - if (fd >= 0) - clist_delete(fd); - - pthread_rwlock_wrlock(&dflt_lock); - if (_cpp) { - cp_logout(_cpp, fd); - cp_close(_cpp, fd); - rv = cp_unload(_cpp); - e = errno; - if (rv == 0) - _cpp = NULL; - _connected = 0; - } - pthread_rwlock_unlock(&dflt_lock); - - if (rv) - errno = e; - return rv; -} - - -/** - Wrapper around the default plugin for calling the null function. - */ -int -clu_null(void) -{ - int ret, e; - - pthread_rwlock_rdlock(&dflt_lock); - ret = cp_null(_cpp); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Obtain a list of cluster members given the group name. This should only - return the nodes which are both online and a member of the specified - group. Infrastructures which do not support the notion of node groups - should return the list of all cluster members. - - @param groupname Name of group - @return NULL on failure (see errno for reason), or a newly - allocated cluster_member_list_t pointer. - - */ -cluster_member_list_t * -clu_member_list(char *groupname) -{ - int e; - cluster_member_list_t * ret; - - pthread_rwlock_rdlock(&dflt_lock); - ret = cp_member_list(_cpp, groupname); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Obtain the cluster's status regarding quorum (e.g. quorate vs. not), as well - as whether or not the local node is a member of the specified group. - Infrastructures which do not support the notion of node groups - should return the list of all cluster members. - - @param groupname Name of group - @return -1 on failure (see errno for reason), or a mixture of - QF_QUORATE and QF_GROUPMEMBER flags. - - */ -int -clu_quorum_status(char *groupname) -{ - int ret, e; - - pthread_rwlock_rdlock(&dflt_lock); - ret = cp_quorum_status(_cpp, groupname); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Call the default plugin's version function. This can be used to find out - which cluster plugin is in use by applications, but should not actually - affect the operation of the application. - - @return Immutable cluster plugin version string. - */ -char * -clu_plugin_version(void) -{ - char *ret; - int e; - - pthread_rwlock_rdlock(&dflt_lock); - ret = cp_plugin_version(_cpp); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Obtain an event from the cluster file descriptor specified using the default - cluster plugin. If no events are waiting, this call may block. After an - event is received, it is up to the application to handle it properly. For - instance, when a membership change event occurs, it is up to the application - to attain a new membership list and update magmamsg's internal table (if in - use). See - @ref magma.h - for events. - - @param fd File descriptor to obtain event from. - @return Event identifier. - */ -int -clu_get_event(int fd) -{ - int ret, e; - - pthread_rwlock_rdlock(&dflt_lock); - ret = cp_get_event(_cpp, fd); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Open a connection to the cluster using the default plugin. This is not - needed if clu_connect is used. - - @return File descriptor on success, or -1 on failure. - @see clu_connect - */ -int -clu_open(void) -{ - int ret; - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_open(_cpp); - pthread_rwlock_unlock(&dflt_lock); - - if (ret >= 0) - clist_insert(ret, MSG_CONNECTED); - - return ret; -} - - -/** - Open a connection to the cluster using the default plugin. This is not - needed if clu_connect is used. - - @return File descriptor on success, or -1 on failure. - @see clu_connect - */ -int -clu_login(int fd, char *groupname) -{ - int ret, e; - - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_login(_cpp, fd, groupname); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Log out of the subscribed group using the default plugin. This is not - needed if clu_disconnect is used. - - @return File descriptor on success, or -1 on failure. - @see clu_disconnect - */ -int -clu_logout(int fd) -{ - int ret, e; - - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_logout(_cpp, fd); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Close a connection to the cluster using the default plugin. This is not - needed if clu_disconnect is used. - - @return File descriptor on success, or -1 on failure. - @see clu_open clu_connect - */ -int -clu_close(int fd) -{ - int ret, e; - - if (fd >= 0) - clist_delete(fd); - - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_close(_cpp, fd); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Fence a given cluster node via the default cluster plugin. This requires - the cluster_member_t structure because the infrastructure may use either - the node name or the node ID to perform the fencing operation. - - @param node cluster_member_t containing hostname/node ID of member - to fence. - @return 0 on success, other value on failure. - */ -int -clu_fence(cluster_member_t *node) -{ - int ret, e; - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_fence(_cpp, node); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Obtain a cluster lock using the default plugin. This uses a silly trick - for preventing starvation and ensuring other threads get a real chance to - get the lock. Basically, if we can't get the lock immediately and we were - called as a blocking lock call (that is, without the CLK_NOWAIT flag), we - sleep for a random few milliseconds. This keeps us from spinning waiting - for the lock, but can hurt performance when lock contention is fairly low - (i.e., the holder releases immediately after we go to sleep). - - @param resource Symbolic resource name to lock. - @param flags Locking flags / mode - @param lockpp Void pointer to opaque data structure which is - allocated and returned to the user. Infastructure - specific information should be returned. - @return 0 on success, other value on failure. - */ -int -clu_lock(char *resource, int flags, void **lockpp) -{ - int ret = 0, block = 0, conv = 0, err; - - block = !(flags & CLK_NOWAIT); - - /* - Bug 193128 - - Try to use a conversion lock mechanism when possible - If the caller calls explicitly with a NULL lock, then - assume the caller knows what it is doing. - - Only take the NULL lock if: - (a) the user isn't specifying CONVERT; if they are, they - know what they are doing. - - ...and one of... - - (b) This is a blocking call, or - (c) The user requested a NULL lock explicitly. In this case, - short-out early; there's no reason to convert a NULL lock - to a NULL lock. - */ - if (!(flags & CLK_CONVERT) && - (block || ((flags & CLK_EX) == 0))) { - /* Acquire NULL lock */ - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_lock(_cpp, resource, CLK_NULL, lockpp); - err = errno; - pthread_rwlock_unlock(&dflt_lock); - if (ret == 0) { - if ((flags & CLK_EX) == 0) { - /* User only wanted a NULL lock... */ - return 0; - } - /* - Ok, NULL lock was taken, rest of blocking - call should be done using lock conversions. - */ - flags |= CLK_CONVERT; - conv = 1; - } else { - switch(err) { - case EINVAL: - /* Oops, null locks don't work on this - plugin; use normal spam mode */ - break; - default: - errno = err; - return -1; - } - } - } - - while (1) { - /* - printf("upgrading to requested lock %04x...\n", flags); - */ - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_lock(_cpp, resource, - flags | CLK_NOWAIT, lockpp); - err = errno; - pthread_rwlock_unlock(&dflt_lock); - - if ((ret != 0) && (err == EAGAIN) && block) { - usleep(random()&32767); - continue; - } - - break; - } - - if (ret != 0 && conv) { - /* If we get some other error, release the NL lock we - took so we don't leak locks*/ - pthread_rwlock_wrlock(&dflt_lock); - cp_unlock(_cpp, resource, lockpp); - pthread_rwlock_unlock(&dflt_lock); - errno = err; - } - - return ret; -} - - -/** - Release a cluster lock using the default plugin. This uses a silly trick - for preventing starvation and ensuring other threads get a real chance to - get the lock. We sleep for a random few milliseconds to allow other - threads which might be sleeping in clu_lock a chance to get the lock. - Most of the time, they will get the lock before us. This is not very - good for performance, but prevents starvation and provides a thread - safe interface without the need for an inter-thread queue as part of - the magma library. - - @param resource Symbolic resource name to unlock. - @param lockp Opaque data structure which was allocated and - by clu_lock. Frees this structure. - @return 0 on success, other value on failure. - */ -int -clu_unlock(char *resource, void *lockp) -{ - int ret, err; - - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_unlock(_cpp, resource, lockp); - err = errno; - pthread_rwlock_unlock(&dflt_lock); - usleep(random()&32767); - - errno = err; - return ret; -} - - -static void -_clu_set_default(cluster_plugin_t *cpp) -{ - _cpp = cpp; -} - - -/** - Make the specified plugin structure the default plugin for all of the - clu_* calls. Not needed if clu_connect is used. - - @param cpp cluster_plugin_t to make default. - @see clu_connect - */ -void -clu_set_default(cluster_plugin_t *cpp) -{ - pthread_rwlock_wrlock(&dflt_lock); - _clu_set_default(cpp); - pthread_rwlock_unlock(&dflt_lock); -} - - -static void -_clu_clear_default(void) -{ - _cpp = NULL; -} - - -/** - Clear out the default plugin. Not needed if clu_disconnect is used. - - @see clu_disconnect - */ -void -clu_clear_default(void) -{ - pthread_rwlock_wrlock(&dflt_lock); - _clu_clear_default(); - pthread_rwlock_unlock(&dflt_lock); -} - - -/** - Returns the local node name using the default plugin as the data source. - This function caches this information in the default plugin structure - for future use. - - @param groupname Group name. If the local node is not a member - of this group, the call will fail. - @param name Preallocated char array into which the local member's - node name is copied. - @param namelen Size, in bytes, of name parameter. - @return 0 on success, or -1 if the node is not a member of - the specified group. - @see clu_local_nodeid cp_local_nodename - */ -int -clu_local_nodename(char *groupname, char *name, size_t namelen) -{ - int ret, e; - - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_local_nodename(_cpp, groupname, name, namelen); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - - -/** - Returns the local node ID using the default plugin as the data source. - This function caches this information in the default plugin structure - for future use. - - @param groupname Group name. If the local node is not a member - of this group, the call will fail. - @param nodeid Pointer to node ID (uint64_t). Node ID - is copied in here. - @return 0 on success, or -1 if the node is not a member of - the specified group. - */ -int -clu_local_nodeid(char *groupname, uint64_t *nodeid) -{ - int ret, e; - - pthread_rwlock_wrlock(&dflt_lock); - ret = cp_local_nodeid(_cpp, groupname, nodeid); - e = errno; - pthread_rwlock_unlock(&dflt_lock); - - errno = e; - return ret; -} - diff --git a/magma/lib/ip_lookup.c b/magma/lib/ip_lookup.c deleted file mode 100644 index abd6d01..0000000 --- a/magma/lib/ip_lookup.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - Replacement for if_lookup using netlink instead of ioctls. This is used - to aid determination of the local node ID. - */ -#include <asm/types.h> -#include <sys/types.h> -#include <arpa/inet.h> -#include <sys/socket.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <netdb.h> -#include <sys/queue.h> - -typedef struct _ip_address { - TAILQ_ENTRY(_ip_address) ipa_entries; - char ipa_family; - char *ipa_address; -} ip_addr_t; - -typedef TAILQ_HEAD(_ip_list, _ip_address) ip_list_t; - - -static int -send_addr_dump(int fd, int family) -{ - struct nlmsghdr *nh; - struct rtgenmsg *g; - char buf[256]; - struct sockaddr_nl addr; - - memset(&addr,0,sizeof(addr)); - addr.nl_family = AF_NETLINK; - - memset(buf, 0, sizeof(buf)); - nh = (struct nlmsghdr *)buf; - g = (struct rtgenmsg *)(buf + sizeof(struct nlmsghdr)); - - nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); - nh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP; - nh->nlmsg_type = RTM_GETADDR; - g->rtgen_family = family; - - return sendto(fd, buf, nh->nlmsg_len, 0, (struct sockaddr *)&addr, - sizeof(addr)); -} - - -static int -add_ip(ip_list_t *ipl, char *ipaddr, char family) -{ - ip_addr_t *ipa; - - ipa = malloc(sizeof(*ipa)); - memset(ipa, 0, sizeof(*ipa)); - ipa->ipa_family = family; - ipa->ipa_address = strdup(ipaddr); - - TAILQ_INSERT_TAIL(ipl, ipa, ipa_entries); - - return 0; -} - - -static int -add_ip_addresses(int family, ip_list_t *ipl) -{ - /* List ipv4 addresses */ - struct nlmsghdr *nh; - struct ifaddrmsg *ifa; - struct rtattr *rta, *nrta; - struct nlmsgerr *err; - char buf[10240]; - char outbuf[256]; - int x, fd, len; - - fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); - if (fd < 0) { - perror("socket"); - exit(1); - } - - send_addr_dump(fd, family); - memset(buf, 0, sizeof(buf)); - x = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0); - if (x < 0) { - perror("recvfrom"); - return -1; - } - - nh = (struct nlmsghdr *)buf; - while (NLMSG_OK(nh, x)) { - - switch(nh->nlmsg_type) { - case NLMSG_DONE: - close(fd); - return 0; - - case NLMSG_ERROR: - err = (struct nlmsgerr*)NLMSG_DATA(nh); - if (nh->nlmsg_len < - NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated"); - } else { - errno = -err->error; - perror("RTNETLINK answers"); - } - close(fd); - return -1; - - case RTM_NEWADDR: - break; - - default: - nh = NLMSG_NEXT(nh, x); - continue; - } - - /* RTM_NEWADDR */ - len = NLMSG_PAYLOAD(nh,0); - ifa = NLMSG_DATA(nh); - - /* Make sure we got the type we expect back */ - if (ifa->ifa_family != family) { - nh = NLMSG_NEXT(nh, x); - continue; - } - - rta = (struct rtattr *)((void *)ifa + sizeof(*ifa)); - len -= sizeof(*ifa); - do { - /* Make sure we've got a valid rtaddr field */ - if (!RTA_OK(rta, len)) - break; - - if (rta->rta_type == IFA_ADDRESS || - rta->rta_type == IFA_BROADCAST) { - inet_ntop(family, RTA_DATA(rta), outbuf, - sizeof(outbuf) ); - add_ip(ipl, outbuf, family); - } - - if (rta->rta_type == IFA_LABEL) { - printf("label: %s\n", (char *)RTA_DATA(rta)); - } - - nrta = RTA_NEXT(rta, len); - if (!nrta) - break; - - len -= ((void *)nrta - (void *)rta); - rta = nrta; - } while (RTA_OK(rta, len)); - - nh = NLMSG_NEXT(nh, x); - } - - close(fd); - return 0; -} - - -static int -search_ip_list(ip_list_t *ipl, char *ip_name) -{ - ip_addr_t *ipa; - - ipa = ipl->tqh_first; - for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) { - if (!strcmp(ip_name, ipa->ipa_address)) { - return 0; - } - } - return 1; -} - - -static inline int -free_ip_list(ip_list_t *ipl) -{ - ip_addr_t *ipa; - - while ((ipa = ipl->tqh_first)) { - TAILQ_REMOVE(ipl, ipa, ipa_entries); - free(ipa->ipa_address); - free(ipa); - } - return 0; -} - - -static inline int -build_ip_list(ip_list_t *ipl) -{ - if (add_ip_addresses(AF_INET6, ipl) < 0) { - free_ip_list(ipl); - return -1; - } - if (add_ip_addresses(AF_INET, ipl) < 0) { - free_ip_list(ipl); - return -1; - } - return 0; -} - - -/** - Look up the interface name which corresponds to the given hostname and - return the list of matching attrinfo structures. We do this by looking - up all the possible physical and virtual network interfaces on the machine - and checking the hostname/IP mappings for each active IP address incurred. - - @param nodename Interface name - @param ret_ai Structure pointer to allocate & return. - @return -1 on failure or 0 on success. - */ -int -ip_lookup(char *nodename, struct addrinfo **ret_ai) -{ - char ip_name[256]; - struct addrinfo *ai = NULL; - struct addrinfo *n; - void *p; - ip_list_t ipl; - int ret = -1; - - /* Build list of IP addresses configured locally */ - TAILQ_INIT(&ipl); - if (build_ip_list(&ipl) < 0) - return -1; - - /* Get list of addresses for the host-name/ip */ - if (getaddrinfo(nodename, NULL, NULL, &ai) != 0) - return -1; - - /* Traverse list of addresses for given host-name/ip */ - for (n = ai; n; n = n->ai_next) { - if (n->ai_family != AF_INET && n->ai_family != AF_INET6) - continue; - - if (n->ai_family == AF_INET) - p = &(((struct sockaddr_in *)n->ai_addr)->sin_addr); - else - p = &(((struct sockaddr_in6 *)n->ai_addr)->sin6_addr); - - if (!inet_ntop(n->ai_family, p, ip_name, - sizeof(ip_name))) - continue; - - /* Search local interfaces for this IP address */ - if (search_ip_list(&ipl, ip_name) != 0) - continue; - - /* Found it */ - ret = 0; - break; - } - - /* Clean up */ - if (!ret_ai) - freeaddrinfo(ai); - else - *ret_ai = ai; - - free_ip_list(&ipl); - - return ret; -} - diff --git a/magma/lib/ip_lookup.h b/magma/lib/ip_lookup.h deleted file mode 100644 index a1016d6..0000000 --- a/magma/lib/ip_lookup.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -*/ -/** @file - * Header for ip_lookup.c - */ -#ifndef _IP_LOOKUP_H -#define _IP_LOOKUP_H - -int ip_lookup(char *, struct addrinfo **); - -#endif diff --git a/magma/lib/localinfo.c b/magma/lib/localinfo.c deleted file mode 100644 index e95e42e..0000000 --- a/magma/lib/localinfo.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - Local information lookup code for Magma. - */ -#include <magma.h> -#include <stdint.h> -#include <ip_lookup.h> -#include <string.h> - -static int -_get_local_info(cluster_plugin_t *cpp, char *groupname) -{ - int x, ret = -1; - cluster_member_list_t *members; - - if (cpp->cp_private.p_localid != NODE_ID_NONE) { - return 0; - } - - members = cp_member_list(cpp, groupname); - - if (!members) - return -1; - - for (x=0; x < members->cml_count; x++) { - if (ip_lookup(members->cml_members[x].cm_name, NULL) == 0) { - cpp->cp_private.p_localid = - members->cml_members[x].cm_id; - strncpy(cpp->cp_private.p_localname, - members->cml_members[x].cm_name, - sizeof(cpp->cp_private.p_localname)-1); - ret = 0; - break; - } - } - - free(members); - - return ret; -} - - -/** - Returns the local node name using the given plugin as the data source. - This function caches this information in the provided cpp plugin structure - for future use. - - @param cpp Cluster plugin structure. Should already be opened, - but does not need to be logged in to a group. - @param groupname Group name. If the local node is not a member - of this group, the call will fail. - @param name Preallocated char array into which the local member's - node name is copied. - @param namelen Size, in bytes, of name parameter. - @return 0 on success, or -1 if the node is not a member of - the specified group. - */ -int -cp_local_nodename(cluster_plugin_t *cpp, char *groupname, char *name, - size_t namelen) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - if (cpp->cp_private.p_localid == NODE_ID_NONE) { - if (_get_local_info(cpp, groupname) < 0) { - return -1; - } - } - - strncpy(name, cpp->cp_private.p_localname, namelen); - - return 0; -} - - -/** - Returns the local node ID using the given plugin as the data source. - This function caches this information for future use. - - @param cpp Cluster plugin structure. Should already be opened, - but does not need to be logged in to a group. - @param groupname Group name. If the local node is not a member - of this group, the call will fail. - @param nodeid Pointer to node ID (uint64_t). Node ID - is copied in here. - @return 0 on success, or -1 if the node is not a member of - the specified group. - */ -int -cp_local_nodeid(cluster_plugin_t *cpp, char *groupname, - uint64_t *nodeid) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - if (cpp->cp_private.p_localid == NODE_ID_NONE) { - if (_get_local_info(cpp, groupname) < 0) { - return -1; - } - } - - *nodeid = cpp->cp_private.p_localid; - - return 0; -} diff --git a/magma/lib/magma-build.h b/magma/lib/magma-build.h deleted file mode 100644 index c9c6f37..0000000 --- a/magma/lib/magma-build.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Definitions for implementing cluster infrastructure plugins; should not - * be included by user programs directly. - */ -#ifndef _MAGMA_BUILD_H -#define _MAGMA_BUILD_H - -#ifndef _CLUSTER_ -#error "Never include this file from user programs." -#endif - -#define CLUSTER_PLUGIN_API_VERSION (double)0.00013 - -#ifndef PLUGINDIR -#define PLUGINDIR "/usr/lib/magma" -#endif - -#ifndef MAGMACONF -#define MAGMACONF "/etc/cluster/magma.conf" -#endif - -#define IMPORT_PLUGIN_API_VERSION() \ -double cluster_plugin_version(void) \ -{\ - return CLUSTER_PLUGIN_API_VERSION;\ -} - - -/** - * Module symbols & definitions - */ -#define CLU_PLUGIN_LOAD cluster_plugin_load -#define CLU_PLUGIN_INIT cluster_plugin_init -#define CLU_PLUGIN_UNLOAD cluster_plugin_unload -#define CLU_PLUGIN_VERSION cluster_plugin_version - -#define CLU_PLUGIN_LOAD_SYM "cluster_plugin_load" -#define CLU_PLUGIN_INIT_SYM "cluster_plugin_init" -#define CLU_PLUGIN_UNLOAD_SYM "cluster_plugin_unload" -#define CLU_PLUGIN_VERSION_SYM "cluster_plugin_version" - - - -/** - * Handy macros - */ -#define CP_IMP(ptr, func) (ptr->cp_ops.s_##func != _U_clu_##func) -#define CP_UNIMP(ptr, func) (ptr->cp_ops.s_##func != _U_clu_##func) -#define CP_SET_UNIMP(ptr, func) (ptr->cp_ops.s_##func = _U_clu_##func) - - -/** - * Cluster plugin object. This is returned by cp_load(char *filename) - * It is up to the user to call cp_init(cluster_plugin_t *) - */ -typedef struct _cluster_plugin { - /** - * Plugin functions. - */ - struct { - /** - No op cluster function. Optional; maps to clu_null - in the default cluster plugin. - - @see clu_null - */ - int (*s_null)(struct _cluster_plugin *); - - /** - Cluster member list function. Required; maps to - clu_member_list in the default cluster plugin. - - @see clu_member_list - */ - cluster_member_list_t * - (*s_member_list)(struct _cluster_plugin *, char *); - - /** - Cluster quorum status function. Required; maps to - clu_quorum_status in the default cluster plugin. - - @see clu_quorum_status - */ - int (*s_quorum_status)(struct _cluster_plugin *, char *); - - /** - Cluster event reading function. Required; maps to - clu_get_event in the default cluster plugin. - - @see clu_get_event - */ - int (*s_get_event)(struct _cluster_plugin *,int); - - /** - Cluster plugin version function. Optional; maps to - clu_plugin_version in the default cluster plugin. - - @see clu_plugin_version - */ - char *(*s_plugin_version)(struct _cluster_plugin *); - - /** - Cluster plugin open function. Required; maps to clu_open - when a default cluster plugin is used. Though required, - this is not generally called directly, as clu_connect handles - this.. - - @see clu_open, clu_connect - */ - int (*s_open)(struct _cluster_plugin *); - - /** - I/O Fencing function. Optional; maps to clu_fence. - - @see clu_fence - */ - int (*s_fence)(struct _cluster_plugin *, cluster_member_t *); - - /** - Group Login function. Optional; maps to clu_login when - a default plugin is set. Not generally called by users; - clu_connect takes care of this for us. - - @see clu_login, clu_connect - */ - int (*s_login)(struct _cluster_plugin *, int, char *); - - /** - Group Logout function. Optional; maps to clu_logout when - a default plugin is set. Not generally called by users; - clu_disconnect takes care of this for us. - - @see clu_logout, clu_disconnect - */ - int (*s_logout)(struct _cluster_plugin *,int); - - /** - Cluster plugin open function. Required; maps to clu_close_ - when a default cluster plugin is used. Though required, - this is not generally called directly, as clu_connect handles - this. - - @see clu_close, clu_disconnect - */ - int (*s_close)(struct _cluster_plugin *,int); - - /** - Cluster lock function. Optional; maps to clu_lock when - a default cluster plugin is used. - - @see clu_lock - */ - int (*s_lock)(struct _cluster_plugin *, char *, int, void **); - - /** - Cluster unlock function. Optional; maps to clu_unlock when - a default cluster plugin is used. - - @see clu_unlock - */ - int (*s_unlock)(struct _cluster_plugin *, char *, void *); - } cp_ops; - - /** - * Private data. - */ - struct { - /** - * Node ID (cache) - */ - uint64_t p_localid; - - /** - * Node name (cache) - */ - char p_localname[64]; - - /** - * Handle we obtained from dlopen() - */ - void *p_dlhandle; - - /** - * Plugin load function. Generally, just sets up function - * pointers. - */ - int (*p_load_func)(struct _cluster_plugin *); - - /** - * Initialization function. Generally, the last two - * arguments are left as NULL, 0; they are there primarily - * for testing. - */ - int (*p_init_func)(struct _cluster_plugin *, const void *, - size_t); - - /** - * De-initialization+unload function. - */ - int (*p_unload_func)(struct _cluster_plugin *); - - /** - * Plugin-specific private data. Can be anything; - * implementation specific. - */ - void *p_data; - - /** - * Plugin-specific private data length. - */ - size_t p_datalen; - } cp_private; -} cluster_plugin_t; - - -/** - * plugin.c: All objects start off with these functions assigned to their - * member functions. These should not be called directly. - */ -int _U_clu_null(cluster_plugin_t *); -cluster_member_list_t *_U_clu_member_list(cluster_plugin_t *, char *); /* FREE ME! */ -int _U_clu_quorum_status(cluster_plugin_t *, char *); -char *_U_clu_plugin_version(cluster_plugin_t *); -int _U_clu_get_event(cluster_plugin_t *,int); -int _U_clu_open(cluster_plugin_t *); -int _U_clu_login(cluster_plugin_t *, int, char *); -int _U_clu_logout(cluster_plugin_t *, int); -int _U_clu_fence(cluster_plugin_t *, cluster_member_t *); -int _U_clu_close(cluster_plugin_t *, int); -int _U_clu_lock(cluster_plugin_t *, char *, int, void **); -int _U_clu_unlock(cluster_plugin_t *, char *, void *); - -#endif /* _MAGMA_BUILD_H */ diff --git a/magma/lib/magma.h b/magma/lib/magma.h deleted file mode 100644 index 0d08a7b..0000000 --- a/magma/lib/magma.h +++ /dev/null @@ -1,484 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - Header for Magma Cluster API Library - */ -#ifndef _MAGMA_H -#define _MAGMA_H - -#include <stdlib.h> -#include <stdint.h> -#include <errno.h> - -#define _MAX_SIZE 256 /** Altering this is hazardous to your health */ - -typedef struct _cluster_member { - uint64_t cm_id; /** Node ID */ - char cm_name[_MAX_SIZE]; /** Node name */ - uint8_t cm_state; /** Node state */ - uint8_t cm_pad[7]; /** Align this */ - struct addrinfo *cm_addrs; /** Node IP addresses */ -} cluster_member_t; - -typedef struct _cluster_member_list { - char cml_groupname[_MAX_SIZE]; /** Group name */ - uint32_t cml_count; /** Node count */ - uint8_t cml_pad[4]; /** Align this */ - cluster_member_t cml_members[0]; /** Node array */ -} cluster_member_list_t; - -#define cml_size(c) \ - (sizeof(cluster_member_list_t) + \ - sizeof(cluster_member_t) * c) - -#define cml_alloc(size) malloc(cml_size(size)) - - -/* don't call this from within modules. */ -void cml_free(cluster_member_list_t *ml); -cluster_member_list_t *cml_dup(cluster_member_list_t *ml); - - -#ifdef DEBUG -#ifndef dbg_printf -#define dbg_printf(fmt, args...) printf("DEBUG: " fmt, ##args) -#endif -#else -#ifndef dbg_dprintf -#define dbg_dprintf(fmt, args...) -#endif -#endif - - -#define clu_perror(func, ret) \ - fprintf(stderr, "%s: %s\n", func, strerror(-ret)) - -/* - * Member states - */ -#define STATE_DOWN 0 /** Node is not online or is not in - the given group. */ -#define STATE_UP 1 /** Node is online and/or is in the - given group */ -#define STATE_INVALID 2 /** Unknown state */ - - -/** - * Quorum/Group states - */ -#define QF_NONE (0) /** Not quorate. Unsafe to run */ -#define QF_QUORATE (1<<0) /** Quorate. Safe to run */ -#define QF_GROUPMEMBER (1<<1) /** Member of group. App specific */ - -#define is_quorate(i) (i&QF_QUORATE) -#define is_group_member(i) (i&QF_GROUPMEMBER) -#define is_safe(i) (isquorate(i) && is_group_member(i)) - - -/* - * Events we need to handle - */ -#define CE_NULL 0 /** No-op/spurious wakeup */ -#define CE_MEMB_CHANGE 1 /** Membership change/transition */ -#define CE_QUORATE 2 /** AKA Quorum formed */ -#define CE_INQUORATE 3 /** AKA Quorum dissolved */ -#define CE_SHUTDOWN 4 /** Clean shutdown please */ -#define CE_SUSPEND 5 /** Pause; next event unpauses */ - - -/** - * Lock flags - */ -#define CLK_NONE (0) /** No flags */ -#define CLK_NOWAIT (1<<0) /** Do not block if not immediately available */ -#define CLK_WRITE (1<<1) /** Write lock */ -#define CLK_READ (1<<2) /** Read lock */ -#define CLK_HOLDER (1<<3) /** Return the holder node ID if lock is held*/ -#define CLK_CONVERT (1<<4) /** Convert this lock to a new type (may not - be supported on all plugins; caller - must be aware of this fact */ -#define CLK_EX (CLK_READ|CLK_WRITE) /** Exclusive lock */ -#define CLK_NULL (0) /** No bits set */ - - -#define NODE_ID_NONE ((uint64_t)-1) /** The nonexistent cluster member */ - - -/** - * User programs should not manipulate the ccluster_plugin_t structure, - * so we have it as a void pointer in user programs. - */ -#ifndef _CLUSTER_ - -typedef void cluster_plugin_t; - -#else - -#include <magma-build.h> - -#endif - - -/* - * plugin.c: Load/unload functions - */ -int cp_connect(cluster_plugin_t **cpp, char *groupname, int login); -cluster_plugin_t *cp_load(const char *libpath); -const char *cp_load_error(int e); -int cp_init(cluster_plugin_t *cpp, const void *priv, size_t privlen); -int cp_unload(cluster_plugin_t *cpp); - -/* - * plugin.c: Wrappers to call member functions of a given driver struct - */ -int cp_null(cluster_plugin_t *); -cluster_member_list_t * cp_member_list(cluster_plugin_t *, char *); -int cp_quorum_status(cluster_plugin_t *, char *); -char *cp_plugin_version(cluster_plugin_t *); - -int cp_open(cluster_plugin_t *); -int cp_login(cluster_plugin_t *, int, char *name); -int cp_get_event(cluster_plugin_t *, int); -int cp_logout(cluster_plugin_t *, int); -int cp_close(cluster_plugin_t *, int); -int cp_fence(cluster_plugin_t *, cluster_member_t *); - -int cp_lock(cluster_plugin_t *, char *, int, void **); -int cp_unlock(cluster_plugin_t *, char *, void*); -int cp_local_nodename(cluster_plugin_t *, char *, char *, size_t); -int cp_local_nodeid(cluster_plugin_t *, char *, uint64_t *); - - -/* - * global.c: Set/clear default driver structure - */ -void clu_set_default(cluster_plugin_t *driver); -void clu_clear_default(void); - - -/* - * global.c: Wrappers around default object, if one exists. All of these - * calls are protected by a mutex, so use wisely. - */ -int clu_null(void); -cluster_member_list_t * clu_member_list(char *); -int clu_quorum_status(char *); -char *clu_plugin_version(void); -int clu_get_event(int); - -/* People who use the high-level APIs ought to just use clu_connect and - clu_disconnect; these are provided for completeness. */ -int clu_open(void); -int clu_close(int); -int clu_login(int, char *); -int clu_logout(int); - -/* These Don't require being logged in. */ -int clu_lock(char *resource, int flags, void **lockinfo); -int clu_unlock(char *resource, void *lockinfo); - - -/* - * global.c: High-level connect/disconnect. Sets up default and disconnects - * from the same. - */ -int clu_connect(char *, int); /** Search for and log in to whatever we find */ -int clu_disconnect(int); /** Log out of whatever module we loaded */ -int clu_connected(void); /** are we successfully connected? */ -int clu_fence(cluster_member_t *); /** Fence a member. Don't do this unless - you know what you're doing */ - - -/* - * localinfo.c: High-level local node info (name, ID). - */ -int clu_local_nodename(char *, char *, size_t); -int clu_local_nodeid(char *, uint64_t *); - -/* - * memberlist.c: Membership deltas. - */ -cluster_member_list_t *memb_gained(cluster_member_list_t *old, - cluster_member_list_t *new_memb); -cluster_member_list_t *memb_lost(cluster_member_list_t *old, - cluster_member_list_t *new_memb); - -/* - * memberlist.c: Utilities for finding nodes - */ -int memb_online(cluster_member_list_t *nodes, uint64_t nodeid); -int memb_count(cluster_member_list_t *nodes); -uint64_t memb_name_to_id(cluster_member_list_t *nodes, char *nodename); -cluster_member_t *memb_name_to_p(cluster_member_list_t *nodes, char *nodename); -char *memb_id_to_name(cluster_member_list_t *nodes, uint64_t nodeid); -cluster_member_t *memb_id_to_p(cluster_member_list_t *nodes, uint64_t nodeid); -int memb_mark_down(cluster_member_list_t *nodes, uint64_t nodeid); - -/* - * Functions to resolve hostnames to ipv4/ipv6 addresses - */ -int memb_resolve(cluster_member_t *member); -int memb_resolve_list(cluster_member_list_t *newl, cluster_member_list_t *old); - -/* - * address.c: Utilities for dealing with addresses - */ -void print_member_list(cluster_member_list_t *list, int verbose); - -#endif /* _MAGMA_H */ - -/** \mainpage - -\section wtf What is Magma? -\par - Magma is an API library for communicating with different cluster - infrastructures. Originally, it was written to port Red Hat - Cluster Manager to the newer, more modern cluster infrastructures - which Sistina Software developed, namely, CMAN and GuLM. For now, - it is immensely important to operate on both infrastructures, given - that they are different architectures which solve slightly different - problems. -\par - Magma is designed as a self-configuring cluster switch, with the - goal ultimately being the ability for applications to run unmodified - on CMAN+DLM and GuLM. The API itself is primitive at best, and - should be thought of as a minimal set of functions necessary to - create a cluster-aware application. The API resembles the - API from Red Hat Cluster Manager. -\par - Magma is by no means restricted to the API(s) it currently has. - Indeed, it is a proof of concept that a self configuring cluster - switch can be created; it is not meant to obsolete other API(s). - It would be more interesting for magma to _provide_ other API(s). - -\section design Plugin Design considerations. - -\subsection All plugins must provide the following dl-mappable functions -(these are checked by cp_load using dlsym): -\par -\p cluster_plugin_load - Maps functions to pointers in new structure -\par -\p cluster_plugin_init - Sets up private data -\par -\p cluster_plugin_unload - Clears out private data and unmaps functions -\par -\p cluster_plugin_version - Returns the version of the implemented magma - plugin API. This can be inherited by placing: - "IMPORT_PLUGIN_API_VERSION()" near the top of your source code. - -\subsection missing Missing Functions in Plugins -\par - Plugins which do not implement a given function should leave - them alone; cp_load() maps all functions in a given - cluster_plugin_t object to be "unimplemented" versions, so - there is no danger of dereferencing NULL function pointers - when cp_load is used. - -\subsection unload Unloading Plugins -\par - When the caller calls cp_unload on a cluster plugin, it must be - fully cleaned up, logged out, and have all resources cleaned - up without further intervention of the caller. - -\subsection cs Coding Style -\par - Please use Linux-Kernel Coding Style. - -\subsection plugins Plugin Design Considerations -\par - Plugins should be designed as re-entrant entities with no global - variables defined. Any specific data should be stored in - plugin-specific private data structures and not accessed by the core - library. - -\section provide What Magma Provides for You -\subsection api High-level basic cluster functions -These functions are high-level, non-reentrant functions which may be used -to implement clustered applications. They are self-configuring, and operate -on a "default" cluster plugin which is loaded when the -\ref clu_connect -function is called for the first time. It is not necessary to log in to -a node or service group in order to obtain the member list of that group; -group login is primarily required for retrieving cluster events. Not all -infrastructures implement group membership; for these, all node/service groups -are the set of all nodes in the cluster. - -\par -\ref clu_connect -\par -\ref clu_disconnect -\par -\ref clu_member_list -\par -\ref clu_quorum_status -\par -\ref clu_fence -\par -\ref clu_get_event -\par -\ref cp_load - -\subsection locking Simple Cluster Locking API -These functions may be used after -\ref clu_connect -is called to create and release cluster locks on arbitrary, user-defined -resources. Logging in to a group is not necessary to take or release cluster -locks. -\par -\ref clu_lock -\par -\ref clu_unlock - -\subsection apire High-level basic cluster functions - Reentrant -These functions are lower level than the non-reentrant versions, and provide -a means of communicating with multiple different cluster infrastructures -running on one node. However, these functions are not self configuring, -and require a more effort to provide the same functionality as the -non-reentrant versions. Note that -\ref cp_load -is not reentrant, as it loads a plugin from the host file system. -\par -\ref cp_init -\par -\ref cp_member_list -\par -\ref cp_quorum_status -\par -\ref cp_fence -\par -\ref cp_get_event -\par -\ref cp_open -\par -\ref cp_close -\par -\ref cp_login -\par -\ref cp_logout - -\subsection lockingre Simple Cluster Locking API - Reentrant -These functions may be used after -\ref cp_load -, -\ref cp_init -, -and -\ref cp_open -are called to create and release cluster locks on arbitrary, user-defined -resources. Logging in to a group is not necessary to take or release -cluster locks. -\par -\ref cp_lock -\par -\ref cp_unlock - -\subsection local Local Node Identification Information -These functions allow applications to find out a node's identity according -to the cluster infrastructure. -\par -\ref clu_local_nodename -\par -\ref clu_local_nodeid - -\subsection localre Local Node Identification Information - Reentrant -These functions allow applications to find out a node's identity according -to the cluster infrastructure. -\par -\ref cp_local_nodename -\par -\ref cp_local_nodeid - - -\subsection membership Membership List Manipulation and Querying -These allow applications to find out information within membership lists, -alter lists, create new ones, find differences between two lists, and resolve -hostnames or addresses in a given list. -\par -\ref memb_gained -\par -\ref memb_lost -\par -\ref memb_online -\par -\ref memb_name_to_id -\par -\ref memb_name_to_p -\par -\ref memb_id_to_name -\par -\ref memb_id_to_p -\par -\ref memb_resolve -\par -\ref memb_resolve_list -\par -\ref cml_free -\par -\ref cml_dup -\par -\ref print_member_list - -\subsection messaging IPv4 / IPv6 abstracted TCP messaging functions -These APIs may be used to address nodes by node ID instead of names, and has -a high dependency on being up to date with -\ref msg_update -. The APIs themselves are part of libmagmamsg, which is licensed under -the GPL, as it is a derivative work of Kimberlite's messaging layer. Thus, -it will eventually need to either be rewritten or replaced by LGPL code. -\par -\ref msg_update -\par -\ref msg_listen -\par -\ref msg_open -\par -\ref msg_send -\par -\ref msg_receive -\par -\ref msg_receive_timeout -\par -\ref msg_accept -\par -\ref msg_close - -\section plugins Notes on Current Plugins - -\subsection gulm GuLM - The Grand Unified Lock Manager (gulm.so) -\par - This plugin does not have a notion of node groups. -\par - The locking system does not support multiple process-locks - on the same node. To get around this, we take a POSIX lock - on a file prior to asking for a lock from GuLM. - -\subsection cman CMAN - Using DLM to sync after transition (cman.so) -\par - This plugin does not have a notion of node groups. - -\subsection sm CMAN - Using the Service Manager (sm.so) -\par - This plugin uses two different methods to query node group - information. -\par - This is the only plugin which returns the CE_SUSPEND event. - Applications intending to use it should also be able to - operate without it for now. The CE_SUSPEND event is more - or less a barrier. -*/ diff --git a/magma/lib/magmamsg.h b/magma/lib/magmamsg.h deleted file mode 100644 index 85fb7a4..0000000 --- a/magma/lib/magmamsg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) Mission Critical Linux, Inc. 2000 - Copyright (C) Red Hat, Inc. 2002-2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - */ -#ifndef _MAGMACOMM_H -#define _MAGMACOMM_H -#include <magma.h> - -int msg_update(cluster_member_list_t *membership); -int msg_set_nodeid(uint64_t nodeid); -void msg_shutdown(void); -ssize_t msg_receive_timeout(int fd, void *buf, ssize_t count, - unsigned int timeout); -int msg_receive(int fd, void *buf, ssize_t buflen); -ssize_t msg_peek(int fd, void *buf, ssize_t buflen); -ssize_t msg_receive_timeout(int fd, void *buf, ssize_t count, - unsigned int timeout); -int msg_open(uint64_t nodeid, uint16_t baseport, int purpose, int timeout); -int msg_listen(uint16_t baseport, int purpose, int *ret, int retlen); -int msg_accept(int fd, int members_only, uint64_t *nodeid); -int msg_close(int fd); -int msg_fill_fdset(fd_set *set, int flags, int purpose); -int msg_next_fd(fd_set *set); -ssize_t msg_send(int fd, void *buf, ssize_t count); -int msg_set_purpose(int fd, int purpose); -int msg_get_purpose(int fd); -int msg_get_flags(int fd); - -#define MSG_OPEN 0x1 /** FD was opened by us somehow. */ -#define MSG_LISTEN 0x2 /** Set up with msg_listen */ -#define MSG_CONNECTED 0x4 /** Attained via msg_accept or msg_open */ -#define MSG_WRITE 0x8 /** Attained via msg_accept or msg_open */ -#define MSG_READ 0x10 /** Attained via msg_accept or msg_open */ -#define MSG_ALL 0x0 /** No set -> Don't care what flags exist */ - -#define MSGP_GENERIC 0 /** Default generic purpose. */ -#define MSGP_ALL -1 /** All defined purposes. */ -#define MSGP_CLUSTER -2 /** Cluster infrastructure FD only. */ - -#endif diff --git a/magma/lib/memberlist.c b/magma/lib/memberlist.c deleted file mode 100644 index 9f6a171..0000000 --- a/magma/lib/memberlist.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - Magma membership list handling routines. - */ -#include <magma.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <string.h> - -/** - Generate and return a list of members which are now online in a new - membership list, given the old membership list. User must call - @ref cml_free - to free the returned - @ref cluster_member_list_t - structure. - - @param old Old membership list - @param new New membership list - @return NULL if no members were gained, or a newly - allocated cluster_member_list_t structure. - */ -cluster_member_list_t * -memb_gained(cluster_member_list_t *old, cluster_member_list_t *new) -{ - int count, x, y; - char in_old = 0; - cluster_member_list_t *gained; - - /* No nodes in new? Then nothing could have been gained */ - if (!new || !new->cml_count) - return NULL; - - /* Nothing in old? Duplicate 'new' and return it. */ - if (!old || !old->cml_count) { - gained = cml_alloc(new->cml_count); - if (!gained) - return NULL; - memcpy(gained, new, cml_size(new->cml_count)); - return gained; - } - - /* Use greatest possible count */ - count = (old->cml_count > new->cml_count ? - cml_size(old->cml_count) : cml_size(new->cml_count)); - - gained = malloc(count); - if (!gained) - return NULL; - memset(gained, 0, count); - - for (x = 0; x < new->cml_count; x++) { - - /* This one isn't active at the moment; it could not have - been gained. */ - if (new->cml_members[x].cm_state != STATE_UP) - continue; - - in_old = 0; - for (y = 0; y < old->cml_count; y++) { - if ((new->cml_members[x].cm_id != - old->cml_members[y].cm_id) || - (old->cml_members[y].cm_state != STATE_UP)) - continue; - in_old = 1; - break; - } - - if (in_old) - continue; - memcpy(&gained->cml_members[gained->cml_count], - &new->cml_members[x], sizeof(cluster_member_t)); - - /* Don't copy this part over */ - gained->cml_members[gained->cml_count++].cm_addrs = NULL; - } - - if (gained->cml_count == 0) { - free(gained); - gained = NULL; - } - - return gained; -} - - -/** - Generate and return a list of members which are lost or no longer online - in a new membership list, given the old membership list. User must call - @ref cml_free - to free the returned - @ref cluster_member_list_t - structure. - - @param old Old membership list - @param new New membership list - @return NULL if no members were lost, or a newly - allocated cluster_member_list_t structure. - */ -cluster_member_list_t * -memb_lost(cluster_member_list_t *old, cluster_member_list_t *new) -{ - cluster_member_list_t *ret; - int x; - - /* Reverse. ;) */ - ret = memb_gained(new, old); - if (!ret) - return NULL; - - for (x = 0; x < ret->cml_count; x++) { - ret->cml_members[x].cm_state = STATE_DOWN; - } - - return ret; -} - - -/** - Find out if a given node ID is online in a membership list. In order for - this check to return '1' (true), the node must (a) exist in the membership - list and (b) must be in STATE_UP state. - - @param list List to search - @param nodeid Node ID to look for - @return 0 if node does not exist or is not STATE_UP, or 1 - if node is STATE_UP - */ -int -memb_online(cluster_member_list_t *list, uint64_t nodeid) -{ - int x; - - if (!list) - return 0; - - for (x = 0; x < list->cml_count; x++) { - if (list->cml_members[x].cm_id == nodeid && - list->cml_members[x].cm_state == STATE_UP) - return 1; - } - - return 0; -} - - -/** - Find a node's name given it's node ID in a membership list. - - @param list Member list to search - @param nodeid Node ID to look for - @return NULL if not found, "none" if the we were asked for - @ref NODE_ID_NONE - or the character pointer of the node name in list. - */ -char * -memb_id_to_name(cluster_member_list_t *list, uint64_t nodeid) -{ - int x; - - if (!list) - return NULL; - - if (nodeid == (uint64_t)-1) - return "none"; - - for (x = 0; x < list->cml_count; x++) { - if (list->cml_members[x].cm_id == nodeid && - list->cml_members[x].cm_state == STATE_UP) - return list->cml_members[x].cm_name; - } - - return NULL; -} - - -/** - Find a node's ID given it's node name in a membership list. - - @param list Member list to search - @param nodename Node name to look for - @return NODE_ID_NONE if not found, or the node ID - corresponding to nodename in the list. - */ -uint64_t -memb_name_to_id(cluster_member_list_t *list, char *nodename) -{ - int x; - - if (!list) - return (uint64_t)-1; - - for (x = 0; x < list->cml_count; x++) { - if (!strcmp(list->cml_members[x].cm_name, nodename) && - list->cml_members[x].cm_state == STATE_UP) - return list->cml_members[x].cm_id; - } - - return (uint64_t)-1; -} - - -/** - Find a node's structure pointer given it's node ID. - - @param list Member list to search - @param nodeid Node ID to look for - @return NULL if not found, or the address of the - cluster_member_t structure corresponding to nodeid. - */ -cluster_member_t * -memb_id_to_p(cluster_member_list_t *list, uint64_t nodeid) -{ - int x; - - if (!list || nodeid == NODE_ID_NONE) - return NULL; - - for (x = 0; x < list->cml_count; x++) { - if (list->cml_members[x].cm_id == nodeid && - list->cml_members[x].cm_state == STATE_UP) - return &list->cml_members[x]; - } - - return NULL; -} - - -/** - Find a node's structure pointer given it's name. - - @param list Member list to search - @param nodename Node name to look for - @return NULL if not found, or the address of the - cluster_member_t structure corresponding to nodename. - */ -cluster_member_t * -memb_name_to_p(cluster_member_list_t *list, char *nodename) -{ - int x; - - if (!list) - return NULL; - - for (x = 0; x < list->cml_count; x++) { - if (!strcmp(list->cml_members[x].cm_name, nodename) && - list->cml_members[x].cm_state == STATE_UP) - return &list->cml_members[x]; - } - - return NULL; -} - - -int -memb_mark_down(cluster_member_list_t *list, uint64_t nodeid) -{ - int x; - - if (!list) - return 0; - - for (x = 0; x < list->cml_count; x++) { - if (list->cml_members[x].cm_id == nodeid) { - list->cml_members[x].cm_state = STATE_DOWN; - return 0; - } - } - - return -1; -} - - -/** - Resolve a cluster member's address(es) using getaddrinfo. - - @param member Member to resolve. - @return -1 on getaddrinfo failure, or 0 on success - */ -int -memb_resolve(cluster_member_t *member) -{ - struct addrinfo ai; - - if (!member) - return -1; - - if (member->cm_addrs) - freeaddrinfo(member->cm_addrs); - member->cm_addrs = NULL; - - memset(&ai, 0, sizeof(ai)); - ai.ai_family = AF_UNSPEC; - ai.ai_flags = AI_CANONNAME; - /* - * Cluster-aware apps using magma must be stream-reachable. - */ - ai.ai_socktype = SOCK_STREAM; - - if (getaddrinfo(member->cm_name, NULL, &ai, &member->cm_addrs) != 0) { - member->cm_addrs = NULL; - return -1; - } - - return 0; -} - - -/** - Duplicate and return a cluster member list structure, sans the DNS resolution - information. - - @param orig List to duplicate. - @return NULL if there is nothing to duplicate or duplication - fails, or a newly allocated cluster_member_list_t - structure. - */ -cluster_member_list_t * -cml_dup(cluster_member_list_t *orig) -{ - int x; - cluster_member_list_t *ret = NULL; - - if (!orig) - return NULL; - - ret = malloc(cml_size(orig->cml_count)); - memset(ret, 0, cml_size(orig->cml_count)); - memcpy(ret, orig, cml_size(orig->cml_count)); - - /* Zero out the addrs */ - for (x = 0; x < ret->cml_count; x++) - ret->cml_members[x].cm_addrs = NULL; - - return ret; -} - - -/** - Find the number of nodes marked as STATE_UP in a membership list - - @param list List to search - @return Number of nodes marked as STATE_UP - */ -int -memb_count(cluster_member_list_t *list) -{ - int x, count = 0; - - for (x = 0; x < list->cml_count; x++) { - if (list->cml_members[x].cm_state == STATE_UP) - count++; - } - - return count; -} - - -/** - Resolve cluster members' hostnames->IP addresses. This gets a list of - all IP addresses and stores them in the cm_addr part of the - cluster_member_t structure; so you must free cluster_member_list_t * - with cml_free. This function uses "old" for hints about addresses: - if called with 'old' and 'old' has any addresses for members contained - within, they are *moved* to 'new'. This modifies both arguments, - beware. - - @param new New membership list - @param old Old membership list (or NULL) - @return 0 - */ -int -memb_resolve_list(cluster_member_list_t *new, cluster_member_list_t *old) -{ - cluster_member_t *nm, *om; - int x, y; - char found = 0; - - if (!new) - return -1; - - for (x = 0; x < new->cml_count; x++) { - - nm = &new->cml_members[x]; - - if (nm->cm_addrs) - continue; - - if (!old) { - memb_resolve(nm); - continue; - } - - /* Ok, look in the old list */ - found = 0; - for (y = 0; y < old->cml_count; y++) { - om = &old->cml_members[y]; - - if (om->cm_id != nm->cm_id) - continue; - - if (strcmp(om->cm_name, nm->cm_name)) - continue; - - /* We have a match, but no old-address */ - if (!om->cm_addrs) - break; - - /* Pointer movage. */ - nm->cm_addrs = om->cm_addrs; - om->cm_addrs = NULL; - found = 1; - break; - } - - if (found) - continue; - - /* Ok, not found in old list or no addresses present. - Do the dirty work. */ - memb_resolve(nm); - } - - return 0; -} - - -/** - Print a membership list structure to stdout. Primarily for debugging. - - @param list cluster_member_list_t structure to print - @param verbose Prints extra messages if set to nonzero - */ -void -print_member_list(cluster_member_list_t *list, int verbose) -{ - int x; - struct addrinfo *ai; - char ipaddr[256]; - void *p; - - if (!list || !list->cml_count) { - return; - } - - memb_resolve_list(list, NULL); - - if (verbose) - printf("+++ Dump of %p (%d nodes)\n", list, list->cml_count); - - for (x=0; x<list->cml_count; x++) { - - printf(" %s (id 0x%016llx) state ", - list->cml_members[x].cm_name, - (unsigned long long)list->cml_members[x].cm_id); - - if (list->cml_members[x].cm_state == STATE_UP) - printf("Up\n"); - else - printf("Down\n"); - - if (!list->cml_members[x].cm_addrs) - continue; - - for (ai = list->cml_members[x].cm_addrs; ai; ai = ai->ai_next){ - if (ai->ai_family == AF_INET) - p = &(((struct sockaddr_in *)ai->ai_addr)->sin_addr); - else if (ai->ai_family == AF_INET6) - p = &(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr); - else - continue; - - if (inet_ntop(ai->ai_family, p, ipaddr, - sizeof(ipaddr)) == NULL) - continue; - - printf(" - %s %s\n", ai->ai_canonname, ipaddr); - } - } - - if (verbose) - printf("--- Done\n"); -} - - -/** - Frees a cluster member list structure, including DNS/host resolution - information. - - @param ml Member list to free. - */ -void -cml_free(cluster_member_list_t *ml) -{ - int x; - - if (!ml) - return; - - for (x = 0; x < ml->cml_count; x++) { - if (ml->cml_members[x].cm_addrs) - freeaddrinfo(ml->cml_members[x].cm_addrs); - } - - free(ml); -} diff --git a/magma/lib/message.c b/magma/lib/message.c deleted file mode 100644 index 9edfe31..0000000 --- a/magma/lib/message.c +++ /dev/null @@ -1,922 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2004 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Super Simple TCP messaging for Magma. - * - * @author Jeff Moyer <jmoyer at redhat.com> - Original msg.c from Kimberlite - * @author Lon H. Hohberger <lhh at redhat.com> - IPv6, magma changes - */ -#include <magma.h> -#include <magmamsg.h> -#include <pthread.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <stdlib.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/types.h> -#include <netdb.h> -#include <endian.h> -#include <byteswap.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <arpa/inet.h> -#include "clist.h" - -#define IPV6_PORT_OFFSET 1 /** When binding an IPv6 port, increment by - this number so we don't conflict with the - IPv4 port. */ - -/* - From fdops.c - */ -int _select_retry(int fdmax, fd_set * rfds, fd_set * wfds, fd_set * xfds, - struct timeval *timeout); -ssize_t _read_retry(int sockfd, void *buf, int count, - struct timeval * timeout); -ssize_t _write_retry(int fd, void *buf, int count, struct timeval * timeout); - - -/* - We store a membership list with resolved addresses internally. - Yes, it's ugly. - */ -static pthread_mutex_t ml_mutex = PTHREAD_MUTEX_INITIALIZER; -static cluster_member_list_t *ml_membership; -static uint64_t _local_id = NODE_ID_NONE; - -/* Mutex to prevent - thread1 thread2 - create_socket - clist_insert - fill fd set - set_purpose - - This case would cause the new fd to appear - */ -static pthread_mutex_t fill_mutex = PTHREAD_MUTEX_INITIALIZER; - - -/** - Update the messaging service's internal membership list with the - provided list. Typically, this is called immediately after obtaining - a new membership list after a CE_MEMB_CHANGE has been received. - - Does NOT copy over resolved addresses; the caller may want to - reuse them for some reason on their list. - - @param membership New membership list - @return 0 on success, -1 on malloc failure - */ -int -msg_update(cluster_member_list_t *membership) -{ - pthread_mutex_lock(&ml_mutex); - - if (ml_membership) - cml_free(ml_membership); - - if (membership) { - ml_membership = cml_dup(membership); - } else { - ml_membership = NULL; - } - - pthread_mutex_unlock(&ml_mutex); - return 0; -} - - -int -msg_set_nodeid(uint64_t my_node_id) -{ - pthread_mutex_lock(&ml_mutex); - _local_id = my_node_id; - pthread_mutex_unlock(&ml_mutex); - return 0; -} - - -/** - Shut down the mssage subsystem. Closes all file descriptors and cleans up - the membership list. - */ -void -msg_shutdown(void) -{ - pthread_mutex_lock(&ml_mutex); - if (ml_membership) - cml_free(ml_membership); - pthread_mutex_unlock(&ml_mutex); - clist_purgeall(); -} - - -/** - Receive a message from a file descriptor. Relative of _msg_receive - from Kimberlite. - - @param fd File descriptor to read from. - @param buf Pre-allocated buffer to fill. - @param count Size of message expected. - @param tv Timeout value. - @return Size of read data, or -1 on failure - */ -static ssize_t -_msg_receive(int fd, void *buf, ssize_t count, - struct timeval *tv) -{ - if (fd < 0) { - errno = EBADF; - return -1; - } - - if (!(clist_get_flags(fd) & MSG_READ)) { - errno = EPERM; - return -1; - } - - return _read_retry(fd, buf, count, tv); -} - - -/** - Read a message from a file descriptor without specifying a timeout - value. Beware: this will wait forever for the amount of requested data - to be read. - - @param fd File descriptor to receive from - @param buf Pre-allocated buffer - @param count Size of expected message; must be <= size of - preallocated buffer. - @return -1 on failure or size of read data - @see _msg_receive, msg_receive_timeout - */ -int -msg_receive(int fd, void *buf, ssize_t count) -{ - return (_msg_receive(fd, buf, count, NULL)); -} - - -/** - Read a message from a file descriptor with a timeout value. - - @param fd File descriptor to receive from - @param buf Pre-allocated buffer - @param count Size of expected message; must be <= size of - preallocated buffer. - @param timeout Timeout, in seconds, to wait for data. - @return -1 on failure or size of read data - @see _msg_receive, msg_receive - */ -ssize_t -msg_receive_timeout(int fd, void *buf, ssize_t count, - unsigned int timeout) -{ - struct timeval tv; - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - return (_msg_receive(fd, buf, count, &tv)); -} - - -/** - Send a message to a file descriptor. - - @param fd File descriptor to send to - @param buf Buffer to send. - @param count Size of buffer to send. - @return Amount of data sent or -1 on error - */ -ssize_t -msg_send(int fd, void *buf, ssize_t count) -{ - if (fd == -1) { - errno = EBADF; - return -1; - } - - if (!(clist_get_flags(fd) & MSG_WRITE)) { - errno = EPERM; - return -1; - } - - return write(fd, buf, count); -} - - -/** - Connect in a non-blocking fashion to the designated address. - - @param fd File descriptor to connect - @param dest sockaddr (ipv4 or ipv6) to connect to. - @param len Length of dest - @param timeout Timeout, in seconds, to wait for a completed - connection. - @return 0 on success, -1 on failure. - */ -static int -connect_nb(int fd, struct sockaddr *dest, socklen_t len, int timeout) -{ - int ret, flags = 1, err; - unsigned l; - fd_set rfds, wfds; - struct timeval tv; - - /* - * Use TCP Keepalive - */ - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, - sizeof(flags))<0) - return -1; - - /* - Set up non-blocking connect - */ - flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); - - ret = connect(fd, dest, len); - - if ((ret < 0) && (errno != EINPROGRESS)) - return -1; - - if (ret != 0) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - FD_ZERO(&wfds); - FD_SET(fd, &wfds); - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - if (_select_retry(fd + 1, &rfds, &wfds, NULL, &tv) == 0) { - errno = ETIMEDOUT; - return -1; - } - - if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds)) { - l = sizeof(err); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, - (void *)&err, &l) < 0) { - close(fd); - return -1; - } - - if (err != 0) { - close(fd); - errno = err; - return -1; - } - - fcntl(fd, F_SETFL, flags); - return 0; - } - } - - errno = EIO; - return -1; -} - - -/** - Connect via ipv6 socket to a given IP address and port. - - @param in6_addr IPv6 address to connect to - @param port Port to connect to - @param timeout Timeout, in seconds, to wait for a completed - connection - @return 0 on success, -1 on failure - @see connect_nb, ipv4_connect - */ -static int -ipv6_connect(struct in6_addr *in6_addr, uint16_t port, int timeout, - cluster_member_t *me) -{ - struct sockaddr_in6 _sin6; - struct sockaddr_in6 srcaddr; - struct addrinfo *ai; - int fd, ret; - - fd = socket(PF_INET6, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - memset(&_sin6, 0, sizeof(_sin6)); - _sin6.sin6_family = AF_INET6; - _sin6.sin6_port = htons(port); - _sin6.sin6_flowinfo = 0; - memcpy(&_sin6.sin6_addr, in6_addr, sizeof(_sin6.sin6_addr)); - - if (me) { - /* if we know the local node, bind to its resolved - interface so other nodes don't reject the connection - due to improper source-routing */ - memset(&srcaddr, 0, sizeof(srcaddr)); - srcaddr.sin6_family = AF_INET6; - - for (ai = me->cm_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET6) - continue; - - if (ai->ai_socktype != SOCK_STREAM) - continue; - - memcpy(&((struct sockaddr_in6 *)&srcaddr)->sin6_addr, - &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, - sizeof(struct in6_addr)); - - bind(fd, (struct sockaddr *)&srcaddr, - sizeof(srcaddr)); - } - } - - ret = connect_nb(fd, (struct sockaddr *)&_sin6, sizeof(_sin6), timeout); - if (ret < 0) { - close(fd); - return -1; - } - return fd; -} - - -/** - Connect via ipv4 socket to a given IP address and port. - - @param in_addr IPv4 address to connect to - @param port Port to connect to - @param timeout Timeout, in seconds, to wait for a completed - connection - @return 0 on success, -1 on failure - @see connect_nb, ipv6_connect - */ -static int -ipv4_connect(struct in_addr *in_addr, uint16_t port, int timeout, - cluster_member_t *me) -{ - struct sockaddr_in _sin; - struct sockaddr_in srcaddr; - struct addrinfo *ai; - int fd, ret; - - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - if (me) { - /* if we know the local node, bind to its resolved - interface so other nodes don't reject the connection - due to improper source-routing */ - memset(&srcaddr, 0, sizeof(srcaddr)); - srcaddr.sin_family = AF_INET; - - for (ai = me->cm_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET) - continue; - - if (ai->ai_socktype != SOCK_STREAM) - continue; - - memcpy(&((struct sockaddr_in *)&srcaddr)->sin_addr, - &((struct sockaddr_in *)ai->ai_addr)->sin_addr, - sizeof(struct in_addr)); - - bind(fd, (struct sockaddr *)&srcaddr, - sizeof(srcaddr)); - } - } - - _sin.sin_family = AF_INET; - _sin.sin_port = htons(port); - memcpy(&_sin.sin_addr, in_addr, sizeof(_sin.sin_addr)); - - ret = connect_nb(fd, (struct sockaddr *)&_sin, sizeof(_sin), timeout); - if (ret < 0) { - close(fd); - return -1; - } - - return fd; -} - - -/** - Open a TCP connection to another cluster member given the node ID and the - base port. This first ties to use IPv6 to connect, and fails back to - IPv4. - - @param nodeid Node ID to connect to. - @param baseport Port to connect to. +1 if we end up using an ipv6 - address instead of an IPv4 one for a given member. - @param purpose User or application defined purpose. - @param timeout If specified, the connection attempt will abort - after this many seconds. - @return File descriptor, or -1 if couldn't connect. - @see ipv4_connect, ipv6_connect - */ -int -msg_open(uint64_t nodeid, uint16_t baseport, int purpose, int timeout) -{ - int fd; - cluster_member_t *nodep; - cluster_member_t *me; - struct addrinfo *ai; - - pthread_mutex_lock(&ml_mutex); - nodep = memb_id_to_p(ml_membership, nodeid); - if (!nodep) { - pthread_mutex_unlock(&ml_mutex); - errno = EINVAL; - return -1; - } - - me = memb_id_to_p(ml_membership, _local_id); - if (me) - memb_resolve(me); - - /* Try to resolve if we haven't done so */ - if (!nodep->cm_addrs && (memb_resolve(nodep) < 0)) { - pthread_mutex_unlock(&ml_mutex); - errno = EFAULT; - return -1; - } - - /* Try IPv6 first */ - for (ai = nodep->cm_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET6) - continue; - - if (ai->ai_socktype != SOCK_STREAM) - continue; - - fd = ipv6_connect( - &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, - baseport + IPV6_PORT_OFFSET, timeout, me); - - if (fd >= 0) { - pthread_mutex_unlock(&ml_mutex); - - pthread_mutex_lock(&fill_mutex); - clist_insert(fd, MSG_OPEN | MSG_CONNECTED | - MSG_READ | MSG_WRITE); - clist_set_purpose(fd, purpose); - pthread_mutex_unlock(&fill_mutex); - return fd; - } - } - - /* Try IPv4 */ - for (ai = nodep->cm_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET) - continue; - - if (ai->ai_socktype != SOCK_STREAM) - continue; - - fd = ipv4_connect( - &((struct sockaddr_in *)ai->ai_addr)->sin_addr, - baseport, timeout, me ); - - if (fd >= 0) { - pthread_mutex_unlock(&ml_mutex); - - pthread_mutex_lock(&fill_mutex); - clist_insert(fd, MSG_OPEN | MSG_CONNECTED | - MSG_READ | MSG_WRITE); - clist_set_purpose(fd, purpose); - pthread_mutex_unlock(&fill_mutex); - return fd; - } - } - - pthread_mutex_unlock(&ml_mutex); - errno = EHOSTUNREACH; - return -1; -} - -/** - Set close-on-exec bit option for a socket. - - @param fd Socket to set CLOEXEC flag - @return 0 on success, -1 on failure - @see fcntl - */ -static int -set_cloexec(int fd) -{ - int flags = fcntl(fd, F_GETFD, 0); - flags |= FD_CLOEXEC; - return fcntl(fd, F_SETFD, flags); -} - - -/** - Bind to a port on the local IPv6 stack - - @param port Port to bind to - @return 0 on success, -1 on failure - @see ipv4_bind - */ -static int -ipv6_bind(uint16_t port) -{ - struct sockaddr_in6 _sin6; - int fd, ret; - - fd = socket(PF_INET6, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - memset(&_sin6, 0, sizeof(_sin6)); - _sin6.sin6_family = AF_INET6; - _sin6.sin6_port = htons(port); - _sin6.sin6_flowinfo = 0; - _sin6.sin6_addr = in6addr_any; - - ret = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ret, sizeof (ret)); - - ret = set_cloexec(fd); - if (ret < 0) { - close(fd); - return -1; - } - - ret = bind(fd, (struct sockaddr *)&_sin6, sizeof(_sin6)); - if (ret < 0) { - close(fd); - return -1; - } - return fd; -} - - -/** - Bind to a port on the local IPv4 stack - - @param port Port to bind to - @return 0 on success, -1 on failure - @see ipv6_bind - */ -static int -ipv4_bind(uint16_t port) -{ - struct sockaddr_in _sin; - int fd, ret; - - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -1; - - _sin.sin_family = AF_INET; - _sin.sin_port = htons(port); - _sin.sin_addr.s_addr = htonl(INADDR_ANY); - - ret = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ret, sizeof (ret)); - - ret = set_cloexec(fd); - if (ret < 0) { - close(fd); - return -1; - } - - ret = bind(fd, (struct sockaddr *)&_sin, sizeof(_sin)); - if (ret < 0) { - close(fd); - return -1; - } - return fd; -} - - -/** - Set up listener sockets on a given base port. First, we try to listen - on IPv6. - - @param baseport Port to listen on. Note that this is altered by - IPV6_PORT_OFFSET. - @param purpose User or application defined purpose. - @param ret Preallocated array of at least two ints. The listening - file descriptors are stored within; up to 2: one for - IPv4, one for IPv6. It should not matter to the caller - which file descriptor corresponds to which network - stack. - @param retlen Size of ret, in ints. Must be at least 2. - @return Number of file descriptors listening in ret (0...2) - @see ipv4_bind, ipv6_bind - */ -int -msg_listen(uint16_t baseport, int purpose, int *ret, int retlen) -{ - int fd, x = 0; - - if (retlen < 2) { - errno = EINVAL; - return -1; - } - - fd = ipv6_bind(baseport + IPV6_PORT_OFFSET); - if (fd >= 0) { - //printf("IPv6 fd = %d\n",fd); - listen(fd, 15); - pthread_mutex_lock(&fill_mutex); - clist_insert(fd, MSG_OPEN | MSG_LISTEN); - clist_set_purpose(fd, purpose); - pthread_mutex_unlock(&fill_mutex); - ret[x++] = fd; - } - - fd = ipv4_bind(baseport); - if (fd >= 0) { - //printf("IPv4 fd = %d\n",fd); - listen(fd, 15); - pthread_mutex_lock(&fill_mutex); - clist_insert(fd, MSG_OPEN | MSG_LISTEN); - clist_set_purpose(fd, purpose); - pthread_mutex_unlock(&fill_mutex); - ret[x++] = fd; - } - - return x; -} - - -/** - Find a node ID by its address in network-byte-order. Addr can be either - a struct sockaddr_in6 or struct sockaddr_in structure. - - @param family AF_INET or AF_INET6 - @param addr Address to look for in ml_membership - @return (uint64_t)-1 if not found or the node ID corresponding - to the given address. - */ -static uint64_t -find_nodeid_by_addr(int family, struct sockaddr *addr) -{ - uint64_t ret; - int x; - char found = 0; - struct addrinfo *ai; - - pthread_mutex_lock(&ml_mutex); - - if (!ml_membership) { - pthread_mutex_unlock(&ml_mutex); - return (uint64_t)-1; - } - - memb_resolve_list(ml_membership, NULL); - - for (x = 0; x < ml_membership->cml_count; x++) { - if (!ml_membership->cml_members[x].cm_addrs) - continue; - - for (ai = ml_membership->cml_members[x].cm_addrs; ai; - ai = ai->ai_next) { - - if (ai->ai_family != AF_INET && - ai->ai_family != AF_INET6) - continue; - - if (family == AF_INET && ai->ai_family == AF_INET) { - if (memcmp(&((struct - sockaddr_in *)addr)->sin_addr, - &((struct - sockaddr_in *)ai->ai_addr)->sin_addr, - sizeof(struct in_addr))) - continue; - found = 1; - break; - } - - if (family == AF_INET6 && ai->ai_family == AF_INET6) { - if (memcmp(&((struct - sockaddr_in6 *)addr)->sin6_addr, - &((struct - sockaddr_in6 *)ai->ai_addr)->sin6_addr, - sizeof(struct in6_addr))) - continue; - found = 1; - break; - } - } - - if (found) { - ret = ml_membership->cml_members[x].cm_id; - pthread_mutex_unlock(&ml_mutex); - return ret; - } - } - pthread_mutex_unlock(&ml_mutex); - return (uint64_t)-1; -} - - -/** - Accept a connection from the given listening file descriptor. - - @param fd Listening file descriptor which has a connection - pending. - @param members_only If nonzero, reject if the connection is not from - a current member of ml_membership. - @param nodeid If non-NULL, we store the nodeid of the connecting - member within. - @return New file descriptor, or -1 in error case. - @see msg_listen - */ -int -msg_accept(int fd, int members_only, uint64_t *nodeid) -{ - int acceptfd; - int p; - uint64_t remoteid = (uint64_t)-1; - union { - struct sockaddr_in6 ip6addr; - struct sockaddr_in ip4addr; - } cliaddr; - struct sockaddr *cliaddrp; - socklen_t clilen; - - if (fd < 0) { - errno = EBADF; - return -1; - } - - if (!(clist_get_flags(fd) & MSG_LISTEN)) { - errno = EPERM; - return -1; - } - - p = clist_get_purpose(fd); - - cliaddrp = (struct sockaddr *)&cliaddr; - memset(cliaddrp, 0, sizeof(cliaddr)); - clilen = sizeof(cliaddr); - - do { - acceptfd = accept(fd, cliaddrp, &clilen); - - if (acceptfd < 0) { - if (errno == EINTR) - continue; - return -1; - } - } while (0); - - remoteid = find_nodeid_by_addr(cliaddrp->sa_family, cliaddrp); - if (members_only && (remoteid == (uint64_t)-1)) { - close(acceptfd); - errno = EPERM; - return -1; - } - - if (nodeid) - *nodeid = remoteid; - - pthread_mutex_lock(&fill_mutex); - clist_insert(acceptfd, MSG_OPEN | MSG_CONNECTED | MSG_READ | MSG_WRITE); - clist_set_purpose(acceptfd, p); - pthread_mutex_unlock(&fill_mutex); - return acceptfd; -} - - -/** - Close a file descriptor and remove it from our file descriptor list. - - @param fd File descriptor to close - @return -1 on failure, 0 on success - @see close, msg_open - */ -int -msg_close(int fd) -{ - if (!(clist_get_flags(fd) & MSG_OPEN)) { - errno = EPERM; - return -1; - } - clist_delete(fd); - return close(fd); -} - - -/** - Fill a file descriptor set with all open file descriptors. - - @param set Set to fill - @param flags Flags to look for. - @param purpose User or application-defined purpose to look for. - @return 0 - */ -int -msg_fill_fdset(fd_set *set, int flags, int purpose) -{ - int rv; - - pthread_mutex_lock(&fill_mutex); - rv = clist_fill_fdset(set, flags, purpose); - pthread_mutex_unlock(&fill_mutex); - return rv; -} - - -/** - Return next active file descriptor in the file descriptor set. - (The bit corresponding to the file descriptor is cleared) - - @param set File descriptor set to check - @return -1 if none available or a file descriptor - @see msg_fill_fdset - */ -int -msg_next_fd(fd_set *set) -{ - return clist_next_set(set); -} - - -/** - Set the user or application-defined purpose of a file descriptor - (application-specific) - - @param fd File descriptor to perform operation upon. - @param purpose User or application defined purpose. - @return 0 if successful, -1 on failure (fd not found in - our list.) - */ -int -msg_set_purpose(int fd, int purpose) -{ - return clist_set_purpose(fd, purpose); -} - - -/** - Get the user or application-defined purpose of a file descriptor - - @param fd File descriptor - @return Purpose ID if successful, -1 on failure (fd not found - in our list.) - */ -int -msg_get_purpose(int fd) -{ - return clist_get_purpose(fd); -} - - -/** - Get the flags of a file descriptor - - @param fd File descriptor - @return Purpose ID if successful, -1 on failure (fd not found - in our list.) - */ -int -msg_get_flags(int fd) -{ - return clist_get_flags(fd); -} - - -/** - Look at a message without reading it off the socket. - - @param sockfd File descriptor - @param buf Preallocated buffer to store received data. - @param count Maximum amount of data to read, in bytes. - @return Number of bytes peeked, or -1 on failure. - @see recv(2) - */ -ssize_t -msg_peek(int sockfd, void *buf, ssize_t count) -{ - - if (sockfd < 0) { - return -1; - } - - return recv(sockfd, buf, count, MSG_PEEK); -} diff --git a/magma/lib/plugin.c b/magma/lib/plugin.c deleted file mode 100644 index 3d4db6e..0000000 --- a/magma/lib/plugin.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2004 - - The Magma Cluster API Library is free software; you can redistribute - it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 of the License, or (at your option) any later version. - - The Magma Cluster API Library is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Plugin loading routines & No-op functions. - */ -#include <magma.h> -#include <dlfcn.h> -#include <stdlib.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <unistd.h> - -/** - Unimplemented stub s_null function for plugins - */ -int -_U_clu_null(cluster_plugin_t __attribute__ ((unused)) *cpp) -{ - printf("Unimplemented NULL function called\n"); - return 0; -} - - -/** - Unimplemented stub s_member_list function for plugins - */ -cluster_member_list_t * -_U_clu_member_list(cluster_plugin_t __attribute__ ((unused)) *cpp, - char __attribute__ ((unused)) *groupname) -{ - errno = ENOSYS; - return NULL; -} - - -/** - Unimplemented stub s_quorum_status function for plugins - */ -int -_U_clu_quorum_status(cluster_plugin_t __attribute__ ((unused)) *cpp, - char __attribute__ ((unused)) *groupname) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_get_event function for plugins - */ -int -_U_clu_get_event(cluster_plugin_t __attribute__ ((unused)) *cpp, - int __attribute__((unused)) fd) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_login function for plugins - */ -int -_U_clu_login(cluster_plugin_t __attribute__ ((unused)) *cpp, - int __attribute__ ((unused)) fd, - char __attribute__ ((unused)) *groupname) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_logout function for plugins - */ -int -_U_clu_logout(cluster_plugin_t __attribute__ ((unused)) *cpp, - int __attribute__((unused)) fd) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_close function for plugins - */ -int -_U_clu_close(cluster_plugin_t __attribute__ ((unused)) *cpp, - int __attribute__((unused)) fd) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_fence function for plugins - */ -int -_U_clu_fence(cluster_plugin_t __attribute__ ((unused)) *cpp, - cluster_member_t __attribute__((unused)) *node) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_lock function for plugins - */ -int -_U_clu_lock(cluster_plugin_t __attribute__ ((unused)) *cpp, - char *__attribute__ ((unused)) resource, - int __attribute__ ((unused)) flags, - void **__attribute__ ((unused)) lockpp) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_unlock function for plugins - */ -int -_U_clu_unlock(cluster_plugin_t __attribute__ ((unused)) *cpp, - char *__attribute__ ((unused)) resource, - void *__attribute__ ((unused)) lockp) -{ - errno = ENOSYS; - return -ENOSYS; -} - - -/** - Unimplemented stub s_plugin_version function for plugins - */ -char * -_U_clu_plugin_version(cluster_plugin_t __attribute__ ((unused)) *cpp) -{ - return "Unimplemented Version Function v1.0"; -} - - -/** - Free up a null-terminated array of strings - */ -void -free_dirnames(char **dirnames) -{ - int x = 0; - - for (; dirnames[x]; x++) - free(dirnames[x]); - - free(dirnames); -} - - -/** - Read all entries in a directory and return them in a NULL-terminated, - sorted array. - */ -int -read_dirnames_sorted(char *directory, char ***dirnames) -{ - DIR *dir; - struct dirent *entry; - char filename[1024]; - int count = 0, x = 0; - - dir = opendir(directory); - if (!dir) - return -1; - - /* Count the number of plugins */ - while ((entry = readdir(dir)) != NULL) - ++count; - - /* Malloc the entries */ - *dirnames = malloc(sizeof(char *) * (count+1)); - if (!*dirnames) { -#ifdef DEBUG - printf("Magma: %s: Failed to malloc %d bytes", - __FUNCTION__, (int)(sizeof(char *) * (count+1))); -#endif - closedir(dir); - errno = ENOMEM; - return -1; - } - memset(*dirnames, 0, sizeof(char *) * (count + 1)); - rewinddir(dir); - - /* Store the directory names. */ - while ((entry = readdir(dir)) != NULL) { - snprintf(filename, sizeof(filename), "%s/%s", directory, - entry->d_name); - - (*dirnames)[x] = strdup(filename); - if (!(*dirnames)[x]) { -#ifdef DEBUG - printf("Magma: Failed to duplicate %s\n", - filename); -#endif - free_dirnames(*dirnames); - closedir(dir); - errno = ENOMEM; - return -1; - } - ++x; - } - - closedir(dir); - - /* Sort the directory names. */ - qsort((*dirnames), count, sizeof(char *), alphasort); - - return 0; -} - - -/** - Searches PLUGINDIR for a plugin which can successfully connect to the - cluster infrastructure (locking/fencing/quorum/membership) which is - running locally. This connects, and tries to log in to the specified - service or node group if specified. - - @param cpp Newly allocated cluster plugin on success - @param groupname Node group to connect to. - @param login If set to nonzero, actually try to log in to the - node or service group. - @return A file descriptor on success; -1 on failure. - select(2) may be used to wait for events on this - file descriptor. - @see clu_disconnect - */ -int -cp_connect(cluster_plugin_t **cpp, char *groupname, int login) -{ - int fd, ret, found = 0; - cluster_plugin_t *cp; - char **filenames; - int fcount = 0; - - if (*cpp) { - errno = EINVAL; - return -1; - } - -#ifdef DEBUG - printf("Magma: Trying plugins in %s\n", PLUGINDIR); -#endif - if (read_dirnames_sorted(PLUGINDIR, &filenames) != 0) { - return -1; - } - - for (fcount = 0; filenames[fcount]; fcount++) { - - cp = cp_load(filenames[fcount]); - if (cp == NULL) - continue; - ++found; - -#ifdef DEBUG - printf("Magma: Trying %s: ", filename[fcount]); - cp_null(cp); - fflush(stdout); -#endif - - if (cp_init(cp, NULL, 0) < 0) { - cp_unload(cp); - cp = NULL; - continue; - } - - fd = cp_open(cp); - if (fd < 0) { - cp_unload(cp); - cp = NULL; - continue; - } - - if (login) { - ret = cp_login(cp, fd, groupname); - if ((ret < 0) && (ret != -ENOSYS)) { - cp_close(cp, fd); - cp_unload(cp); - cp = NULL; - continue; - } - } - - *cpp = cp; - free_dirnames(filenames); - -#ifdef DEBUG - printf("Magma: Connected, file descriptor %d\n", fd); -#endif - return fd; - } - - free_dirnames(filenames); - if (!found) { -#ifdef DEBUG - printf("Magma: No usable plugins found.\n"); -#endif - errno = ELIBACC; - } else { -#ifdef DEBUG - printf("Magma: No applicable plugin found or no cluster " - "infrastructure running.\n"); -#endif - errno = ESRCH; - } - return -1; -} - - -const char * -cp_load_error(int e) -{ - switch(e) { - case EINVAL: - return "NULL plugin filename specified"; - case EPERM: - return "User-readable bit not set"; - case ELIBBAD: - return "dlopen() error"; - case EPROTO: - return "API version incorrect or nonexistent"; - case ENOSYS: - return "Load/init function nonexistent"; - case EBADE: - return "Load function failed"; - default: - return strerror(e); - } - - return NULL; -} - - -/** - * Load a cluster plugin .so file and map all the functions - * provided to entries in a cluster_plugin_t structure. Maps all unimplemented - * functions to their _U_* counterparts. - * - * @param libpath Path to file. - * @return NULL on failure, or a newly allocated - * cluster_plugin_t structure on success. - */ -cluster_plugin_t * -cp_load(const char *libpath) -{ - void *handle = NULL; - cluster_plugin_t *cpp = NULL; - double (*modversion)(void); - struct stat sb; - - errno = 0; - - if (!libpath) { - errno = EINVAL; - return NULL; - } - - if (stat(libpath, &sb) != 0) { - return NULL; - } - - /* - If it's not owner-readable or it's a directory, - ignore/fail. Thus, a user may change the permission of - a plugin "u-r" and this would then prevent magma apps - from loading it. - */ - if (S_ISDIR(sb.st_mode)) { - errno = EISDIR; - return NULL; - } - if (!(sb.st_mode & S_IRUSR)) { -#ifdef DEBUG - printf("Magma: Ignoring %s (User-readable bit not set)\n", - libpath); -#endif - errno = EPERM; - return NULL; - } - - handle = dlopen(libpath, RTLD_LAZY); - if (!handle) { - errno = ELIBBAD; - return NULL; - } - - modversion = dlsym(handle, CLU_PLUGIN_VERSION_SYM); - if (!modversion) { -#ifdef DEBUG - printf("Magma: Failed to map %s\n", CLU_PLUGIN_VERSION_SYM); -#endif - dlclose(handle); - errno = EPROTO; /* XXX what? */ - return NULL; - } - - if (modversion() != CLUSTER_PLUGIN_API_VERSION) { -#ifdef DEBUG - printf("Magma: API version mismatch in %s: \n" - " %f expected; %f received.\n", libpath, - CLUSTER_PLUGIN_API_VERSION, modversion()); -#endif - dlclose(handle); - errno = EPROTO; /* XXX What? */ - return NULL; - } - - cpp = malloc(sizeof(*cpp)); - if (!cpp) { -#ifdef DEBUG - printf("Magma: Failed to malloc %d bytes\n", - (int)sizeof(*cpp)); -#endif - errno = ENOMEM; - return NULL; - } - - memset(cpp, 0, sizeof(*cpp)); - - /* Initially, set everything to _U */ - CP_SET_UNIMP(cpp, null); - CP_SET_UNIMP(cpp, member_list); - CP_SET_UNIMP(cpp, login); - CP_SET_UNIMP(cpp, logout); - CP_SET_UNIMP(cpp, plugin_version); - CP_SET_UNIMP(cpp, lock); - CP_SET_UNIMP(cpp, unlock); - - /* Store the handle */ - cpp->cp_private.p_dlhandle = handle; - - /* Set local node ID to none */ - cpp->cp_private.p_localid = NODE_ID_NONE; - - /* Grab the init and deinit functions */ - cpp->cp_private.p_load_func = dlsym(handle, CLU_PLUGIN_LOAD_SYM); - cpp->cp_private.p_init_func = dlsym(handle, CLU_PLUGIN_INIT_SYM); - cpp->cp_private.p_unload_func = dlsym(handle, CLU_PLUGIN_UNLOAD_SYM); - - /* - * Modules *MUST* have a load function, and it can not fail. - */ - if (!cpp->cp_private.p_load_func) { -#ifdef DEBUG - printf("Magma: Module load function not found in %s\n", - libpath); -#endif - free(cpp); - dlclose(handle); - errno = ENOSYS; - return NULL; - } - - /* - * Modules *MUST* have an init function. - */ - if (!cpp->cp_private.p_init_func) { -#ifdef DEBUG - printf("Magma: Module init function not found in %s\n", - libpath); -#endif - free(cpp); - dlclose(handle); - errno = ENOSYS; - return NULL; - } - - if (cpp->cp_private.p_load_func(cpp) < 0) { -#ifdef DEBUG - printf("Load function failed\n"); -#endif - free(cpp); - dlclose(handle); - errno = EBADE; - return NULL; - } - - return cpp; -} - - -/** - * Initialize a cluster plugin structure. This calls the - * initialization function we loaded in cp_load. - * - * @param cpp Pointer to plugin structure to initialize. - * @param priv Optional driver-specific private data to copy in - * to cpp. - * @param privlen Size of data in priv. - * @return -1 on failure; 0 on success. - * @see cp_load - */ -int -cp_init(cluster_plugin_t *cpp, const void *priv, size_t privlen) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - /* - * Modules *MUST* have an initialization function, and it can not - * fail. - */ - if (!cpp->cp_private.p_init_func) { - errno = ENOSYS; - return -ENOSYS; - } - - if ((cpp->cp_private.p_init_func)(cpp, priv, privlen) < 0) { - return -EINVAL; - } - - return 0; -} - - -int -cp_unload(cluster_plugin_t *cpp) -{ - void *handle; - - if (!cpp) - return 0; - - /* - * Call the deinitialization function, if it exists. - */ - if (cpp->cp_private.p_unload_func && - (cpp->cp_private.p_unload_func(cpp) < 0)) { - return -EINVAL; - } - - handle = cpp->cp_private.p_dlhandle; - free(cpp); - dlclose(handle); - - return 0; -} - - -/** - Reentrant version of - @ref clu_null - using specified plugin. - */ -int -cp_null(cluster_plugin_t *cpp) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_null(cpp); -} - - -/** - Reentrant version of - @ref clu_member_list - using specified plugin. - */ -cluster_member_list_t * -cp_member_list(cluster_plugin_t *cpp, char *groupname) -{ - if (!cpp) { - errno = EINVAL; - return NULL; - } - - return cpp->cp_ops.s_member_list(cpp, groupname); -} - - -/** - Reentrant version of - @ref clu_quorum_status - using specified plugin. - */ -int -cp_quorum_status(cluster_plugin_t *cpp, char *groupname) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_quorum_status(cpp, groupname); -} - - -/** - Reentrant version of - @ref clu_plugin_version - using specified plugin. - */ -char * -cp_plugin_version(cluster_plugin_t *cpp) -{ - if (!cpp) { - errno = EINVAL; - return NULL; - } - - return cpp->cp_ops.s_plugin_version(cpp); -} - - -/** - Reentrant version of - @ref clu_get_event - using specified plugin. - */ -int -cp_get_event(cluster_plugin_t *cpp, int fd) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_get_event(cpp, fd); -} - - -/** - Obtain a cluster lock using the specified plugin. The caller must - take care to ensure mutual exclusion; not all lock managers will - provide this based solely on the lock information. - - @see clu_lock - */ -int -cp_lock(cluster_plugin_t *cpp, char *resource, int flags, void **lockpp) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_lock(cpp, resource, flags, lockpp); -} - - -/** - Release a cluster lock using the specified plugin. The caller must - take care to ensure mutual exclusion if the underlying lock manager - requires it. - - @see clu_unlock - */ -int -cp_unlock(cluster_plugin_t *cpp, char *resource, void *lockp) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_unlock(cpp, resource, lockp); -} - - -/** - Reentrant version of - @ref clu_login - using specified plugin. - */ -int -cp_login(cluster_plugin_t *cpp, int fd, char *groupname) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_login(cpp, fd, groupname); -} - - -/** - Reentrant version of - @ref clu_open - using specified plugin. - */ -int -cp_open(cluster_plugin_t *cpp) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_open(cpp); -} - - -/** - Reentrant version of - @ref clu_close - using specified plugin. - */ -int -cp_close(cluster_plugin_t *cpp, int fd) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_close(cpp, fd); -} - - -/** - Reentrant version of - @ref clu_fence - using specified plugin. - */ -int -cp_fence(cluster_plugin_t *cpp, cluster_member_t *node) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_fence(cpp, node); -} - - -/** - Reentrant version of - @ref clu_logout - using specified plugin. - */ -int -cp_logout(cluster_plugin_t *cpp, int fd) -{ - if (!cpp) { - errno = EINVAL; - return -1; - } - - return cpp->cp_ops.s_logout(cpp, fd); -} - - diff --git a/magma/make/defines.mk.input b/magma/make/defines.mk.input deleted file mode 100644 index 84dc8e9..0000000 --- a/magma/make/defines.mk.input +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}@SBINDIR@ -mandir ?= ${DESTDIR}@MANDIR@ -libdir ?= ${DESTDIR}@LIBDIR@ -slibdir ?= ${DESTDIR}@SLIBDIR@ -plugindir ?= ${DESTDIR}@PLUGINDIR@ -incdir ?= ${DESTDIR}@INCDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -Wall ${INCLUDE} diff --git a/magma/make/release.mk.input b/magma/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/magma/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/magma/man/Makefile b/magma/man/Makefile deleted file mode 100644 index f14712e..0000000 --- a/magma/man/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl - -install: - install -d ${mandir}/man3 - install -d ${mandir}/man8 - install clu_connect.3 clu_disconnect.3 clu_get_event.3 ${mandir}/man3 - install magma_tool.8 ${mandir}/man8 - -uninstall: - ${UNINSTALL} clu_connect.3 clu_disconnect.3 clu_get_event.3 ${mandir}/man3 - ${UNINSTALL} magma_tool.8 ${mandir}/man8 diff --git a/magma/man/clu_connect.3 b/magma/man/clu_connect.3 deleted file mode 100644 index 3056b8e..0000000 --- a/magma/man/clu_connect.3 +++ /dev/null @@ -1,34 +0,0 @@ -.TH "CLU_CONNECT" "3" "Mar 2004" "" "Magma Cluster Plugin Library" -.SH NAME -clu_connect, clu_disconnect - -High-level cluster infrastructure connect/disconnect functions. -.SH SYNOPSIS -.nf -.B #include <magma.h> -.sp -.BI "int clu_connect(char *groupname, int login);" -.BI "int clu_disconnect(int fd);" -.BI "int cp_connect(cluster_plugin_t **cpp, char *groupname, int login);" -.fi -.SH DESCRIPTION -The \fBclu_connect()\fP function attempts to connect to the cluster -software running on the local machine. If it successfully does so, -it registers for events and returns a file descriptor. -.LP -The returned file descriptor may be waited on using the \fBselect(2)\fP -system call. - -The \fBclu_disconnect()\fP function cleans up all related descriptors, -threads, and other resources and unmaps the connected cluster plugin. -.SH "RETURN VALUE" -The \fBclu_connect()\fP function returns a file descriptor (>= 0) on success -or a negative value indicating the error incurred. -The \fBclu_disconnect()\fP function returns a file descriptor on success, -or -1 on failure. -.LP -The \fBclu_disconnect()\fP returns 0. -.SH "FILES" -.LP -/usr/lib/magma/* - Cluster plugins. -.SH "SEE ALSO" -clu_get_event(3), select(2) diff --git a/magma/man/clu_disconnect.3 b/magma/man/clu_disconnect.3 deleted file mode 100644 index 93784cb..0000000 --- a/magma/man/clu_disconnect.3 +++ /dev/null @@ -1 +0,0 @@ -.so man3/clu_connect.3 diff --git a/magma/man/clu_get_event.3 b/magma/man/clu_get_event.3 deleted file mode 100644 index f73ba4b..0000000 --- a/magma/man/clu_get_event.3 +++ /dev/null @@ -1,39 +0,0 @@ -.TH "CLU_GET_EVENT" "3" "Mar 2004" "" "Magma Cluster Plugin Library" -.SH NAME -clu_get_event - Obtain an event description of whatever made -.SH SYNOPSIS -.nf -.B #include <magma.h> -.sp -.BI "int clu_get_event(int fd);" -.sp -.SH DESCRIPTION -.LP -The \fBclu_get_event()\fP function retrieves an event from an active cluster -file descriptor \fBfd\fP. -.SH "RETURN VALUE" -.LP -.B CEV_NULL -- Spurious Event Wakeup -.LP -.B CEV_SHUTDOWN -- Local node left or is leaving the cluster. -.LP -.B CEV_MEMB_CHANGE -- Change in membership / Node transition. This should only be handled when -the local node is quorate, and should be ignored at all other times. -Generally, programs ought to call \fBclu_member_list()\fP to retrieve the -active membership after this event is received. It is up to the caller -to figure out the differences in the membership lists. -.LP -.B CEV_QUORATE -- The local node is now a part of the cluster quorum. Generally, programs -ought to call \fBclu_member_list()\fP to retrieve the active membership -after this event is received. -.LP -.B CEV_INQUORATE -- The local node is no longer a part of the cluster quorum; expect to be -fenced. - -.SH "SEE ALSO" -clu_connect(3), clu_disconnect(3), clu_member_list(3) diff --git a/magma/man/magma_tool.8 b/magma/man/magma_tool.8 deleted file mode 100644 index fbcf3d0..0000000 --- a/magma/man/magma_tool.8 +++ /dev/null @@ -1,98 +0,0 @@ -." Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. -." -." This copyrighted material is made available to anyone wishing to use, -." modify, copy, or redistribute it subject to the terms and conditions -." of the GNU General Public License v.2. -.TH magma_tool 8 -.SH NAME -magma_tool - Magma API test program - -.SH SYNOPSIS\fP -\fBmagma_tool\fP \fIcommand\fP - -.SH DESCRIPTION\fP -\fBmagma_tool\fP is part of the Magma cluster API abstraction library. -Its primary purpose is for API debugging and tweaking; it does not control -anything and has no configuration information to speak of. - -.SH OPTIONS -.TP -\fB-h\fP -Help. Print out the usage. - -.SH PLUGIN COMMANDS -.TP -\fBlist\fP -This command is used to list plugins and other files in Magma's plugin -directory and whether or not they are legal plugins. This will list all -non-directory files in Magma's plugin directory, whether or not they are -legal plugins, and why. -.TP -\fBenable\fP \fI<filename>\fP -This command is used to enable a plugin in Magma's plugin directory. -It is synonymous with "chmod u+r <filename>". Files without in the -plugin directory without the user-readable bit set (S_IRUSR) are ignored. -.TP -\fBdisable\fP \fI<filename>\fP -This command is used to disable a plugin in Magma's plugin directory. -It is synonymous with "chmod u+r <filename>". Files without in the -plugin directory without the user-readable bit set (S_IRUSR) are ignored. - -.SH API TEST COMMANDS\fP -These commands may all be preceded by the option \fIlogin\fP. If specified, -magma_tool will log in to the service/node group on cluster infrastructures -where this notion is supported. -.TP -\fBlock\fP \fI[resource]\fP -This causes magma_tool to connect to the underlying cluster infrastructure -and/or lock manager and acquire a clusterlock. If \fI[resource]\fP is not -specified, then the name "Something" is used. -.TP -\fBlisten\fP \fI[group]\fP -This causes magma_tool to connect to the underlying cluster infrastructure -and/or lock manager and listen for events in the group \fI[group]\fP. This -is only useful with the \fIlogin\fP flag. -.TP -\fBlocalname\fP \fI[group]\fP -This causes magma_tool to connect to the underlying cluster infrastructure -and/or lock manager and request the local node name, which it then displays. -.TP -\fBlocalid\fP \fI[group]\fP -This causes magma_tool to connect to the underlying cluster infrastructure -and/or lock manager and request the local node ID, which it then displays. -.TP -\fBmembers\fP \fI[group]\fP -This causes magma_tool to connect to the underlying cluster infrastructure -and/or lock manager and request the list of members, which it then displays. -If \fI[group]\fP is specified, then only the members of the given service -or node group are listed. -.TP -\fBquorum\fP \fI[group]\fP -This causes magma_tool to connect to the underlying cluster infrastructure -and/or lock manager and request the local node's quorum status as well as -whether or not it is a member of \fI[group]\fP. -.TP -\fBconfig\fP \fI<item>\fP -This displays compile-time information; see below. - -.SH CONFIGURATION -.TP -\fBconfig cflags\fP -Displays the compiler flags needed to build applications against Magma. -.TP -\fBconfig libs\fP -Displays the compiler linker flags needed to build applications against -Magma. -.TP -\fBconfig libs-nt\fP -Displays the compiler linker flags needed to build applications against -Magma's lightweight, mostly-reentrant library. -.TP -\fBconfig plugindir\fP -Displays directory Magma uses for plugins. -.TP -\fBconfig libdir\fP -Displays where Magma's dynamic libraries reside. -.TP -\fBconfig slibdir\fP -Displays where Magma's static libraries reside. diff --git a/magma/scripts/uninstall.pl b/magma/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/magma/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/magma/tests/Makefile b/magma/tests/Makefile deleted file mode 100644 index 72e9fd7..0000000 --- a/magma/tests/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -include ${top_srcdir}/make/defines.mk -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -INCLUDE+= -I${top_srcdir}/lib -LIBS = -L${top_srcdir}/lib -lmagma -lmagmamsg -ldl -lpthread -LIBSNT = -L${top_srcdir}/lib -lmagma_nt -ldl -TARGETS = magma_tool circleping cluster_cmd -TESTS = cptester thread_test -CFLAGS += -DDEBUG -D_GNU_SOURCE -DPLUGINDIR="${plugindir}" \ - -DINCDIR="${incdir}" -DLIBDIR="${libdir}" \ - -DSLIBDIR="${slibdir}" - -all: $(TARGETS) $(TESTS) - -install: all - install -d ${sbindir} - install -m 0755 $(TARGETS) ${sbindir} - -uninstall: - ${UNINSTALL} ${TARGETS} ${sbindir} - -circleping: circleping.o - $(CC) -o $@ $^ $(LIBS) -ggdb - -cluster_cmd: cluster_cmd.o - $(CC) -o $@ $^ $(LIBS) - -magma_tool: magma_tool.o - $(CC) -o $@ $^ $(LIBS) -ggdb - -cptester: cptester.o - $(CC) -o $@ $^ $(LIBSNT) - -thread_test: thread_test.o - $(CC) -o $@ $^ $(LIBS) -ggdb - - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS) -ggdb - -clean: - rm -f *o *~ *.so $(TARGETS) $(TESTS) - diff --git a/magma/tests/circleping.c b/magma/tests/circleping.c deleted file mode 100644 index aa73c70..0000000 --- a/magma/tests/circleping.c +++ /dev/null @@ -1,250 +0,0 @@ -#include <magma.h> -#include <magmamsg.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#define MY_BASE_PORT 13412 -#define MY_SERVICE_GROUP "magma::ping" -#define MY_PURPOSE 0x12389af - -int quorate = 0; -cluster_member_list_t *membership = NULL; - -int -handle_cluster_event(int fd) -{ - cluster_member_list_t *new, *gained, *lost; - int ret; - - ret = clu_get_event(fd); - - switch(ret) { - case CE_NULL: - //printf("-E- Spurious wakeup\n"); - break; - case CE_SUSPEND: - printf("*E* Suspend activities\n"); - break; - case CE_MEMB_CHANGE: - printf("*E* Membership change\n"); - - new = clu_member_list(MY_SERVICE_GROUP); - lost = memb_lost(membership, new); - gained = memb_gained(membership, new); - - if (lost) { - printf("<<< Begin Nodes lost\n"); - print_member_list(lost, 0); - printf("<<< End Nodes Lost\n"); - cml_free(lost); - } - - if (gained) { - printf(">>> Begin Nodes gained\n"); - print_member_list(gained, 0); - printf(">>> End Nodes gained\n"); - cml_free(gained); - } - - memb_resolve_list(new, membership); - msg_update(new); - cml_free(membership); - membership = new; - break; - - case CE_QUORATE: - quorate = 1; - printf("*E* Quorum formed\n"); - break; - case CE_INQUORATE: - quorate = 0; - printf("*E* Quorum dissolved\n"); - break; - case CE_SHUTDOWN: - printf("*E* Node shutdown\n"); - exit(0); - } - - return ret; -} - - -uint64_t -next_node_id(uint64_t me) -{ - uint64_t low = (uint64_t)(-1); - uint64_t next = me, curr; - int x; - - for (x = 0; x < membership->cml_count; x++) { - curr = membership->cml_members[x].cm_id; - if (curr < low) - low = curr; - - if ((curr > me) && ((next == me) || (curr < next))) - next = curr; - } - - /* I am highest ID; go to lowest */ - if (next == me) - next = low; - - return next; -} - - -uint32_t -send_to_next(uint32_t msg) -{ - int fd = -1; - uint32_t mymsg; - uint64_t my_node_id = (uint64_t)-1; - uint64_t target; - - if (my_node_id == (uint64_t)-1) - clu_local_nodeid(MY_SERVICE_GROUP, &my_node_id); - - target = my_node_id; - - do { - target = next_node_id(target); - if (target == my_node_id) { - printf("I am all alone :(\n"); - return msg; - } - fd = msg_open(target, MY_BASE_PORT, MY_PURPOSE, 5); - if (fd != -1) - break; - } while (1); - - /* Bump pinger. */ - mymsg = msg + 1; - - printf("Sending %d to %s\n", mymsg, - memb_id_to_name(membership, target)); - msg_send(fd, &mymsg, sizeof(mymsg)); - msg_close(fd); - return mymsg; -} - - -uint32_t -ping_pong_message(int fd, uint32_t mycount, uint64_t nodeid) -{ - int n; - uint32_t msg; - - n = msg_receive_timeout(fd, &msg, sizeof(msg), 5); - - if (n == -1) { - perror("msg_receive_timeout"); - return mycount; - } - - printf("Received %d from %s\n", msg, - memb_id_to_name(membership,nodeid)); - - if (msg <= mycount) - msg = mycount; - - sleep(1); - - return send_to_next(msg); -} - - -int -wait_for_stuff_to_happen(int clusterfd, int *listen_fds, int lfd_count) -{ - int newfd, fd, n, max; - fd_set rfds; - static uint32_t pingpong = 1; - struct timeval tv; - uint64_t nodeid; - - FD_ZERO(&rfds); - max = msg_fill_fdset(&rfds, MSG_ALL, MSGP_ALL); - - tv.tv_sec = 5; - tv.tv_usec = 0; - n = select(max + 1, &rfds, NULL, NULL, &tv); - - /* No new messages. See if someone else logged in to the group */ - if (n == 0) { - printf("Looking for my friends...\n"); - pingpong = send_to_next(pingpong); - return 0; - } - - if (n < 0) { - printf("Select error: %s\n", strerror(errno)); - sleep(1); - return 0; - } - - while (n) { - fd = msg_next_fd(&rfds); - if (fd == -1) - break; - - --n; - - if (fd == clusterfd) { - if (handle_cluster_event(clusterfd) == - CE_MEMB_CHANGE) { - pingpong = send_to_next(pingpong); - } - - continue; - } - - /* One of our listen file descriptors */ - newfd = msg_accept(fd, 1, &nodeid); - if (quorate) { - pingpong = ping_pong_message(newfd, pingpong, - nodeid); - } else { - printf("Dropping connect from %s: NO QUORUM\n", - memb_id_to_name(membership, nodeid)); - } - msg_close(newfd); - } - - return 0; -} - - -int -main(void) -{ - int cluster_fd; - int listen_fds[2], listeners; - - if ((listeners = msg_listen(MY_BASE_PORT, MY_PURPOSE, - listen_fds, 2)) <= 0) { - printf("Couldn't set up listen socket\n"); - return -1; - } - - /* Connect to the cluster software. */ - cluster_fd = clu_connect(MY_SERVICE_GROUP, 1); - - if (cluster_fd < 0) - return -1; - - quorate = (clu_quorum_status(MY_SERVICE_GROUP) & QF_QUORATE); - printf("Using plugin: %s\n", clu_plugin_version()); - printf("Initial status = %s\n", quorate?"Quorate":"Inquorate"); - - membership = clu_member_list(MY_SERVICE_GROUP); - msg_update(membership); - memb_resolve_list(membership, NULL); - print_member_list(membership, 1); - - while (1) { - wait_for_stuff_to_happen(cluster_fd, listen_fds, listeners); - } -} - diff --git a/magma/tests/cluster_cmd.c b/magma/tests/cluster_cmd.c deleted file mode 100644 index 165dec4..0000000 --- a/magma/tests/cluster_cmd.c +++ /dev/null @@ -1,482 +0,0 @@ -#if 0 -echo "Compiling cluster_cmd."; -gcc -lmagma -lmagmamsg -ldl cluster_cmd.c -o cluster_cmd -if [ $? != 0 ]; then -echo "Failed to compile cluster_cmd."; -echo "Perhaps you don't have the magma libraries installed?"; -exit 1; -else -echo "Complete." -exit 0; -fi -#endif -/************************************************************ - ** This program executes a command on all cluster nodes - ** that are currently "active" in the cluster. It executes - ** the command at a specific instance in time (t + timeofday). - ** You can set that time or use the default (3 sec). If - ** you have ntp running on your cluster nodes, the command - ** will execute at almost exactly the same time on each node. - ** If you don't have ntp running, you may not get a response - ** back from some of your nodes, because the command will - ** fail to execute in time. - ** - ** Proximity in execution times should be within ~1ms if - ** used properly. - ***********************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <sys/time.h> -#include <string.h> -#include "magma.h" -#include "magmamsg.h" - -#define CLIENT_BASE_PORT 25001 -#define SERVER_BASE_PORT 25011 - -void print_usage(FILE *stream); -static char *capture_output(int fd); -static char *run_cmd(char *cmd, char *args[], time_t t); -static int await_command(void); -static int send_command(char *cmd, int t); - -char *nodes[256]; - -int main(int argc, char *argv[]){ - int i,idx=0; - int t = 3; - int pid; - char cmd[256]; - - memset(nodes, 0, sizeof(nodes)); - - if(argc < 2){ - fprintf(stderr, "Wrong number of arguments.\n"); - exit(EXIT_FAILURE); - } - - for(i=1; i < argc; i++){ - if(!strcmp(argv[i], "-d") || - !strcmp(argv[i], "--daemon")){ - printf("WARNING:: Use of this program opens a big security hole.\n"); - pid = fork(); - if(pid){ - exit(EXIT_SUCCESS); - } else { - await_command(); - } - exit(EXIT_FAILURE); - } - if(!strcmp(argv[i], "-h") || - !strcmp(argv[i], "--help")){ - print_usage(stdout); - exit(EXIT_SUCCESS); - } - if(!strcmp(argv[i], "-n") || - !strcmp(argv[i], "--node")){ - if(argc <= i+1){ - fprintf(stderr, "-t/--time requires an argument.\n"); - exit(EXIT_FAILURE); - } - i++; - nodes[idx++] = argv[i]; - continue; - } - if(!strcmp(argv[i], "-t") || - !strcmp(argv[i], "--time")){ - if(argc <= i+1){ - fprintf(stderr, "-t/--time requires an argument.\n"); - exit(EXIT_FAILURE); - } - i++; - t = atoi(argv[i]); - continue; - } - if(argv[i][0] == '-'){ - fprintf(stderr, "Unknown option '%s'.\n", argv[i]); - exit(EXIT_FAILURE); - } - break; - } - - memset(cmd, 0, sizeof(cmd)); - for(idx=0; i < argc; i++){ - strncpy(cmd+idx, argv[i], (sizeof(cmd)-idx)-1); - idx = strlen(cmd); - cmd[idx++] = ' '; - } - - if(!strlen(cmd)){ - fprintf(stderr, "No command specified.\n"); - exit(EXIT_FAILURE); - } - - if(send_command(cmd, t)){ - exit(EXIT_FAILURE); - } - - exit(EXIT_SUCCESS); -} - -void print_usage(FILE *stream){ - fprintf(stream, - "cluster_cmd [options] <command>\n" - "\n" - "Options:\n" - " -d/--daemon Start the daemon.\n" - " -h/--help Print usage.\n" - " -t/--time <sec> Specify the number of seconds before command execution.\n" - ); -} - -static char *capture_output(int fd) -{ - char *rtn = NULL; - char buf[512]; - - memset(buf, 0, sizeof(buf)); - - while (read(fd, buf, sizeof(buf)-1) > 0) { - if(rtn){ - rtn = realloc(rtn, (strlen(buf)+1)+strlen(rtn)); - strncpy(rtn+strlen(rtn), buf, strlen(buf)); - } else { - rtn = malloc(strlen(buf)+1); - memset(rtn, 0, strlen(buf)+1); - strncpy(rtn, buf, strlen(buf)); - } - memset(buf, 0, sizeof(buf)); - } - return rtn; -} - - -static char *run_cmd(char *cmd, char *args[], time_t t) -{ - int pid, status; - int pr_fd, pw_fd; /* parent read/write file descriptors */ - int cr_fd, cw_fd; /* child read/write file descriptors */ - int fd1[2]; - int fd2[2]; - char *rtn; - struct timeval exec_time; - - cr_fd = cw_fd = pr_fd = pw_fd = -1; - - if (pipe(fd1)) - goto fail; - pr_fd = fd1[0]; - cw_fd = fd1[1]; - - if (pipe(fd2)) - goto fail; - cr_fd = fd2[0]; - pw_fd = fd2[1]; - - pid = fork(); - if (pid < 0) - goto fail; - - if (pid) { - /* parent */ - fcntl(pr_fd, F_SETFL, fcntl(pr_fd, F_GETFL, 0) | O_NONBLOCK); - - close(pw_fd); - waitpid(pid, &status, 0); - - if (!WIFEXITED(status)){ - goto fail; - } else { - rtn = capture_output(pr_fd); - } - } else { - /* child */ - - close(0); - dup(cr_fd); - close(1); - dup(cw_fd); - close(2); - dup(cw_fd); - /* keep cw_fd open so parent can report all errors. */ - close(pr_fd); - close(pw_fd); - gettimeofday(&exec_time, NULL); - exec_time.tv_sec = (t - exec_time.tv_sec)-1; - exec_time.tv_usec= 1000000 - exec_time.tv_usec; - if(exec_time.tv_sec & (1<<(sizeof(time_t)*8-1))){ - /* Overflow detected -- Executing now! */ - } else { - select(0, NULL, NULL, NULL, &exec_time); - } - execvp(cmd, args); - exit(EXIT_FAILURE); - } - - close(pr_fd); - close(cw_fd); - close(cr_fd); - close(pw_fd); - return rtn; - - fail: - close(pr_fd); - close(cw_fd); - close(cr_fd); - close(pw_fd); - return NULL; -} - - -static int await_command(void){ - int fds[2]; - int fd; - int afd; - uint64_t nodeid; - int max_fds, n; - int cluster_fd = -1; - fd_set rset; - char buffer[512]; - cluster_member_list_t *membership = NULL; - - if(msg_listen(CLIENT_BASE_PORT, 0, fds, 2) <= 0){ - return -1; - } - - restart: - while(cluster_fd < 0){ - cluster_fd = clu_connect(NULL, 0); - } - - membership = clu_member_list(NULL); - msg_update(membership); - memb_resolve_list(membership, NULL); - - while(1){ - FD_ZERO(&rset); - max_fds = msg_fill_fdset(&rset, MSG_ALL, MSGP_ALL); - n = select(max_fds+1, &rset, NULL, NULL, NULL); - - if(n < 0){ - continue; - } - - while(n){ - memset(buffer, 0, sizeof(buffer)); - fd = msg_next_fd(&rset); - if(fd == -1) { break; } - n--; - if(fd == cluster_fd){ - switch(clu_get_event(cluster_fd)){ - case CE_NULL: - case CE_MEMB_CHANGE: - case CE_QUORATE: - case CE_INQUORATE: - cml_free(membership); - membership = clu_member_list(NULL); - msg_update(membership); - memb_resolve_list(membership, NULL); - continue; - case CE_SHUTDOWN: - default: - clu_disconnect(cluster_fd); - cluster_fd = -1; - goto restart; - } - } - - afd = msg_accept(fd, 1, &nodeid); - if(afd < 0){ - continue; - } - msg_receive(afd, buffer, sizeof(buffer)); - msg_close(afd); - - if(!strncmp(buffer, "COMMAND", 7)){ /* execute command */ - char *tmp, *tmp2; - char *args[64]; - int i=-1; - time_t t; - - memset(args, 0, sizeof(args)); - - for(tmp = strstr(buffer, " ")+1; tmp < buffer+strlen(buffer); tmp = tmp2){ - tmp2 = strstr(tmp, " "); - if(!tmp2){ - break; - } - if(i < 0){ - i++; - args[0] = (char *)strndup(tmp, tmp2-tmp); - t = atoi(args[0]); - free(args[0]); - args[0] = NULL; - } else { - - args[i++] = (char *)strndup(tmp, tmp2-tmp); - } - tmp2++; - } - if(args[0]){ - tmp = run_cmd(args[0], args, t); - fd = msg_open(nodeid, SERVER_BASE_PORT, 0, 5); - if(fd < 0){ - continue; - } - - if(tmp){ - msg_send(fd, tmp, strlen(tmp)); - free(tmp); - } else { - msg_send(fd, "\n", 1); - } - msg_close(fd); - } - } - } - } - return -1; -} - - -static int send_command(char *cmd, int t){ - int i, j, fds[2], fd, afd, n, max_fds; - int count; - int cluster_fd = -1; - int resp=0; - uint64_t nodeid; - uint64_t *ids; - fd_set rset; - char buffer[512]; - struct timeval timeout; - struct timeval exec_time; - cluster_member_list_t *membership = NULL; - - gettimeofday(&exec_time, NULL); - - memset(buffer, 0, sizeof(buffer)); - sprintf(buffer, "COMMAND %lu ", exec_time.tv_sec+t); - strncpy(buffer+strlen(buffer), cmd, (sizeof(buffer)-strlen(buffer))-1); - - cluster_fd = clu_connect(NULL, 0); - if(cluster_fd < 0){ - fprintf(stderr, "Unable to connect to cluster infrastructure.\n"); - return -1; - } - - if(msg_listen(SERVER_BASE_PORT, 0, fds, 2) <= 0){ - return -1; - } - - membership = clu_member_list(NULL); - msg_update(membership); - memb_resolve_list(membership, NULL); - - if(!membership->cml_count){ - fprintf(stderr, "No members.\n"); - return -1; - } - - if(!nodes[0]){ - count = membership->cml_count; - } else { - for(i=0, count=0; nodes[i]; i++){ - count++; - } - } - ids = malloc(sizeof(uint64_t)*count); - if(!ids){ - fprintf(stderr, "Not enough memory.\n"); - return -1; - } - memset(ids, 0, sizeof(uint64_t)*count); - - for(i = 0; i < count; i++){ - if(!nodes[0]){ - ids[i] = membership->cml_members[i].cm_id; - } else { - for(j=0; j < membership->cml_count; j++){ - if(!strcmp(nodes[i], membership->cml_members[j].cm_name)){ - ids[i] = membership->cml_members[j].cm_id; - break; - } - } - if(j == membership->cml_count){ - fprintf(stderr, "Unable to find node, %s, in membership.\n", nodes[i]); - return -1; - } - } - } - - for(i=0; i < count; i++){ - fd = msg_open(ids[i], CLIENT_BASE_PORT, 0, 5); - if(fd < 0){ - fprintf(stderr, "ERROR:: Unable to communicate with %s\n" - " Is the cluster_cmd daemon running there?\n", - memb_id_to_name(membership, ids[i])); - continue; - } - msg_send(fd, buffer, strlen(buffer)); - msg_close(fd); - } - - while(1){ - FD_ZERO(&rset); - max_fds = msg_fill_fdset(&rset, MSG_ALL, MSGP_ALL); - /* have to wait at least as long a it takes before clients exec */ - timeout = (struct timeval){t+1,0}; - n = select(max_fds+1, &rset, NULL, NULL, &timeout); - - if(n < 0){ - continue; - } - - if(!n){ - break; - } - - while(n){ - memset(buffer, 0, sizeof(buffer)); - fd = msg_next_fd(&rset); - if(fd == -1) { break; } - n--; - if(fd == cluster_fd){ - switch(clu_get_event(cluster_fd)){ - case CE_NULL: - case CE_MEMB_CHANGE: - case CE_QUORATE: - case CE_INQUORATE: - cml_free(membership); - membership = clu_member_list(NULL); - msg_update(membership); - memb_resolve_list(membership, NULL); - continue; - case CE_SHUTDOWN: - default: - clu_disconnect(cluster_fd); - cluster_fd = -1; - return -1; - } - } - - resp++; - afd = msg_accept(fd, 1, &nodeid); - msg_receive(afd, buffer, sizeof(buffer)); - msg_close(afd); - printf("\nRESPONSE from %s::\n", memb_id_to_name(membership, nodeid)); - printf("%s\n", buffer); - } - } - - if(resp == 0){ - fprintf(stderr, "No responses.\n"); - } else { - printf("%d responses.\n", resp); - } - return 0; -} - diff --git a/magma/tests/cptester.c b/magma/tests/cptester.c deleted file mode 100644 index 1e5fc12..0000000 --- a/magma/tests/cptester.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Cluster Namespace Test Program. - * - * XXX Needs Doxygenification. - */ -#include <magma.h> -#include <dlfcn.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - - -void -perform_op(cluster_plugin_t *cp, char *op, char *data) -{ - void *lockp = NULL; - cluster_member_list_t *nodelist; - int x; - char foo[5]; - - if (strcmp(op, "null") == 0) { - cp_null(cp); - } else if (strcmp(op, "members") == 0) { - nodelist = cp_member_list(cp, NULL); - if (nodelist) { - for (x=0; x<nodelist->cml_count; x++) { - printf("Member ID %d: %s\n", - (int)nodelist->cml_members[x].cm_id, - nodelist->cml_members[x].cm_name); - } - } - } else if (strcmp(op, "quorum") == 0) { - printf("Quorum state = %d\n", cp_quorum_status(cp, NULL)); - } else if (strcmp(op, "version") == 0) { - printf("Version = %s\n", cp_plugin_version(cp)); - } else if (strcmp(op, "lock") == 0) { - if (!data) - data = "Something"; - - printf("Locking %s...", data); - fflush(stdout); - if (cp_lock(cp, data, CLK_EX, &lockp) == 0) { - printf("OK\n"); - printf("Press <ENTER> to unlock\n"); - fgets(foo, 2, stdin); - cp_unlock(cp, data, lockp); - } else { - printf("FAILED: %s\n", strerror(errno)); - } - } else { - printf("Function %s not implemented\n", op); - } -} - - -int -main(int argc, char **argv) -{ - cluster_plugin_t *cpp; - int fd; - - if (argc < 2) { - printf("usage: %s <libname> [<op> <data>]\n", - argv[0]); - return 1; - } - - cpp = cp_load(argv[1]); - if (!cpp) { - perror("cp_load"); - return 1; - } - - cp_init(cpp, NULL, 0); - fd = cp_open(cpp); - if (fd < 0) { - printf("Error: %s\n", strerror(-fd)); - return -1; - } - if (argc == 3) { - perform_op(cpp, argv[2], NULL); - } else if (argc == 4) { - perform_op(cpp, argv[2], argv[3]); - } - - cp_close(cpp, fd); - cp_unload(cpp); - - return 0; -} diff --git a/magma/tests/magma_tool.c b/magma/tests/magma_tool.c deleted file mode 100644 index 095050a..0000000 --- a/magma/tests/magma_tool.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Cluster Plugin Test Program. - * - * XXX Needs Doxygenification. - */ -#include <magma.h> -#include <dlfcn.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> - - -void -usage(char *arg0) -{ - printf( -"usage: %s <options>\n\n" -"Plugin debugging functions:\n\n" -"\tlist List plugins and their status\n" -"\tenable <plugin> Enable the specified plugin\n" -"\tdisable <plugin> Disable the specified plugin (DANGEROUS)\n" -"\n" -"Cluster debugging functions. These may be prepended by "login" to \n" -"force logging in to the specified service group.\n\n" -"\tlock [resource] Obtain a cluster resource lock\n" -"\tlisten [group] Listen for events (only useful with "login" \n" -"\t when using CMAN's Service Manager)\n" -"\tlocalname Display this member's name\n" -"\tlocalid Display this member's node ID\n" - -"\tmembers [group] List cluster members (optionally in [group]\n" -"\tquorum [group] Display cluster/node quorum/group state\n" -"\n" -"Other options:\n" -"\tconfig <item> Show library build configuration\n\n", arg0); -} - - -void -config_usage(char *arg0) -{ - printf( -"usage: %s config <item>\n" -"\tlibs Show library link flags\n" -"\tlibs-nt Show reentrant (non-pthread-encumbered) linker\n" -"\t flags\n" -"\tcflags Show CFLAGS necessary to build\n" -"\tplugindir Show where to install plugins\n" -"\tlibdir Show where dynamic libraries are installed\n" -"\tslibdir Show where static libraries are installed\n" -, arg0); -} - - - -void -wait_for_events(int fd, char *groupname) -{ - cluster_member_list_t *membership; - cluster_member_list_t *new, *lost, *gained; - fd_set rfds; - - membership = clu_member_list(groupname); - - print_member_list(membership, 1); - - printf("=== Waiting for events.\n"); - - while(1) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - select(fd+1, &rfds, NULL, NULL, NULL); - - switch(clu_get_event(fd)) { - case CE_NULL: - printf("-E- Spurious wakeup\n"); - break; - case CE_SUSPEND: - printf("*E* Suspend activities\n"); - break; - case CE_MEMB_CHANGE: - printf("*E* Membership change\n"); - - new = clu_member_list(groupname); - lost = memb_lost(membership, new); - gained = memb_gained(membership, new); - - if (lost) { - printf("<<< Begin Nodes lost\n"); - print_member_list(lost, 0); - printf("<<< End Nodes Lost\n"); - free(lost); - } - - if (gained) { - printf(">>> Begin Nodes gained\n"); - print_member_list(gained, 0); - printf(">>> End Nodes gained\n"); - free(gained); - } - - free(membership); - membership = new; - - break; - case CE_QUORATE: - printf("*E* Quorum formed\n"); - break; - case CE_INQUORATE: - printf("*E* Quorum dissolved\n"); - break; - case CE_SHUTDOWN: - printf("*E* Node shutdown\n"); - exit(0); - } - } -} - - -void -lock_something(char *lockname) -{ - void *lockp = NULL; - int ret; - - if (!lockname) - lockname = "Something"; - - printf("Locking "%s"...",lockname); - fflush(stdout); - - ret = clu_lock(lockname, CLK_EX, &lockp); - - if (ret != 0) { - printf("FAILED: %d\n", ret); - return; - } - - printf("OK\n"); - printf("Press <ENTER> to unlock\n"); - getchar(); - - printf("Unlocking "%s"...", lockname); - fflush(stdout); - if (clu_unlock(lockname, lockp) != 0) { - printf("FAILED\n"); - return; - } - printf("OK\n"); -} - - -void -perform_op(int fd, char *op, char *data) -{ - cluster_member_list_t *nodelist; - int x; - char *state; - char name[256]; - uint64_t nid; - - if (strcmp(op, "null") == 0) { - clu_null(); - } else if (strcmp(op, "localname") == 0) { - if (clu_local_nodename(data, name, 256) == 0) { - printf("Local node name = %s\n", name); - } - } else if (strcmp(op, "localid") == 0) { - if (clu_local_nodeid(data, &nid) == 0) { - printf("Local node id = 0x%x\n", (uint32_t)nid); - } - } else if (strcmp(op, "lock") == 0) { - lock_something(data); - } else if (strcmp(op, "members") == 0) { - nodelist = clu_member_list(data); - if (nodelist) { - for (x=0; x<nodelist->cml_count; x++) { - - switch (nodelist->cml_members[x].cm_state) { - case STATE_DOWN: - state = "DOWN"; - break; - case STATE_UP: - state = "UP"; - break; - default: - state = "UNKNOWN"; - break; - } - printf("Member ID 0x%016llx: %s, state %s\n", - (unsigned long long) - nodelist->cml_members[x].cm_id, - nodelist->cml_members[x].cm_name, - state); - } - } - } else if (strcmp(op, "quorum") == 0) { - switch (clu_quorum_status(data)) { - case (QF_QUORATE|QF_GROUPMEMBER): - state = "Quorate & Group Member"; - break; - case (QF_QUORATE): - state = "Quorate"; - break; - default: - state = "Inquorate"; - break; - } - printf("Quorum state = %s\n", state); - } else if (strcmp(op, "listen") == 0) { - printf("Listening for events (group %s)...\n", data?data:"ALL"); - wait_for_events(fd, data); - } -} - - -/** - ... uses internal magma library functions... - */ -int read_dirnames_sorted(char *dir, char ***filenames); -void free_dirnames(char **); - - -int -toggle_plugin(int argc, char **argv) -{ - struct stat sb; - char filename[1024]; - - if (argc < 3) { - printf("No file specified\n"); - usage(basename(argv[0])); - return 1; - } - - snprintf(filename, sizeof(filename), "%s/%s", - PLUGINDIR, argv[2]); - - if (stat(filename, &sb) < 0) { - fprintf(stderr, "Failed to %s %s: %s\n", argv[1], - argv[2], strerror(errno)); - return 1; - } - - if (S_ISDIR(sb.st_mode)) { - errno = EISDIR; - fprintf(stderr, "Failed to %s %s: %s\n", argv[1], - argv[2], strerror(errno)); - return 1; - } - - if (!strcmp(argv[1], "disable")) { - if (!(sb.st_mode & S_IRUSR)) { - fprintf(stderr, - "Failed to disable %s: Already disabled\n", - argv[2]); - return 1; - } - sb.st_mode &= (mode_t)(~S_IRUSR); - } else { - if (sb.st_mode & S_IRUSR) { - fprintf(stderr, - "Failed to enable %s: Already enabled\n", - argv[2]); - return 1; - } - sb.st_mode |= S_IRUSR; - } - - if (chmod(filename, sb.st_mode) < 0) { - fprintf(stderr, "Failed to %s %s: %s\n", argv[1], - argv[2], strerror(errno)); - return 1; - } - - return 0; -} - - -int -show_config(int argc, char **argv) -{ - /* XXX hardcoded ;( */ - if (argc < 3) { - config_usage(basename(argv[0])); - return 1; - } - - if (!strcmp(argv[2], "cflags")) { - printf("-I%s -DPLUGINDIR="%s"\n", INCDIR, - PLUGINDIR); - return 0; - } - - if (!strcmp(argv[2], "libs")) { - printf("-L%s -lmagma -lmagmamsg -lpthread -ldl\n", LIBDIR); - return 0; - } - - if (!strcmp(argv[2], "libs-nt")) { - printf("-L%s -lmagma_nt -ldl\n", LIBDIR); - return 0; - } - - if (!strcmp(argv[2], "libdir")) { - printf("%s\n", LIBDIR); - return 0; - } - - if (!strcmp(argv[2], "slibdir")) { - printf("%s\n", SLIBDIR); - return 0; - } - - if (!strcmp(argv[2], "plugindir")) { - printf("%s\n", PLUGINDIR); - return 0; - } - - config_usage(basename(argv[0])); - return 1; -} - - -int -list_plugins(void) -{ - int found = 0; - cluster_plugin_t *cp; - char **filenames; - int fcount = 0, l; - char *bname, *tab; - - printf("Magma: Checking plugins in %s\n", PLUGINDIR); - - if (read_dirnames_sorted(PLUGINDIR, &filenames) != 0) { - printf("Error reading %s: %s\n", PLUGINDIR, - strerror(errno)); - return -1; - } - - printf("\n"); - printf("File\t\tStatus\tMessage\n"); - printf("----\t\t------\t-------\n"); - - for (fcount = 0; filenames[fcount]; fcount++) { - - cp = cp_load(filenames[fcount]); - - bname = basename(filenames[fcount]); - l = strlen(bname); - if (l < 8) - tab = "\t\t"; - else - tab = "\t"; - - - if (cp == NULL) { - if (errno == EISDIR) - continue; - printf("%s%s[FAIL]\t%s\n", bname, tab, - cp_load_error(errno)); - continue; - } - - if (cp_init(cp, NULL, 0) < 0) { - printf("%s%s[FAIL]\t%s\n", bname, tab, - strerror(errno)); - cp_unload(cp); - cp = NULL; - continue; - } - - ++found; - - printf("%s%s[OK]\t%s\n", bname, tab, cp_plugin_version(cp)); - - cp_unload(cp); - cp = NULL; - } - - printf("\n"); - free_dirnames(filenames); - - if (!found) { - printf("Magma: No usable plugins found.\n"); - errno = ELIBACC; - return -1; - } - - printf("Magma: %d plugins available\n", found); - - return 0; -} - - -int -main(int argc, char **argv) -{ - int fd, login=0; - char *arg0 = basename(argv[0]); - - if (argc < 2 || (strcmp(argv[1], "-h") == 0)) { - usage(arg0); - return 1; - } - - if (!strcmp(argv[1], "login")) { - login = 1; - --argc; - ++argv; - } - - if (!strcmp(argv[1], "list")) { - return list_plugins(); - } - - if (!strcmp(argv[1], "enable")) { - return toggle_plugin(argc, argv); - } - - if (!strcmp(argv[1], "disable")) { - return toggle_plugin(argc, argv); - } - - if (!strcmp(argv[1], "config")) { - return show_config(argc, argv); - } - - - fd = clu_connect("cluster::usrm", login); - - if (fd < 0) { - switch(errno) { - case ESRCH: - fprintf(stderr, - "Connect failure: No cluster running?\n"); - break; - case ELIBACC: - fprintf(stderr, "Connect failure: No plugins " - "available (try '%s list')\n", - arg0); - break; - default: - perror("Connect failure"); - break; - } - return -1; - } - - printf("Connected via: %s\n",clu_plugin_version()); - - if (argc == 2) { - perform_op(fd, argv[1], NULL); - } else if (argc == 3) { - perform_op(fd, argv[1], argv[2]); - } - - clu_disconnect(fd); - - return 0; -} diff --git a/magma/tests/thread_test.c b/magma/tests/thread_test.c deleted file mode 100644 index d233345..0000000 --- a/magma/tests/thread_test.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Multithreaded cluster locking test program. - */ -#include <pthread.h> -#include <magma.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> - - -void * -thread_func(void *arg) -{ - void *lockp; - int max = *(int *)arg; - int ret, iter = 0; - - printf("Thread %u running %d iterations\n",(int)pthread_self(), - max); - - while (iter < max) { - ret = clu_lock("locky", CLK_EX, &lockp); - - if (ret != 0) { - printf("Denied: %s\n", strerror(errno)); - sleep(1); - continue; - } - - ++iter; - clu_unlock("locky", lockp); - } - - printf("Thread %u done\n", (int)pthread_self()); - return NULL; -} - - -int -main(int argc, char **argv) -{ - pthread_t th[10]; - int fd; - int x, max = 1, iter = 200; - void *ret; - struct timeval start, end; - - if (argc == 1) { - printf("Multithreaded Magma cluster locking test program\n"); - printf("\n"); - printf("usage: %s <num_threads> [lock_iterations]\n", - argv[0]); - printf(" num_threads 1 to 10, default = 1\n"); - printf(" lock_iterations 1 to 2^31-1, default = 200\n"); - return 1; - } - - if (argc >= 2) - max = atoi(argv[1]); - if (max > 10) - max = 10; - if (argc >= 3) - iter = atoi(argv[2]); - if (iter < 1) - iter = 1; - - fd = clu_connect("test::lock", 1); - - clu_null(); - - printf("Requested %d threads, %d iterations\n", max, iter); - - gettimeofday(&start, NULL); - - for (x = 0; x < max; x++) - pthread_create(&th[x], NULL, thread_func, &iter); - - for (x = 0; x < max; x++) - pthread_join(th[x], &ret); - - gettimeofday(&end, NULL); - - clu_disconnect(fd); - - start.tv_sec = end.tv_sec - start.tv_sec; - start.tv_usec = end.tv_usec - start.tv_usec; - if (start.tv_usec < 0) { - start.tv_sec--; - start.tv_usec += 1000000; - } - - printf("Time taken: %ld.%06ld seconds\n", (long)start.tv_sec, - (long)start.tv_usec); - - return 0; -} diff --git a/rgmanager/AUTHORS b/rgmanager/AUTHORS deleted file mode 100644 index 4172ad5..0000000 --- a/rgmanager/AUTHORS +++ /dev/null @@ -1,13 +0,0 @@ -Lon Hohberger lhh-@-redhat.com -* Resource tree -* Failover domains -* Resource agent scripts - -Gregory Myrdal [private] -* Misc utilities -* Resource agent scripts - -Jeff Moyer jmoyer-@-redhat.com -* Syslog wrapper & logging program - -Portions of this code (C) 2000-2001 Mission Critical Linux, Inc. diff --git a/rgmanager/COPYING b/rgmanager/COPYING deleted file mode 100644 index d60c31a..0000000 --- a/rgmanager/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. -
- GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) -
-These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. -
- 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. -
- 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -
- How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/rgmanager/ChangeLog b/rgmanager/ChangeLog deleted file mode 100644 index f4092f8..0000000 --- a/rgmanager/ChangeLog +++ /dev/null @@ -1,312 +0,0 @@ -2008-03-04 Lon Hohberger <lhh at redhat.com> - * src/resources/Makefile, oracledb.sh: Add Oracle 10g failover - support (#182423) - -2008-02-26 Lon Hohberger <lhh at redhat.com> - * src/resources/ip.sh: Fix incorrect netmask handling; bz #434886 - -2008-01-28 Lon Hohberger <lhh at redhat.com> - * include/rg_locks.h, src/daemons/groups.c, rg_locks.c: - fix #430538 - unbounded status / clustat thread counts cause - timeout errors - * src/daemons/main.c, src/utils/clulog.c: Incorrect ccs API - return code processing results in unwanted log messages - * src/resources/nfsclient.sh: Fix #292861 - unexport doesn't work - -2007-10-26 Lon Hohberger <lhh at redhat.com> - * src/daemons/main.c, src/utils/clustat.c, clusvcadm.c: Call - msg_set_nodeid() to ensure we route from the right IP on a - host with multiple IPs on our cluster subnet. - -2007-10-03 Lon hohberger <lhh at redhat.com> - * ChangeLog: Fix dates. - * include/reslist.h: Actually commit fix for #310981 - -2007-09-28 Lon hohberger <lhh at redhat.com> - * include/reslist.h, src/daemons/resgroup.c, restree.c: - Fix #310981 - -2007-09-25 Lon Hohberger <lhh at redhat.com> - * src/resources/clusterfs.sh: Make self_fence work. #252241 - * src/resources/SAPInstance, SAPDatabase, Makefile: Add - SAP resource agents #204084 - -2007-07-31 Lon Hohberger <lhh at redhat.com> - * src/daemons/groups.c, rg_thread.c: Fix #246669 - status check unbounded - but should be 1 - -2007-06-28 Marek Grac <mgrac at redhat.com> - * src/resources/named.sh, named.metadata: Add resource agent - for named (fix #213524) - -2007-06-28 Marek Grac <mgrac at redhat.com> - * src/daemons/rg_state.c: Fix #236431. Message: Taking over service - serv from down member (null) shows correct member (if possible). - -2007-06-22 Marek Grac <mgrac at redhat.com> - * src/daemons/reslist.c: Apply patch from Lon (same as in RHEL5) to - fix #245171 attr inheritance should try all direct ancestors. - -2007-05-03 Lon Hohberger <lhh at redhat.com> - * Merge patch from Crosswalk development team: - * Scott Cannata - * Henry Harris - * Leonard Maiorani - * src/daemons/groups.c, rg_state.c: Apply patch from Andrey - Mirkin to fix bug #237144; prevents exclusive services from - being accidentally (or intentionally) being started on the - same node - * src/daemons/restree.c: Don't print (null) when an attr - isn't inherited - * src/daemons/reslist.c: Try all direct ancestors while - performing run-time inheritance resolution #231521 - * src/daemons/tests/*: Clean up test cases; don't look for (null) - any more - -===== - -2006-11-03 Lon Hohberger <lhh at redhat.com> - * src/daemons/restree.c: Merge patch from Jeff Layton to instrument - res_exec more closely. (#213246) - * src/daemons/rg_thread.c: Fix segfault caused by improper loop - semantics (#213312) - -2006-10-05 Lon Hohberger <lhh at redhat.com> - * src/clulib/clulog.c: Change stdout/stderr to nonblocking (#207144 - part 1) - * src/daemons/main.c: Give a timeout for a message to be received - after msg_accept() so that if we are processing a message from a - client which died, we don't wait forever, thereby preventing - group updates (#207144 part 2). - -2006-09-27 Lon Hohberger <lhh at redhat.com> - * src/daemons/rg_state.c: Fix fail->disable state transitions, - bugzilla #208011 - -2006-09-07 Lon Hohberger <lhh at redhat.com> - * src/daemons/main.c, init.d/rgmanager: Make rgmanager init script - report failure correctly in most cases. (#193603) - * src/utils/clustat.c: Fix #146924 - segfault if cman is not - in a state to give out member lists - -2006-06-21 Lon Hohberger <lhh at redhat.com> - * src/daemons/nodeevent.c: Don't use the rg thread refcount in - node event handling (#194491) - -2006-06-16 Lon Hohberger <lhh at redhat.com> - * src/daemons/fo_domain.c, groups.c: Get rid of compiler warnings - * src/daemons/rg_state.c: Change clu_lock_verbose to use the NULL - lock/convert mechanism offered by DLM to work around #193128 - * src/daemons/restree.c: Apply patch from Navid Sheikhol-Eslami - (navid at redhat.com) to fix #193859 - * src/resources/fs.sh, clusterfs.sh, nfsexport.sh, nfsclient.sh, - service.sh, svclib_nfslock: Finish up initial NFS workaround. - -2006-05-23 Lon Hohberger <lhh at redhat.com> - * src/daemons/members.c: Zap pad fields on copy-out - * src/daemons/main.c: Give notice if skipping an event because of - locked services. Call the self-watchdog init function - * src/daemons/watchdog.c: Add Stanko Kupcevic's self-watchdog from - CVS head (fixes #193247) - * src/daemons/groups.c: Add debug messages. Actually count - resgroups during node transition handling - * src/daemons/rg_state.c: allow failover of stopping services if - the owner died (#193255) - * src/utils/clustat.c: fix typo, misc. usability problems (#192999) - -2006-05-16 Lon Hohberger <lhh at redhat.com> - * src/resources/nfsclient.sh: Fix 189218 - nfsclient not matching - wildcards correctly when checking status. Allow disabling of - recovery for services where the nfs clients are ordered (this will - cause a full service restart, but works) - * src/resources/clusterfs.sh, fs.sh, svclib_nfslock, service.sh: - Implement rudimentary atomic bomb-style NFS lock reclaim handling - Needs compatible and correctly configured version of nfs-utils - installed and running on the system. For clusterfs.sh, ensure - that we flush buffers during service tear-down - regardless of - whether or not we unmount the file system. - * src/utils/clunfslock.sh: HA-callout program (/usr/sbin/clunfslock) - for use with the rpc.statd -H parameter. Copies the client to all - cluster-managed mounted file systems so that it will get lock - reclaim notification on failover. - -2006-05-09 Lon Hohberger <lhh at redhat.com> - * include/list.h: Prevent dereferencing curr if it's null for some - reason - * include/resgroup.h: Clean up alignment, add rgmanager lock/unlock - message types - * src/daemons/Makefile: Add nodeevent.o to the build for rgmanager - * src/clulib/msgsimple.c: Misc code path cleanups - * src/clulib/vft.c: Add local reads for fast clustat operation. - * src/daemons/groups.c: Count all resource groups for all nodes - in one pass, rather than one node per pass. Split queueing of - status checks off so we never block the main thread. Mark services - which have autostart=0 in the config as "disabled" to help remove - confusion between "disabled", "stopped", and the no-longer-needed - "stopped but behave like disabled" states. bz #182454 / - #190234 / #190408 - * src/daemons/fo_domain.c: Add patch from Josef Whiter to - implement no-failback option for a given FO domain - bz #189841 - * src/daemons/main.c: Queue node events for another thread to - handle, so we never block the main thread. Also, implement - cluster-wide service lock/unlock feature from clumanager 1.2.x - - bz #175010 - * src/daemons/nodeevent.c: Split out node event queueing / handling - in to a separate thread so the main thread does not block - * src/daemons/rg_state.c: Return error codes if resource groups - are locked. - * src/daemons/rg_thread.c: Fix assertion failure causing segfault - in extremely rare cases. Quash the rg queue during shutdown. - - bz #181539 - * src/daemons/rg_state.c: Add fast local service state query to - reduce unnecessary lock contention - * src/daemons/groups.c: Handle request for expedited information - from clustat. - * src/daemons/main.c: Pass arg1 to send_rg_states() to enable fast - clustat operation. - * src/resources/fs.sh: Implement user/group quota support if - enabled in the file system options - * src/utils/clustat.c: Misc. error handling. Add single service / - member output and add -Q to the help information. #185952. - Added -f flag. - * src/utils/clusvcadm.c: Implement client-side of #175010 - * src/utils/clustat.c: show transition time in clustat -x - - bz #191398 - * src/resources/fs.sh: enable user/group quotas if enabled in the - options attribute - bz #191182 - * init.d/rgmanager: fix typo - bz #191205 - - -------------- - -2005-03-21 Lon Hohberger <lhh at redhat.com> - * init.d/rgmanager, Makefile: Fix up init script and add Makefile - so that the init script is properly installed #142754 - * src/daemons/*: Fixes for #150344, #151187: Relocate to same node - returns failure, hang during shutdown if user relocate is in-flight. - Fix service state getting stuck in "recoverable" on fail-to-start - scenarios where other nodes failed (or no other node was available) - Rename "resourcegroup" to "service" to be consistent with UI - * src/resources/fs.sh, clusterfs.sh: Fix #151077: Force unmount broken - * src/resources/netfs.sh: Fix #151091: netfs status broken - * src/resources/resourcegroup.sh, service.sh: Remove resourcegroup, - rename to service.sh - -2005-03-14 Lon Hohberger <lhh at redhat.com> - * src/resources/clusterfs.sh, fs.sh: Make clusterfs actually work. - Clean up fs.sh + clusterfs.sh "status" when mount reports none/ - devpets/usbdev/etc. - * src/daemons/test.c: Add a 'rules' test function for printing - resource rules to stdout. - * src/daemons/reslist.c: Fix 151095 - -2005-03-07 Lon Hohberger <lhh at redhat.com> - * include/resgroup.h: Add STOP_USER so we can handle user - STOP (instead of just DISABLE) requests. #150333 - * src/resources/fs.sh: umount should umount mount points, not - devices. Handle symlinks to file system block devices. #150481 - * src/clulib/rg_strings.c: Add user stop string. - * src/clulib/gettid.c: errno fix from trunk - * src/clulib/vft.c: Connect timeout extension for VF - * src/daemons/main.c: Separate connect + login. GuLM doesn't know - about SGs. - * src/daemons/rg_state.c: Change stop handling. Add generic recover - function. - * src/daemons/rg_thread.c: Add support for RESTART, USER_STOP. - #150330, #150333 - * src/utils/clusvcadm.c: Use USER_STOP to signal a user-called stop. - #150333 - -2005-03-02 Lon Hohberger <lhh at redhat.com> - * include/clulog.h: Change default log level to INFO - * include/resgroup.h: Add proto for "best_target_node" - * src/clulib/clulog.c: Change log facility to LOG_DAEMON to match - other cluster daemons (e.g. lock_gulmd) - * src/daemons/groups.c: Add best_target_node, count_resource_groups. - Implement missing autostart-disable feature and requested exclusive - resource group feature. Store configuration view number so we can - tell when the configuration changes. - * src/daemons/main.c: Print node state transition messages before - calling node_event(). Use do_status_checks() so we don't try to - check services we're not running. Bump periodic status event - queueing to 10 seconds instead of 5. Poll ccsd for config updates - since we have no other way to find them. Fix bug preventing - status checks when clustat -i 1 is running. - * src/daemons/rg_state.c: Fix handle_relocate_req so that it uses - best_target_node() correctly. Leave services which failed on all - current nodes as 'stopped', so the next node transition will cause - us to try to restart it automagically. Consider recovery policy - when taking recovery action. - * src/daemons/rg_thread.c: Use recovery routine instead of start. - * src/daemons/restree.c: Fix tree delta updates. - * src/resources/resourcegroup.sh: Add 'exclusive' parameter. Change - 'autostart' to a boolean instead of string. Add recovery policy - parameter. - * src/utils/clusvcadm.c: Make "relocate to node X" work. - -2005-02-28 Lon Hohberger <lhh at redhat.com> - * errors.txt: Remove random whitespace at the bottom. - * include/resgroup.h: Add do_status_checks proto - * include/rg_queue.h: Remove __ definitions so as not to conflict - with glibc internals. - * include/vf.h: Increase VF_COORD_TIMEOUT to something reasonable. - * src/daemons/groups.c: Add do_status_checks(). We were previously - queueing status checks for RGs that we didn't own. Not useful. - * src/daemons/main.c: Fix for #149410. - * src/daemons/rg_state.c: Fix various failover service problems. - * src/resources/script.sh: Remove "recover" from generic script - wrapper. - -======================================================================= - -2004-09-23 Lon Hohberger <lhh at redhat.com> - * include/reslist.h: Add needstart/needstop/common flags for - reconfiguration. Added RS_CONDSTART/CONDSTOP to perform "stop - if needed/start if needed" operations after a resource [group] - reconfiguration. Cleaned up structures. Added NO_CCS define for - testing. - * src/daemons/fo_domain.c: Added NO_CCS defines for testing. - * src/daemons/main.c: Added reconfigure() stub function. Added - testing support. - * src/daemons/reslist.c: Added comparsion + primary-attr functions - for resources. Add printout of needstart/stop in resource dump. - * src/daemons/restree.c: Added resource list comparsion + - resource tree comparison functions. Added condstart/stop to ops - list. Added CONDSTART/CONDSTOP handling in res_op. - * src/daemons/rg_locks.c: Added NO_CCS support for testing. - -2004-09-13 Lon Hohberger <lhh at redhat.com> - * include/resgroup.h: Add a default check interval. - * include/reslist.h: Add a recover operation, and put operations - and checks together in each instantiated resource structure. - * src/daemons/groups.c: Don't use the old rg_status() func -- - its internals have changed. - * src/daemons/reslist.c: Duplicate the action structure of a - parent resource type into an instantiated resource. - * src/daemons/resrules.c: Find the actions with the correct - path. - * src/daemons/restree.c: Add depth parameter to res_exec. Add - do_status - find the highest check/status level to perform given - the elapsed time since another status operation was performed. - Add a reference count each time a resource is started on a node. - * src/daemons/rg_thread.c: Implement periodic status checks. - Currently (in contrast to clumanager 1.2), these status checks - are automatic and not configurable. - * src/resources/*: Misc updates re: check intervals, new - parameters, etc. - -2004-09-07 Lon Hohberger <lhh at redhat.com> - * src/resources/group.sh: Add 'autostart' parameter to group - entity - * src/daemons/*: Add support for OCF 'action' specifications. - -2004-08-30 Lon Hohberger <lhh at redhat.com> - * src/resources/*: Add status/monitor actions to metadata - * include/list.h: Update to fix compiler warnings. This is not - complete; it's better to add a 'field' to structures requiring - list specs. - * src/clulib/vft.c: Remove unnecessary pthread locks. - * src/daemons/*: Misc. code cleanups. - -2004-08-12 Lon Hohberger <lhh at redhat.com> - * global: prepare for RPM build diff --git a/rgmanager/INSTALL b/rgmanager/INSTALL deleted file mode 100644 index 747e893..0000000 --- a/rgmanager/INSTALL +++ /dev/null @@ -1,7 +0,0 @@ -Note: This only works on Linux; it's a silly thing to try to get it to run -elsewhere, but good luck. Accepting patches ;) - -./autogen.sh -./configure -make all install - diff --git a/rgmanager/Makefile b/rgmanager/Makefile deleted file mode 100644 index 27ef596..0000000 --- a/rgmanager/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd src && ${MAKE} all - -clean: - cd src && ${MAKE} clean - -distclean: clean - rm -f make/defines.mk - -install: - cd src && ${MAKE} install - cd man && ${MAKE} install - cd init.d && ${MAKE} install - -check: - cd src && ${MAKE} check - -uninstall: - cd src && ${MAKE} uninstall diff --git a/rgmanager/NEWS b/rgmanager/NEWS deleted file mode 100644 index 583c7c0..0000000 --- a/rgmanager/NEWS +++ /dev/null @@ -1 +0,0 @@ -2004-Aug-12 NEWS file created! diff --git a/rgmanager/README b/rgmanager/README deleted file mode 100644 index c8d73fe..0000000 --- a/rgmanager/README +++ /dev/null @@ -1,359 +0,0 @@ -This is a clustered resource group manager layered on top of Magma, a -single API which can talk to multiple cluster infrastructures via their -native APIs. This resource manager requires both magma and one or more -plugins to be available (the dumb plugin will work just fine, but will -only get you one node...). - - -Note: I tend to use "service" and "resource group" to mean the same -thing. While they are slightly different, "services" were simply -collections of different things (IPs, file systems, etc.), as are -resource groups. - -Introduction - -The resource manager is a daemon which provides failover of user-defined -resource collected into groups. It is a direct descendent of the -Service Manager from Red Hat Cluster Manager 1.2, which is a descendent -of Cluster Manager 1.0, which is a descendent of Kimberlite 1.1.0. -The primary reason for a rename was to avoid confusion with the Service -Manager present in David Tiegland's Symmetric Cluster Architecture paper -and software, with which this application must collaborate. - -The simplicity, ease of maintenance, and stability in the field has led -us to attempt to preserve as much of the method of operations of Cluster -Manager's Service Manager, but certain aspects needed to be removed in -order to provide a more flexible framework for users. - -At this point, the resource manager is designed primarily for cold -failover (= application has to restart entirely). This allows a lot of -flexibility in the sense that most off-the-shelf applications can -benefit from increased availability with minimal effort. However, it -may be extended to support warm and even hot failover if necessary, -though these models require often require application modification - -which is outside the scope of this readme. - - -Goals and Requirements - -(1) Supercede Red Hat Cluster Manager's capabilities with respect to -service modification. Red Hat Cluster Manager's resource model was -based on an old model from Kimberlite 1.1.0. In this model, services -were entirely monolithic, and had to be disabled in order to be changed. -This meant that if one had an NFS service with a list of clients and a -new client was added, all other clients had to lose access in order to -add the new client. In short, provide for on-line service modification -and have intelligence about what to restart/reload after a new -configuration is received. Note that this intelligence is not yet -completed, but the framework exists for it to be completed. - -(2) Be able to use CMAN/DLM/SM and GuLM cluster infrastructures. This -is done via magma. - -(3) Use CCS for all configuration data. - -(4) Be able to queue requests for services. This is forward-looking -towards things such as event scheduling (e.g. disable this resource -group at this time in the future). - -(5) Provide an extensible set of rules which define resource structure. -This is accomplished by providing rule sets which essentially define how -resources may be defined in CCS. These rule sets attempt to be OCF -RA API compliant. This has the side effect of partially solving (1) -for us. - -(6) Use a distributed model for resource group/service state. This is -currently done with a port of the View-Formation code from Cluster -Manager 1.2. Ideally, it would be nice to use LVBs in the DLM or GuLM -to distribute this state; but it probably requires >64 bytes (DLM's -limit). Another model is client-server like NFS, where clients tell -the new master what resource groups they have. However, this has -implications if the server fails and was running a RG. - -(7) Combination of 3 and 6 gives us: no dependency on shared storage. - -(8) Be practical. Try to follow the model from clumanager 1.x as much -as possible without sacrificing flexibility. It should be easy to -convert an existing clumanager 1.2 user to use this RM. While it will -be impossible to perform a rolling upgrade from clumanager 1.2 to this -RM, it should be easy to convert an existing installation's -configuration information. - -(9) Try to be OCF compliant across how the resource scripts are written. -While this is a goal, it is not a guarantee at this point. - -(10) Work with the same fencing model as clumanager and GFS (i.e. -"top-down" - the infrastructure handles it). Resource-based fencing, -for example, is specifically not a goal at this point. - -(11) Be scalable without being overly complex ;) Note that we're not -very scalable at the moment (VF is too slow for this kind of thing) - -(12) Introduce other failover/balancing policies (instead of just -failover domains). - - -Directory Structure - -include/ - -Include files - -src/daemons/ - -The RM daemon and clurmtabd (from RHEL3), which keeps /var/lib/nfs/rmtab -in sync with clustered exports, or tries to. - -src/utils/ - -Home of various utilities including clustat and clusvcadm. - -src/clulib/ - -Library functions which aren't necessarily tied to a specific daemon. -This was more important in clumanager 1.2; and is mostly cruft at this -point. - -src/resources/ - -Shell scripts and resource XML rules for various resources. Includes -a DTD to validate a given resource XML rule. - - -Implementation - Handling of Client Requests - -The resource manager currently uses a threaded model which has a -producer thread and a set of consumer threads with their own work -queues. - - Client <--(result)---------+ - | | - (req) | - | [Handle request] - | ^ - v | -Listener --(req)--> Resource group thread - -In a typical example, the client sends a request to the listener thread. -The listener accepts hands it off to a resource group queue and -immediately resumes listening for requests. Queueing the request on a -resource thread queue has a side effect of spawning a new resource group -thread if one is needed. The resource group thread pulls the request -off of its work queue and handles the request. After the request -completes, the resource thread sends the result of the operation back to -the client. If no other requests are pending and the last operation -resulted in the resource group being in a non-running state (stopped, -disabled, etc.), then the resource group thread cleans itself up and -exits. - -The resource manager handles failed resource groups in a simplistic -manner which is the same as how Red Hat Cluster Manager handled -failover. If a resource group fails a status check, the resource -manager stops the affected RG. If the 'STOP' operation succeeds, then -the RM tries to restart the RG. If this succeeds, the RM is done. - -However, if it fails to restart/recover the resource group, it again -stops the RG and attempts to determine the best-available online node -based on the failover domain or (not implemented yet) least-loaded -cluster member. If none are available, or all members fail to start the -RG, the RG is disabled. - - -Cluster Events - -Cluster events are provided by a cluster-abstraction library called -Magma. Magma currently runs with CMAN/DLM, gulm, or no cluster -infrastructure at all (e.g. one node, always-quorate-pseudo-cluster). - -Magma provides group membership lists, state of the cluster quorum (if -one exists), cluster locking, and (in some cases), barriers - so the RM -needs to implement none of the above. - -Cluster events are handed to the listener thread via a file descriptor, -and can affect resource group states. For instance, when a member is no -longer quorate, all resource groups are stopped immediately (and, quite -normally, the member is fenced prior to this actually completing!). - -Whenever a node transition occurs (or in the SM case, a node joins the -requisite service group), all RG states are evaluated to see if they -should be moved about or started (or failed-over), depending on the -failover domain (or other policies which are not yet implemented). - - -The Resource Tree - -In clumanager 1.x (and Kimberlite, for that matter), the attributes of -various resources attributes were read one by one, as required, inside -of a large shell script. This had several benefits (hard dependency -enforcment, maintenance, support, etc.), but had several drawbacks as -well; the most important being flexibility. - -In contrast to clumanager 1.x, the resource groups are now modeled in -the daemon's RAM as tree structures with all their requisite -attributes loaded from CCS based on external XML rules. - -After a resource is started, it follows down the tree and starts all -dependent children. Before a resource is stopped, all of its dependent -children are first stopped. Because of this structure, it is possible -to add or restart, for instance, an "NFS client" resource without -affecting its parent "export" resource. By determining the delta -between resource lists and/or resource trees, it's possible to use this -information to automatically restart a node in the tree and all its -dependent children in the event of a configuration change. - -The tree can be summarized as follows: - - group - ip address... - file system... - NFS export... - NFS client... - samba share(s)... - script... - - -Resource Agents - -Resource agents are scripts or executables which handle operations for a -given resource (such as start, stop, restart, etc.). See the OCF RA API -v1.0 for more details on how the resource agents work: - - http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/ - -The resource agents and handling should be OCF compliant (at least in -how they are called), primarily because it is fairly nonsensical to -require third party application developers to write multiple differing -application scripts in order to have their application work in different -cluster environments on an otherwise similar system [1]. - - -The XML Resource Rules - -The XML Resource Rules are encapsulated in the resource agent scripts, -which attempt to follow the OCF RA API 1.0. The RA API, however, does -not work with the goals of this project as it exists today, so there are -a few extensions to the ra-api-1.dtd. - - * Addition of a 'required' tag parameter elements. This allows the UI - and/or the resource group manager to determine if a resource is - configured properly without having to ask the resource agent itself. - * Addition of a 'primary' tag parameter elements. This allows the - resource tree to reference resource instances using the 'ref=' - tag in the code. - * Addition of an 'inherit' tag to allow resources to inherit a parent - resources' parameters. - -Additionally, there is some data which is used in the 'special' element -of the RA API DTD. - -Description of rgmanager-specific block. - -<!ELEMENT attributes> -<!ATTLIST - root (0|1) #IMPLIED - maxinstances CDATA #IMPLIED> - - * root: This is the root resource type. This should only exist in the - 'group' resource, generally. - * maxinstances: This is the maximum number of instances in the resource - tree this resource may exist. - -Description of a resource type or attribute. - -<!ELEMENT child EMPTY> -<!ATTLIST child - type CDATA #REQUIRED - start CDATA #IMPLIED - stop CDATA #IMPLIED> - -Describes a valid child rule type. - - * type: Resource type which is to be declared as a valid child for - this resource type. - * start: Start level of this child type. All resource children at - level '1' are started before all resource children at level '2'. - Valid values are 1-99. - * stop: Stop level of this child type. All resource children at level - '1' are stopped before all resource children at level '2'. - Valid values are 1-99. - - -Failover Domains - -A failover domain is an ordered subset of cluster members to which a -resource group may be bound. The following is a list of semantics -governing the options as to how the different configuration options -affect the behavior of a resource group which is bound to a particular -failover domain: - - * restricted domain: Resource groups bound to the domain may only run - on cluster members which are also members of the failover domain. If - no members of the failover domain are available, the resource group - is placed in the stopped state. - - * unrestricted domain: Resource groups bound to this domain may run on - all cluster members members, but will run on a member of the domain - whenever one is available. This means that if a resource group is - running outside of the domain and a member of the domain transitions - online, the resource group will migrate to that cluster member. - - * ordered domain: Nodes in an ordered domain are assigned a priority - level from 1-100, priority 1 being the highest and 100 being the - lowest. A member of the highest priority group will run a resourece - group bound to a given domain whenever one is online. This means - that if member A has a higher priority than member B, the resource - group will migrate to A if it was running on B if A transitions from - offline to online. - - * unordered domain: Members of the domain have no order of preference; - any member may run the resource group. Resource groups will always - migrate to members of their failover domain whenever possible, - however, in an unordered domain. - -Ordering and restriction are flags and may be combined in any way (ie, -ordered+restricted, unordered+unrestricted, etc.). These combinations -affect both where resource groups start after initial quorum formation -and which cluster members will take over resource groups in the event -that the resource group or the member running it has failed (without -being recoverable on that member). - - -Failover Domains (Examples) - -Given a cluster comprised of this set of members: {A, B, C, D, E, F, G} - -Ordered, restricted failover domain {A(1), B(2), C(3)}. A resource group -'S' will always run on member 'A' whenever member 'A' is online and -there is a quorum. If all members of {A, B, C} are offline, the -resource group will be stopped. If the resource group is running on 'C' -and 'A' transitions online, the resource group will migrate to 'A'. - -Unordered, restricted failover domain {A, B, C}. A service 'S' will only -run if there is a quorum and at least one member of {A, B, C} is online. -If another member of the domain transitions online, the service does not -relocate. - -Ordered, unrestricted failover domain {A(1), B(2), C(3)}. A resource -group 'S' will run whenever there is a quorum. If a member of the -failover domain is online, the resource group will run on the highest -ranking member. That is, if 'A' is online, the resource group will run -on 'A'. - -Unordered, unrestricted failover domain {A, B, C}. This is also called a -"Set of Preferred Members". When one or more members of the failover -domain are online, the service will run on a nonspecific online member -of the failover domain. If another member of the failover domain -transitions online, the service does not relocate. - - - -Notes: - -[1] Lars Marowsky-Bree pointed this out; which makes perfect sense. The -OCF RA API attempts to follow LSB with respect to how init-scripts -handle starting/stopping/status of daemons and such, so it was directly -in line with where we were going with this RM. - -[2] This is derived from the OCF RA metadata DTD: - - http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/ra-api-1.dtd diff --git a/rgmanager/TODO b/rgmanager/TODO deleted file mode 100644 index df78649..0000000 --- a/rgmanager/TODO +++ /dev/null @@ -1,22 +0,0 @@ -* Not currently tested with GuLM. - -* Online configuration works, but needs SIGHUP from either ccsd or - a ccsd-called-program - -* I suspect View-Formation is not scalable more than about 32 nodes -the way it's currently implemented. - - Another implementation would be to only keep track of pieces of data - relevant to resource groups running on each node and update a - centralized server. This is more scalable, but requires more recovery - in the event that the centralized server fails. Centralized server - can simply be high-node-ID or low-node-ID of the current active - membership. - -* No man pages. - -* Init script 100% broken. - - Ok, all we need to do is start clurgmgrd and stop it. - -* Write RHEL 3 -> LCP upgrade. - - Should be simple; the resource group structure is based on the RHEL3 - cluster manager model. diff --git a/rgmanager/configure b/rgmanager/configure deleted file mode 100755 index f1df418..0000000 --- a/rgmanager/configure +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Long; - -print "\nConfiguring Makefiles for your system...\n"; - -# Set a bunch of variables -$CC = gcc; - -$ret = 0; - -%options = ( - help => $help, - incdir => $incdir, - kernel_src => $kernel_src, - libdir => $libdir, - mandir => $mandir, - prefix => $prefix, - sbindir => $sbindir, - sharedir => $sharedir, - verbose => $verbose -); - -$err = &GetOptions (%options, - 'help', - 'incdir=s', - 'kernel_src=s', - 'libdir=s', - 'mandir=s', - 'prefix=s', - 'sbindir=s', - 'sharedir=s', - 'verbose'); - -if(!$err) { - $ret = 1; - print "*** ERROR: Invalid option detected ***\n"; -} - -# Check for the --help flag -if ($help || !$err) { - $_ = $0; - s/.*./(.*)/\1/; - print "Usage: $_ [flags]\n"; - print "--help\t\tPrints this usage information\n\n"; - print "install flags:\n"; - print "--incdir=\tthe base directory for include files. (Default: /usr/include)\n"; - print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: system dependant)\n"; - print "--libdir=\tthe base directory for libraries. (Default: /usr/lib)\n"; - print "--mandir=\tthe base directory for man pages. (Default: /usr/share/man)\n"; - print "--prefix=\tthe base directory to install into. (Default: /)\n"; - print "--sbindir=\tthe base directory for system binaries. (Default: /usr/sbin)\n"; - print "--sharedir=\tthe base directory for misc cluster files. (Default: /usr/share/cluster)\n"; - print "--verbose\t\tVerbose output\n"; - exit $ret; -} - -verbose("------------------------------------------------"); - -$pwd = `pwd`; -chomp($pwd); - -if (!$incdir) { - $incdir="${prefix}/usr/include"; -} -if (!$libdir) { - $libdir="${prefix}/usr/lib"; -} -if (!$mandir) { - $mandir="${prefix}/usr/share/man"; -} -if (!$sbindir) { - $sbindir="${prefix}/usr/sbin"; -} -if (!$sharedir) { - $sharedir="${prefix}/usr/share/cluster"; -} - - -open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin"; -open OFILE, ">make/defines.mk" or die "Can't redirect stdout"; - -print OFILE "# This file was generated by configure from defines.mk.input\n"; - -while (<IFILE>) { - chomp; - $_ =~ s/@CC@/${CC}/; - $_ =~ s/@INCDIR@/$incdir/; - $_ =~ s/@KERNEL_SRC@/$kernel_src/; - $_ =~ s/@LIBDIR@/$libdir/; - $_ =~ s/@MANDIR@/$mandir/; - $_ =~ s/@SBINDIR@/$sbindir/; - $_ =~ s/@SHAREDIR@/$sharedir/; - print OFILE "$_\n"; -} - -close IFILE; -open IFILE, "<make/release.mk.input" or die "Can't redirect stdin"; -while (<IFILE>) { - chomp; - if($_ =~ /RELEASE_MAJOR\s=\s(.*)/){ - $release_major = $1; - } elsif($_ =~ /RELEASE_MINOR\s=\s(.*)/){ - $release_minor = $1; - } -} - -if($release_minor =~ m/DATE/i){ - $release_minor = `date +%s`; - chomp $release_minor; -} - -print OFILE "RELEASE_MAJOR = $release_major\n"; -print OFILE "RELEASE_MINOR = $release_minor\n"; -print OFILE "RELEASE = $release_major.$release_minor\n"; -close OFILE; - -verbose("--------------------------------"); -print "Completed Makefile configuration\n\n"; - -sub find_tool($tool_name) -{ - my($tool_name) = shift(@_); - preverbose("Checking for the presence of $tool_name"); - open SV, "scripts/find_executable $tool_name |"; - if (<SV>) { - print "\n'$tool_name' not found. Make sure you have '$tool_name' installed and in your path.\n"; - die "Configure error: Can't find '$tool_name'."; - } - postverbose("found $tool_name"); -} - -sub preverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg..."; - } -} - -sub verbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - -sub postverbose($msg) { - if($verbose) { - $msg = shift(@_); - print "$msg\n"; - } -} - - diff --git a/rgmanager/errors.txt b/rgmanager/errors.txt deleted file mode 100644 index 14e1c68..0000000 --- a/rgmanager/errors.txt +++ /dev/null @@ -1,554 +0,0 @@ -Service (Resource Group) Manager Errors - -Herein lie explanations as to the various errors and warnings that you may -see while running the resource group manager. This is meant to be -all-inclusive; if any error messages or warning messages are experienced -which are not explained below, please file a bugzilla: - -http://bugzilla.redhat.com/bugzilla - -#1: Quorum Dissolved - -The cluster infrastructure has reported to the resource group manager that -the local node and/or entire cluster is inquorate. At this point, all -services and resources managed by the resource group manager are stopped -and the resource group manager restarts, waiting for a quorum to form. - -If this node was disconnected, it should be evicted and fenced by the rest -of the cluster. Nodes which become inquorate may reboot themselves. - -#2: Service <name> returned failure code. Last owner: <name> - -The resource group named <name> has failed to stop. This generally means -that it may not be automatically recovered and that the system administrator -must intervene in order to cleanly restart the service. Services which -fail must first be disabled then re-enabled. However, be sure that all -resources have been properly cleaned up first. Generally, a hard reset -of the node on which the service failed will restore it to working order -and is the safest measure to take prior to restarting the failed service. - -This, however, is not required. - -#3: Service <name> returned failure code. Last owner: -<integer> - -Same as #2, but the node name was not determinable given the node ID. - -#4: Administrator intervention required. - -Only occurs after #2 or #3. Complaint stating that the administrator -must take action after a service failed. See #2. - -#5: Couldn't connect to ccsd! - -The resource group manager was unable to connect to ccsd. This generally -means that ccsd was not running at the time the resource group manager -tried to connect. Starting ccsd generally solves this. If this does -not solve it, try checking firewall rules to ensure that the connection -to ccsd's port is not blocked. Additionally, it could be that there is -a conflict between ccsd and the version of the system library (libccs) that -rgmanager was built against. - -#6: Error loading services - -The resource group manager was unable to load configuration information -from ccsd. This could mean a communication problem or an invalid -configuration. - -This error is fatal; the resource group manager aborts. - -#7: Error building resource tree - -The resource group manager was unable to load configuration information -from ccsd. This could mean a communication problem or an invalid -configuration. - -This error is fatal; the resource group manager aborts. - -#8: Couldn't initialize services - -The resource group manager was unable to load configuration information -from ccsd. This could mean a communication problem or an invalid -configuration. - -#9: Couldn't connect to cluster - -The resource group manager was unable to find a plugin which was able to -talk to the cluster infrastructure. Generally, this occurs when no cluster -infrastruture is running. Try starting the preferred cluster infrastructure -for your configuration (e.g. CMAN+DLM, GuLM) and restarting rgmanager. This -can also occur if CMAN is loaded, while DLM is not. Rgmanager (really, -the SM magma plugin) requires that the DLM be loaded prior to starting. - -#10: Couldn't set up listen socket - -The resource group manager was unable to bind to its listening socket. -This generally happens when there is already a resource group manager running, -but it is possible for other applications to use the port that rgmanager -wants to use for this purpose. - -#11: Couldn't set up VF listen socket - -The resource group manager was unable to bind to its listening socket which -is used fo internal state distribution. This generally happens when there -is already a resource group manager running, but it is possible for other -applications to use the port that rgmanager wants to use for this purpose. - -#12: RG <name> failed to stop; intervention required - -The resource group manager has failed to cleanly stop a service. -See #2 for actions to take. - -#13: Service <name> failed to stop cleanly - -The resource group manager has failed to cleanly stop a service after -failing to start the same resource group during an enable or start operation. -See #2 for actions to take. - -#14: Failed to send <integer> bytes to <integer> - -During a broadcast operation to all nodes, the view-formation library has -failed to send a message to one of the nodes. This is generally recovered -automatically. - -#15: rmtab_modified: stat: <error> - -The stat(2) function received an error while scanning for changes to -/var/lib/nfs/rmtab. Though generally handled automatically, repeats of -this kind of error could indicate a problem with /var/lib/nfs/rmtab. - -If repeated errors occur: - * Ensure /var/lib/nfs exists and is a directory. - * Ensure /var/lib/nfs/rmtab exists and is a regular file (not a directory) - -#16: Failed to reread rmtab: <error> - -Clurmtabd had trouble reading or parsing /var/lib/nfs/rmtab. This could -mean that there is garbage in /var/lib/nfs/rmtab or that the internal -format has changed or some problem with the filesystem. If the latter is -suspected, please file a Bugzilla. Ensure you include your -/var/lib/nfs/rmtab and version of rgmanager. - -#17: Failed to prune rmtab: <error> - -Clurmtabd failed to prune a new copy of /var/lib/nfs/rmtab against its -specified mount point. - -#18: Failed to diff rbtab: <error> - -Clurmtabd failed to determine the differences, if any, between a previous -copy of /var/lib/nfs/rmtab and the current data stored there. - -#19: (Obsolete) - -#20: Failed to set log level - -Clurmtabd failed to change its log level to the specified level. This -is non-fatal. The side effect is that more or less verbose logging will -be seen depending on whether the log level was increased or decreased. - -#21: Couldn't read/create <filename> - -Clurmtabd stores service-specific rmtab information in -<mount_point>/.clumanager/rmtab so that when the service fails over, -the new instance of clurmtabd on the other node can pick up and know which -hosts already have mounted any NFS exports. This error could indicate that -clients will receive ESTALE (Stale NFS file handle) after failover. - -#22: Failed to read <filename>: <error> - -Clurmtabd failed to read or parse <filename>. This could indicate garbage -in that file, or another error. This could have side effects of ESTALEs -being received by clients. The error should be indicative of the cause. - -#23: Failed to read /var/lib/nfs/rmtab: <error> - -Clurmtabd failed to read or parse <filename>. This could indicate garbage -in that file, or another error. This could have side effects of ESTALEs -being received by clients. The error should be indicative of the cause. - -#24: Failed to prune rmtab: <error> - -Clurmtabd failed to prune unrelated entries in /var/lib/nfs/rmtab. The -error should be indicative of the cause. - -#25: Failed to write /var/lib/nfs/rmtab: <error> - -Clurmtabd failed to atomically write a new copy of /var/lib/nfs/rmtab after -merging changes between private cluster data (<mount_point>/.clumanager/rmtab) -and the system-wide copy (/var/lib/nfs/rmtab). The error should be indicative -of the cause. - -#26: Failed to write <filename>: <error> - -Clurmtabd failed to atomically write a new copy of its private cluster data -file after changes between it and the system-wide copy in -(/var/lib/nfs/rmtab). The error should be indicative of the cause. - -#27: Couldn't initialize - exiting - -Clurmtabd failed to initialize for one reason or another. A previous -error should indicate the reason why. - -#28: daemonize: <error> - -Clurmtabd failed to become a daemon. The possible reasons this could happen -are documented in fork(2) and setsid(2). - -#29: rmtab_write_atomic: <error> - -Clurmtabd failed to atomically write a new copy of /var/lib/nfs/rmtab after -merging changes between private cluster data (<mount_point>/.clumanager/rmtab) -and the system-wide copy (/var/lib/nfs/rmtab). The error should be indicative -of the cause. - -#30: Node <name> defined multiple times in domain <domain> - -This indicates a configuration error where a node <name> was defined more -than once in a given failover domain <domain>. If this occurs, only the first -entry for the node <name> will be used. Remove the duplicate copy and restart -rgmanager on all nodes. - -#31: Domain <domain> defined multiple times - -This indicates a configuration error where a domain <domain> was defined -more than once. Failover domains may not have duplicate names. If this -occurs, the first one found will be used. - -#32: Code path error: Invalid return from node_in_domain() - -If this occurs, please file a Bugzilla. - -#33: Unable to obtain cluster lock: <error> - -This occurs while evaluating services after a node transition. If -this occurs, the current service under evaluation will not be able -to be checked for possible starting. - -Possible reasons obtaining a cluster lock would fail: - * Loss of node/cluster quorum - * Broken connection to GuLM/DLM - * Error in magma-plugins package. - -#34: Cannot get status for service <name> - -This occurs while evaluating services after a node transition. The -service <name> has an indeterminable state. This could indicate a -bug with the data distribution subsystem, or an invalid service. - -#35: Unable to inform partner to start failback - -This occurs after a node transition where a node asks other nodes for -services (resource groups) which it should own. This generally indicates -a communication problem between the cluster nodes. If this occurs, -services may not migrate to the node which just came online. - -#36: Cannot initialize services - -The resource group manager could not initialize services after a node -transition. This is fatal, and rgmanager exits uncleanly afterward. - -#37: Error receiving message header - -This occurs after an incoming request causes the resource group manager to -accept a new connection. After a new connection is received, there is a -short amount of time during which to receive the message header. If this -does not occur, the connection is dropped and the message (if any) is -rejected. - -#38: Invalid magic: Wanted 0x<hex>, got 0x<hex> - -This occurs after an incoming request causes the resource group manager to -accept a new connection. This could indicate a mismatched version between -resource group managers or an unauthorized program attempting to communicate -with the resource group manager. The connection is dropped and the message -is rejected. - -#39: Error receiving entire request - -This occurs after an incoming request causes the service manager to -accept a new connection. The amount of data received did not match the amount -of data specified in the message header. This could indicate a mismatched -version between service managers or an unauthorized program attempting -to communicate with the service manager. The connection is dropped -and the message is rejected. - -#40: Error replying to action request. - -A resource action request was received (enable/disable/etc.) while the -resource groups were locked and we failed to reply properly to the waiting -client connection. - -#41: Couldn't obtain lock for RG <name>: <error> - -While trying to report a failed service (resource group) to the other -cluster members, we failed to obtain a cluster lock. This could indicate -that the cluster quorum has dissolved, communication errors with the lock -server, or other problems. The effect of this is, however, minimal; simply -put, the #2 and #3 messages won't appear in the logs, so the last owner -of the service will be unknown. - -See #33 for reasons as to why obtaining a lock might fail. - -#42: Cannot stop service <name>: Invalid State <integer> - -The service <name> could not be stopped. It was in an invalid state. -This could indicate a bug in rgmanager. - -#43: Service <name> has failed on all applicable members; can not -start. - -I don't know how to make this more verbose. The service must be disabled and -enabled prior to being allowed to start. See #2 and #3 for more information. - -#44: Cannot start service <name>: Invalid State <integer> - -The service <name> could not be stopped. It was in an invalid state. -This could indicate a bug in rgmanager. - -#45: Unable to obtain cluster lock: <error> - -This occurs while trying to determine the state of a resource group prior -to starting it. If this occurs, the start operation will fail. The error -should be indicative of the reason. - -See #33 for reasons as to why obtaining a lock might fail. - -#46: Failed getting status for RG <name> - -This occurs while trying to determine the state of a resource group prior -to starting it. If this occurs, the start operation will fail. - -Generally, this indicates attempt to retrieve the current view of that -resource group's state after quorum has dissolved. - -#47: Failed changing service status - -This occurs while trying to write out a new ownership state of a resource -group prior to starting it. If this occurs, the start operation will fail. - -Generally, this indicates attempt to write a new view of that resource -group's state after quorum has dissolved. - -#48: Unable to obtain cluster lock: <error> - -This occurs while trying to determine the state of a resource group prior -to performing a status operation on it. If this occurs, the status -operation will fail. - -See #33 for reasons as to why obtaining a lock might fail. - -#49: Failed getting status for RG <name> - -This occurs while trying to determine the state of a resource group prior -to performing a status operation on it. If this occurs, the status -operation will fail. - -Generally, this indicates attempt to retrieve the current view of that -resource group's state after quorum has dissolved. - -#50: Unable to obtain cluster lock: <error> - -This occurs while trying to determine the state of a resource group prior -to performing a stop or disable operation on it. If this occurs, the stop -operation will fail. - -If a stop operation fails on a service, the service is marked as 'failed', -if possible. - -See #33 for reasons as to why obtaining a lock might fail. -See #2 for steps to take after a resource group has failed. - -#51: Failed getting status for service <name> - -This occurs while trying to determine the state of a resource group prior -to performing a stop or disable operation on it. If this occurs, the stop -operation will fail. - -Generally, this indicates attempt to retrieve the current view of that -resource group's state after quorum has dissolved. - -If a stop operation fails on a service, the service is marked as 'failed', -if possible (if the cluster is not quorate, then this is not possible). - -See #2 for steps to take after a resource group has failed. - -#52: Failed changing RG status - -This occurs while trying to write out a new ownership state of a resource -group prior to stopping it. If this occurs, the stop operation will fail. - -Generally, this indicates attempt to write a new view of that resource -group's state after quorum has dissolved. - -See #2 for steps to take after a resource group has failed. - -#53: Unable to obtain cluster lock: <error> - -This occurs while trying to determine the state of a resource group after -performing a stop or disable operation on it. If this occurs, the stop -operation will fail. - -If a stop operation fails on a service, the service is marked as 'failed', -if possible. - -See #33 for reasons as to why obtaining a lock might fail. -See #2 for steps to take after a resource group has failed. - -#54: Failed getting status for RG <name> - -This occurs while trying to determine the state of a resource group after -to performing a stop or disable operation on it. If this occurs, the stop -operation will fail. - -Generally, this indicates attempt to retrieve the current view of that -resource group's state after quorum has dissolved. - -If a stop operation fails on a service, the service is marked as 'failed', -if possible (if the cluster is not quorate, then this is not possible). - -#55: Failed changing RG status - -This occurs while trying to write out a new ownership state of a resource -group after stopping it. If this occurs, the stop operation will fail. - -Generally, this indicates attempt to write a new view of that resource -group's state after quorum has dissolved. - -See #2 for steps to take after a resource group has failed. - -#55: Unable to obtain cluster lock: <error> - -This occurs while trying to determine the state of a resource group after -a stop operation has failed, while the cluster is trying to disable -the service. If this occurs, the operation will fail. - -See #33 for reasons as to why obtaining a lock might fail. -See #2 for steps to take after a resource group has failed. - -#56: Failed getting status for RG <name> - -This occurs while trying to determine the state of a resource group after -failing to perform a stop or disable operation on it. If this occurs, -the operation to lock the service will fail. - -Generally, this indicates attempt to retrieve the current view of that -resource group's state after quorum has dissolved. - -#57: Failed changing RG status - -This occurs while trying to write out a new ownership state of a resource -group after marking it as failed. If this occurs, the stop operation -will fail. - -Generally, this indicates attempt to write a new view of that resource -group's state after quorum has dissolved. - -See #2 for steps to take after a resource group has failed. - -#58: Failed opening connection to member #<integer> - -We attempted to relocate a resource group (service) to another node, but -failed to actually connect to that node's resource group manager. This -could indicate that rgmanager is not running on that node. In any case, -the next node in the cluster member list is tried. - -#59: Error sending relocate request to member #<integer> - -We attempted to relocate a resource group (service) to another node, but -failed to send the relocation message. This could indicate a problem with -network connectivity, extremely high local/remote load, or other problems. -The next node in the cluster member list is tried. - -#60: Mangled reply from member #<integer> during RG relocate - -We sent a resource group to another node, but it failed to send us a -useful reply. At this point, the state of the resource group is unknown, but -we give it the benefit of the doubt and assume it started okay. - -#61: Invalid reply from member <integer> during relocate operation! - -Similar to #60, but this occurs only after the inital preferred node failed -to start the service and/or failed to communicate a proper reply. - -#62: /var/lib/nfs/rmtab does not exist - creating - -/var/lib/nfs/rmtab did not exist. Clurmtabd creates it. - -#63: Couldn't write PID! - -Clurmtabd failed to write its pid to <mount_point>/.clumanager/pid. This -will cause fs.sh to kill it with -9 during a stop operation, preventing -it from synchronizing with /var/lib/nfs/rmtab prior to exiting. This -increases the risk of ESTALE (Stale NFS file handle) on clients after -a relocation. - -#64: Could not validate <mount_point> -#65: NFS failover of <mount_point> will malfunction - -Clurmtabd failed to initialize the mount point's private cluster rmtab -file. This will prevent updating of that mount point's rmtab file, which -means that clients will receive ESTALE after a relocation or failover. - -#66: Domain '<domain>' specified for resource group <name> nonexistent! - -The failover domain <domain> does not exist in the current view of the -cluster configuration. This is a configuration error. - -#67: Shutting down uncleanly - -The node has left the cluster cleanly, but rgmanager was still running. -All services are halted as quickly as possible to prevent data corruption. - -(It may be a good idea to have rgmanager reboot if this is received) - -#68: Failed to start <name>; return value: <integer> - -The resource group <name> failed to start and returned the value <integer>. -This could indicate missing resources on the node or an improperly configured -resource group. Check your resource group's configuration against your -hardware and software configuration and ensure that it is correct. - -#69: Unclean [stop|disable] of <name> - -The resource group is being stopped because of a local node exiting or -loss of quorum. The distributed state is left unchanged. - -#70: Attempting to restart resource group <name> locally. - -The resource group failed to start on all other applicable nodes during -processing of a relocate operation. (A relocate operation occurs either -by an administrator manually relocating a service or the service being -relocated after a fail-to-restart event.) - -#71: Relocating failed service <name> - -The resource group <name> failed a status check and subsequently failed to -restart. At this point, we try to send it to another applicable node in -the cluster. - -#72: clunfsops: NFS syscall <name> failed: <error>. -#73: clunfsops: Kernel may not have NFS failover enhancements. - -Required NFS failover enhancements were not present on the host kernel. -It is impossible to restart or relocate NFS services without these, but -they should properly work in the case of true failover situations (i.e. -the node on whicch the NFS service was running has failed and been -fenced by the cluster). - -#74: Unable to obtain cluster lock: <error> - -This occurs while trying to determine the state of a resource group after -an attempt to start it has completed (at the script level). If this occurs, -the start operation will fail. - -See #33 for reasons as to why obtaining a lock might fail. - -#75: Failed getting status for RG <name> - -This occurs while trying to determine the state of a resource group after -an attempt to start it has completed. If this occurs, the start operation -will report a failure. - -Generally, this indicates attempt to retrieve the current view of that -resource group's state after quorum has dissolved. diff --git a/rgmanager/event-script.txt b/rgmanager/event-script.txt deleted file mode 100644 index 00a8b4c..0000000 --- a/rgmanager/event-script.txt +++ /dev/null @@ -1,311 +0,0 @@ -TODO: -* Return correct error codes to clusvcadm (currently it always returns - "Unknown") -* Write glue for 'migrate' operations and migrate-enabled services - -Basic configuration specification: - - <rm> - <events> - <event class="node"/> <!-- all node events --> - <event class="node" - node="bar"/> <!-- events concerning 'bar' --> - <event class="node" - node="foo" - node_state="up"/> <!-- 'up' events for 'foo' --> - <event class="node" - node_id="3" - node_state="down"/> <!-- 'down' events for node ID 3 --> - - (note, all service ops and such deal with node ID, not - with node names) - - <event class="service"/> <!-- all service events--> - <event class="service" - service_name="A"/> <!-- events concerning 'A' --> - <event class="service" - service_name="B" - service_state="started"/> <!-- when 'B' is started... --> - <event class="service" - service_name="B" - service_state="started"/> - service_owner="3"/> <!-- when 'B' is started on node 3... --> - - <event class="service" - priority="1" - service_state="started"/> - service_owner="3"/> <!-- when 'B' is started on node 3, do this - before the other event handlers ... --> - - - </events> - ... - </rm> - -General globals available from all scripts: - - node_self - local node ID - event_type - event class, either: - EVENT_NONE - unspecified / unknown - EVENT_NODE - node transition - EVENT_SERVICE - service transition - EVENT_USER - a user-generated request - EVENT_CONFIG - [NOT CONFIGURABLE] - -Node event globals (i.e. when event_type == EVENT_NODE): - - node_id - node ID which is transitioning - node_name - name of node which is transitioning - node_state - new node state (NODE_ONLINE or NODE_OFFLINE, or if you prefer, - 1 or 0, respectively) - node_clean - 0 if the node has not been fenced, 1 if the node has been - fenced - -Service event globals (i.e. when event_type == EVENT_SERVICE): - - service_name - Name of service which transitioned - service_state - new state of service - service_owner - new owner of service (or <0 if service is no longer - running) - service_last_owner - Last owner of service if known. Used for when - service_state = "recovering" generally, in order to - apply restart/relocate/disable policy. - -User event globals (i.e. when event_type == EVENT_USER): - - service_name - service to perform request upon - user_request - request to perform (USER_ENABLE, USER_DISABLE, - USER_STOP, USER_RELOCATE, [TODO] USER_MIGRATE) - user_target - target node ID if applicable - - -Scripting functions - Informational: - - node_list = nodes_online(); - - Returns a list of all online nodes. - - service_list = service_list(); - - Returns a list of all configured services. - - (restarts, last_owner, owner, state) = service_status(service_name); - - Returns the state, owner, last_owner, and restarts. Note that - all return values are optional, but are right-justified per S-Lang - specification. This means if you only want the 'state', you can use: - - (state) = service_status(service_name); - - However, if you need the restart count, you must provide all four - return values as above. - - (nofailback, restricted, ordered, node_list) = - service_domain_info(service_name); - - Returns the failover domain specification, if it exists, for the - specified service name. The node list returned is an ordered list - according to priority levels. In the case of unordered domains, - the ordering of the returned list is pseudo-random. - -Scripting functions - Operational: - - err = service_start(service_name, node_list, [avoid_list]); - - Start a non-running, (but runnable, i.e. not failed) - service on the first node in node_list. Failing that, start it on - the second node in node_list and so forth. One may also specify - an avoid list, but it's better to just use the subtract() function - below. If the start is successful, the node ID running the service - is returned. If the start is unsuccessful, a value < 0 is returned. - - err = service_stop(service_name, [0 = stop, 1 = disable]); - - Stop a running service. The second parameter is optional, and if - non-zero is specified, the service will enter the disabled state. - - ... stuff that's not done but needs to be: - - err = service_relocate(service_name, node_list); - - Move a running service to the specified node_list in order of - preference. In the case of VMs, this is actually a migrate-or- - relocate operation. - -Utility functions - Node list manipulation - - node_list = union(left_node_list, right_node_list); - - Calculates the union between the two node list, removing duplicates - and preserving ordering according to left_node_list. Any added - values from right_node_list will appear in their order, but - after left_node_list in the returned list. - - node_list = intersection(left_node_list, right_node_list); - - Calculates the intersection (items in both lists) between the two - node lists, removing duplicates and preserving ordering according - to left_node_list. Any added values from right_node_list will - appear in their order, but after left_node_list in the returned list. - - node_list = delta(left_node_list, right_node_list); - - Calculates the delta (items not in both lists) between the two - node lists, removing duplicates and preserving ordering according - to left_node_list. Any added values from right_node_list will - appear in their order, but after left_node_list in the returned list. - - node_list = subtract(left_node_list, right_node_list); - - Removes any duplicates as well as items specified in right_node_list - from left_node_list. Example: - - all_nodes = nodes_online(); - allowed_nodes = subtract(nodes_online, node_to_avoid); - - node_list = shuffle(node_list_old); - - Rearranges the contents of node_list_old randomly and returns a - new node list. - -Utility functions - Logging: - - debug(item1, item2, ...); LOG_DEBUG level - info(...); LOG_INFO level - notice(...); LOG_NOTICE level - warning(...); LOG_WARNING level - err(...); LOG_ERR level - crit(...); LOG_CRIT level - alert(...); LOG_ALERT level - emerg(...); LOG_EMERG level - - items - These can be strings, integer lists, or integers. Logging - string lists is not supported. - - level - the level is consistent with syslog(8) - - stop_processing(); - - Calling this function will prevent further event scripts from being - executed on a particular event. Call this script if, for example, - you do not wish for the default event handler to process the event. - - Note: This does NOT terminate the caller script; that is, the - script being executed will run to completion. - -Event scripts are written in a language called S-Lang; documentation specifics -about the language are available at http://www.s-lang.org - -Example script (creating a follows-but-avoid-after-start behavior): -% -% If the main queue server and replication queue server are on the same -% node, relocate the replication server somewhere else if possible. -% -define my_sap_event_trigger() -{ - variable state, owner_rep, owner_main; - variable nodes, allowed; - - % - % If this was a service event, don't execute the default event - % script trigger after this script completes. - % - if (event_type == EVENT_SERVICE) { - stop_processing(); - } - - (owner_main, state) = service_status("service:main_queue"); - (owner_rep, state) = service_status("service:replication_server"); - - if ((event_type == EVENT_NODE) and (owner_main == node_id) and - (node_state == NODE_OFFLINE) and (owner_rep >= 0)) { - % - % uh oh, the owner of the main server died. Restart it - % on the node running the replication server - % - notice("Starting Main Queue Server on node ", owner_rep); - ()=service_start("service:main_queue", owner_rep); - return; - } - - % - % S-Lang doesn't short-circuit prior to 2.1.0 - % - if ((owner_main >= 0) and - ((owner_main == owner_rep) or (owner_rep < 0))) { - - % - % Get all online nodes - % - nodes = nodes_online(); - - % - % Drop out the owner of the main server - % - allowed = subtract(nodes, owner_main); - if ((owner_rep >= 0) and (length(allowed) == 0)) { - % - % Only one node is online and the rep server is - % already running. Don't do anything else. - % - return; - } - - if ((length(allowed) == 0) and (owner_rep < 0)) { - % - % Only node online is the owner ... go ahead - % and start it, even though it doesn't increase - % availability to do so. - % - allowed = owner_main; - } - - % - % Move the replication server off the node that is - % running the main server if a node's available. - % - if (owner_rep >= 0) { - ()=service_stop("service:replication_server"); - } - ()=service_start("service:replication_server", allowed); - } - - return; -} - -my_sap_event_trigger(); - - -Relevant <rm> section from cluster.conf: - - <rm central_processing="1"> - <events> - <event name="main-start" class="service" - service="service:main_queue" - service_state="started" - file="/tmp/sap.sl"/> - <event name="rep-start" class="service" - service="service:replication_server" - service_state="started" - file="/tmp/sap.sl"/> - <event name="node-up" node_state="up" - class="node" - file="/tmp/sap.sl"/> - - </events> - <failoverdomains> - <failoverdomain name="all" ordered="1" restricted="1"> - <failoverdomainnode name="molly" -priority="2"/> - <failoverdomainnode name="frederick" -priority="1"/> - </failoverdomain> - </failoverdomains> - <resources/> - <service name="main_queue"/> - <service name="replication_server" autostart="0"/> - <!-- replication server is started when main-server start - event completes --> - </rm> - - diff --git a/rgmanager/examples/cluster.conf b/rgmanager/examples/cluster.conf deleted file mode 100644 index a53e479..0000000 --- a/rgmanager/examples/cluster.conf +++ /dev/null @@ -1,106 +0,0 @@ -<?xml version="1.0"?> -<cluster name="pretty" config_version="6"> - -<cman> -</cman> - -<dlm> -</dlm> - -<clusternodes> - <clusternode name="red" votes="4"> - <fence> - <method name="power"> - <device name="wti" port="1"/> - </method> - </fence> - </clusternode> - <clusternode name="green" votes="3"> - <fence> - <method name="power"> - <device name="wti" port="2"/> - </method> - </fence> - </clusternode> -</clusternodes> - - -<fencedevices> - <fencedevice name="wti" agent="fence_wti" ipaddress="nps1" password="wti"/> -</fencedevices> - - -<!-- The RM block holds resources, failover domains, and any number of - 'group' (= resource group) blocks --> -<rm> - <!-- Similar to failover domains in RHEL3 --> - <failoverdomains> - <failoverdomain name="thisdomain" ordered="1"> - <failoverdomainnode name="red" priority="1"/> - <failoverdomainnode name="green" priority="1"/> - <failoverdomainnode name="blue" priority="2"/> - </failoverdomain> - <failoverdomain name="bluedomain" restricted="1"> - <failoverdomainnode name="blue" priority="2"/> - </failoverdomain> - </failoverdomains> - - <!-- Define resources here --> - <resources> - - <group name="oracle" domain="thisdomain"/> - <script name="Oracle Script" file="/etc/init.d/oracle"/> - <script name="Oracle Script 2" file="/etc/init.d/oracle2"/> - <ip address="192.168.0.28" monitor_link="yes"/> - <ip address="192.168.0.29" monitor_link="yes"/> - <nfsclient name="User group" target="@users" options="ro"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsexport name="nfs exports"/> - </resources> - - <!-- Define resource groups here --> - <service ref="oracle"> - - <!-- Reference the above resources by their primary attribute --> - <script ref="Oracle Script"/> - <script ref="Oracle Script 2"/> - <ip ref="192.168.0.28"/> - <ip ref="192.168.0.29"/> - - <!-- Or define them inline. Fine with me! --> - <fs fstype="ext3" name="NFS Mount" mountpoint="/mnt/cluster" device="/dev/sdb8"> - - <!-- nfs export path inherited from parent file system's mount point--> - <nfsexport ref="nfs exports"> - <!-- Export path inherited from export. So, for this instance - of "admin group", the export path is /mnt/cluster. --> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - </nfsexport> - </fs> - - <fs fstype="ext3" name="NFS2" mountpoint="/mnt/sdb7" device="/dev/sdb7"> - <!-- nfs export path inherited from parent file system's mount point--> - <nfsexport name="NFS Export" type="nfs"> - <!-- Export path inherited from export. So, for this instance - of "admin group", the export path is /mnt/sdb7. --> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - </nfsexport> - </fs> - </service> - - <!-- Define a bunch of test resource groups. --> - <service name="test1"/> - <service name="test2"/> - <service name="test3"/> - <service name="test4"/> - <service name="test5"/> - <service name="test6"/> - <service name="test7"/> - <service name="test8"/> - <service name="test9"/> - <service name="blueonly" domain="bluedomain"/> -</rm> - -</cluster> diff --git a/rgmanager/include/clulog.h b/rgmanager/include/clulog.h deleted file mode 100644 index e6b7ff8..0000000 --- a/rgmanager/include/clulog.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Header for clulog.c - */ -/* - * author: Jeff Moyer moyer@missioncriticallinux.com - */ - -#ifndef __CLUSTER_LOG_H -#define __CLUSTER_LOG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <syslog.h> -#include <sys/types.h> - -#define LOGLEVEL_DFLT LOG_NOTICE -#define MAX_LOGMSG_LEN 512 - -/* - * int clu_set_loglevel(int severity) - * - * DESCRIPTION - * Set the logging level for this daemon. This is not a - * system-wide setting. - * - * ARGUMENTS - * severity Severity as documented in sys/syslog.h (i.e. LOG_ERR) - * - * RETURN VALUES - * On success, the previous loglevel is returned. On error -1 is returned. - * - * NOTES - * The only way of generating errors for this call is to give a negative - * value for severity. Currently, syslog lists severities up to 8, but - * I see no reason for this restriction if, in the future, we decided to - * add more levels. Thus, any number up to MAXINT will be supported. - */ -int clu_set_loglevel(int severity); -int clu_set_facility(char *facility); -int clu_log_console(int onoff); - -/* - * int clu_get_loglevel(void) - * - * DESCRIPTION - * Get the current logging level. - * - * ARGUMENTS - * none - * - * RETURN VALUES - * The current logging level is returned. - */ -int clu_get_loglevel(void); - -/* - * DESCRIPTION - * Cluster logging facility. This is the actual function that does the - * logging. No one should call this, you should call the wrappers provided. - * i.e. clulog and clulog_and_print. - */ -int do_clulog(int severity, int write_to_cons, pid_t pid, - char *prog, const char *fmt, ...); -/* - * int clulog(int severity, const char *fmt, ...) - * - * DESCRIPTION - * Cluster logging facility. This is a library routine which sends the - * supplied parameters to the syslog daemon. If the supplied severity is - * numerically larger than the current loglevel, the message is never sent - * to the log. - * - * ARGUMENTS - * severity Severity as documented in sys/syslog.h (i.e. LOG_ERR) - * fmt Format string as used with printf. - * - * RETURN VALUES - * On success, 0 is returned. On error, -1 is returned. - * - * NOTES - * Inability to contact the logging daemon is the only source of error - * for this function. Thus, it would behoove you to try a clulog before - * daemonizing your process. If it fails, print a message to stderr - * explaining that the cluster logging daemon should probably be started. - * If you really want your message to be heard by someone, use - * clulog_and_print(). - */ -#define clulog(x,fmt,args...) do_clulog(x,0,0,NULL,fmt,##args) -#define clulog_pid(x,pid,prog,fmt,args...) do_clulog(x,0,pid,prog,fmt,##args) - -/* - * int clulog_and_print(int severity, int write_to_cons, const char *fmt, ...) - * - * DESCRIPTION - * Cluster logging facility. This is a library routine which sends the - * supplied parameters to the syslog daemon. If the supplied severity is - * numerically larger than the current loglevel, the message is never sent - * to the log. This version also prints the given message to the terminal. - * - * ARGUMENTS - * severity Severity as documented in sys/syslog.h (i.e. LOG_ERR) - * fmt Format string as used with printf. - * - * RETURN VALUES - * On success, 0 is returned. On error, -1 is returned. - */ -#define clulog_and_print(x,fmt,args...) do_clulog(x,1,0,NULL,fmt,##args) - - -/* - * void clulog_close(void) - * - * DESCRIPTION - * This is an optional call to close the logfile. This translates into a - * closelog() call. - * - * ARGUMENTS - * none - * - * RETURN VALUES - * This function does not return anything. - */ -void clulog_close(void); - - -#ifdef __cplusplus -} -#endif -#endif /* __CLUSTER_LOG_H */ -/* - * Local variables: - * c-basic-offset: 8 - * c-indent-level: 8 - * tab-width: 8 - * End: - */ diff --git a/rgmanager/include/event.h b/rgmanager/include/event.h deleted file mode 100644 index bd8bc0a..0000000 --- a/rgmanager/include/event.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _EVENT_H -#define _EVENT_H - -/* 128 is a bit big, but it should be okay */ -typedef struct __rge_q { - char rg_name[128]; - uint32_t rg_state; - uint32_t pad1; - int rg_owner; - int rg_last_owner; -} group_event_t; - -typedef struct __ne_q { - uint64_t ne_nodeid; - int ne_local; - int ne_state; - int ne_clean; - int pad1; -} node_event_t; - -typedef struct __cfg_q { - int cfg_version; - int cfg_oldversion; -} config_event_t; - -typedef struct __user_q { - char u_name[128]; - uint64_t u_target; /* Node ID */ - int pad1; - int u_fd; - int u_request; - int u_arg1; - int u_arg2; -} user_event_t; - -typedef enum { - EVENT_NONE=0, - EVENT_CONFIG, - EVENT_NODE, - EVENT_RG, - EVENT_USER -} event_type_t; - -/* Data that's distributed which indicates which - node is the event master */ -typedef struct __rgm { - uint64_t m_nodeid; - uint64_t m_master_time; - uint32_t m_magic; - uint8_t m_reserved[108]; -} event_master_t; - -#define swab_event_master_t(ptr) \ -{\ - swab64((ptr)->m_nodeid);\ - swab64((ptr)->m_master_time);\ - swab32((ptr)->m_magic);\ -} - -/* Just a magic # to help us ensure we've got good - date from VF */ -#define EVENT_MASTER_MAGIC 0xfabab0de - -/* Event structure - internal to the event subsystem; use - the queueing functions below which allocate this struct - and pass it to the event handler */ -typedef struct _event { - /* Not used dynamically - part of config info */ - list_head(); - char *ev_name; - char *ev_script; - char *ev_script_file; - int ev_prio; - int ev_pad; - /* --- end config part */ - int ev_type; /* config & generated by rgmanager*/ - int ev_transaction; - union { - group_event_t group; - node_event_t node; - config_event_t config; - user_event_t user; - } ev; -} event_t; - -#define EVENT_PRIO_COUNT 100 - -typedef struct _event_table { - int max_prio; - int pad; - event_t *entries[0]; -} event_table_t; - - -int construct_events(int ccsfd, event_table_t **); -void deconstruct_events(event_table_t **); -void print_events(event_table_t *); - -/* Does the event match a configured event? */ -int event_match(event_t *pattern, event_t *actual); - -/* Event queueing functions. */ -void node_event_q(int local, uint64_t nodeID, int state, int clean); -void rg_event_q(char *name, uint32_t state, uint64_t owner, uint64_t last); -void user_event_q(char *svc, int request, int arg1, int arg2, - uint64_t target, int fd); -void config_event_q(int old_version, int new_version); - -/* Call this to see if there's a master. */ -int event_master_info_cached(event_master_t *); - -/* Call this to get the node ID of the current - master *or* become the master if none exists */ -uint64_t event_master(void); - -/* Setup */ -int central_events_enabled(void); -void set_central_events(int flag); -int slang_process_event(event_table_t *event_table, event_t *ev); - -/* For distributed events. */ -void set_transition_throttling(int nsecs); - -/* Simplified service start. */ -int service_op_start(char *svcName, uint64_t *target_list, int target_list_len, - uint64_t *new_owner); -int service_op_stop(char *svcName, int do_disable, int event_type); - - -#endif diff --git a/rgmanager/include/findproc.h b/rgmanager/include/findproc.h deleted file mode 100644 index 3d39048..0000000 --- a/rgmanager/include/findproc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - */ -/** @file - * Header for findproc.c - */ -#ifndef __PROC_H -#define __PROC_H - -int findkillproc(char *, pid_t *, size_t, int); -int findproc(char *, pid_t *, size_t); -int killall(char *, int); - -#endif diff --git a/rgmanager/include/gettid.h b/rgmanager/include/gettid.h deleted file mode 100644 index 636560c..0000000 --- a/rgmanager/include/gettid.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __GETTID_H -#define __GETTID_H - -pid_t gettid(void); - -#endif - diff --git a/rgmanager/include/list.h b/rgmanager/include/list.h deleted file mode 100644 index 9d58891..0000000 --- a/rgmanager/include/list.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _LIST_H -#define _LIST_H - -/** - Simple list handlig macros. - Needs rewrite or inclusion of /usr/include/linux/list.h as a replacement. - */ - -/* Must be first if structure is going to use it. */ -struct list_entry { - struct list_entry *le_next, *le_prev; -}; - -#define list_head() struct list_entry _list_head - -#define le(p) (&((*p)._list_head)) - -#define list_insert(list, newnode) \ -do { \ - if (!(*list)) { \ - le(newnode)->le_next = \ - le(newnode)->le_prev = le(newnode); \ - *list = (void *)le(newnode); \ - } else { \ - le(*list)->le_prev->le_next = le(newnode); \ - le(newnode)->le_next = le(*list); \ - le(newnode)->le_prev = le(*list)->le_prev; \ - le(*list)->le_prev = le(newnode); \ - } \ -} while (0) - - -#define list_prepend(list, newnode) \ -do { \ - list_insert(list, newnode); \ - *list = newnode; \ -} while (0) - - -#define list_remove(list, oldnode) \ -do { \ - if (le(oldnode) == le(*list)) { \ - *list = (void *)le(*list)->le_next; \ - } \ - if (le(oldnode) == le(*list)) { \ - le(oldnode)->le_next = NULL; \ - le(oldnode)->le_prev = NULL; \ - *list = NULL; \ - } else { \ - le(oldnode)->le_next->le_prev = le(oldnode)->le_prev; \ - le(oldnode)->le_prev->le_next = le(oldnode)->le_next; \ - le(oldnode)->le_prev = NULL; \ - le(oldnode)->le_next = NULL; \ - } \ -} while (0) - -/* - list_do(list, node) { - stuff; - } while (!list_done(list, node)); - */ -#define list_do(list, curr) \ - if (*list && (curr = *list)) do - -#define list_done(list, curr) \ - (curr && (((curr = (void *)le(curr)->le_next)) && (curr == *list))) - -/* - * list_for(list, tmp, counter) { - * stuff; - * } - * - * counter = # of items in list when done. - * * sets cnt to 0 before even checking list; - * * checks for valid list - * * traverses list, incrementing counter. If we get to the for loop, - * there must be at least one item in the list - */ -#define list_for(list, curr, cnt) \ - if (!(cnt=0) && list && *list) \ - for (curr = *list; \ - (cnt == 0) || (curr != *list); \ - curr = (void*)le(curr)->le_next, \ - cnt++) - -#define list_for_rev(list, curr, cnt) \ - if (!(cnt=0) && list && *list) \ - for (curr = (void *)(le(*list)->le_prev); \ - (cnt == 0) || ((void *)curr != le(*list)->le_prev); \ - curr = (void*)(le(curr)->le_prev), \ - cnt++) - - -#endif diff --git a/rgmanager/include/msgsimple.h b/rgmanager/include/msgsimple.h deleted file mode 100644 index c04231c..0000000 --- a/rgmanager/include/msgsimple.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __MSG_SIMPLE_H -#define __MSG_SIMPLE_H - -#include <errno.h> -#include <stdint.h> -#include <resgroup.h> - -typedef struct __attribute__ ((packed)) { - uint32_t gh_magic; - uint32_t gh_length; - uint32_t gh_command; - uint32_t gh_arg1; - uint32_t gh_arg2; - /* XXX alignment issue on ia64 */ -} generic_msg_hdr; - -#define swab_generic_msg_hdr(ptr)\ -{\ - swab32((ptr)->gh_magic);\ - swab32((ptr)->gh_length);\ - swab32((ptr)->gh_command);\ - swab32((ptr)->gh_arg1);\ - swab32((ptr)->gh_arg2);\ -} - -typedef struct __attribute__ ((packed)) { - generic_msg_hdr sm_hdr; - struct { - char d_svcName[64]; - uint32_t d_action; - uint32_t d_svcState; - uint64_t d_svcOwner; - int32_t d_ret; - uint32_t d_pad; - } sm_data; -} SmMessageSt; - -#define swab_SmMessageSt(ptr) \ -{\ - swab_generic_msg_hdr(&((ptr)->sm_hdr));\ - swab32((ptr)->sm_data.d_action);\ - swab32((ptr)->sm_data.d_svcState);\ - swab64((ptr)->sm_data.d_svcOwner);\ - swab32((ptr)->sm_data.d_ret);\ -} - -typedef struct __attribute__ ((packed)) { - generic_msg_hdr rsm_hdr; - rg_state_t rsm_state; -} rg_state_msg_t; - -#define swab_rg_state_msg_t(ptr) \ -{\ - swab_generic_msg_hdr(&((ptr)->rsm_hdr));\ - swab_rg_state_t(&((ptr)->rsm_state));\ -} - - -#define GENERIC_HDR_MAGIC 0x123abc00 -#define GENERIC_HDR_MAGICV2 0x123abc02 - -int msg_send_simple(int fd, int cmd, int arg1, int arg2); -int msg_receive_simple(int fd, generic_msg_hdr ** buf, int timeout); - -#endif diff --git a/rgmanager/include/platform.h b/rgmanager/include/platform.h deleted file mode 100644 index 7c8d02b..0000000 --- a/rgmanager/include/platform.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - The Red Hat Cluster Manager API Library is free software; you can - redistribute it and/or modify it under the terms of the GNU Lesser - General Public License as published by the Free Software Foundation; - either version 2.1 of the License, or (at your option) any later - version. - - The Red Hat Cluster Manager API Library is distributed in the hope - that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. - */ -/** @file - * Defines for byte-swapping - */ -#ifndef _PLATFORM_H -#define _PLATFORM_H - -#include <endian.h> -#include <sys/param.h> -#include <byteswap.h> -#include <bits/wordsize.h> - -/* - -Configure is gone... - #ifndef HAVE_CONFIG_H -#error "Please run configure first" -#endif - -*/ - -/* #include <config.h> */ - -/* No swapping on little-endian machines */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define le_swap16(x) (x) -#define le_swap32(x) (x) -#define le_swap64(x) (x) -#else -#define le_swap16(x) bswap_16(x) -#define le_swap32(x) bswap_32(x) -#define le_swap64(x) bswap_64(x) -#endif - -/* No swapping on big-endian machines */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define be_swap16(x) bswap_16(x) -#define be_swap32(x) bswap_32(x) -#define be_swap64(x) bswap_64(x) -#else -#define be_swap16(x) (x) -#define be_swap32(x) (x) -#define be_swap64(x) (x) -#endif - - -#define swab16(x) x=be_swap16(x) -#define swab32(x) x=be_swap32(x) -#define swab64(x) x=be_swap64(x) - - - - -#endif /* _PLATFORM_H */ diff --git a/rgmanager/include/pthread_dbg.h b/rgmanager/include/pthread_dbg.h deleted file mode 100644 index 7b6d5e0..0000000 --- a/rgmanager/include/pthread_dbg.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _PTHREAD_DBG_H -#define _PTHREAD_DBG_H -#include <pthread.h> - -#define pthread_mutex_lock(x) \ -{\ - printf("pthread_mutex_lock(%s) @ %s:%d in %s\n",\ - #x, __FILE__, __LINE__, __FUNCTION__); \ - pthread_mutex_lock(x);\ -} - -#define pthread_mutex_unlock(x) \ -{\ - printf("pthread_mutex_unlock(%s) @ %s:%d in %s\n",\ - #x, __FILE__, __LINE__, __FUNCTION__); \ - pthread_mutex_unlock(x);\ -} - - -#define pthread_rwlock_rdlock(x) \ -{\ - printf("pthread_rwlock_rdlock(%s) @ %s:%d in %s\n",\ - #x, __FILE__, __LINE__, __FUNCTION__); \ - pthread_rwlock_rdlock(x);\ -} - -#define pthread_rwlock_unlock(x) \ -{\ - printf("pthread_rwlock_unlock(%s) @ %s:%d in %s\n",\ - #x, __FILE__, __LINE__, __FUNCTION__); \ - pthread_rwlock_unlock(x);\ -} - -#define pthread_rwlock_wrlock(x) \ -{\ - printf("pthread_rwlock_wrlock(%s) @ %s:%d in %s\n",\ - #x, __FILE__, __LINE__, __FUNCTION__); \ - pthread_rwlock_wrlock(x);\ -} - -#endif diff --git a/rgmanager/include/res-ocf.h b/rgmanager/include/res-ocf.h deleted file mode 100644 index b55bf44..0000000 --- a/rgmanager/include/res-ocf.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _RES_OCF_H -#define _RES_OCF_H 1 - -#define OCF_ROOT RESOURCE_ROOTDIR - -#define OCF_API_VERSION "1.0" - -#define OCF_RES_PREFIX "OCF_RESKEY_" - -#define OCF_ROOT_STR "OCF_ROOT" -#define OCF_RA_VERSION_MAJOR_STR "OCF_RA_VERSION_MAJOR" -#define OCF_RA_VERSION_MINOR_STR "OCF_RA_VERSION_MINOR" -#define OCF_RESOURCE_INSTANCE_STR "OCF_RESOURCE_INSTANCE" -#define OCF_CHECK_LEVEL_STR "OCF_CHECK_LEVEL" -#define OCF_RESOURCE_TYPE_STR "OCF_RESOURCE_TYPE" -#define OCF_REFCNT_STR "OCF_RESKEY_RGMANAGER_meta_refcnt" - -/* - LSB return codes - */ -#define OCF_RA_SUCCESS 0 -#define OCF_RA_ERROR 1 -#define OCF_RA_INVALID_ARG 2 -#define OCF_RA_UNIMPLEMENTED 3 -#define OCF_RA_PERMISSION 4 -#define OCF_RA_NOT_INSTALLED 5 -#define OCF_RA_NOT_CONFIGURED 6 -#define OCF_RA_NOT_RUNNING 7 -#define OCF_RA_MAX 7 - -/* - Resource operations - not ocf-specified - */ -#define RS_START (0) -#define RS_STOP (1) -#define RS_STATUS (2) -#define RS_RESINFO (3) -#define RS_RESTART (4) -#define RS_RELOAD (5) -#define RS_CONDRESTART (6) -#define RS_RECOVER (7) -#define RS_CONDSTART (8) /** Start if flagged with RF_NEEDSTART */ -#define RS_CONDSTOP (9) /** STOP if flagged with RF_NEEDSTOP */ -#define RS_MONITOR (10) -#define RS_META_DATA (11) -#define RS_VALIDATE (12) -#define RS_MIGRATE (13) -#define RS_RECONFIG (14) - -#endif diff --git a/rgmanager/include/resgroup.h b/rgmanager/include/resgroup.h deleted file mode 100644 index c52dcc0..0000000 --- a/rgmanager/include/resgroup.h +++ /dev/null @@ -1,260 +0,0 @@ -#ifndef __RESGROUP_H -#define __RESGROUP_H - -#include <pthread.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <errno.h> -#include <sys/wait.h> -#include <sys/types.h> -#include <sys/select.h> -#include <gettid.h> -#include <rg_locks.h> -#include <magma.h> -#include <rg_queue.h> -#include <signals.h> - -/** - * Service state as represented on disk. - * - * This structure represents a service description. This data structure - * represents the in-memory service description. (There is a separate - * description of the on-disk format.) - */ -typedef struct { - char rs_name[64]; /**< Service name */ - uint64_t rs_owner; /**< Member ID running service. */ - uint64_t rs_last_owner; /**< Last member to run the service. */ - uint32_t rs_state; /**< State of service. */ - uint32_t rs_restarts; /**< Number of cluster-induced - restarts */ - uint64_t rs_transition; /**< Last service transition time */ - uint32_t rs_id; /**< Service ID */ - uint32_t rs_pad; /**< pad to 64-bit boundary */ -} rg_state_t; - -#define swab_rg_state_t(ptr) \ -{\ - swab64((ptr)->rs_owner);\ - swab64((ptr)->rs_last_owner);\ - swab32((ptr)->rs_state);\ - swab32((ptr)->rs_restarts);\ - swab64((ptr)->rs_transition);\ - swab32((ptr)->rs_pad);\ -} - - -#define RG_PORT 41966 -#define RG_VF_PORT 41968 -#define RG_PURPOSE 0x11398fed -#define RG_SERVICE_GROUP "usrm::manager" - -#define RG_ACTION_REQUEST /* Message header */ 0x138582 -/* Argument to RG_ACTION_REQUEST */ -#define RG_ACTION_MASTER 0xfe0db143 -#define RG_ACTION_USER 0x3f173bfd -/* */ -#define RG_EVENT 0x138583 - -#define RG_SUCCESS 0 -#define RG_FAIL 1 -#define RG_START 2 -#define RG_STOP 3 -#define RG_STATUS 4 -#define RG_DISABLE 5 -#define RG_STOP_RECOVER 6 -#define RG_START_RECOVER 7 -#define RG_RESTART 8 -#define RG_EXITING 9 -#define RG_INIT 10 -#define RG_ENABLE 11 -#define RG_STATUS_NODE 12 -#define RG_RELOCATE 13 -#define RG_CONDSTOP 14 -#define RG_CONDSTART 15 -#define RG_START_REMOTE 16 /* Part of a relocate */ -#define RG_STOP_USER 17 /* User-stop request */ -#define RG_STOP_EXITING 18 /* Exiting. */ -#define RG_LOCK 19 -#define RG_UNLOCK 20 -#define RG_QUERY_LOCK 21 -/* #define RG_MIGRATE 22 */ -/* Compat: FREEZE = 23, UNFREEZE = 24 */ -/* #define RG_STATUS_INQUIRY 25 */ -#define RG_NONE 999 - -const char *rg_req_str(int req); - -int handle_relocate_req(char *svcName, int request, uint64_t preferred_target, - uint64_t *new_owner); -int handle_start_req(char *svcName, int req, uint64_t *new_owner); -int handle_recover_req(char *svcName, uint64_t *new_owner); -int handle_start_remote_req(char *svcName, int req); - -/* Resource group states (for now) */ -#define RG_STATE_BASE 110 -#define RG_STATE_STOPPED 110 /** Resource group is stopped */ -#define RG_STATE_STARTING 111 /** Resource is starting */ -#define RG_STATE_STARTED 112 /** Resource is started */ -#define RG_STATE_STOPPING 113 /** Resource is stopping */ -#define RG_STATE_FAILED 114 /** Resource has failed */ -#define RG_STATE_UNINITIALIZED 115 /** Thread not running yet */ -#define RG_STATE_CHECK 116 /** Checking status */ -#define RG_STATE_ERROR 117 /** Recoverable error */ -#define RG_STATE_RECOVER 118 /** Pending recovery */ -#define RG_STATE_DISABLED 119 /** Resource not allowd to run */ -/* #define RG_STATE_MIGRATE 120 */ - -#define DEFAULT_CHECK_INTERVAL 10 - -const char *rg_state_str(int val); -int rg_state_str_to_id(const char *val); -const char *agent_op_str(int val); - -int eval_groups(int local, uint64_t nodeid, int nodeStatus); - -int rg_status(const char *resgroupname); -int group_op(char *rgname, int op); -void rg_init(void); - -int svc_start(char *svcName, int req); -int svc_stop(char *svcName, int error); -int svc_status(char *svcName); -int svc_disable(char *svcName); -int svc_fail(char *svcName); -int check_restart(char *svcName); -int add_restart(char *svcName); - -int rt_enqueue_request(const char *resgroupname, int request, int response_fd, - int max, uint64_t target, int arg0, int arg1); - -void send_response(int ret, uint64_t owner, request_t *req); -void send_ret(int fd, char *name, int ret, int req, uint64_t newowner); - -/* do this op on all resource groups. The handler for the request - will sort out whether or not it's a valid request given the state */ -void rg_doall(int request, int block, char *debugfmt); -void do_status_checks(void); /* Queue status checks for locally running - services */ - -/* from rg_state.c */ -int set_rg_state(char *name, rg_state_t *svcblk); -int get_rg_state(char *servicename, rg_state_t *svcblk); -uint64_t best_target_node(cluster_member_list_t *allowed, uint64_t owner, - char *rg_name, int lock); -char *c_name(char *svcName); - -#ifdef DEBUG -int _rg_lock_dbg(char *, void **, char *, int); -#define rg_lock(name, p) _rg_lock_dbg(name, p, __FILE__, __LINE__) - -int _rg_unlock_dbg(char *, void *, char *, int); -#define rg_unlock(name, p) _rg_unlock_dbg(name, p, __FILE__, __LINE__) - -#else -int rg_lock(char *name, void **p); -int rg_unlock(char *name, void *p); -#endif - - -/* - from memberlist.c - */ -void member_list_update(cluster_member_list_t *new_ml); -cluster_member_list_t *member_list(void); -uint64_t my_id(void); -int member_online(uint64_t nid); -void member_set_state(uint64_t nid, int state); - - -/* Return codes */ -#define RG_EDEPEND -17 /* Dependency rule would be violated */ -#define RG_EEXCL -16 /* Service not runnable due to - the fact that it is tagged - exclusive and there are no - empty nodes. */ -#define RG_EDOMAIN -15 /* Service not runnable given the - set of nodes and its failover - domain */ -#define RG_ESCRIPT -14 /* S/Lang script failed */ -#define RG_EFENCE -13 /* Fencing operation pending */ -#define RG_ENODE -12 /* Node is dead/nonexistent */ -#define RG_EINVAL -11 /* Invalid operation for resource */ -#define RG_EQUORUM -10 /* Operation requires quorum */ - -#define RG_ERELO -9 /* Operation cannot complete here */ -#define RG_ENODEDEATH -8 /* Processing node died */ -#define RG_ERUN -7 /* Service is running already */ -#define RG_EAGAIN -6 /* Try again */ -#define RG_EDEADLCK -5 /* Operation would cause deadlock */ -#define RG_ENOSERVICE -4 /* Service does not exist */ -#define RG_EFORWARD -3 /* Ask current service owner to do this, please */ -#define RG_EABORT -2 /* Request cancelled */ -#define RG_EFAIL -1 /* Generic error */ -#define RG_ESUCCESS 0 -#define RG_YES 1 -#define RG_NO 2 - - -const char *rg_strerror(int val); - - -/* - * Fail-over domain states - */ -#define FOD_ILLEGAL 0 -#define FOD_GOOD 1 -#define FOD_BETTER 2 -#define FOD_BEST 3 - -/* - Fail-over domain flags - */ -#define FOD_ORDERED (1<<0) -#define FOD_RESTRICTED (1<<1) -#define FOD_NOFAILBACK (1<<2) - -/* - Status tree flags - */ -#define SFL_FAILURE (1<<0) -#define SFL_RECOVERABLE (1<<1) - -//#define DEBUG -#ifdef DEBUG - -#define dprintf(fmt, args...) \ -{\ - printf("{%d} ", gettid());\ - printf(fmt, ##args);\ - fflush(stdout);\ -} - -#if 0 -#define pthread_mutex_lock(mutex) \ -{\ - printf("lock(%s) @ %s:%d\n", #mutex, __FUNCTION__, __LINE__);\ - fflush(stdout);\ - pthread_mutex_lock(mutex);\ -} - - -#define pthread_mutex_unlock(mutex) \ -{\ - printf("unlock(%s) @ %s:%d\n", #mutex, __FUNCTION__, __LINE__);\ - fflush(stdout);\ - pthread_mutex_unlock(mutex);\ -} -#endif - -#else /* DEBUG */ - -#define dprintf(fmt, args...) - -#endif - -#endif diff --git a/rgmanager/include/reslist.h b/rgmanager/include/reslist.h deleted file mode 100644 index 4d3feea..0000000 --- a/rgmanager/include/reslist.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _RESLIST_H -#define _RESLIST_H - -#include <stdint.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include <libxml/xpath.h> -#include <sets.h> - - -#define RA_PRIMARY (1<<0) /** Primary key */ -#define RA_UNIQUE (1<<1) /** Unique for given type */ -#define RA_REQUIRED (1<<2) /** Required (or an error if not present */ -#define RA_INHERIT (1<<3) /** Inherit a parent resource's attr */ -#define RA_RECONFIG (1<<4) /** Allow inline reconfiguration */ - -#define RF_INLINE (1<<0) -#define RF_DEFINED (1<<1) -#define RF_NEEDSTART (1<<2) /** Used when adding/changing resources */ -#define RF_NEEDSTOP (1<<3) /** Used when deleting/changing resources */ -#define RF_COMMON (1<<4) /** " */ -#define RF_INDEPENDENT (1<<5) /** Define this for a resource if it is - otherwise an independent subtree */ -#define RF_RECONFIG (1<<6) - -#define RF_INIT (1<<7) /** Resource rule: Initialize this resource - class on startup */ -#define RF_DESTROY (1<<8) /** Resource rule flag: Destroy this - resource class if you delete it from - the configuration */ -#define RF_ROOT (1<<9) - -#define RF_ENFORCE_TIMEOUTS (1<<10) /** Enforce timeouts for this node */ - - - -#define RES_STOPPED (0) -#define RES_STARTED (1) -#define RES_FAILED (2) - -#ifndef SHAREDIR -#define SHAREDIR "/usr/share/rgmanager" -#endif - -#define RESOURCE_ROOTDIR SHAREDIR -#define RESOURCE_TREE_ROOT "//rm" -#define RESOURCE_BASE RESOURCE_TREE_ROOT "/resources" -#define RESOURCE_ROOT_FMT RESOURCE_TREE_ROOT "/%s[%d]" - -#define RESOURCE_MAX_LEVELS 100 - -/* Include OCF definitions */ -#include <res-ocf.h> - - -typedef struct _resource_attribute { - char *ra_name; - char *ra_value; - int ra_flags; - int _pad_; -} resource_attr_t; - - -typedef struct _resource_child { - char *rc_name; - int rc_startlevel; - int rc_stoplevel; - int rc_forbid; - int rc_flags; -} resource_child_t; - - -typedef struct _resource_act { - char *ra_name; - time_t ra_timeout; - time_t ra_last; - time_t ra_interval; - int ra_depth; - int _pad_; -} resource_act_t; - - -typedef struct _resource_rule { - list_head(); - char * rr_type; - char * rr_agent; - char * rr_version; /** agent XML spec version; OCF-ism */ - int rr_flags; - int rr_maxrefs; - resource_attr_t * rr_attrs; - resource_child_t * rr_childtypes; - resource_act_t * rr_actions; -} resource_rule_t; - - -typedef struct _resource { - list_head(); - resource_rule_t * r_rule; - char * r_name; - resource_attr_t * r_attrs; - resource_act_t * r_actions; - time_t r_started; /** Time this resource was last started */ - int r_flags; - int r_refs; - int r_incarnations; /** Number of instances running locally */ - int _pad_; /* align */ -} resource_t; - - -typedef struct _rg_node { - list_head(); - struct _rg_node *rn_child, *rn_parent; - resource_t *rn_resource; - resource_act_t *rn_actions; - restart_counter_t rn_restart_counter; - int rn_state; /* State of this instance of rn_resource */ - int rn_flags; - int rn_last_status; - int rn_last_depth; - int rn_checked; - int rn_pad; -} resource_node_t; - -typedef struct _fod_node { - list_head(); - char *fdn_name; - int fdn_prio; - uint64_t fdn_nodeid; /* on rhel4 this will be 64-bit int */ -} fod_node_t; - -typedef struct _fod { - list_head(); - char *fd_name; - fod_node_t *fd_nodes; - int fd_flags; - int _pad_; /* align */ -} fod_t; - - -/* - Exported Functions - */ -int res_start(resource_node_t **tree, resource_t *res, void *ret); -int res_stop(resource_node_t **tree, resource_t *res, void *ret); -int res_status(resource_node_t **tree, resource_t *res, void *ret); -int res_condstart(resource_node_t **tree, resource_t *res, void *ret); -int res_condstop(resource_node_t **tree, resource_t *res, void *ret); -int res_exec(resource_node_t *node, int op, const char *arg, int depth); -/*int res_resinfo(resource_node_t **tree, resource_t *res, void *ret);*/ -int expand_time(char *val); -int store_action(resource_act_t **actsp, char *name, int depth, int timeout, int interval); - - -/* - Calculate differences - */ -int resource_delta(resource_t **leftres, resource_t **rightres); -int resource_tree_delta(resource_node_t **, resource_node_t **); - - -/* - Load/kill resource rule sets - */ -int load_resource_rules(const char *rpath, resource_rule_t **rules); -void print_resource_rule(resource_rule_t *rr); -void destroy_resource_rules(resource_rule_t **rules); - -/* - Load/kill resource sets - */ -int load_resources(int ccsfd, resource_t **reslist, resource_rule_t **rulelist); -void print_resource(resource_t *res); -void destroy_resources(resource_t **list); - -/* - Construct/deconstruct resource trees - */ -int build_resource_tree(int ccsfd, resource_node_t **tree, - resource_rule_t **rulelist, resource_t **reslist); -void print_resource_tree(resource_node_t **tree); -void destroy_resource_tree(resource_node_t **tree); - -/* - Construct/deconstruct failover domains - */ -int construct_domains(int ccsfd, fod_t **domains); -void deconstruct_domains(fod_t **domains); -void print_domains(fod_t **domains); -int node_should_start(uint64_t nodeid, cluster_member_list_t *membership, - char *rg_name, fod_t **domains); -int node_domain_set(fod_t **domains, char *name, set_type_t **ret, int *retlen, int *flags); -int node_domain_set_safe(char *domainname, set_type_t **ret, int *retlen, int *flags); - - -/* - Handy functions - */ -resource_t *find_resource_by_ref(resource_t **reslist, char *type, char *ref); -resource_t *find_root_by_ref(resource_t **reslist, char *ref); -resource_rule_t *find_rule_by_type(resource_rule_t **rulelist, char *type); -void res_build_name(char *, size_t, resource_t *); - -/* - Internal functions; shouldn't be needed. - */ -char *xpath_get_one(xmlDocPtr doc, xmlXPathContextPtr ctx, char *query); -int store_attribute(resource_attr_t **attrsp, char *name, char *value, - int flags); - -resource_t *load_resource(int ccsfd, resource_rule_t *rule, char *base); -int store_resource(resource_t **reslist, resource_t *newres); -void destroy_resource(resource_t *res); - -char *attr_value(resource_node_t *node, char *attrname); -char *rg_attr_value(resource_node_t *node, char *attrname); -char *res_attr_value(resource_t *res, char *attrname); -char *primary_attr_value(resource_t *); -int rescmp(resource_t *l, resource_t *r); - -#ifdef NO_CCS -int conf_get(char *query, char **ret); -int conf_setconfig(char *path); -#endif - -#endif /* _RESLIST_H */ diff --git a/rgmanager/include/restart_counter.h b/rgmanager/include/restart_counter.h deleted file mode 100644 index 2f158ad..0000000 --- a/rgmanager/include/restart_counter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/* Time-based restart counters for rgmanager */ - -#ifndef _RESTART_COUNTER_H -#define _RESTART_COUNTER_H - -typedef void *restart_counter_t; - -int restart_add(restart_counter_t arg); -int restart_clear(restart_counter_t arg); -int restart_count(restart_counter_t arg); -int restart_treshold_exceeded(restart_counter_t arg); -restart_counter_t restart_init(time_t expire_timeout, int max_restarts); -int restart_cleanup(restart_counter_t arg); - -#endif diff --git a/rgmanager/include/rg_locks.h b/rgmanager/include/rg_locks.h deleted file mode 100644 index 4cb808b..0000000 --- a/rgmanager/include/rg_locks.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef __RG_LOCKS_H -#define __RG_LOCKS_H - -int rg_running(void); - -int rg_locked(void); -int rg_lockall(int flag); -int rg_unlockall(int flag); - -int rg_quorate(void); -int rg_set_quorate(void); -int rg_set_inquorate(void); - -int rg_inc_threads(void); -int rg_dec_threads(void); -int rg_wait_threads(void); - -int rg_initialized(void); -int rg_set_initialized(void); -int rg_set_uninitialized(void); -int rg_wait_initialized(void); - -int rg_inc_status(void); -int rg_dec_status(void); -int rg_set_statusmax(int max); - -int rg_inc_children(void); -int rg_dec_children(void); -int rg_set_childmax(int max); - -int ccs_lock(void); -int ccs_unlock(int fd); - -#endif - diff --git a/rgmanager/include/rg_queue.h b/rgmanager/include/rg_queue.h deleted file mode 100644 index d40793e..0000000 --- a/rgmanager/include/rg_queue.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifndef _RG_QUEUE_H -#define _RG_QUEUE_H -#include <list.h> -#include <stdint.h> -#include <sys/time.h> -#include <unistd.h> -#include <magmamsg.h> - - -/** - * Resource Group thread request queue entry. - */ -typedef struct _request { - list_head(); /** Next/prev pointers */ - char rr_group[64]; /** Resource Group */ - uint32_t rr_request; /** Request */ - uint32_t rr_errorcode; /** Error condition */ - uint32_t rr_orig_request; /** Original request */ - uint64_t rr_target; /** Target node */ - uint32_t rr_arg0; /** Integer argument */ - uint32_t rr_arg1; /** Integer argument */ - uint32_t rr_arg2; /** Integer argument */ - uint32_t rr_line; /** Line no */ - uint32_t rr_resp_fd; /** FD to send response */ - char *rr_file; /** Who made req */ - time_t rr_when; /** time to execute */ -} request_t; - - -int _rq_queue_request(request_t **queue, char *name, uint32_t request, - uint32_t err, uint32_t oldreq, uint32_t fd, time_t when, - uint64_t target, uint32_t arg0, uint32_t arg1, char *file, - int line); - -#define rq_queue_request(queue, name, request, err, oldreq,\ - fd, when, target, arg0, arg1) \ - _rq_queue_request(queue, name, request, err, oldreq, fd, when, \ - target, arg0, arg1, __FILE__, __LINE__) - -request_t *rq_next_request(request_t **q); -int rq_queue_empty(request_t **q); -void rq_free(request_t *foo); - -void forward_request(request_t *req); -void forward_message(int fd, void *msg, uint64_t nodeid); - - -#endif diff --git a/rgmanager/include/rmtab.h b/rgmanager/include/rmtab.h deleted file mode 100644 index f2be1f8..0000000 --- a/rgmanager/include/rmtab.h +++ /dev/null @@ -1,119 +0,0 @@ -/** @file - * Header for rmtab.c. - */ -/* - Copyright Red Hat, Inc. 2002 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/* - * Author: Lon H. Hohberger <lhh at redhat.com> - */ -#ifndef _RMTAB_H -#define _RMTAB_H - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdint.h> - -/* Shamelessly ripped from nfs-utils */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#ifndef _PATH_RMTAB -#define _PATH_RMTAB "/var/lib/nfs/rmtab" -#endif - -/* private types */ -#ifndef MSG_RMTAB_UPDATE -#define MSG_RMTAB_UPDATE 978 -#endif - -#ifndef MSG_RMTAB_BOOT -#define MSG_RMTAB_BOOT 603 -#endif - -/* Just a mem-size trim for now */ -#define __MAXPATHLEN 1024 - -/** - * rmtab node list entry. - * - * This contains all the information necessary to reconstruct a line in - * /var/lib/nfs/rmtab. - */ -typedef struct _rmtab_node { - struct _rmtab_node *rn_next; /**< Next pointer */ - char *rn_hostname; /**< Mount entry hostname */ - char *rn_path; /**< Export mounted */ - uint32_t rn_count; /**< Number of times export is - mounted. */ -} rmtab_node; - - -/* - * list addition (insert) - */ -int __rmtab_insert(rmtab_node **head, rmtab_node *rnew); -rmtab_node *rmtab_insert(rmtab_node **head, rmtab_node *pre, char *host, - char *path, int count); - -/* - * list deletion/removal/etc. - */ -rmtab_node *__rmtab_remove(rmtab_node **head, rmtab_node *entry); -rmtab_node *rmtab_remove(rmtab_node **head, char *host, char *path); -void rmtab_kill(rmtab_node **head); - -/* - * diff/merge functions - */ -int rmtab_diff(rmtab_node *old, rmtab_node *new, rmtab_node **diff); -int rmtab_merge(rmtab_node **head, rmtab_node *patch); - -/* - * Read/write/import/export... - */ -int rmtab_import(rmtab_node **head, FILE *fp); -int rmtab_export(rmtab_node *head, FILE *fp); - -int rmtab_read(rmtab_node **head, char *filename); -int rmtab_write_atomic(rmtab_node *head, char *filename); - -/* - * Translation to/from network block [array] style - */ -int rmtab_pack(char *dest, rmtab_node *head); -int rmtab_unpack(rmtab_node **dest, char *src, size_t srclen); - -/* - * utility functions - */ -int rmtab_cmp_min(rmtab_node *left, rmtab_node *right); -int rmtab_cmp(rmtab_node *left, rmtab_node *right); -size_t rmtab_pack_size(rmtab_node *head); -int rmtab_move(rmtab_node **dest, rmtab_node **src); - -/* - * DEBUG junk - */ -#ifdef DEBUG -int rmtab_dump(rmtab_node *head); -#endif - -#endif diff --git a/rgmanager/include/sets.h b/rgmanager/include/sets.h deleted file mode 100644 index 8cc271b..0000000 --- a/rgmanager/include/sets.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** - @file sets.h - Header file for sets.c - @author Lon Hohberger <lhh at redhat.com> - */ -#ifndef _SETS_H -#define _SETS_H - -#include <stdint.h> -typedef uint64_t set_type_t; - -int s_add(set_type_t *, int *, set_type_t); -int s_union(set_type_t *, int, set_type_t *, - int, set_type_t **, int *); - -int s_intersection(set_type_t *, int, set_type_t *, - int, set_type_t **, int *); -int s_delta(set_type_t *, int, set_type_t *, - int, set_type_t **, int *); -int s_subtract(set_type_t *, int, set_type_t *, int, set_type_t **, int *); -int s_shuffle(set_type_t *, int); - -#endif diff --git a/rgmanager/include/signals.h b/rgmanager/include/signals.h deleted file mode 100644 index c5f7d6c..0000000 --- a/rgmanager/include/signals.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SIGNALS_H -#define __SIGNALS_H - -void *setup_signal(int, void (*)(int)); -int block_signal(int sig); -int unblock_signal(int sig); -int block_all_signals(void); - -#endif diff --git a/rgmanager/include/vf.h b/rgmanager/include/vf.h deleted file mode 100644 index 4376c47..0000000 --- a/rgmanager/include/vf.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - */ -/** @file - * Header for vf.c. - */ -#ifndef __VF_H -#define __VF_H - -#include <magma.h> -#include <stdint.h> -#include <sys/types.h> -#include <msgsimple.h> - -/* - * We use this to initiate the VF protocol. This doesn't really belong here. - */ -typedef struct __attribute__ ((packed)) _vf_msg_info { - uint32_t vf_command; - uint32_t vf_pad; - char vf_keyid[64]; - uint32_t vf_coordinator; /* Node ID of who coordinates */ - uint32_t vf_datalen; - uint64_t vf_view; - char vf_data[0]; -} vf_msg_info_t; - -#define swab_vf_msg_info_t(ptr) \ -{\ - swab32((ptr)->vf_command);\ - swab32((ptr)->vf_coordinator);\ - swab64((ptr)->vf_view);\ - swab32((ptr)->vf_datalen);\ -} - - -typedef struct __attribute__ ((packed)) _vf_msg { - generic_msg_hdr vm_hdr; - vf_msg_info_t vm_msg; -} vf_msg_t; - -#define swab_vf_msg_t(ptr) \ -{\ - swab_generic_msg_hdr(&((ptr)->vm_hdr));\ - swab_vf_msg_info_t(&((ptr)->vm_msg));\ -} - - -/* - * Exp: Callback function proto definitions. - */ -typedef int32_t (*vf_vote_cb_t)(char *, uint64_t, void *, uint32_t); -typedef int32_t (*vf_commit_cb_t)(char *, uint64_t, void *, uint32_t); - -/* - * INTERNAL VF STRUCTURES - */ - - /** - * A view node. This holds the data from a VF_JOIN_VIEW message until it - * is committed. - */ -typedef struct _view_node { - struct _view_node * - vn_next; /**< Next pointer. */ - int vn_fd; /**< Associated file descriptor. */ - uint32_t vn_nodeid; /**< Node ID of coordinator. */ - struct timeval vn_timeout; /**< Expiration time. */ - uint64_t vn_viewno; /**< View Number. */ - uint32_t vn_datalen; /**< Length of included data. */ - uint32_t vn_pad; /**< pad */ - char vn_data[0]; /**< Included data. */ -} view_node_t; - - -/** - * A commit node. This holds a commit message until it is possible to - * resolve it with its corresponding view_node_t. - */ -typedef struct _commit_node { - struct _commit_node * - vc_next; /**< Next pointer. */ - int vc_fd; /**< File descriptor. */ -} commit_node_t; - - -/** - * A key node. For each type of data used, a key node is created - * and managed by the programmer. - */ -typedef struct _key_node { - struct _key_node *kn_next; /**< Next pointer. */ - char *kn_keyid; /**< Key ID this key node refers to. */ - uint32_t kn_pid; /**< PID. Child process running - View-Formation on this key. */ - uint32_t kn_datalen; /**< Current length of data. */ - view_node_t *kn_jvlist; /**< Buffered join-view list. */ - commit_node_t *kn_clist; /**< Buffered commit list. */ - uint64_t kn_viewno; /**< Current view number of data. */ - char *kn_data; /**< Current data. */ - int kn_tsec; /**< Default timeout (in seconds */ - int kn_pad; /**< pad */ - vf_vote_cb_t kn_vote_cb; /**< Voting callback function */ - vf_commit_cb_t kn_commit_cb; /**< Commit callback function */ -} key_node_t; - - - - -/* - * VF message types. - */ -/* Main programs handle this */ -#define VF_MESSAGE 0x3000 - -#define VF_JOIN_VIEW 0x3001 -#define VF_VOTE 0x3002 -#define VF_ABORT 0x3004 -#define VF_VIEW_FORMED 0x3005 -#define VF_CURRENT 0x3006 -#define VF_ACK 0x3007 -#define VF_NACK 0x3008 - - -#define VF_COORD_TIMEOUT 60 /* 60 seconds MAX timeout */ -#define VF_COMMIT_TIMEOUT_MIN (2 * VF_COORD_TIMEOUT) -#define MAX_FDS 1024 - -/* Return codes for vf_handle_msg... */ -#define VFR_ERROR 100 -#define VFR_OK 0 -#define VFR_YES VFR_OK -#define VFR_NO 1 -#define VFR_COMMIT 2 -#define VFR_ABORT 3 -#define VFR_NODATA 4 - -/* - * Operational flags for vf_start - */ -#define VFF_RETRY 0x1 -#define VFF_IGN_CONN_ERRORS 0x2 -#define VFF_IGN_WRITE_ERRORS 0x4 -#define VFF_IGN_READ_ERRORS 0x8 -#define VFF_IGN_ALL_ERRORS (VFF_IGN_CONN_ERRORS|VFF_IGN_WRITE_ERRORS|\ - VFF_IGN_READ_ERRORS) - - -/* - * VF Stuff. VF only talks to peers. - */ -int vf_init(uint64_t, uint16_t, vf_vote_cb_t, vf_commit_cb_t); -int vf_shutdown(void); - -/* - * Returns a file descriptor on which the caller can select(). - * - * This is a pipe which is used to notify the parent process that - * the child has exited - */ -int vf_write(cluster_member_list_t *membership, uint32_t flags, - char *keyid, void *data, uint32_t datalen); -int vf_read(cluster_member_list_t *membership, char *keyid, - uint64_t *view, void **data, uint32_t *datalen); -int vf_key_init(char *keyid, int timeout, vf_vote_cb_t vote_cb, - vf_commit_cb_t commit_cb); -int getuptime(struct timeval *tv); - -#define MSGP_VFS 0x18dcf1 -#define MSGP_VFC 0x0103fab - -#endif diff --git a/rgmanager/init.d/Makefile b/rgmanager/init.d/Makefile deleted file mode 100644 index 580e027..0000000 --- a/rgmanager/init.d/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -TARGET= rgmanager - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -top_srcdir=.. - -include ${top_srcdir}/make/defines.mk - -all: - -clean: - -install: - install -d ${DESTDIR}/etc/init.d - install ${TARGET} ${DESTDIR}/etc/init.d - -uninstall: - ${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d diff --git a/rgmanager/init.d/rgmanager b/rgmanager/init.d/rgmanager deleted file mode 100755 index 5760574..0000000 --- a/rgmanager/init.d/rgmanager +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2003 Red Hat, Inc. -# -# This program is Free Software. You may modify and/or redistribute it under -# the terms of the GNU General Public License version 2, or (at your option) -# any later version. -# -# description: Starts and stops Red Hat Service (resource group) Manager -# chkconfig: 2345 99 01 -# - -# Source function library -. /etc/init.d/functions - -# Grab the network config file -. /etc/sysconfig/network - -# Grab cluster start config if it exists -[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - -PATH=/sbin:/bin:/usr/sbin:/usr/bin - -export PATH - -ID="Cluster Service Manager" -RGMGRD="clurgmgrd" -CFG_FILE="/etc/cluster/cluster.conf" - -LOG_ERR=3 -LOG_WARNING=4 -LOG_NOTICE=5 -LOG_INFO=6 - -# -# Only root wants to run this... -# -[ `id -u` = 0 ] || exit 0 - -# -# If we're not configured, then don't start anything. -# -[ "${NETWORKING}" = "yes" ] || exit 0 -[ -f "$CFG_FILE" ] || exit 0 - - -# -# log_and_print <level> <message> -# -log_and_print() -{ - if [ -z "$1" -o -z "$2" ]; then - return 1; - fi - - clulog -p $$ -n "rgmanager" -s $1 "$2" - echo $2 - - return 0; -} - - -# -# Bring down the cluster on a node. -# -stop_cluster() -{ - kill -TERM `pidof $RGMGRD` - - while [ 0 ]; do - - if [ -n "`pidof $RGMGRD`" ]; then - echo -n $"Waiting for services to stop: " - while [ -n "`pidof $RGMGRD`" ]; do - sleep 1 - done - echo_success - echo - else - echo $"Services are stopped." - fi - - # Ensure all NFS rmtab daemons are dead. - killall $RMTABD &> /dev/null - - rm -f /var/run/$RGMGRD.pid - - return 0 - done -} - - - -case $1 in - start) - [ -z "$RGMGR_OPTS" ] && RGMGR_OPTS="-t 30" - echo -n $"Starting $ID: " - daemon $RGMGRD $RGMGR_OPTS - rv=$? - echo - - # To be consistent... - if [ $rv -eq 0 ]; then - touch /var/lock/subsys/rgmanager - fi - exit $rv - ;; - - restart) - $0 status &> /dev/null - if [ $? -ne 1 ]; then - $0 stop - fi - $0 start - ;; - - condrestart) - $0 status $> /dev/null - if [ $? -eq 0 ]; then - $0 stop - $0 start - fi - ;; - - reload) - clulog -p $LOG_NOTICE "Reloading Resource Configuration." - echo -n $"Reloading Resource Configuration: " - killproc $RGMGRD -HUP - rv=$? - echo - - exit $rv - ;; - - status) - status $RGMGRD - exit $? - ;; - - stop) - if [ -n "`pidof $RGMGRD`" ]; then - log_and_print $LOG_NOTICE "Shutting down $ID..." - stop_cluster - fi - - rm -f /var/lock/subsys/rgmanager - log_and_print $LOG_NOTICE "$ID is stopped." - ;; -esac diff --git a/rgmanager/make/defines.mk.input b/rgmanager/make/defines.mk.input deleted file mode 100644 index 2b827e8..0000000 --- a/rgmanager/make/defines.mk.input +++ /dev/null @@ -1,42 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -#Install Locations -sbindir ?= ${DESTDIR}/@SBINDIR@ -mandir ?= ${DESTDIR}/@MANDIR@ -libdir ?= ${DESTDIR}/@LIBDIR@ -incdir ?= ${DESTDIR}/@INCDIR@ -sharedir ?= ${DESTDIR}/@SHAREDIR@ - -# Where's the kernel? -KERNEL_SRC = @KERNEL_SRC@ - -# C Compiler defaults -CC = @CC@ - -STRIP = strip -AR = ar -LD = ld -#RANLIB = echo -RANLIB = ranlib - -# Default CFLAGS -CFLAGS += -DSHAREDIR="@SHAREDIR@" -Wall ${INCLUDE} - -# -# Wrappers around pthread_mutex / pthread_rwlock calls for deadlock -# detection (and other things) -# -#CFLAGS += -DSHAREDIR="/usr/share/cluster" -Wall ${INCLUDE} -DWRAP_LOCKS -DMAX_DISPATCH_RETRIES=3 -#LDFLAGS += -Wl,-wrap,pthread_mutex_lock,-wrap,pthread_mutex_unlock,-wrap,pthread_rwlock_rdlock,-wrap,pthread_rwlock_wrlock,-wrap,pthread_rwlock_unlock - diff --git a/rgmanager/make/release.mk.input b/rgmanager/make/release.mk.input deleted file mode 100644 index 84d1d46..0000000 --- a/rgmanager/make/release.mk.input +++ /dev/null @@ -1,15 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -RELEASE_MAJOR = DEVEL -RELEASE_MINOR = DATE diff --git a/rgmanager/man/Makefile b/rgmanager/man/Makefile deleted file mode 100644 index 4e34b6e..0000000 --- a/rgmanager/man/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### -top_srcdir=.. -UNINSTALL = ${top_srcdir}/scripts/uninstall.pl -TARGETS = clubufflush.8 clufindhostname.8 clulog.8 \ - clurgmgrd.8 clurmtabd.8 clustat.8 clusvcadm.8 - -include ${top_srcdir}/make/defines.mk - -install: - install -d ${mandir}/man8 - install ${TARGETS} ${mandir}/man8 - -uninstall: - ${UNINSTALL} ${TARGETS} ${mandir}/man8 diff --git a/rgmanager/man/cluarp.8 b/rgmanager/man/cluarp.8 deleted file mode 100644 index 5bc912e..0000000 --- a/rgmanager/man/cluarp.8 +++ /dev/null @@ -1,15 +0,0 @@ -.TH "cluarp" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands" -.SH "NAME" -cluarp - Send a gratuitous ARP -.SH "WARNING" -Use of this command can cause the cluster to malfunction. Do not run this -without instructions from Red Hat Support. -.SH "DESCRIPTION" -.PP -The -.B cluarp -command is an internal command used to broadcast new ARP information when -a service IP address is configured by the Service Manager. - -.SH "SEE ALSO" -arp(8) diff --git a/rgmanager/man/clubufflush.8 b/rgmanager/man/clubufflush.8 deleted file mode 100644 index 848d01e..0000000 --- a/rgmanager/man/clubufflush.8 +++ /dev/null @@ -1,13 +0,0 @@ -.TH "clubufflush" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands" -.SH "NAME" -clubufflush - Flush buffers on a service's file system. - -.SH "DESCRIPTION" -.PP -The -.B clubufflush -command is an internal command used to synchronize buffers to disk -prior to stopping a clustered service. - -.SH "SEE ALSO" -sync(1), sync(2), fsync(2), fdatasync(2) diff --git a/rgmanager/man/clufindhostname.8 b/rgmanager/man/clufindhostname.8 deleted file mode 100644 index 7035cd5..0000000 --- a/rgmanager/man/clufindhostname.8 +++ /dev/null @@ -1,22 +0,0 @@ -.TH "clufindhostname" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands" -.SH "NAME" -clufindhostname - Find a hostname or IP address given the other. -.SH "SYNOPSIS" -.B clufindhostname -.B [-i <ip_address>] -.B [-n <hostname>] - -.SH "DESCRIPTION" -.PP -The -.B clufindhostname -command is a wrapper around gethostbyname(3) and gethostbyaddr(3). - -.SH "OPTIONS" -.IP "-i <ip_address>" -Call gethostbyaddr(3) on specified IP address. -.IP "-n <hostname>" -Call gethostbyname(3) on specified hostname. - -.SH "SEE ALSO" -host(1), gethostbyname(3), gethostbyaddr(3) diff --git a/rgmanager/man/clulog.8 b/rgmanager/man/clulog.8 deleted file mode 100644 index 571c341..0000000 --- a/rgmanager/man/clulog.8 +++ /dev/null @@ -1,35 +0,0 @@ -.TH "clulog" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands" -.SH "NAME" -clulog - Log a message to the cluster and/or system logs -.SH "SYNOPSIS" -.B clulog -.B -s -.I severity -.B [-l -.I priority_filter -.B ] -.B [-n -.I program_name -.B ] -.B [-p -.I pid -.B ] -.B message -.SH "DESCRIPTION" -.PP -The -.B clulog -command sends a message to syslogd(8). -.SH "OPTIONS" -.IP "-s <severity>" -Log at the specified severity (0-7; 0=ALERT, 7=DEBUG). -.IP "-l <priority_filter>" -Apply the specified filter (0-7) for the message. By default, -.B clulog -uses the service manager's assigned log level. -.IP "-n <program_name>" -Log as the specified program name. -.IP "-p <pid>" -Log as the specified PID. -.SH "SEE ALSO" -syslog(2), syslogd(8) diff --git a/rgmanager/man/clunfsops.8 b/rgmanager/man/clunfsops.8 deleted file mode 100644 index ba768e4..0000000 --- a/rgmanager/man/clunfsops.8 +++ /dev/null @@ -1,14 +0,0 @@ -.TH "clunfsops" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands" -.SH "NAME" -clunfsops - Manipulate NFS -.SH "WARNING" -Use of this command can cause the cluster to malfunction. Do not run this -without instructions from Red Hat Support. -.SH "DESCRIPTION" -.PP -The -.B clunfsops -command is an internal command used to manipulate clustered NFS services. - -.SH "SEE ALSO" -nfs(5), rpc.nfsd(8) diff --git a/rgmanager/man/clurgmgrd.8 b/rgmanager/man/clurgmgrd.8 deleted file mode 100644 index bbde0f2..0000000 --- a/rgmanager/man/clurgmgrd.8 +++ /dev/null @@ -1,30 +0,0 @@ -.TH "clusvcmgrd" "8" "Jan 2005" "" "Red Hat Cluster Suite" -.SH "NAME" -Clurgmgrd - Resource Group (Cluster Service) Manager Daemon -.SH "DESCRIPTION" -.PP -.B Clurgmgrd -handles management of user-defined cluster services (also known as resource -groups). This includes handling of user requests including service start, -service disable, service relocate, and service restart. The service -manager daemon also handles restarting and relocating services in the -event of failures. -.SH "HOW IT WORKS" -.PP -The service manager is spawned by an init script after the cluster -infrastructure has been started and ccsd has been spawned, and only -functions when the cluster is quorate. -.LP -During initialization, the service manager runs scripts which ensure that all -services are clear to be started. After that, it determines which services -need to be started and starts them. -.LP -When an event is received, members which are no longer online have their -services taken away from them. The event should only occur in the case that -the member has been fenced whenever fencing is available. -.LP -When a cluster member determines that it is no longer in the cluster quorum, -the service manager stops all services and waits for a new quorum to form. - -.SH "SEE ALSO" -clurmtabd(8), ccsd(8) diff --git a/rgmanager/man/clurmtabd.8 b/rgmanager/man/clurmtabd.8 deleted file mode 100644 index 3094499..0000000 --- a/rgmanager/man/clurmtabd.8 +++ /dev/null @@ -1,37 +0,0 @@ -.TH "clurmtabd" "8" "Jan 2005" "" "Red Hat Cluster Suite" -.SH "NAME" -clurmtabd - Cluster NFS Remote Mount Table Daemon -.SH "DESCRIPTION" -.PP -Instances of -.B clurmtabd -keep entries relevant to a given mount point in sync cluster-wide. It does -this by polling /var/lib/nfs/rmtab periodically. -.SH "HOW IT WORKS" -.PP -A single instance of -.B clurmtabd -is spawned by the service manager (clusvcmgrd(8)) for each mount point in a -given user service. Each instance polls /var/lib/nfs/rmtab every few seconds, -looking for changes. When changes are detected, they are merged in with the -current in-memory view. The entries are filtered according to the mount point -being monitored and are subsequently written out synchronously to that -mount point. -.LP -When a user service is relocated (or after a fail-over), clurmtabd reads the -entries on a given mount point and synchronizes them with the new member's -/var/lib/nfs/rmtab. This is done prior to running the exportfs(8) command -so that clients of the given service do not receive "Stale NFS file handle" -errors. -.SH "NOTES" -.PP -Clurmtabd is not a part of NFS and can not ensure that "Stale NFS file handle" -errors are never received. It is a best-effort attempt. To fully prevent -"Stale NFS file handle" errors, it is necessary to modify the Linux kernel -as well as nfs-utils. - -.SH "FILES" -/var/lib/nfs/rmtab - -.SH "SEE ALSO" -clurgmgrd(8), rpc.mountd(8), exportfs(8) diff --git a/rgmanager/man/clushutdown.8 b/rgmanager/man/clushutdown.8 deleted file mode 100644 index c63159f..0000000 --- a/rgmanager/man/clushutdown.8 +++ /dev/null @@ -1,13 +0,0 @@ -.TH "clushutdown" "27" "Jan 2005" "" "Red Hat Cluster Suite" -.SH "NAME" -clushutdown - Cluster Mass Service Shutdown -.SH "DESCRIPTION" -.PP -.B Clushutdown -is responsible for stopping all services and ensuring that none are restarted -when a member goes off line. It is only useful for situations where an -administrator needs to take enough cluster members offline such that the -cluster quorum will be disrupted. This is not required for shutting down a -single member when all other members are online. -.SH "SEE ALSO" -clusvcadm(8) diff --git a/rgmanager/man/clustat.8 b/rgmanager/man/clustat.8 deleted file mode 100644 index ca84a84..0000000 --- a/rgmanager/man/clustat.8 +++ /dev/null @@ -1,53 +0,0 @@ -.TH "clustat" "8" "Jan 2005" "" "Red Hat Cluster Suite" -.SH "NAME" -clustat - Cluster Status Utility -.SH "SYNOPSIS" -.B clustat -.B [-i -.I delay -.B ] -.B [-I] -.B [-m -.I member -.B ] -.B [-Q] -.B [-s -.I service -.B ] -.B [-v] -.B [-x] - -.SH "DESCRIPTION" -.PP -The -.B clustat -command displays the status of the cluster. It shows membership information, -quorum view, and the state of all configured user services. The -.B clustat -command displays cluster status only from the viewpoint of the cluster system -on which it is running. -.SH "OPTIONS" -.IP "-I" -Display the member ID of the current member. -.IP "-i <delay>" -Display cluster status and refresh the status every -.I delay -seconds. Mutually exclusive with the -.B "-x" -option. -.B "-m <member>" -Display the status of the specified member. -.IP "-Q" -Return cluster quorum status to calling shell. (No output) -.IP "-s <service>" -Displays the status of the specified service. -.IP "-x" -Display cluster configuration combined with status in XML format. Mutually -exclusive with -.B "-i" -option. -.IP -v -Display version information and exit. - -.SH "SEE ALSO" -clusvcadm(8) diff --git a/rgmanager/man/clusvcadm.8 b/rgmanager/man/clusvcadm.8 deleted file mode 100644 index 20ae823..0000000 --- a/rgmanager/man/clusvcadm.8 +++ /dev/null @@ -1,93 +0,0 @@ -.TH "clusvcadm" "8" "Jan 2005" "" "Red Hat Cluster Suite" -.SH "NAME" -clusvcadm - Cluster User Service Administration Utility -.SH "SYNOPSIS" -.B clusvcadm -.B [-d -.I <service> -.B ] -.B [-e -.I <service> -.B ] -.B [-l] -.B [-u] -.B [-S] -.B [-m -.I <member> -.B ] -.B [-r -.I <service> -.B ] -.B [-S] -.B [-R -.I <service> -.B ] -.B [-s -.I <service> -.B ] -.B [-v] - -.SH "DESCRIPTION" -.PP -The -.B clusvcadm -command allows an administrator to enable, disable, relocate, and restart -user services in a cluster. In order to perform cluster service operations, -the cluster daemons must be running (and have quorum) on the member system -on which the command is invoked. - -.SH "OPTIONS" -.IP "-d <service>" -Stops and disables the user service named -.I -service -.IP "-e <service>" -Enables and starts the user service named -.I -service -.IP -l -Lock the local resource group manager. This should only be used if the -administrator intends to perform a global, cluster-wide shutdown. This -prevents starting resource groups on the local node, allowing -services will not fail over during the shutdown of the cluster. -Once the cluster quorum is dissolved, this state is reset. -.IP "-m <member>" -When used in conjunction with either the -.B --e -or -.B --r -options, this specifies the -.I -preferred -target member on which to start the -service. -.IP "-r <service>" -Relocates the user service named -.I -service -to another cluster member. -.IP "-R <service>" -Restarts the user service named -.I -service -on the cluster member on which it is currently running. -.IP "-S" -Display whether each of the active service managers is locked or not. This -can be used to verify the correct operation of the \fB-l\fR and \fB-u\fR -options, but is only useful for debugging. -.IP "-s <service>" -Stops the service named -.I -service -until a member transition or until it is enabled again. -.IP -u -Unlock the cluster's service managers. This allows services to transition -again. - -.IP -v -Display version information and exit. - -.SH "SEE ALSO" -clustat(8) diff --git a/rgmanager/scripts/uninstall.pl b/rgmanager/scripts/uninstall.pl deleted file mode 100755 index 483d5a0..0000000 --- a/rgmanager/scripts/uninstall.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -## Description: Basically the reverse of the install program, except it -## only supports a list of files and a directory as arguments - -$| = 1; - -use Getopt::Std; - -# list all valid options here. User will get errors if invalid options are -# specified on the command line -getopts('hD'); - -$args = 1; - -# We need at least two arguments to uninstall -if(!defined($ARGV[1])) { - $args = 0; -} - -# if the user set the help flag or didn't provide enough args, print help -# and die. -if(defined($opt_h) || ($args == 0)) { - $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n"; - $msg = $msg . "\t-D\tRemove specified directory if empty\n"; - $msg = $msg . "\t-h\tDisplay this help message\n"; - die $msg; -} - -# find out how many command line arguments we have -$length = $#ARGV; -# We need a special case if there is only one file specified -if($length > 1) { - @filelist = @ARGV; - $#filelist = $length - 1; -} -else { - @filelist = @ARGV[0]; -} - -# the last argument is the directory -$dir = @ARGV[$length]; - -# prepend the directory name to all files in the filelist -$i = 0; -print "Attempting to remove the following files from directory $dir/:\n"; -while($i < $length) { - print "@filelist[$i] "; - @filelist[$i] = "$dir/" . @filelist[$i]; - $i++; -} -print "\n"; - -#print "Files:@filelist\n"; -#print "Directory: $dir\n"; - -# delete the files in filelist -$unlinked = unlink @filelist; -if($unlinked < $length) { - print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n" -} -# if user specifed they want the directory deleted, try to delete it. Print -# error message if not able to delete directory, including error. -if(defined($opt_D)) { - $result = rmdir($dir); - if($result == FALSE) { - print "Error! Unable to remove directory $dir/:\n\t$!\n"; - } -} - - diff --git a/rgmanager/src/Makefile b/rgmanager/src/Makefile deleted file mode 100644 index 2841313..0000000 --- a/rgmanager/src/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -all: - cd resources && ${MAKE} all - cd clulib && ${MAKE} all - cd daemons && ${MAKE} all - cd utils && ${MAKE} all - -clean: - cd resources && ${MAKE} clean - cd clulib && ${MAKE} clean - cd daemons && ${MAKE} clean - cd utils && ${MAKE} clean - -check: - cd resources && ${MAKE} check - cd daemons && ${MAKE} check - -distclean: clean - rm -f make/defines.mk - -install: - cd resources && ${MAKE} install - cd clulib && ${MAKE} install - cd daemons && ${MAKE} install - cd utils && ${MAKE} install - -uninstall: - cd resources && ${MAKE} uninstall - cd clulib && ${MAKE} uninstall - cd daemons && ${MAKE} uninstall - cd utils && ${MAKE} uninstall diff --git a/rgmanager/src/clulib/Makefile b/rgmanager/src/clulib/Makefile deleted file mode 100644 index 5531e82..0000000 --- a/rgmanager/src/clulib/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk -INCLUDE += -I $(top_srcdir)/include - -CFLAGS+= -g -I${incdir} -DCMAN_RELEASE_NAME="${RELEASE}" - -CFLAGS+= -g -Wstrict-prototypes -Wshadow -fPIC -D_GNU_SOURCE - - -TARGETS=libclulib.a liblalloc.a - -all: ${TARGETS} - -install: all - -uninstall: - -libclulib.a: clulog.o daemon_init.o signals.o msgsimple.o \ - vft.o gettid.o rg_strings.o wrap_lock.o \ - sets.o - ${AR} cru $@ $^ - ranlib $@ - -liblalloc.a: alloc.o - ${AR} cru $@ $^ - ranlib $@ - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDE) $(CFLAGS) - -clean: - rm -f *.o $(TARGETS) diff --git a/rgmanager/src/clulib/alloc.c b/rgmanager/src/clulib/alloc.c deleted file mode 100644 index b3774b4..0000000 --- a/rgmanager/src/clulib/alloc.c +++ /dev/null @@ -1,1225 +0,0 @@ -/** - Copyright Red Hat, Inc. 2004 - Copyright Lon Hohberger, 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Author: Lon Hohberger <lhh at redhat.com> - <lon at metamorphism.com> - */ -/** - @file - - Bounded memory allocator. This is designed for applications which require - bounded memory allocation and which ought not be swapped out to disk. - - What it is: - - Replacement for malloc, calloc, free, and realloc which allocates - memory from a fixed-size heap, which is either allocated at the time - of the first allocation or during program initialization with a call - to 'malloc_init(size_t count)'. - - - Designed for applications requiring small amounts of RAM. Note - that though we use size_t arguments, the maximum supported in the - header structure is a 32-bit integer. - - - Fairly fast. - - - What it's _not_: - - General purpose. The heap is allocated either at the first call to - malloc() or the call to malloc_init(), and is a fixed size. There is no - memalign/valloc/pvalloc currently. - - - Super-efficient. It's reasonably fast in many situations compared to - glibc's malloc, but records states in the memory blocks to help prevent - accidental double-frees and such (it's still possible, mind you). In - general, your program will consume MORE memory when using this allocator, - because it preallocates a huge block. However, your program should run - faster. It's also probably not terribly efficient in a threaded - program, but it does work (and properly zap its mutex on fork()). - - - malloc algorithm in detail: - - (1) Init the pool as necessary. After the pool is initialized, we have - one large free block which is the size of the memory pool less the header. - - (2) Whenever we get a call to malloc, we look for a free block. If the - size of a free block matches within 25% of the requested size (bounded at - MIN_SAVE), we immediately return that chunk to the user. If no blocks are - found matching this criteria, we look for chunks which are large enough - to split (i.e. with a size >= requested_size + MIN_EXTRA). - - (3) If we find one, we split the block, create a new (smaller) free block, - and return the block to the user. - - [ Note: Steps 4 and 5 only if AGGR_RECLAIM is 0 ] - (4) If none are found, we perform an aggressive consolidation which searches - the entire memory pool for free blocks next to each other and combines - them into one larger block. - - (5) Repeat steps (2) and (3). - - (6) If no blocks are found again, we're done. Return NULL/ENOMEM. - - - free algorithm in detail: - - (1) Sanity check the pointer and block structure it would point to. - - (2) [ If AGGR_RECLAIM = 0 ] Consolidate this block with all free blocks - with a higher address than it in the pool. - - (2) [ If AGGR_RECLAIM = 1 ] Aggressively consolidate all free blocks - in the pool which are next to one another. - - - realloc: - - ... Just an obvious wrapper around malloc. Potentially could resize if - the next block was free and has enough space. I.e. Join-blocks, - resize, and split again if necessary. For now, it works, so we'll - leave it alone. This would be both an increase in speed and memory - efficiency (while performing the operation), but otherwise isn't necessary. - - - calloc: - - ... Really obvious wrapper. Uses memset to clear the memory. - - TODO: Use futex, perhaps, instead of pthread stuff. - */ -#include <stdint.h> -#include <pthread.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <stdint.h> -#include <malloc.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/wait.h> - -#ifndef DEBUG -#define DEBUG /* Record program counter of malloc/calloc */ -#endif /* or realloc call; print misc stuff out */ - -/* Tunable stuff XXX This should be external */ -#define PARANOID /* Trade off a bit of space and speed for - extra sanity checks */ -#define DIE_ON_FAULT /* Kill program if we do something bad - (double free, free after overrun, etc. - for instance) */ -#undef AGGR_RECLAIM /* consolidate_all on free (*slow*) */ - -#undef STACKSIZE /*4 backtrace to store if DEBUG is set */ - -#undef GDB_HOOK /* Dump program addresses in malloc_table - using a fork/exec of gdb (SLOW but fun) - building this defeats the purpose of - a bounded memory allocator, and is only - useful for debugging memory leaks. - This does not harm anything except code - size until "malloc_dump_table" is called. - Given that this is not a normal malloc - API, this should not matter. */ - -#define DEFAULT_SIZE (1<<23) /* 8MB default giant block size */ -#define BUCKET_COUNT (13) /* 2^BUCKET_COUNT = max. interesting size */ -#define MIN_POWER (3) /* 2^MIN_POWER = minimum size */ -#define MIN_SIZE (1<<MIN_POWER) -#define ALIGN (sizeof(void *)) -#define NOBUCKET ((uint16_t)(~0)) -#define MIN_EXTRA (1<<5) /* 64 bytes to split a block */ - -/* Misc stuff */ -#define ST_FREE 0xfec3 /* Block is free */ -#define ST_ALLOC 0x08f7 /* Block is in use */ - - -#ifndef NOPTHREADS -#include <pthread.h> -#ifdef WRAP_LOCKS -static pthread_mutex_t _alloc_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -#else -static pthread_mutex_t _alloc_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif /* WRAP_LOCKS */ -#else -#define pthread_mutex_trylock(x) (0) -#define pthread_mutex_lock(x) -#define pthread_mutex_unlock(x) -#endif - -#ifdef DIE_ON_FAULT - -#include <signal.h> - -#define die_or_return(val)\ -do { \ - raise(SIGSEGV); \ - return val; \ -} while (0) - -#else - -#define die_or_return(val)\ -do { \ - return val; \ -} while (0) - -#endif - - -typedef struct _memblock { - /* - Need to align for 64-bit arches, so for now, we'll keep - the header size to 8 bytes. - */ - uint32_t mb_size; - uint16_t mb_bucket; - uint16_t mb_state; -#ifdef DEBUG -#ifdef STACKSIZE - void *mb_pc[STACKSIZE]; -#endif -#endif - /* If PARANOID isn't defined, we use the following pointer for - more space. */ - struct _memblock *mb_next; -} memblock_t; - - -/** - mmap(2)ed memory pool. - */ -static void *_pool = NULL; - -/** - Pool size - */ -static size_t _poolsize = 0; - -/** - Free buckets - */ -static memblock_t *free_buckets[BUCKET_COUNT]; - - -#ifdef PARANOID - -/** - Allocated buckets - */ -static memblock_t *alloc_buckets[BUCKET_COUNT]; - -/* - We use the next pointer for the alloc_bucket list if we're PARANOID, as - we record the allocated block list in that mode. - */ -#define HDR_SIZE (sizeof(memblock_t)) - -#else /* ... not PARANOID */ - -/* - We use the next pointer for extra data space if we're secure. Makes the - allocator slightly more memory efficient. - */ -#define HDR_SIZE (sizeof(memblock_t) - sizeof(memblock_t *)) - -#endif /* PARANOID */ - -/* Return the user pointer for a given memblock_t structure. */ -#define pointer(block) (void *)((void *)block + HDR_SIZE) - -/* Return the memblock_t structure given a pointer */ -#define block(pointer) (memblock_t *)((void *)pointer - HDR_SIZE) - -/* Calculate and return the next memblock_t pointer in the memory pool - given a memblock_t pointer. */ -#define nextblock(pointer) \ - (memblock_t *)((void *)pointer + pointer->mb_size + HDR_SIZE) - -/* Doesn't *ensure* a block is free, but is a pretty good heuristic */ -#define is_valid_free(block) \ - (block->mb_bucket < BUCKET_COUNT && block->mb_state == ST_FREE) - -/* Doesn't *ensure* a block is allocated, but is a pretty good heuristic */ -#define is_valid_alloc(block) \ - (block->mb_bucket == NOBUCKET && block->mb_state == ST_ALLOC && \ - block->mb_size != 0) - - -/** - Find the proper bucket index, given a size - */ -static inline int -find_bucket(size_t size) -{ - int rv = 0; - size_t s = size; - - s >>= MIN_POWER; - while (s && (rv < (BUCKET_COUNT-1))) { - s >>= 1; - rv++; - } - - return rv; -} - - -#ifdef PARANOID -/** - Check for and remove a block from its free list. - */ -static inline int -remove_alloc_block(memblock_t *b) -{ - memblock_t *block, **prev; - uint16_t bucket; - - /* Could improve performance if NOBUCKET wasn't used - as an indicator of an allocated block */ - bucket = find_bucket(b->mb_size); - prev = &(alloc_buckets[bucket]); - - if (!(block = alloc_buckets[bucket])) - return 0; - - do { - if (b == block) { - *prev = b->mb_next; - b->mb_next = NULL; - return 1; - } - - prev = &(*prev)->mb_next; - block = block->mb_next; - } while (block); - - /* Couldn't find in its appropriate bucket */ - return 0; -} -#endif - - -/** - Check for and remove a block from its free list. - */ -static inline int -remove_free_block(memblock_t *b) -{ - memblock_t *block, **prev; - uint16_t bucket; - - bucket = b->mb_bucket; - prev = &(free_buckets[bucket]); - - if (!(block = free_buckets[bucket])) - return 0; - - do { - if (b == block) { - *prev = b->mb_next; - b->mb_next = NULL; - return 1; - } - - prev = &(*prev)->mb_next; - block = block->mb_next; - } while (block); - - /* Couldn't find in its appropriate bucket */ - return 0; -} - - -#ifdef PARANOID -/** - Insert a block on to the allocated bucket list - */ -static inline memblock_t * -insert_alloc_block(memblock_t *b) -{ - uint16_t bucket = find_bucket(b->mb_size); - - b->mb_bucket = NOBUCKET; - b->mb_state = ST_ALLOC; - b->mb_next = NULL; - - if (alloc_buckets[bucket] != NULL) - b->mb_next = alloc_buckets[bucket]; - - alloc_buckets[bucket] = b; - - return b; -} -#endif - - -/** - Insert a block on to the free bucket list - */ -static inline memblock_t * -insert_free_block(memblock_t *b) -{ - uint16_t bucket = find_bucket(b->mb_size); - - b->mb_bucket = bucket; - b->mb_state = ST_FREE; - b->mb_next = NULL; - - if (free_buckets[bucket] != NULL) - b->mb_next = free_buckets[bucket]; - - free_buckets[bucket] = b; - - return b; -} - - -/** - Consolidate a block with all free blocks to the right of it in the - pool. - - @param left Left block - @return Number of blocks consolidated. - */ -static inline int -consolidate(memblock_t *left) -{ - memblock_t *right; - int merged = 0; - - while (1) { - right = nextblock(left); - if ((void *)right >= (_pool + _poolsize)) - return merged; - - if (!is_valid_free(right)) { - if (is_valid_alloc(right)) - return merged; - - /* Not valid free and not valid allocated. BAD. */ - fprintf(stderr, "consolidate: Block %p corrupt. " - "(Overflow from block %p?)\n", right, left); - die_or_return(-1); - } - if (!remove_free_block(right)) - return merged; - - left->mb_size += (right->mb_size + HDR_SIZE); - right->mb_state = 0; - - ++merged; - } - /* Not reached */ - return merged; -} - - -/** - Consolidate all free blocks next to each-other in the pool in to larger - blocks. This algorithm is slow... - */ -static inline void -consolidate_all(void) -{ - memblock_t *b, *p; - int total = 0; - - p = NULL; - b = _pool; - - while ((void *)b < (void *)(_pool + _poolsize)) { - - if (is_valid_free(b)) { - if (!remove_free_block(b)) { - fprintf(stderr, "consolidate: Free block %p " - "was not in our free list.\n", b); - } - - total += consolidate(b); - insert_free_block(b); - } else if (!is_valid_alloc(b)) { - /* Not valid free and not valid allocated. BAD. */ - fprintf(stderr, "consolidate_all: Block %p corrupt. " - "(Overflow from block %p?)\n", b, p); - die_or_return(); - } - - /* Consolidated or we're a valid allocated block */ - p = b; - b = nextblock(b); - } - -#ifdef DEBUG - if (total) - fprintf(stderr, "%s: consolidated %d\n", __FUNCTION__, total); -#endif - -} - - -#ifndef NOTHREADS -/** - After a fork, we need to kill the mutex so the child can still call malloc - without getting stuck. - */ -void -malloc_zap_mutex(void) -{ - pthread_mutex_init(&_alloc_mutex, NULL); -} -#endif - - -/** - Initialize the giant mmap pool storage. - */ -#ifndef NOTHREADS -static inline int -_malloc_init(size_t poolsize) -#else -int -malloc_init(size_t poolsize) -#endif -{ - int e; - memblock_t *first = NULL; - - if (_pool) - return -1; - - if (poolsize % 32) - poolsize += (32 - (poolsize % 32)); - - _pool = mmap(NULL, poolsize, PROT_READ | PROT_WRITE, MAP_LOCKED | - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - if ((_pool == MAP_FAILED) && (errno == EAGAIN)) { - /* Try again without MAP_LOCKED */ - _pool = mmap(NULL, poolsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (_pool != MAP_FAILED) - fprintf(stderr, "malloc_init: Warning: using unlocked" - " memory pages (got root?)\n"); - } - - if (_pool == MAP_FAILED) { - return -1; - } - - _poolsize = poolsize; - - for (e = 0; e < BUCKET_COUNT; e++) - free_buckets[e] = NULL; - - first = _pool; - first->mb_size = (_poolsize - HDR_SIZE); - first->mb_state = ST_FREE; - first->mb_next = NULL; - first->mb_bucket = NOBUCKET; - -#ifdef PARANOID - for (e = 0; e < BUCKET_COUNT; e++) - alloc_buckets[e] = NULL; -#endif -#if 0 -#ifdef DEBUG - fprintf(stderr, "malloc_init: %lu/%lu available\n", - (long unsigned)first->mb_size, (long unsigned)_poolsize); -#endif -#endif - - insert_free_block(first); - return 0; -} - - -#ifndef NOTHREADS -/* Same as above, but lock first! */ -int -malloc_init(size_t poolsize) -{ - int e = 0, ret = -1; - pthread_mutex_lock(&_alloc_mutex); - if (!_pool) { - ret = _malloc_init(poolsize); - e = errno; - } - pthread_atfork(NULL, NULL, malloc_zap_mutex); - pthread_mutex_unlock(&_alloc_mutex); - errno = e; - return ret; -} -#endif - - -static inline memblock_t * -split(memblock_t *block, size_t size) -{ - memblock_t *nb; - size_t oldsz; - - oldsz = block->mb_size; - - /* Ok, we got it. */ - block->mb_size = size; - block->mb_next = NULL; - block->mb_state = ST_ALLOC; - block->mb_bucket = NOBUCKET; - - nb = nextblock(block); - nb->mb_state = ST_FREE; - nb->mb_bucket = NOBUCKET; - nb->mb_size = (size_t)(oldsz - (HDR_SIZE + size)); - insert_free_block(nb); - - /* Created a new next-block. */ - - return block; -} - - -/** - Search the freestore and return an available block which accomodates the - requested size, splitting up a free block if necessary. - */ -static inline memblock_t * -search_freestore(size_t size) -{ - uint16_t bucket; - memblock_t *block, **prev; - - for (bucket = find_bucket(size); bucket < BUCKET_COUNT; bucket++) { - block = free_buckets[bucket]; - if (!block) - continue; - - prev = &(free_buckets[bucket]); - - do { - /* - Look for block with size within 25% - */ - if (block->mb_size >= size) { - - /* - Split if size >= size + MIN_EXTRA. - - 25% of 1MB = 256kb -- which is way too much - unused space to leave hanging around when - we're tuned for small bits. - */ - if (block->mb_size >= (size + MIN_EXTRA)) { - *prev = block->mb_next; - block->mb_state = ST_ALLOC; - block->mb_bucket = NOBUCKET; - return split(block, size); - } - - /* - Otherwise, return if the size matches - within 25% - - So, the max unused bytes from a malloc - operation for a given size is 56 (since - 64 == MIN_EXTRA). So the following is - very inefficient: - - p = malloc(280); - free(p); - p = malloc(224); - */ - if (block->mb_size < (size + size / 4)) { - *prev = block->mb_next; - block->mb_state = ST_ALLOC; - block->mb_bucket = NOBUCKET; - return block; - } - } - - prev = &(*prev)->mb_next; - block = block->mb_next; - } while (block); - } - - /* Ok, nothing big enough in the free store */ - return NULL; -} - - -#ifdef DEBUG - -#define stack_pointer(n) \ - (__builtin_frame_address(n)?__builtin_return_address(n):NULL) - -#define assign_address(_ptr, _cnt) \ -{ \ - switch(_cnt) { \ - case 0: \ - (_ptr)[_cnt] = stack_pointer(0); \ - break; \ - case 1: \ - (_ptr)[_cnt] = stack_pointer(1); \ - break; \ - case 2: \ - (_ptr)[_cnt] = stack_pointer(2); \ - break; \ - case 3: \ - (_ptr)[_cnt] = stack_pointer(3); \ - break; \ - case 4: \ - (_ptr)[_cnt] = stack_pointer(4); \ - break; \ - case 5: \ - (_ptr)[_cnt] = stack_pointer(5); \ - break; \ - case 6: \ - (_ptr)[_cnt] = stack_pointer(6); \ - break; \ - case 7: \ - (_ptr)[_cnt] = stack_pointer(7); \ - break; \ - case 8: \ - raise(SIGKILL); \ - break; \ - }\ -} -#endif - - - - -/** - Memory allocation - */ -void * -malloc(size_t size) -{ -#ifndef NOROUND - size_t r; -#endif - memblock_t *block; -#ifdef DEBUG -#ifdef STACKSIZE - int sp; -#endif -#endif - - if (size < MIN_SIZE) - size = MIN_SIZE; -#ifndef NOROUND - else { - r = size % MIN_SIZE; - size += (r ? (MIN_SIZE - r) : 0); - } -#endif /* NOROUND */ - -#ifndef NOTHREADS - while (pthread_mutex_trylock(&_alloc_mutex) != 0); -#endif - if (!_pool) { -#if 0 -#ifdef DEBUG - fprintf(stderr, - "malloc: Initializing region default size %lu\n", - (long unsigned)DEFAULT_SIZE); -#endif -#endif -#ifndef NOTHREADS - if (_malloc_init(DEFAULT_SIZE) < 0) -#else - if (malloc_init(DEFAULT_SIZE) < 0) -#endif - return NULL; - } - - block = search_freestore(size); - if (block) { -#ifdef DEBUG -#ifdef STACKSIZE - for (sp = 0; sp < STACKSIZE; sp++) { - assign_address(block->mb_pc, sp); - if (!block->mb_pc[sp]) - break; - } -#endif -#endif -#ifdef PARANOID - insert_alloc_block(block); -#endif -#ifndef NOTHREADS - pthread_mutex_unlock(&_alloc_mutex); -#endif - return pointer(block); - } - -#ifdef AGGR_RECLAIM - consolidate_all(); - block = search_freestore(size); - if (block) { -#ifdef DEBUG -#ifdef STACKSIZE - for (sp = 0; sp < STACKSIZE; sp++) { - assign_address(block->mb_pc, sp); - if (!block->mb_pc[sp]) - break; - } -#endif -#endif -#ifdef PARANOID - insert_alloc_block(block); -#endif - pthread_mutex_unlock(&_alloc_mutex); - return pointer(block); - } -#endif /* AGGR_RECLAIM */ - -#ifdef DEBUG - fprintf(stderr, "Out of memory malloc(%lu) @ %p\n", - (long unsigned)size, __builtin_return_address(0)); -#endif - errno = ENOMEM; - return NULL; -} - - -/** - Memory free - */ -void -free(void *p) -{ - memblock_t *b; - - if (!p) { -#if 0 - fprintf(stderr, "free(NULL) @ %p\n", - __builtin_return_address(0)); -#endif - /* POSIX allows for free(NULL) */ - return; - } - - b = ((void *)p - HDR_SIZE); - - pthread_mutex_lock(&_alloc_mutex); - if (((void *)b < _pool) || ((void *)b >= (_pool + _poolsize))) { - fprintf(stderr, "free(%p) @ %p - Out of bounds\n", - p, __builtin_return_address(0)); - pthread_mutex_unlock(&_alloc_mutex); - die_or_return(); - } - -#ifdef PARANOID - /* Remove from the allocated list if we're tracking it. */ - if (!remove_alloc_block(b)) { - fprintf(stderr, "free(%p) @ %p - Not allocated\n", - p, __builtin_return_address(0)); - pthread_mutex_unlock(&_alloc_mutex); - die_or_return(); - } -#endif - - if (!is_valid_alloc(b)) { -#ifdef DEBUG - if (!is_valid_free(b)) - fprintf(stderr, - "free(%p) @ %p - Invalid address\n", - p, __builtin_return_address(0)); - else - fprintf(stderr, - "free(%p) @ %p - Already free\n", - p, __builtin_return_address(0)); -#endif - pthread_mutex_unlock(&_alloc_mutex); - die_or_return(); - } - - b->mb_state = ST_FREE; - b->mb_next = NULL; - -#ifdef AGGR_RECLAIM - /* Aggressively search the whole pool and combine all side-by-side - free blocks */ - insert_free_block(b); - consolidate_all(); -#else - /* Combine with all blocks to the right in the pool */ - b->mb_bucket = find_bucket(b->mb_size); - consolidate(b); - insert_free_block(b); -#endif - pthread_mutex_unlock(&_alloc_mutex); -} - - -/** - Slow realloc. It *should* resize the memory, but since we're dealing - with a static heap, it doesn't. - */ -void * -realloc(void *oldp, size_t newsize) -{ - memblock_t *oldb; -#ifdef DEBUG - memblock_t *newb; -#ifdef STACKSIZE - int sp; -#endif -#endif - void *newp; - - newp = malloc(newsize); - - if (!newp) { - return NULL; - } - - if (oldp) { - oldb = block(oldp); - memcpy(newp, oldp, (newsize > oldb->mb_size) ? - oldb->mb_size : newsize); - free(oldp); - } -#ifdef DEBUG - newb = block(newp); -#ifdef STACKSIZE - for (sp = 0; sp < STACKSIZE; sp++) { - assign_address(newb->mb_pc, sp); - if (!newb->mb_pc[sp]) - break; - } -#endif -#endif - return newp; -} - - -/** - simple calloc. - */ -void * -calloc(size_t sz, size_t nmemb) -{ - void *p; -#ifdef DEBUG - memblock_t *newb; -#ifdef STACKSIZE - int sp; -#endif -#endif - - sz *= nmemb; - p = malloc(sz); - if (!p) - return NULL; - -#ifdef DEBUG - newb = block(p); -#ifdef STACKSIZE - for (sp = 0; sp < STACKSIZE; sp++) { - assign_address(newb->mb_pc, sp); - if (!newb->mb_pc[sp]) - break; - } -#endif -#endif - memset(p, 0, sz); - return p; -} - - -void resolve_stack_gdb(void **, size_t); - - -/** - Dump the allocated memory table. Only does anything useful if PARANOID - is set. - */ -void -malloc_dump_table(size_t minsize, size_t maxsize) -{ -#ifdef PARANOID - int any = 0; - int x; -#ifdef STACKSIZE -#ifndef GDB_HOOK - int sp; -#endif -#endif - memblock_t *b; - - fflush(stdout); - pthread_mutex_lock(&_alloc_mutex); - for (x=0; x<BUCKET_COUNT; x++) { - for (b = alloc_buckets[x]; b; b = b->mb_next) { - - if (b->mb_size < minsize || b->mb_size > maxsize) - continue; - - if (!any) - fprintf(stderr, - "+++ Memory table dump +++\n"); - any++; -#ifndef DEBUG - fprintf(stderr, " %p (%lu bytes)\n", pointer(b), - (unsigned long)b->mb_size); -#else /* DEBUG */ - fprintf(stderr, - " %p (%lu bytes) allocation trace:\n", - pointer(b), (unsigned long)b->mb_size); -#ifdef STACKSIZE -#ifdef GDB_HOOK - resolve_stack_gdb(b->mb_pc, STACKSIZE); - fprintf(stderr,"\n"); -#else - for (sp = 0; sp < STACKSIZE; sp++) - fprintf(stderr,"\t%p\n",b->mb_pc[sp]); -#endif -#endif /* STACKSIZE */ -#endif /* DEBUG */ - } - } - pthread_mutex_unlock(&_alloc_mutex); - if (any) - fprintf(stderr, "--- End Memory table dump ---\n"); - -#else /* PARANOID */ - fprintf(stderr, "malloc_dump_table: Unimplemented\n"); -#endif /* PARANOID */ -} - - -/** - Print general stats about how we're doing with memory. - */ -void -malloc_stats(void) -{ - int fb = 0, ub = 0, x; - size_t metadata = 0, ucount = 0, fcount = 0, ps = 0; - memblock_t *b; - void *p; - - pthread_mutex_lock(&_alloc_mutex); - if (!_pool) { - pthread_mutex_unlock(&_alloc_mutex); - fprintf(stderr,"malloc_stats: No information\n"); - return; - } - - - for (x=0; x<BUCKET_COUNT; x++) { - for (b = free_buckets[x]; b; b = b->mb_next) { - metadata += HDR_SIZE; - fcount += b->mb_size; - ++fb; - } - } - -#ifdef PARANOID - for (x=0; x<BUCKET_COUNT; x++) { - for (b = alloc_buckets[x]; b; b = b->mb_next) { - metadata += HDR_SIZE; - ucount += b->mb_size; - ++ub; - } - } -#else - /* Estimate only... :( */ - ucount = fcount - metadata; - ub = 0; -#endif - p = _pool; - ps = _poolsize; - - pthread_mutex_unlock(&_alloc_mutex); - - fprintf(stderr, "malloc_stats:\n"); - fprintf(stderr, " Total: %lu bytes\n", (unsigned long)ps); - fprintf(stderr, " Base address: %p\n", p); - fprintf(stderr, " Free: %lu bytes in %d blocks\n", - (unsigned long)fcount, fb); -#ifdef PARANOID - fprintf(stderr, " Used: %lu bytes in %d blocks\n", - (unsigned long)ucount, ub); - fprintf(stderr, " Metadata Usage: %lu bytes\n", - (unsigned long)metadata); -#else - fprintf(stderr, - " Used: %lu bytes (debugging off, block count unknown)\n", - (unsigned long)ucount); - fprintf(stderr, - " Metadata Usage: %lu bytes (debugging off, estimate)\n", - (unsigned long)metadata); -#endif -} - - -#ifdef DEBUG -#ifdef STACKSIZE -#ifdef GDB_HOOK -void -show_gdb_address(char *buf, size_t buflen, void *address) -{ - char *line; - char *end = buf + buflen; - char foo[32]; - - snprintf(foo, sizeof(foo), "%p", address); - - line = buf; - while ((line = strchr(line, '\n'))) { - - if ((line + strlen(foo) + 1) > end) - return; - ++line; - - if (!strncmp(line, foo, strlen(foo))) { - end = strchr(line, ':'); - if (end) - *end = 0; - fprintf(stderr,"\t%s\n", line); - if (end) - *end = ':'; - return; - } - } -} - - -int -my_system(char *foo, char *outbuf, size_t buflen) -{ - char cmd[4096]; - char *args[128]; - int x = 0, y; - int pid, arg; - int p[2]; - - strncpy(cmd, foo, sizeof(cmd)); - foo = NULL; - do { - if (!x) - args[x] = strtok_r(cmd, " ", &foo); - else - args[x] = strtok_r(NULL, " ", &foo); - - } while (args[x++]); - - pipe(p); - pid = fork(); - if (!pid) { - close(STDOUT_FILENO); - dup2(p[1], STDOUT_FILENO); - execv(args[0], args); - exit(1); - } - - close(p[1]); - - y = 0; - arg = WNOHANG; - memset(outbuf, 0, buflen); - while (waitpid(pid, NULL, arg) != pid) { - - /* Interrupt after we decided to block for child */ - if (!arg) - continue; - - if (y >= buflen) { - /* Out of space. Wait for child without - the WNOHANG flag now... */ - arg = 0; - continue; - } - x = read(p[0], outbuf + y, 1); - ++y; - } - - return 0; -} - - -/* - Yes, it's slow. Painfully slow. - */ -void -resolve_stack_gdb(void **stack, size_t stacksize) -{ - int pid, fd; - char fname[1024]; - char programname[1024]; - char commandline[4096]; - char tmp[4096]; - int s; - - pid = fork(); - if (pid < 0) { - return; - } - - if (pid) { - while (waitpid(pid, &s, 0) != pid); - return; - } - - /* Child */ - - pid = getppid(); - - snprintf(fname, sizeof(fname), "/proc/%d/exe", pid); - memset(programname, 0, sizeof(programname)); - readlink(fname, programname, sizeof(programname)); - - snprintf(fname, sizeof(fname), "/tmp/alloc.gdb.XXXXXX"); - - fd = mkstemp(fname); - for (s = 0; s < stacksize; s++) { - if (!stack[s]) - break; - snprintf(tmp, sizeof(tmp), "x/i %p\n", stack[s]); - write(fd, tmp, strlen(tmp)); - } - snprintf(tmp, sizeof(tmp), "quit\n"); - write(fd, tmp, strlen(tmp)); - fsync(fd); - fdatasync(fd); - - snprintf(commandline, sizeof(commandline), - "/usr/bin/gdb %s %d -batch -x %s", - programname, pid, fname); - my_system(commandline, tmp, sizeof(tmp)); - for (s = 0; s < stacksize; s++) { - if (!stack[s]) - break; - show_gdb_address(tmp, sizeof(tmp), stack[s]); - } - - unlink(fname); - close(fd); - exit(0); -} -#endif -#endif -#endif - diff --git a/rgmanager/src/clulib/clulog.c b/rgmanager/src/clulib/clulog.c deleted file mode 100644 index dacf39b..0000000 --- a/rgmanager/src/clulib/clulog.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Library routines for communicating with the logging daemon. - * - * $Id$ - * - * Author: Jeff Moyer moyer@missioncriticallinux.com - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <malloc.h> -#include <dirent.h> -#include <signal.h> -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <ccs.h> -#define SYSLOG_NAMES -#include <sys/syslog.h> -#undef SYSLOG_NAMES - -#include <sys/wait.h> -#include <sys/types.h> -#include <linux/unistd.h> -#include <pthread.h> -#include <gettid.h> -#include <clulog.h> -#include <string.h> - - -static const char *version __attribute__ ((unused)) = "$Revision$"; - -#ifdef DEBUG -#include <assert.h> -#define Dprintf(fmt,args...) printf(fmt,##args) -#define DBG_ASSERT(x) assert(x) -#else -#define Dprintf(fmt,args...) -#define DBG_ASSERT(x) -#endif - -/* - * Globals - */ -static int log_is_open = 0; -static int useconsole = 0; -static int loglevel = LOGLEVEL_DFLT; -static int syslog_facility = LOG_DAEMON; -static char *daemon_name = NULL; -static pid_t daemon_pid = -1; - -#ifdef WRAP_LOCKS -static pthread_mutex_t log_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -#else -static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - -CODE logger_prioritynames[] = -{ {"emerg", LOG_EMERG}, - {"alert", LOG_ALERT}, - {"crit", LOG_CRIT}, - {"err", LOG_ERR}, - {"warning", LOG_WARNING}, - {"notice", LOG_NOTICE}, - {"info", LOG_INFO}, - {"debug", LOG_DEBUG} -}; - -/* - * Exported Functions. - */ - -/** - * @return The current cluster log level. - */ -int -clu_get_loglevel(void) -{ - return loglevel; -} - - -/** - * Set the cluster log level. - * - * @param severity New log level. - * @return Old log level, or -1 if 'severity' is an invalid log - * level. - */ -int -clu_set_loglevel(int severity) -{ - int ret = loglevel; - - if (severity > 0) { - loglevel = severity; - return ret; - } - - return -1; -} - - -/** - * @return The current cluster log facility. - */ -char * -clu_get_facility(void) -{ - int x = 0; - - pthread_mutex_lock(&log_mutex); - for (; facilitynames[x].c_name; x++) { - if (syslog_facility == facilitynames[x].c_val) { - pthread_mutex_unlock(&log_mutex); - return facilitynames[x].c_name; - } - } - - pthread_mutex_unlock(&log_mutex); - return "local4"; -} - - -/** - * Set the cluster log facility. - * - * @param facilityname New log facility (see /usr/include/sys/syslog.h). - * @return 0 - */ -int -clu_set_facility(char *facilityname) -{ - int x = 0, old; - - pthread_mutex_lock(&log_mutex); - old = syslog_facility; - - for (; facilitynames[x].c_name; x++) { - if (strcmp(facilityname, facilitynames[x].c_name)) - continue; - - syslog_facility = facilitynames[x].c_val; - break; - } - - if (syslog_facility == old) { - pthread_mutex_unlock(&log_mutex); - return 0; - } - - closelog(); - log_is_open = 0; - pthread_mutex_unlock(&log_mutex); - return 0; -} - - -/** - * Set the console logging mode. Does not work for daemons. - * - * @param onoff 0 = off, otherwise on. - * @return Old log-to-console state. - */ -int -clu_log_console(int onoff) -{ - int ret = useconsole; - int val; - - if (onoff) { - val = fcntl(STDERR_FILENO, F_GETFL, 0); - fcntl(STDERR_FILENO, F_SETFL, val|O_NONBLOCK); - val = fcntl(STDOUT_FILENO, F_GETFL, 0); - fcntl(STDOUT_FILENO, F_SETFL, val|O_NONBLOCK); - } - - useconsole = !!onoff; - return ret; -} - - -/** - * Cluster logging function. Talks to syslog and writes to the - * console, if necessary. - */ -int -do_clulog(int severity, - int write_to_cons, - pid_t pid, - char *prog, - const char *fmt, ...) -{ - va_list args; - char logmsg[MAX_LOGMSG_LEN]; /* message to go to the log */ - char printmsg[MAX_LOGMSG_LEN]; /* message to go to stdout */ - int syslog_flags = LOG_NDELAY; - int val; - - pthread_mutex_lock(&log_mutex); - if (severity > loglevel) { - pthread_mutex_unlock(&log_mutex); - return 0; - } - - memset(logmsg, 0, MAX_LOGMSG_LEN); - memset(printmsg, 0, MAX_LOGMSG_LEN); - - /* - * Check to see if the caller has forked. - */ - if (!pid) { - - /* Use thread IDs */ - if (daemon_pid != gettid()) { - - daemon_pid = gettid(); - log_is_open = 0; - } - - syslog_flags |= LOG_PID; - - } else { - - daemon_pid = pid; - closelog(); - log_is_open = 0; - snprintf(logmsg, MAX_LOGMSG_LEN, "[%d]: ", pid); - } - - if (prog) { - - if (daemon_name) { - - free(daemon_name); - daemon_name = NULL; - } - - daemon_name = strdup(prog); - } - - if (!log_is_open) { - - openlog(daemon_name, syslog_flags, syslog_facility); - log_is_open = 1; - } - /* - * Note: This can be called in the context of a CGI program, in which - * case anything printed to stdout goes to the web page. This can - * cause problems if we have our standard <warning> strings b/c - * the web client will try to interpret this as an html tag. - */ - snprintf(logmsg + strlen(logmsg), MAX_LOGMSG_LEN - strlen(logmsg), - "<%s> ", logger_prioritynames[severity].c_name); - - va_start(args, fmt); - vsnprintf(logmsg + strlen(logmsg), MAX_LOGMSG_LEN - strlen(logmsg), - fmt, args); - va_end(args); - - if (write_to_cons || useconsole) { - snprintf(printmsg, MAX_LOGMSG_LEN, "[%d] %s: ", daemon_pid, - logger_prioritynames[severity].c_name); - - va_start(args, fmt); - vsnprintf(printmsg + strlen(printmsg), - MAX_LOGMSG_LEN - strlen(printmsg), fmt, args); - va_end(args); - - if (useconsole && !write_to_cons) { - val = fcntl(STDOUT_FILENO, F_GETFL, 0); - fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK); - } - - /* Ignore error return code */ - write(STDOUT_FILENO, printmsg, strlen(printmsg)); - - if (useconsole && !write_to_cons) - fcntl(STDOUT_FILENO, F_SETFL, val); - } - - /* TODO make this non-blocking */ - syslog(severity, "%s", logmsg); - - pthread_mutex_unlock(&log_mutex); - - return 0; -} - - -/** - * Stop the cluster logging facility. - */ -void -clulog_close(void) -{ - closelog(); -} diff --git a/rgmanager/src/clulib/daemon_init.c b/rgmanager/src/clulib/daemon_init.c deleted file mode 100644 index b05f2cd..0000000 --- a/rgmanager/src/clulib/daemon_init.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * daemon_init function, does sanity checks and calls daemon(). - * - * $Id$ - * - * Author: Jeff Moyer moyer@mclinux.com - */ -/* - * TODO: Clean this up so that only one function constructs the - * pidfile /var/run/loggerd.PID, and perhaps only one function - * forms the /proc/PID/ path. - * - * Also need to add file locking for the pid file. - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <fcntl.h> -#include <dirent.h> -#include <sys/mman.h> -#include <sys/errno.h> -#include <libgen.h> -#include <signal.h> - -/* - * This should ultimately go in a header file. - */ -void daemon_init(char *prog); -int check_pid_valid(pid_t pid, char *prog); -int check_process_running(char *prog, pid_t * pid); - -/* - * Local prototypes. - */ -static void update_pidfile(char *prog); -static int setup_sigmask(void); - - -int -check_pid_valid(pid_t pid, char *prog) -{ - FILE *fp; - DIR *dir; - char filename[PATH_MAX]; - char dirpath[PATH_MAX]; - char proc_cmdline[64]; /* yank this from kernel somewhere */ - char *s = NULL; - - memset(filename, 0, PATH_MAX); - memset(dirpath, 0, PATH_MAX); - - snprintf(dirpath, sizeof (dirpath), "/proc/%d", pid); - if ((dir = opendir(dirpath)) == NULL) { - closedir(dir); - return 0; /* Pid has gone away. */ - } - closedir(dir); - - /* - * proc-pid directory exists. Now check to see if this - * PID corresponds to the daemon we want to start. - */ - snprintf(filename, sizeof (filename), "/proc/%d/cmdline", pid); - fp = fopen(filename, "r"); - if (fp == NULL) { - perror("check_pid_valid"); - return 0; /* Who cares.... Let's boogy on. */ - } - - if (!fgets(proc_cmdline, sizeof (proc_cmdline) - 1, fp)) { - /* - * Okay, we've seen processes keep a reference to a - * /proc/PID/stat file and not let go. Then when - * you try to read /proc/PID/cmline, you get either - * \000 or -1. In either case, we can safely assume - * the process has gone away. - */ - fclose(fp); - return 0; - } - fclose(fp); - - s = &(proc_cmdline[strlen(proc_cmdline)]); - if (*s == '\n') - *s = 0; - - /* - * Check to see if this is the same executable. - */ - if ((s = strstr(proc_cmdline, prog)) == NULL) { - return 0; - } else { - return 1; - } -} - - -int -check_process_running(char *prog, pid_t * pid) -{ - pid_t oldpid; - FILE *fp; - char filename[PATH_MAX]; - char *cmd; - int ret; - struct stat st; - - *pid = -1; - - /* - * Now see if there is a pidfile associated with this cmd in /var/run - */ - fp = NULL; - memset(filename, 0, PATH_MAX); - - cmd = basename(prog); - snprintf(filename, sizeof (filename), "/var/run/%s.pid", cmd); - - ret = stat(filename, &st); - if ((ret < 0) || (!st.st_size)) - return 0; - - /* - * Read the pid from the file. - */ - fp = fopen(filename, "r"); - if (fp == NULL) { /* error */ - return 0; - } - fscanf(fp, "%d\n", &oldpid); - fclose(fp); - if (check_pid_valid(oldpid, cmd)) { - *pid = oldpid; - return 1; - } - return 0; -} - - -static void -update_pidfile(char *prog) -{ - FILE *fp = NULL; - char *cmd; - char filename[PATH_MAX]; - - memset(filename, 0, PATH_MAX); - - cmd = basename(prog); - snprintf(filename, sizeof (filename), "/var/run/%s.pid", cmd); - - fp = fopen(filename, "w"); - if (fp == NULL) { - exit(1); - } - - fprintf(fp, "%d", getpid()); - fclose(fp); -} - - -static int -setup_sigmask(void) -{ - sigset_t set; - - sigfillset(&set); - - /* - * Dont't block signals which would cause us to dump core. - */ - sigdelset(&set, SIGQUIT); - sigdelset(&set, SIGILL); - sigdelset(&set, SIGTRAP); - sigdelset(&set, SIGABRT); - sigdelset(&set, SIGFPE); - sigdelset(&set, SIGSEGV); - sigdelset(&set, SIGBUS); - - return (sigprocmask(SIG_BLOCK, &set, NULL)); -} - - -void -daemon_init(char *prog) -{ - uid_t uid; - pid_t pid; - - uid = getuid(); - if (uid) { - fprintf(stderr, - "daemon_init: Sorry, only root wants to run this.\n"); - exit(1); - } - - if (check_process_running(prog, &pid) && (pid != getpid())) { - fprintf(stderr, - "daemon_init: Process "%s" already running.\n", - prog); - exit(1); - } - if (setup_sigmask() < 0) { - fprintf(stderr, "daemon_init: Unable to set signal mask.\n"); - exit(1); - } - - daemon(0, 0); - - update_pidfile(prog); - nice(-1); - //mlockall(MCL_CURRENT | MCL_FUTURE); -} diff --git a/rgmanager/src/clulib/gettid.c b/rgmanager/src/clulib/gettid.c deleted file mode 100644 index ba571c6..0000000 --- a/rgmanager/src/clulib/gettid.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <sys/types.h> -#include <sys/syscall.h> -#include <linux/unistd.h> -#include <gettid.h> -#include <errno.h> -#include <unistd.h> - -/* Patch from Adam Conrad / Ubuntu: Don't use _syscall macro */ - -#ifdef __NR_gettid -pid_t gettid (void) -{ - return syscall(__NR_gettid); -} -#else - -#warn "gettid not available -- substituting with pthread_self()" - -#include <pthread.h> -pid_t gettid (void) -{ - return (pid_t)pthread_self(); -} -#endif diff --git a/rgmanager/src/clulib/msgsimple.c b/rgmanager/src/clulib/msgsimple.c deleted file mode 100644 index f873715..0000000 --- a/rgmanager/src/clulib/msgsimple.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/socket.h> -#include <malloc.h> -#include <linux/limits.h> -#include <sys/time.h> -#include <sys/un.h> -#include <dirent.h> -#include <string.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <libgen.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <fcntl.h> -#include <sys/syslog.h> -#include <sys/ioctl.h> - -#include <vf.h> -#include <magmamsg.h> -#include <platform.h> - -ssize_t msg_peek(int sockfd, void *buf, ssize_t count); - -/* - * msg_send_simple - */ -int -msg_send_simple(int fd, int cmd, int arg1, int arg2) -{ - int status; - int my_errno; - generic_msg_hdr msg; - - msg.gh_magic = GENERIC_HDR_MAGIC; - msg.gh_length = sizeof (msg); - msg.gh_command = cmd; - msg.gh_arg1 = arg1; - msg.gh_arg2 = arg2; - swab_generic_msg_hdr(&msg); - - my_errno = 0; - status = msg_send(fd, (void *) &msg, sizeof (msg)); - my_errno = errno; - - if (status <= 0) - { - /* - * Should never be the case since msg_send() is - * wrapped in a retry loop. Give one more try - * calling msg_send() for a few errnos, others, return - * error as they cannot and should not be retried. - */ - if ((my_errno == EINTR) || (my_errno == EAGAIN) || - (my_errno == ENOSPC)) { - status = msg_send(fd, (void *) &msg, sizeof (msg)); - } - } - - return (status); -} - - -/* - * receive_message - * - * Read a message and the corresponding buffer off of the file descriptor - * indicated by fd. This allocates **buf; so the user must free it when - * [s]he is done with it. Also returns the length of the full buffer in - * *buf_size. - * - * Returns 0 on success or -1 on failure. - */ -int -msg_receive_simple(int fd, generic_msg_hdr ** buf, int timeout) -{ - int ret; - generic_msg_hdr peek_msg; - - /* - * Peek at the header. We need the size of the inbound buffer! - */ - errno = EAGAIN; - ret = msg_peek(fd, &peek_msg, sizeof (generic_msg_hdr)); - if (ret != sizeof (generic_msg_hdr)) { - if (ret == -1) { - if (errno != ECONNRESET) - fprintf(stderr, "fd%d peek: %s\n", fd, - strerror(errno)); - //perror("msg_peek"); - } else if (ret != 0) /* Blank message = probably closed socket */ - fprintf(stderr, "fd%d peek: %d/%d bytes\n", fd, - ret, (int)sizeof (generic_msg_hdr)); - else if (ret == 0) - errno = ECONNRESET; - return -1; - } - - swab_generic_msg_hdr(&peek_msg); - if (peek_msg.gh_magic != GENERIC_HDR_MAGIC) { - fprintf(stderr, "Invalid magic: Wanted 0x%08x, got 0x%08x\n", - GENERIC_HDR_MAGIC, peek_msg.gh_magic); - return -1; - } - - /* - * allocate enough memory to receive the header + diff buffer - */ - *buf = malloc(peek_msg.gh_length); - - if (!*buf) { - fprintf(stderr, "%s: malloc: %s", __FUNCTION__, - strerror(errno)); - return -1; - } - - memset(*buf, 0, peek_msg.gh_length); - - /* - * Now, do the real receive. 2 second timeout, if none specified. - */ - ret = msg_receive_timeout(fd, (void *) (*buf), peek_msg.gh_length, - timeout ? timeout : 2); - - if (ret == -1) { - fprintf(stderr, "msg_receive_timeout: %s\n", strerror(errno)); - free(*buf); - *buf = NULL; - return -1; - } - - if (ret != peek_msg.gh_length) { - fprintf(stderr, "short read: %d/%d\n", ret, peek_msg.gh_length); - free(*buf); - *buf = NULL; - return -1; - } - - return ret; -} diff --git a/rgmanager/src/clulib/rg_strings.c b/rgmanager/src/clulib/rg_strings.c deleted file mode 100644 index 5d561b7..0000000 --- a/rgmanager/src/clulib/rg_strings.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004-2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <res-ocf.h> -#include <resgroup.h> - -struct string_val { - int val; - char *str; -}; - - -const struct string_val rg_error_strings[] = { - { RG_EEXCL, "Service not runnable: cannot run exclusive" }, - { RG_EDOMAIN, "Service not runnable: restricted failover domain offline" }, - { RG_ESCRIPT, "S/Lang Script Error" }, - { RG_EFENCE, "Fencing operation pending; try again later" }, - { RG_ENODE, "Target node dead / nonexistent" }, - { RG_ERUN, "Service is already running" }, - { RG_EQUORUM, "Operation requires quorum" }, - { RG_EINVAL, "Invalid operation for resource" }, - { RG_EDEPEND, "Operation violates dependency rule" }, - { RG_EAGAIN, "Temporary failure; try again" }, - { RG_EDEADLCK, "Operation would cause a deadlock" }, - { RG_ENOSERVICE,"Service does not exist" }, - { RG_EFORWARD, "Service not mastered locally" }, - { RG_EABORT, "Aborted; service failed" }, - { RG_EFAIL, "Failure" }, - { RG_ESUCCESS, "Success" }, - { RG_YES, "Yes" }, - { RG_NO, "No" }, - { 0, NULL } -}; - - -const struct string_val rg_req_strings[] = { - {RG_SUCCESS, "success" }, - {RG_FAIL, "fail"}, - {RG_START, "start"}, - {RG_STOP, "stop"}, - {RG_STATUS, "status"}, - {RG_DISABLE, "disable"}, - {RG_STOP_RECOVER, "stop (recovery)"}, - {RG_START_RECOVER, "start (recovery)"}, - {RG_RESTART, "restart"}, - {RG_EXITING, "exiting"}, - {RG_INIT, "initialize"}, - {RG_ENABLE, "enable"}, - {RG_STATUS_NODE, "status inquiry"}, - {RG_RELOCATE, "relocate"}, - {RG_CONDSTOP, "conditional stop"}, - {RG_CONDSTART, "conditional start"}, - {RG_START_REMOTE,"remote start"}, - {RG_STOP_USER, "user stop"}, - {RG_STOP_EXITING, "stop (shutdown)"}, - {RG_LOCK, "locking"}, - {RG_UNLOCK, "unlocking"}, - {RG_QUERY_LOCK, "lock status inquiry"}, - //{RG_MIGRATE, "migrate"}, - //{RG_STATUS_INQUIRY, "out of band service status inquiry"}, - {RG_NONE, "none"}, - {0, NULL} -}; - - -const struct string_val rg_state_strings[] = { - {RG_STATE_STOPPED, "stopped"}, - {RG_STATE_STARTING, "starting"}, - {RG_STATE_STARTED, "started"}, - {RG_STATE_STOPPING, "stopping"}, - {RG_STATE_FAILED, "failed"}, - {RG_STATE_UNINITIALIZED, "uninitialized"}, - {RG_STATE_CHECK, "checking"}, - {RG_STATE_ERROR, "recoverable"}, - {RG_STATE_RECOVER, "recovering"}, - {RG_STATE_DISABLED, "disabled"}, - //{RG_STATE_MIGRATE, "migrating"}, - {0, NULL} -}; - - -const struct string_val agent_ops[] = { - {RS_START, "start"}, - {RS_STOP, "stop"}, - {RS_STATUS, "status"}, - {RS_RESINFO, "resinfo"}, - {RS_RESTART, "restart"}, - {RS_RELOAD, "reload"}, - {RS_CONDRESTART, "condrestart"}, /* Unused */ - {RS_RECOVER, "recover"}, - {RS_CONDSTART, "condstart"}, - {RS_CONDSTOP, "condstop"}, - {RS_MONITOR, "monitor"}, - {RS_META_DATA, "meta-data"}, /* printenv */ - {RS_VALIDATE, "validate-all"}, - //{RS_MIGRATE, "migrate"}, - {RS_RECONFIG, "reconfig"}, - {0 , NULL} -}; - - -static inline const char * -rg_search_table(const struct string_val *table, int val) -{ - int x; - - for (x = 0; table[x].str != NULL; x++) { - if (table[x].val == val) { - return table[x].str; - } - } - - return "Unknown"; -} - - -static inline int -rg_search_table_by_str(const struct string_val *table, const char *val) -{ - int x; - - for (x = 0; table[x].str != NULL; x++) { - if (!strcasecmp(table[x].str, val)) - return table[x].val; - } - - return -1; -} - - - -const char * -rg_strerror(int val) -{ - return rg_search_table(rg_error_strings, val); -} - -const char * -rg_state_str(int val) -{ - return rg_search_table(rg_state_strings, val); -} - - -int -rg_state_str_to_id(const char *val) -{ - return rg_search_table_by_str(rg_state_strings, val); -} - - - -const char * -rg_req_str(int val) -{ - return rg_search_table(rg_req_strings, val); -} - - -const char * -agent_op_str(int val) -{ - return rg_search_table(agent_ops, val); -} diff --git a/rgmanager/src/clulib/sets.c b/rgmanager/src/clulib/sets.c deleted file mode 100644 index f734064..0000000 --- a/rgmanager/src/clulib/sets.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** - @file sets.c - Order-preserving set functions (union / intersection / delta) - (designed for integer types; a la int, uint64_t, etc...) - @author Lon Hohberger <lhh at redhat.com> - */ -#include <stdio.h> -#include <malloc.h> -#include <string.h> -#include <stdlib.h> -#include <sets.h> -#include <sys/time.h> - - -/** - Add a value to a set. This function disregards an add if the value is already - in the set. Note that the maximum length of set s must be preallocated; this - function doesn't do error or bounds checking. - - @param s Set to modify - @param curlen Current length (modified if added) - @param val Value to add - @return 0 if not added, 1 if added - */ -int -s_add(set_type_t *s, int *curlen, set_type_t val) -{ - int idx=0; - - for (; idx < *curlen; idx++) - if (s[idx] == val) - return 0; - s[*curlen] = val; - ++(*curlen); - return 1; -} - - -/** - Union-set function. Allocates and returns a new set which is the union of - the two given sets 'left' and 'right'. Also returns the new set length. - - @param left Left set - order is preserved on this set; that is, - this is the set where the caller cares about ordering. - @param ll Length of left set. - @param right Right set - order is not preserved on this set during - the union operation - @param rl Length of right set - @param ret Return set. Should * not * be preallocated. - @param retl Return set length. Should be ready to accept 1 integer - upon calling this function - @return 0 on success, -1 on error - */ -int -s_union(set_type_t *left, int ll, set_type_t *right, int rl, - set_type_t **ret, int *retl) -{ - int l, r, cnt = 0, total; - - total = ll + rl; /* Union will never exceed both sets */ - - *ret = malloc(sizeof(set_type_t)*total); - if (!*ret) { - return -1; - } - memset((void *)(*ret), 0, sizeof(set_type_t)*total); - - cnt = 0; - - /* Add all the ones on the left */ - for (l = 0; l < ll; l++) - s_add(*ret, &cnt, left[l]); - - /* Add the ones on the left */ - for (r = 0; r < rl; r++) - s_add(*ret, &cnt, right[r]); - - *retl = cnt; - - return 0; -} - - -/** - Intersection-set function. Allocates and returns a new set which is the - intersection of the two given sets 'left' and 'right'. Also returns the new - set length. - - @param left Left set - order is preserved on this set; that is, - this is the set where the caller cares about ordering. - @param ll Length of left set. - @param right Right set - order is not preserved on this set during - the union operation - @param rl Length of right set - @param ret Return set. Should * not * be preallocated. - @param retl Return set length. Should be ready to accept 1 integer - upon calling this function - @return 0 on success, -1 on error - */ -int -s_intersection(set_type_t *left, int ll, set_type_t *right, int rl, - set_type_t **ret, int *retl) -{ - int l, r, cnt = 0, total; - - total = ll; /* Intersection will never exceed one of the two set - sizes */ - - *ret = malloc(sizeof(set_type_t)*total); - if (!*ret) { - return -1; - } - memset((void *)(*ret), 0, sizeof(set_type_t)*total); - - cnt = 0; - /* Find duplicates */ - for (l = 0; l < ll; l++) { - for (r = 0; r < rl; r++) { - if (left[l] != right[r]) - continue; - if (s_add(*ret, &cnt, right[r])) - break; - } - } - - *retl = cnt; - return 0; -} - - -/** - Delta-set function. Allocates and returns a new set which is the delta (i.e. - numbers not in both sets) of the two given sets 'left' and 'right'. Also - returns the new set length. - - @param left Left set - order is preserved on this set; that is, - this is the set where the caller cares about ordering. - @param ll Length of left set. - @param right Right set - order is not preserved on this set during - the union operation - @param rl Length of right set - @param ret Return set. Should * not * be preallocated. - @param retl Return set length. Should be ready to accept 1 integer - upon calling this function - @return 0 on success, -1 on error - */ -int -s_delta(set_type_t *left, int ll, set_type_t *right, int rl, - set_type_t **ret, int *retl) -{ - int l, r, cnt = 0, total, found; - - total = ll + rl; /* Union will never exceed both sets */ - - *ret = malloc(sizeof(set_type_t)*total); - if (!*ret) { - return -1; - } - memset((void *)(*ret), 0, sizeof(set_type_t)*total); - - cnt = 0; - - /* not efficient, but it works */ - /* Add all the ones on the left */ - for (l = 0; l < ll; l++) { - found = 0; - for (r = 0; r < rl; r++) { - if (right[r] == left[l]) { - found = 1; - break; - } - } - - if (found) - continue; - s_add(*ret, &cnt, left[l]); - } - - - /* Add all the ones on the right*/ - for (r = 0; r < rl; r++) { - found = 0; - for (l = 0; l < ll; l++) { - if (right[r] == left[l]) { - found = 1; - break; - } - } - - if (found) - continue; - s_add(*ret, &cnt, right[r]); - } - - *retl = cnt; - - return 0; -} - - -/** - Subtract-set function. Allocates and returns a new set which is the - subtraction of the right set from the left set. - Also returns the new set length. - - @param left Left set - order is preserved on this set; that is, - this is the set where the caller cares about ordering. - @param ll Length of left set. - @param right Right set - order is not preserved on this set during - the union operation - @param rl Length of right set - @param ret Return set. Should * not * be preallocated. - @param retl Return set length. Should be ready to accept 1 integer - upon calling this function - @return 0 on success, -1 on error - */ -int -s_subtract(set_type_t *left, int ll, set_type_t *right, int rl, - set_type_t **ret, int *retl) -{ - int l, r, cnt = 0, total, found; - - total = ll; /* Union will never exceed left set length*/ - - *ret = malloc(sizeof(set_type_t)*total); - if (!*ret) { - return -1; - } - memset((void *)(*ret), 0, sizeof(set_type_t)*total); - - cnt = 0; - - /* not efficient, but it works */ - for (l = 0; l < ll; l++) { - found = 0; - for (r = 0; r < rl; r++) { - if (right[r] == left[l]) { - found = 1; - break; - } - } - - if (found) - continue; - s_add(*ret, &cnt, left[l]); - } - - *retl = cnt; - - return 0; -} - - -/** - Shuffle-set function. Weakly randomizes ordering of a set in-place. - - @param set Set to randomize - @param sl Length of set - @return 0 - */ -int -s_shuffle(set_type_t *set, int sl) -{ - int x, newidx; - unsigned r_state = 0; - set_type_t t; - struct timeval tv; - - gettimeofday(&tv, NULL); - r_state = (int)(tv.tv_usec); - - for (x = 0; x < sl; x++) { - newidx = (rand_r(&r_state) % sl); - if (newidx == x) - continue; - t = set[x]; - set[x] = set[newidx]; - set[newidx] = t; - } - - return 0; -} - - -#ifdef STANDALONE -/* Testbed */ -/* - gcc -o sets sets.c -DSTANDALONE -ggdb -I../../include \ - -Wall -Werror -Wstrict-prototypes -Wextra - */ -int -main(int __attribute__ ((unused)) argc, char __attribute__ ((unused)) **argv) -{ - set_type_t a[] = { 1, 2, 3, 3, 3, 2, 2, 3 }; - set_type_t b[] = { 2, 3, 4 }; - set_type_t *i; - int ilen = 0, x; - - s_union(a, 8, b, 3, &i, &ilen); - - /* Should return length of 4 - { 1 2 3 4 } */ - printf("set_union [%d] = ", ilen); - for ( x = 0; x < ilen; x++) { - printf("%d ", (int)i[x]); - } - printf("\n"); - - s_shuffle(i, ilen); - printf("shuffled [%d] = ", ilen); - for ( x = 0; x < ilen; x++) { - printf("%d ", (int)i[x]); - } - printf("\n"); - - - free(i); - - /* Should return length of 2 - { 2 3 } */ - s_intersection(a, 8, b, 3, &i, &ilen); - - printf("set_intersection [%d] = ", ilen); - for ( x = 0; x < ilen; x++) { - printf("%d ", (int)i[x]); - } - printf("\n"); - - free(i); - - /* Should return length of 2 - { 1 4 } */ - s_delta(a, 8, b, 3, &i, &ilen); - - printf("set_delta [%d] = ", ilen); - for ( x = 0; x < ilen; x++) { - printf("%d ", (int)i[x]); - } - printf("\n"); - - free(i); - - /* Should return length of 1 - { 1 } */ - s_subtract(a, 8, b, 3, &i, &ilen); - - printf("set_subtract [%d] = ", ilen); - for ( x = 0; x < ilen; x++) { - printf("%d ", (int)i[x]); - } - printf("\n"); - - free(i); - - - return 0; -} -#endif diff --git a/rgmanager/src/clulib/signals.c b/rgmanager/src/clulib/signals.c deleted file mode 100644 index fa9f4a6..0000000 --- a/rgmanager/src/clulib/signals.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright Red Hat, Inc. 2003-2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <resgroup.h> - -void * -setup_signal(int sig, void (*handler)(int)) -{ - struct sigaction act; - struct sigaction oldact; - - memset(&act, 0, sizeof(act)); - act.sa_handler = handler; - - unblock_signal(sig); - if (sigaction(sig, &act, &oldact) == 0) { - return oldact.sa_handler; - } - - return NULL; -} - - -/** - * Block the given signal. - * - * @param sig Signal to block. - * @return See man sigprocmask. - */ -int -block_signal(int sig) -{ - sigset_t set; - - sigemptyset(&set); - sigaddset(&set, sig); - - return(sigprocmask(SIG_BLOCK, &set, NULL)); -} - - -/** - * Block the given signal. - * - * @param sig Signal to block. - * @return See man sigprocmask. - */ -int -unblock_signal(int sig) -{ - sigset_t set; - - sigemptyset(&set); - sigaddset(&set, sig); - - return(sigprocmask(SIG_UNBLOCK, &set, NULL)); -} - - -int -block_all_signals(void) -{ - sigset_t set; - - sigfillset(&set); - sigdelset(&set, SIGSEGV); - return(sigprocmask(SIG_BLOCK, &set, NULL)); -} diff --git a/rgmanager/src/clulib/tmgr.c b/rgmanager/src/clulib/tmgr.c deleted file mode 100644 index 2565f26..0000000 --- a/rgmanager/src/clulib/tmgr.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - Copyright Crosswalk 2006-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifdef WRAP_THREADS -#include <stdio.h> -#include <sys/types.h> -#include <gettid.h> -#include <pthread.h> -#include <string.h> -#include <errno.h> -#include <malloc.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <pthread.h> -#include <list.h> -#include <execinfo.h> - -typedef struct _thr { - list_head(); - void *(*fn)(void *arg); - char **name; - pthread_t th; -} mthread_t; - -static mthread_t *_tlist = NULL; -static int _tcount = 0; -static pthread_rwlock_t _tlock = PTHREAD_RWLOCK_INITIALIZER; - -void -dump_thread_states(FILE *fp) -{ - int x; - mthread_t *curr; - fprintf(fp, "Thread Information\n"); - pthread_rwlock_rdlock(&_tlock); - list_for(&_tlist, curr, x) { - fprintf(fp, " Thread #%d id: %d function: %s\n", - x, (unsigned)curr->th, curr->name[0]); - } - pthread_rwlock_unlock(&_tlock); - fprintf(fp, "\n\n"); -} - - -int __real_pthread_create(pthread_t *, const pthread_attr_t *, - void *(*)(void*), void *); -int -__wrap_pthread_create(pthread_t *th, const pthread_attr_t *attr, - void *(*start_routine)(void*), - void *arg) -{ - void *fn = start_routine; - mthread_t *new; - int ret; - - new = malloc(sizeof (*new)); - - ret = __real_pthread_create(th, attr, start_routine, arg); - if (ret) { - if (new) - free(new); - return ret; - } - - if (new) { - new->th = *th; - new->fn = start_routine; - new->name = backtrace_symbols(&fn, 1); - pthread_rwlock_wrlock(&_tlock); - list_insert(&_tlist, new); - ++_tcount; - pthread_rwlock_unlock(&_tlock); - } - - return ret; -} - - -void __real_pthread_exit(void *); -void -__wrap_pthread_exit(void *exitval) -{ - mthread_t *old; - int ret = 0, found = 0; - pthread_t me = pthread_self(); - - pthread_rwlock_rdlock(&_tlock); - list_for(&_tlist, old, ret) { - if (old->th == me) { - found = 1; - break; - } - } - if (!found) - old = NULL; - pthread_rwlock_unlock(&_tlock); - - if (!old) - __real_pthread_exit(exitval); - - pthread_rwlock_wrlock(&_tlock); - list_remove(&_tlist, old); - --_tcount; - pthread_rwlock_unlock(&_tlock); - - if (old->name) - free(old->name); - free(old); - __real_pthread_exit(exitval); -} -#endif diff --git a/rgmanager/src/clulib/vft.c b/rgmanager/src/clulib/vft.c deleted file mode 100644 index fea3a2c..0000000 --- a/rgmanager/src/clulib/vft.c +++ /dev/null @@ -1,1953 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -//#define DEBUG -/** @file - * View-Formation Thread Library - * - * Similar to a two-phase commit. This code is not especially optimal - * for the kind of work it's doing in rgmanager (e.g. distributing - * resource group state). It's probably better to use a client/server - * model like NFS and have clients restate their resource group states - * after a server failure. - */ -#include <magma.h> -#include <magmamsg.h> -#include <platform.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/resource.h> -#include <sys/wait.h> -#include <stdlib.h> -#include <sys/time.h> -#include <pthread.h> -#include <vf.h> -#include <unistd.h> -#include <stdio.h> -#include <assert.h> -#include <signals.h> - - -static int vf_lfds[2]; -static int vf_lfd = 0; -static key_node_t *key_list = NULL; /** List of key nodes. */ -static uint64_t _node_id = (uint64_t)-1;/** Our node ID, set with vf_init. */ -static uint16_t _port = 0; /** Our daemon ID, set with vf_init. */ - -/* - * TODO: We could make it thread safe, but this might be unnecessary work - * Solution: Super-coarse-grained-bad-code-locking! - */ -#ifdef WRAP_LOCKS -static pthread_mutex_t key_list_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -static pthread_mutex_t vf_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -#else -static pthread_mutex_t key_list_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t vf_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif /* WRAP_LOCKS */ -static pthread_t vf_thread = (pthread_t)-1; -static int thread_ready = 0; -static vf_vote_cb_t default_vote_cb = NULL; -static vf_vote_cb_t default_commit_cb = NULL; - - -/* - * Internal Functions - */ -static int send_to_all(int *peer_fds, int32_t command, int arg1, int arg2, - int log_errors); -static int vf_send_abort(int *fds); -static int vf_send_commit(int *fds); -static void close_all(int *fds); -static key_node_t * kn_find_key(char *keyid); -static key_node_t * kn_find_fd(uint32_t fd); -static int vf_handle_join_view_msg(int fd, vf_msg_t * hdrp); -static int vf_resolve_views(key_node_t *key_node); -static int vf_unanimous(int *peer_fds, int remain, int timeout); -static view_node_t * vn_new(int fd, uint32_t nodeid, uint64_t viewno, - void *data, uint32_t datalen); -static int vf_request_current(cluster_member_list_t *membership, char *keyid, - uint64_t *viewno, void **data, uint32_t *datalen); -static int _vf_purge(key_node_t *key_node, int *fd); - -/* Join-view buffer list functions */ -static int vn_cmp(view_node_t *left, view_node_t *right); -static int vn_insert_sorted(view_node_t **head, view_node_t *node); -static view_node_t * vn_remove(view_node_t **head, int fd); -static int vf_buffer_join_msg(int fd, vf_msg_t *hdr, - struct timeval *timeout); - -/* Commits buffer list functions */ -static int vc_cmp(commit_node_t *left, commit_node_t *right); -static int vc_insert_sorted(commit_node_t **head, commit_node_t *node); -static commit_node_t * vc_remove(commit_node_t **head, int fd); -static int vf_buffer_commit(int fd); - -/* Simple functions which client calls to vote/abort */ -static int vf_vote_yes(int fd); -static int vf_vote_no(int fd); -static int vf_abort(int fd); -static int tv_cmp(struct timeval *left, struct timeval *right); - -/* Resolution */ -static int vf_try_commit(key_node_t *key_node); - -int vf_init(uint64_t my_node_id, uint16_t my_port, - vf_vote_cb_t vote_cb, vf_commit_cb_t commit_cb); -int vf_key_init(char *keyid, int timeout, vf_vote_cb_t vote_cb, - vf_commit_cb_t commit_cb); -static int vf_key_init_nt(char *keyid, int timeout, vf_vote_cb_t vote_cb, - vf_commit_cb_t commit_cb); -int vf_write(cluster_member_list_t *memberhip, uint32_t flags, - char *keyid, void *data, uint32_t datalen); -int vf_process_msg(int handle, generic_msg_hdr *msgp, int nbytes); -int vf_end(char *keyid); -int vf_read(cluster_member_list_t *membership, char *keyid, uint64_t *view, - void **data, uint32_t *datalen); - -/* Reply to request for current data */ -static int vf_send_current(int fd, char *); - - -struct vf_args { - uint16_t port; - uint64_t local_node_id; -}; - - -static int -send_to_all(int *peer_fds, int32_t command, int arg1, int arg2, int log_errors) -{ - generic_msg_hdr hdr; - int x, rv = 0; - - hdr.gh_magic = GENERIC_HDR_MAGIC; - hdr.gh_length = sizeof(hdr); - hdr.gh_command = command; - hdr.gh_arg1 = arg1; - hdr.gh_arg2 = arg2; - - swab_generic_msg_hdr(&hdr); - - for (x=0; peer_fds[x] != -1; x++) { - if (msg_send(peer_fds[x], &hdr, sizeof(hdr)) == sizeof(hdr)) - continue; - - if (log_errors) { -#if 0 - clulog(LOG_ERR, "#14: Failed to send %d " - "bytes to %d!\n", sizeof(hdr), - x); -#endif - } - rv = -1; - } - - return rv; -} - - -static int -vf_send_abort(int *fds) -{ -#ifdef DEBUG - printf("VF: Broadcasting ABORT\n"); -#endif - return send_to_all(fds, VF_MESSAGE, VF_ABORT, 0, 0); -} - - -static int -vf_send_commit(int *fds) -{ -#ifdef DEBUG - printf("VF: Broadcasting FORMED\n"); -#endif - return send_to_all(fds, VF_MESSAGE, VF_VIEW_FORMED, 0, 1); -} - - -static void -close_all(int *fds) -{ - int x; - - if (!fds) - return; - for (x = 0; fds[x] != -1; x++) { - msg_close(fds[x]); - } -} - - -static key_node_t * -kn_find_key(char *keyid) -{ - key_node_t *cur; - - for (cur = key_list; cur; cur = cur->kn_next) - if (!strcmp(cur->kn_keyid,keyid)) - return cur; - - return NULL; -} - - -static key_node_t * -kn_find_fd(uint32_t fd) -{ - key_node_t *cur; - view_node_t *curvn; - - for (cur = key_list; cur; cur = cur->kn_next) - for (curvn = cur->kn_jvlist; curvn; curvn = curvn->vn_next) - if (curvn->vn_fd == fd) - return cur; - - return NULL; -} - - -static int -vf_handle_join_view_msg(int fd, vf_msg_t * hdrp) -{ - struct timeval timeout; - key_node_t *key_node; - -#ifdef DEBUG - printf("VF_JOIN_VIEW from member #%d! Key: %s #%d\n", - hdrp->vm_msg.vf_coordinator, hdrp->vm_msg.vf_keyid, - (int) hdrp->vm_msg.vf_view); -#endif - - pthread_mutex_lock(&key_list_mutex); - key_node = kn_find_key(hdrp->vm_msg.vf_keyid); - - /* - * Call the voting callback function to see if we should continue. - */ - if (!key_node) { - if ((vf_key_init_nt(hdrp->vm_msg.vf_keyid, - VF_COMMIT_TIMEOUT_MIN, NULL, - NULL) < 0)) { - pthread_mutex_unlock(&key_list_mutex); - printf("VF: Error: Failed to initialize %s\n", - hdrp->vm_msg.vf_keyid); - vf_vote_no(fd); - return VFR_ERROR; - } - - key_node = kn_find_key(hdrp->vm_msg.vf_keyid); - assert(key_node); - } - - if (key_node->kn_vote_cb) { - if ((key_node->kn_vote_cb)(hdrp->vm_msg.vf_keyid, - hdrp->vm_msg.vf_view, - hdrp->vm_msg.vf_data, - hdrp->vm_msg.vf_datalen) == 0) { - pthread_mutex_unlock(&key_list_mutex); -#ifdef DEBUG - printf("VF: Voting NO (via callback)\n"); -#endif - vf_vote_no(fd); - return VFR_OK; - } - } - - /* - * Buffer the join-view message. - */ - timeout.tv_sec = key_node->kn_tsec; - timeout.tv_usec = 0; - - if (vf_buffer_join_msg(fd, (vf_msg_t *) hdrp, &timeout)) { - pthread_mutex_unlock(&key_list_mutex); -#ifdef DEBUG - printf("VF: Voting YES\n"); -#endif - vf_vote_yes(fd); - return VFR_OK; - } - - pthread_mutex_unlock(&key_list_mutex); -#ifdef DEBUG - printf("VF: Voting NO\n"); -#endif - vf_vote_no(fd); - return VFR_NO; -} - - -/* - * Try to resolve (JOIN_VIEW, FORMED_VIEW) messages in the proper order. - * Returns the number of commits. - */ -static int -vf_resolve_views(key_node_t *key_node) -{ - int commitfd, commits = 0; - void *data; - uint32_t datalen; - - while ((commitfd = vf_try_commit(key_node)) != -1) { - - /* XXX in general, this shouldn't kill the fd... */ - commits++; - msg_close(commitfd); - } - - if (key_node->kn_commit_cb) { - data = malloc(key_node->kn_datalen); - if (!data) { - /* XXX */ - return commits; - } - - datalen = key_node->kn_datalen; - memcpy(data, key_node->kn_data, datalen); - - (key_node->kn_commit_cb)(key_node->kn_keyid, - key_node->kn_viewno, - data, - datalen); - } - - return commits; -} - - -static int -vf_unanimous(int *peer_fds, int remain, int timeout) -{ - generic_msg_hdr response; - struct timeval tv; - fd_set rfds; - int nready, x; - int myerrno = 0; - - /* Set up for the select */ - tv.tv_sec = timeout; - tv.tv_usec = 0; - - /* - * Wait for activity - */ - - /* - * Flag hosts which we received messages from so we don't - * read a second message. - */ - while (remain) { - FD_ZERO(&rfds); - for (x = 0; peer_fds[x] != -1; x++) - FD_SET(peer_fds[x], &rfds); - - nready = select(MAX_FDS, &rfds, NULL, NULL, &tv); - - /* - * fix, rhat erroneous check of nready==0 and - * not retrying on EINTR. - */ - if (nready < 0) - { - myerrno = errno; - fprintf(stderr, "VF Abort: %s\n", strerror(myerrno)); - - if (myerrno == EINTR) { - tv.tv_sec = timeout; - tv.tv_usec = 0; - continue; - } - - errno = myerrno; - return 0; - } - - if (nready == 0) { - fprintf(stderr, - "VF Abort: Timed out!\n"); - - return 0; - } - - for (x = 0; (peer_fds[x] != -1) && nready; x++) { - if (!FD_ISSET(peer_fds[x], &rfds)) - continue; - - remain--; - nready--; - /* - * Get reply from node x. XXX 1 second timeout? - */ - if (msg_receive_timeout(peer_fds[x], &response, - sizeof(response), - 1) == -1) { - printf("VF: Abort: Timed out during " - "receive from fd #%d\n", peer_fds[x]); - return 0; - } - - /* - * Decode & validate message - */ - swab_generic_msg_hdr(&response); - if ((response.gh_magic != GENERIC_HDR_MAGIC) || - (response.gh_command != VF_MESSAGE) || - (response.gh_arg1 != VF_VOTE)) { - printf("VF: Abort: Invalid header in" - " reply from fd #%d\n", peer_fds[x]); - return 0; - } - - /* - * If we get a 'NO', we are done. - */ - if (response.gh_arg2 != 1) { - /* - * XXX ok, it might be a mangled message; - * treat it as no anyway! - */ - printf("VF: Abort: fd #%d voted NO\n", - peer_fds[x]); - return 0; - } - -#ifdef DEBUG - printf("VF: fd #%d voted YES\n", peer_fds[x]); -#endif - } - } - - /* - * Whohoooooooo! - */ - return 1; -} - - -/* - * ... - */ -static view_node_t * -vn_new(int fd, uint32_t nodeid, uint64_t viewno, void *data, uint32_t datalen) -{ - view_node_t *new; - size_t totallen; - - totallen = sizeof(*new) + datalen; - new = malloc(totallen); - if (!new) - return NULL; - - memset(new,0,totallen); - - new->vn_fd = fd; - new->vn_nodeid = nodeid; - new->vn_viewno = viewno; - new->vn_datalen = datalen; - memcpy(new->vn_data, data, datalen); - - return new; -} - - -static int -vn_cmp(view_node_t *left, view_node_t *right) -{ - if ((left->vn_viewno < right->vn_viewno) || - ((left->vn_viewno == right->vn_viewno) && - (left->vn_nodeid < right->vn_nodeid))) - return -1; - - /* Equal? ERROR!!! */ - if ((left->vn_viewno == right->vn_viewno) && - (left->vn_nodeid == right->vn_nodeid)) - return 0; - - return 1; -} - - -static int -vn_insert_sorted(view_node_t **head, view_node_t *node) -{ - view_node_t *cur = *head, *back = NULL; - - /* only entry */ - if (!cur) { - *head = node; - return 1; - } - - while (cur) { - switch (vn_cmp(node, cur)) { - case 0: - /* duplicate */ - return 0; - case -1: - if (back) { - /* middle */ - node->vn_next = cur; - back->vn_next = node; - return 1; - } - - node->vn_next = *head; - *head = node; - return 1; - } - - back = cur; - cur = cur->vn_next; - } - - /* end */ - back->vn_next = node; - node->vn_next = NULL; - - return 1; -} - - -static view_node_t * -vn_remove(view_node_t **head, int fd) -{ - view_node_t *cur = *head, *back = NULL; - - if (!cur) - return NULL; - - do { - if (cur->vn_fd == fd) { - if (back) { - back->vn_next = cur->vn_next; - cur->vn_next = NULL; - return cur; - } - - *head = cur->vn_next; - cur->vn_next = NULL; - return cur; - } - - back = cur; - cur = cur->vn_next; - } while (cur); - - return NULL; -} - - -/* - * Buffer a join-view message. We attempt to resolve the buffered join-view - * messages whenever: - * (a) we receive a commit message - * (b) we don't receive any messages. - */ -static int -vf_buffer_join_msg(int fd, vf_msg_t *hdr, struct timeval *timeout) -{ - key_node_t *key_node; - view_node_t *newp; - int rv = 0; - - key_node = kn_find_key(hdr->vm_msg.vf_keyid); - if (!key_node) { - printf("Key %s not initialized\n", - hdr->vm_msg.vf_keyid); - return 0; - } - - /* - * Store if the view < viewno. - */ - if (hdr->vm_msg.vf_view < key_node->kn_viewno) { - return 0; - } - - newp = vn_new(fd, hdr->vm_msg.vf_coordinator, hdr->vm_msg.vf_view, - hdr->vm_msg.vf_data, hdr->vm_msg.vf_datalen); - - if (timeout && (timeout->tv_sec || timeout->tv_usec)) { - if (getuptime(&newp->vn_timeout) == -1) { - /* XXX What do we do here? */ - free(newp); - return 0; - } - - newp->vn_timeout.tv_sec += timeout->tv_sec; - newp->vn_timeout.tv_usec += timeout->tv_usec; - } - - rv = vn_insert_sorted(&key_node->kn_jvlist, newp); - if (!rv) - free(newp); - - return rv; -} - - -/* - * XXX... - */ -static int -vc_cmp(commit_node_t *left, commit_node_t *right) -{ - if (left->vc_fd < right->vc_fd) - return -1; - - if (left->vc_fd == right->vc_fd) - return 0; - - return 1; -} - - -static int -vc_insert_sorted(commit_node_t **head, commit_node_t *node) -{ - commit_node_t *cur = *head, *back = NULL; - - /* only entry */ - if (!cur) { - *head = node; - return 1; - } - - while (cur) { - switch (vc_cmp(node, cur)) { - case 0: - /* duplicate */ - return 0; - case -1: - if (back) { - /* middle */ - node->vc_next = cur; - back->vc_next = node; - return 1; - } - - node->vc_next = *head; - *head = node; - return 1; - } - - back = cur; - cur = cur->vc_next; - } - - /* end */ - back->vc_next = node; - node->vc_next = NULL; - - return 1; -} - - -static commit_node_t * -vc_remove(commit_node_t **head, int fd) -{ - commit_node_t *cur = *head, *back = NULL; - - if (!cur) - return NULL; - - do { - if (cur->vc_fd == fd) { - if (back) { - back->vc_next = cur->vc_next; - cur->vc_next = NULL; - return cur; - } - - *head = cur->vc_next; - cur->vc_next = NULL; - return cur; - } - - back = cur; - cur = cur->vc_next; - } while (cur); - - return NULL; -} - - -/* - * Buffer a commit message received on a file descriptor. We don't need - * to know the node id; since the file descriptor will still be open from - * the last 'join-view' message. - */ -static int -vf_buffer_commit(int fd) -{ - key_node_t *key_node; - commit_node_t *newp; - int rv; - - key_node = kn_find_fd(fd); - if (!key_node) - return 0; - - newp = malloc(sizeof(*newp)); - if (!newp) - return 0; - - newp->vc_next = NULL; - newp->vc_fd = fd; - - rv = vc_insert_sorted(&key_node->kn_clist, newp); - if (!rv) - free(newp); - - return rv; -} - - -static int -vf_vote_yes(int fd) -{ - return msg_send_simple(fd, VF_MESSAGE, VF_VOTE, 1); - -} - - -static int -vf_vote_no(int fd) -{ - return msg_send_simple(fd, VF_MESSAGE, VF_VOTE, 0); -} - - -static int -vf_abort(int fd) -{ - key_node_t *key_node; - view_node_t *cur; - - key_node = kn_find_fd(fd); - if (!key_node) - return -1; - - cur = vn_remove(&key_node->kn_jvlist, fd); - if (!cur) - return -1; - - free(cur); - return 0; -} - - -static int -tv_cmp(struct timeval *left, struct timeval *right) -{ - if (left->tv_sec > right->tv_sec) - return 1; - - if (left->tv_sec < right->tv_sec) - return -1; - - if (left->tv_usec > right->tv_usec) - return 1; - - if (left->tv_usec < right->tv_usec) - return -1; - - return 0; -} - - -/** - * Grab the uptime from /proc/uptime. - * - * @param tv Timeval struct to store time in. The sec - * field contains seconds, the usec field - * contains the hundredths-of-seconds (converted - * to micro-seconds) - * @return -1 on failure, 0 on success. - */ -int -getuptime(struct timeval *tv) -{ - FILE *fp; - struct timeval junk; - int rv; - - fp = fopen("/proc/uptime","r"); - - if (!fp) - return -1; - -#if defined(__sparc__) || defined(__hppa__) || defined(__sparc64__) || defined (__hppa64__) - rv = fscanf(fp,"%ld.%d %ld.%d\n", &tv->tv_sec, &tv->tv_usec, - &junk.tv_sec, &junk.tv_usec); -#else - rv = fscanf(fp,"%ld.%ld %ld.%ld\n", &tv->tv_sec, &tv->tv_usec, - &junk.tv_sec, &junk.tv_usec); -#endif - fclose(fp); - - if (rv != 4) { - return -1; - } - - tv->tv_usec *= 10000; - - return 0; -} - - -/** - * Try to commit views in a given key_node. - */ -static int -vf_try_commit(key_node_t *key_node) -{ - view_node_t *vnp; - commit_node_t *cmp; - int fd = -1; - - if (!key_node) - return -1; - - if (!key_node->kn_jvlist) - return -1; - - fd = key_node->kn_jvlist->vn_fd; - - cmp = vc_remove(&key_node->kn_clist, fd); - if (!cmp) { - /*printf("VF: Commit for fd%d not received yet!", fd);*/ - return -1; - } - - free(cmp); /* no need for it any longer */ - - vnp = vn_remove(&key_node->kn_jvlist, fd); - if (!vnp) { - /* - * But, we know it was the first element on the list?!! - */ - fprintf(stderr,"VF: QUAAAAAAAAAAAAAACKKKK!"); - raise(SIGSTOP); - } - -#ifdef DEBUG - printf("VF: Commit Key %s #%d from member #%d\n", - key_node->kn_keyid, (int)vnp->vn_viewno, vnp->vn_nodeid); -#endif - - /* - * Store the current view of everything in our key node - */ - key_node->kn_viewno = vnp->vn_viewno; - if (key_node->kn_data) - free(key_node->kn_data); - key_node->kn_datalen = vnp->vn_datalen; - key_node->kn_data = malloc(vnp->vn_datalen); - - /* - * Need to check return of malloc always - */ - if (key_node->kn_data == NULL) { - fprintf (stderr, "malloc fail err=%d\n", errno); - return -1; - } - - memcpy(key_node->kn_data, vnp->vn_data, vnp->vn_datalen); - - free(vnp); - return fd; -} - - -void -vf_event_loop(uint64_t my_node_id) -{ - int max, nready, n, fd, flags; - struct timeval tv; - fd_set rfds; - generic_msg_hdr *hdrp = NULL; - int myerrno = 0; - - while (1) { - FD_ZERO(&rfds); - max = msg_fill_fdset(&rfds, MSG_ALL, MSGP_VFS); - - tv.tv_sec = 1; - tv.tv_usec = 0; - - nready = select(max + 1, &rfds, NULL, NULL, &tv); - if (nready < 0) - { - myerrno = errno; -#ifdef NOT_NOW - /* - * i think red hat wants to return w/ EINTR - */ - if (myerrno == EINTR) - { - continue; - } -#endif /* NOT_NOW */ - - errno = myerrno; - return; - } - - if (nready == 0) { - return; - } - - /* - * positive return value, break and process. - */ - break; - } - - while (nready) { - fd = msg_next_fd(&rfds); - --nready; - - flags = msg_get_flags(fd); - - if (flags & MSG_LISTEN) - fd = msg_accept(fd, 1, NULL); - - n = msg_receive_simple(fd, &hdrp, 5); - - if (n <= 0 || !hdrp) { - msg_close(fd); - continue; - } - - swab_generic_msg_hdr(hdrp); - if (hdrp->gh_command == VF_MESSAGE) { - if (vf_process_msg(fd, hdrp, n) == VFR_COMMIT) { -#ifdef DEBUG - printf("VFT: View committed\n"); -#endif - } - } - - if (hdrp) { - free(hdrp); - hdrp = NULL; - } - } -} - - -static void -vf_wait_ready(void) -{ - pthread_mutex_lock(&vf_mutex); - while (!thread_ready) { - pthread_mutex_unlock(&vf_mutex); - usleep(50000); - pthread_mutex_lock(&vf_mutex); - } - pthread_mutex_unlock(&vf_mutex); -} - - -void * -vf_server(void *arg) -{ - uint64_t my_node_id; - uint16_t port; - key_node_t *cur; - int fd; - - block_all_signals(); - - port = ((struct vf_args *)arg)->port; - my_node_id = ((struct vf_args *)arg)->local_node_id; - free(arg); - -#ifdef DEBUG - printf("VFT: Thread id %ld starting\n", (long)pthread_self()); -#endif - - pthread_mutex_lock(&vf_mutex); - if ((vf_lfd = msg_listen(port, MSGP_VFS, vf_lfds, 2)) <= 0) { - printf("Unable to set up listen socket on port %d\n", - port); - pthread_mutex_unlock(&vf_mutex); - pthread_exit(NULL); - } - - thread_ready = 1; - pthread_mutex_unlock(&vf_mutex); - - while (1) { - pthread_mutex_lock(&key_list_mutex); - for (cur = key_list; cur; cur = cur->kn_next) { - /* Destroy timed-out join views */ - while (_vf_purge(cur, &fd) != VFR_NO) { - msg_close(fd); - } - } - pthread_mutex_unlock(&key_list_mutex); - vf_event_loop(my_node_id); - } - return NULL; -} - - - -/** - * Initialize VF. Initializes the View Formation sub system. - * @param my_node_id The node ID of the caller. - * @param my_port The port of the caller. - * @return 0 on success, -1 on failure. - */ -int -vf_init(uint64_t my_node_id, uint16_t my_port, vf_vote_cb_t vcb, - vf_commit_cb_t ccb) -{ - struct vf_args *va; - - if (my_node_id == (uint64_t)-1) - return -1; - - if (my_port == 0) - return -1; - - pthread_mutex_lock(&vf_mutex); - if (vf_thread != (pthread_t)-1) { - pthread_mutex_unlock(&vf_mutex); - return 0; - } - - va = malloc(sizeof(*va)); - - if (va == NULL) { - fprintf (stderr, "vf_init: malloc fail2 err=%d\n", errno); - return -1; - } - - va->local_node_id = my_node_id; - va->port = my_port; - - pthread_create(&vf_thread, NULL, vf_server, va); - - /* Write/read needs this */ - _port = my_port; - _node_id = my_node_id; - default_vote_cb = vcb; - default_commit_cb = ccb; - pthread_mutex_unlock(&vf_mutex); - - vf_wait_ready(); - - return 0; -} - - -/** - Shut down VF - */ -int -vf_shutdown(void) -{ - int x; - key_node_t *c_key; - view_node_t *c_jv; - commit_node_t *c_cn; - - pthread_mutex_lock(&vf_mutex); - pthread_cancel(vf_thread); - pthread_join(vf_thread, NULL); - thread_ready = 0; - vf_thread = (pthread_t)0; - - for (x = 0 ; x < vf_lfd; x++) - msg_close(vf_lfds[x]); - - _port = 0; - _node_id = (uint64_t)-1; - pthread_mutex_lock(&key_list_mutex); - - while ((c_key = key_list) != NULL) { - - while ((c_jv = c_key->kn_jvlist) != NULL) { - msg_close(c_jv->vn_fd); - key_list->kn_jvlist = c_jv->vn_next; - free(c_jv); - } - - while ((c_cn = c_key->kn_clist) != NULL) { - c_key->kn_clist = c_cn->vc_next; - free(c_cn); - } - - key_list = c_key->kn_next; - - if (c_key->kn_data) - free(c_key->kn_data); - free(c_key->kn_keyid); - free(c_key); - } - - pthread_mutex_unlock(&key_list_mutex); - pthread_mutex_unlock(&vf_mutex); - - return 0; -} - - -/** - * Adds a key to key node list and sets up callback functions. - * - * @param keyid The ID of the key to add. - * @param timeout Amount of time to wait before purging a JOIN_VIEW - * message from our buffers. - * @param vote_cb Function to call on a given data set/view number - * to help decide whether to vote yes or no. This is - * optional, and DOES NOT obviate the need for VF's - * decision-making (version/node ID based). Also, - * the data from the view-node is passed UNCOPIED to - * the callback function! - * @param commit_cb Function to call when a key has had one or more - * commits. Same info applies: the data passed to the - * callback function is UNCOPIED. - * @return 0 (always) - */ -static int -vf_key_init_nt(char *keyid, int timeout, vf_vote_cb_t vote_cb, - vf_commit_cb_t commit_cb) -{ - key_node_t *newnode = NULL; - - newnode = kn_find_key(keyid); - if (newnode) { - printf("Key %s already initialized\n", keyid); - pthread_mutex_unlock(&key_list_mutex); - return -1; - } - - newnode = malloc(sizeof(*newnode)); - - if (newnode == NULL) { - fprintf(stderr, "malloc fail3 err=%d\n", errno); - pthread_mutex_unlock(&key_list_mutex); - return -1; - } - - newnode->kn_data = NULL; - memset(newnode,0,sizeof(*newnode)); - newnode->kn_keyid = strdup(keyid); - - /* Set up callbacks */ - if (vote_cb) - newnode->kn_vote_cb = vote_cb; - else - newnode->kn_vote_cb = default_vote_cb; - - if (commit_cb) - newnode->kn_commit_cb = commit_cb; - else - newnode->kn_commit_cb = default_commit_cb; - - if (timeout < VF_COMMIT_TIMEOUT_MIN) { - /* Join View message timeout must exceed the - coordinator timeout */ - timeout = VF_COMMIT_TIMEOUT_MIN; - } - newnode->kn_tsec = timeout; - - newnode->kn_next = key_list; - key_list = newnode; - - return 0; -} - - -int -vf_key_init(char *keyid, int timeout, vf_vote_cb_t vote_cb, - vf_commit_cb_t commit_cb) -{ - int rv; - - pthread_mutex_lock(&key_list_mutex); - rv = vf_key_init_nt(keyid, timeout, vote_cb, commit_cb); - pthread_mutex_unlock(&key_list_mutex); - - return 0; -} - - -vf_msg_t * -build_vf_data_message(int cmd, char *keyid, void *data, uint32_t datalen, - uint64_t viewno, uint32_t *retlen) -{ - uint32_t totallen; - vf_msg_t *msg; - /* - * build the message - */ - totallen = sizeof(vf_msg_t) + datalen; - msg = malloc(totallen); - *retlen = 0; - if (!msg) - return NULL; - memset(msg, 0, totallen); - - /* header */ - msg->vm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msg->vm_hdr.gh_length = totallen; - msg->vm_hdr.gh_command = VF_MESSAGE; - msg->vm_hdr.gh_arg1 = cmd; - - /* Data */ - strncpy(msg->vm_msg.vf_keyid,keyid,sizeof(msg->vm_msg.vf_keyid)); - msg->vm_msg.vf_datalen = datalen; - msg->vm_msg.vf_coordinator = _node_id; - msg->vm_msg.vf_view = viewno; - memcpy(msg->vm_msg.vf_data, data, datalen); - - *retlen = totallen; - return msg; -} - - -/** - * Begin VF. Begins View-Formation for agiven set of data. - * - * @param membership Current membership. - * @param flags Operational flags. - * @param keyid Key ID of the data to distribute. - * @param data The actual data to distribute. - * @param datalen The length of the data. - * @param viewno The current view number of the data. - * @param block Block until completion? - * @return -1 on failure, or 0 on success. The parent will - * either get a SIGCHLD or can randomly call vf_end() - * on keyid to cause the VF child to be cleaned up. - * @see vf_end - */ -int -vf_write(cluster_member_list_t *membership, uint32_t flags, char *keyid, - void *data, uint32_t datalen) -{ - uint64_t nodeid; - int *peer_fds = NULL; - int count; - key_node_t *key_node = NULL; - vf_msg_t *join_view = NULL; - int remain = 0, x, y, rv = 1; - uint32_t totallen; - struct timeval start, end, dif; - void *lockp = NULL; - int l = 1; /* keep track of whether we got a lock */ - char lock_name[256]; - int my_status; - int ret_status = 0; - - if (!data || !datalen || !keyid || !strlen(keyid) || !membership) - return -1; - - pthread_mutex_lock(&vf_mutex); - - /* set to -1 */ - count = sizeof(int) * (membership->cml_count + 1); - peer_fds = malloc(count); - if(!peer_fds) { - pthread_mutex_unlock(&vf_mutex); - return -1; - } - - for (x=0; x < membership->cml_count + 1; x++) - peer_fds[x] = -1; - getuptime(&start); - -retry_top: - /* Obtain cluster lock on it. */ - snprintf(lock_name, sizeof(lock_name), "usrm::vf"); - l = clu_lock(lock_name, CLK_EX, &lockp); - if (l < 0) { - pthread_mutex_unlock(&vf_mutex); - return l; - } - - /* - * Connect to everyone, except ourself. We separate this from the - * initial send cycle because the connect cycle can cause timeouts - * within the code - ie, if a node is down, it is likely the connect - * will take longer than the client is expecting to wait for the - * commit/abort messages! - * - * We assume we're up. Since challenge-response needs both - * processes to be operational... - */ - for (x = 0, y = 0; x < membership->cml_count; x++) { - if (!memb_online(membership, - membership->cml_members[x].cm_id)) { - continue; - } - - if (peer_fds[x] != -1) - continue; - - nodeid = membership->cml_members[x].cm_id; -#ifdef DEBUG - printf("VF: Connecting to member #%d\n", (int)nodeid); - fflush(stdout); -#endif - peer_fds[y] = msg_open(nodeid, _port, MSGP_VFC, 15); - - if (peer_fds[y] == -1) { -#ifdef DEBUG - printf("VF: Connect to %d failed: %s\n", (int)nodeid, - strerror(errno)); -#endif - if (flags & VFF_IGN_CONN_ERRORS) - continue; - - if (flags & VFF_RETRY) { - clu_unlock(lock_name, lockp); - lockp = NULL; - usleep(20000); /* XXX */ - goto retry_top; - } - - /* No retry and no connection ignoring */ - rv = -1; - goto out_cleanup; - } - ++y; - } - - if (y == 0) { - /* No hosts online / all refused connection (including - ourself) - guess we're good */ - rv = 1; - goto out_cleanup; - } - - pthread_mutex_lock(&key_list_mutex); - key_node = kn_find_key(keyid); - if (!key_node) { - - if ((vf_key_init_nt(keyid, 10, NULL, NULL) < 0)) { - pthread_mutex_unlock(&key_list_mutex); - /* key_list_mutex is only held here; so we do - not put it in the cleanup section */ - rv = -1; - goto out_cleanup; - } - key_node = kn_find_key(keyid); - assert(key_node); - } - - join_view = build_vf_data_message(VF_JOIN_VIEW, keyid, data, datalen, - key_node->kn_viewno+1, &totallen); - - pthread_mutex_unlock(&key_list_mutex); - - if (!join_view) { - rv = -1; - goto out_cleanup; - } - -#ifdef DEBUG - printf("VF: Push %d.%d #%d\n", (int)_node_id, getpid(), - (int)join_view->vm_msg.vf_view); -#endif - /* - * Encode the package. - */ - swab_vf_msg_t(join_view); - - /* - * Send our message to everyone - */ - for (x = 0; peer_fds[x] != -1; x++) { - - /* - * Still send msg to everyone, but then close - * all peers fds and cleanup - TBD JSC - */ - my_status = msg_send(peer_fds[x], join_view, totallen); - if (my_status != totallen) { - ret_status = -1; - } - - remain++; - } - - /* - * Now cleanup - */ - if (ret_status == -1) { - vf_send_abort(peer_fds); - rv = -1; - goto out_cleanup; - } - -#ifdef DEBUG - printf("VF: Checking for consensus...\n"); -#endif - /* - * See if we have a consensus =) - */ - if ((rv = (vf_unanimous(peer_fds, remain, VF_COORD_TIMEOUT)))) { - vf_send_commit(peer_fds); - } else { - vf_send_abort(peer_fds); -#ifdef DEBUG - printf("VF: Aborted!\n"); -#endif - } - - -out_cleanup: - /* - * Clean up - */ - if (peer_fds) { - close_all(peer_fds); - free(peer_fds); - } - - /* - * unanimous returns 1 for true; 0 for false, so negate it and - * return our value... - */ - if (join_view) - free(join_view); - if (l == 0) /* from clu_lock() above - if 0, - we have a lock to release. Note that vf_read - uses 'l' for another use; maybe we should - clean it up for maintenance. This fixes - bugzilla #448108 */ - clu_unlock(lock_name, lockp); - - pthread_mutex_unlock(&vf_mutex); - - if (rv >= 0) { - getuptime(&end); - - dif.tv_usec = end.tv_usec - start.tv_usec; - dif.tv_sec = end.tv_sec - start.tv_sec; - - if (dif.tv_usec < 0) { - dif.tv_usec += 1000000; - dif.tv_sec--; - } - -#ifdef DEBUG - printf("VF: Converge Time: %d.%06d\n", (int)dif.tv_sec, - (int)dif.tv_usec); -#endif - } - - return ((rv>=0)?0:-1); -} - - -/** - * Purge an unresolved JOIN-VIEW message if it has expired. This only - * purges a single message; if used, it should be called in a while() - * loop. The function returns a file descriptor which can be closed and - * cleaned up by the caller if a request has indeed timed out. Also, - * if a request has timed out, the function calls vf_resolve_views to try - * to resolve any outstanding views which were opened up by the timed-out - * request. - * - * @param keyid Key ID on which to purge timeouts. - * @param fd Pointer which, upon return, will either contain -1 - * whenever VFR_NO is the return value, or the file - * descriptor which was resolved. - * @return VFR_ERROR on error. VFR_NO if there are no timed-out - * requests, or if there are no requests at all, or if - * keyid isn't valid. VFR_OK if there are timed-out - * requests and the virtue of removing the timed-out - * requests did not cause commit-resolution, or - * VFR_COMMIT if new views were committed. - */ -static int -_vf_purge(key_node_t *key_node, int *fd) -{ - view_node_t *cur, *dead = NULL; - struct timeval tv; - - *fd = -1; - - if (!key_node) - return VFR_NO; - - cur = key_node->kn_jvlist; - if (!cur) - return VFR_NO; - - if (getuptime(&tv) == -1) { - fprintf(stderr,"VF: getuptime(): %s\n", strerror(errno)); - return VFR_ERROR; - } - - for (; cur; cur = cur->vn_next) { - if (tv_cmp(&tv, &cur->vn_timeout) < 0) - continue; - - *fd = cur->vn_fd; - dead = vn_remove(&key_node->kn_jvlist, *fd); - free(dead); - - printf("VF: Killed fd %d\n", *fd); - /* - * returns the removed associated file descriptor - * so that we can close it and get on with life - */ - break; - } - - if (*fd == -1) - return VFR_NO; - - if (vf_resolve_views(key_node)) - return VFR_COMMIT; - return VFR_OK; -} - - -/** - * Process a VF message. - * - * @param handle File descriptor on which msgp was received. - * @param msgp Pointer to already-received message. - * @param nbytes Length of msgp. - * @return -1 on failure, 0 on success. - */ -int -vf_process_msg(int handle, generic_msg_hdr *msgp, int nbytes) -{ - vf_msg_t *hdrp; - int ret; - - if ((nbytes <= 0) || (nbytes < sizeof(generic_msg_hdr)) || - (msgp->gh_command != VF_MESSAGE)) - return VFR_ERROR; - - switch(msgp->gh_arg1) { - case VF_CURRENT: -#ifdef DEBUG - printf("VF: Received request for current data\n"); -#endif - - /* Validate size... */ - if (nbytes < sizeof(*hdrp)) { - fprintf(stderr, "VF: JOIN_VIEW message too short!\n"); - return VFR_ERROR; - } - - hdrp = (vf_msg_t *)msgp; - swab_vf_msg_info_t(&hdrp->vm_msg); - - return vf_send_current(handle, hdrp->vm_msg.vf_keyid); - - case VF_JOIN_VIEW: - /* Validate size... */ - if (nbytes < sizeof(*hdrp)) { - fprintf(stderr, "VF: JOIN_VIEW message too short!\n"); - return VFR_ERROR; - } - - /* Unswap so we can swab the whole message */ - hdrp = (vf_msg_t *)msgp; - swab_vf_msg_info_t(&hdrp->vm_msg); - - if ((hdrp->vm_msg.vf_datalen + sizeof(*hdrp)) != nbytes) { - fprintf(stderr, "VF: JOIN_VIEW: Invalid size %d/%d\n", - nbytes, hdrp->vm_msg.vf_datalen + - (uint32_t)sizeof(*hdrp)); - - return VFR_ERROR; - } - return vf_handle_join_view_msg(handle, hdrp); - - case VF_ABORT: - printf("VF: Received VF_ABORT, fd%d\n", handle); - vf_abort(handle); - return VFR_ABORT; - - case VF_VIEW_FORMED: -#ifdef DEBUG - printf("VF: Received VF_VIEW_FORMED, fd%d\n", - handle); -#endif - pthread_mutex_lock(&key_list_mutex); - vf_buffer_commit(handle); - ret = (vf_resolve_views(kn_find_fd(handle)) ? - VFR_COMMIT : VFR_OK); - pthread_mutex_unlock(&key_list_mutex); - return ret; - - default: - printf("VF: Unknown msg type 0x%08x\n", - msgp->gh_arg1); - } - - return VFR_OK; -} - - -/** - * Retrieves the current dataset for a given key ID. - * - * @param keyid Key ID of data set to retrieve. - * @param view Pointer which will be filled with the current data - * set's view number. - * @param data Pointer-to-pointer which will be allocated and - * filled with the current data set. Caller must free. - * @param datalen Pointer which will be filled with the current data - * set's size. - * @return -1 on failure, 0 on success. - */ -int -vf_read(cluster_member_list_t *membership, char *keyid, uint64_t *view, - void **data, uint32_t *datalen) -{ - key_node_t *key_node; - char lock_name[256]; - void *lockp = NULL; - int l; - - /* Obtain cluster lock on it. */ - pthread_mutex_lock(&vf_mutex); - snprintf(lock_name, sizeof(lock_name), "usrm::vf"); - l = clu_lock(lock_name, CLK_EX, &lockp); - if (l < 0) { - pthread_mutex_unlock(&vf_mutex); - printf("Couldn't lock %s\n", keyid); - return l; - } - - do { - pthread_mutex_lock(&key_list_mutex); - - key_node = kn_find_key(keyid); - if (!key_node) { - if ((vf_key_init_nt(keyid, 10, NULL, NULL) < 0)) { - pthread_mutex_unlock(&key_list_mutex); - clu_unlock(lock_name, lockp); - pthread_mutex_unlock(&vf_mutex); - printf("Couldn't locate %s\n", keyid); - return VFR_ERROR; - } - - key_node = kn_find_key(keyid); - assert(key_node); - } - - /* XXX Don't allow reads during commits. */ - if (key_node->kn_jvlist || key_node->kn_clist) { - pthread_mutex_unlock(&key_list_mutex); - usleep(10000); - continue; - } - } while (0); - - if (!key_node->kn_data || !key_node->kn_datalen) { - pthread_mutex_unlock(&key_list_mutex); - - if (!membership) { - clu_unlock(lock_name, lockp); - //printf("Membership NULL, can't find %s\n", keyid); - pthread_mutex_unlock(&vf_mutex); - return VFR_ERROR; - } - - l = vf_request_current(membership, keyid, view, data, - datalen); - if (l == VFR_NODATA || l == VFR_ERROR) { - clu_unlock(lock_name, lockp); - //printf("Requesting current failed %s %d\n", keyid, l); - pthread_mutex_unlock(&vf_mutex); - return l; - } - } - - *data = malloc(key_node->kn_datalen); - if (! *data) { - pthread_mutex_unlock(&key_list_mutex); - clu_unlock(lock_name, lockp); - pthread_mutex_unlock(&vf_mutex); - printf("Couldn't malloc %s\n", keyid); - return VFR_ERROR; - } - - memcpy(*data, key_node->kn_data, key_node->kn_datalen); - *datalen = key_node->kn_datalen; - *view = key_node->kn_viewno; - - pthread_mutex_unlock(&key_list_mutex); - clu_unlock(lock_name, lockp); - pthread_mutex_unlock(&vf_mutex); - - return VFR_OK; -} - - -int -vf_read_local(char *keyid, uint64_t *view, void **data, uint32_t *datalen) -{ - key_node_t *key_node = NULL; - - pthread_mutex_lock(&vf_mutex); - pthread_mutex_lock(&key_list_mutex); - - key_node = kn_find_key(keyid); - if (!key_node) { - pthread_mutex_unlock(&key_list_mutex); - pthread_mutex_unlock(&vf_mutex); - printf("no key for %s\n", keyid); - return VFR_NODATA; - } - - if (!key_node->kn_data || !key_node->kn_datalen) { - pthread_mutex_unlock(&key_list_mutex); - pthread_mutex_unlock(&vf_mutex); - return VFR_NODATA; - } - - *data = malloc(key_node->kn_datalen); - if (! *data) { - pthread_mutex_unlock(&key_list_mutex); - pthread_mutex_unlock(&vf_mutex); - printf("Couldn't malloc %s\n", keyid); - return VFR_ERROR; - } - - memcpy(*data, key_node->kn_data, key_node->kn_datalen); - *datalen = key_node->kn_datalen; - *view = key_node->kn_viewno; - - pthread_mutex_unlock(&key_list_mutex); - pthread_mutex_unlock(&vf_mutex); - - return VFR_OK; -} - - -static int -vf_send_current(int fd, char *keyid) -{ - key_node_t *key_node; - vf_msg_t *msg; - int ret; - uint32_t totallen; - - if (fd == -1) - return VFR_ERROR; - - pthread_mutex_lock(&key_list_mutex); - - key_node = kn_find_key(keyid); - if (!key_node || !key_node->kn_data || !key_node->kn_datalen) { - pthread_mutex_unlock(&key_list_mutex); - printf("VFT: No data for keyid %s\n", keyid); - return (msg_send_simple(fd, VF_NACK, 0, 0) != -1)? - VFR_OK : VFR_ERROR; - } - - /* - * XXX check for presence of nodes on the commit lists; send - * VF_AGAIN if there is any. - */ - msg = build_vf_data_message(VF_ACK, keyid, key_node->kn_data, - key_node->kn_datalen, - key_node->kn_viewno, - &totallen); - - pthread_mutex_unlock(&key_list_mutex); - if (!msg) - return (msg_send_simple(fd, VFR_ERROR, 0, 0) != -1)? - VFR_OK : VFR_ERROR; - - swab_vf_msg_t(msg); - ret = (msg_send(fd, msg, totallen) != -1)?VFR_OK:VFR_ERROR; - free(msg); - return ret; -} - - -static int -vf_set_current(char *keyid, uint64_t view, void *data, uint32_t datalen) -{ - key_node_t *key_node; - void *datatmp; - - pthread_mutex_lock(&key_list_mutex); - - key_node = kn_find_key(keyid); - if (!key_node) { - pthread_mutex_unlock(&key_list_mutex); - return VFR_ERROR; - } - - datatmp = malloc(datalen); - if (! datatmp) { - pthread_mutex_unlock(&key_list_mutex); - return VFR_ERROR; - } - - if (key_node->kn_data) { - free(key_node->kn_data); - key_node->kn_data = NULL; - } - - key_node->kn_data = datatmp; - memcpy(key_node->kn_data, data, datalen); - key_node->kn_datalen = datalen; - key_node->kn_viewno = view; - - pthread_mutex_unlock(&key_list_mutex); - - return VFR_OK; -} - - -/** - * Request the current state of a keyid from the membership. - * XXX This doesn't wait for outstanding transactions to complete. - * Perhaps it should. - * - * @param membership Membership mask. - * @param keyid VF key id (application-defined). - * @param viewno Return view number. Passed in pre-allocated. - * @param data Return data pointer. Allocated within. - * @param datalen Size of data returned. - */ -static int -vf_request_current(cluster_member_list_t *membership, char *keyid, - uint64_t *viewno, void **data, uint32_t *datalen) -{ - int fd, x, n, rv = VFR_OK, port; - vf_msg_t rmsg; - vf_msg_t *msg = &rmsg; - generic_msg_hdr * gh; - uint64_t me; - - if (_port == 0) { - return -1; - } - - port = _port; - me = _node_id; - - memset(msg, 0, sizeof(*msg)); - msg->vm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msg->vm_hdr.gh_length = sizeof(*msg); - msg->vm_hdr.gh_command = VF_MESSAGE; - msg->vm_hdr.gh_arg1 = VF_CURRENT; - strncpy(msg->vm_msg.vf_keyid, keyid, - sizeof(msg->vm_msg.vf_keyid)); - - swab_generic_msg_hdr(&(msg->vm_hdr)); - swab_vf_msg_info_t(&(msg->vm_msg)); - - for (x = 0; x < membership->cml_count; x++) { - if (!memb_online(membership, - membership->cml_members[x].cm_id)) - continue; - - /* Can't request from self. */ - if (membership->cml_members[x].cm_id == me) - continue; - - rv = VFR_ERROR; - fd = msg_open(membership->cml_members[x].cm_id, port, - MSGP_VFC, 15); - if (fd == -1) - continue; - - msg = &rmsg; - //printf("VF: Requesting current value of %s from %d\n", - //msg->vm_msg.vf_keyid, - //(int)membership->cml_members[x].cm_id); - - if (msg_send(fd, msg, sizeof(*msg)) != sizeof(*msg)) { - printf("Couldn't send entire message\n"); - continue; - } - - gh = NULL; - if ((n = msg_receive_simple(fd, (generic_msg_hdr **)&gh, 10)) - == -1) { - if (gh) - free(gh); - msg_close(fd); - continue; - } - msg_close(fd); - msg = (vf_msg_t *)gh; - break; - } - - if (x >= membership->cml_count) - return VFR_ERROR; - - /* Uh oh */ - if (!msg || (msg == &rmsg)) { - printf("VF: No valid message\n"); - return VFR_ERROR; - } - - swab_generic_msg_hdr(&(msg->vm_hdr)); - if (msg->vm_hdr.gh_command == VF_NACK) { - free(msg); - return VFR_NODATA; - } - - if (msg->vm_hdr.gh_length < sizeof(vf_msg_t)) { - fprintf(stderr, "VF: Short reply from %d\n", x); - free(msg); - return VFR_ERROR; - } - - if (msg->vm_hdr.gh_length > n) { - fprintf(stderr,"VF: Size mismatch during decode (%d > %d)\n", - msg->vm_hdr.gh_length, n); - free(msg); - return VFR_ERROR; - } - - swab_vf_msg_info_t(&(msg->vm_msg)); - - if (msg->vm_msg.vf_datalen != (n - sizeof(*msg))) { - fprintf(stderr,"VF: Size mismatch during decode (\n"); - free(msg); - return VFR_ERROR; - } - - if (vf_set_current(keyid, msg->vm_msg.vf_view, - msg->vm_msg.vf_data, - msg->vm_msg.vf_datalen) == VFR_ERROR) { - free(msg); - return VFR_ERROR; - } - - free(msg); - - return VFR_OK; -} - diff --git a/rgmanager/src/clulib/wrap_lock.c b/rgmanager/src/clulib/wrap_lock.c deleted file mode 100644 index a1ffd24..0000000 --- a/rgmanager/src/clulib/wrap_lock.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - Copyright Crosswalk 2006-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#ifdef WRAP_LOCKS -#include <stdio.h> -#include <sys/types.h> -#include <gettid.h> -#include <pthread.h> -#include <string.h> -#include <errno.h> -#include <string.h> -#include <signal.h> - -int __real_pthread_mutex_lock(pthread_mutex_t *lock); -int -__wrap_pthread_mutex_lock(pthread_mutex_t *lock) -{ - int status; - struct timespec delay; - - while (1) { - status = __real_pthread_mutex_lock(lock); - - switch(status) { - case EDEADLK: - /* Already own it: Note the error, but continue */ - fprintf(stderr, "[%d] %s(%p): %s; continuing\n", - gettid(), - __FUNCTION__, lock, strerror(status)); - /* deliberate fallthrough */ - case 0: - return 0; - case EBUSY: - /* Try again */ - break; - default: - /* Other return codes */ - fprintf(stderr, "[%d] %s(%p): %s\n", gettid(), - __FUNCTION__, lock, strerror(status)); - raise(SIGSEGV); - /* EINVAL? */ - return 0; - } - - delay.tv_sec = 0; - delay.tv_nsec = 100000; - nanosleep(&delay, NULL); - } - - /* Not reached */ - return 0; -} - - -int __real_pthread_mutex_unlock(pthread_mutex_t *lock); -int -__wrap_pthread_mutex_unlock(pthread_mutex_t *lock) -{ - int status; - struct timespec delay; - - while (1) { - status = __real_pthread_mutex_unlock(lock); - - switch(status) { - case EPERM: - /* Don't own it: Note the error, but continue */ - fprintf(stderr, "[%d] %s(%p): %s; continuing\n", - gettid(), - __FUNCTION__, lock, strerror(status)); - /* deliberate fallthrough */ - case 0: - return 0; - default: - fprintf(stderr, "[%d] %s(%p): %s\n", gettid(), - __FUNCTION__, lock, strerror(status)); - raise(SIGSEGV); - return 0; - } - - delay.tv_sec = 0; - delay.tv_nsec = 100000; - nanosleep(&delay, NULL); - } - - /* Not reached */ - return 0; -} - - -int __real_pthread_rwlock_rdlock(pthread_rwlock_t *lock); -int -__wrap_pthread_rwlock_rdlock(pthread_rwlock_t *lock) -{ - int status; - struct timespec delay; - - while (1) { - status = __real_pthread_rwlock_rdlock(lock); - - switch(status) { - case EDEADLK: - /* Already own it: Note the error, but continue */ - fprintf(stderr, "[%d] %s(%p): %s; continuing\n", - gettid(), - __FUNCTION__, lock, strerror(status)); - /* deliberate fallthrough */ - case 0: - return 0; - case EBUSY: - /* Try again */ - break; - default: - /* Other return codes */ - fprintf(stderr, "[%d] %s(%p): %s\n", gettid(), - __FUNCTION__, lock, strerror(status)); - raise(SIGSEGV); - /* EINVAL? */ - return 0; - } - - delay.tv_sec = 0; - delay.tv_nsec = 100000; - nanosleep(&delay, NULL); - } - - /* Not reached */ - return 0; -} - - -int __real_pthread_rwlock_wrlock(pthread_rwlock_t *lock); -int -__wrap_pthread_rwlock_wrlock(pthread_rwlock_t *lock) -{ - int status; - struct timespec delay; - - while (1) { - status = __real_pthread_rwlock_wrlock(lock); - - switch(status) { - case EDEADLK: - /* Already own it: Note the error, but continue */ - fprintf(stderr, "[%d] %s(%p): %s; continuing\n", - gettid(), - __FUNCTION__, lock, strerror(status)); - /* deliberate fallthrough */ - case 0: - return 0; - case EBUSY: - /* Try again */ - break; - default: - /* Other return codes */ - fprintf(stderr, "[%d] %s(%p): %s\n", gettid(), - __FUNCTION__, lock, strerror(status)); - raise(SIGSEGV); - /* EINVAL? */ - return 0; - } - - delay.tv_sec = 0; - delay.tv_nsec = 100000; - nanosleep(&delay, NULL); - } - - /* Not reached */ - return 0; -} - - -int __real_pthread_rwlock_unlock(pthread_rwlock_t *lock); -int -__wrap_pthread_rwlock_unlock(pthread_rwlock_t *lock) -{ - int status; - struct timespec delay; - - while (1) { - status = __real_pthread_rwlock_unlock(lock); - - switch(status) { - case EPERM: - /* Don't own it: Note the error, but continue */ - fprintf(stderr, "[%d] %s(%p): %s; continuing\n", - gettid(), - __FUNCTION__, lock, strerror(status)); - /* deliberate fallthrough */ - case 0: - return 0; - default: - fprintf(stderr, "[%d] %s(%p): %s\n", gettid(), - __FUNCTION__, lock, strerror(status)); - raise(SIGSEGV); - return 0; - } - - delay.tv_sec = 0; - delay.tv_nsec = 100000; - nanosleep(&delay, NULL); - } - - /* Not reached */ - return 0; -} -#endif - diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile deleted file mode 100644 index 55b37d5..0000000 --- a/rgmanager/src/daemons/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk -INCLUDE += -I $(top_srcdir)/include - -CFLAGS+= -g -I${incdir} -I/usr/include/libxml2 -L${libdir} -CFLAGS+= -I/usr/include/slang - -CFLAGS+= -g -Wstrict-prototypes -Wshadow -fPIC -D_GNU_SOURCE - -CFLAGS+= -L ../clulib - -LDFLAGS+= -lclulib -lxml2 -lmagmamsg -lmagma -lpthread -ldl -lslang -TARGETS=clurgmgrd clurmtabd rg_test - -all: ${TARGETS} - -install: all - install -d ${sbindir} - install clurgmgrd ${sbindir} - install clurmtabd ${sbindir} - install rg_test ${sbindir} - -uninstall: - ${UNINSTALL} clurgmgrd ${sbindir} - ${UNINSTALL} clurmtabd ${sbindir} - ${UNINSTALL} rg_test ${sbindir} - -clurgmgrd: rg_thread.o rg_locks.o main.o groups.o rg_state.o \ - rg_queue.o members.o rg_forward.o reslist.o \ - resrules.o restree.o fo_domain.o \ - watchdog.o restart_counter.o event_config.o \ - slang_event.o rg_event.o service_op.o - $(CC) -o $@ $^ $(INCLUDE) $(CFLAGS) $(LDFLAGS) -lccs - -# -# Our test program links against the local allocator so that -# we can see if our program is leaking memory during XML parsing, tree -# delta calculations, building/teardown of resource lists, etc. -# If it's leaking memory, the 'make check' will fail. Also, we can -# use it to test known-good configurations for regressions. -# -# The data in the 'tests' directory is hand-crafted; so running 'gentests.sh' -# will require that the developer hand-verify the correctness of the -# resulting output prior to committing back to CVS. -# -# This is NOT meant to be an installed binary. Rather, RPMs and/or other -# packages should run 'make check' as part of the build process. -# -rg_test: rg_locks-noccs.o test-noccs.o reslist-noccs.o \ - resrules-noccs.o restree-noccs.o fo_domain-noccs.o \ - event_config-noccs.o restart_counter.o - $(CC) -o $@ $^ $(INCLUDE) $(CFLAGS) -llalloc $(LDFLAGS) - -clurmtabd: clurmtabd.o clurmtabd_lib.o - $(CC) -o $@ $^ $(INCLUDE) $(CFLAGS) $(LDFLAGS) - -clean: - rm -f *.o $(TARGETS) rg_test - rm -f tests/*.out* - -check: rg_test - cd tests && ./runtests.sh - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDE) $(CFLAGS) - -%-noccs.o: %.c - $(CC) -c -o $@ $^ $(INCLUDE) $(CFLAGS) -DNO_CCS - diff --git a/rgmanager/src/daemons/clurmtabd.c b/rgmanager/src/daemons/clurmtabd.c deleted file mode 100644 index fb84536..0000000 --- a/rgmanager/src/daemons/clurmtabd.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Keeps /var/lib/nfs/rmtab in sync across the cluster. - * - * Author: Lon H. Hohberger <lhh at redhat.com> - * - * Synchronizes entries in a mount point with /var/lib/nfs/rmtab. - */ - -#define CM_NFS_DIR ".clumanager" - -#include <stdio.h> -#include <rmtab.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <syslog.h> -#include <clulog.h> -#include <unistd.h> -#include <limits.h> -#include <regex.h> - -#define POLLINT_DEFAULT 2 - -/* FIXME DAEMON_STR is equivalent to the one in quorumd.c: CLURMTABD_DAEMON */ -/* Would be nice to have stuff like this defined in one place */ -#define DAEMON_STR "clurmtabd" -#define LOGLEVEL_STR DAEMON_STR "%logLevel" -#define POLLINT_STR DAEMON_STR "%pollInterval" - -/* - * Globals - */ - -static int exiting = 0; -static int poll_interval = POLLINT_DEFAULT; - -/* - * Function Prototypes - */ -static int rmtab_modified(void); -static int rmtab_copy_bypath(rmtab_node ** dest, rmtab_node ** src, - const char *path); -static int rmtab_get_update(rmtab_node ** rmtab, rmtab_node ** pruned_rmtab, - rmtab_node ** diff, char *path); - -/* Signal Handlers */ -static void sh_sync(int sig); -static void sh_exit(int sig); -static void sh_reconfigure(int sig); -static inline void register_sighandlers(void); - -/* Configuration */ -#if 0 -static inline int __get_int_param(char *str, int *val, int dflt); -#endif -static int get_rmtabd_loglevel(int *level); -static int get_rmtabd_pollinterval(int *interval); -static void rmtabd_reconfigure(void); - -/* Initialization */ -static int rmtabd_config_init(void); -int main(int argc, char **argv); - - -/** - * stat _PATH_RMTAB and see if it's changed. - * - * @returns 1 if it's been modified; 0 if not. - */ -static int -rmtab_modified(void) -{ - /* Preserved data */ - static struct stat prev_stat; - static int __prev_stat = 0; - - struct stat curr_stat; - int rv = 1; - - /* Initialize */ - if (!__prev_stat) { - memset(&prev_stat, 0, sizeof (prev_stat)); - stat(_PATH_RMTAB, &prev_stat); - __prev_stat = 1; - return 1; - } - - memset(&curr_stat, 0, sizeof (curr_stat)); - while (stat(_PATH_RMTAB, &curr_stat) == -1) { - if (errno != ENOENT) { - clulog(LOG_ERR, "#15: %s: stat: %s\n", __FUNCTION__, - strerror(errno)); - return -1; - } - - /* Create the file. */ - clulog(LOG_WARNING, "#62: " _PATH_RMTAB - " does not exist - creating"); - close(open(_PATH_RMTAB, O_CREAT | O_SYNC, 0600)); - } - - if ((rv = memcmp(&prev_stat.st_mtime, &curr_stat.st_mtime, - sizeof (curr_stat.st_mtime)))) { - clulog(LOG_DEBUG, "Detected modified " _PATH_RMTAB "\n"); - memcpy(&prev_stat, &curr_stat, sizeof (prev_stat)); - } - - return !!rv; -} - - -/** - * Insert (copy) entries in **src with the same rn_path as *path to - * destination list **dest. - * - * @param dest Destination list pointer. - * @param src Source list pointer. - * @param path Path to prune (only copy entries in the specified - * path). - * Returns -1 if rmtab_insert fails; 0 on success - */ -static int -rmtab_copy_bypath(rmtab_node ** dest, rmtab_node ** src, const char *path) -{ - rmtab_node *curr, *last = NULL; - - for (curr = *src; curr; curr = curr->rn_next) - if (!strcmp(path, curr->rn_path)) - if ((last = rmtab_insert(dest, last, - curr->rn_hostname, - curr->rn_path, - curr->rn_count)) == NULL) - return -1; - return 0; -} - - -/** - * Update the rmtab from /var/lib/nfs/rmtab. We need to maintain two separate - * lists (rmtab and pruned_rmtab). This is because we don't want to sync - * non-cluster exports. Non-cluster exports will not show up in pruned_rmtab, - * however, when we receive an update from our peer, we'd lose non-cluster - * entries if we didn't preserve them when we merge in changes from our peer. - * - * The current (full) rmtab is passed in as **rmtab. The current cluster-only - * (pruned) rmtab is passed in as **pruned_rmtab. The differences between - * the current and new cluster-only rmtabs are passed out in **diff, and the - * new versions (if any) of the full rmtab and pruned rmtab are moved into - * - * @return -1 on error, 0 on success, 1 if no differences exist. - */ -static int -rmtab_get_update(rmtab_node ** rmtab, rmtab_node ** pruned_rmtab, - rmtab_node ** diff, char *path) -{ - int rv = -1; - rmtab_node *old_rmtab = NULL, *old_pruned = NULL; - - if (!rmtab_modified()) - return 1; - - /* Save the current full list */ - rmtab_move(&old_rmtab, rmtab); - - if (rmtab_read(rmtab, _PATH_RMTAB) == -1) { - clulog(LOG_ERR, "#16: Failed to reread rmtab: %s\n", - strerror(errno)); - - /* Don't kill the list if we fail to reread. */ - rmtab_move(rmtab, &old_rmtab); - goto out; - } - - /* Save the current cluster-specific list */ - rmtab_move(&old_pruned, pruned_rmtab); - - if (rmtab_copy_bypath(pruned_rmtab, rmtab, path) == -1) { - clulog(LOG_ERR, "#17: Failed to prune rmtab: %s\n", - strerror(errno)); - - /* - * Since we couldn't build a new list, restore the old - * one. Otherwise, next time, we'd send a weird diff to - * our peer with all entries as "added". - */ - rmtab_move(pruned_rmtab, &old_pruned); - goto out; - } - - if (!diff) { - rv = 1; - goto out; - } - - /* find the differences */ - if (rmtab_diff(old_pruned, *pruned_rmtab, diff)) { - clulog(LOG_ERR, "Failed to diff rmtab: %s\n", strerror(errno)); - goto out; - } - - if (!*diff) { - /* No differences */ - rv = 1; - goto out; - } - - rv = 0; - out: - /* stick a finger in the memory dike */ - rmtab_kill(&old_rmtab); /* these will be NOPs if NULL */ - rmtab_kill(&old_pruned); - - return rv; -} - - - - -/* **************** * - * SIGNAL HANDLERS! - * **************** */ - -/** - * INT, USR1, USR2 handler. - * - * What these signals actually do is interrupt the select(2) we enter when we - * call sleep(). Effectively, this causes sleep() to short out, and makes - * us drop down into rmtab_get_update() - causing us to re-check and sync - * changes if there are any. The service script, svclib_nfs, sends us a - * TERM whenever it receives the request to stop a service (which happens - * when the service manager relocates as well), thus, when a service is - * disabled or relocates to the other node, clurmtabd syncs immediately its - * current state to the other node, preventing a timing window between - * "service relocate" and "rmtabd update" during which a client could - * receive ESTALE. - */ -static void -sh_sync(int sig) -{ - clulog(LOG_DEBUG, "Signal %d received; syncing ASAP\n", sig); -} - - -/** - * QUIT, TERM - * - * In this case, we go down ASAP. But first, we sync. These will, like the - * above, short-out msg_accept_timeout() and drop down for that one last - * sync. - */ -static void -sh_exit(int sig) -{ - clulog(LOG_DEBUG, "Signal %d received; exiting\n", sig); - exiting = 1; -} - - -/** - * HUP - * - * Traditional behavior. Reconfigure on SIGHUP. - */ -static void -sh_reconfigure(int sig) -{ - clulog(LOG_DEBUG, "Re-reading the cluster database\n"); - rmtabd_reconfigure(); -} - - -/** - * Set up signal handlers. - */ -static inline void -register_sighandlers(void) -{ - sigset_t set; - struct sigaction act; - - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGUSR1); - sigaddset(&set, SIGUSR2); - - sigaddset(&set, SIGHUP); - - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGQUIT); - - sigaddset(&set, SIGILL); - sigaddset(&set, SIGIO); - sigaddset(&set, SIGSEGV); - sigaddset(&set, SIGBUS); - - sigprocmask(SIG_UNBLOCK, &set, NULL); - - memset(&act, 0, sizeof (act)); - sigemptyset(&act.sa_mask); - - /* In some cases, just continue */ - act.sa_handler = sh_sync; - - sigaction(SIGINT, &act, NULL); - sigaction(SIGUSR1, &act, NULL); - sigaction(SIGUSR2, &act, NULL); - - /* Ok, reconfigure here */ - act.sa_handler = sh_reconfigure; - sigaction(SIGHUP, &act, NULL); - - /* Exit signals */ - act.sa_handler = sh_exit; - sigaction(SIGTERM, &act, NULL); - sigaction(SIGQUIT, &act, NULL); -} - -/* ******************************* * - * Configuration Utility Functions - * ******************************* */ - -/** - * Retrieve an integer parameter from the config file. - * - * @param str config token - * @param val return value - * @param dflt Default integer value. - * @return 0 s - */ -#if 0 -static inline int -__get_int_param(char *str, int *val, int dflt) -{ - char *value; - int ret; - - ret = CFG_Get(str, NULL, &value); - - switch (ret) { - case CFG_DEFAULT: - *val = dflt; - break; - case CFG_OK: - *val = atoi(value); - break; - default: - clulog(LOG_ERR, "#19: Cannot get "%s" from database; " - "CFG_Get() failed, err=%d\n", ret); - return 0; - } - - return 0; -} -#endif - - -/** - * Gets the loglevel of rmtabd - */ -static int -get_rmtabd_loglevel(int *level) -{ -#if 0 - return __get_int_param(LOGLEVEL_STR, level, LOG_DEFAULT); -#endif - return LOG_INFO; -} - - -/** - * Retrieves the polling interval, in seconds, of _RMTAB_PATH from the cluster - * configuration database. - */ -static int -get_rmtabd_pollinterval(int *interval) -{ -#if 0 - return __get_int_param(POLLINT_STR, interval, POLLINT_DEFAULT); -#endif - return POLLINT_DEFAULT; -} - - -/** - * This is called at init and by sh_reconfigure and sets up daemon-specific - * configuration params. - */ -static void -rmtabd_reconfigure(void) -{ - int level, old_level, old_interval; - - /* loglevel */ - old_level = clu_get_loglevel(); - get_rmtabd_loglevel(&level); - - if (old_level != level) { - if (clu_set_loglevel(level) == -1) - clulog(LOG_ERR, "#20: Failed set log level\n"); - else - clulog(LOG_DEBUG, "Log level is now %d\n", level); - } - - /* rmtabd polling interval (tw33k4bl3) */ - old_interval = poll_interval; - get_rmtabd_pollinterval(&poll_interval); - - /* bounds-check */ - if (poll_interval < 1) - poll_interval = 1; - else if (poll_interval > 10) - poll_interval = 10; - - if (old_interval != poll_interval) { - clulog_and_print(LOG_DEBUG, - "Polling interval is now %d seconds\n", - poll_interval); - } -} - - -/** - * Set up local parameters & signal handlers. - */ -static int -rmtabd_config_init(void) -{ - /* Yes, it does this twice */ -#if 0 - if (CFG_ReadFile(CLU_CONFIG_FILE) != CFG_OK) - return -1; -#endif - - rmtabd_reconfigure(); - register_sighandlers(); - return 0; -} - - -/** - * Initializes and synchronizes /var/lib/nfs/rmtab with - * [path]/.clumanager/rmtab. - * - * @param path Path to mount point we're monitoring. - * @param rmtab Will contain full rmtab upon exit. - * @param pruned_rmtab Will contain rmtab entries we care about on exit. - */ -int -rmtab_init(char *path, rmtab_node **rmtab, rmtab_node **pruned_rmtab) -{ - char buf[PATH_MAX]; - - snprintf(buf, sizeof(buf), "%s/%s", path, CM_NFS_DIR); - - if ((mkdir(buf, 0700) == -1) && (errno != EEXIST)) { - clulog_and_print(LOG_ERR, "#21: Couldn't read/create %s: %s\n", - buf, strerror(errno)); - return -1; - } - - snprintf(buf, sizeof(buf), "%s/%s/rmtab", path, CM_NFS_DIR); - - if (rmtab_read(rmtab, buf) == -1) { - clulog_and_print(LOG_ERR, "#22: Failed to read %s: %s\n", buf, - strerror(errno)); - return -1; - } - - /* - * Read into the same pointer -> inserting each node will - * cause the nodes with the greater count to be kept. - */ - if (rmtab_read(rmtab, _PATH_RMTAB) == -1) { - clulog_and_print(LOG_ERR, "#23: Failed to read %s: %s\n", - _PATH_RMTAB, strerror(errno)); - return -1; - } - - /* - * Prune by our path - */ - if (rmtab_copy_bypath(pruned_rmtab, rmtab, path) == -1) { - clulog_and_print(LOG_ERR, "#24: Failed to prune rmtab: %s\n", - strerror(errno)); - return -1; - } - - /* - * XXX could lose a mount if rpc.mountd writes a file before - * we rewrite the file. - */ - if (rmtab_write_atomic(*rmtab, _PATH_RMTAB) == -1) { - clulog_and_print(LOG_ERR, "#25: Failed to write %s: %s\n", - _PATH_RMTAB, strerror(errno)); - return -1; - } - /* - * Write new contents. - */ - if (rmtab_write_atomic(*pruned_rmtab, buf) == -1) { - clulog_and_print(LOG_ERR, "#26: Failed to write %s: %s\n", buf, - strerror(errno)); - return -1; - } - - return 0; -} - - -/** - * Fork off into the background and store our pid file in - * [path]/.clumanager/pid - * - * @param path Mount point we're monitoring. - * @return -1 on failure, 0 on success. - */ -static int -daemonize(char *path) -{ - FILE *fp=NULL; - char filename[PATH_MAX]; - - if (daemon(0,0) == -1) - return -1; - - memset(filename,0,PATH_MAX); - snprintf(filename, sizeof(filename), "%s/%s/pid", path, CM_NFS_DIR); - - fp = fopen(filename, "w"); - if (fp == NULL) { - clulog(LOG_WARNING, "#63: Couldn't write PID!\n"); - } - - fprintf(fp, "%d", getpid()); - fclose(fp); - - return 0; -} - - -/** - * main - * - * Main. Main. Main. Main. Main. Main. Main. Main. Main. Main. - */ -int -main(int argc, char **argv) -{ - char path[PATH_MAX]; - char rmtab_priv[PATH_MAX]; - - rmtab_node *rmtab = NULL, *pruned_rmtab = NULL, *diff = NULL; - - if (argc < 2) { - fprintf(stderr, "usage: clurmtabd <mount-point>\n"); - return -1; - } - - /* Set up configuration parameters */ - if (rmtabd_config_init() == -1) { - clulog_and_print(LOG_ERR, - "#27: Couldn't initialize - exiting\n"); - return -1; - } - - /* Set up our internal variables */ - snprintf(path, sizeof(path), "%s", argv[1]); - snprintf(rmtab_priv, sizeof(rmtab_priv), "%s/%s/rmtab", path, - CM_NFS_DIR); - - /* - * Synchronize the rmtab files - * - * We do this before we call daemonize() to ensure that when - * the service script calls exportfs, /var/lib/nfs/rmtab has - * all the necessary entries. - */ - if (rmtab_init(path, &rmtab, &pruned_rmtab) == -1) { - clulog_and_print(LOG_WARNING, - "#64: Could not validate %s\n", path); - clulog_and_print(LOG_WARNING, - "#65: NFS Failover of %s will malfunction\n", - path); - return -1; - } - - /* Jump off into the background */ - if (daemonize(path) == -1) { - clulog_and_print(LOG_ERR, "#28: daemonize: %s\n", - strerror(errno)); - return -1; - } - - /* Main loop */ - while (!exiting) { - - /* Snooze a bit */ - sleep(poll_interval); - - /* Check for updates */ - if (rmtab_get_update(&rmtab, &pruned_rmtab, &diff, path) - == 0) { - /* Handle updates */ - rmtab_merge(&pruned_rmtab, diff); - rmtab_kill(&diff); - if (rmtab_write_atomic(pruned_rmtab, rmtab_priv) == -1) - clulog(LOG_ERR, - "#29: rmtab_write_atomic: %s\n", - strerror(errno)); - } - } - - return 0; -} diff --git a/rgmanager/src/daemons/clurmtabd_lib.c b/rgmanager/src/daemons/clurmtabd_lib.c deleted file mode 100644 index 29fcd42..0000000 --- a/rgmanager/src/daemons/clurmtabd_lib.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Implements rmtab read/write/list handling functions utilized by - * clurmtabd. - * - * Author: Lon H. Hohberger <lhh at redhat.com> - * - * This was written for two reasons: - * (1) The nfs-utils code was difficult to adapt to the requirements, and - * (2) to prevent cross-breeding of nfs-utils with clumanager. - * - * So, in a sense, this is a re-invention of the wheel, but it keeps the - * pacakges separate, thus easing maintenance by lessening the number of - * patches and code forks required for Enterprise Linux. - */ -#include <platform.h> -#include <stdlib.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/param.h> -#include <unistd.h> -#include <rmtab.h> -#include <libgen.h> - -/* - * Function Prototypes - */ -static int fp_lock(FILE *fp, int type); -static int fp_unlock(FILE *fp); -static inline void un_diffize(rmtab_node *dest, rmtab_node *src); - - -/* - * free an rmtab node - */ -void -rmtab_free(rmtab_node *ptr) -{ - if(ptr->rn_hostname) - free(ptr->rn_hostname); - if(ptr->rn_path) - free(ptr->rn_path); - free(ptr); -} - - -/* - * take advisory lock. Retry until we're blue in the face. - */ -static int -fp_lock(FILE *fp, int type) -{ - int fd; - struct flock flock; - - fd = fileno(fp); - memset(&flock,0,sizeof(flock)); - - /* Lock. */ - flock.l_type = type; - while (fcntl(fd, F_SETLK, &flock) == -1) { - if ((errno != EAGAIN) && (errno != EACCES)) - return -1; - - usleep(10000); - } - - return 0; -} - - -/* - * unlock... - */ -static int -fp_unlock(FILE *fp) -{ - int fd = fileno(fp); - struct flock flock; - - memset(&flock,0,sizeof(flock)); - flock.l_type = F_UNLCK; - return fcntl(fd, F_SETLK, &flock); -} - - -/* - * Inserts a node into the list in ASCII-sorted order; rnew must have been - * a user-allocated chunk of memory. (static = big nono) - */ -int -__rmtab_insert(rmtab_node **head, rmtab_node *rnew) -{ - rmtab_node *back, *curr; - int rv = 1; - - /* insert as first entry */ - if (!(*head) || (rv = rmtab_cmp_min(rnew, *head)) < 0) { - rnew->rn_next = *head; - *head = rnew; - return 0; - } - - /* Duplicate match? */ - if (!rv) { - if ((*head)->rn_count < rnew->rn_count) - (*head)->rn_count = rnew->rn_count; - return 1; - } - - /* Standard insert - not beginning, not end. */ - back = NULL; - curr = *head; - while (curr) { - /* Insert before current */ - if ((rv = rmtab_cmp_min(rnew, curr)) < 0) { - back->rn_next = rnew; - rnew->rn_next = curr; - return 0; - } - - /* Duplicate match? Snag the greater count. */ - if (!rv) { - if (curr->rn_count < rnew->rn_count) - curr->rn_count = rnew->rn_count; - return 0; - } - - /* Loopy loopy */ - back = curr; - curr = curr->rn_next; - } - - /* Tack on at end of list */ - back->rn_next = rnew; - - return 0; -} - - -/* - * Inserts a node into the list in ASCII-sorted order; rnew must have been - * a user-allocated chunk of memory. (static = big nono) - */ -int -__rmtab_insert_after(rmtab_node *pre, rmtab_node *rnew) -{ - rmtab_node *back, *curr; - int rv = 1; - - /* insert as first entry */ - if ((rv = rmtab_cmp_min(rnew, pre)) < 0) { - return -1; - } - - /* Duplicate match? */ - if (!rv) { - if (pre->rn_count < rnew->rn_count) - pre->rn_count = rnew->rn_count; - return 1; - } - - /* Standard insert - not beginning, not end. */ - back = NULL; - curr = pre; - while (curr) { - /* Insert before current */ - if ((rv = rmtab_cmp_min(rnew, curr)) < 0) { - back->rn_next = rnew; - rnew->rn_next = curr; - return 0; - } - - /* Duplicate match? Snag the greater count. */ - if (!rv) { - if (curr->rn_count < rnew->rn_count) - curr->rn_count = rnew->rn_count; - return 0; - } - - /* Loopy loopy */ - back = curr; - curr = curr->rn_next; - } - - /* Tack on at end of list */ - back->rn_next = rnew; - - return 0; -} - - -/* - * Inserts (host,path) rmtab into a list pointed to by **head - */ -rmtab_node * -rmtab_insert(rmtab_node **head, rmtab_node *pre, char *host, - char *path, int count) -{ - rmtab_node *rnew; - - /* simple bounds-checking */ - if (!head || !host || !path || !strlen(host) || !strlen(path)) - return NULL; - - /* Copy in info */ - rnew = malloc(sizeof(*rnew)); - memset(rnew, 0, sizeof(*rnew)); - rnew->rn_hostname = strdup(host); - rnew->rn_path = strdup(path); - rnew->rn_count = count; - - if (pre) { - /* We got a preceding node... try to insert */ - switch(__rmtab_insert_after(pre, rnew)) { - case -1: - /* Failed insert after... try before? */ - break; - case 0: - goto out; - case 1: - rmtab_free(rnew); - rnew = NULL; - goto out; - } - } - - - /* Insert into our list officially */ - if (__rmtab_insert(head, rnew) == 1) { - /* Duplicate match */ - rmtab_free(rnew); - rnew = NULL; - } - -out: - return rnew; -} - - -/* - * removes a node based on contents of *entry - * user must free memory, if applicable. - */ -rmtab_node * -__rmtab_remove(rmtab_node **head, rmtab_node *entry) -{ - int rv = -1; - rmtab_node *curr, *back; - - back = NULL; curr = *head; - - for (curr = *head, back = NULL; - (rv = rmtab_cmp_min(curr, entry)) < 0; - back = curr, curr = curr->rn_next); - - /* overshot => no match */ - if (rv != 0) - return NULL; - - if (back) { - back->rn_next = curr->rn_next; - curr->rn_next = NULL; - return curr; - } - - /* no back pointer = first node in list. */ - back = curr; - *head = curr->rn_next; - back->rn_next = NULL; - return back; -} - - -/* - * removes an entry in the list; user must free. - */ -rmtab_node * -rmtab_remove(rmtab_node **head, char *host, char *path) -{ - rmtab_node tmp; - rmtab_node *ret; - - /* Wrappers, wrappers */ - memset(&tmp, 0, sizeof(tmp)); - if (host) - tmp.rn_hostname = strdup(host); - if (path) - tmp.rn_path = strdup(path); - - ret = __rmtab_remove(head, &tmp); - if (tmp.rn_hostname) - free(tmp.rn_hostname); - if (tmp.rn_path) - free(tmp.rn_path); - - return ret; -} - - -/* - * Frees an entire rmtab list. - */ -void -rmtab_kill(rmtab_node **head) -{ - rmtab_node *curr, *back; - - if (!head || !*head) - return; - - curr = *head; back = NULL; - - while (curr) { - if (back) - rmtab_free(back); - back = curr; - curr = curr->rn_next; - } - - if (back) - rmtab_free(back); - - *head = NULL; -} - - -/* - * Finds the differences between two rmtabs. This is generally called when - * we read our file locally. The diff outputs in **diff are collapsed - * noted as '<' and '>' before the hostname, eg - * - * <boris /tmp 1 - * >dragracer /tmp2 1 - */ -int -rmtab_diff(rmtab_node *old, rmtab_node *new, rmtab_node **diff) -{ - rmtab_node *old_curr, *new_curr, *last = NULL; - int rv; - char buf[MAXHOSTNAMELEN]; - - if (!diff) - return -1; - - old_curr = old; - new_curr = new; - - /* This loop will exit when the first list is exhausted. */ - while (old_curr && new_curr) { - - /* Entries the same. */ - if (!(rv = rmtab_cmp(old_curr, new_curr))) { - old_curr = old_curr->rn_next; - new_curr = new_curr->rn_next; - continue; - } - - /* Old < new = deleted entry */ - if (rv < 0) { - snprintf(buf, sizeof(buf), "<%s", - old_curr->rn_hostname); - last = rmtab_insert(diff, last, buf, old_curr->rn_path, - old_curr->rn_count); - old_curr = old_curr->rn_next; - continue; - } - - /* old > new = new entry */ - snprintf(buf, sizeof(buf), ">%s", new_curr->rn_hostname); - last = rmtab_insert(diff, last, buf, new_curr->rn_path, - new_curr->rn_count); - new_curr = new_curr->rn_next; - } - - /* Meaning only one of the two following loops actually is executed:*/ - - /* Add remaining stuff in 'old' to 'deleted' list */ - for (;old_curr; old_curr = old_curr->rn_next) { - snprintf(buf, sizeof(buf), "<%s", old_curr->rn_hostname); - last = rmtab_insert(diff, last, buf, old_curr->rn_path, - old_curr->rn_count); - } - - /* Add remaining stuff in 'new' to 'added' list. */ - for (;new_curr; new_curr = new_curr->rn_next) { - snprintf(buf, sizeof(buf), ">%s", new_curr->rn_hostname); - last = rmtab_insert(diff, last, buf, new_curr->rn_path, - new_curr->rn_count); - } - - return 0; -} - - -/* - * strips the "diff" character ('>' || '<') from the beginning of the hostname - * in *src and stores the resulting stuff in *dest. - */ -static inline void -un_diffize(rmtab_node *dest, rmtab_node *src) -{ - dest->rn_hostname = strdup(&src->rn_hostname[1]); - dest->rn_path = strdup(src->rn_path); - dest->rn_count = src->rn_count; - dest->rn_next = NULL; -} - - -/* - * Merges 'patch' list with **head. - * Modifies list in **head; leaves *patch unchanged. This is generally - * called when we receive an update from a peer. - */ -int -rmtab_merge(rmtab_node **head, rmtab_node *patch) -{ - rmtab_node *curr, *oldp = NULL, *last = NULL; - rmtab_node tmpnode; - int rv = -1; - - /* Delete all matching entries */ - for (curr = patch; curr; curr = curr->rn_next) { - - un_diffize(&tmpnode, curr); - - if (curr->rn_hostname[0] == '<') { - if ((oldp = __rmtab_remove(head, &tmpnode))) { - rmtab_free(oldp); - oldp = NULL; - } - } else if (curr->rn_hostname[0] == '>') { - if ((last = rmtab_insert(head, last, - tmpnode.rn_hostname, - tmpnode.rn_path, - tmpnode.rn_count)) == NULL) { - rv = -1; - break; - } - } else { - /* EEEEEKKKK */ - rv = -1; - break; - } - - /* - * Free anything we allocated - */ - if (tmpnode.rn_hostname) { - free(tmpnode.rn_hostname); - tmpnode.rn_hostname = NULL; - } - if (tmpnode.rn_path) { - free(tmpnode.rn_path); - tmpnode.rn_path = NULL; - } - } - - if (tmpnode.rn_hostname) - free(tmpnode.rn_hostname); - if (tmpnode.rn_path) - free(tmpnode.rn_path); - - return 0; -} - - -/* - * Builds a list by parsing an rmtab in *fp... pretty simple - */ -int -rmtab_import(rmtab_node **head, FILE *fp) -{ - int n = 0; - char line[MAXPATHLEN]; - char *hostname, *path, *cnt; - int count = 0; - rmtab_node *last = NULL; - - if (!fp || !head) - return 0; - - if (fp_lock(fp, F_RDLCK) == -1) { - perror("fplock"); - return -1; - } - - while (fgets(line,sizeof(line),fp) != NULL) { - hostname = strtok(line, ":"); - path = strtok(NULL, ":"); - - /* mount count corresponding to the entry */ - cnt = strtok(NULL, ":"); - if (cnt) - count = strtol(cnt, NULL, 0); - - if (!hostname || !path || !count) - /* End - malformed last line */ - break; - - if ((last = rmtab_insert(head, last, hostname, path, - count)) != NULL) - n++; - } - - fp_unlock(fp); - return n; -} - - -/* - * Writes rmtab to export file *fp - */ -int -rmtab_export(rmtab_node *head, FILE *fp) -{ - rmtab_node *curr; - - /* - * lhh - fix - we removed the check for !head, because we _CAN_ have - * an empty /var/lib/nfs/rmtab!! - */ - if (!fp) - return -1; - - if (fp_lock(fp, F_WRLCK) == -1) - return -1; - - for (curr = head; curr; curr = curr->rn_next) - fprintf(fp,"%s:%s:0x%08x\n",curr->rn_hostname, curr->rn_path, - curr->rn_count); - - fp_unlock(fp); - return 0; -} - - -/* - * - */ -int -rmtab_read(rmtab_node **head, char *filename) -{ - FILE *fp; - int rv = 0; - int esave = 0; - - if (!filename || !strlen(filename)) - return -1; - - fp = fopen(filename, "r"); - if (!fp) { - /* It's ok if it's not there. */ - if (errno == ENOENT) { - close(open(filename, O_WRONLY|O_SYNC|O_CREAT)); - return 0; - } - perror("fopen"); - return -1; - } - - rv = rmtab_import(head, fp); - esave = errno; - - fclose(fp); - errno = esave; - return rv; -} - - -/* - * Writes rmtab list in *head to *filename; in an atomic fashion - */ -int -rmtab_write_atomic(rmtab_node *head, char *filename) -{ - char tmpfn[MAXPATHLEN], - oldfn[MAXPATHLEN], - realfn[MAXPATHLEN]; - FILE *fp; - int len, tfd, ofd; - int rv = -1; - - memset(realfn, 0, sizeof(realfn)); - memset(oldfn, 0, sizeof(oldfn)); - memset(tmpfn, 0, sizeof(tmpfn)); - - len = strlen(filename); - if (len > (MAXPATHLEN - 1)) - len = MAXPATHLEN - 1; - - memcpy(realfn, filename, len); - - /* chop off the end - GLIBC modifies the argument here */ - dirname(realfn); - - snprintf(oldfn, sizeof(oldfn), "%s/tmp.XXXXXX", realfn); - snprintf(tmpfn, sizeof(tmpfn), "%s/tmp.XXXXXX", realfn); - - if ((ofd = mkstemp(oldfn)) == -1) - return -1; - if ((tfd = mkstemp(tmpfn)) == -1) { - close(ofd); - unlink(oldfn); - return -1; - } - - /* Kill the file so we can link it (else it'll not work) */ - close(ofd); - unlink(oldfn); - - /* set up the link */ - if (link(filename, oldfn) == -1) - goto fail; - - /* Export the file. Yes, we have two fd's on it now. That's ok :) */ - if (!(fp = fopen(tmpfn, "w"))) - goto fail; - - if (rmtab_export(head, fp) == -1) - goto fail; - - fsync(fileno(fp)); - fclose(fp); - - /* atomic update */ - if (rename(tmpfn, filename) == -1) - goto fail; - - if (unlink(oldfn) == -1) - goto fail; - - rv = 0; -fail: - close(tfd); - - return rv; -} - - -/* - * Well, 1106 bytes per transaction is a bit much, especially for - * busy nfs clusters... so, we invent 'compact', which simply eliminates - * all dead data. We basically have two strings + their trailing NULLs, - * and one int (the mount count) - */ -size_t -rmtab_pack_size(rmtab_node *head) -{ - rmtab_node *curr; - size_t total = 0; - - for (curr = head; curr; curr = curr->rn_next) { - /* leave space for NULLs */ - total += strlen(curr->rn_hostname) + 1; - total += strlen(curr->rn_path) + 1; - total += sizeof(curr->rn_count); /* uint32_t */ - } - - return total; -} - - -/* - * rmtab_pack - * - * stores the list in *head in *buf - packed as much as possible without - * actually employing compression. - * - * host.domain.com\0/usr/src\0####host2.domain.com\0/usr/src\0#### - */ -int -rmtab_pack(char *buf, rmtab_node *head) -{ - int n = 0; - char *bptr = buf; - rmtab_node *curr; - size_t len; - uint32_t c_tmp; - - /* Pass 2 */ - for (curr = head; curr; curr = curr->rn_next) { - /* Hostname */ - len = strlen(curr->rn_hostname); - memcpy(bptr, curr->rn_hostname, len); - bptr[len] = 0; - bptr += (len + 1); /* space for the NULL */ - - /* path */ - len = strlen(curr->rn_path); - memcpy(bptr, curr->rn_path, len); - bptr[len] = 0; - bptr += (len + 1); - - /* count */ - len = sizeof(curr->rn_count); - - /* Flip-endianness */ - c_tmp = curr->rn_count; /* uint32_t! */ - swab32(c_tmp); - - memcpy(bptr, &c_tmp, len); - bptr += len; - - n++; - } - - return n; -} - - -/* - * rmtab_unpack - * .... reverse of rmtab_pack. - */ -int -rmtab_unpack(rmtab_node **head, char *src, size_t srclen) -{ - int n = 0; - char *hostp, *pathp; - uint32_t *countp; - size_t len; - size_t total = 0; - rmtab_node *last = NULL; - - if (!src[0]) - return 0; - - hostp = src; - - while (total < srclen) { - len = strlen(hostp) + 1; - pathp = hostp + len; - - len += strlen(pathp) + 1; - - /* flip-endianness if require */ - countp = (uint32_t *)(hostp + len); - swab32(*countp); - - len += sizeof(uint32_t); - - if ((last = rmtab_insert(head, NULL, hostp, pathp, - *countp)) == NULL) - return -1; - - hostp += len; - total += len; - - n++; - } - - return n; -} - - -int -rmtab_cmp_min(rmtab_node *left, rmtab_node *right) -{ - int rv = 0; - - if (!left || !right) - return ( !!right - !!left ); - - if ((rv = strcmp(left->rn_hostname, right->rn_hostname))) - return rv; - - return (strcmp(left->rn_path, right->rn_path)); -} - - -/* - * Compares two rmtab_nodes. - */ -int -rmtab_cmp(rmtab_node *left, rmtab_node *right) -{ - int rv; - - if ((rv = rmtab_cmp_min(left,right))) - return rv; - - if (left->rn_count > right->rn_count) - return -1; - - return (left->rn_count < right->rn_count); -} - - -/* - * Kill an old rmtab in dest and overwrite with *src. - */ -int -rmtab_move(rmtab_node **dest, rmtab_node **src) -{ - rmtab_kill(dest); - - *dest = *src; - *src = NULL; - - return 0; -} - - -#ifdef DEBUG -/* - * prints the contents of **head - */ -int -rmtab_dump(rmtab_node *head) -{ - rmtab_node *curr; - - for (curr = head; curr; curr = curr->rn_next) - printf("%s:%s:0x%08x\n",curr->rn_hostname,curr->rn_path, - curr->rn_count); - return 0; -} -#endif - diff --git a/rgmanager/src/daemons/event_config.c b/rgmanager/src/daemons/event_config.c deleted file mode 100644 index c679866..0000000 --- a/rgmanager/src/daemons/event_config.c +++ /dev/null @@ -1,540 +0,0 @@ -/** - Copyright Red Hat, Inc. 2002-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * CCS event parsing, based on failover domain parsing - */ -#include <string.h> -#include <list.h> -#include <clulog.h> -#include <resgroup.h> -#include <restart_counter.h> -#include <reslist.h> -#include <ccs.h> -#include <pthread.h> -#include <stdlib.h> -#include <stdio.h> -#include <reslist.h> -#include <ctype.h> -#include <event.h> - -#define CONFIG_NODE_ID_TO_NAME \ - "/cluster/clusternodes/clusternode[@nodeid="%d"]/@name" -#define CONFIG_NODE_NAME_TO_ID \ - "/cluster/clusternodes/clusternode[@name="%s"]/@nodeid" - -void deconstruct_events(event_table_t **); -void print_event(event_t *ev); - -//#define DEBUG - -#ifdef DEBUG -#define ENTER() clulog(LOG_DEBUG, "ENTER: %s\n", __FUNCTION__) -#define RETURN(val) {\ - clulog(LOG_DEBUG, "RETURN: %s line=%d value=%d\n", __FUNCTION__, \ - __LINE__, (val));\ - return(val);\ -} -#else -#define ENTER() -#define RETURN(val) return(val) -#endif - -#ifdef NO_CCS -#define ccs_get(fd, query, ret) conf_get(query, ret) -#endif - -/* - <events> - <event name="helpful_name_here" class="node" - node="nodeid|nodename" nodestate="up|down"> - slang_script_stuff(); - start_service(); - </event> - </events> - */ -int -event_match(event_t *pattern, event_t *actual) -{ - if (pattern->ev_type != EVENT_NONE && - actual->ev_type != pattern->ev_type) - return 0; - - /* If there's no event class specified, the rest is - irrelevant */ - if (pattern->ev_type == EVENT_NONE) - return 1; - - switch(pattern->ev_type) { - case EVENT_NODE: - if (pattern->ev.node.ne_nodeid >= 0 && - actual->ev.node.ne_nodeid != - pattern->ev.node.ne_nodeid) { - return 0; - } - if (pattern->ev.node.ne_local >= 0 && - actual->ev.node.ne_local != - pattern->ev.node.ne_local) { - return 0; - } - if (pattern->ev.node.ne_state >= 0 && - actual->ev.node.ne_state != - pattern->ev.node.ne_state) { - return 0; - } - if (pattern->ev.node.ne_clean >= 0 && - actual->ev.node.ne_clean != - pattern->ev.node.ne_clean) { - return 0; - } - return 1; /* All specified params match */ - case EVENT_RG: - if (pattern->ev.group.rg_name[0] && - strcasecmp(actual->ev.group.rg_name, - pattern->ev.group.rg_name)) { - return 0; - } - if (pattern->ev.group.rg_state != (uint32_t)-1 && - actual->ev.group.rg_state != - pattern->ev.group.rg_state) { - return 0; - } - if (pattern->ev.group.rg_owner >= 0 && - actual->ev.group.rg_owner != - pattern->ev.group.rg_owner) { - return 0; - } - return 1; - case EVENT_CONFIG: - if (pattern->ev.config.cfg_version >= 0 && - actual->ev.config.cfg_version != - pattern->ev.config.cfg_version) { - return 0; - } - if (pattern->ev.config.cfg_oldversion >= 0 && - actual->ev.config.cfg_oldversion != - pattern->ev.config.cfg_oldversion) { - return 0; - } - return 1; - case EVENT_USER: - if (pattern->ev.user.u_name[0] && - strcasecmp(actual->ev.user.u_name, - pattern->ev.user.u_name)) { - return 0; - } - if (pattern->ev.user.u_request != 0 && - actual->ev.user.u_request != - pattern->ev.user.u_request) { - return 0; - } - if (pattern->ev.user.u_target != 0 && - actual->ev.user.u_target != - pattern->ev.user.u_target) { - return 0; - } - return 1; - default: - break; - } - - return 0; -} - - -char * -ccs_node_id_to_name(int ccsfd, int nodeid) -{ - char xpath[256], *ret = 0; - - snprintf(xpath, sizeof(xpath), CONFIG_NODE_ID_TO_NAME, - nodeid); - if (ccs_get(ccsfd, xpath, &ret) == 0) - return ret; - return NULL; -} - - -int -ccs_node_name_to_id(int ccsfd, char *name) -{ - char xpath[256], *ret = 0; - int rv = 0; - - snprintf(xpath, sizeof(xpath), CONFIG_NODE_NAME_TO_ID, - name); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - rv = atoi(ret); - free(ret); - return rv; - } - return 0; -} - - -static void -deconstruct_event(event_t *ev) -{ - if (ev->ev_script) - free(ev->ev_script); - if (ev->ev_name) - free(ev->ev_name); - free(ev); -} - - -static int -get_node_event(int ccsfd, char *base, event_t *ev) -{ - char xpath[256], *ret = NULL; - - /* Clear out the possibilitiies */ - ev->ev.node.ne_nodeid = -1; - ev->ev.node.ne_local = -1; - ev->ev.node.ne_state = -1; - ev->ev.node.ne_clean = -1; - - snprintf(xpath, sizeof(xpath), "%s/@node_id", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev.node.ne_nodeid = atoi(ret); - free(ret); - if (ev->ev.node.ne_nodeid <= 0) - return -1; - } else { - /* See if there's a node name */ - snprintf(xpath, sizeof(xpath), "%s/@node", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev.node.ne_nodeid = - ccs_node_name_to_id(ccsfd, ret); - free(ret); - if (ev->ev.node.ne_nodeid <= 0) - return -1; - } - } - - snprintf(xpath, sizeof(xpath), "%s/@node_state", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - if (!strcasecmp(ret, "up")) { - ev->ev.node.ne_state = 1; - } else if (!strcasecmp(ret, "down")) { - ev->ev.node.ne_state = 0; - } else { - ev->ev.node.ne_state = !!atoi(ret); - } - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/@node_clean", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev.node.ne_clean = !!atoi(ret); - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/@node_local", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev.node.ne_local = !!atoi(ret); - free(ret); - } - - return 0; -} - - -static int -get_rg_event(int ccsfd, char *base, event_t *ev) -{ - char xpath[256], *ret = NULL; - - /* Clear out the possibilitiies */ - ev->ev.group.rg_name[0] = 0; - ev->ev.group.rg_state = (uint32_t)-1; - ev->ev.group.rg_owner = -1; - - snprintf(xpath, sizeof(xpath), "%s/@service", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - strncpy(ev->ev.group.rg_name, ret, - sizeof(ev->ev.group.rg_name)); - free(ret); - if (!strlen(ev->ev.group.rg_name)) { - return -1; - } - } - - snprintf(xpath, sizeof(xpath), "%s/@service_state", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - if (!isdigit(ret[0])) { - ev->ev.group.rg_state = - rg_state_str_to_id(ret); - } else { - ev->ev.group.rg_state = atoi(ret); - } - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/@service_owner", base); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - if (!isdigit(ret[0])) { - ev->ev.group.rg_owner = - ccs_node_name_to_id(ccsfd, ret); - } else { - ev->ev.group.rg_owner = !!atoi(ret); - } - free(ret); - } - - return 0; -} - - -static int -get_config_event(int __attribute__((unused)) ccsfd, - char __attribute__((unused)) *base, - event_t __attribute__((unused)) *ev) -{ - errno = ENOSYS; - return -1; -} - - -static event_t * -get_event(int ccsfd, char *base, int idx, int *_done) -{ - event_t *ev; - char xpath[256]; - char *ret = NULL; - - *_done = 0; - snprintf(xpath, sizeof(xpath), "%s/event[%d]/@name", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) != 0) { - *_done = 1; - return NULL; - } - - ev = malloc(sizeof(*ev)); - if (!ev) - return NULL; - memset(ev, 0, sizeof(*ev)); - ev->ev_name = ret; - - /* Get the script file / inline from config */ - ret = NULL; - snprintf(xpath, sizeof(xpath), "%s/event[%d]/@file", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev_script_file = ret; - } else { - snprintf(xpath, sizeof(xpath), "%s/event[%d]", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev_script = ret; - } else { - goto out_fail; - } - } - - /* Get the priority ordering (must be nonzero) */ - ev->ev_prio = 99; - ret = NULL; - snprintf(xpath, sizeof(xpath), "%s/event[%d]/@priority", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - ev->ev_prio = atoi(ret); - if (ev->ev_prio <= 0 || ev->ev_prio > EVENT_PRIO_COUNT) { - clulog(LOG_ERR, - "event %s: priority %s invalid\n", - ev->ev_name, ret); - goto out_fail; - } - free(ret); - } - - /* Get the event class */ - snprintf(xpath, sizeof(xpath), "%s/event[%d]/@class", - base, idx); - ret = NULL; - if (ccs_get(ccsfd, xpath, &ret) == 0) { - snprintf(xpath, sizeof(xpath), "%s/event[%d]", - base, idx); - if (!strcasecmp(ret, "node")) { - ev->ev_type = EVENT_NODE; - if (get_node_event(ccsfd, xpath, ev) < 0) - goto out_fail; - } else if (!strcasecmp(ret, "service") || - !strcasecmp(ret, "resource") || - !strcasecmp(ret, "rg") ) { - ev->ev_type = EVENT_RG; - if (get_rg_event(ccsfd, xpath, ev) < 0) - goto out_fail; - } else if (!strcasecmp(ret, "config") || - !strcasecmp(ret, "reconfig")) { - ev->ev_type = EVENT_CONFIG; - if (get_config_event(ccsfd, xpath, ev) < 0) - goto out_fail; - } else { - clulog(LOG_ERR, - "event %s: class %s unrecognized\n", - ev->ev_name, ret); - goto out_fail; - } - - free(ret); - ret = NULL; - } - - return ev; -out_fail: - if (ret) - free(ret); - deconstruct_event(ev); - return NULL; -} - - -static event_t * -get_default_event(void) -{ - event_t *ev; - char xpath[1024]; - - ev = malloc(sizeof(*ev)); - if (!ev) - return NULL; - memset(ev, 0, sizeof(*ev)); - ev->ev_name = strdup("Default"); - - /* Get the script file / inline from config */ - snprintf(xpath, sizeof(xpath), "%s/default_event_script.sl", - RESOURCE_ROOTDIR); - - ev->ev_prio = 100; - ev->ev_type = EVENT_NONE; - ev->ev_script_file = strdup(xpath); - if (!ev->ev_script_file || ! ev->ev_name) { - deconstruct_event(ev); - return NULL; - } - - return ev; -} - - -/** - * similar API to failover domain - */ -int -construct_events(int ccsfd, event_table_t **events) -{ - char xpath[256]; - event_t *ev; - int x = 1, done = 0; - - /* Allocate the event list table */ - *events = malloc(sizeof(event_table_t) + - sizeof(event_t) * (EVENT_PRIO_COUNT+1)); - if (!*events) - return -1; - memset(*events, 0, sizeof(event_table_t) + - sizeof(event_t) * (EVENT_PRIO_COUNT+1)); - (*events)->max_prio = EVENT_PRIO_COUNT; - - snprintf(xpath, sizeof(xpath), - RESOURCE_TREE_ROOT "/events"); - - do { - ev = get_event(ccsfd, xpath, x++, &done); - if (ev) - list_insert(&((*events)->entries[ev->ev_prio]), ev); - } while (!done); - - ev = get_default_event(); - if (ev) - list_insert(&((*events)->entries[ev->ev_prio]), ev); - - return 0; -} - - -void -print_event(event_t *ev) -{ - printf(" Name: %s\n", ev->ev_name); - - switch(ev->ev_type) { - case EVENT_NODE: - printf(" Node %d State %d\n", (int)ev->ev.node.ne_nodeid, - ev->ev.node.ne_state); - break; - case EVENT_RG: - printf(" RG %s State %s\n", ev->ev.group.rg_name, - rg_state_str(ev->ev.group.rg_state)); - break; - case EVENT_CONFIG: - printf(" Config change - unsupported\n"); - break; - default: - printf(" (Any event)\n"); - break; - } - - if (ev->ev_script) { - printf(" Inline script.\n"); - } else { - printf(" File: %s\n", ev->ev_script_file); - } -} - - -void -print_events(event_table_t *events) -{ - int x, y; - event_t *ev; - - for (x = 0; x <= events->max_prio; x++) { - if (!events->entries[x]) - continue; - printf("Event Priority Level %d:\n", x); - list_for(&(events->entries[x]), ev, y) { - print_event(ev); - } - } -} - - -void -deconstruct_events(event_table_t **eventsp) -{ - int x; - event_table_t *events = *eventsp; - event_t *ev = NULL; - - if (!events) - return; - - for (x = 0; x <= events->max_prio; x++) { - while ((ev = (events->entries[x]))) { - list_remove(&(events->entries[x]), ev); - deconstruct_event(ev); - } - } - - free(events); - *eventsp = NULL; -} - - diff --git a/rgmanager/src/daemons/fo_domain.c b/rgmanager/src/daemons/fo_domain.c deleted file mode 100644 index be1918d..0000000 --- a/rgmanager/src/daemons/fo_domain.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Fail-over Domain & Preferred Node Ordering Driver. Ripped right from - * the clumanager 1.2 code base. - * - * April 2006 - Nofailback option added to restrict failover behavior in ordered - * + restricted failover domains by Josef Whiter - */ -#include <string.h> -#include <list.h> -#include <clulog.h> -#include <resgroup.h> -#include <restart_counter.h> -#include <reslist.h> -#include <ccs.h> -#include <pthread.h> -#include <stdlib.h> -#include <stdio.h> -#include <magma.h> -#include <sets.h> - - -//#define DEBUG - -#ifdef DEBUG -#define ENTER() clulog(LOG_DEBUG, "ENTER: %s\n", __FUNCTION__) -#define RETURN(val) {\ - clulog(LOG_DEBUG, "RETURN: %s line=%d value=%d\n", __FUNCTION__, \ - __LINE__, (val));\ - return(val);\ -} -#else -#define ENTER() -#define RETURN(val) return(val) -#endif - -#ifdef NO_CCS -#define ccs_get(fd, query, ret) conf_get(query, ret) -#endif - -/* - <failoverdomains> - <failoverdomain name="foo"> - <failoverdomainnode name="member" priority="1"/> - <failoverdomainnode name="member2" priority="1"/> - <failoverdomainnode name="member3" priority="2"/> - </failoverdomain> - </failoverdomains> - */ -int group_property_unlocked(char *, char *, char *, size_t); - -fod_node_t * -get_node(int ccsfd, char *base, int idx, fod_t *domain) -{ - fod_node_t *fodn; - char xpath[256]; - char *ret; - - snprintf(xpath, sizeof(xpath), "%s/failoverdomainnode[%d]/@name", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) != 0) - return NULL; - - list_do(&domain->fd_nodes, fodn) { - if (strcasecmp(ret, fodn->fdn_name)) - continue; - - clulog(LOG_ERR, "#30: Node %s defined multiple times in " - "domain %s\n", ret, domain->fd_name); - free(ret); - return NULL; - } while (!list_done(&domain->fd_nodes, fodn)); - - fodn = malloc(sizeof(*fodn)); - if (!fodn) - return NULL; - memset(fodn, 0, sizeof(*fodn)); - - /* Already malloc'd; simply store */ - fodn->fdn_name = ret; - fodn->fdn_prio = 0; - - snprintf(xpath, sizeof(xpath), - "/cluster/clusternodes/clusternode[@name="%s"]/@nodeid", - ret); - if (ccs_get(ccsfd, xpath, &ret) != 0) { - clulog(LOG_WARNING, "Node %s has no nodeid attribute\n", - fodn->fdn_name); - fodn->fdn_nodeid = -1; - } else { - /* 64-bit-ism on rhel4? */ - fodn->fdn_nodeid = atoi(ret); - } - - /* Don't even bother getting priority if we're not ordered (it's set - to 0 above */ - if (!(domain->fd_flags & FOD_ORDERED)) - return fodn; - - snprintf(xpath, sizeof(xpath), "%s/failoverdomainnode[%d]/@priority", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) != 0) - return fodn; - - fodn->fdn_prio = atoi(ret); - if (fodn->fdn_prio > 100 || fodn->fdn_prio <= 0) - fodn->fdn_prio = 0; - free(ret); - - return fodn; -} - - -fod_t * -get_domain(int ccsfd, char *base, int idx, fod_t **domains) -{ - fod_t *fod; - fod_node_t *fodn; - char xpath[256]; - char *ret; - int x = 1; - - snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@name", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) != 0) - return NULL; - - list_do(domains, fod) { - if (strcasecmp(fod->fd_name, ret)) - continue; - - clulog(LOG_ERR, "#31: Domain %s defined multiple times\n", - ret); - free(ret); - return NULL; - } while (!list_done(domains, fod)); - - fod = malloc(sizeof(*fod)); - if (!fod) - return NULL; - memset(fod, 0, sizeof(*fod)); - fod->fd_name = ret; - fod->fd_nodes = 0; - fod->fd_flags = 0; - - snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@ordered", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - if (atoi(ret) != 0) - fod->fd_flags |= FOD_ORDERED; - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@restricted", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - if (atoi(ret) != 0) - fod->fd_flags |= FOD_RESTRICTED; - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@nofailback", - base, idx); - if (ccs_get(ccsfd, xpath, &ret) == 0) { - if (atoi(ret) != 0) - fod->fd_flags |= FOD_NOFAILBACK; - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]", - base, idx); - - do { - fodn = get_node(ccsfd, xpath, x++, fod); - if (fodn) { - list_insert(&fod->fd_nodes, fodn); - } - } while (fodn); - - return fod; -} - - -int -construct_domains(int ccsfd, fod_t **domains) -{ - char xpath[256]; - int x = 1; - fod_t *fod; - - snprintf(xpath, sizeof(xpath), - RESOURCE_TREE_ROOT "/failoverdomains"); - - do { - fod = get_domain(ccsfd, xpath, x++, domains); - if (fod) { - list_insert(domains, fod); - } - } while (fod); - - return 0; -} - - -void -deconstruct_domains(fod_t **domains) -{ - fod_t *domain = NULL; - fod_node_t *node; - - while ((domain = *domains)) { - list_remove(domains, domain); - while ((node = domain->fd_nodes)) { - list_remove(&domain->fd_nodes, node); - if (node->fdn_name) - free(node->fdn_name); - free(node); - } - - if (domain->fd_name) - free(domain->fd_name); - free(domain); - } -} - - -void -print_domains(fod_t **domains) -{ - fod_t *fod; - fod_node_t *fodn = NULL; - /* - int x; - int *node_set = NULL; - int node_set_len = 0; - */ - - list_do(domains, fod) { - printf("Failover domain: %s\n", fod->fd_name); - printf("Flags: "); - if (!fod->fd_flags) { - printf("none\n"); - } else { - if (fod->fd_flags & FOD_ORDERED) - printf("Ordered "); - if (fod->fd_flags & FOD_RESTRICTED) - printf("Restricted "); - if (fod->fd_flags & FOD_NOFAILBACK) - printf("No Failback"); - printf("\n"); - } - - list_do(&fod->fd_nodes, fodn) { - printf(" Node %s (id %d, priority %d)\n", - fodn->fdn_name, (int)fodn->fdn_nodeid, - fodn->fdn_prio); - } while (!list_done(&fod->fd_nodes, fodn)); - - /* - node_domain_set(fod, &node_set, &node_set_len); - printf(" Failover Order = {"); - for (x = 0; x < node_set_len; x++) { - printf(" %d ", node_set[x]); - } - free(node_set); - printf("}\n"); - */ - - } while (!list_done(domains, fod)); -} - - -/** - * Check to see if a given node is the current preferred node within a domain - * on which we should start the service... - * @param nodename Node/member name. - * @param domain Existing domain. - * @param membership Current membership mask. - * @return 0 for No, All domain members offline. - * 1 for No, 1+ Domain member(s) online. - * 2 for Yes, Not lowest-ordered, online member. - * 3 for Yes, Lowest-ordered, online member. - */ -int -node_in_domain(char *nodename, fod_t *domain, - cluster_member_list_t *membership) -{ - int online = 0, member_match = 0, preferred = 100, myprio = -1; - fod_node_t *fodn; - - list_do(&domain->fd_nodes, fodn) { - /* - * We have to check the membership mask here so that - * we can decide whether or not 'nodename' is the lowest - * ordered node. - */ - if (!memb_online(membership, - memb_name_to_id(membership, fodn->fdn_name))) - continue; - - /* - * If we get here, we know: - * A member of the domain is online somewhere - */ - online = 1; - if (!strcmp(nodename, fodn->fdn_name)) { - /* - * If we get here, we know: - * We are a member of the domain. - */ - member_match = 1; - myprio = fodn->fdn_prio; - } - - if (fodn->fdn_prio < preferred) - preferred = fodn->fdn_prio; - } while (!list_done(&domain->fd_nodes, fodn)); - - if (!online) - return 0; - - if (!member_match) - return 1; - - /* Figure out if we're the in the most-preferred group */ - preferred = (myprio <= preferred); - if (!preferred) - return 2; - - return 3; -} - - -int -node_domain_set(fod_t **domains, char *name, set_type_t **ret, int *retlen, int *flags) -{ - int x, i, j; - set_type_t *tmpset; - int ts_count; - fod_node_t *fodn; - fod_t *domain; - int found = 0; - - list_for(domains, domain, x) { - if (!strcasecmp(domain->fd_name, name)) { - found = 1; - break; - } - } // while (!list_done(&_domains, fod)); - - if (!found) - return -1; - - /* Count domain length */ - list_for(&domain->fd_nodes, fodn, x) { } - - *retlen = 0; - *ret = malloc(sizeof(uint64_t) * x); - if (!(*ret)) - return -1; - tmpset = malloc(sizeof(uint64_t) * x); - if (!(*tmpset)) - return -1; - - *flags = domain->fd_flags; - - if (domain->fd_flags & FOD_ORDERED) { - for (i = 1; i <= 100; i++) { - - ts_count = 0; - list_for(&domain->fd_nodes, fodn, x) { - if (fodn->fdn_prio == i) { - s_add(tmpset, &ts_count, - fodn->fdn_nodeid); - } - } - - if (!ts_count) - continue; - - /* Shuffle stuff at this prio level */ - if (ts_count > 1) - s_shuffle(tmpset, ts_count); - for (j = 0; j < ts_count; j++) - s_add(*ret, retlen, tmpset[j]); - } - } - - /* Add unprioritized nodes */ - ts_count = 0; - list_for(&domain->fd_nodes, fodn, x) { - if (!fodn->fdn_prio) { - s_add(tmpset, &ts_count, - fodn->fdn_nodeid); - } - } - - if (!ts_count) - return 0; - - /* Shuffle stuff at this prio level */ - if (ts_count > 1) - s_shuffle(tmpset, ts_count); - for (j = 0; j < ts_count; j++) - s_add(*ret, retlen, tmpset[j]); - - return 0; -} - - -/** - * See if a given nodeid should start a specified service svcid. - * - * @param nodeid The node ID in question. - * @param membership Current membership mask. - * @param rg_name The resource group name in question. - * @param domains List of failover domains. - * @return 0 on NO, 1 for YES - */ -int -node_should_start(uint64_t nodeid, cluster_member_list_t *membership, - char *rg_name, fod_t **domains) -{ - char *nodename = NULL; - char domainname[128]; - int ordered = 0; - int restricted = 0; - int nofailback = 0; - fod_t *fod = NULL; - int found = 0; - int owned_by_node = 0, started = 0, no_owner = 0; -#ifndef NO_CCS - rg_state_t svc_state; - void *lockp; -#endif - - ENTER(); - - /* - * Um, if the node isn't online... - */ - if (!memb_online(membership, nodeid)) { -#ifdef DEBUG - clulog(LOG_DEBUG,"Member #%d is not online -> NO\n", nodeid); -#endif - RETURN(FOD_ILLEGAL); - } - - nodename = memb_id_to_name(membership, nodeid); - -#ifndef NO_CCS /* XXX Testing only */ - if (group_property_unlocked(rg_name, "domain", - domainname, sizeof(domainname))) { - /* - * If no domain is present, then the node in question should - * try to start the service. - */ -#ifdef DEBUG - clulog(LOG_DEBUG, - "Fail-over Domain for service %d nonexistent\n"); -#endif - RETURN(FOD_BEST); - } -#endif - - if (!strlen(domainname)) - RETURN(FOD_BEST); - - /* - * Ok, we've got a failover domain associated with the service. - * Let's see if the domain actually exists... - */ - list_do(domains, fod) { - if (!strcasecmp(fod->fd_name, domainname)) { - found = 1; - break; - } - } while (!list_done(domains, fod)); - - if (!found) { - /* - * Domain doesn't exist! Weird... - */ - clulog(LOG_WARNING, "#66: Domain '%s' specified for resource " - "group %s nonexistent!\n", domainname, rg_name); - RETURN(FOD_BEST); - } - - /* - * Determine whtehter this domain has failback turned on or not.. - */ - nofailback = !!(fod->fd_flags & FOD_NOFAILBACK); - - /* - * Determine whether this domain is restricted or not... - */ - restricted = !!(fod->fd_flags & FOD_RESTRICTED); - - /* - * Determine whether this domain is ordered or not... - */ - ordered = !!(fod->fd_flags & FOD_ORDERED); - -#ifndef NO_CCS - if(nofailback) { - if (rg_lock(rg_name, &lockp) != 0) { - clulog(LOG_WARNING, "Error getting a lock\n"); - RETURN(FOD_BEST); - } - - if (get_rg_state(rg_name, &svc_state) == RG_EFAIL) { - /* - * Couldn't get the service state, thats odd - */ - clulog(LOG_WARNING, "Problem getting state information for " - "%s\n", rg_name); - rg_unlock(rg_name, lockp); - RETURN(FOD_BEST); - } - rg_unlock(rg_name, lockp); - - /* - * Check to see if the service is started and if we are the owner in case of - * restricted+owner+no failback - */ - if (svc_state.rs_state == RG_STATE_STARTED) - started = 1; - if (svc_state.rs_owner == nodeid) - owned_by_node = 1; - if (!memb_online(membership, svc_state.rs_owner)) - no_owner = 1; - } -#endif - - switch (node_in_domain(nodename, fod, membership)) { - case 0: - /* - * Node is not a member of the domain and no members of the - * domain are online. - */ -#ifdef DEBUG - clulog(LOG_DEBUG, "Member #%d is not a member and no " - "members are online\n", nodeid); -#endif - if (!restricted) { -#ifdef DEBUG - clulog(LOG_DEBUG,"Restricted mode off -> BEST\n"); -#endif - RETURN(FOD_BEST); - } -#ifdef DEBUG - clulog(LOG_DEBUG,"Restricted mode -> ILLEGAL\n"); -#endif - RETURN(FOD_ILLEGAL); - case 1: - /* - * Node is not a member of the domain and at least one member - * of the domain is online. - */ - /* In this case, we can ignore 'restricted' */ -#ifdef DEBUG - clulog(LOG_DEBUG, "Member #%d is not a member of domain %s " - "and a member is online\n", nodeid, domainname); -#endif - if (!restricted) { -#ifdef DEBUG - clulog(LOG_DEBUG,"Restricted mode off -> GOOD\n"); -#endif - RETURN(FOD_GOOD); - } -#ifdef DEBUG - clulog(LOG_DEBUG,"Restricted mode -> ILLEGAL\n"); -#endif - RETURN(FOD_ILLEGAL); - case 2: - /* - * Node is a member of the domain, but is not the - * lowest-ordered, online member. - */ -#ifdef DEBUG - clulog(LOG_DEBUG, "Member #%d is a member, but is not the " - "lowest-ordered\n", nodeid); -#endif - if (ordered) { - /* - * If we are ordered we want to see if failback is - * turned on - */ - if (nofailback && started && owned_by_node && !no_owner) { -#ifdef DEBUG - clulog(LOG_DEBUG,"Ordered mode and no " - "failback -> BEST\n"); -#endif - RETURN(FOD_BEST); - } -#ifdef DEBUG - clulog(LOG_DEBUG,"Ordered mode -> BETTER\n"); -#endif - RETURN(FOD_BETTER); - } - -#ifdef DEBUG - clulog(LOG_DEBUG,"Not using ordered mode -> BEST\n"); -#endif - RETURN(FOD_BEST); - case 3: - /* - * Node is a member of the domain and is the lowest-ordered, - * online member. - */ - - if(nofailback && started && !owned_by_node && !no_owner) { -#ifdef DEBUG - clulog(LOG_DEBUG, "Member #%d is the lowest-ordered " - "memeber of the domain, but is not the owner " - "-> BETTER\n", nodeid); -#endif - RETURN(FOD_BETTER); - } - - /* In this case, we can ignore 'ordered' */ -#ifdef DEBUG - clulog(LOG_DEBUG, "Member #%d is the lowest-ordered member " - "of the domain -> BEST\n", nodeid); -#endif - RETURN(FOD_BEST); - default: - /* Do what? */ - clulog(LOG_ERR, "#32: Code path error: " - "Invalid return from node_in_domain()\n"); - RETURN(FOD_ILLEGAL); - } - - /* not reached */ - RETURN(FOD_ILLEGAL); -} diff --git a/rgmanager/src/daemons/groups.c b/rgmanager/src/daemons/groups.c deleted file mode 100644 index f26c0d4..0000000 --- a/rgmanager/src/daemons/groups.c +++ /dev/null @@ -1,1749 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2006 - Copyright Mission Critical Linux, Inc. 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -//#define DEBUG -#include <sets.h> -#include <platform.h> -#include <restart_counter.h> -#include <resgroup.h> -#include <reslist.h> -#include <vf.h> -#include <magma.h> -#include <ccs.h> -#include <clulog.h> -#include <magmamsg.h> -#include <list.h> -#include <reslist.h> -#include <assert.h> -#include <event.h> - -int get_rg_state_local(char *name, rg_state_t *svcblk); - -/* Use address field in this because we never use it internally, - and there is no extra space in the cman_node_t type. - */ - -#define cm_svccount cm_pad[0] /* Theses are uint8_t size */ -#define cm_svcexcl cm_pad[1] - -extern event_table_t *master_event_table; - -static int config_version = 0; -static resource_t *_resources = NULL; -static resource_rule_t *_rules = NULL; -static resource_node_t *_tree = NULL; -static fod_t *_domains = NULL; - -#ifdef WRAP_LOCKS -pthread_mutex_t config_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -pthread_mutex_t status_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -#else -pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t status_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif -pthread_rwlock_t resource_lock = PTHREAD_RWLOCK_INITIALIZER; - -void res_build_name(char *, size_t, resource_t *); -int group_migratory(char *groupname, int lock); -int group_property(char *groupname, char *property, char *ret, size_t len); -int member_online_set(set_type_t **nodes, int *nodecount); - - -struct status_arg { - int fd; - int fast; -}; - - -/** - See if a given node ID should start a resource, given cluster membership - - @see node_should_start - */ -int -node_should_start_safe(uint64_t nodeid, cluster_member_list_t *membership, - char *rg_name) -{ - int ret; - - pthread_rwlock_rdlock(&resource_lock); - ret = node_should_start(nodeid, membership, rg_name, &_domains); - pthread_rwlock_unlock(&resource_lock); - - return ret; -} - - -int -node_domain_set_safe(char *domainname, set_type_t **ret, int *retlen, int *flags) -{ - int rv = 0; - pthread_rwlock_rdlock(&resource_lock); - rv = node_domain_set(&_domains, domainname, ret, retlen, flags); - pthread_rwlock_unlock(&resource_lock); - - return rv; -} - - -int -count_resource_groups(cluster_member_list_t *ml) -{ - resource_t *res; - resource_node_t *node; - char rgname[64], *val; - int x; - rg_state_t st; - void *lockp; - cluster_member_t *mp; - - for (x = 0; x < ml->cml_count; x++) { - ml->cml_members[x].cm_svccount = 0; - ml->cml_members[x].cm_svcexcl = 0; - } - - pthread_rwlock_rdlock(&resource_lock); - - list_do(&_tree, node) { - - res = node->rn_resource; - - res_build_name(rgname, sizeof(rgname), res); - - if (rg_lock(rgname, &lockp) < 0) { - clulog(LOG_ERR, "#XX: Unable to obtain cluster " - "lock @ %s:%d: %s\n", __FILE__, __LINE__, - strerror(errno)); - continue; - } - - if (get_rg_state(rgname, &st) < 0) { - clulog(LOG_ERR, "#34: Cannot get status " - "for service %s\n", c_name(rgname)); - rg_unlock(rgname, lockp); - continue; - } - - rg_unlock(rgname, lockp); - - if (st.rs_state != RG_STATE_STARTED && - st.rs_state != RG_STATE_STARTING) - continue; - - mp = memb_id_to_p(ml, st.rs_owner); - if (!mp) - continue; - - ++mp->cm_svccount; - - val = res_attr_value(res, "exclusive"); - if (val && ((!strcmp(val, "yes") || - (atoi(val)>0))) ) { - ++mp->cm_svcexcl; - } - - } while (!list_done(&_tree, node)); - - pthread_rwlock_unlock(&resource_lock); - return 0; -} - - -static inline int -is_exclusive_res(resource_t *res) -{ - char *val; - - val = res_attr_value(res, "exclusive"); - if (val && ((!strcmp(val, "yes") || - (atoi(val)>0))) ) { - return 1; - } - return 0; -} - - -/* Locked exported function */ -int -is_exclusive(char *svcName) -{ - int ret = 0; - resource_t *res = NULL; - - pthread_rwlock_rdlock(&resource_lock); - res = find_root_by_ref(&_resources, svcName); - - if (!res) - ret = RG_ENOSERVICE; - else - ret = is_exclusive_res(res); - - pthread_rwlock_unlock(&resource_lock); - return ret; -} - - -resource_node_t * -node_by_ref(resource_node_t **tree, char *name) -{ - resource_t *res; - resource_node_t *node, *ret = NULL; - char rgname[64]; - int x; - - list_for(tree, node, x) { - - res = node->rn_resource; - res_build_name(rgname, sizeof(rgname), res); - - if (!strcasecmp(name, rgname)) { - ret = node; - break; - } - } - - return ret; -} - - -int -count_resource_groups_local(cluster_member_t *mp) -{ - resource_t *res; - resource_node_t *node; - char rgname[64]; - rg_state_t st; - - mp->cm_svccount = 0; - mp->cm_svcexcl = 0; - - pthread_rwlock_rdlock(&resource_lock); - - list_do(&_tree, node) { - - res = node->rn_resource; - - res_build_name(rgname, sizeof(rgname), res); - - if (get_rg_state_local(rgname, &st) < 0) { - continue; - } - - if (st.rs_state != RG_STATE_STARTED && - st.rs_state != RG_STATE_STARTING) - continue; - - if (mp->cm_id != st.rs_owner) - continue; - - ++mp->cm_svccount; - - if (is_exclusive_res(res)) - ++mp->cm_svcexcl; - - } while (!list_done(&_tree, node)); - - pthread_rwlock_unlock(&resource_lock); - return 0; -} - - -int -have_exclusive_resources(void) -{ - resource_t *res; - - pthread_rwlock_rdlock(&resource_lock); - - list_do(&_resources, res) { - if (is_exclusive_res(res)) { - pthread_rwlock_unlock(&resource_lock); - return 1; - } - - } while (!list_done(&_resources, res)); - - pthread_rwlock_unlock(&resource_lock); - - return 0; -} - - -int -check_exclusive_resources(cluster_member_list_t *membership, char *svcName) -{ - cluster_member_t *mp; - int exclusive, count, excl; - resource_t *res; - - mp = memb_id_to_p(membership, my_id()); - assert(mp); - count_resource_groups_local(mp); - exclusive = mp->cm_svcexcl; - count = mp->cm_svccount; - pthread_rwlock_rdlock(&resource_lock); - res = find_root_by_ref(&_resources, svcName); - if (!res) { - pthread_rwlock_unlock(&resource_lock); - return RG_ENOSERVICE; - } - - excl = is_exclusive_res(res); - pthread_rwlock_unlock(&resource_lock); - if (exclusive || (count && excl)) - return RG_YES; - - return 0; -} - - -/** - Find the best target node for a service *besides* the current service - owner. Takes into account: - - - Failover domain (ordering / restricted policy) - - Exclusive service policy - */ -uint64_t -best_target_node(cluster_member_list_t *allowed, uint64_t owner, - char *rg_name, int lock) -{ - int x; - int highscore = 1; - int score; - uint64_t highnode = owner, nodeid; - char *val; - resource_t *res; - int exclusive; - - if (lock) - pthread_rwlock_rdlock(&resource_lock); - count_resource_groups(allowed); - if (lock) - pthread_rwlock_unlock(&resource_lock); - - for (x=0; x < allowed->cml_count; x++) { - if (allowed->cml_members[x].cm_state != STATE_UP) - continue; - - nodeid = allowed->cml_members[x].cm_id; - - /* Don't allow trying a restart just yet */ - if (owner != NODE_ID_NONE && nodeid == owner) - continue; - - if (lock) - pthread_rwlock_rdlock(&resource_lock); - score = node_should_start(nodeid, allowed, rg_name, &_domains); - if (!score) { /* Illegal -- failover domain constraint */ - if (lock) - pthread_rwlock_unlock(&resource_lock); - continue; - } - - /* Add 2 to score if it's an exclusive service and nodeid - isn't running any services currently. Set score to 0 if - it's an exclusive service and the target node already - is running a service. */ - res = find_root_by_ref(&_resources, rg_name); - val = res_attr_value(res, "exclusive"); - exclusive = val && ((!strcmp(val, "yes") || (atoi(val)>0))); - - if (lock) - pthread_rwlock_unlock(&resource_lock); - - if (exclusive) { - - if (allowed->cml_members[x].cm_svccount > 0) { - /* Definitely not this guy */ - continue; - } else { - score += 2; - } - } else if (allowed->cml_members[x].cm_svcexcl) { - /* This guy has an exclusive resource group. - Can't relocate / failover to him. */ - continue; - } - - if (score < highscore) - continue; - - highnode = nodeid; - highscore = score; - } - - return highnode; -} - - -int -check_depend(resource_t *res) -{ - char *val; - rg_state_t rs; - - val = res_attr_value(res, "depend"); - if (!val) - /* No dependency */ - return -1; - - if (get_rg_state_local(val, &rs) == 0) - return (rs.rs_state == RG_STATE_STARTED); - - return 1; -} - - -int -check_depend_safe(char *rg_name) -{ - resource_t *res; - int ret; - - pthread_rwlock_rdlock(&resource_lock); - res = find_root_by_ref(&_resources, rg_name); - if (!res) - return -1; - - ret = check_depend(res); - pthread_rwlock_unlock(&resource_lock); - - return ret; -} - - -int -check_rdomain_crash(char *svcName) -{ - set_type_t *nodes = NULL; - set_type_t *fd_nodes = NULL; - set_type_t *isect = NULL; - int nodecount = 0; - int fd_nodecount = 0, fl = 0; - int icount = 0; - char fd_name[256]; - - if (group_property(svcName, "domain", fd_name, sizeof(fd_name)) != 0) - goto out_free; - - member_online_set(&nodes, &nodecount); - - if (node_domain_set(&_domains, fd_name, &fd_nodes, - &fd_nodecount, &fl) != 0) - goto out_free; - - if (!(fl & FOD_RESTRICTED)) - goto out_free; - - if (s_intersection(fd_nodes, fd_nodecount, nodes, nodecount, - &isect, &icount) < 0) - goto out_free; - - if (icount == 0) { - clulog(LOG_DEBUG, "Marking %s as stopped: " - "Restricted domain unavailable\n", svcName); - rt_enqueue_request(svcName, RG_STOP, -1, 0, 0, - 0, 0); - } - -out_free: - if (fd_nodes) - free(fd_nodes); - if (nodes) - free(nodes); - if (isect) - free(isect); - - return 0; -} - - -/** - Start or failback a resource group: if it's not running, start it. - If it is running and we're a better member to run it, then ask for - it. - */ -void -consider_start(resource_node_t *node, char *svcName, rg_state_t *svcStatus, - cluster_member_list_t *membership) -{ - char *val; - cluster_member_t *mp; - int autostart, exclusive; - void *lockp = NULL; - int fod_ret; - - mp = memb_id_to_p(membership, my_id()); - assert(mp); - - /* - * Service must be not be running elsewhere to consider for a - * local start. - */ - if (svcStatus->rs_state == RG_STATE_STARTED && - svcStatus->rs_owner == mp->cm_id) - return; - - if (svcStatus->rs_state == RG_STATE_DISABLED) - return; - - /* Stopped, and hasn't been started yet. See if - autostart is disabled. If it is, leave it stopped */ - if (svcStatus->rs_state == RG_STATE_STOPPED && - svcStatus->rs_transition == 0) { - val = res_attr_value(node->rn_resource, "autostart"); - autostart = !(val && ((!strcmp(val, "no") || - (atoi(val)==0)))); - if (!autostart) { - /* - clulog(LOG_DEBUG, - "Skipping RG %s: Autostart disabled\n", - logname); - */ - /* - Mark non-autostart services as disabled to avoid - confusion! - */ - if (rg_lock(svcName, &lockp) < 0) { - clulog(LOG_ERR, "#XX: Unable to obtain cluster " - "lock @ %s:%d: %s\n", __FILE__, __LINE__, - strerror(errno)); - return; - } - - if (get_rg_state(svcName, svcStatus) != 0) { - clulog(LOG_ERR, "#34: Cannot get status " - "for service %s\n", - c_name(svcName)); - rg_unlock(svcName, lockp); - return; - } - - if (svcStatus->rs_transition == 0 && - svcStatus->rs_state == RG_STATE_STOPPED) { - svcStatus->rs_state = RG_STATE_DISABLED; - set_rg_state(svcName, svcStatus); - } - - rg_unlock(svcName, lockp); - - return; - } - } - - /* See if service this one depends on is running. If not, - don't start it */ - if (check_depend(node->rn_resource) == 0) { - clulog(LOG_DEBUG, - "Skipping %s: Dependency missing\n", svcName); - return; - } - - val = res_attr_value(node->rn_resource, "exclusive"); - exclusive = val && ((!strcmp(val, "yes") || (atoi(val)>0))); - - if (exclusive && mp->cm_svccount) { - clulog(LOG_DEBUG, - "Skipping %s: Exclusive and I am running services\n", - svcName); - return; - } - - /* - Don't start other services if I'm running an exclusive - service. - */ - if (mp->cm_svcexcl) { - clulog(LOG_DEBUG, - "Skipping %s: I am running an exclusive service\n", - svcName); - return; - } - - /* - * Start any stopped services, or started services - * that are owned by a down node. - */ - fod_ret = node_should_start(mp->cm_id, membership, - svcName, &_domains); - if (fod_ret == FOD_BEST) - rt_enqueue_request(svcName, RG_START, -1, 0, mp->cm_id, - 0, 0); - else if (fod_ret == FOD_ILLEGAL) - check_rdomain_crash(svcName); -} - - -void -consider_relocate(char *svcName, rg_state_t *svcStatus, uint64_t nodeid, - cluster_member_list_t *membership) -{ - int a, b, req = RG_RELOCATE; - - /* - Service must be running locally in order to consider for - a relocate - */ - if ((svcStatus->rs_state != RG_STATE_STARTING && - svcStatus->rs_state != RG_STATE_STARTED) || - svcStatus->rs_owner != my_id()) - return; - - /* - * Send the resource group to a node if it's got a higher prio - * to run the resource group. - */ -#if 0 - if (best_target_node(membership, my_id(), svcName, 0) != - nodeid) { - return; - } -#endif - a = node_should_start(nodeid, membership, svcName, &_domains); - b = node_should_start(my_id(), membership, svcName, &_domains); - - if (a <= b) - return; - - clulog(LOG_NOTICE, "Relocating %s to better node %s\n", - svcName, - memb_id_to_name(membership, nodeid)); - - rt_enqueue_request(svcName, req, -1, 0, nodeid, 0, 0); -} - - -char ** -get_service_names(int *len) -{ - resource_node_t *node = NULL; - int nservices, ncopied = 0, x; - char **ret = NULL; - char rg_name[64]; - - pthread_rwlock_rdlock(&resource_lock); - - nservices = 0; - list_do(&_tree, node) { - ++nservices; - } while (!list_done(&_tree, node)); - - ret = malloc(sizeof(char *) * (nservices + 1)); - if (!ret) - goto out_fail; - - memset(ret, 0, sizeof(char *) * (nservices + 1)); - nservices = 0; - list_for(&_tree, node, nservices) { - res_build_name(rg_name, sizeof(rg_name), - node->rn_resource); - - if (!strlen(rg_name)) - continue; - - ret[ncopied] = strdup(rg_name); - if (ret[ncopied]) { - ncopied++; - } else { - goto out_fail; - } - } - - if (len) - *len = ncopied; - pthread_rwlock_unlock(&resource_lock); - return ret; - -out_fail: - pthread_rwlock_unlock(&resource_lock); - for (x = 0; x < ncopied; x++) - free(ret[x]); - if (ret) - free(ret); - return NULL; -} - - - - - -/** - * Called to decide what services to start locally during a node_event. - * Originally a part of node_event, it is now its own function to cut down - * on the length of node_event. - * - * @see node_event - */ -int -eval_groups(int local, uint64_t nodeid, int nodeStatus) -{ - void *lockp = NULL; - char svcName[96], *nodeName; - resource_node_t *node; - rg_state_t svcStatus; - cluster_member_list_t *membership; - int ret; - - if (rg_locked()) { - clulog(LOG_NOTICE, - "Resource groups locked; not evaluating\n"); - return -EAGAIN; - } - - membership = member_list(); - - pthread_rwlock_rdlock(&resource_lock); - - /* Requires read lock */ - count_resource_groups(membership); - - list_do(&_tree, node) { - - if ((node->rn_resource->r_rule->rr_flags & RF_ROOT)== 0) - continue; - - res_build_name(svcName, sizeof(svcName), node->rn_resource); - - /* - * Lock the service information and get the current service - * status. - */ - if ((ret = rg_lock(svcName, &lockp)) < 0) { - clulog(LOG_ERR, - "#33: Unable to obtain cluster lock: %s\n", - strerror(-ret)); - pthread_rwlock_unlock(&resource_lock); - cml_free(membership); - return ret; - } - - if (get_rg_state(svcName, &svcStatus) != 0) { - clulog(LOG_ERR, - "#34: Cannot get status for service %s\n", - c_name(svcName)); - rg_unlock(svcName, lockp); - continue; - } - - rg_unlock(svcName, lockp); - - if (svcStatus.rs_owner == NODE_ID_NONE) - nodeName = "none"; - else - nodeName = memb_id_to_name(membership, - svcStatus.rs_owner); - - /* Disabled/failed/in recovery? Do nothing */ - if ((svcStatus.rs_state == RG_STATE_DISABLED) || - (svcStatus.rs_state == RG_STATE_FAILED) || - (svcStatus.rs_state == RG_STATE_RECOVER)) { - continue; - } - - clulog(LOG_DEBUG, "Evaluating %s, state %s, owner " - "%s\n", svcName, - rg_state_str(svcStatus.rs_state), - nodeName); - - if ((local && (nodeStatus == STATE_UP)) || - svcStatus.rs_state == RG_STATE_STOPPED) { - - consider_start(node, svcName, &svcStatus, membership); - - } else if (!local && (nodeStatus == STATE_DOWN)) { - - /* - * Start any stopped services, or started services - * that are owned by a down node. - */ - consider_start(node, svcName, &svcStatus, membership); - - /* - * TODO - * Mark a service as 'stopped' if no members in its - * restricted fail-over domain are running. - */ - } else { - /* Send to the node if that ndoe is a better - owner for this service */ - consider_relocate(svcName, &svcStatus, nodeid, - membership); - } - - } while (!list_done(&_tree, node)); - - pthread_rwlock_unlock(&resource_lock); - cml_free(membership); - - clulog(LOG_DEBUG, "Event (%d:%llx:%d) Processed\n", local, - nodeid, nodeStatus); - - return 0; -} - - -/** - * Called to decide what services to start locally after a service event. - * - * @see eval_groups - */ -int -group_event(char *rg_name, uint32_t state, int owner) -{ - char svcName[64], *nodeName; - resource_node_t *node; - rg_state_t svcStatus; - cluster_member_list_t *membership; - int depend; - - if (rg_locked()) { - clulog(LOG_DEBUG, - "Resource groups locked; not evaluating\n"); - return -EAGAIN; - } - - membership = member_list(); - if (!membership) - return -1; - - pthread_rwlock_rdlock(&resource_lock); - - /* Requires read lock */ - count_resource_groups(membership); - - list_do(&_tree, node) { - - res_build_name(svcName, sizeof(svcName), node->rn_resource); - - if (get_rg_state_local(svcName, &svcStatus) != 0) - continue; - - if (svcStatus.rs_owner == 0) - nodeName = "none"; - else - nodeName = memb_id_to_name(membership, - svcStatus.rs_owner); - - /* Disabled/failed/in recovery? Do nothing */ - if ((svcStatus.rs_state == RG_STATE_DISABLED) || - (svcStatus.rs_state == RG_STATE_FAILED) || - (svcStatus.rs_state == RG_STATE_RECOVER)) { - continue; - } - - depend = check_depend(node->rn_resource); - - /* Skip if we have no dependency */ - if (depend == -1) - continue; - - /* - If we have: - (a) a met dependency - (b) we're in the STOPPED state, and - (c) our new service event is a started service - - Then see if we should start this other service as well. - */ - if (depend == 1 && - svcStatus.rs_state == RG_STATE_STOPPED && - state == RG_STATE_STARTED) { - - clulog(LOG_DEBUG, "Evaluating %s, state %s, owner " - "%s\n", svcName, - rg_state_str(svcStatus.rs_state), - nodeName); - consider_start(node, svcName, &svcStatus, membership); - continue; - } - - /* - If we lost a dependency for this service and it's running - locally, stop it. - */ - if (depend == 0 && - svcStatus.rs_state == RG_STATE_STARTED && - svcStatus.rs_owner == my_id()) { - - clulog(LOG_WARNING, - "Stopping %s: Dependency missing\n", - svcName); - rt_enqueue_request(svcName, RG_STOP, -1, 0, my_id(), - 0, 0); - } - - } while (!list_done(&_tree, node)); - - pthread_rwlock_unlock(&resource_lock); - cml_free(membership); - - return 0; -} - - - -/** - Perform an operation on a resource group. That is, walk down the - tree for that resource group, performing the given operation on - all children in the necessary order. - - XXX Needs to handle more return codes to be more OCF compliant - - @param groupname Resource group to operate on - @param op Operation to perform - @return 0 on success, 1 on failure/error. - */ -int -group_op(char *groupname, int op) -{ - resource_t *res; - int ret = -1; - - pthread_rwlock_rdlock(&resource_lock); - /* XXX get group from somewhere else */ - res = find_root_by_ref(&_resources, groupname); - if (!res) { - pthread_rwlock_unlock(&resource_lock); - return -1; - } - - switch (op) { - case RG_START: - ret = res_start(&_tree, res, NULL); - break; - case RG_STOP: - ret = res_stop(&_tree, res, NULL); - break; - case RG_STATUS: - ret = res_status(&_tree, res, NULL); - break; - case RG_CONDSTOP: - ret = res_condstop(&_tree, res, NULL); - break; - case RG_CONDSTART: - ret = res_condstart(&_tree, res, NULL); - break; - } - pthread_rwlock_unlock(&resource_lock); - - /* - Do NOT return error codes if we failed to stop for one of these - reasons. It didn't start, either, so it's safe to assume that - if the program wasn't installed, there's nothing to tear down. - */ - if (op == RG_STOP) { - switch(ret) { - case OCF_RA_SUCCESS: - case OCF_RA_NOT_INSTALLED: - case OCF_RA_NOT_CONFIGURED: - ret = 0; - break; - default: - ret = 1; - break; - } - } - - return ret; -} - - -/** - Gets an attribute of a resource group. - - @param groupname Name of group - @param property Name of property to check for - @param ret Preallocated return buffer - @param len Length of buffer pointed to by ret - @return 0 on success, -1 on failure. - */ -int -_group_property(char *groupname, char *property, char *ret, - size_t len, int lock) -{ - resource_t *res = NULL; - int x = 0, rv=-1; - - if (lock) - pthread_rwlock_rdlock(&resource_lock); - - res = find_root_by_ref(&_resources, groupname); - if (!res) - goto out; - - for (; res->r_attrs[x].ra_name; x++) { - if (strcasecmp(res->r_attrs[x].ra_name, property)) - continue; - strncpy(ret, res->r_attrs[x].ra_value, len); - rv = 0; - break; - } -out: - if (lock) - pthread_rwlock_unlock(&resource_lock); - return rv; -} - - -int -group_property(char *groupname, char *property, char *ret, - size_t len) -{ - return _group_property(groupname, property, ret, len, 1); -} - - -int -group_property_unlocked(char *groupname, char *property, char *ret, - size_t len) -{ - return _group_property(groupname, property, ret, len, 0); -} - - -/** - Send the state of a resource group to a given file descriptor. - - @param fd File descriptor to send state to - @param rgname Resource group name whose state we want to send. - @see send_rg_states - */ -void -send_rg_state(int fd, char *rgname, int fast) -{ - rg_state_msg_t msg, *msgp = &msg; - void *lockp; - - msgp->rsm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msgp->rsm_hdr.gh_length = sizeof(msg); - msgp->rsm_hdr.gh_command = RG_STATUS; - - /* try fast read -- only if it fails and fast is not - specified should we do the full locked read */ - if (get_rg_state_local(rgname, &msgp->rsm_state) != 0 && - !fast) { - if (rg_lock(rgname, &lockp) < 0) - return; - if (get_rg_state(rgname, &msgp->rsm_state) < 0) { - rg_unlock(rgname, lockp); - return; - } - rg_unlock(rgname, lockp); - } - - swab_rg_state_msg_t(msgp); - - if (msg_send(fd, msgp, sizeof(msg)) < 0) - perror("msg_send"); -} - - -/** - Send status from a thread because we don't want rgmanager's - main thread to block in the case of DLM issues - */ -static void * -status_check_thread(void *arg) -{ - int fd = ((struct status_arg *)arg)->fd; - int fast = ((struct status_arg *)arg)->fast; - char name[96]; - resource_t *res; - generic_msg_hdr hdr; - - free(arg); - - if (central_events_enabled()) { - /* Never call get_rg_state() (distributed) if - central events are enabled, otherwise we - might overwrite the rg state with 'stopped' - when it should be 'disabled' (e.g. autostart="0") */ - fast = 1; - } - - /* See if we have a slot... */ - if (rg_inc_status() < 0) { - /* Too many outstanding status checks. try again later. */ - msg_send_simple(fd, RG_FAIL, RG_EAGAIN, 0); - msg_close(fd); - pthread_exit(NULL); - } - - pthread_rwlock_rdlock(&resource_lock); - - list_do(&_resources, res) { - if ((res->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - res_build_name(name, sizeof(name), res); - send_rg_state(fd, name, fast); - } while (!list_done(&_resources, res)); - - pthread_rwlock_unlock(&resource_lock); - - msg_send_simple(fd, RG_SUCCESS, 0, 0); - - /* XXX wait for client to tell us it's done; I don't know why - this is needed when doing fast I/O, but it is. */ - msg_receive_timeout(fd, &hdr, sizeof(hdr), 10); - - msg_close(fd); - - rg_dec_status(); - - pthread_exit(NULL); -} - - -/** - Send all resource group states to a file descriptor - - @param fd File descriptor to send states to. - @return 0 - */ -int -send_rg_states(int fd, int fast) -{ - struct status_arg *arg; - pthread_t newthread; - pthread_attr_t attrs; - - arg = malloc(sizeof(struct status_arg)); - if (!arg) { - msg_send_simple(fd, RG_FAIL, 0, 0); - return -1; - } - - arg->fd = fd; - arg->fast = fast; - - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attrs, 65535); - - pthread_create(&newthread, &attrs, status_check_thread, arg); - pthread_attr_destroy(&attrs); - - return 0; -} - - -int -svc_exists(char *name) -{ - resource_t *res; - int ret = 0; - char rgname[64]; - - pthread_rwlock_rdlock(&resource_lock); - - list_do(&_resources, res) { - if ((res->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - res_build_name(rgname, sizeof(rgname), res); - - if (!strcmp(name, rgname)) { - ret = 1; - break; - } - if (!strcmp(name, c_name(rgname))) { - ret = 1; - break; - } - } while (!list_done(&_resources, res)); - - pthread_rwlock_unlock(&resource_lock); - - return ret; -} - - -void -rg_doall(int request, int block, char *debugfmt) -{ - resource_node_t *curr; - char name[96]; - rg_state_t svcblk; - - pthread_rwlock_rdlock(&resource_lock); - list_do(&_tree, curr) { - - if ((curr->rn_resource->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - /* Group name */ - res_build_name(name, sizeof(name), curr->rn_resource); - - if (debugfmt) - clulog(LOG_DEBUG, debugfmt, c_name(name)); - - /* Optimization: Don't bother even queueing the request - during the exit case if we don't own it */ - if (request == RG_STOP_EXITING) { - if (get_rg_state_local(name, &svcblk) < 0) - continue; - - /* Always run stop if we're the owner, regardless - of state; otherwise, don't run stop */ - if (svcblk.rs_owner != my_id()) - continue; - } - - rt_enqueue_request(name, request, -1, 0, - NODE_ID_NONE, 0, 0); - } while (!list_done(&_tree, curr)); - - pthread_rwlock_unlock(&resource_lock); - - /* XXX during shutdown, if we're doing a simultaenous shutdown, - this will cause this rgmanager to hang waiting for all the - other rgmanagers to complete. */ - if (block) - rg_wait_threads(); -} - - -/** - Stop changed resources. - */ -void * -q_status_checks(void *arg) -{ - resource_node_t *curr; - char name[96]; - rg_state_t svcblk; - - /* Only one status thread at a time, please! */ - if (pthread_mutex_trylock(&status_mutex) != 0) - pthread_exit(NULL); - - pthread_rwlock_rdlock(&resource_lock); - list_do(&_tree, curr) { - - if ((curr->rn_resource->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - /* Group name */ - res_build_name(name, sizeof(name), curr->rn_resource); - - /* Local check - no one will make us take a service */ - if (get_rg_state_local(name, &svcblk) < 0) { - continue; - } - - if (svcblk.rs_owner != my_id() || - svcblk.rs_state != RG_STATE_STARTED) - continue; - - rt_enqueue_request(name, RG_STATUS, - -1, 1, NODE_ID_NONE, 0, 0); - - } while (!list_done(&_tree, curr)); - - pthread_rwlock_unlock(&resource_lock); - pthread_mutex_unlock(&status_mutex); - - pthread_exit(NULL); -} - - -void -do_status_checks(void) -{ - pthread_attr_t attrs; - pthread_t newthread; - - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attrs, 65535); - - pthread_create(&newthread, &attrs, q_status_checks, NULL); - pthread_attr_destroy(&attrs); -} - - -/** - Stop changed resources. - */ -void -do_condstops(void) -{ - resource_node_t *curr; - char name[96]; - rg_state_t svcblk; - int need_kill; - - clulog(LOG_INFO, "Stopping changed resources.\n"); - - pthread_rwlock_rdlock(&resource_lock); - list_do(&_tree, curr) { - - if ((curr->rn_resource->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - /* Group name */ - res_build_name(name, sizeof(name), curr->rn_resource); - - /* If we're not running it, no need to CONDSTOP */ - if (get_rg_state_local(name, &svcblk) < 0) { - continue; - } - - if (svcblk.rs_owner != my_id()) - continue; - - /* Set state to uninitialized if we're killing a RG */ - need_kill = 0; - if (curr->rn_resource->r_flags & RF_NEEDSTOP) { - need_kill = 1; - clulog(LOG_DEBUG, "Removing %s\n", name); - } - - rt_enqueue_request(name, need_kill ? RG_DISABLE : RG_CONDSTOP, - -1, 0, NODE_ID_NONE, 0, 0); - - } while (!list_done(&_tree, curr)); - - pthread_rwlock_unlock(&resource_lock); - rg_wait_threads(); -} - - -/** - Start changed resources. - */ -void -do_condstarts(void) -{ - resource_node_t *curr; - char name[96], *val; - rg_state_t svcblk; - int need_init, new_groups = 0, autostart; - void *lockp; - - clulog(LOG_INFO, "Starting changed resources.\n"); - - /* Pass 1: Start any normally changed resources */ - pthread_rwlock_rdlock(&resource_lock); - list_do(&_tree, curr) { - - if ((curr->rn_resource->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - /* Group name */ - res_build_name(name, sizeof(name), curr->rn_resource); - - /* New RG. We'll need to initialize it. */ - need_init = 0; - if (curr->rn_resource->r_flags & RF_NEEDSTART) - need_init = 1; - - if (!need_init) { - if (get_rg_state_local(name, &svcblk) < 0) - continue; - } else { - if (rg_lock(name, &lockp) != 0) - continue; - - if (get_rg_state(name, &svcblk) < 0) { - rg_unlock(name, lockp); - continue; - } - - rg_unlock(name, lockp); - } - - if (!need_init && svcblk.rs_owner != my_id()) { - continue; - } - - if (need_init) { - ++new_groups; - clulog(LOG_DEBUG, "Initializing %s\n", name); - } - - rt_enqueue_request(name, need_init ? RG_INIT : RG_CONDSTART, - -1, 0, NODE_ID_NONE, 0, 0); - - } while (!list_done(&_tree, curr)); - - pthread_rwlock_unlock(&resource_lock); - rg_wait_threads(); - - if (!new_groups) - return; - - /* Pass 2: Tag all new resource groups as stopped */ - pthread_rwlock_rdlock(&resource_lock); - list_do(&_tree, curr) { - - if ((curr->rn_resource->r_rule->rr_flags & RF_ROOT) == 0) - continue; - - /* Group name */ - res_build_name(name, sizeof(name), curr->rn_resource); - - /* New RG. We'll need to initialize it. */ - if (!(curr->rn_resource->r_flags & RF_NEEDSTART)) - continue; - - if (rg_lock(name, &lockp) != 0) - continue; - - if (get_rg_state(name, &svcblk) < 0) { - rg_unlock(name, lockp); - continue; - } - - /* If it is a replacement of an old RG, it will - be in the DISABLED state, which will prevent it - from restarting. That's bad. However, if it's - a truly new service, it will be in the UNINITIALIZED - state, which will be caught by eval_groups. */ - if (svcblk.rs_state != RG_STATE_DISABLED) { - rg_unlock(name, lockp); - continue; - } - - /* Set it up for an auto-start */ - val = res_attr_value(curr->rn_resource, "autostart"); - autostart = !(val && ((!strcmp(val, "no") || - (atoi(val)==0)))); - if (autostart) - svcblk.rs_state = RG_STATE_STOPPED; - else - svcblk.rs_state = RG_STATE_DISABLED; - - set_rg_state(name, &svcblk); - - rg_unlock(name, lockp); - - } while (!list_done(&_tree, curr)); - pthread_rwlock_unlock(&resource_lock); - - /* Pass 3: See if we should start new resource groups */ - eval_groups(1, my_id(), STATE_UP); -} - - -int -check_config_update(void) -{ - int newver = 0, fd, ret = 0; - char *val = NULL; - - fd = ccs_lock(); - if (fd == -1) { - return 0; - } - - if (ccs_get(fd, "/cluster/@config_version", &val) == 0) { - newver = atoi(val); - } - - if (val) - free(val); - - pthread_mutex_lock(&config_mutex); - if (newver && newver != config_version) - ret = 1; - pthread_mutex_unlock(&config_mutex); - ccs_unlock(fd); - - return ret; -} - - -void -dump_config_version(FILE *fp) -{ - fprintf(fp, "Cluster configuration version %d\n\n", config_version); -} - - -/** - Initialize resource groups. This reads all the resource groups from - CCS, builds the tree, etc. Ideally, we'll have a similar function - performing deltas on the two trees so that we can fully support online - resource group modification. - */ -int -init_resource_groups(int reconfigure) -{ - int fd, x, y, cnt; - - event_table_t *evt = NULL; - resource_t *reslist = NULL, *res; - resource_rule_t *rulelist = NULL, *rule; - resource_node_t *tree = NULL; - fod_t *domains = NULL, *fod; - event_t *evp; - char *val; - - if (reconfigure) - clulog(LOG_NOTICE, "Reconfiguring\n"); - clulog(LOG_INFO, "Loading Service Data\n"); - clulog(LOG_DEBUG, "Loading Resource Rules\n"); - if (load_resource_rules(RESOURCE_ROOTDIR, &rulelist) != 0) { - return -1; - } - x = 0; - list_do(&rulelist, rule) { ++x; } while (!list_done(&rulelist, rule)); - clulog(LOG_DEBUG, "%d rules loaded\n", x); - - fd = ccs_lock(); - if (fd == -1) { - clulog(LOG_CRIT, "#5: Couldn't connect to ccsd!\n"); - return -1; - } - - if (ccs_get(fd, "/cluster/@config_version", &val) == 0) { - pthread_mutex_lock(&config_mutex); - config_version = atoi(val); - pthread_mutex_unlock(&config_mutex); - free(val); - } - - if (ccs_get(fd, "/cluster/rm/@statusmax", &val) == 0) { - if (strlen(val)) - rg_set_statusmax(atoi(val)); - free(val); - } - - clulog(LOG_DEBUG, "Building Resource Trees\n"); - /* About to update the entire resource tree... */ - if (load_resources(fd, &reslist, &rulelist) != 0) { - clulog(LOG_CRIT, "#6: Error loading services\n"); - destroy_resources(&reslist); - destroy_resource_rules(&rulelist); - ccs_unlock(fd); - return -1; - } - - if (build_resource_tree(fd, &tree, &rulelist, &reslist) != 0) { - clulog(LOG_CRIT, "#7: Error building resource tree\n"); - destroy_resource_tree(&tree); - destroy_resources(&reslist); - destroy_resource_rules(&rulelist); - ccs_unlock(fd); - return -1; - } - - x = 0; - list_do(&reslist, res) { ++x; } while (!list_done(&reslist, res)); - clulog(LOG_DEBUG, "%d resources defined\n", x); - - clulog(LOG_DEBUG, "Loading Failover Domains\n"); - construct_domains(fd, &domains); - x = 0; - list_do(&domains, fod) { ++x; } while (!list_done(&domains, fod)); - clulog(LOG_DEBUG, "%d domains defined\n", x); - construct_events(fd, &evt); - cnt = 0; - if (evt) { - for (x=0; x <= evt->max_prio; x++) { - if (!evt->entries[x]) - continue; - - y = 0; - - list_do(&evt->entries[x], evp) { - ++y; - } while (!list_done(&evt->entries[x], evp)); - - cnt += y; - } - } - clulog(LOG_DEBUG, "%d events defined\n", cnt); - - - /* Reconfiguration done */ - ccs_unlock(fd); - - if (reconfigure) { - /* Calc tree deltas */ - pthread_rwlock_wrlock(&resource_lock); - resource_delta(&_resources, &reslist); - resource_tree_delta(&_tree, &tree); - pthread_rwlock_unlock(&resource_lock); - - do_condstops(); - } - - /* Swap in the new configuration */ - pthread_rwlock_wrlock(&resource_lock); - if (_tree) - destroy_resource_tree(&_tree); - _tree = tree; - if (_resources) - destroy_resources(&_resources); - _resources = reslist; - if (_rules) - destroy_resource_rules(&_rules); - _rules = rulelist; - if (_domains) - deconstruct_domains(&_domains); - _domains = domains; - if (master_event_table) - deconstruct_events(&master_event_table); - master_event_table = evt; - pthread_rwlock_unlock(&resource_lock); - - if (reconfigure) { - /* Switch to read lock and do the up-half of the - reconfig request */ - clulog(LOG_INFO, "Restarting changed resources.\n"); - do_condstarts(); - } else { - /* Do initial stop-before-start */ - clulog(LOG_INFO, "Initializing Services\n"); - rg_doall(RG_INIT, 1, "Initializing %s\n"); - clulog(LOG_INFO, "Services Initialized\n"); - rg_set_initialized(); - } - - return 0; -} - - -void -get_recovery_policy(char *rg_name, char *buf, size_t buflen) -{ - resource_t *res; - char *val; - - pthread_rwlock_rdlock(&resource_lock); - - strncpy(buf, "restart", buflen); - res = find_root_by_ref(&_resources, rg_name); - if (res) { - val = res_attr_value(res, "recovery"); - if (val) { - strncpy(buf, val, buflen); - } - } - - pthread_rwlock_unlock(&resource_lock); -} - - -int -get_service_property(char *rg_name, char *prop, char *buf, size_t buflen) -{ - int ret = 0; - resource_t *res; - char *val; - - memset(buf, 0, buflen); - -#if 0 - if (!strcmp(prop, "domain")) { - /* not needed */ - strncpy(buf, "", buflen); - } else if (!strcmp(prop, "autostart")) { - strncpy(buf, "1", buflen); - } else if (!strcmp(prop, "hardrecovery")) { - strncpy(buf, "0", buflen); - } else if (!strcmp(prop, "exclusive")) { - strncpy(buf, "0", buflen); - } else if (!strcmp(prop, "nfslock")) { - strncpy(buf, "0", buflen); - } else if (!strcmp(prop, "recovery")) { - strncpy(buf, "restart", buflen); - } else if (!strcmp(prop, "depend")) { - /* not needed */ - strncpy(buf, "", buflen); - } else { - /* not found / no defaults */ - ret = -1; - } -#endif - - pthread_rwlock_rdlock(&resource_lock); - res = find_root_by_ref(&_resources, rg_name); - if (res) { - val = res_attr_value(res, prop); - if (val) { - ret = 0; - strncpy(buf, val, buflen); - } - } - pthread_rwlock_unlock(&resource_lock); - -#if 0 - if (ret == 0) - printf("%s(%s, %s) = %s\n", __FUNCTION__, rg_name, prop, buf); - else - printf("%s(%s, %s) = NOT FOUND\n", __FUNCTION__, rg_name, prop); -#endif - - return ret; -} - - -int -add_restart(char *rg_name) -{ - resource_node_t *node; - int ret = 1; - - pthread_rwlock_rdlock(&resource_lock); - node = node_by_ref(&_tree, rg_name); - if (node) { - ret = restart_add(node->rn_restart_counter); - } - pthread_rwlock_unlock(&resource_lock); - - return ret; -} - - -int -check_restart(char *rg_name) -{ - resource_node_t *node; - int ret = 0; - - pthread_rwlock_rdlock(&resource_lock); - node = node_by_ref(&_tree, rg_name); - if (node) { - ret = restart_threshold_exceeded(node->rn_restart_counter); - } - pthread_rwlock_unlock(&resource_lock); - - return ret; -} - - -void -kill_resource_groups(void) -{ - pthread_rwlock_wrlock(&resource_lock); - - destroy_resource_tree(&_tree); - destroy_resources(&_resources); - destroy_resource_rules(&_rules); - deconstruct_domains(&_domains); - - pthread_rwlock_unlock(&resource_lock); -} diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c deleted file mode 100644 index b999c55..0000000 --- a/rgmanager/src/daemons/main.c +++ /dev/null @@ -1,982 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2004 - Copyright Mission Critical Linux, Inc. 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <magma.h> -#include <magmamsg.h> -#include <platform.h> -#include <ccs.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <rg_locks.h> -#include <fcntl.h> -#include <resgroup.h> -#include <clulog.h> -#include <msgsimple.h> -#include <vf.h> -#include <rg_queue.h> -#include <event.h> -#include <malloc.h> - -#define L_SYS (1<<1) -#define L_USER (1<<0) - -int configure_logging(int ccsfd); - -int daemon_init(char *); -int init_resource_groups(int); -void kill_resource_groups(void); -void set_my_id(uint64_t); -int eval_groups(int, uint64_t, int); -void graceful_exit(int); -void flag_shutdown(int sig); -void hard_exit(void); -int send_rg_states(int, int); -int check_config_update(void); -int svc_exists(char *); -int watchdog_init(void); -int32_t master_event_callback(char *key, uint64_t viewno, void *data, uint32_t datalen); - - -int running = 1, need_reconfigure = 0; -int shutdown_pending = 0; -char debug = 0; /* XXX* */ -static int signalled = 0; -static int status_poll_interval = 10; - -uint64_t next_node_id(cluster_member_list_t *membership, uint64_t me); - - -void -segfault(int sig) -{ - char ow[64]; - - snprintf(ow, sizeof(ow)-1, "PID %d Thread %d: SIGSEGV\n", getpid(), - gettid()); - write(2, ow, strlen(ow)); - while(1) - sleep(60); -} - - -int -send_exit_msg(uint64_t nodeid) -{ - int fd; - - fd = msg_open(nodeid, RG_PORT, 0, 5); - msg_send_simple(fd, RG_EXITING, 0, 0); - msg_close(fd); - - return 0; -} - - -/** - Notify other resource group managers that we're leaving, since - cluster membership is not necessarily tied to the members running - the rgmgr. - */ -int -notify_exiting(void) -{ - int x; - uint64_t partner; - cluster_member_list_t *membership; - - membership = member_list(); - if (!membership) - return 0; - - for (x = 0; x < membership->cml_count; x++) { - - partner = membership->cml_members[x].cm_id; - - if (partner == my_id() || - membership->cml_members[x].cm_state != STATE_UP) - continue; - - send_exit_msg(partner); - } - - cml_free(membership); - - return 0; -} - - -void -flag_reconfigure(int sig) -{ - need_reconfigure++; -} - - -/** - This updates our local membership view and handles whether or not we - should exit, as well as determines node transitions (thus, calling - node_event()). - - @see node_event - @return 0 - */ -int -membership_update(void) -{ - cluster_member_list_t *new_ml, *node_delta, *old_membership; - int x; - int me = 0; - - if (!rg_quorate()) - return 0; - - clulog(LOG_INFO, "Magma Event: Membership Change\n"); - - old_membership = member_list(); - new_ml = clu_member_list(RG_SERVICE_GROUP); - member_list_update(new_ml); - - clulog(LOG_DEBUG, "I am node 0x%llx\n", my_id()); - - /* - * Handle nodes lost. Do our local node event first. - */ - node_delta = memb_lost(old_membership, new_ml); - - me = memb_online(node_delta, my_id()); - if (me) { - /* Should not happen */ - clulog(LOG_INFO, "State change: LOCAL OFFLINE\n"); - cml_free(node_delta); - node_event_q(1, my_id(), STATE_DOWN, 1); - /* NOTREACHED */ - } - - for (x=0; node_delta && x < node_delta->cml_count; x++) { - - clulog(LOG_INFO, "State change: %s DOWN\n", - node_delta->cml_members[x].cm_name); - /* Don't bother evaluating anything resource groups are - locked. This is just a performance thing */ - if (!rg_locked()) { - node_event_q(0, node_delta->cml_members[x].cm_id, - STATE_DOWN, 1); - } else { - clulog(LOG_NOTICE, "Not taking action - services" - " locked\n"); - } - } - - /* Free nodes */ - cml_free(node_delta); - - /* - * Handle nodes gained. Do our local node event first. - */ - node_delta = memb_gained(old_membership, new_ml); - - me = memb_online(node_delta, my_id()); - if (me) { - clulog(LOG_INFO, "State change: Local UP\n"); - node_event_q(1, my_id(), STATE_UP, 1); - } - - for (x=0; node_delta && x < node_delta->cml_count; x++) { - - if (!memb_online(node_delta, - node_delta->cml_members[x].cm_id)) - continue; - - if (node_delta->cml_members[x].cm_id == my_id()) - continue; - - clulog(LOG_INFO, "State change: %s UP\n", - node_delta->cml_members[x].cm_name); - node_event_q(0, node_delta->cml_members[x].cm_id, - STATE_UP, 1); - } - - cml_free(node_delta); - cml_free(new_ml); - - rg_unlockall(L_SYS); - - return 0; -} - - -int -lock_commit_cb(char *key, uint64_t viewno, void *data, uint32_t datalen) -{ - char lockstate; - - if (datalen != 1) { - clulog(LOG_WARNING, "%s: invalid data length!\n", __FUNCTION__); - free(data); - return 0; - } - - lockstate = *(char *)data; - free(data); - - if (lockstate == 0) { - rg_unlockall(L_USER); /* Doing this multiple times - has no effect */ - clulog(LOG_NOTICE, "Resource Groups Unlocked\n"); - return 0; - } - - if (lockstate == 1) { - rg_lockall(L_USER); /* Doing this multiple times - has no effect */ - clulog(LOG_NOTICE, "Resource Groups Locked\n"); - return 0; - } - - clulog(LOG_DEBUG, "Invalid lock state in callback: %d\n", lockstate); - return 0; -} - - -int -do_lockreq(int fd, int req) -{ - int ret; - char state; - cluster_member_list_t *m = member_list(); - - state = (req==RG_LOCK)?1:0; - ret = vf_write(m, VFF_IGN_CONN_ERRORS, "rg_lockdown", &state, 1); - cml_free(m); - - if (ret == 0) { - msg_send_simple(fd, RG_SUCCESS, 0, 0); - } else { - msg_send_simple(fd, RG_FAIL, 0, 0); - } - - return 0; -} - - -/** - * Receive and process a message on a file descriptor and decide what to - * do with it. This function doesn't handle messages from the quorum daemon. - * - * @param fd File descriptor with a waiting message.S - * @return -1 - failed to receive/handle message, or invalid - * data received. 0 - handled message successfully. - * @see quorum_msg - */ -int -dispatch_msg(int fd, uint64_t nodeid) -{ - int ret; - uint64_t nid; - generic_msg_hdr msg_hdr; - SmMessageSt msg_sm; - rg_state_msg_t msg_rsm; - fd_set rfds; - struct timeval tv = { 0, 500000 }; - - /* Peek-a-boo */ - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - if (select(fd+1, &rfds, NULL, NULL, &tv) <= 0) { - clulog(LOG_WARNING, "Client timeout after new connection.\n"); - msg_close(fd); - return -1; - } - - ret = msg_peek(fd, &msg_hdr, sizeof(msg_hdr)); - if (ret != sizeof (generic_msg_hdr)) { - clulog(LOG_ERR, "#37: Error receiving message header\n"); - msg_close(fd); - return -1; - } - - /* Decode the header */ - swab_generic_msg_hdr(&msg_hdr); - if ((msg_hdr.gh_magic != GENERIC_HDR_MAGIC)) { - clulog(LOG_ERR, - "#38: Invalid magic: Wanted 0x%08x, got 0x%08x\n", - GENERIC_HDR_MAGIC, msg_hdr.gh_magic); - msg_close(fd); - return -1; - } - - switch (msg_hdr.gh_command) { - case RG_STATUS: - clulog(LOG_DEBUG, "Sending service states to fd%d\n",fd); - send_rg_states(fd, msg_hdr.gh_arg1); - break; - - - case RG_LOCK: - msg_receive_timeout(fd, &msg_hdr, sizeof(msg_hdr), 1); - if (rg_quorate()) { - do_lockreq(fd, RG_LOCK); - } - - msg_close(fd); - break; - - case RG_UNLOCK: - msg_receive_timeout(fd, &msg_hdr, sizeof(msg_hdr), 1); - if (rg_quorate()) { - do_lockreq(fd, RG_UNLOCK); - } - - msg_close(fd); - break; - - case RG_QUERY_LOCK: - msg_receive_timeout(fd, &msg_hdr, sizeof(msg_hdr), 1); - if (rg_quorate()) { - ret = (rg_locked() & L_USER) ? RG_LOCK : RG_UNLOCK; - msg_send_simple(fd, ret, 0, 0); - } - msg_close(fd); - break; - - - case RG_ACTION_REQUEST: - - ret = msg_receive_timeout(fd, &msg_sm, sizeof(msg_sm), - 10); - if (ret != sizeof(msg_sm)) { - clulog(LOG_ERR, - "#39: Error receiving entire request\n"); - msg_close(fd); - return -1; - } - - /* Decode SmMessageSt message */ - swab_SmMessageSt(&msg_sm); - - if (!svc_exists(msg_sm.sm_data.d_svcName)) { - msg_sm.sm_data.d_ret = RG_ENOSERVICE; - /* No such service! */ - swab_SmMessageSt(&msg_sm); - - if (msg_send(fd, &msg_sm, sizeof (SmMessageSt)) != - sizeof (SmMessageSt)) - clulog(LOG_ERR, "#40: Error replying to " - "action request.\n"); - break; - } - - if (central_events_enabled() && - msg_sm.sm_hdr.gh_arg1 != RG_ACTION_MASTER) { - - /* Centralized processing or request is from - clusvcadm */ - nid = event_master(); - if (nid != my_id()) { - /* Forward the message to the event master */ - forward_message(fd, &msg_sm, nid); - } else { - /* for us: queue it */ - /* return below is intentional; the - event engine will close the fd for us */ - user_event_q(msg_sm.sm_data.d_svcName, - msg_sm.sm_data.d_action, - msg_sm.sm_hdr.gh_arg1, - msg_sm.sm_hdr.gh_arg2, - msg_sm.sm_data.d_svcOwner, - fd); - } - - return 0; - } - - /* Queue request */ - rt_enqueue_request(msg_sm.sm_data.d_svcName, - msg_sm.sm_data.d_action, - fd, 0, msg_sm.sm_data.d_svcOwner, - msg_sm.sm_hdr.gh_arg1, - msg_sm.sm_hdr.gh_arg2); - break; - - case RG_EVENT: - ret = msg_receive_timeout(fd, &msg_rsm, sizeof(msg_rsm), 1); - - /* Service event. Run a dependency check */ - if (ret < (int)sizeof(rg_state_msg_t)) { - clulog(LOG_ERR, - "#39: Error receiving entire request (%d/%d)\n", - ret, (int)sizeof(rg_state_msg_t)); - msg_close(fd); - break; - } - - /* Decode SmMessageSt message */ - swab_rg_state_msg_t(&msg_rsm); - - /* Send to our rg event handler */ - rg_event_q(msg_rsm.rsm_state.rs_name, - msg_rsm.rsm_state.rs_state, - msg_rsm.rsm_state.rs_owner, - msg_rsm.rsm_state.rs_last_owner); - - msg_close(fd); - break; - - case RG_EXITING: - - clulog(LOG_NOTICE, "Member %d is now offline\n", (int)nodeid); - - /* Don't really need to do these */ - msg_receive_timeout(fd, &msg_hdr, sizeof(msg_hdr), 5); - swab_generic_msg_hdr(&msg_hdr); - msg_close(fd); - - member_set_state(nodeid, STATE_DOWN); - node_event_q(0, nodeid, STATE_DOWN, 1); - break; - - default: - clulog(LOG_DEBUG, "unhandled message request %d\n", - msg_hdr.gh_command); - msg_close(fd); - break; - } - return 0; -} - -/** - Grab a magma event off of the designated file descriptor - - @param fd File descriptor to check - @return Event - */ -int -handle_cluster_event(int fd) -{ - int ret; - - ret = clu_get_event(fd); - - switch(ret) { - case CE_NULL: - clulog(LOG_DEBUG, "NULL cluster event\n"); - break; - case CE_SUSPEND: - clulog(LOG_DEBUG, "Suspend Event\n"); - rg_lockall(L_SYS); - break; - case CE_MEMB_CHANGE: - clulog(LOG_DEBUG, "Membership Change Event\n"); - if (rg_quorate() && running) { - rg_unlockall(L_SYS); - membership_update(); - } - break; - case CE_QUORATE: - rg_set_quorate(); - rg_unlockall(L_SYS); - rg_unlockall(L_USER); - clulog(LOG_NOTICE, "Quorum Achieved\n"); - membership_update(); - break; - case CE_INQUORATE: - clulog(LOG_EMERG, "#1: Quorum Dissolved\n"); - rg_set_inquorate(); - member_list_update(NULL); /* Clear member list */ - rg_lockall(L_SYS); - rg_doall(RG_INIT, 1, "Emergency stop of %s"); - rg_set_uninitialized(); - break; - case CE_SHUTDOWN: - clulog(LOG_WARNING, "#67: Shutting down uncleanly\n"); - rg_set_inquorate(); - rg_doall(RG_INIT, 1, "Emergency stop of %s"); - exit(0); - } - - return ret; -} - - -void dump_threads(void); - -int -event_loop(int clusterfd) -{ - int newfd, fd, n, max; - fd_set rfds; - struct timeval tv; - uint64_t nodeid; - - tv.tv_sec = status_poll_interval; - tv.tv_usec = 0; - - if (signalled) { - signalled = 0; - /* - malloc_stats(); - dump_threads(); - */ - } - - while (running && (tv.tv_sec || tv.tv_usec)) { - FD_ZERO(&rfds); - max = msg_fill_fdset(&rfds, MSG_LISTEN, RG_PURPOSE); - FD_SET(clusterfd, &rfds); - if (clusterfd > max) - max = clusterfd; - - n = select(max + 1, &rfds, NULL, NULL, &tv); - - if (n <= 0) - break; - - while ((fd = msg_next_fd(&rfds)) != -1) { - - if (fd == clusterfd) { - handle_cluster_event(clusterfd); - continue; - } - - newfd = msg_accept(fd, 1, &nodeid); - - if (newfd == -1) - continue; - - if (rg_quorate()) { - /* Handle message */ - /* When request completes, the fd is closed */ - dispatch_msg(newfd, nodeid); - continue; - - } - - if (!rg_initialized()) { - msg_close(newfd); - continue; - } - - printf("Dropping connect: NO QUORUM\n"); - msg_close(newfd); - } - } - - if (need_reconfigure || check_config_update()) { - need_reconfigure = 0; - configure_logging(-1); - init_resource_groups(1); - return 0; - } - - /* Did we receive a SIGTERM? */ - if (n < 0) - return 0; - - /* No new messages. Drop in the status check requests. */ - if (n == 0 && rg_quorate()) { - do_status_checks(); - return 0; - } - - return 0; -} - - -void -flag_shutdown(int sig) -{ - shutdown_pending = 1; -} - - -void -hard_exit(void) -{ - rg_lockall(L_SYS); - rg_doall(RG_INIT, 1, "Emergency stop of %s"); - vf_shutdown(); - exit(1); -} - - -void -cleanup(int cluster_fd) -{ - rg_lockall(L_SYS); - rg_doall(RG_STOP_EXITING, 1, NULL); - vf_shutdown(); - kill_resource_groups(); - member_list_update(NULL); - clu_disconnect(cluster_fd); - msg_shutdown(); - notify_exiting(); -} - - - -void -statedump(int sig) -{ - signalled++; -} - - -void malloc_dump_table(size_t, size_t); - - -/* - * Configure logging based on data in cluster.conf - */ -int -configure_logging(int ccsfd) -{ - char *v; - char internal = 0; - int status_child_max = 0; - - if (ccsfd < 0) { - internal = 1; - ccsfd = ccs_connect(); - if (ccsfd < 0) - return -1; - } - - if (ccs_get(ccsfd, "/cluster/rm/@log_facility", &v) == 0) { - clu_set_facility(v); - free(v); - } - - if (ccs_get(ccsfd, "/cluster/rm/@log_level", &v) == 0) { - clu_set_loglevel(atoi(v)); - free(v); - } - - if (ccs_get(ccsfd, "/cluster/rm/@central_processing", &v) == 0) { - set_central_events(atoi(v)); - if (atoi(v)) - clulog(LOG_NOTICE, - "Centralized Event Processing enabled\n"); - free(v); - } - - if (ccs_get(ccsfd, "/cluster/rm/@status_poll_interval", &v) == 0) { - status_poll_interval = atoi(v); - if (status_poll_interval >= 1) { - clulog(LOG_NOTICE, - "Status Polling Interval set to %d\n", - status_poll_interval); - } else { - clulog(LOG_WARNING, "Ignoring illegal " - "status_poll_interval of %s\n", v); - status_poll_interval = 10; - } - - free(v); - } - - if (ccs_get(ccsfd, "/cluster/rm/@status_child_max", &v) == 0) { - status_child_max = atoi(v); - if (status_child_max >= 1) { - clulog(LOG_NOTICE, - "Status Child Max set to %d\n", - status_child_max); - rg_set_childmax(status_child_max); - } else { - clulog(LOG_WARNING, "Ignoring illegal " - "status_child_max of %s\n", v); - } - - free(v); - } - - if (internal) - ccs_disconnect(ccsfd); - - return 0; -} - - -void -wait_for_quorum(void) -{ - int fd, q; - - /* Do NOT log in */ - fd = clu_connect(RG_SERVICE_GROUP, 0); - - q = clu_quorum_status(RG_SERVICE_GROUP); - if (q & QF_QUORATE) { - clu_disconnect(fd); - return; - } - - /* - There are two ways to do this; this happens to be the simpler - of the two. The other method is to join with a NULL group - and log in -- this will cause the plugin to not select any - node group (if any exist). - */ - clulog(LOG_NOTICE, "Waiting for quorum to form\n"); - - while (! (q&QF_QUORATE)) { - sleep(2); - q = clu_quorum_status(RG_SERVICE_GROUP); - } - - clulog(LOG_NOTICE, "Quorum formed; resuming\n"); - clu_disconnect(fd); -} - - -void -set_nonblock(int fd) -{ - int flags; - - flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); -} - - -void * -shutdown_thread(void __attribute__ ((unused)) *arg) -{ - rg_lockall(L_SYS); - rg_doall(RG_STOP_EXITING, 1, NULL); - running = 0; - - pthread_exit(NULL); -} - - -void -wait_for_status(int pid, int fd, int timeout) -{ - struct timeval tv; - fd_set rfds; - int err; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = timeout; - tv.tv_usec = 0; - - if (select(fd + 1, &rfds, NULL, NULL, &tv) == 1) { - err = 0; - read(fd, &err, sizeof(err)); - exit(!!err); - /* could put in messages for waiting */ - } - exit(1); -} - - -#define notify_status(value) \ -do { \ - if (waittime) { \ - waiter = value; \ - write(waitpipe[1], &waiter, sizeof(waiter)); \ - close(waitpipe[0]); \ - close(waitpipe[1]); \ - } \ -} while(0) - - -int -main(int argc, char **argv) -{ - int cluster_fd, rv; - char foreground = 0; - int quorate; - int listen_fds[2], listeners, waittime = 0, waitpipe[2]; - int waiter; - uint64_t myNodeID; - pthread_t th; - - while ((rv = getopt(argc, argv, "fdt:")) != EOF) { - switch (rv) { - case 'd': - debug = 1; - break; - case 'f': - foreground = 1; - break; - case 't': - waittime = atoi(optarg); - if (waittime < 0) - waittime = 0; - break; - default: - break; - } - } - - /* - Set up logging / foreground mode, etc. - */ - if (debug) - clu_set_loglevel(LOG_DEBUG); - if (foreground) - clu_log_console(1); - - if (!foreground && (geteuid() == 0)) { - if (waittime) { - waitpipe[0] = -1; - waitpipe[1] = -1; - pipe(waitpipe); - waiter = fork(); - if (waiter > 0) - wait_for_status(waiter, waitpipe[0], waittime); - /* notreached by parent */ - } - - daemon_init(argv[0]); - if (!debug && !watchdog_init()) - clulog(LOG_NOTICE, "Failed to start watchdog\n"); - } - - /* - We need quorum before we can read the configuration data from - ccsd. - */ - wait_for_quorum(); - - /* - We know we're quorate. At this point, we need to - read the resource group trees from ccsd. - */ - configure_logging(-1); - clulog(LOG_NOTICE, "Resource Group Manager Starting\n"); - - if (init_resource_groups(0) != 0) { - clulog(LOG_CRIT, "#8: Couldn't initialize services\n"); - notify_status(1); - return -1; - } - - /* - Connect to the cluster software. - */ - cluster_fd = clu_connect(RG_SERVICE_GROUP, 0); - if (cluster_fd < 0) { - clu_log_console(1); - clulog(LOG_CRIT, "#9: Couldn't connect to cluster\n"); - notify_status(2); - return -1; - } - msg_set_purpose(cluster_fd, MSGP_CLUSTER); - - clulog(LOG_DEBUG, "Using %s\n", clu_plugin_version()); - - setup_signal(SIGINT, flag_shutdown); - setup_signal(SIGTERM, flag_shutdown); - setup_signal(SIGUSR1, statedump); - unblock_signal(SIGCHLD); - setup_signal(SIGPIPE, SIG_IGN); - if (debug) { - setup_signal(SIGSEGV, segfault); - } else { - unblock_signal(SIGSEGV); - } - - if ((listeners = msg_listen(RG_PORT, RG_PURPOSE, - listen_fds, 2)) <= 0) { - clulog(LOG_CRIT, "#10: Couldn't set up listen socket\n"); - notify_status(3); - return -1; - } - - for (rv = 0; rv < listeners; rv++) - set_nonblock(listen_fds[rv]); - quorate = (clu_quorum_status(RG_SERVICE_GROUP) & QF_QUORATE); - - if (quorate) { - rg_set_quorate(); - } - - clulog(LOG_DEBUG, "Cluster Status: %s\n", - quorate?"Quorate":"Inquorate"); - - clu_local_nodeid(NULL, &myNodeID); - set_my_id(myNodeID); - msg_set_nodeid(myNodeID); - - /* - Initialize the VF stuff. - */ - if (vf_init(myNodeID, RG_VF_PORT, NULL, NULL) != 0) { - clulog(LOG_CRIT, "#11: Couldn't set up VF listen socket\n"); - notify_status(4); - return -1; - } - - vf_key_init("rg_lockdown", 10, NULL, lock_commit_cb); - vf_key_init("Transition-Master", 10, NULL, master_event_callback); - - if (clu_login(cluster_fd, RG_SERVICE_GROUP) == -1) { - if (errno != ENOSYS) { - clu_log_console(1); - clulog(LOG_CRIT, - "#XX: Couldn't log in to service group!\n"); - } - /* Not all support node groups. If we don't support - node groups, don't try to fake it. */ - clulog(LOG_INFO, "Faking SG support\n"); - //have_groups = 0; - } else { - clulog(LOG_INFO, "Logged in SG "%s"\n", - RG_SERVICE_GROUP); - //have_groups = 1; - } - - /* - Get an initial membership view. - */ - membership_update(); - - /* - Do everything useful - */ - notify_status(0); - - while (running) { - event_loop(cluster_fd); - - if (shutdown_pending) { - /* Kill local socket; local requests need to - be ignored here */ - for (rv = 0; rv < listeners; rv++) - msg_close(listen_fds[rv]); - ++shutdown_pending; - clulog(LOG_NOTICE, "Shutting down\n"); - pthread_create(&th, NULL, shutdown_thread, NULL); - } - } - - clulog(LOG_NOTICE, "Shutting down\n"); - cleanup(cluster_fd); - clulog(LOG_NOTICE, "Shutdown complete, exiting\n"); - - /*malloc_dump_table(); */ /* Only works if alloc.c us used */ - /*malloc_stats();*/ - - exit(0); -} diff --git a/rgmanager/src/daemons/members.c b/rgmanager/src/daemons/members.c deleted file mode 100644 index 6fc1327..0000000 --- a/rgmanager/src/daemons/members.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <sets.h> -#include <pthread.h> -#include <magma.h> -#include <magmamsg.h> -#include <string.h> - - -static pthread_rwlock_t memblock = PTHREAD_RWLOCK_INITIALIZER; -static uint64_t myid = NODE_ID_NONE; -static cluster_member_list_t *membership = NULL; - -void -member_list_update(cluster_member_list_t *new_ml) -{ - pthread_rwlock_wrlock(&memblock); - if (membership) - cml_free(membership); - if (new_ml) - membership = cml_dup(new_ml); - else - membership = NULL; - msg_update(membership); - pthread_rwlock_unlock(&memblock); -} - - -void -member_set_state(uint64_t nid, int state) -{ - int x; - - pthread_rwlock_wrlock(&memblock); - if (membership) { - for (x = 0; x < membership->cml_count; x++) { - if (membership->cml_members[x].cm_id == nid) { - membership->cml_members[x].cm_state = state; - goto out; - } - } - } - -out: - pthread_rwlock_unlock(&memblock); -} - - -int -member_online(uint64_t nid) -{ - int x, ret = 0; - - pthread_rwlock_wrlock(&memblock); - if (membership) { - for (x = 0; x < membership->cml_count; x++) { - if (membership->cml_members[x].cm_id == nid) { - ret = membership->cml_members[x].cm_state; - goto out; - } - } - } - -out: - pthread_rwlock_unlock(&memblock); - return ret; -} - - -cluster_member_list_t * -member_list(void) -{ - cluster_member_list_t *ret = NULL; - pthread_rwlock_rdlock(&memblock); - if (membership) - ret = cml_dup(membership); - pthread_rwlock_unlock(&memblock); - return ret; -} - - -int -member_online_set(set_type_t **nodes, int *nodecount) -{ - int ret = 1, i; - - pthread_rwlock_rdlock(&memblock); - if (!membership) - goto out_unlock; - - *nodes = malloc(sizeof(set_type_t) * membership->cml_count); - if (!*nodes) - goto out_unlock; - - *nodecount = 0; - for (i = 0; i < membership->cml_count; i++) { - if (membership->cml_members[i].cm_state && - membership->cml_members[i].cm_id > 0) { - (*nodes)[*nodecount] = membership->cml_members[i].cm_id; - ++(*nodecount); - } - } - - ret = 0; -out_unlock: - pthread_rwlock_unlock(&memblock); - return ret; -} - - -char * -member_name(uint64_t id, char *buf, int buflen) -{ - char *n; - - if (!buf || !buflen) - return NULL; - - pthread_rwlock_rdlock(&memblock); - n = memb_id_to_name(membership, id); - if (n) { - strncpy(buf, n, buflen); - } else { - buf[0] = 0; - } - pthread_rwlock_unlock(&memblock); - return buf; -} - - -uint64_t -my_id(void) -{ - uint64_t me; - pthread_rwlock_rdlock(&memblock); - me = myid; - pthread_rwlock_unlock(&memblock); - return me; -} - - -void -set_my_id(uint64_t me) -{ - pthread_rwlock_wrlock(&memblock); - myid = me; - pthread_rwlock_unlock(&memblock); -} diff --git a/rgmanager/src/daemons/nodeevent.c b/rgmanager/src/daemons/nodeevent.c deleted file mode 100644 index 6b02ace..0000000 --- a/rgmanager/src/daemons/nodeevent.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <resgroup.h> -#include <rg_locks.h> -#include <gettid.h> -#include <assert.h> - -typedef struct __ne_q { - list_head(); - int ne_local; - uint64_t ne_nodeid; - int ne_state; -} nevent_t; - -int node_event(int, uint64_t, int); - -/** - * Node event queue. - */ -static nevent_t *event_queue = NULL; -static pthread_mutex_t ne_queue_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_t ne_thread = 0; - - -void * -node_event_thread(void *arg) -{ - nevent_t *ev; - - while (1) { - pthread_mutex_lock(&ne_queue_mutex); - ev = event_queue; - if (ev) - list_remove(&event_queue, ev); - else - break; /* We're outta here */ - pthread_mutex_unlock(&ne_queue_mutex); - - node_event(ev->ne_local, ev->ne_nodeid, ev->ne_state); - - free(ev); - } - - /* Mutex held */ - ne_thread = 0; - pthread_mutex_unlock(&ne_queue_mutex); - return NULL; -} - - -void -node_event_q(int local, uint64_t nodeID, int state) -{ - nevent_t *ev; - pthread_attr_t attrs; - - while (1) { - ev = malloc(sizeof(nevent_t)); - if (ev) { - break; - } - sleep(1); - } - - memset(ev,0,sizeof(*ev)); - - ev->ne_state = state; - ev->ne_local = local; - ev->ne_nodeid = nodeID; - - pthread_mutex_lock (&ne_queue_mutex); - list_insert(&event_queue, ev); - if (ne_thread == 0) { - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attrs, 262144); - - pthread_create(&ne_thread, &attrs, node_event_thread, NULL); - pthread_attr_destroy(&attrs); - } - pthread_mutex_unlock (&ne_queue_mutex); -} diff --git a/rgmanager/src/daemons/reslist.c b/rgmanager/src/daemons/reslist.c deleted file mode 100644 index 11c5122..0000000 --- a/rgmanager/src/daemons/reslist.c +++ /dev/null @@ -1,886 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include <libxml/xpath.h> -#include <ccs.h> -#include <stdlib.h> -#include <stdio.h> -#include <resgroup.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <list.h> -#include <restart_counter.h> -#include <reslist.h> -#include <pthread.h> -#ifndef NO_CCS -#include <clulog.h> -#endif - - -char *attr_value(resource_node_t *node, char *attrname); -char *rg_attr_value(resource_node_t *node, char *attrname); - -void -res_build_name(char *buf, size_t buflen, resource_t *res) -{ - snprintf(buf, buflen, "%s:%s", res->r_rule->rr_type, - res->r_attrs[0].ra_value); -} - -/** - Find and determine an attribute's value. - - @param res Resource node to look examine - @param attrname Attribute to retrieve. - @return value of attribute or NULL if not found - */ -char * -res_attr_value(resource_t *res, char *attrname) -{ - resource_attr_t *ra; - int x; - - for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { - if (strcmp(attrname, res->r_attrs[x].ra_name)) - continue; - - ra = &res->r_attrs[x]; - - if (ra->ra_flags & RA_INHERIT) - /* Can't check inherited resources */ - return NULL; - - return ra->ra_value; - } - - return NULL; -} - - -/** - Find and determine an attribute's value. Takes into account inherited - attribute flag, and append attribute flag, which isn't implemented yet. - - @param node Resource tree node to look examine - @param attrname Attribute to retrieve. - @param ptype Resource type to look for (if inheritance) - @return value of attribute or NULL if not found - */ -static char * -_attr_value(resource_node_t *node, char *attrname, char *ptype) -{ - resource_t *res; - resource_attr_t *ra; - char *c, p_type[32]; - ssize_t len; - int x; - - if (!node) - return NULL; - - res = node->rn_resource; - - /* Go up the tree if it's not the right parent type */ - if (ptype && strcmp(res->r_rule->rr_type, ptype)) - return _attr_value(node->rn_parent, attrname, ptype); - - for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { - if (strcmp(attrname, res->r_attrs[x].ra_name)) - continue; - - ra = &res->r_attrs[x]; - - if (!(ra->ra_flags & RA_INHERIT)) - return ra->ra_value; - /* - Handle resource_type%field to be more precise, so we - don't have to worry about this being a child - of an unexpected type. E.g. lots of things have the - "name" attribute. - */ - c = strchr(ra->ra_value, '%'); - if (!c) { - /* Someone doesn't care or uses older - semantics on inheritance */ - return _attr_value(node->rn_parent, ra->ra_value, - NULL); - } - - len = (c - ra->ra_value); - memset(p_type, 0, sizeof(p_type)); - memcpy(p_type, ra->ra_value, len); - - /* Skip the "%" and recurse */ - return _attr_value(node->rn_parent, ++c, p_type); - } - - return NULL; -} - - -char * -attr_value(resource_node_t *node, char *attrname) -{ - return _attr_value(node, attrname, NULL); -} - - -/** - Run to the top of the tree. Used to determine certain attributes of the - resource group in-line, during resource tree operations. - */ -char * -rg_attr_value(resource_node_t *node, char *attrname) -{ - for (; node->rn_parent; node = node->rn_parent); - return res_attr_value(node->rn_resource, attrname); -} - - -char * -primary_attr_value(resource_t *res) -{ - int x; - resource_attr_t *ra; - - for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { - ra = &res->r_attrs[x]; - - if (!(ra->ra_flags & RA_PRIMARY)) - continue; - - return ra->ra_value; - } - - return NULL; -} - - - -/** - Compare two resources. - - @param left Left resource - @param right Right resource - @return -1 on different resource, 0 if the same, 1 if different, - 2 if different, but only safe resources are different - - */ -int -rescmp(resource_t *left, resource_t *right) -{ - int x, y = 0, found = 0, ret = 0; - - - /* Completely different resource class... */ - if (strcmp(left->r_rule->rr_type, right->r_rule->rr_type)) { - return -1; - } - - /* - printf("Comparing %s:%s to %s:%s\n", - left->r_rule->rr_type, left->r_attrs[0].ra_value, - right->r_rule->rr_type, right->r_attrs[0].ra_value) - */ - - for (x = 0; left->r_attrs && left->r_attrs[x].ra_name; x++) { - - found = 0; - for (y = 0; right->r_attrs && right->r_attrs[y].ra_name; y++) { - if (!strcmp(right->r_attrs[y].ra_name, - left->r_attrs[x].ra_name)) - found = 1; - else - /* Different attribute name */ - continue; - - if (right->r_attrs[y].ra_flags != - left->r_attrs[x].ra_flags) { - /* Flags are different. Change in - resource agents? */ - /* - printf("* flags differ %08x vs %08x\n", - left->r_attrs[x].ra_flags, - right->r_attrs[y].ra_flags); - */ - return 1; - } - - if (strcmp(right->r_attrs[y].ra_value, - left->r_attrs[x].ra_value)) { - /* Different attribute value. */ - /* - printf("* different value for attr '%s':" - " '%s' vs '%s'", - right->r_attrs[y].ra_name, - left->r_attrs[x].ra_value, - right->r_attrs[y].ra_value); - */ - if (left->r_attrs[x].ra_flags & RA_RECONFIG) { - /* printf(" [SAFE]\n"); */ - ret = 2; - } else { - /* printf("\n"); */ - return 1; - } - } - } - - /* Attribute missing -> different attribute value. */ - if (!found) { - /* - printf("* Attribute '%s' deleted\n", - left->r_attrs[x].ra_name); - */ - return 1; - } - } - - /* Different attribute count */ - if (x != y) { - /* printf("* Attribute count differ (attributes added!) "); */ - return 1; - } - - /* All the same */ - return ret; -} - - -/** - Find a resource given its reference. A reference is the value of the - primary attribute. - - @param reslist List of resources to traverse. - @param type Type of resource to look for. - @param ref Reference - @return Resource matching type/ref or NULL if none. - */ -resource_t * -find_resource_by_ref(resource_t **reslist, char *type, char *ref) -{ - resource_t *curr; - int x; - - list_do(reslist, curr) { - if (strcmp(curr->r_rule->rr_type, type)) - continue; - - /* - This should be one operation - the primary attr - is generally at the head of the array. - */ - for (x = 0; curr->r_attrs && curr->r_attrs[x].ra_name; - x++) { - if (!(curr->r_attrs[x].ra_flags & RA_PRIMARY)) - continue; - if (strcmp(ref, curr->r_attrs[x].ra_value)) - continue; - - return curr; - } - } while (!list_done(reslist, curr)); - - return NULL; -} - - -/** - Find a root resource by ref (service, usually). No name is required. - Only one type of root resource may exist because of the primary - attribute flag - - @param reslist List of resources to traverse. - @param ref Reference - @return Resource matching type/ref or NULL if none. - */ -resource_t * -find_root_by_ref(resource_t **reslist, char *ref) -{ - resource_t *curr; - char ref_buf[128]; - char *type; - char *name = ref; - int x; - - snprintf(ref_buf, sizeof(ref_buf), "%s", ref); - - type = ref_buf; - if ((name = strchr(ref_buf, ':'))) { - *name = 0; - name++; - } else { - /* Default type */ - type = "service"; - name = ref; - } - - list_do(reslist, curr) { - - /* - This should be one operation - the primary attr - is generally at the head of the array. - */ - for (x = 0; curr->r_attrs && curr->r_attrs[x].ra_name; - x++) { - if (strcmp(type, curr->r_rule->rr_type)) - continue; - if (!(curr->r_attrs[x].ra_flags & RA_PRIMARY)) - continue; - if (strcmp(name, curr->r_attrs[x].ra_value)) - continue; - - return curr; - } - } while (!list_done(reslist, curr)); - - - return NULL; -} - - -/** - Store a resource in the resource list if it's legal to do so. - Otherwise, don't store it. - Note: This function needs to be rewritten; it's way too long and way - too indented. - - @param reslist Resource list to store the new resource. - @param newres Resource to store - @return 0 on succes; nonzero on failure. - */ -int -store_resource(resource_t **reslist, resource_t *newres) -{ - resource_t *curr; - int x, y; - - if (!*reslist) { - /* first resource */ - list_insert(reslist, newres); - return 0; - } - - list_do(reslist, curr) { - - if (strcmp(curr->r_rule->rr_type, newres->r_rule->rr_type)) - continue; - - for (x = 0; newres->r_attrs && newres->r_attrs[x].ra_name; - x++) { - /* - Look for conflicting primary/unique keys - */ - if (!(newres->r_attrs[x].ra_flags & - (RA_PRIMARY | RA_UNIQUE))) - continue; - - for (y = 0; curr->r_attrs[y].ra_name; y++) { - if (curr->r_attrs[y].ra_flags & RA_INHERIT) - continue; - - if (strcmp(curr->r_attrs[y].ra_name, - newres->r_attrs[x].ra_name)) - continue; - if (!strcmp(curr->r_attrs[y].ra_value, - newres->r_attrs[x].ra_value)) { - /* - Unique/primary is not unique - */ -#ifdef NO_CCS - printf("Error: " - "%s attribute collision. " - "type=%s attr=%s value=%s\n", - (newres->r_attrs[x].ra_flags& - RA_PRIMARY)?"Primary": - "Unique", - newres->r_rule->rr_type, - newres->r_attrs[x].ra_name, - newres->r_attrs[x].ra_value - ); -#else - clulog(LOG_ERR, - "%s attribute collision. " - "type=%s attr=%s value=%s\n", - (newres->r_attrs[x].ra_flags& - RA_PRIMARY)?"Primary": - "Unique", - newres->r_rule->rr_type, - newres->r_attrs[x].ra_name, - newres->r_attrs[x].ra_value - ); -#endif - return -1; - } - break; - } - } - } while (!list_done(reslist, curr)); - - list_insert(reslist, newres); - return 0; -} - - -/** - Execute an XPath query, returning the first match. Multiple matches are - ignored. Please be advised that this is quite inefficient. - - @param doc Loaded XML document to search - @param ctx Predefined XML XPath context - @param query Query to execute. - @return newly allocated pointer to value or NULL if not found. - */ -char * -xpath_get_one(xmlDocPtr doc, xmlXPathContextPtr ctx, char *query) -{ - char *val = NULL, *ret = NULL; - xmlXPathObjectPtr obj; - xmlNodePtr node; - size_t size = 0; - int nnv = 0; - - obj = xmlXPathEvalExpression((unsigned char *)query, ctx); - if (!obj) - return NULL; - if (!obj->nodesetval) - goto out; - if (obj->nodesetval->nodeNr <= 0) - goto out; - - node = obj->nodesetval->nodeTab[0]; - if(!node) - goto out; - - if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*")) || - ((node->type == XML_ELEMENT_NODE) && strstr(query, "child::*"))){ - if (node->children && node->children->content) - size = strlen((char *)node->children->content)+ - strlen((char *)node->name)+2; - else - size = strlen((char *)node->name)+2; - nnv = 1; - } else { - if (node->children && node->children->content) { - size = strlen((char *)node->children->content)+1; - } else { - goto out; - } - } - - val = (char *)malloc(size); - if(!val) - goto out; - memset(val, 0, size); - if (nnv) { - sprintf(val, "%s=%s", node->name, node->children ? - (char *)node->children->content:""); - } else { - sprintf(val, "%s", node->children ? node->children->content : - node->name); - } - - ret = val; -out: - xmlXPathFreeObject(obj); - - return ret; -} - - -/** - Obliterate a resource_t structure. - - @param res Resource to free. - */ -void -destroy_resource(resource_t *res) -{ - int x; - - if (res->r_name) - free(res->r_name); - - if (res->r_attrs) { - for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { - free(res->r_attrs[x].ra_name); - free(res->r_attrs[x].ra_value); - } - - free(res->r_attrs); - } - - if (res->r_actions) { - /* Don't free the strings; they're part of the rule */ - free(res->r_actions); - } - - free(res); -} - - - -/** - Obliterate a resource_t list. - - @param list Resource list to free. - */ -void -destroy_resources(resource_t **list) -{ - resource_t *res; - - while ((res = *list)) { - list_remove(list, res); - destroy_resource(res); - } -} - - -/** - Print a resource_t structure to stdout - - @param res Resource to print. - */ -void -print_resource(resource_t *res) -{ - int x; - - printf("Resource type: %s", res->r_rule->rr_type); - if (res->r_rule->rr_flags & RF_ROOT) - printf(" [ROOT]"); - if (res->r_flags & RF_INLINE) - printf(" [INLINE]"); - if (res->r_flags & RF_NEEDSTART) - printf(" [NEEDSTART]"); - if (res->r_flags & RF_NEEDSTOP) - printf(" [NEEDSTOP]"); - if (res->r_flags & RF_COMMON) - printf(" [COMMON]"); - if (res->r_flags & RF_RECONFIG) - printf(" [RECONFIG]"); - printf("\n"); - - if (res->r_rule->rr_maxrefs) - printf("Instances: %d/%d\n", res->r_refs, - res->r_rule->rr_maxrefs); - if (res->r_rule->rr_agent) - printf("Agent: %s\n", basename(res->r_rule->rr_agent)); - - printf("Attributes:\n"); - if (!res->r_attrs) { - printf(" - None -\n\n"); - return; - } - - for (x = 0; res->r_attrs[x].ra_name; x++) { - - if (!(res->r_attrs[x].ra_flags & RA_INHERIT)) { - printf(" %s = %s", res->r_attrs[x].ra_name, - res->r_attrs[x].ra_value); - } else { - printf(" %s", res->r_attrs[x].ra_name); - } - - if (!res->r_attrs[x].ra_flags) { - printf("\n"); - continue; - } - - printf(" ["); - if (res->r_attrs[x].ra_flags & RA_PRIMARY) - printf(" primary"); - if (res->r_attrs[x].ra_flags & RA_UNIQUE) - printf(" unique"); - if (res->r_attrs[x].ra_flags & RA_REQUIRED) - printf(" required"); - if (res->r_attrs[x].ra_flags & RA_RECONFIG) - printf(" reconfig"); - if (res->r_attrs[x].ra_flags & RA_INHERIT) - printf(" inherit("%s")", res->r_attrs[x].ra_value); - printf(" ]\n"); - } - - printf("\n"); -} - - -void * -act_dup(resource_act_t *acts) -{ - int x; - resource_act_t *newacts; - - for (x = 0; acts[x].ra_name; x++); - - ++x; - x *= sizeof(resource_act_t); - - newacts = malloc(x); - if (!newacts) - return NULL; - - memcpy(newacts, acts, x); - - return newacts; -} - - -/* Copied from resrules.c -- _get_actions */ -void -_get_actions_ccs(int ccsfd, char *base, resource_t *res) -{ - char xpath[256]; - int idx = 0; - char *act, *ret; - int interval, timeout, depth; - - do { - /* setting these to -1 prevents overwriting with 0 */ - interval = -1; - depth = -1; - act = NULL; - timeout = -1; - - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@name", base, ++idx); - -#ifndef NO_CCS - if (ccs_get(ccsfd, xpath, &act) != 0) -#else - if (conf_get(xpath, &act) != 0) -#endif - break; - - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@timeout", base, idx); -#ifndef NO_CCS - if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) { -#else - if (conf_get(xpath, &ret) == 0 && ret) { -#endif - timeout = expand_time(ret); - if (timeout < 0) - timeout = 0; - free(ret); - } - - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@interval", base, idx); -#ifndef NO_CCS - if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) { -#else - if (conf_get(xpath, &ret) == 0 && ret) { -#endif - interval = expand_time(ret); - if (interval < 0) - interval = 0; - free(ret); - } - - if (!strcmp(act, "status") || !strcmp(act, "monitor")) { - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@depth", base, idx); -#ifndef NO_CCS - if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) { -#else - if (conf_get(xpath, &ret) == 0 && ret) { -#endif - depth = atoi(ret); - if (depth < 0) - depth = 0; - - /* */ - if (ret[0] == '*') - depth = -1; - free(ret); - } - } - - if (store_action(&res->r_actions, act, depth, timeout, - interval) != 0) - free(act); - } while (1); -} - - -/** - Try to load all the attributes in our rule set. If none are found, - or an error occurs, return NULL and move on to the next one. - - @param ccsfd File descriptor connected to CCS - @param rule Resource rule set to use when looking for data - @param base Base XPath path to start with. - @return New resource if legal or NULL on failure/error - */ -resource_t * -load_resource(int ccsfd, resource_rule_t *rule, char *base) -{ - resource_t *res; - char ccspath[1024]; - char *attrname, *attr; - int x, found = 0, flags; - - res = malloc(sizeof(*res)); - if (!res) { - printf("Out of memory\n"); - return NULL; - } - - memset(res, 0, sizeof(*res)); - res->r_rule = rule; - - for (x = 0; res->r_rule->rr_attrs && - res->r_rule->rr_attrs[x].ra_name; x++) { - - flags = rule->rr_attrs[x].ra_flags; - attrname = strdup(rule->rr_attrs[x].ra_name); - if (!attrname) { - destroy_resource(res); - return NULL; - } - - /* - Ask CCS for the respective attribute - */ - attr = NULL; - snprintf(ccspath, sizeof(ccspath), "%s/@%s", base, attrname); - -#ifndef NO_CCS - if (ccs_get(ccsfd, ccspath, &attr) != 0) { -#else - if (conf_get(ccspath, &attr) != 0) { -#endif - - if (flags & (RA_REQUIRED | RA_PRIMARY)) { - /* Missing required attribute. We're done. */ - free(attrname); - destroy_resource(res); - return NULL; - } - - if (!(flags & RA_INHERIT)) { - /* - If we don't have the inherit flag, see if - we have a value anyway. If we do, - this value is the default value, and - should be used. - */ - if (!rule->rr_attrs[x].ra_value) { - free(attrname); - continue; - } - - /* Copy default value from resource rule */ - attr = strdup(rule->rr_attrs[x].ra_value); - } - } - - found = 1; - - /* - If we are supposed to inherit and we don't have an - instance of the specified attribute in CCS, then we - keep the inherit flag and use it as the attribute. - - However, if we _do_ have the attribute for this instance, - we drop the inherit flag and use the attribute. - */ - if (flags & RA_INHERIT) { - if (attr) { - flags &= ~RA_INHERIT; - } else { - attr = strdup(rule->rr_attrs[x].ra_value); - if (!attr) { - destroy_resource(res); - free(attrname); - return NULL; - } - } - } - - /* - Store the attribute. We'll ensure all required - attributes are present soon. - */ - if (attrname && attr) - store_attribute(&res->r_attrs, attrname, attr, flags); - } - - if (!found) { - destroy_resource(res); - return NULL; - } - - res->r_actions = act_dup(rule->rr_actions); - _get_actions_ccs(ccsfd, base, res); - - return res; -} - - -/** - Read all resources in the resource manager block in CCS. - - @param ccsfd File descriptor connected to CCS. - @param reslist Empty list to fill with resources. - @param rulelist List of rules to use when searching CCS. - @return 0 on success, nonzero on failure. - */ -int -load_resources(int ccsfd, resource_t **reslist, resource_rule_t **rulelist) -{ - int resID = 0; - resource_t *newres; - resource_rule_t *currule; - char tok[256]; - - list_do(rulelist, currule) { - - for (resID = 1; ; resID++) { - snprintf(tok, sizeof(tok), RESOURCE_BASE "/%s[%d]", - currule->rr_type, resID); - - newres = load_resource(ccsfd, currule, tok); - if (!newres) - break; - - if (store_resource(reslist, newres) != 0) { -#ifdef NO_CCS - printf("Error storing %s resource\n", - newres->r_rule->rr_type); -#else - clulog(LOG_ERR, - "Error storing %s resource\n", - newres->r_rule->rr_type); -#endif - - destroy_resource(newres); - } - - /* Just information */ - newres->r_flags = RF_DEFINED; - } - } while (!list_done(rulelist, currule)); - - return 0; -} - diff --git a/rgmanager/src/daemons/resrules.c b/rgmanager/src/daemons/resrules.c deleted file mode 100644 index 6102a6b..0000000 --- a/rgmanager/src/daemons/resrules.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include <libxml/xpath.h> -#include <ccs.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <resgroup.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <list.h> -#include <ctype.h> -#include <restart_counter.h> -#include <reslist.h> -#include <pthread.h> -#include <dirent.h> -#include <libgen.h> -#ifndef NO_CCS -#include <clulog.h> -#endif - - -/** - Store a new resource rule in the given rule list. - - @param rulelist List of rules to store new rule in. - @param newrule New rule to store. - @return 0 on success or -1 if rule with same name - already exists in rulelist - */ -int -store_rule(resource_rule_t **rulelist, resource_rule_t *newrule) -{ - resource_rule_t *curr; - - list_do(rulelist, curr) { - if (!strcmp(newrule->rr_type, curr->rr_type)) { -#ifdef NO_CCS - fprintf(stderr, "Error storing %s: Duplicate\n", - newrule->rr_type); -#else - clulog(LOG_ERR, "Error storing %s: Duplicate\n", - newrule->rr_type); -#endif - return -1; - } - if ((newrule->rr_flags & RF_ROOT) && - (curr->rr_flags & RF_ROOT)) { -#ifdef NO_CCS - fprintf(stderr, "Error storing %s: root " - "resource type %s exists already\n", - newrule->rr_type, curr->rr_type); -#else - clulog(LOG_ERR, "Error storing %s: root " - "resource type %s exists already\n", - newrule->rr_type, curr->rr_type); -#endif - return -1; - } - - } while (!list_done(rulelist, curr)); - - list_insert(rulelist, newrule); - return 0; -} - - -/** - Obliterate a resource_rule_t structure. - - @param rr Resource rule to free. - */ -void -destroy_resource_rule(resource_rule_t *rr) -{ - int x; - - if (rr->rr_type) - free(rr->rr_type); - if (rr->rr_agent) - free(rr->rr_agent); - if (rr->rr_version) - free(rr->rr_version); - - if (rr->rr_attrs) { - for (x = 0; rr->rr_attrs && - rr->rr_attrs[x].ra_name; x++) { - free(rr->rr_attrs[x].ra_name); - if (rr->rr_attrs[x].ra_value) - free(rr->rr_attrs[x].ra_value); - } - - free(rr->rr_attrs); - } - - if (rr->rr_actions) { - for (x = 0; rr->rr_actions && - rr->rr_actions[x].ra_name; x++) { - free(rr->rr_actions[x].ra_name); - } - - free(rr->rr_actions); - } - - if (rr->rr_childtypes) { - for (x = 0; rr->rr_childtypes && - rr->rr_childtypes[x].rc_name; x++) - free(rr->rr_childtypes[x].rc_name); - free(rr->rr_childtypes); - } - - free(rr); -} - - -/** - Destroy a list of resource rules. - - @param rules List of rules to destroy. - */ -void -destroy_resource_rules(resource_rule_t **rules) -{ - resource_rule_t *rr; - - while ((rr = *rules)) { - list_remove(rules, rr); - destroy_resource_rule(rr); - } -} - - -/** - Get and store the maxparents (max instances) attribute for a given - resource rule set. - - @param doc Pre-parsed XML document pointer. - @param ctx Pre-allocated XML XPath context pointer. - @param base XPath prefix to search - @param rr Resource rule to store new information in. - */ -void -_get_maxparents(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, - resource_rule_t *rr) -{ - char xpath[256]; - char *ret = NULL; - - snprintf(xpath, sizeof(xpath), - "%s/attributes/@maxinstances", - base); - ret = xpath_get_one(doc, ctx, xpath); - if (ret) { - rr->rr_maxrefs = atoi(ret); - if (rr->rr_maxrefs < 0) - rr->rr_maxrefs = 0; - free(ret); - } -} - - -/** - Get and store a bit field. - - @param doc Pre-parsed XML document pointer. - @param ctx Pre-allocated XML XPath context pointer. - @param base XPath prefix to search - @param rr Resource rule to store new information in. - */ -void -_get_rule_flag(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, - resource_rule_t *rr, char *flag, int bit) -{ - char xpath[256]; - char *ret = NULL; - - snprintf(xpath, sizeof(xpath), - "%s/attributes/@%s", - base, flag); - ret = xpath_get_one(doc, ctx, xpath); - if (ret) { - if (atoi(ret)) { - rr->rr_flags |= bit; - } else { - rr->rr_flags &= ~bit; - } - free(ret); - } -} - - -/** - Get and store the version - - @param doc Pre-parsed XML document pointer. - @param ctx Pre-allocated XML XPath context pointer. - @param base XPath prefix to search - @param rr Resource rule to store new information in. - */ -void -_get_version(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, - resource_rule_t *rr) -{ - char xpath[256]; - char *ret = NULL; - - snprintf(xpath, sizeof(xpath), "%s/@version", base); - ret = xpath_get_one(doc, ctx, xpath); - if (ret) { - rr->rr_version = ret; - free(ret); - } - rr->rr_version = NULL; -} - - -int -expand_time(char *val) -{ - int l = strlen(val); - char c = val[l - 1]; - int ret = atoi(val); - - if (ret <= 0) - return 0; - - if ((c >= '0') && (c <= '9')) - return ret; - - switch(c) { - case 'S': - case 's': - return (ret); - case 'M': - case 'm': - return (ret * 60); - case 'h': - case 'H': - return (ret * 3600); - case 'd': - case 'D': - return (ret * 86400); - case 'w': - case 'W': - return (ret * 604800); - case 'y': - case 'Y': - return (ret * 31536000); - } - - return ret; -} - - -/** - * Store a resource action - * @param actsp Action array; may be modified and returned! - * @param name Name of the action - * @param depth Resource depth (status/monitor; -1 means *ALL LEVELS* - * ... this means that only the highest-level check depth - * will ever be performed!) - * @param timeout Timeout (not used) - * @param interval Time interval for status/monitor - * @return 0 on success, -1 on failure - * - */ -int -store_action(resource_act_t **actsp, char *name, int depth, - int timeout, int interval) -{ - int x = 0, replace = 0; - resource_act_t *acts = *actsp; - - if (!name) - return -1; - - if (depth < 0 && timeout < 0 && interval < 0) - return -1; - - if (!acts) { - /* Can't create with anything < 0 */ - if (depth < 0 || timeout < 0 || interval < 0) - return -1; - - acts = malloc(sizeof(resource_act_t) * 2); - if (!acts) - return -1; - acts[0].ra_name = name; - acts[0].ra_depth = depth; - acts[0].ra_timeout = timeout; - acts[0].ra_interval = interval; - acts[0].ra_last = 0; - acts[1].ra_name = NULL; - - *actsp = acts; - return 0; - } - - for (x = 0; acts[x].ra_name; x++) { - if (!strcmp(acts[x].ra_name, name) && - (depth == acts[x].ra_depth || depth == -1)) { - printf("Replacing action '%s' depth %d: ", - name, acts[x].ra_depth); - if (timeout >= 0) { - printf("timeout: %d->%d ", - (int)acts[x].ra_timeout, - (int)timeout); - acts[x].ra_timeout = timeout; - } - if (interval >= 0) { - printf("interval: %d->%d", - (int)acts[x].ra_interval, - (int)interval); - acts[x].ra_interval = interval; - } - printf("\n"); - replace = 1; - } - } - - if (replace) - /* If we replaced something, we're done */ - return 1; - - /* Can't create with anything < 0 */ - if (depth < 0 || timeout < 0 || interval < 0) - return -1; - - acts = realloc(acts, sizeof(resource_act_t) * (x+2)); - if (!acts) - return -1; - - acts[x].ra_name = name; - acts[x].ra_depth = depth; - acts[x].ra_timeout = timeout; - acts[x].ra_interval = interval; - acts[x].ra_last = 0; - - acts[x+1].ra_name = NULL; - - *actsp = acts; - return 0; -} - - - -void -_get_actions(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, - resource_rule_t *rr) -{ - char xpath[256]; - int idx = 0; - char *act, *ret; - int interval, timeout, depth; - - do { - interval = 0; - depth = 0; - act = NULL; - timeout = 0; - - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@name", base, ++idx); - - act = xpath_get_one(doc,ctx,xpath); - if (!act) - break; - - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@timeout", base, idx); - ret = xpath_get_one(doc, ctx, xpath); - if (ret) { - timeout = expand_time(ret); - if (timeout < 0) - timeout = 0; - free(ret); - } - - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@interval", base, idx); - ret = xpath_get_one(doc, ctx, xpath); - if (ret) { - interval = expand_time(ret); - if (interval < 0) - interval = 0; - free(ret); - } - - if (!strcmp(act, "status") || !strcmp(act, "monitor")) { - snprintf(xpath, sizeof(xpath), - "%s/action[%d]/@depth", base, idx); - ret = xpath_get_one(doc, ctx, xpath); - if (ret) { - depth = atoi(ret); - if (depth < 0) - depth = 0; - free(ret); - } - } - - if (store_action(&rr->rr_actions, act, depth, timeout, - interval) != 0) - free(act); - } while (1); - - -} - - - - -/** - Store an attribute with the given name, value, and flags in a resource_t - structure. - XXX This could be rewritten to use the list macros. - - @param attrsp Attribute array to store new attribute in. - @param name Name of attribute (must be non-null) - @param value Value of attribute - @param flags Attribute flags, or 0 if none. - @return 0 on success, nonzero on error/failure - */ -int -store_attribute(resource_attr_t **attrsp, char *name, char *value, int flags) -{ - int x = 0; - resource_attr_t *attrs = *attrsp; - - if (!name) - return -1; - - if (!attrs) { - attrs = malloc(sizeof(resource_attr_t) * 2); - if (!attrs) - return -1; - attrs[0].ra_name = name; - attrs[0].ra_value = value; - attrs[0].ra_flags = flags; - attrs[1].ra_name = NULL; - attrs[1].ra_value= NULL; - - *attrsp = attrs; - return 0; - } - - for (x = 0; attrs[x].ra_name; x++); - - attrs = realloc(attrs, sizeof(resource_attr_t) * (x+2)); - if (!attrs) - return -1; - - /* Primary attribute goes first. This makes this interaction - with CCS work way faster. */ - if (flags & RA_PRIMARY) { - attrs[x].ra_name = attrs[0].ra_name; - attrs[x].ra_value = attrs[0].ra_value; - attrs[x].ra_flags = attrs[0].ra_flags; - attrs[0].ra_name = name; - attrs[0].ra_value = value; - attrs[0].ra_flags = flags; - } else { - attrs[x].ra_name = name; - attrs[x].ra_value = value; - attrs[x].ra_flags = flags; - } - attrs[x+1].ra_name = NULL; - attrs[x+1].ra_value = NULL; - - *attrsp = attrs; - return 0; -} - - -/** - Take the first unique + required attr and call it the 'primary' attr - for rgmanager. If there's no primary, index 0 becomes the primary attr. - */ -int -choose_primary(resource_attr_t *attrs) -{ - int x = 0, primary = 0; - int flags; - char *name, *val; - - if (!attrs) - return 0; - - for (x = 0; attrs[x].ra_name; x++) { - - if ((attrs[x].ra_flags & (RA_UNIQUE | RA_REQUIRED)) == - (RA_UNIQUE | RA_REQUIRED)) { - primary = x; - break; - } - } - - if (primary != 0) { - flags = attrs[primary].ra_flags | RA_PRIMARY; - name = attrs[primary].ra_name; - val = attrs[primary].ra_value; - - attrs[primary].ra_flags = attrs[0].ra_flags; - attrs[primary].ra_name = attrs[0].ra_name; - attrs[primary].ra_value = attrs[0].ra_value; - - attrs[0].ra_flags = flags; - attrs[0].ra_name = name; - attrs[0].ra_value = val; - } else { - attrs[0].ra_flags |= RA_PRIMARY; - } - - return 0; -} - -/** - Store a child type in the child array of a resource rule. - XXX Could be rewritten to use list macros. - - @param childp Child array. Might be modified. - @param name Name of child type - @param start Start level - @param stop Stop level - @param forbid Do NOT allow this child type to exist - @param flags set to 1 to note that it was defined inline - @return 0 on success, nonzero on failure - */ -int -store_childtype(resource_child_t **childp, char *name, int start, int stop, - int forbid, int flags) -{ - int x = 0; - resource_child_t *child = *childp; - - if (!name) - return -1; - - if (!child) { - child = malloc(sizeof(resource_child_t) * 2); - if (!child) - return -1; - child[0].rc_name = name; - child[0].rc_startlevel = start; - child[0].rc_stoplevel = stop; - child[0].rc_forbid = forbid; - child[0].rc_flags = flags; - child[1].rc_name = NULL; - - *childp = child; - return 0; - } - - for (x = 0; child[x].rc_name; x++); - - child = realloc(child, sizeof(resource_child_t) * (x+2)); - if (!child) - return -1; - - child[x].rc_name = name; - child[x].rc_startlevel = start; - child[x].rc_stoplevel = stop; - child[x].rc_forbid = forbid; - child[x].rc_flags = flags; - child[x+1].rc_name = NULL; - - *childp = child; - return 0; -} - - -/** - Print a resource_t structure to stdout - - @param rr Resource rule to print. - */ -void -print_resource_rule(resource_rule_t *rr) -{ - int x; - - printf("Resource Rules for "%s"", rr->rr_type); - if (rr->rr_flags & RF_ROOT) - printf(" [ROOT]"); - printf("\n"); - - if (rr->rr_version) - printf("OCF API Version: %s\n", rr->rr_version); - - if (rr->rr_maxrefs) - printf("Max instances: %d\n", rr->rr_maxrefs); - if (rr->rr_agent) - printf("Agent: %s\n", basename(rr->rr_agent)); - - printf("Flags: "); - if (rr->rr_flags) { - if (rr->rr_flags & RF_INIT) - printf("init_on_add "); - if (rr->rr_flags & RF_DESTROY) - printf("destroy_on_delete "); - } else { - printf("(none)"); - } - printf("\n"); - - printf("Attributes:\n"); - if (!rr->rr_attrs) { - printf(" - None -\n"); - goto actions; - } - - for (x = 0; rr->rr_attrs[x].ra_name; x++) { - printf(" %s", rr->rr_attrs[x].ra_name); - - if (!rr->rr_attrs[x].ra_flags && !rr->rr_attrs[x].ra_value) { - printf("\n"); - continue; - } - - if (rr->rr_attrs[x].ra_flags) { - printf(" ["); - if (rr->rr_attrs[x].ra_flags & RA_PRIMARY) - printf(" primary"); - if (rr->rr_attrs[x].ra_flags & RA_UNIQUE) - printf(" unique"); - if (rr->rr_attrs[x].ra_flags & RA_REQUIRED) - printf(" required"); - if (rr->rr_attrs[x].ra_flags & RA_INHERIT) - printf(" inherit"); - if (rr->rr_attrs[x].ra_flags & RA_RECONFIG) - printf(" reconfig"); - printf(" ]"); - } - - if (rr->rr_attrs[x].ra_value) - printf(" default="%s"\n", rr->rr_attrs[x].ra_value); - else - printf("\n"); - } - -actions: - printf("Actions:\n"); - if (!rr->rr_actions) { - printf(" - None -\n"); - goto children; - } - - for (x = 0; rr->rr_actions[x].ra_name; x++) { - printf(" %s\n", rr->rr_actions[x].ra_name); - if (rr->rr_actions[x].ra_timeout) - printf(" Timeout (hint): %d seconds\n", - (int)rr->rr_actions[x].ra_timeout); - if (rr->rr_actions[x].ra_depth) - printf(" OCF Check Depth (status/monitor): " - "%d seconds\n", - (int)rr->rr_actions[x].ra_depth); - if (rr->rr_actions[x].ra_interval) - printf(" Check Interval: %d seconds\n", - (int)rr->rr_actions[x].ra_interval); - } - - -children: - printf("Explicitly defined child resource types:\n"); - if (!rr->rr_childtypes) { - printf(" - None -\n\n"); - return; - } - for (x = 0; rr->rr_childtypes[x].rc_name; x++) { - printf(" %s", rr->rr_childtypes[x].rc_name); - if (rr->rr_childtypes[x].rc_forbid) { - printf(" (forbidden)\n"); - continue; - } - if (rr->rr_childtypes[x].rc_startlevel || - rr->rr_childtypes[x].rc_stoplevel) { - printf(" ["); - - if (rr->rr_childtypes[x].rc_startlevel) { - printf(" startlevel = %d", - rr->rr_childtypes[x].rc_startlevel); - } - - if (rr->rr_childtypes[x].rc_stoplevel) { - printf(" stoplevel = %d", - rr->rr_childtypes[x].rc_stoplevel); - } - printf(" ] "); - } - - printf("\n"); - } - - printf("\n"); -} - - -/** - Get and store attributes for a given instance of a resource rule. - - @param doc Pre-parsed XML document pointer. - @param ctx Pre-allocated XML XPath context pointer. - @param base XPath prefix to search - @param rr Resource rule to store new information in. - @return 0 - */ -int -_get_rule_attrs(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, - resource_rule_t *rr) -{ - char *ret, *attrname, *dflt = NULL, xpath[256]; - int x, flags, primary_found = 0; - - for (x = 1; 1; x++) { - snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@name", - base, x); - - ret = xpath_get_one(doc,ctx,xpath); - if (!ret) - break; - - flags = 0; - attrname = ret; - - /* - See if there's a default value. - */ - snprintf(xpath, sizeof(xpath), - "%s/parameter[%d]/content/@default", base, x); - dflt = xpath_get_one(doc,ctx,xpath); - - /* - See if this is either the primary identifier or - a required field. - */ - snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@required", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - if ((atoi(ret) != 0) || (ret[0] == 'y')) - flags |= RA_REQUIRED; - free(ret); - } - - /* - See if this is supposed to be unique - */ - snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@unique", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - if ((atoi(ret) != 0) || (ret[0] == 'y')) - flags |= RA_UNIQUE; - free(ret); - } - - snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@primary", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - if ((atoi(ret) != 0) || (ret[0] == 'y')) { - if (primary_found) { - free(ret); - printf("Multiple primary " - "definitions for " - "resource type %s\n", - rr->rr_type); - return -1; - } - flags |= RA_PRIMARY; - primary_found = 1; - } - free(ret); - } - - /* - See if this can be reconfigured on the fly without a - stop/start - */ - snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@reconfig", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - if ((atoi(ret) != 0) || (ret[0] == 'y')) - flags |= RA_RECONFIG; - free(ret); - } - - /* - See if this is supposed to be inherited - */ - snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@inherit", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - flags |= RA_INHERIT; - - if (flags & (RA_REQUIRED | RA_PRIMARY | RA_UNIQUE)) { - free(ret); - printf("Can not inherit and be primary, " - "unique, or required\n"); - return -1; - } - /* - don't free ret. Store as attr value. If we had - a default value specified from above, free it; - inheritance supercedes a specified default value. - */ - if (dflt) - free(dflt); - } else { - /* - Use default value, if specified, as the attribute - value. - */ - ret = dflt; - } - - /* - Store the attribute. We'll ensure all required - attributes are present soon. - */ - if (attrname) - store_attribute(&rr->rr_attrs, attrname, ret, flags); - } - - if (!primary_found) - choose_primary(rr->rr_attrs); - - return 0; -} - - -/** - Get and store attributes for a given instance of a resource. - - @param doc Pre-parsed XML document pointer. - @param ctx Pre-allocated XML XPath context pointer. - @param base XPath prefix to search - @param rr Resource rule to store new information in. - @return 0 - */ -int -_get_childtypes(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, - resource_rule_t *rr) -{ - char *ret, *childname, xpath[256]; - int x, startlevel = 0, stoplevel = 0, forbid = 0; - - for (x = 1; 1; x++) { - snprintf(xpath, sizeof(xpath), "%s/child[%d]/@type", - base, x); - - ret = xpath_get_one(doc,ctx,xpath); - if (!ret) - break; - - startlevel = stoplevel = forbid = 0; - childname = ret; - - /* - Try to get the start level if it exists - */ - snprintf(xpath, sizeof(xpath), "%s/child[%d]/@start", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - startlevel = atoi(ret); - free(ret); - } - - - /* - Try to get the stop level if it exists - */ - snprintf(xpath, sizeof(xpath), "%s/child[%d]/@stop", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - stoplevel = atoi(ret); - free(ret); - } - - /* - Get the 'forbidden' flag if it exists - */ - snprintf(xpath, sizeof(xpath), "%s/child[%d]/@forbid", - base, x); - if ((ret = xpath_get_one(doc,ctx,xpath))) { - forbid = atoi(ret); - free(ret); - } - - /* - Store the attribute. We'll ensure all required - attributes are present soon. - */ - if (childname) - store_childtype(&rr->rr_childtypes, childname, - startlevel, stoplevel, forbid, 0); - } - - return 0; -} - - -/** - Read a file from a stdout pipe. - */ -int -read_pipe(int fd, char **file, size_t *length) -{ - char buf[4096]; - int n, done = 0; - - *file = NULL; - *length = 0; - - while (!done) { - - n = read(fd, buf, sizeof(buf)); - if (n < 0) { - - if (errno == EINTR) - continue; - - if (*file) - free(*file); - return -1; - } - - if (n == 0 && (!*length)) - return 0; - - if (n == 0) { - done = 1; - } - - if (*file) - *file = realloc(*file, (*length) + n + done); - else - *file = malloc(n + done); - - if (!*file) - return -1; - - memcpy((*file) + (*length), buf, n); - *length += (done + n); - } - - /* Null terminator */ - (*file)[(*length) - 1] = 0; - - return 0; -} - - -xmlDocPtr -read_resource_agent_metadata(char *filename) -{ - int pid; - int _pipe[2]; - char *data; - size_t size; - xmlDocPtr doc; - - if (pipe(_pipe) == -1) - return NULL; - - pid = fork(); - if (pid == -1) { - close(_pipe[0]); - close(_pipe[1]); - } - - if (pid == 0) { - /* child */ - close(0); - close(1); - close(2); - - close(_pipe[0]); - dup2(_pipe[1], 1); - close(_pipe[1]); - - /* exec */ - execl(filename, filename, "meta-data", NULL); - exit(1); - } - - close(_pipe[1]); - /* parent */ - if (read_pipe(_pipe[0], &data, &size) == -1) { - close(_pipe[0]); - return NULL; - } - - waitpid(pid, NULL, 0); - close(_pipe[0]); - - if (!size) - return NULL; - - doc = xmlParseMemory(data, size); - free(data); - return doc; -} - - -/** - Load the XML rule set for a resource and store attributes, constructing - a new resource_t structure. - - @param filename File name to load rules from - @param rules Rule list to add new rules to - @return 0 - */ -int -load_resource_rulefile(char *filename, resource_rule_t **rules) -{ - resource_rule_t *rr = NULL; - xmlDocPtr doc = NULL; - xmlXPathContextPtr ctx = NULL; - int ruleid=0; - char *type; - char base[256]; - - doc = read_resource_agent_metadata(filename); - if (!doc) - return 0; - ctx = xmlXPathNewContext(doc); - - do { - /* Look for resource types */ - snprintf(base, sizeof(base), "/resource-agent[%d]/@name", - ++ruleid); - type = xpath_get_one(doc, ctx, base); - if (!type) - break; - - if (!strcasecmp(type, "action")) { -#ifdef NO_CCS - fprintf(stderr, - "Error: Resource type '%s' is reserved", - type); -#else - clulog(LOG_ERR, - "Error: Resource type '%s' is reserved", - type); -#endif - free(type); - break; - } - - rr = malloc(sizeof(*rr)); - if (!rr) - break; - memset(rr,0,sizeof(*rr)); - - rr->rr_flags = RF_INIT | RF_DESTROY; - rr->rr_type = type; - snprintf(base, sizeof(base), "/resource-agent[%d]", ruleid); - - /* - First, grab the global attributes if existent - */ - _get_version(doc, ctx, base, rr); - - snprintf(base, sizeof(base), - "/resource-agent[%d]/special[@tag="rgmanager"]", - ruleid); - _get_maxparents(doc, ctx, base, rr); - _get_rule_flag(doc, ctx, base, rr, "root", RF_ROOT); - _get_rule_flag(doc, ctx, base, rr, "init_on_add", RF_INIT); - _get_rule_flag(doc, ctx, base, rr, "destroy_on_delete", RF_DESTROY); - rr->rr_agent = strdup(filename); - - /* - Second, add the children fields - */ - _get_childtypes(doc, ctx, base, rr); - - /* - Get the OCF status check intervals/monitor. - */ - snprintf(base, sizeof(base), "/resource-agent[%d]/actions", - ruleid); - _get_actions(doc, ctx, base, rr); - - - /* - Last, load the attributes from our XML file and their - respective instantiations from CCS - */ - snprintf(base, sizeof(base), - "/resource-agent[%d]/parameters", ruleid); - if (_get_rule_attrs(doc, ctx, base, rr) < 0) { - destroy_resource_rule(rr); - rr = NULL; - } - - if (!rr) - continue; - - if (store_rule(rules, rr) != 0) { - destroy_resource_rule(rr); - rr = NULL; - } - } while (1); - - if (ctx) - xmlXPathFreeContext(ctx); - if (doc) - xmlFreeDoc(doc); - - return 0; -} - - -/** - Load all the resource rules we can find from our resource root - directory. - - @param rules Rule list to create/add to - @return 0 on success, -1 on failure. Sucess does not - imply any rules have been found; only that no - errors were encountered. - */ -int -load_resource_rules(const char *rpath, resource_rule_t **rules) -{ - DIR *dir; - struct dirent *de; - char *fn, *dot; - char path[2048]; - struct stat st_buf; - - dir = opendir(rpath); - if (!dir) - return -1; - - xmlInitParser(); - while ((de = readdir(dir))) { - - fn = basename(de->d_name); - if (!fn) - continue; - - /* Ignore files with common backup extension */ - if ((fn != NULL) && (strlen(fn) > 0) && - (fn[strlen(fn)-1] == '~')) - continue; - - /* Ignore hidden files */ - if (*fn == '.') - continue; - - dot = strrchr(fn, '.'); - if (dot) { - /* Ignore RPM installed save files, patches, - diffs, etc. */ - if (!strncasecmp(dot, ".rpm", 4)) { - fprintf(stderr, "Warning: " - "Ignoring %s/%s: Bad extension %s\n", - rpath, de->d_name, dot); - continue; - } - } - - snprintf(path, sizeof(path), "%s/%s", - rpath, de->d_name); - - if (stat(path, &st_buf) < 0) - continue; - - if (S_ISDIR(st_buf.st_mode)) - continue; - - if (st_buf.st_mode & (S_IXUSR|S_IXOTH|S_IXGRP)) { - //printf("Loading resource rule from %s\n", path); - load_resource_rulefile(path, rules); - } - } - xmlCleanupParser(); - - closedir(dir); - - return 0; -} - - -/** - Find a resource rule given its type. - - @param rulelist Rule list to search - @param type Rule type identifier - @return Resource rule or NULL if not found. - */ -resource_rule_t * -find_rule_by_type(resource_rule_t **rulelist, char *type) -{ - resource_rule_t *curr = NULL; - - list_do(rulelist, curr) { - if (!strcmp(curr->rr_type, type)) - return curr; - } while (!list_done(rulelist, curr)); - - return NULL; -} diff --git a/rgmanager/src/daemons/restart_counter.c b/rgmanager/src/daemons/restart_counter.c deleted file mode 100644 index c889c6d..0000000 --- a/rgmanager/src/daemons/restart_counter.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/* Time-based restart counters for rgmanager */ - -#include <stdio.h> -#include <list.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <time.h> -#include <restart_counter.h> - - - -#define RESTART_INFO_MAGIC 0x184820ab - -typedef struct { - list_head(); - time_t restart_time; -} restart_item_t; - -typedef struct { - int magic; - time_t expire_timeout; - int max_restarts; - int restart_count; - restart_item_t *restart_nodes; -} restart_info_t; - - -#define VALIDATE(arg, ret) \ -do { \ - if (!arg) {\ - errno = EINVAL; \ - return ret; \ - } \ - if (((restart_info_t *)arg)->magic != RESTART_INFO_MAGIC) {\ - errno = EINVAL; \ - return ret; \ - } \ -} while(0) - - -/* Remove expired restarts */ -static int -restart_timer_purge(restart_counter_t arg, time_t now) -{ - restart_info_t *restarts = (restart_info_t *)arg; - restart_item_t *i; - int x, done = 0; - - VALIDATE(arg, -1); - - /* No timeout */ - if (restarts->expire_timeout == 0) - return 0; - - do { - done = 1; - list_for(&restarts->restart_nodes, i, x) { - if ((now - i->restart_time) >= - restarts->expire_timeout) { - restarts->restart_count--; - list_remove(&restarts->restart_nodes, i); - done = 0; - break; - } - } - } while(!done); - - return 0; -} - - -int -restart_count(restart_counter_t arg) -{ - restart_info_t *restarts = (restart_info_t *)arg; - time_t now; - - VALIDATE(arg, -1); - now = time(NULL); - restart_timer_purge(arg, now); - return restarts->restart_count; -} - - -int -restart_threshold_exceeded(restart_counter_t arg) -{ - restart_info_t *restarts = (restart_info_t *)arg; - time_t now; - - VALIDATE(arg, -1); - now = time(NULL); - restart_timer_purge(arg, now); - if (restarts->restart_count >= restarts->max_restarts) - return 1; - return 0; -} - - -/* Add a restart entry to the list. Returns 1 if restart - count is exceeded */ -int -restart_add(restart_counter_t arg) -{ - restart_info_t *restarts = (restart_info_t *)arg; - restart_item_t *i; - time_t t; - - if (!arg) - /* No max restarts / threshold = always - ok to restart! */ - return 0; - - VALIDATE(arg, -1); - - i = malloc(sizeof(*i)); - if (!i) { - return -1; - } - - t = time(NULL); - i->restart_time = t; - - list_insert(&restarts->restart_nodes, i); - restarts->restart_count++; - - /* Check and remove old entries */ - restart_timer_purge(restarts, t); - - if (restarts->restart_count >= restarts->max_restarts) - return 1; - - return 0; -} - - -int -restart_clear(restart_counter_t arg) -{ - restart_info_t *restarts = (restart_info_t *)arg; - restart_item_t *i; - - VALIDATE(arg, -1); - while ((i = restarts->restart_nodes)) { - list_remove(&restarts->restart_nodes, i); - free(i); - } - - restarts->restart_count = 0; - - return 0; -} - - -restart_counter_t -restart_init(time_t expire_timeout, int max_restarts) -{ - restart_info_t *info; - - if (max_restarts < 0) { - errno = EINVAL; - return NULL; - } - - info = malloc(sizeof(*info)); - if (info == NULL) - return NULL; - - info->magic = RESTART_INFO_MAGIC; - info->expire_timeout = expire_timeout; - info->max_restarts = max_restarts; - info->restart_count = 0; - info->restart_nodes = NULL; - - return (void *)info; -} - - -int -restart_cleanup(restart_counter_t arg) -{ - VALIDATE(arg, -1); - restart_clear(arg); - free(arg); - return 0; -} diff --git a/rgmanager/src/daemons/restree.c b/rgmanager/src/daemons/restree.c deleted file mode 100644 index fab77f3..0000000 --- a/rgmanager/src/daemons/restree.c +++ /dev/null @@ -1,1711 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004-2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. - - Fix for #193859 - relocation of a service w/o umounting file-systems - by Navid Sheikhol-Eslami [ navid at redhat dot com ] -*/ -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include <libxml/xpath.h> -#include <ccs.h> -#include <rg_locks.h> -#include <stdlib.h> -#include <stdio.h> -#include <resgroup.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <list.h> -#include <restart_counter.h> -#include <reslist.h> -#include <pthread.h> -#include <clulog.h> -#include <assert.h> - -#ifdef INTERNAL_MALLOC -void malloc_zap_mutex(void); -#endif - -/* XXX from resrules.c */ -int store_childtype(resource_child_t **childp, char *name, int start, - int stop, int forbid, int flags); -int _res_op(resource_node_t **tree, resource_t *first, char *type, - void * __attribute__((unused))ret, int op); -static inline int -_res_op_internal(resource_node_t **tree, resource_t *first, - char *type, void *__attribute__((unused))ret, int realop, - resource_node_t *node); -void print_env(char **env); -static inline int _res_op_internal(resource_node_t **tree, resource_t *first, - char *type, void *__attribute__((unused))ret, int realop, - resource_node_t *node); - -/* XXX from reslist.c */ -void * act_dup(resource_act_t *acts); - - -/* XXX from reslist.c */ -void * act_dup(resource_act_t *acts); - - -/* XXX from reslist.c */ -void * act_dup(resource_act_t *acts); -time_t get_time(char *action, int depth, resource_node_t *node); - - - -const char *ocf_errors[] = { - "success", // 0 - "generic error", // 1 - "invalid argument(s)", // 2 - "function not implemented", // 3 - "insufficient privileges", // 4 - "program not installed", // 5 - "program not configured", // 6 - "not running", - NULL -}; - - -/* XXX MEGA HACK */ -#ifdef NO_CCS -static int _no_op_mode_ = 0; -void -_no_op_mode(int arg) -{ - _no_op_mode_ = arg; -} -#endif - - -/** - ocf_strerror - */ -const char * -ocf_strerror(int ret) -{ - if (ret >= 0 && ret < OCF_RA_MAX) - return ocf_errors[ret]; - - return "unspecified"; -} - - -/** - Destroys an environment variable array. - - @param env Environment var to kill - @see build_env - */ -static void -kill_env(char **env) -{ - int x; - - for (x = 0; env[x]; x++) - free(env[x]); - free(env); -} - - -/** - Adds OCF environment variables to a preallocated environment var array - - @param res Resource w/ additional variable stuff - @param args Preallocated environment variable array - @see build_env - */ -static void -add_ocf_stuff(resource_t *res, char **env, int depth, int refcnt) -{ - char ver[10]; - char *minor, *val; - size_t n; - - if (!res->r_rule->rr_version) - strncpy(ver, OCF_API_VERSION, sizeof(ver)-1); - else - strncpy(ver, res->r_rule->rr_version, sizeof(ver)-1); - - minor = strchr(ver, '.'); - if (minor) { - *minor = 0; - minor++; - } else - minor = "0"; - - /* - Store the OCF major version - */ - n = strlen(OCF_RA_VERSION_MAJOR_STR) + strlen(ver) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s", OCF_RA_VERSION_MAJOR_STR, ver); - *env = val; env++; - - /* - Store the OCF minor version - */ - n = strlen(OCF_RA_VERSION_MINOR_STR) + strlen(minor) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s", OCF_RA_VERSION_MINOR_STR, minor); - *env = val; env++; - - /* - Store the OCF root - */ - n = strlen(OCF_ROOT_STR) + strlen(OCF_ROOT) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s", OCF_ROOT_STR, OCF_ROOT); - *env = val; env++; - - /* - Store the OCF Resource Instance (primary attr) - */ - n = strlen(OCF_RESOURCE_INSTANCE_STR) + - strlen(res->r_rule->rr_type) + 1 + - strlen(res->r_attrs[0].ra_value) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s:%s", OCF_RESOURCE_INSTANCE_STR, - res->r_rule->rr_type, - res->r_attrs[0].ra_value); - *env = val; env++; - - /* - Store the OCF Resource Type - */ - n = strlen(OCF_RESOURCE_TYPE_STR) + - strlen(res->r_rule->rr_type) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s", OCF_RESOURCE_TYPE_STR, - res->r_rule->rr_type); - *env = val; env++; - - /* - Store the OCF Check Level (0 for now) - */ - snprintf(ver, sizeof(ver), "%d", depth); - n = strlen(OCF_CHECK_LEVEL_STR) + strlen(ver) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s", OCF_CHECK_LEVEL_STR, ver); - *env = val; env++; - - /* - Store the resource local refcnt (0 for now) - */ - snprintf(ver, sizeof(ver), "%d", refcnt); - n = strlen(OCF_REFCNT_STR) + strlen(ver) + 2; - val = malloc(n); - if (!val) - return; - snprintf(val, n, "%s=%s", OCF_REFCNT_STR, ver); - *env = val; env++; -} - - -/** - Allocate and fill an environment variable array. - - @param node Node in resource tree to use for parameters - @param depth Depth (status/monitor/etc.) - @return Newly allocated environment array or NULL if - one could not be formed. - @see kill_env res_exec add_ocf_stuff - */ -static char ** -build_env(resource_node_t *node, int depth, int refcnt) -{ - resource_t *res = node->rn_resource; - char **env; - char *val; - int x, attrs, n; - - for (attrs = 0; res->r_attrs && res->r_attrs[attrs].ra_name; attrs++); - attrs += 8; /* - Leave space for: - OCF_RA_VERSION_MAJOR - OCF_RA_VERSION_MINOR - OCF_ROOT - OCF_RESOURCE_INSTANCE - OCF_RESOURCE_TYPE - OCF_CHECK_LEVEL - OCF_RESKEY_RGMANAGER_meta_refcnt - (null terminator) - */ - - env = malloc(sizeof(char *) * attrs); - if (!env) - return NULL; - - memset(env, 0, sizeof(char *) * attrs); - - /* Reset */ - attrs = 0; - for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { - - val = attr_value(node, res->r_attrs[x].ra_name); - if (!val) - continue; - - /* Strlen of both + '=' + 'OCF_RESKEY' + '\0' terminator' */ - n = strlen(res->r_attrs[x].ra_name) + strlen(val) + 2 + - strlen(OCF_RES_PREFIX); - - env[attrs] = malloc(n); - if (!env[attrs]) { - kill_env(env); - return NULL; - } - - /* Prepend so we don't conflict with normal shell vars */ - snprintf(env[attrs], n, "%s%s=%s", OCF_RES_PREFIX, - res->r_attrs[x].ra_name, val); - -#if 0 - /* Don't uppercase; OCF-spec */ - for (n = 0; env[x][n] != '='; n++) - env[x][n] &= ~0x20; /* Convert to uppercase */ -#endif - ++attrs; - } - - add_ocf_stuff(res, &env[attrs], depth, refcnt); - - return env; -} - - -/** - Print info in an environment array - - @param env Environment to print. - */ -void -print_env(char **env) -{ - int x; - - for (x = 0; env[x]; x++) { - printf("%s\n", env[x]); - } -} - - -/** - Set all signal handlers to default for exec of a script. - ONLY do this after a fork(). - */ -void -restore_signals(void) -{ - sigset_t set; - int x; - - for (x = 1; x < _NSIG; x++) - signal(x, SIG_DFL); - - sigfillset(&set); - sigprocmask(SIG_UNBLOCK, &set, NULL); -} - - -/** Find the index for a given operation / depth in a resource node */ -int -res_act_index(resource_node_t *node, const char *op_str, int depth) -{ - int x = 0; - resource_act_t *act; - - for (x = 0; node->rn_actions[x].ra_name; x++) { - act = &node->rn_actions[x]; - if (depth != act->ra_depth) - continue; - if (strcasecmp(act->ra_name, op_str)) - continue; - return x; - } - - return -1; -} - - -/** - Execute a resource-specific agent for a resource node in the tree. - - @param node Resource tree node we're dealing with - @param op Operation to perform (stop/start/etc.) - @param depth OCF Check level/depth - @return Return value of script. - @see build_env - */ -int -res_exec(resource_node_t *node, int op, const char *arg, int depth) -{ - int childpid, pid; - int ret = 0; - int act_index; - time_t sleeptime = 0; - char **env = NULL; - resource_t *res = node->rn_resource; - const char *op_str = agent_op_str(op); - char fullpath[2048]; - - if (!res->r_rule->rr_agent) - return 0; - - /* Get the action index for later */ - act_index = res_act_index(node, op_str, depth); - - /* This shouldn't happen, but execing an action for which - we have an incorrect depth or no status action does not - indicate a problem. This allows people writing resource - agents to write agents which have no status/monitor function - at their option, in violation of the OCF RA API specification. */ - if (act_index < 0) - return 0; - -#ifdef DEBUG - env = build_env(node, depth, node->rn_resource->r_incarnations); - if (!env) - return -errno; -#endif - -#ifdef NO_CCS - if (_no_op_mode_) { - printf("[%s] %s:%s\n", op_str, res->r_rule->rr_type, - res->r_attrs->ra_value); - return 0; - } -#endif - - childpid = fork(); - if (childpid < 0) - return -errno; - - if (!childpid) { - /* Child */ -#ifdef INTERNAL_MALLOC - malloc_zap_mutex(); -#endif -#if 0 - printf("Exec of script %s, action %s type %s\n", - res->r_rule->rr_agent, agent_op_str(op), - res->r_rule->rr_type); -#endif - -#ifndef DEBUG - env = build_env(node, depth, node->rn_resource->r_incarnations); -#endif - - if (!env) - exit(-ENOMEM); - - if (res->r_rule->rr_agent[0] != '/') - snprintf(fullpath, sizeof(fullpath), "%s/%s", - RESOURCE_ROOTDIR, res->r_rule->rr_agent); - else - snprintf(fullpath, sizeof(fullpath), "%s", - res->r_rule->rr_agent); - - restore_signals(); - - if (arg) - execle(fullpath, fullpath, op_str, arg, NULL, env); - else - execle(fullpath, fullpath, op_str, NULL, env); - } - -#ifdef DEBUG - kill_env(env); -#endif - - if (node->rn_flags & RF_ENFORCE_TIMEOUTS) - sleeptime = node->rn_actions[act_index].ra_timeout; - - if (sleeptime > 0) { - - /* There's a better way to do this, but this is easy and - doesn't introduce signal woes */ - while (sleeptime) { - pid = waitpid(childpid, &ret, WNOHANG); - - if (pid == childpid) - break; - sleep(1); - --sleeptime; - } - - if (pid != childpid && sleeptime == 0) { - - clulog(LOG_ERR, - "%s on %s:%s timed out after %d seconds\n", - op_str, res->r_rule->rr_type, - res->r_attrs->ra_value, - node->rn_actions[act_index].ra_timeout, - ocf_strerror(ret)); - - /* This can't be guaranteed to kill even the child - process if the child is in disk-wait :( */ - kill(childpid, SIGKILL); - sleep(1); - pid = waitpid(childpid, &ret, WNOHANG); - if (pid == 0) { - clulog(LOG_ERR, - "Task %s PID %d did not exit " - "after SIGKILL\n", - op_str, childpid); - } - - /* Always an error if we time out */ - return 1; - } - } else { - do { - pid = waitpid(childpid, &ret, 0); - if ((pid < 0) && (errno == EINTR)) - continue; - } while (0); - } - - if (WIFEXITED(ret)) { - - ret = WEXITSTATUS(ret); - -#ifndef NO_CCS - if ((op == RS_STATUS && - node->rn_state == RES_STARTED && ret) || - (op != RS_STATUS && ret)) { -#else - if (ret) { -#endif - clulog(LOG_NOTICE, - "%s on %s "%s" returned %d (%s)\n", - op_str, res->r_rule->rr_type, - res->r_attrs->ra_value, ret, - ocf_strerror(ret)); - } - - return ret; - } - - if (!WIFSIGNALED(ret)) - assert(0); - - return -EFAULT; -} - - -static inline void -assign_restart_policy(resource_t *curres, resource_node_t *parent, - resource_node_t *node) -{ - char *val; - int max_restarts = 0; - time_t restart_expire_time = 0; - - node->rn_restart_counter = NULL; - - if (!curres || !node) - return; - if (parent) /* Non-parents don't get one for now */ - return; - - val = res_attr_value(curres, "max_restarts"); - if (!val) - return; - max_restarts = atoi(val); - if (max_restarts <= 0) - return; - val = res_attr_value(curres, "restart_expire_time"); - if (val) { - restart_expire_time = (time_t)expand_time(val); - if ((int64_t)restart_expire_time < 0) - return; - } - - node->rn_restart_counter = restart_init(restart_expire_time, - max_restarts); -} - - -static inline int -do_load_resource(int ccsfd, char *base, - resource_rule_t *rule, - resource_node_t **tree, - resource_t **reslist, - resource_node_t *parent, - resource_node_t **newnode) -{ - char tok[512]; - char *ref; - resource_node_t *node; - resource_t *curres; - - snprintf(tok, sizeof(tok), "%s/@ref", base); - -#ifndef NO_CCS - if (ccs_get(ccsfd, tok, &ref) != 0) { -#else - if (conf_get(tok, &ref) != 0) { -#endif - /* There wasn't an existing resource. See if there - is one defined inline */ - curres = load_resource(ccsfd, rule, base); - if (!curres) { - /* No ref and no new one inline == - no more of the selected type */ - return 1; - } - - if (store_resource(reslist, curres) != 0) { - printf("Error storing %s resource\n", - curres->r_rule->rr_type); - destroy_resource(curres); - return -1; - } - - curres->r_flags = RF_INLINE; - - } else { - - curres = find_resource_by_ref(reslist, rule->rr_type, - ref); - if (!curres) { - printf("Error: Reference to nonexistent " - "resource %s (type %s)\n", ref, - rule->rr_type); - free(ref); - return -1; - } - - if (curres->r_flags & RF_INLINE) { - printf("Error: Reference to inlined " - "resource %s (type %s) is illegal\n", - ref, rule->rr_type); - free(ref); - return -1; - } - free(ref); - } - - /* Load it if its max refs hasn't been exceeded */ - if (rule->rr_maxrefs && (curres->r_refs >= rule->rr_maxrefs)){ - printf("Warning: Max references exceeded for resource" - " %s (type %s)\n", curres->r_attrs[0].ra_name, - rule->rr_type); - return -1; - } - - node = malloc(sizeof(*node)); - if (!node) - return -1; - - memset(node, 0, sizeof(*node)); - - //printf("New resource tree node: %s:%s \n", curres->r_rule->rr_type,curres->r_attrs->ra_value); - - node->rn_child = NULL; - node->rn_parent = parent; - node->rn_resource = curres; - node->rn_state = RES_STOPPED; - node->rn_flags = 0; - node->rn_actions = (resource_act_t *)act_dup(curres->r_actions); - assign_restart_policy(curres, parent, node); - - snprintf(tok, sizeof(tok), "%s/@__independent_subtree", base); -#ifndef NO_CCS - if (ccs_get(ccsfd, tok, &ref) == 0) { -#else - if (conf_get(tok, &ref) == 0) { -#endif - if (atoi(ref) > 0 || strcasecmp(ref, "yes") == 0) - node->rn_flags |= RF_INDEPENDENT; - free(ref); - } - - snprintf(tok, sizeof(tok), "%s/@__enforce_timeouts", base); -#ifndef NO_CCS - if (ccs_get(ccsfd, tok, &ref) == 0) { -#else - if (conf_get(tok, &ref) == 0) { -#endif - if (atoi(ref) > 0 || strcasecmp(ref, "yes") == 0) - node->rn_flags |= RF_ENFORCE_TIMEOUTS; - free(ref); - } - - curres->r_refs++; - - *newnode = node; - - list_insert(tree, node); - - return 0; -} - - -/** - Build the resource tree. If a new resource is defined inline, add it to - the resource list. All rules, however, must have already been read in. - - @param ccsfd File descriptor connected to CCS - @param tree Tree to modify/insert on to - @param parent Parent node, if one exists. - @param rule Rule surrounding the new node - @param rulelist List of all rules allowed in the tree. - @param reslist List of all currently defined resources - @param base Base CCS path. - @see destroy_resource_tree - */ -#define RFL_FOUND 0x1 -#define RFL_FORBID 0x2 -static int -build_tree(int ccsfd, resource_node_t **tree, - resource_node_t *parent, - resource_rule_t *rule, - resource_rule_t **rulelist, - resource_t **reslist, char *base) -{ - char tok[512]; - resource_rule_t *childrule; - resource_node_t *node; - char *ref; - char *tmp; - int ccount = 0, x = 0, y = 0, flags = 0; - - //printf("DESCEND: %s / %s\n", rule?rule->rr_type:"(none)", base); - - /* Pass 1: typed / defined children */ - for (y = 0; rule && rule->rr_childtypes && - rule->rr_childtypes[y].rc_name; y++) { - - - flags = 0; - list_for(rulelist, childrule, x) { - if (strcmp(rule->rr_childtypes[y].rc_name, - childrule->rr_type)) - continue; - - flags |= RFL_FOUND; - - if (rule->rr_childtypes[y].rc_forbid) - flags |= RFL_FORBID; - - break; - } - - if (flags & RFL_FORBID) - /* Allow all *but* forbidden */ - continue; - - if (!(flags & RFL_FOUND)) - /* Not found? Wait for pass 2 */ - continue; - - //printf("looking for %s %s @ %s\n", - //rule->rr_childtypes[y].rc_name, - //childrule->rr_type, base); - for (x = 1; ; x++) { - - /* Search for base/type[x]/@ref - reference an existing - resource */ - snprintf(tok, sizeof(tok), "%s/%s[%d]", base, - childrule->rr_type, x); - - flags = 1; - switch(do_load_resource(ccsfd, tok, childrule, tree, - reslist, parent, &node)) { - case -1: - continue; - case 1: - /* 1 == no more */ - //printf("No resource found @ %s\n", tok); - flags = 0; - break; - case 0: - break; - } - if (!flags) - break; - - /* Got a child :: bump count */ - snprintf(tok, sizeof(tok), "%s/%s[%d]", base, - childrule->rr_type, x); - - /* Kaboom */ - build_tree(ccsfd, &node->rn_child, node, childrule, - rulelist, reslist, tok); - - } - } - - - /* Pass 2: untyped children */ - for (ccount=1; ; ccount++) { - snprintf(tok, sizeof(tok), "%s/child::*[%d]", base, ccount); - -#ifndef NO_CCS - if (ccs_get(ccsfd, tok, &ref) != 0) { -#else - if (conf_get(tok, &ref) != 0) { -#endif - /* End of the line. */ - //printf("End of the line: %s\n", tok); - break; - } - - tmp = strchr(ref, '='); - if (tmp) { - *tmp = 0; - } else { - /* no = sign... bad */ - free(ref); - continue; - } - - /* Find the resource rule */ - flags = 0; - list_for(rulelist, childrule, x) { - if (!strcasecmp(childrule->rr_type, ref)) { - /* Ok, matching rule found */ - flags = 1; - break; - } - } - /* No resource rule matching the child? Press on... */ - if (!flags) { - free(ref); - continue; - } - - flags = 0; - /* Don't descend on anything we should have already picked - up on in the above loop */ - for (y = 0; rule && rule->rr_childtypes && - rule->rr_childtypes[y].rc_name; y++) { - /* SKIP defined child types of any type */ - if (strcmp(rule->rr_childtypes[y].rc_name, ref)) - continue; - if (rule->rr_childtypes[y].rc_flags == 0) { - /* 2 = defined as a real child */ - flags = 2; - break; - } - - flags = 1; - break; - } - - free(ref); - if (flags == 2) - continue; - - x = 1; - switch(do_load_resource(ccsfd, tok, childrule, tree, - reslist, parent, &node)) { - case -1: - continue; - case 1: - /* no more found */ - x = 0; - printf("No resource found @ %s\n", tok); - break; - case 0: - /* another is found */ - break; - } - if (!x) /* no more found */ - break; - - /* childrule = rule set of this child at this point */ - /* tok = set above; if we got this far, we're all set */ - /* Kaboom */ - - build_tree(ccsfd, &node->rn_child, node, childrule, - rulelist, reslist, tok); - } - - //printf("ASCEND: %s / %s\n", rule?rule->rr_type:"(none)", base); - return 0; -} - - -/** - Set up to call build_tree. Hides the nastiness from the user. - - @param ccsfd File descriptor connected to CCS - @param tree Tree pointer. Should start as a pointer to NULL. - @param rulelist List of all rules allowed - @param reslist List of all currently defined resources - @return 0 - @see build_tree destroy_resource_tree - */ -int -build_resource_tree(int ccsfd, resource_node_t **tree, - resource_rule_t **rulelist, - resource_t **reslist) -{ - resource_node_t *root = NULL; - char tok[512]; - - snprintf(tok, sizeof(tok), "%s", RESOURCE_TREE_ROOT); - - /* Find and build the list of root nodes */ - build_tree(ccsfd, &root, NULL, NULL/*curr*/, rulelist, reslist, tok); - - if (root) - *tree = root; - - return 0; -} - - -/** - Deconstruct a resource tree. - - @param tree Tree to obliterate. - @see build_resource_tree - */ -void -destroy_resource_tree(resource_node_t **tree) -{ - resource_node_t *node; - - while ((node = *tree)) { - if ((*tree)->rn_child) - destroy_resource_tree(&(*tree)->rn_child); - - list_remove(tree, node); - - if (node->rn_restart_counter) { - restart_cleanup(node->rn_restart_counter); - } - - if(node->rn_actions){ - free(node->rn_actions); - } - free(node); - } -} - - -void -_print_resource_tree(resource_node_t **tree, int level) -{ - resource_node_t *node; - int x, y; - char *val; - - list_do(tree, node) { - for (x = 0; x < level; x++) - printf(" "); - - printf("%s", node->rn_resource->r_rule->rr_type); - if (node->rn_flags) { - printf(" [ "); - if (node->rn_flags & RF_NEEDSTOP) - printf("NEEDSTOP "); - if (node->rn_flags & RF_NEEDSTART) - printf("NEEDSTART "); - if (node->rn_flags & RF_COMMON) - printf("COMMON "); - if (node->rn_flags & RF_INDEPENDENT) - printf("INDEPENDENT "); - if (node->rn_flags & RF_ENFORCE_TIMEOUTS) - printf("ENFORCE-TIMEOUTS "); - printf("]"); - } - printf(" {\n"); - - for (x = 0; node->rn_resource->r_attrs && - node->rn_resource->r_attrs[x].ra_value; x++) { - val = attr_value(node, - node->rn_resource->r_attrs[x].ra_name); - if (!val) - continue; - - for (y = 0; y < level+1; y++) - printf(" "); - printf("%s = "%s";\n", - node->rn_resource->r_attrs[x].ra_name, - val); - } - - _print_resource_tree(&node->rn_child, level + 1); - - for (x = 0; x < level; x++) - printf(" "); - printf("}\n"); - } while (!list_done(tree, node)); -} - - -void -print_resource_tree(resource_node_t **tree) -{ - _print_resource_tree(tree, 0); -} - - -static inline int -_do_child_levels(resource_node_t **tree, resource_t *first, void *ret, - int op) -{ - resource_node_t *node = *tree; - resource_t *res = node->rn_resource; - resource_rule_t *rule = res->r_rule; - int l, lev, x, rv = 0; - - for (l = 1; l <= RESOURCE_MAX_LEVELS; l++) { - - for (x = 0; rule->rr_childtypes && - rule->rr_childtypes[x].rc_name; x++) { - - if(op == RS_STOP) - lev = rule->rr_childtypes[x].rc_stoplevel; - else - lev = rule->rr_childtypes[x].rc_startlevel; - - if (!lev || lev != l) - continue; - -#if 0 - printf("%s children of %s type %s (level %d)\n", - agent_op_str(op), - node->rn_resource->r_rule->rr_type, - rule->rr_childtypes[x].rc_name, l); -#endif - - /* Do op on all children at our level */ - rv |= _res_op(&node->rn_child, first, - rule->rr_childtypes[x].rc_name, - ret, op); - - if (rv & SFL_FAILURE && op != RS_STOP) - return rv; - } - - if (rv != 0 && op != RS_STOP) - return rv; - } - - return rv; -} - - -static inline int -_xx_child_internal(resource_node_t *node, resource_t *first, - resource_node_t *child, void *ret, int op) -{ - int x; - resource_rule_t *rule = node->rn_resource->r_rule; - - for (x = 0; rule->rr_childtypes && - rule->rr_childtypes[x].rc_name; x++) { - if (!strcmp(child->rn_resource->r_rule->rr_type, - rule->rr_childtypes[x].rc_name)) { - if (rule->rr_childtypes[x].rc_startlevel || - rule->rr_childtypes[x].rc_stoplevel) { - return 0; - } - } - } - - return _res_op_internal(&child, first, - child->rn_resource->r_rule->rr_type, - ret, op, child); -} - - -static inline int -_do_child_default_level(resource_node_t **tree, resource_t *first, - void *ret, int op) -{ - resource_node_t *node = *tree, *child; - int y, rv = 0; - - if (op == RS_START || op == RS_STATUS) { - list_for(&node->rn_child, child, y) { - rv |= _xx_child_internal(node, first, child, ret, op); - - if (rv & SFL_FAILURE) - return rv; - } - } else { - list_for_rev(&node->rn_child, child, y) { - rv |= _xx_child_internal(node, first, child, ret, op); - } - } - - return rv; -} - - - - - -/** - Nasty codependent function. Perform an operation by numerical level - at some point in the tree. This allows indirectly-dependent resources - (such as IP addresses and user scripts) to have ordering without requiring - a direct dependency. - - @param tree Resource tree to search/perform operations on - @param first Resource we're looking to perform the operation on, - if one exists. - @param ret Unused, but will be used to store status information - such as resources consumed, etc, in the future. - @param op Operation to perform if either first is found, - or no first is declared (in which case, all nodes - in the subtree). - @see _res_op res_exec - */ -int -_res_op_by_level(resource_node_t **tree, resource_t *first, void *ret, - int op) -{ - resource_node_t *node = *tree; - resource_t *res = node->rn_resource; - resource_rule_t *rule = res->r_rule; - int rv = 0; - - if (!rule->rr_childtypes) - return _res_op(&node->rn_child, first, NULL, ret, op); - - if (op == RS_START || op == RS_STATUS) { - rv |= _do_child_levels(tree, first, ret, op); - if (rv & SFL_FAILURE) - return rv; - - /* Start default level after specified ones */ - rv |= _do_child_default_level(tree, first, ret, op); - - } /* stop */ else { - - rv |= _do_child_default_level(tree, first, ret, op); - rv |= _do_child_levels(tree, first, ret, op); - } - - return rv; -} - - -void -mark_nodes(resource_node_t *node, int state, int flags) -{ - int x; - resource_node_t *child; - - list_for(&node->rn_child, child, x) { - if (child->rn_child) - mark_nodes(child->rn_child, state, flags); - } - - node->rn_state = state; - node->rn_flags |= (RF_NEEDSTART | RF_NEEDSTOP); -} - - -/** - Do a status on a resource node. This takes into account the last time the - status operation was run and selects the highest possible resource depth - to use given the elapsed time. - */ -int -do_status(resource_node_t *node) -{ - int x = 0, idx = -1; - int has_recover = 0; - time_t delta = 0, now = 0; - - now = time(NULL); - - for (; node->rn_actions[x].ra_name; x++) { - if (!has_recover && - !strcmp(node->rn_actions[x].ra_name, "recover")) { - has_recover = 1; - continue; - } - - if (strcmp(node->rn_actions[x].ra_name, "status")) - continue; - - delta = now - node->rn_actions[x].ra_last; - - /* - printf("%s:%s %s level %d interval = %d elapsed = %d\n", - node->rn_resource->r_rule->rr_type, - node->rn_resource->r_attrs->ra_value, - node->rn_actions[x].ra_name, node->rn_actions[x].ra_depth, - (int)node->rn_actions[x].ra_interval, (int)delta); - */ - - /* Ok, it's a 'status' action. See if enough time has - elapsed for a given type of status action */ - if (delta < node->rn_actions[x].ra_interval || - !node->rn_actions[x].ra_interval) - continue; - - if (idx == -1 || - node->rn_actions[x].ra_depth > node->rn_actions[idx].ra_depth) - idx = x; - } - - /* No check levels ready at the moment. */ - /* Cap status check children if configured to do so */ - if (idx == -1 || rg_inc_children() < 0) { - if (node->rn_checked) - return node->rn_last_status; - return 0; - } - - x = res_exec(node, RS_STATUS, NULL, node->rn_actions[idx].ra_depth); - rg_dec_children(); - - /* Record status check result *after* the status check has - * completed. */ - node->rn_actions[idx].ra_last = time(NULL); - - node->rn_last_status = x; - node->rn_last_depth = node->rn_actions[idx].ra_depth; - node->rn_checked = 1; - - if (x == 0) - return 0; - - if (!has_recover) - return x; - - /* Strange/failed status. Try to recover inline. */ - if ((x = res_exec(node, RS_RECOVER, NULL, 0)) == 0) - return 0; - - return x; -} - - -void -set_time(char *action, int depth, resource_node_t *node) -{ - time_t now; - int x = 0; - - time(&now); - - for (; node->rn_actions[x].ra_name; x++) { - - if (strcmp(node->rn_actions[x].ra_name, action) || - node->rn_actions[x].ra_depth != depth) - continue; - - node->rn_actions[x].ra_last = now; - break; - } -} - - -time_t -get_time(char *action, int depth, resource_node_t *node) -{ - int x = 0; - - for (; node->rn_actions[x].ra_name; x++) { - - if (strcmp(node->rn_actions[x].ra_name, action) || - node->rn_actions[x].ra_depth != depth) - continue; - - return node->rn_actions[x].ra_last; - } - - return (time_t)0; -} - - -void -clear_checks(resource_node_t *node) -{ - time_t now; - int x = 0; - resource_t *res = node->rn_resource; - - now = res->r_started; - - for (; node->rn_actions[x].ra_name; x++) { - - if (strcmp(node->rn_actions[x].ra_name, "monitor") && - strcmp(node->rn_actions[x].ra_name, "status")) - continue; - - node->rn_actions[x].ra_last = now; - } - - node->rn_checked = 0; - node->rn_last_status = 0; - node->rn_last_depth = 0; -} - - -/** - Nasty codependent function. Perform an operation by type for all siblings - at some point in the tree. This allows indirectly-dependent resources - (such as IP addresses and user scripts) to have ordering without requiring - a direct dependency. - - @param tree Resource tree to search/perform operations on - @param first Resource we're looking to perform the operation on, - if one exists. - @param type Type to look for. - @param ret Unused, but will be used to store status information - such as resources consumed, etc, in the future. - @param realop Operation to perform if either first is found, - or no first is declared (in which case, all nodes - in the subtree). - @see _res_op_by_level res_exec - */ -static inline int -_res_op_internal(resource_node_t **tree, resource_t *first, - char *type, void *__attribute__((unused))ret, int realop, - resource_node_t *node) -{ - int rv = 0, me, op; - - /* Restore default operation. */ - op = realop; - - /* If we're starting by type, do that funky thing. */ - if (type && strlen(type) && - strcmp(node->rn_resource->r_rule->rr_type, type)) - return 0; - - /* If the resource is found, all nodes in the subtree must - have the operation performed as well. */ - me = !first || (node->rn_resource == first); - - //printf("begin %s: %s %s [0x%x]\n", res_ops[op], - //node->rn_resource->r_rule->rr_type, - //primary_attr_value(node->rn_resource), - //node->rn_flags); - - if (me) { - /* - If we've been marked as a node which - needs to be started or stopped, clear - that flag and start/stop this resource - and all resource babies. - - Otherwise, don't do anything; look for - children with RF_NEEDSTART and - RF_NEEDSTOP flags. - - CONDSTART and CONDSTOP are no-ops if - the appropriate flag is not set. - */ - if ((op == RS_CONDSTART) && - (node->rn_flags & RF_NEEDSTART)) { - printf("Node %s:%s - CONDSTART\n", - node->rn_resource->r_rule->rr_type, - primary_attr_value(node->rn_resource)); - op = RS_START; - } - - if ((op == RS_CONDSTOP) && - (node->rn_flags & RF_NEEDSTOP)) { - printf("Node %s:%s - CONDSTOP\n", - node->rn_resource->r_rule->rr_type, - primary_attr_value(node->rn_resource)); - op = RS_STOP; - } - } - - /* Start starts before children */ - if (me && (op == RS_START)) { - - if (node->rn_flags & RF_RECONFIG && - realop == RS_CONDSTART) { - rv = res_exec(node, RS_RECONFIG, NULL, 0); - op = realop; /* reset to CONDSTART */ - } else { - rv = res_exec(node, op, NULL, 0); - } - node->rn_flags &= ~(RF_NEEDSTART | RF_RECONFIG); - if (rv != 0) { - node->rn_state = RES_FAILED; - return SFL_FAILURE; - } - - set_time("start", 0, node); - clear_checks(node); - - if (node->rn_state != RES_STARTED) { - ++node->rn_resource->r_incarnations; - node->rn_state = RES_STARTED; - } - } else if (me && (op == RS_STATUS)) { - /* Check status before children*/ - rv = do_status(node); - if (rv != 0) { - /* - If this node's status has failed, all of its - dependent children are failed, whether or not this - node is independent or not. - */ - mark_nodes(node, RES_FAILED, - RF_NEEDSTART | RF_NEEDSTOP); - - /* If we're an independent subtree, return a flag - stating that this section is recoverable apart - from siblings in the resource tree. All child - resources of this node must be restarted, - but siblings of this node are not affected. */ - if (node->rn_flags & RF_INDEPENDENT) - return SFL_RECOVERABLE; - - return SFL_FAILURE; - } - - } - - if (node->rn_child) { - rv |= _res_op_by_level(&node, me?NULL:first, ret, op); - - /* If one or more child resources are failed and at least one - of them is not an independent subtree then let's check if - if we are an independent subtree. If so, mark ourself - and all our children as failed and return a flag stating - that this section is recoverable apart from siblings in - the resource tree. */ - if (op == RS_STATUS && (rv & SFL_FAILURE) && - (node->rn_flags & RF_INDEPENDENT)) { - mark_nodes(node, RES_FAILED, - RF_NEEDSTART | RF_NEEDSTOP); - rv = SFL_RECOVERABLE; - } - } - - /* Stop should occur after children have stopped */ - if (me && (op == RS_STOP)) { - node->rn_flags &= ~RF_NEEDSTOP; - rv |= res_exec(node, op, NULL, 0); - - if (rv != 0) { - node->rn_state = RES_FAILED; - return SFL_FAILURE; - } - - if (node->rn_state != RES_STOPPED) { - --node->rn_resource->r_incarnations; - node->rn_state = RES_STOPPED; - } - } - - //printf("end %s: %s %s\n", res_ops[op], - //node->rn_resource->r_rule->rr_type, - //primary_attr_value(node->rn_resource)); - - return rv; -} - - -/** - Nasty codependent function. Perform an operation by type for all siblings - at some point in the tree. This allows indirectly-dependent resources - (such as IP addresses and user scripts) to have ordering without requiring - a direct dependency. - - @param tree Resource tree to search/perform operations on - @param first Resource we're looking to perform the operation on, - if one exists. - @param type Type to look for. - @param ret Unused, but will be used to store status information - such as resources consumed, etc, in the future. - @param realop Operation to perform if either first is found, - or no first is declared (in which case, all nodes - in the subtree). - @see _res_op_by_level res_exec - */ -int -_res_op(resource_node_t **tree, resource_t *first, - char *type, void * __attribute__((unused))ret, int realop) -{ - resource_node_t *node; - int count = 0, rv = 0; - - if (realop == RS_STOP) { - list_for_rev(tree, node, count) { - rv |= _res_op_internal(tree, first, type, ret, realop, - node); - } - } else { - list_for(tree, node, count) { - rv |= _res_op_internal(tree, first, type, ret, realop, - node); - - /* If we hit a problem during a 'status' op in an - independent subtree, rv will have the - SFL_RECOVERABLE bit set, but not SFL_FAILURE. - If we ever hit SFL_FAILURE during a status - operation, we're *DONE* - even if the subtree - is flagged w/ indy-subtree */ - - if (rv & SFL_FAILURE) - return rv; - } - } - - return rv; -} - -/** - Start all occurrences of a resource in a tree - - @param tree Tree to search for our resource. - @param res Resource to start/stop - @param ret Unused - */ -int -res_start(resource_node_t **tree, resource_t *res, void *ret) -{ - return _res_op(tree, res, NULL, ret, RS_START); -} - - -/** - Start all occurrences of a resource in a tree - - @param tree Tree to search for our resource. - @param res Resource to start/stop - @param ret Unused - */ -int -res_condstop(resource_node_t **tree, resource_t *res, void *ret) -{ - return _res_op(tree, res, NULL, ret, RS_CONDSTOP); -} - - -/** - Start all occurrences of a resource in a tree - - @param tree Tree to search for our resource. - @param res Resource to start/stop - @param ret Unused - */ -int -res_condstart(resource_node_t **tree, resource_t *res, void *ret) -{ - return _res_op(tree, res, NULL, ret, RS_CONDSTART); -} - - -/** - Stop all occurrences of a resource in a tree - - @param tree Tree to search for our resource. - @param res Resource to start/stop - @param ret Unused - */ -int -res_stop(resource_node_t **tree, resource_t *res, void *ret) -{ - return _res_op(tree, res, NULL, ret, RS_STOP); -} - - -/** - Check status of all occurrences of a resource in a tree - - @param tree Tree to search for our resource. - @param res Resource to start/stop - @param ret Unused - */ -int -res_status(resource_node_t **tree, resource_t *res, void *ret) -{ - return _res_op(tree, res, NULL, ret, RS_STATUS); -} - - -/** - Grab resource info for all occurrences of a resource in a tree - - @param tree Tree to search for our resource. - @param res Resource to start/stop - @param ret Unused - */ -int -res_resinfo(resource_node_t **tree, resource_t *res, void *ret) -{ - return _res_op(tree, res, NULL, ret, RS_RESINFO); -} - - -/** - Find the delta of two resource lists and flag the resources which need - to be restarted/stopped/started. - */ -int -resource_delta(resource_t **leftres, resource_t **rightres) -{ - resource_t *lc, *rc; - int ret; - - list_do(leftres, lc) { - rc = find_resource_by_ref(rightres, lc->r_rule->rr_type, - primary_attr_value(lc)); - - /* No restart. It's gone. */ - if (!rc) { - lc->r_flags |= RF_NEEDSTOP; - continue; - } - - /* Ok, see if the resource is the same */ - ret = rescmp(lc, rc); - if (ret == 0) { - rc->r_flags |= RF_COMMON; - continue; - } - - if (ret == 2) { - /* return of 2 from rescmp means - the two resources differ only - by reconfigurable bits */ - /* Do nothing on condstop phase; - do a "reconfig" instead of - "start" on conststart phase */ - rc->r_flags |= RF_COMMON; - rc->r_flags |= RF_NEEDSTART; - rc->r_flags |= RF_RECONFIG; - continue; - } - - rc->r_flags |= RF_COMMON; - - /* Resource has changed. Flag it. */ - lc->r_flags |= RF_NEEDSTOP; - rc->r_flags |= RF_NEEDSTART; - - } while (!list_done(leftres, lc)); - - /* Ok, if we weren't existing, flag as a needstart. */ - list_do(rightres, rc) { - if (rc->r_flags & RF_COMMON) - rc->r_flags &= ~RF_COMMON; - else - rc->r_flags |= RF_NEEDSTART; - } while (!list_done(rightres, rc)); - /* Easy part is done. */ - return 0; -} - - -/** - Part 2 of online mods: Tree delta. Ow. It hurts. It hurts. - We need to do this because resources can be moved from one RG - to another with nothing changing (not even refcnt!). - */ -int -resource_tree_delta(resource_node_t **ltree, resource_node_t **rtree) -{ - resource_node_t *ln, *rn; - int rc; - - list_do(ltree, ln) { - /* - Ok. Run down the left tree looking for obsolete resources. - (e.g. those that need to be stopped) - - If it's obsolete, continue. All children will need to be - restarted too, so we don't need to compare the children - of this node. - */ - if (ln->rn_resource->r_flags & RF_NEEDSTOP) { - ln->rn_flags |= RF_NEEDSTOP; - continue; - } - - /* - Ok. This particular node wasn't flagged. - */ - list_do(rtree, rn) { - - rc = rescmp(ln->rn_resource, rn->rn_resource); - - /* Wildly different resource? */ - if (rc <= -1) - continue; - - /* - If it needs to be started (e.g. it's been altered - or is new), then we don't really care about its - children. - */ - - if (rn->rn_resource->r_flags & RF_NEEDSTART) { - rn->rn_flags |= RF_NEEDSTART; - if ((rn->rn_resource->r_flags & RF_RECONFIG) == 0) - continue; - } - - if (rc == 0 || rc == 2) { - if (rc == 2) - rn->rn_flags |= RF_NEEDSTART | RF_RECONFIG; - - /* Ok, same resource. Recurse. */ - ln->rn_flags |= RF_COMMON; - rn->rn_flags |= RF_COMMON; - resource_tree_delta(&ln->rn_child, - &rn->rn_child); - } - - } while (!list_done(rtree, rn)); - - if (ln->rn_flags & RF_COMMON) - ln->rn_flags &= ~RF_COMMON; - else - ln->rn_flags |= RF_NEEDSTOP; - - } while (!list_done(ltree, ln)); - - /* - See if we need to start anything. Stuff which wasn't flagged - as COMMON needs to be started. - - As always, if we have to start a node, everything below it - must also be started. - */ - list_do(rtree, rn) { - if (rn->rn_flags & RF_COMMON) - rn->rn_flags &= ~RF_COMMON; - else - rn->rn_flags |= RF_NEEDSTART; - } while (!list_done(rtree, rn)); - - return 0; -} diff --git a/rgmanager/src/daemons/rg_event.c b/rgmanager/src/daemons/rg_event.c deleted file mode 100644 index 335d6d2..0000000 --- a/rgmanager/src/daemons/rg_event.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - Copyright Red Hat, Inc. 2006-2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <resgroup.h> -#include <rg_locks.h> -#include <gettid.h> -#include <assert.h> -#include <ccs.h> -#include <clulog.h> -#include <event.h> -#include <stdint.h> -#include <platform.h> -#include <magma.h> -#include <magmamsg.h> -#include <vf.h> -#include <time.h> - - -/** - * resource group event queue. - */ -static event_t *event_queue = NULL; -#ifdef WRAP_LOCKS -static pthread_mutex_t event_queue_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -static pthread_mutex_t mi_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -#else -static pthread_mutex_t event_queue_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t mi_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif -static pthread_cond_t event_queue_cond = PTHREAD_COND_INITIALIZER; -static pthread_t event_thread = 0; -static int transition_throttling = 5; -static int central_events = 0; - -extern int running; -static int _master = 0; -static void *_master_lock = NULL; -static int _xid = 0; -static event_master_t *mi = NULL; - -void hard_exit(void); -int init_resource_groups(int); -void flag_shutdown(int sig); -void flag_reconfigure(int sig); - -event_table_t *master_event_table = NULL; - - -void -set_transition_throttling(int nsecs) -{ - if (nsecs < 0) - nsecs = 0; - transition_throttling = nsecs; -} - - -void -set_central_events(int flag) -{ - central_events = flag; -} - - -int -central_events_enabled(void) -{ - return central_events; -} - - -/** - Called to handle the transition of a cluster member from up->down or - down->up. This handles initializing services (in the local node-up case), - exiting due to loss of quorum (local node-down), and service fail-over - (remote node down). This is the distributed node event processor; - for the local-only node event processor, see slang_event.c - - @param nodeID ID of the member which has come up/gone down. - @param nodeStatus New state of the member in question. - @see eval_groups - */ -void -node_event(int local, uint64_t nodeID, int nodeStatus, int clean) -{ - if (!running) - return; - - if (local) { - - /* Local Node Event */ - if (nodeStatus == 0) { - clulog(LOG_ERR, "Exiting uncleanly\n"); - hard_exit(); - } - - if (!rg_initialized()) { - if (init_resource_groups(0) != 0) { - clulog(LOG_ERR, - "#36: Cannot initialize services\n"); - hard_exit(); - } - } - - if (!running) { - clulog(LOG_NOTICE, "Processing delayed exit signal\n"); - return; - } - setup_signal(SIGINT, flag_shutdown); - setup_signal(SIGTERM, flag_shutdown); - setup_signal(SIGHUP, flag_reconfigure); - - eval_groups(1, nodeID, 1); - return; - } - - /* - * Nothing to do for events from other nodes if we are not ready. - */ - if (!rg_initialized()) { - clulog(LOG_DEBUG, "Services not initialized.\n"); - return; - } - - eval_groups(0, nodeID, nodeStatus); -} - - -/** - Callback from view-formation when a commit occurs for the Transition- - Master key. - */ -int32_t -master_event_callback(char *key, uint64_t viewno, - void *data, uint32_t datalen) -{ - event_master_t *m; - - m = data; - if (datalen != (uint32_t)sizeof(*m)) { - clulog(LOG_ERR, "%s: wrong size\n", __FUNCTION__); - return 1; - } - - swab_event_master_t(m); - if (m->m_magic != EVENT_MASTER_MAGIC) { - clulog(LOG_ERR, "%s: wrong size\n", __FUNCTION__); - return 1; - } - - if (m->m_nodeid == my_id()) - clulog(LOG_DEBUG, "Master Commit: I am master\n"); - else - clulog(LOG_DEBUG, "Master Commit: %d is master\n", m->m_nodeid); - - pthread_mutex_lock(&mi_mutex); - if (mi) - free(mi); - mi = m; - pthread_mutex_unlock(&mi_mutex); - - return 0; -} - - -/** - Read the Transition-Master key from vf if it exists. If it doesn't, - attempt to become the transition-master. - */ -static int -find_master(void) -{ - event_master_t *masterinfo = NULL; - void *data; - uint32_t sz; - cluster_member_list_t *m = NULL; - uint64_t vn; - int master_id = -1; - - m = member_list(); - if (vf_read(m, "Transition-Master", &vn, - (void **)(&data), &sz) < 0) { - clulog(LOG_ERR, "Unable to discover master" - " status\n"); - masterinfo = NULL; - } else { - masterinfo = (event_master_t *)data; - } - cml_free(m); - - if (masterinfo && (sz >= sizeof(*masterinfo))) { - swab_event_master_t(masterinfo); - if (masterinfo->m_magic == EVENT_MASTER_MAGIC) { - clulog(LOG_DEBUG, "Master Locate: %d is master\n", - masterinfo->m_nodeid); - pthread_mutex_lock(&mi_mutex); - if (mi) - free(mi); - mi = masterinfo; - pthread_mutex_unlock(&mi_mutex); - master_id = masterinfo->m_nodeid; - } - } - - return master_id; -} - - -/** - Return a copy of the cached event_master_t structure to the - caller. - */ -int -event_master_info_cached(event_master_t *mi_out) -{ - if (!central_events || !mi_out) { - errno = -EINVAL; - return -1; - } - - pthread_mutex_lock(&mi_mutex); - if (!mi) { - pthread_mutex_unlock(&mi_mutex); - errno = -ENOENT; - return -1; - } - - memcpy(mi_out, mi, sizeof(*mi)); - pthread_mutex_unlock(&mi_mutex); - return 0; -} - - -/** - Return the node ID of the master. If none exists, become - the master and return our own node ID. - */ -uint64_t -event_master(void) -{ - cluster_member_list_t *m = NULL; - event_master_t masterinfo; - uint64_t master_id = NODE_ID_NONE; - - /* We hold this forever. */ - if (_master) - return my_id(); - - m = member_list(); - pthread_mutex_lock(&mi_mutex); - - if (mi) { - master_id = mi->m_nodeid; - pthread_mutex_unlock(&mi_mutex); - if (memb_online(m, master_id)) { - //clulog(LOG_DEBUG, "%d is master\n", mi->m_nodeid); - goto out; - } - } - - pthread_mutex_unlock(&mi_mutex); - - memset(&_master_lock, 0, sizeof(_master_lock)); - if (clu_lock("Transition-Master", CLK_EX|CLK_NOWAIT, - &_master_lock) < 0) { - /* not us, find out who is master */ - master_id = find_master(); - goto out; - } - -#if 0 /* XXX */ - if (_master_lock.sb_status != 0) { - master_id = -1; - goto out; - } -#endif - - _master = 1; - - memset(&masterinfo, 0, sizeof(masterinfo)); - masterinfo.m_magic = EVENT_MASTER_MAGIC; - masterinfo.m_nodeid = my_id(); - masterinfo.m_master_time = (uint64_t)time(NULL); - swab_event_master_t(&masterinfo); - - if (vf_write(m, VFF_IGN_CONN_ERRORS | VFF_RETRY, - "Transition-Master", &masterinfo, - sizeof(masterinfo)) < 0) { - clulog(LOG_ERR, "Unable to advertise master" - " status to all nodes\n"); - } - - master_id = my_id(); -out: - if(m) - cml_free(m); - return master_id; -} - - - -void group_event(char *name, uint32_t state, int owner); - -/** - Event handling function. This only stays around as long as - events are on the queue. - */ -void * -_event_thread_f(void *arg) -{ - event_t *ev; - struct timeval now; - struct timespec expire; - int count = 0; - - /* Event thread usually doesn't hang around. When it's - spawned, sleep for this many seconds in order to let - some events queue up */ - if (transition_throttling && !central_events) { - sleep(transition_throttling); - } - - while (1) { - pthread_mutex_lock(&event_queue_mutex); - ev = event_queue; - if (!ev && !central_events) { - gettimeofday(&now, NULL); - expire.tv_sec = now.tv_sec + 5; - expire.tv_nsec = now.tv_usec * 1000; - pthread_cond_timedwait(&event_queue_cond, - &event_queue_mutex, - &expire); - ev = event_queue; - } - if (!ev) - break; /* We're outta here */ - - list_remove(&event_queue, ev); - - ++count; - pthread_mutex_unlock(&event_queue_mutex); - - if (ev->ev_type == EVENT_CONFIG) { - /* - clulog(LOG_NOTICE, "Config Event: %d -> %d\n", - ev->ev.config.cfg_oldversion, - ev->ev.config.cfg_version); - */ - init_resource_groups(1); - free(ev); - continue; - } - - if (central_events) { - /* If the master node died or there isn't - one yet, take the master lock. */ - if (event_master() == my_id()) { - slang_process_event(master_event_table, - ev); - } - free(ev); - continue; - /* ALL OF THE CODE BELOW IS DISABLED - when using central_events */ - } - - if (ev->ev_type == EVENT_RG) { - /* - clulog(LOG_NOTICE, "RG Event: %s %s %d\n", - ev->ev.group.rg_name, - rg_state_str(ev->ev.group.rg_state), - ev->ev.group.rg_owner); - */ - group_event(ev->ev.group.rg_name, - ev->ev.group.rg_state, - ev->ev.group.rg_owner); - } else if (ev->ev_type == EVENT_NODE) { - /* - clulog(LOG_NOTICE, "Node Event: %s %d %s %s\n", - ev->ev.node.ne_local?"Local":"Remote", - ev->ev.node.ne_nodeid, - ev->ev.node.ne_state?"UP":"DOWN", - ev->ev.node.ne_clean?"Clean":"Dirty") - */ - - node_event(ev->ev.node.ne_local, - ev->ev.node.ne_nodeid, - ev->ev.node.ne_state, - ev->ev.node.ne_clean); - } - - free(ev); - } - - if (!central_events || _master) { - clulog(LOG_DEBUG, "%d events processed\n", count); - } - /* Mutex held */ - event_thread = 0; - pthread_mutex_unlock(&event_queue_mutex); - pthread_exit(NULL); -} - - -static void -insert_event(event_t *ev) -{ - pthread_attr_t attrs; - pthread_mutex_lock (&event_queue_mutex); - ev->ev_transaction = ++_xid; - list_insert(&event_queue, ev); - if (event_thread == 0) { - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attrs, 262144); - - pthread_create(&event_thread, &attrs, _event_thread_f, NULL); - pthread_attr_destroy(&attrs); - } else { - pthread_cond_broadcast(&event_queue_cond); - } - pthread_mutex_unlock (&event_queue_mutex); -} - - -static event_t * -new_event(void) -{ - event_t *ev; - - while (1) { - ev = malloc(sizeof(*ev)); - if (ev) { - break; - } - sleep(1); - } - memset(ev,0,sizeof(*ev)); - ev->ev_type = EVENT_NONE; - - return ev; -} - - -void -rg_event_q(char *name, uint32_t state, uint64_t owner, uint64_t last) -{ - event_t *ev = new_event(); - - ev->ev_type = EVENT_RG; - - strncpy(ev->ev.group.rg_name, name, 128); - ev->ev.group.rg_state = state; - ev->ev.group.rg_owner = owner; - ev->ev.group.rg_last_owner = last; - - insert_event(ev); -} - - -void -node_event_q(int local, uint64_t nodeID, int state, int clean) -{ - event_t *ev = new_event(); - - ev->ev_type = EVENT_NODE; - ev->ev.node.ne_state = state; - ev->ev.node.ne_local = local; - ev->ev.node.ne_nodeid = nodeID; - ev->ev.node.ne_clean = clean; - insert_event(ev); -} - - -void -config_event_q(int old_version, int new_version) -{ - event_t *ev = new_event(); - - ev->ev_type = EVENT_CONFIG; - ev->ev.config.cfg_version = new_version; - ev->ev.config.cfg_oldversion = old_version; - insert_event(ev); -} - -void -user_event_q(char *svc, int request, - int arg1, int arg2, uint64_t target, int fd) -{ - event_t *ev = new_event(); - - ev->ev_type = EVENT_USER; - strncpy(ev->ev.user.u_name, svc, sizeof(ev->ev.user.u_name)); - ev->ev.user.u_request = request; - ev->ev.user.u_arg1 = arg1; - ev->ev.user.u_arg2 = arg2; - ev->ev.user.u_target = target; - ev->ev.user.u_fd = fd; - insert_event(ev); -} - diff --git a/rgmanager/src/daemons/rg_forward.c b/rgmanager/src/daemons/rg_forward.c deleted file mode 100644 index 0d7df55..0000000 --- a/rgmanager/src/daemons/rg_forward.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -//#define DEBUG -#include <magma.h> -#include <magmamsg.h> -#include <resgroup.h> -#include <rg_queue.h> -#include <platform.h> -#include <msgsimple.h> -#include <clulog.h> - - -struct fw_message { - SmMessageSt msg; - uint64_t nodeid; - int fd; - int unused; -}; - - -void -build_message(SmMessageSt *msgp, int action, char *svcName, uint64_t target) -{ - msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msgp->sm_hdr.gh_command = RG_ACTION_REQUEST; - msgp->sm_hdr.gh_length = sizeof(*msgp); - msgp->sm_data.d_action = action; - strncpy(msgp->sm_data.d_svcName, svcName, - sizeof(msgp->sm_data.d_svcName)); - msgp->sm_data.d_svcOwner = target; - msgp->sm_data.d_ret = 0; - - swab_SmMessageSt(msgp); -} - - -void * -forwarding_thread(void *arg) -{ - rg_state_t rgs; - request_t *req = (request_t *)arg; - void *lockp; - int fd, ret; - SmMessageSt msg; - cluster_member_list_t *m = NULL; - - if (rg_lock(req->rr_group, &lockp) != 0) { - msg_close(req->rr_resp_fd); - rq_free(req); - pthread_exit(NULL); - } - - if (get_rg_state(req->rr_group, &rgs) != 0) { - rg_unlock(req->rr_group, lockp); - msg_close(req->rr_resp_fd); - rq_free(req); - pthread_exit(NULL); - } - - rg_unlock(req->rr_group, lockp); - - /* Construct message */ - build_message(&msg, req->rr_request, req->rr_group, req->rr_target); - - /* - clulog(LOG_DEBUG, "Forwarding %s request to %d\n", - rg_req_str(req->rr_request), (int)rgs.rs_owner); - */ - - fd = msg_open(rgs.rs_owner, RG_PORT, RG_PURPOSE, 10); - if (fd == -1) { - msg_close(req->rr_resp_fd); - rq_free(req); - pthread_exit(NULL); - } - - if (msg_send(fd, &msg, sizeof(msg)) != sizeof(msg)) { - msg_close(fd); - msg_close(req->rr_resp_fd); - rq_free(req); - pthread_exit(NULL); - } - - /* - * Ok, we're forwarding a message to another node. Keep tabs on - * the node to make sure it doesn't die. Basically, wake up every - * now and again to make sure it's still online. If it isn't, send - * a response back to the caller. - */ - do { - ret = msg_receive_timeout(fd, &msg, sizeof(msg), 10); - if (ret < (int)sizeof(msg)) { - if (ret < 0 && errno == ETIMEDOUT) { - m = member_list(); - if (!memb_online(m, rgs.rs_owner)) { - msg.sm_data.d_ret = RG_ENODEDEATH; - /* we decode down below, - * so encode here */ - swab_SmMessageSt(&msg); - break; - } - cml_free(m); - m = NULL; - continue; - } - msg_close(fd); - msg_close(req->rr_resp_fd); - goto out; - } - break; - } while(1); - - if (m) - cml_free(m); - msg_close(fd); - - swab_SmMessageSt(&msg); - send_response(msg.sm_data.d_ret, req->rr_target, req); -out: - rq_free(req); - pthread_exit(NULL); -} - - -void -forward_request(request_t *req) -{ - pthread_t newthread; - pthread_attr_t attrs; - - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attrs, 262144); - - pthread_create(&newthread, &attrs, forwarding_thread, req); - pthread_attr_destroy(&attrs); -} - - -void * -forwarding_thread_v2(void *arg) -{ - int fd = -1, resp_fd = -1; - cluster_member_list_t *m = NULL; - SmMessageSt *msgp = NULL, msg; - int response_code = RG_EAGAIN, ret, target = -1; - int retries = 0; - struct fw_message *fwmsg = (struct fw_message *)arg; - - msgp = &fwmsg->msg; - resp_fd = fwmsg->fd; - target = fwmsg->nodeid; - - clulog(LOG_DEBUG, "FW: Forwarding SM request to %d\n", - target); - - if ((fd = msg_open(target, RG_PORT, RG_PURPOSE, 10)) < 0) { - clulog(LOG_DEBUG, "FW: Failed to open channel to %d: %s\n", - target, strerror(errno)); - goto out_fail; - } - - /* swap + send */ - swab_SmMessageSt(msgp); - if (msg_send(fd, msgp, sizeof(*msgp)) < sizeof(*msgp)) { - clulog(LOG_DEBUG, "FW: Failed to send message to %d fd %d: %s\n", - target, fd, strerror(errno)); - goto out_fail; - } - - - /* - * Ok, we're forwarding a message to another node. Keep tabs on - * the node to make sure it doesn't die. Basically, wake up every - * now and again to make sure it's still online. If it isn't, send - * a response back to the caller. - */ - do { - ret = msg_receive_timeout(fd, &msg, sizeof(msg), 10); - if (ret < (int)sizeof(msg)) { - if (ret < 0 && errno == ETIMEDOUT) { - if (!member_online(target)) { - response_code = RG_ENODE; - goto out_fail; - } - continue; - } - - if (ret == 0) - continue; - } - break; - } while(++retries < 60); /* old 600 second rule */ - - swab_SmMessageSt(&msg); - - response_code = msg.sm_data.d_ret; - target = msg.sm_data.d_svcOwner; - -out_fail: - free(fwmsg); - - if (resp_fd >= 0) { - send_ret(resp_fd, msgp->sm_data.d_svcName, response_code, - msgp->sm_data.d_action, target); - msg_close(resp_fd); - } - - if (fd >= 0) - msg_close(fd); - - pthread_exit(NULL); -} - - -void -forward_message(int fd, void *msgp, uint64_t nodeid) -{ - pthread_t newthread; - pthread_attr_t attrs; - struct fw_message *fwmsg; - - fwmsg = malloc(sizeof(struct fw_message)); - if (!fwmsg) { - msg_close(fd); - return; - } - - memcpy(&fwmsg->msg, msgp, sizeof(fwmsg->msg)); - fwmsg->fd = fd; - fwmsg->nodeid = nodeid; - - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attrs, 262144); - - pthread_create(&newthread, &attrs, forwarding_thread_v2, fwmsg); - pthread_attr_destroy(&attrs); -} diff --git a/rgmanager/src/daemons/rg_locks.c b/rgmanager/src/daemons/rg_locks.c deleted file mode 100644 index 759a2de..0000000 --- a/rgmanager/src/daemons/rg_locks.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <pthread.h> -#include <stdio.h> -#include <assert.h> -#ifdef NO_CCS -#include <libxml/xmlmemory.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <string.h> -char*xpath_get_one(xmlDocPtr, xmlXPathContextPtr, char *); -#else -#include <ccs.h> -#endif - -static int __rg_quorate = 0; -static int __rg_lock = 0; -static int __rg_threadcnt = 0; -static int __rg_initialized = 0; - -static int _rg_statuscnt = 0; -static int _rg_statusmax = 5; /* XXX */ - -static int _rg_childcnt = 0; -static int _rg_childmax = 0; /* XXX */ - -static pthread_cond_t unlock_cond = PTHREAD_COND_INITIALIZER; -static pthread_cond_t zero_cond = PTHREAD_COND_INITIALIZER; -static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER; - -#ifdef WRAP_LOCKS -static pthread_mutex_t locks_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -static pthread_mutex_t _ccs_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -#else -static pthread_mutex_t locks_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t _ccs_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - -#ifdef NO_CCS -static xmlDocPtr ccs_doc = NULL; -static char *conffile = "/etc/cluster/cluster.conf"; -#endif - -int -rg_initialized(void) -{ - int ret; - pthread_mutex_lock(&locks_mutex); - ret = __rg_initialized; - pthread_mutex_unlock(&locks_mutex); - return ret; -} - - -int -rg_set_initialized(void) -{ - pthread_mutex_lock(&locks_mutex); - __rg_initialized = 1; - pthread_cond_broadcast(&init_cond); - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_set_uninitialized(void) -{ - pthread_mutex_lock(&locks_mutex); - __rg_initialized = 0; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_wait_initialized(void) -{ - pthread_mutex_lock(&locks_mutex); - while (!__rg_initialized) - pthread_cond_wait(&init_cond, &locks_mutex); - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -/** - not sure if ccs is thread safe or not - */ -int -ccs_lock(void) -#ifndef NO_CCS -{ - int ret; - pthread_mutex_lock(&_ccs_mutex); - ret = ccs_connect(); - if (ret < 0) { - pthread_mutex_unlock(&_ccs_mutex); - return -1; - } - return ret; -} -#else /* No ccs support */ -{ - pthread_mutex_lock(&_ccs_mutex); - xmlInitParser(); - ccs_doc = xmlParseFile(conffile); - xmlCleanupParser(); - if (!ccs_doc) - return -1; - return 0; -} -#endif - - -int -ccs_unlock(int fd) -#ifndef NO_CCS -{ - int ret; - - ret = ccs_disconnect(fd); - pthread_mutex_unlock(&_ccs_mutex); - if (ret < 0) { - return -1; - } - return 0; -} -#else -{ - xmlFreeDoc(ccs_doc); - ccs_doc = NULL; - pthread_mutex_unlock(&_ccs_mutex); - return 0; -} - - -void -conf_setconfig(char *path) -{ - pthread_mutex_lock(&_ccs_mutex); - conffile = path; - pthread_mutex_unlock(&_ccs_mutex); -} - - -int -conf_get(char *path, char **value) -{ - char *foo; - xmlXPathContextPtr ctx; - - ctx = xmlXPathNewContext(ccs_doc); - foo = xpath_get_one(ccs_doc, ctx, path); - xmlXPathFreeContext(ctx); - - if (foo) { - *value = foo; - return 0; - } - return 1; -} -#endif - - -int -rg_lockall(int flag) -{ - pthread_mutex_lock(&locks_mutex); - if (!__rg_lock) - __rg_lock |= flag; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_locked(void) -{ - int ret; - pthread_mutex_lock(&locks_mutex); - ret = __rg_lock; - pthread_mutex_unlock(&locks_mutex); - return ret; -} - - -int -rg_unlockall(int flag) -{ - pthread_mutex_lock(&locks_mutex); - if (__rg_lock) - __rg_lock &= ~flag; - pthread_cond_broadcast(&unlock_cond); - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_set_quorate(void) -{ - pthread_mutex_lock(&locks_mutex); - if (!__rg_quorate) - __rg_quorate = 1; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_set_inquorate(void) -{ - pthread_mutex_lock(&locks_mutex); - if (__rg_quorate) - __rg_quorate = 0; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_quorate(void) -{ - int ret; - pthread_mutex_lock(&locks_mutex); - ret = __rg_quorate; - pthread_mutex_unlock(&locks_mutex); - return ret; -} - - -int -rg_inc_threads(void) -{ - pthread_mutex_lock(&locks_mutex); - ++__rg_threadcnt; -#ifdef DEBUG - printf("%s: %d threads active\n", __FILE__, __rg_threadcnt); -#endif - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_dec_threads(void) -{ - pthread_mutex_lock(&locks_mutex); - --__rg_threadcnt; - if (__rg_threadcnt <= 0) { - __rg_threadcnt = 0; - pthread_cond_broadcast(&zero_cond); - } -#ifdef DEBUG - printf("%s: %d threads active\n", __FILE__, __rg_threadcnt); -#endif - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_set_statusmax(int max) -{ - int old; - - if (max <= 3) - max = 3; - - pthread_mutex_lock(&locks_mutex); - old = _rg_statusmax; - _rg_statusmax = max; - pthread_mutex_unlock(&locks_mutex); - return old; -} - - -int -rg_inc_status(void) -{ - pthread_mutex_lock(&locks_mutex); - if (_rg_statuscnt >= _rg_statusmax) { - pthread_mutex_unlock(&locks_mutex); - return -1; - } - ++_rg_statuscnt; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_dec_status(void) -{ - pthread_mutex_lock(&locks_mutex); - --_rg_statuscnt; - if (_rg_statuscnt < 0) - _rg_statuscnt = 0; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_set_childmax(int max) -{ - int old; - - if (max <= 1) - max = 1; - - pthread_mutex_lock(&locks_mutex); - old = _rg_childmax; - _rg_childmax = max; - pthread_mutex_unlock(&locks_mutex); - return old; -} - - -int -rg_inc_children(void) -{ - pthread_mutex_lock(&locks_mutex); - if (_rg_childmax && (_rg_childcnt >= _rg_childmax)) { - pthread_mutex_unlock(&locks_mutex); - return -1; - } - ++_rg_childcnt; - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_dec_children(void) -{ - pthread_mutex_lock(&locks_mutex); - --_rg_childcnt; - if (_rg_childcnt < 0) { - assert(0); - _rg_childcnt = 0; - } - pthread_mutex_unlock(&locks_mutex); - return 0; -} - - -int -rg_wait_threads(void) -{ - pthread_mutex_lock(&locks_mutex); - if (__rg_threadcnt) - pthread_cond_wait(&zero_cond, &locks_mutex); - pthread_mutex_unlock(&locks_mutex); - return 0; -} diff --git a/rgmanager/src/daemons/rg_queue.c b/rgmanager/src/daemons/rg_queue.c deleted file mode 100644 index 3ea17b9..0000000 --- a/rgmanager/src/daemons/rg_queue.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <rg_queue.h> -#include <malloc.h> -#include <string.h> -#include <stdio.h> - - -int -_rq_queue_request(request_t **queue, char *name, uint32_t request, - uint32_t err, uint32_t oldreq, uint32_t fd, time_t when, - uint64_t target, uint32_t arg0, uint32_t arg1, char *file, - int line) -{ - request_t *req; - - req = malloc(sizeof(*req)); - if (!req) - return -1; - - if (name && strlen(name)) { - strncpy(req->rr_group, name, sizeof(req->rr_group)); - } - req->rr_request = request; - req->rr_errorcode = err; - req->rr_orig_request = oldreq; - req->rr_resp_fd = fd; - req->rr_target = target; - req->rr_when = when; - req->rr_arg0 = arg0; - req->rr_arg1 = arg1; - req->rr_file = file; - req->rr_line = line; - - list_insert(queue, req); - - return 0; -} - - -void -rq_free(request_t *dead) -{ - if (!dead) - return; - - free(dead); -} - - -request_t * -rq_next_request(request_t **queue) -{ - request_t *req = NULL; - - req = *queue; - if (req) - list_remove(queue, req); - - return req; -} - - -int -rq_queue_empty(request_t **queue) -{ - return !(*queue); -} diff --git a/rgmanager/src/daemons/rg_state.c b/rgmanager/src/daemons/rg_state.c deleted file mode 100644 index 7b4a991..0000000 --- a/rgmanager/src/daemons/rg_state.c +++ /dev/null @@ -1,1716 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -//#define DEBUG -#include <sets.h> -#include <assert.h> -#include <platform.h> -#include <magma.h> -#include <magmamsg.h> -#include <vf.h> -#include <stdio.h> -#include <string.h> -#include <resgroup.h> -#include <clulog.h> -#include <rg_locks.h> -#include <ccs.h> -#include <rg_queue.h> -#include <msgsimple.h> -#include <event.h> - -#define cm_svccount cm_pad[0] /* Theses are uint8_t size */ -#define cm_svcexcl cm_pad[1] - -int node_should_start_safe(uint64_t, cluster_member_list_t *, char *); - -uint64_t next_node_id(cluster_member_list_t *membership, uint64_t me); - -int rg_exec_script(char *rgname, char *script, char *action); -static int _svc_stop_finish(char *svcName, int failed, uint32_t newstate); - -int set_rg_state(char *servicename, rg_state_t *svcblk); -int get_rg_state(char *servicename, rg_state_t *svcblk); -void get_recovery_policy(char *rg_name, char *buf, size_t buflen); -int have_exclusive_resources(void); -int check_exclusive_resources(cluster_member_list_t *membership, char *svcName); -int count_resource_groups_local(cluster_member_t *mp); - - -pthread_mutex_t exclusive_mutex = PTHREAD_MUTEX_INITIALIZER; - - -uint64_t -next_node_id(cluster_member_list_t *membership, uint64_t me) -{ - uint64_t low = (uint64_t)(-1); - uint64_t next = me, curr; - int x; - - for (x = 0; x < membership->cml_count; x++) { - curr = membership->cml_members[x].cm_id; - if (curr < low) - low = curr; - - if ((curr > me) && ((next == me) || (curr < next))) - next = curr; - } - - /* I am highest ID; go to lowest */ - if (next == me) - next = low; - - return next; -} - - -char * -c_name(char *svcName) -{ - char *ptr, *ret = svcName; - - ptr = strchr(svcName,':'); - if (!ptr) - return ret; - if ((int)(ptr - svcName) == 7 && - !memcmp(svcName, "service", 7)) /* strlen("service") */ - ret = ptr + 1; - - return ret; -} - - -void -broadcast_event(char *svcName, uint32_t state, uint64_t owner, uint64_t last) -{ - rg_state_msg_t msgp; - cluster_member_list_t *membership = NULL; - int fd, x, target; - - msgp.rsm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msgp.rsm_hdr.gh_command = RG_EVENT; - msgp.rsm_hdr.gh_length = sizeof(msgp); - - msgp.rsm_state.rs_state = state; - strncpy(msgp.rsm_state.rs_name, svcName, - sizeof(msgp.rsm_state.rs_name)); - msgp.rsm_state.rs_owner = owner; - msgp.rsm_state.rs_last_owner = last; - - swab_rg_state_msg_t(&msgp); - - membership = member_list(); - if (!membership) { - clulog(LOG_ERR, "Cannot send event: %s\n", strerror(errno)); - return; - } - - for (x = 0; x < membership->cml_count; x++) { - if (!membership->cml_members[x].cm_state) - continue; - - target = membership->cml_members[x].cm_id; - - fd = msg_open(target, RG_PORT, RG_PURPOSE, 2); - if (fd < 0) - continue; - - msg_send(fd, &msgp, sizeof(msgp)); - msg_close(fd); - } - - cml_free(membership); -} - - -int -svc_report_failure(char *svcName) -{ - void *lockp = NULL; - rg_state_t svcStatus; - char *nodeName; - cluster_member_list_t *membership; - - if (rg_lock(svcName, &lockp) == -1) { - clulog(LOG_ERR, "#41: Couldn't obtain lock for %s: %s\n", - svcName, strerror(errno)); - return -1; - } - - if (get_rg_state(svcName, &svcStatus) != 0) { - clulog(LOG_ERR, "#42: Couldn't obtain status for %s\n", - svcName); - clu_unlock(svcName, lockp); - return -1; - } - rg_unlock(svcName, lockp); - - membership = member_list(); - nodeName = memb_id_to_name(membership, svcStatus.rs_last_owner); - if (nodeName) { - clulog(LOG_ALERT, "#2: Service %s returned failure " - "code. Last Owner: %s\n", - c_name(svcName), nodeName); - } else { - clulog(LOG_ALERT, "#3: Service %s returned failure " - "code. Last Owner: %llx\n", - c_name(svcName), (int)svcStatus.rs_last_owner); - } - - cml_free(membership); - - clulog(LOG_ALERT, - "#4: Administrator intervention required.\n", - svcName, nodeName); - - return 0; -} - - -int -#ifdef DEBUG -_rg_lock(char *name, void **p) -#else -rg_lock(char *name, void **p) -#endif -{ - char res[256]; - - snprintf(res, sizeof(res), "usrm::rg="%s"", name); - return clu_lock(res, CLK_EX, p); -} - - -#ifdef DEBUG -int -_rg_lock_dbg(char *name, void **p, char *file, int line) -{ - dprintf("rg_lock(%s) @ %s:%d\n", name, file, line); - return _rg_lock(name, p); -} -#endif - - - -int -#ifdef DEBUG -_rg_unlock(char *name, void *p) -#else -rg_unlock(char *name, void *p) -#endif -{ - char res[256]; - - snprintf(res, sizeof(res), "usrm::rg="%s"", name); - return clu_unlock(res, p); -} - - -#ifdef DEBUG -int -_rg_unlock_dbg(char *name, void *p, char *file, int line) -{ - dprintf("rg_unlock(%s) @ %s:%d\n", name, file, line); - return _rg_unlock(name, p); -} -#endif - - -void -send_ret(int fd, char *name, int ret, int orig_request, uint64_t newowner) -{ - SmMessageSt msg, *msgp = &msg; - if (fd < 0) - return; - - msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msgp->sm_hdr.gh_command = RG_ACTION_REQUEST; - msgp->sm_hdr.gh_length = sizeof(*msgp); - msgp->sm_data.d_action = orig_request; - strncpy(msgp->sm_data.d_svcName, name, - sizeof(msgp->sm_data.d_svcName)); - if (newowner == NODE_ID_NONE) { - msgp->sm_data.d_svcOwner = my_id(); /* XXX Broken */ - } else { - msgp->sm_data.d_svcOwner = newowner; - } - msgp->sm_data.d_ret = ret; - - swab_SmMessageSt(msgp); - msg_send(fd, msgp, sizeof(*msgp)); - - /* :) */ - msg_close(fd); -} - - -void -send_response(int ret, uint64_t newowner, request_t *req) -{ - SmMessageSt msg, *msgp = &msg; - - if (req->rr_resp_fd < 0) - return; - - msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msgp->sm_hdr.gh_command = RG_ACTION_REQUEST; - msgp->sm_hdr.gh_length = sizeof(*msgp); - msgp->sm_data.d_action = req->rr_orig_request; - strncpy(msgp->sm_data.d_svcName, req->rr_group, - sizeof(msgp->sm_data.d_svcName)); - if (newowner == NODE_ID_NONE) { - msgp->sm_data.d_svcOwner = my_id(); /* XXX Broken */ - } else { - msgp->sm_data.d_svcOwner = newowner; - } - msgp->sm_data.d_ret = ret; - - swab_SmMessageSt(msgp); - msg_send(req->rr_resp_fd, msgp, sizeof(*msgp)); - - /* :) */ - msg_close(req->rr_resp_fd); - req->rr_resp_fd = -1; -} - - -int -set_rg_state(char *rgname, rg_state_t *svcblk) -{ - cluster_member_list_t *membership; - char res[256]; - int ret; - char *name; - - name = c_name(rgname); - - if (name) - strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)); - - membership = member_list(); - snprintf(res, sizeof(res), "usrm::rg="%s"", name); - ret = vf_write(membership, VFF_IGN_CONN_ERRORS, res, svcblk, - sizeof(*svcblk)); - cml_free(membership); - return ret; -} - - -static int -init_rg(char *name, rg_state_t *svcblk) -{ - svcblk->rs_owner = NODE_ID_NONE; - svcblk->rs_last_owner = NODE_ID_NONE; - svcblk->rs_state = RG_STATE_STOPPED; - svcblk->rs_restarts = 0; - svcblk->rs_transition = 0; - strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)); - - return set_rg_state(name, svcblk); -} - - -int -get_rg_state(char *rgname, rg_state_t *svcblk) -{ - char res[256]; - int ret; - void *data = NULL; - uint32_t datalen = 0; - uint64_t viewno; - cluster_member_list_t *membership; - char *name; - - name = c_name(rgname); - - /* ... */ - if (name) - strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)); - - membership = member_list(); - - snprintf(res, sizeof(res),"usrm::rg="%s"", svcblk->rs_name); - ret = vf_read(membership, res, &viewno, &data, &datalen); - - if (ret != VFR_OK || datalen == 0) { - if (data) - free(data); - - ret = init_rg(name, svcblk); - if (ret != VFR_OK) { - cml_free(membership); - printf("Couldn't initialize rg %s!\n", name); - return RG_EFAIL; - } - - ret = vf_read(membership, res, &viewno, &data, &datalen); - if (ret != VFR_OK) { - if (data) - free(data); - cml_free(membership); - printf("Couldn't reread rg %s! (%d)\n", name, ret); - return RG_EFAIL; - } - } - - if (datalen != sizeof(*svcblk)) { - printf("Size mismatch; expected %d got %d\n", - (int)sizeof(*svcblk), datalen); - if (data) - free(data); - cml_free(membership); - return RG_EFAIL; - } - - /* Copy out the data. */ - memcpy(svcblk, data, sizeof(*svcblk)); - free(data); - cml_free(membership); - - return 0; -} - - -int vf_read_local(char *, uint64_t *, void *, uint32_t *); -int -get_rg_state_local(char *rgname, rg_state_t *svcblk) -{ - char res[256]; - int ret; - void *data = NULL; - char *name; - uint32_t datalen = 0; - uint64_t viewno; - - /* ... */ - name = c_name(rgname); - if (name) - strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)); - - snprintf(res, sizeof(res),"usrm::rg="%s"", svcblk->rs_name); - ret = vf_read_local(res, &viewno, &data, &datalen); - - if (ret != VFR_OK || datalen == 0 || - datalen != sizeof(*svcblk)) { - if (data) - free(data); - - svcblk->rs_owner = NODE_ID_NONE; - svcblk->rs_last_owner = NODE_ID_NONE; - svcblk->rs_state = RG_STATE_UNINITIALIZED; - svcblk->rs_restarts = 0; - svcblk->rs_transition = 0; - strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)); - - return RG_EFAIL; - } - - /* Copy out the data. */ - memcpy(svcblk, data, sizeof(*svcblk)); - free(data); - - return 0; -} - - -/** - * Advise service manager as to whether or not to stop a service, given - * that we already know it's legal to run the service. - * - * @param svcStatus Current service status. - * @param svcName Service name - * @param req Specify request to perform - * @return 0 = DO RG_NOT stop service, return RG_EFAIL - * 1 = STOP service - return whatever it returns. - * 2 = DO NOT stop service, return 0 (success) - * 3 = DO NOT stop service, return RG_EFORWARD - * 4 = DO NOT stop service, return RG_EAGAIN - * 5 = DO NOT stop service, return RG_EFROZEN - * 6 = DO NOT stop service, mark stopped and return - * RG_SUCCESS (0) - */ -int -svc_advise_stop(rg_state_t *svcStatus, char *svcName, int req) -{ - cluster_member_list_t *membership = member_list(); - int ret = 0; - - switch(svcStatus->rs_state) { - case RG_STATE_FAILED: - if (req == RG_DISABLE) - ret = 1; /* Failed services can be disabled */ - else - ret = 0; /* Failed services may not be stopped */ - break; - - case RG_STATE_STOPPING: - case RG_STATE_STARTED: - case RG_STATE_CHECK: - case RG_STATE_STARTING: - case RG_STATE_RECOVER: - if ((svcStatus->rs_owner != my_id()) && - memb_online(membership, svcStatus->rs_owner)) { - /* - Service is running and the owner is online. - Forward the request if it's a user request - (e.g. disable). - */ - if (req == RG_STOP) { - /* - It's running somewhere, but not here, - and it's not a user request. Toss - it out the window. - */ - ret = 2; - break; - } - - /* Disable or relocate request here. */ - clulog(LOG_DEBUG, "Forwarding req. to %s.\n", - memb_id_to_name(membership, - svcStatus->rs_owner)); - ret = 3; - break; - } - - if (svcStatus->rs_owner == NODE_ID_NONE || - (svcStatus->rs_owner == my_id())) { - /* - Service is marked as running locally or on - NODE_ID_NONE (e.g. no member). Safe - to do a full stop. - */ - ret = 1; - break; - } - - /* - Service is marked as running but node is down. - Doesn't make much sense to stop it - but we need - to mark it stopped - */ - ret = 6; - break; - - case RG_STATE_ERROR: - /* Don't stop; return failure. */ - if (req == RG_DISABLE) { - ret = 1; - break; - } - clulog(LOG_DEBUG, - "Not stopping %s: service is failed\n", - c_name(svcName)); - ret = 0; - break; - - case RG_STATE_STOPPED: - /* Allow disabling of stopped services */ - if (req == RG_DISABLE) - ret = 1; - else - ret = 2; /* if it's already stopped, do nothing */ - break; - - case RG_STATE_DISABLED: - case RG_STATE_UNINITIALIZED: - if (req == RG_DISABLE) { - clulog(LOG_NOTICE, - "Disabling disabled service %s\n", - c_name(svcName)); - ret = 1; - break; - } - - ret = 2; - clulog(LOG_DEBUG, "Not stopping disabled service %s\n", - c_name(svcName)); - break; - - default: - clulog(LOG_ERR, - "#42: Cannot stop %s: Invalid State %d\n", - svcName, svcStatus->rs_state); - break; - } - - cml_free(membership); - return ret; -} - - -/** - * Advise service manager as to whether or not to start a service, given - * that we already know it's legal to run the service. - * - * @param svcStatus Current service status. - * @param svcName Service name - * @param flags Specify whether or not it's legal to start a - * disabled service, etc. - * @return 0 = DO RG_NOT start service, return RG_EFAIL - * 1 = START service - return whatever it returns. - * 2 = DO RG_NOT start service, return 0 - * 3 = DO RG_NOT start service, return RG_EAGAIN - * 4 = DO RG_NOT start servuce, return RG_ERUN - */ -int -svc_advise_start(rg_state_t *svcStatus, char *svcName, int req) -{ - cluster_member_list_t *membership = member_list(); - int ret = 0; - int fd; - char *nodename = NULL; - char query[255]; - - switch(svcStatus->rs_state) { - case RG_STATE_FAILED: - clulog(LOG_ERR, - "#43: Service %s has failed; can not start.\n", - c_name(svcName)); - break; - - case RG_STATE_STOPPING: - case RG_STATE_STARTED: - case RG_STATE_CHECK: - case RG_STATE_STARTING: - if (svcStatus->rs_owner == my_id()) { - /* - * Service is already running locally - clulog(LOG_DEBUG, - "%s is already running locally\n", svcName); - */ - ret = 4; - break; - } - - if (svcStatus->rs_owner != my_id() && - memb_online(membership, svcStatus->rs_owner)) { - /* - * Service is running and the owner is online! - clulog(LOG_DEBUG, "%s is running on member %s.\n", - svcName, - memb_id_to_name(membership,svcStatus->rs_owner)); - */ - ret = 4; - break; - } - - /* We are allowed to do something with the service. Make - sure we're not locked */ - if (svcStatus->rs_owner == NODE_ID_NONE) { - if (rg_locked()) { - ret = 3; - break; - } - - clulog(LOG_NOTICE, - "Starting stopped service %s\n", - c_name(svcName)); - ret = 1; - break; - } - - if (rg_locked()) { - clulog(LOG_WARNING, "Not initiating failover of %s: " - "Resource groups locked!\n", svcName); - ret = 3; - break; - } - - /* - * Service is running but owner is down -> RG_EFAILOVER - */ - fd = ccs_connect(); - if (fd > 0) { - snprintf(query, - sizeof(query), - "/cluster/clusternodes/clusternode[@nodeid="%d"]/@name", - (int)svcStatus->rs_owner); - ccs_get(fd, query, &nodename); - ccs_disconnect(fd); - } - - clulog(LOG_NOTICE, - "Taking over service %s from down member %s\n", - c_name(svcName), nodename); - ret = 1; - break; - - case RG_STATE_RECOVER: - /* - * Starting failed service... - */ - if (req == RG_START_RECOVER || central_events_enabled()) { - clulog(LOG_NOTICE, - "Recovering failed service %s\n", - c_name(svcName)); - svcStatus->rs_state = RG_STATE_STOPPED; - /* Start! */ - ret = 1; - break; - } - - /* Don't start, but return success. */ - clulog(LOG_DEBUG, - "Not starting %s: recovery state\n", - c_name(svcName)); - ret = 2; - break; - - case RG_STATE_STOPPED: - case RG_STATE_ERROR: - /* Don't actually enable if the RG is locked! */ - if (rg_locked()) { - ret = 3; - break; - } - - clulog(LOG_NOTICE, "Starting stopped service %s\n", - c_name(svcName)); - ret = 1; - break; - - case RG_STATE_DISABLED: - case RG_STATE_UNINITIALIZED: - if (req == RG_ENABLE || req == RG_START_REMOTE) { - /* Don't actually enable if the RG is locked! */ - if (rg_locked()) { - ret = 3; - break; - } - - clulog(LOG_NOTICE, - "Starting disabled service %s\n", - c_name(svcName)); - ret = 1; - break; - } - if (req == RG_START_RECOVER) { - ret = 1; - break; - } - - clulog(LOG_DEBUG, "Not starting disabled %s\n", - svcName); - break; - - default: - clulog(LOG_ERR, - "#44: Cannot start %s: Invalid State %d\n", - svcName, svcStatus->rs_state); - break; - } - - cml_free(membership); - return ret; -} - - -/** - * Start a cluster service. - * - * @param svcName Service ID to start. - * @param flags Service-operation specific flags to take into account. - * @see svc_advise_start - * @return FAIL, 0 - */ -int -svc_start(char *svcName, int req) -{ - void *lockp = NULL; - int ret, xret; - rg_state_t svcStatus; - int need_check = have_exclusive_resources(); - cluster_member_list_t *membership; - - if (need_check) - pthread_mutex_lock(&exclusive_mutex); - - ret = RG_EFAIL; - - if (rg_lock(svcName, &lockp) < 0) { - clulog(LOG_ERR, "#45: Unable to obtain cluster lock: %s\n", - strerror(errno)); - goto out_nolock; - } - - if (get_rg_state(svcName, &svcStatus) != 0) { - clulog(LOG_ERR, "#46: Failed getting status for %s\n", - svcName); - goto out_unlock; - } - - if (need_check) { - membership = member_list(); - xret = check_exclusive_resources(membership, svcName); - cml_free(membership); - if (xret != 0) { - if (xret > 0) - /* Exc. service running */ - ret = RG_ERELO; - else - /* XXX */ - ret = RG_ENOSERVICE; - goto out_unlock; - } - } - - /* LOCK HELD */ - switch (svc_advise_start(&svcStatus, svcName, req)) { - case 0: /* Don't start service, return RG_EFAIL */ - goto out_unlock; - case 2: /* Don't start service, return 0 */ - ret = 0; - goto out_unlock; - case 3: - ret = RG_EAGAIN; - goto out_unlock; - case 4: - ret = RG_ERUN; - goto out_unlock; - default: - break; - } - - /* LOCK HELD if we get here */ - if (req == RG_START_RECOVER || - svcStatus.rs_state == RG_STATE_RECOVER) { - if (!central_events_enabled()) - add_restart(svcName); - svcStatus.rs_restarts++; - } else { - svcStatus.rs_restarts = 0; - } - - svcStatus.rs_owner = my_id(); - svcStatus.rs_state = RG_STATE_STARTING; - svcStatus.rs_transition = (uint64_t)time(NULL); - - if (set_rg_state(svcName, &svcStatus) != 0) { - clulog(LOG_ERR, - "#47: Failed changing service status\n"); - goto out_unlock; - } - - rg_unlock(svcName, lockp); - - /* release excl. mutex during start */ - if (need_check) { - /* Also clear need_check so we don't double-unlock */ - pthread_mutex_unlock(&exclusive_mutex); - need_check = 0; - } - - ret = group_op(svcName, RG_START); - ret = !!ret; /* Either it worked or it didn't. Ignore all the - cute values scripts might return */ - - if (rg_lock(svcName, &lockp) < 0) { - clulog(LOG_ERR, "#74: Unable to obtain cluster lock: %s\n", - strerror(errno)); - ret = RG_EFAIL; - goto out_nolock; - } - - svcStatus.rs_state = RG_STATE_STARTED; - if (set_rg_state(svcName, &svcStatus) != 0) { - clulog(LOG_ERR, - "#75: Failed changing service status\n"); - ret = RG_EFAIL; - goto out_unlock; - } - - if (ret == 0) { - clulog(LOG_NOTICE, - "Service %s started\n", - c_name(svcName)); - - broadcast_event(svcName, RG_STATE_STARTED, svcStatus.rs_owner, - svcStatus.rs_last_owner); - } else { - clulog(LOG_WARNING, - "#68: Failed to start %s; return value: %d\n", - svcName, ret); - } - -out_unlock: - rg_unlock(svcName, lockp); -out_nolock: - if (need_check) - pthread_mutex_unlock(&exclusive_mutex); - return ret; -} - - -/** - * Check status of a cluster service - * - * @param svcName Service name to check. - * @return RG_EFORWARD, RG_EFAIL, 0 - */ -int -svc_status(char *svcName) -{ - void *lockp = NULL; - rg_state_t svcStatus; - - if (rg_lock(svcName, &lockp) < 0) { - clulog(LOG_ERR, "#48: Unable to obtain cluster lock: %s\n", - strerror(errno)); - return RG_EFAIL; - } - - if (get_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#49: Failed getting status for %s\n", - svcName); - return RG_EFAIL; - } - rg_unlock(svcName, lockp); - - if (svcStatus.rs_owner != my_id()) - /* Don't check status for anything not owned */ - return RG_ESUCCESS; - - if (svcStatus.rs_state != RG_STATE_STARTED) - /* Not-running RGs should not be checked either. */ - return RG_ESUCCESS; - - return group_op(svcName, RG_STATUS); -} - - -/** - * Stop a cluster service. - * - * @param svcName Service ID to stop. - * @param flags Service-operation specific flags to take into account. - * @see svc_advise_stop - * @return FAIL, 0 - */ -static int -_svc_stop(char *svcName, int req, int recover, uint32_t newstate) -{ - void *lockp = NULL; - rg_state_t svcStatus; - int ret; - int old_state; - - if (!rg_quorate()) { - clulog(LOG_WARNING, "#69: Unclean %s of %s\n", - rg_req_str(req), svcName); - return group_op(svcName, RG_STOP); - } - - if (rg_lock(svcName, &lockp) == RG_EFAIL) { - clulog(LOG_ERR, "#50: Unable to obtain cluster lock: %s\n", - strerror(errno)); - return RG_EFAIL; - } - - if (get_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#51: Failed getting status for %s\n", - svcName); - return RG_EFAIL; - } - - switch (svc_advise_stop(&svcStatus, svcName, req)) { - case 0: - rg_unlock(svcName, lockp); - clulog(LOG_DEBUG, "Unable to stop %s in %s state\n", - svcName, rg_state_str(svcStatus.rs_state)); - return RG_EFAIL; - case 6: - /* Mark stopped, but do not do anything */ - svcStatus.rs_last_owner = svcStatus.rs_owner; - svcStatus.rs_owner = 0; - svcStatus.rs_state = RG_STATE_STOPPED; - if (set_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - return RG_EFAIL; - } - /* FALLTHROUGH */ - case 2: - rg_unlock(svcName, lockp); - return RG_ESUCCESS; - case 3: - rg_unlock(svcName, lockp); - return RG_EFORWARD; - case 4: - rg_unlock(svcName, lockp); - return RG_EAGAIN; - default: - break; - } - - old_state = svcStatus.rs_state; - - if (old_state == RG_STATE_RECOVER) { - clulog(LOG_DEBUG, "%s is clean; skipping double-stop\n", - svcName); - svcStatus.rs_state = newstate; - - if (set_rg_state(svcName, &svcStatus) != 0) { - clulog(LOG_ERR, "#52: Failed changing RG status\n"); - return RG_EFAIL; - } - rg_unlock(svcName, lockp); - return 0; - } - - clulog(LOG_NOTICE, "Stopping service %s\n", c_name(svcName)); - - if (recover) - svcStatus.rs_state = RG_STATE_ERROR; - else - svcStatus.rs_state = RG_STATE_STOPPING; - svcStatus.rs_transition = (uint64_t)time(NULL); - - //printf("rg state = %s\n", rg_state_str(svcStatus.rs_state)); - - if (set_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#52: Failed changing RG status\n"); - return RG_EFAIL; - } - rg_unlock(svcName, lockp); - - if (group_op(svcName, RG_STOP) != 0) - ret = RG_EFAIL; - else - ret = 0; - - if (old_state == RG_STATE_FAILED && newstate == RG_STATE_DISABLED) { - if (ret) - clulog(LOG_ALERT, "Marking %s as 'disabled', " - "but some resources may still be allocated!\n", - svcName); - _svc_stop_finish(svcName, 0, newstate); - ret = 0; - } else { - _svc_stop_finish(svcName, ret, newstate); - } - - return ret; -} - - -static int -_svc_stop_finish(char *svcName, int failed, uint32_t newstate) -{ - rg_state_t svcStatus; - void *lockp; - - if (rg_lock(svcName, &lockp) == RG_EFAIL) { - clulog(LOG_ERR, "#53: Unable to obtain cluster lock: %s\n", - strerror(errno)); - return RG_EFAIL; - } - - if (get_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#54: Failed getting status for %s\n", - svcName); - return RG_EFAIL; - } - - if ((svcStatus.rs_state != RG_STATE_STOPPING) && - (svcStatus.rs_state != RG_STATE_ERROR)) { - rg_unlock(svcName, lockp); - return 0; - } - - svcStatus.rs_last_owner = svcStatus.rs_owner; - svcStatus.rs_owner = NODE_ID_NONE; - - if (failed) { - clulog(LOG_CRIT, "#12: %s failed to stop; intervention " - "required\n", svcName); - svcStatus.rs_state = RG_STATE_FAILED; - } else if (svcStatus.rs_state == RG_STATE_ERROR) - svcStatus.rs_state = RG_STATE_RECOVER; - else - svcStatus.rs_state = newstate; - - clulog(LOG_NOTICE, "Service %s is %s\n", c_name(svcName), - rg_state_str(svcStatus.rs_state)); - //printf("rg state = %s\n", rg_state_str(svcStatus.rs_state)); - - svcStatus.rs_transition = (uint64_t)time(NULL); - if (set_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#55: Failed changing RG status\n"); - return RG_EFAIL; - } - rg_unlock(svcName, lockp); - - broadcast_event(svcName, svcStatus.rs_state, NODE_ID_NONE, svcStatus.rs_last_owner); - - return 0; -} - - -/** - * Disable a cluster service. Services in the disabled state are never - * automatically started by the service manager - one must send a SVC_START - * message. - * - * @param svcName Service ID to stop. - * @return FAIL, 0 - */ -int -svc_disable(char *svcName) -{ - return _svc_stop(svcName, RG_DISABLE, 0, RG_STATE_DISABLED); -} - - -int -svc_stop(char *svcName, int req) -{ - return _svc_stop(svcName, req, (req == RG_STOP_RECOVER), - RG_STATE_STOPPED); -} - - -/** - * Mark a cluster service as failed. User intervention required. - * - * @param svcName Service ID to stop. - * @return FAIL, 0 - */ -int -svc_fail(char *svcName) -{ - void *lockp = NULL; - rg_state_t svcStatus; - - if (rg_lock(svcName, &lockp) == RG_EFAIL) { - clulog(LOG_ERR, "#55: Unable to obtain cluster lock: %s\n", - strerror(errno)); - return RG_EFAIL; - } - - clulog(LOG_DEBUG, "Handling failure request for %s\n", svcName); - - if (get_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#56: Failed getting status for %s\n", - svcName); - return RG_EFAIL; - } - - if ((svcStatus.rs_state == RG_STATE_STARTED) && - (svcStatus.rs_owner != my_id())) { - rg_unlock(svcName, lockp); - clulog(LOG_DEBUG, "Unable to disable %s in %s state\n", - svcName, rg_state_str(svcStatus.rs_state)); - return RG_EFAIL; - } - - /* - * Leave a bread crumb so we can debug the problem with the service! - */ - if (svcStatus.rs_owner != NODE_ID_NONE) { - svcStatus.rs_last_owner = svcStatus.rs_owner; - svcStatus.rs_owner = NODE_ID_NONE; - } - svcStatus.rs_state = RG_STATE_FAILED; - svcStatus.rs_transition = (uint64_t)time(NULL); - svcStatus.rs_restarts = 0; - if (set_rg_state(svcName, &svcStatus) != 0) { - rg_unlock(svcName, lockp); - clulog(LOG_ERR, "#57: Failed changing RG status\n"); - return RG_EFAIL; - } - rg_unlock(svcName, lockp); - - broadcast_event(svcName, RG_STATE_FAILED, NODE_ID_NONE, - svcStatus.rs_last_owner); - - return 0; -} - - -/* - * Send a message to the target node to start the service. - */ -int -svc_start_remote(char *svcName, int request, uint64_t target) -{ - SmMessageSt msg_relo; - int fd_relo, msg_ret; - cluster_member_list_t *ml; - - /* Build the message header */ - msg_relo.sm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msg_relo.sm_hdr.gh_command = RG_ACTION_REQUEST; - msg_relo.sm_hdr.gh_arg1 = RG_ACTION_MASTER; - msg_relo.sm_hdr.gh_length = sizeof (SmMessageSt); - msg_relo.sm_data.d_action = request; - strncpy(msg_relo.sm_data.d_svcName, svcName, - sizeof(msg_relo.sm_data.d_svcName)); - msg_relo.sm_data.d_ret = 0; - - /* Open a connection to the other node */ - - if ((fd_relo = msg_open(target, RG_PORT, RG_PURPOSE, 2)) < 0) { - clulog(LOG_ERR, - "#58: Failed opening connection to member #%llx\n", - target); - return -1; - } - - /* Encode */ - swab_SmMessageSt(&msg_relo); - - /* Send relocate message to the other node */ - if (msg_send(fd_relo, &msg_relo, sizeof (SmMessageSt)) != - sizeof (SmMessageSt)) { - clulog(LOG_ERR, - "#59: Error sending remote start request to member #%llx\n", - target); - msg_close(fd_relo); - return -1; - } - - clulog(LOG_DEBUG, "Sent remote start request to #%llx\n", target); - - /* Check the response */ - do { - msg_ret = msg_receive_timeout(fd_relo, &msg_relo, - sizeof (SmMessageSt), 10); - if ((msg_ret == -1 && errno != ETIMEDOUT) || - (msg_ret >= 0)) { - break; - } - - /* Check to see if resource groups are locked for local - shutdown */ - if (rg_locked()) { - clulog(LOG_WARNING, - "#XX: Cancelling relocation: Shutting down\n"); - msg_close(fd_relo); - return RG_NO; - } - - /* Check for node transition in the middle of a relocate */ - ml = member_list(); - if (memb_online(ml, target)) { - cml_free(ml); - continue; - } - clulog(LOG_WARNING, - "#XX: Cancelling relocation: Target node down\n"); - cml_free(ml); - msg_close(fd_relo); - return RG_EFAIL; - } while (1); - - if (msg_ret != sizeof (SmMessageSt)) { - /* - * In this case, we don't restart the service, because the - * service state is actually unknown to us at this time. - */ - clulog(LOG_ERR, "#60: Mangled reply from member #%llx during " - "relocate\n", target); - msg_close(fd_relo); - return 0; /* XXX really UNKNOWN */ - } - - /* Got a valid response from other node. */ - msg_close(fd_relo); - - /* Decode */ - swab_SmMessageSt(&msg_relo); - - return msg_relo.sm_data.d_ret; -} - - -/** - * handle_relocate_req - Relocate a service. This seems like a huge - * deal, except it really isn't. - * - * @param svcID Service ID in question. - * @param flags If (flags & SVCF_PENDING), we were called from - * handle_start_req - and so we should ignore all local - * restarts/stops - since handle_start_req does this - * for us. - * @param preferred_target When sent a relocate message from the - * management software, a destination node - * is sent as well. This causes us to try - * starting the service on that node *first*, - * but does RG_NOT GUARANTEE that the service - * will end up on that node. It will end up - * on whatever node actually successfully - * starts it. - * @param new_owner Member who actually ends up owning the service. - */ -int -handle_relocate_req(char *svcName, int request, uint64_t preferred_target, - uint64_t *new_owner) -{ - cluster_member_list_t *allowed_nodes = NULL, *backup = NULL; - cluster_member_t *m; - uint64_t target = preferred_target, me = my_id(); - int ret, x; - rg_state_t svcStatus; - - get_rg_state_local(svcName, &svcStatus); - if (svcStatus.rs_state == RG_STATE_DISABLED || - svcStatus.rs_state == RG_STATE_UNINITIALIZED) - return RG_EINVAL; - - if (preferred_target != NODE_ID_NONE) { - /* TODO: simplify this and don't keep alloc/freeing - member lists */ - allowed_nodes = member_list(); - /* Avoid even bothering the other node if we can */ - m = memb_id_to_p(allowed_nodes, preferred_target); - if (!m) { - cml_free(allowed_nodes); - return RG_EINVAL; - } - - count_resource_groups_local(m); - if (m->cm_svcexcl || - (m->cm_svccount && is_exclusive(svcName))) { - cml_free(allowed_nodes); - return RG_EDEPEND; - } - cml_free(allowed_nodes); - } - - /* - * Stop the service - if we haven't already done so. - */ - if (request != RG_START_RECOVER) { - ret = _svc_stop(svcName, request, 0, RG_STATE_STOPPED); - if (ret == RG_EFAIL) { - svc_fail(svcName); - return RG_EFAIL; - } - if (ret == RG_EFORWARD) - return RG_EFORWARD; - } - - if (preferred_target != NODE_ID_NONE) { - - allowed_nodes = member_list(); - /* - Mark everyone except me and the preferred target DOWN for now - If we can't start it on the preferred target, then we'll try - other nodes. - */ - //count_resource_groups(allowed_nodes); - backup = cml_dup(allowed_nodes); - - for (x = 0; x < allowed_nodes->cml_count; x++) { - if (allowed_nodes->cml_members[x].cm_id == me || - allowed_nodes->cml_members[x].cm_id == - preferred_target) - continue; - allowed_nodes->cml_members[x].cm_state = 0; - } - - /* - * First, see if it's legal to relocate to the target node. - * Legal means: the node is online and is in the - * [restricted] failover domain of the service, or the - * service has no failover domain. - */ - target = best_target_node(allowed_nodes, me, svcName, 1); - - cml_free(allowed_nodes); - - /* - * I am the ONLY one capable of running this service, - * PERIOD... - */ - if (target == me && me != preferred_target) { - cml_free(backup); - goto exhausted; - } - - if (target == me) { - /* - Relocate to self. Don't send a network request - to do it; it would block. - */ - if (svc_start(svcName, RG_START) == 0) { - *new_owner = me; - return 0; - } - } else if (target == preferred_target) { - /* - * It's legal to start the service on the given - * node. Try to do so. - */ - if (svc_start_remote(svcName, request, target) == 0) { - *new_owner = target; - /* - * Great! We're done... - */ - return 0; - } - } - } - - /* - * Ok, so, we failed to send it to the preferred target node. - * Try to start it on all other nodes. - */ - if (backup) { - allowed_nodes = backup; - } else { - allowed_nodes = member_list(); - //count_resource_groups(allowed_nodes); - } - - if (preferred_target != NODE_ID_NONE) - memb_mark_down(allowed_nodes, preferred_target); - memb_mark_down(allowed_nodes, me); - - while (memb_count(allowed_nodes)) { - target = best_target_node(allowed_nodes, me, svcName, 1); - if (target == me) - goto exhausted; - - ret = svc_start_remote(svcName, request, target); - switch (ret) { - case RG_ERUN: - /* Someone stole the service while we were - trying to relo it */ - get_rg_state_local(svcName, &svcStatus); - *new_owner = svcStatus.rs_owner; - cml_free(allowed_nodes); - return 0; - case RG_EDEPEND: - case RG_EFAIL: - memb_mark_down(allowed_nodes, target); - continue; - case RG_EABORT: - svc_report_failure(svcName); - cml_free(allowed_nodes); - return RG_EFAIL; - default: - /* deliberate fallthrough */ - clulog(LOG_ERR, - "#61: Invalid reply from member %llx during" - " relocate operation!\n", target); - case RG_NO: - /* state uncertain */ - cml_free(allowed_nodes); - clulog(LOG_CRIT, "State Uncertain: svc:%s " - "nid:%llx req:%s ret:%d\n", svcName, - target, rg_req_str(request), ret); - return 0; - case 0: - *new_owner = target; - clulog(LOG_NOTICE, "Service %s is now running " - "on member %llx\n", svcName, (int)target); - cml_free(allowed_nodes); - return 0; - } - } - cml_free(allowed_nodes); - - /* - * We got sent here from handle_start_req. - * We're DONE. - */ - if (request == RG_START_RECOVER) { - _svc_stop_finish(svcName, 0, RG_STATE_STOPPED); - return RG_EFAIL; - } - - /* - * All potential places for the service to start have been exhausted. - * We're done. - */ -exhausted: - if (!rg_locked()) { - clulog(LOG_WARNING, - "#70: Failed to relocate %s; restarting locally\n", - svcName); - if (svc_start(svcName, RG_START_RECOVER) == 0) { - *new_owner = me; - return RG_EFAIL; - } - } - - if (svc_stop(svcName, RG_STOP) != 0) { - svc_fail(svcName); - svc_report_failure(svcName); - } - - return RG_EFAIL; - -} - - -int -handle_fd_start_req(char *svcName, int request, uint64_t *new_owner) -{ - cluster_member_list_t *allowed_nodes; - uint64_t target, me = my_id(); - int ret; - - allowed_nodes = member_list(); - - while (memb_count(allowed_nodes)) { - target = best_target_node(allowed_nodes, NODE_ID_NONE, - svcName, 1); - if (target == me) { - ret = handle_start_remote_req(svcName, request); - } else { - ret = svc_start_remote(svcName, request, target); - } - - switch (ret) { - case RG_ERUN: - return RG_ERUN; - case RG_EFAIL: - memb_mark_down(allowed_nodes, target); - continue; - case RG_EABORT: - svc_report_failure(svcName); - cml_free(allowed_nodes); - return RG_EFAIL; - case RG_NO: - /* state uncertain */ - cml_free(allowed_nodes); - clulog(LOG_DEBUG, "State Uncertain: %s " - "nid:%llx req:%d\n", svcName, - target, request); - return 0; - case 0: - *new_owner = target; - clulog(LOG_NOTICE, "Service %s is now running " - "on member %llx\n", c_name(svcName), - (int)target); - cml_free(allowed_nodes); - return 0; - default: - clulog(LOG_ERR, - "#61: Invalid reply from member %llx during" - " relocate operation!\n", target); - } - } - - cml_free(allowed_nodes); - return RG_EFAIL; -} - - -/** - * handle_start_req - Handle a generic start request from a user or during - * service manager boot. - * - * @param svcID Service ID to start. - * @param flags - * @param new_owner Owner which actually started the service. - * @return FAIL - Failure. - * 0 - The service is running. - */ -int -handle_start_req(char *svcName, int req, uint64_t *new_owner) -{ - int ret, tolerance = FOD_BEST; - cluster_member_list_t *membership = member_list(); - - /* - * When a service request is from a user application (eg, clusvcadm), - * accept FOD_GOOD instead of FOD_BEST - */ - if (req == RG_ENABLE) - tolerance = FOD_GOOD; - - if (req != RG_RESTART && - req != RG_START_RECOVER && - (node_should_start_safe(my_id(), membership, svcName) < - tolerance)) { - cml_free(membership); - return RG_EFAIL; - } - cml_free(membership); - - /* - * This is a 'root' start request. We need to clear out our failure - * mask here - so that we can try all nodes if necessary. - */ - ret = svc_start(svcName, req); - switch(ret) { - case RG_ERELO: - goto relocate; - - case RG_EAGAIN: - /* If services are locked, return the error */ - case RG_ENOSERVICE: - /* service doesn't exist? */ - case RG_ERUN: - /* If service is already running, return that value */ - return ret; - - case RG_ESUCCESS: - /* If we succeeded, then we're done. */ - *new_owner = my_id(); - case RG_NO: - return RG_ESUCCESS; - } - - /* - * Keep the state open so the other nodes don't try to start - * it. This allows us to be the 'root' of a given service. - */ - clulog(LOG_DEBUG, "Stopping failed service %s\n", c_name(svcName)); - if (svc_stop(svcName, RG_STOP_RECOVER) != 0) { - clulog(LOG_CRIT, - "#13: Service %s failed to stop cleanly\n", - c_name(svcName)); - (void) svc_fail(svcName); - - /* - * If we failed to stop the service, we're done. At this - * point, we can't determine the service's status - so - * trying to start it on other nodes is right out. - */ - return RG_EABORT; - } - - /* - * OK, it failed to start - but succeeded to stop. Now, - * we should relocate the service. - */ - clulog(LOG_WARNING, "#71: Relocating failed service %s\n", - c_name(svcName)); -relocate: - ret = handle_relocate_req(svcName, RG_START_RECOVER, -1, new_owner); - - /* If we leave the service stopped, instead of disabled, someone - will try to start it after the next node transition */ - if (ret == RG_EFAIL) { - if (svc_stop(svcName, RG_STOP) != 0) { - svc_fail(svcName); - svc_report_failure(svcName); - } - } - - return ret; -} - - -/** - * handle_start_remote_req - Handle a remote start request. - * - * @param svcID Service ID to start. - * @param flags Flags to use to determine start behavior. - * @return FAIL - Local failure. ABORT - Unrecoverable error: - * the service didn't start, nor stop cleanly. 0 - * - We started the service. - */ -int -handle_start_remote_req(char *svcName, int req) -{ - int tolerance = FOD_BEST; - int x; - uint64_t me = my_id(); - cluster_member_list_t *membership = member_list(); - - /* XXX ok, so we need to say "should I start this if I was the - only cluster member online */ - for (x = 0; x < membership->cml_count; x++) { - if (membership->cml_members[x].cm_id == me) - continue; - - membership->cml_members[x].cm_state = STATE_DOWN; - } - - if (req == RG_ENABLE) - tolerance = FOD_GOOD; - - /* - * See if we agree with our ability to start the given service. - */ - if (node_should_start_safe(me, membership, svcName) < tolerance){ - cml_free(membership); - return RG_EFAIL; - } - cml_free(membership); - - x = svc_start(svcName, req); - switch(x) { - case RG_ERELO: - /* Don't relocate from here; it was a remote start */ - /* Return fail so the other node can go ahead and - try the other nodes in the cluster */ - return RG_ERELO; - case RG_NO: - return RG_EFAIL; - - case RG_EAGAIN: - /* If services are locked, return the error */ - case RG_ENOSERVICE: - /* service doesn't exist? */ - case RG_ERUN: - /* If service is already running, return that value */ - return x; - - case RG_ESUCCESS: - /* If we succeeded, then we're done. */ - return RG_ESUCCESS; - } - - if (svc_stop(svcName, RG_STOP_RECOVER) == 0) - return RG_EFAIL; - - svc_fail(svcName); - return RG_EABORT; -} - - -/** - handle_recover_req - */ -int -handle_recover_req(char *svcName, uint64_t *new_owner) -{ - char policy[20]; - - get_recovery_policy(svcName, policy, sizeof(policy)); - - if (!strcasecmp(policy, "disable")) { - return svc_disable(svcName); - } else if (!strcasecmp(policy, "relocate")) { - return handle_relocate_req(svcName, RG_START_RECOVER, - NODE_ID_NONE, - new_owner); - } - - /* Check restart counter/timer for this resource */ - if (check_restart(svcName) > 0) { - clulog(LOG_NOTICE, "Restart threshold for %s exceeded; " - "attempting to relocate\n", svcName); - return handle_relocate_req(svcName, RG_START_RECOVER, - NODE_ID_NONE, - new_owner); - } - - return handle_start_req(svcName, RG_START_RECOVER, new_owner); -} diff --git a/rgmanager/src/daemons/rg_thread.c b/rgmanager/src/daemons/rg_thread.c deleted file mode 100644 index c1d6140..0000000 --- a/rgmanager/src/daemons/rg_thread.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <resgroup.h> -#include <rg_locks.h> -#include <gettid.h> -#include <rg_queue.h> -#include <assert.h> - -/** - * Resource thread list entry. - */ -typedef struct __resthread { - list_head(); - pthread_t rt_thread; /** Thread identifier */ - int rt_request; /** Current pending operation */ - int rt_status; /** Used for init */ - char rt_name[256]; /** RG name */ - request_t **rt_queue; /** RG event queue */ - pthread_mutex_t *rt_queue_mutex; /** Mutex for event queue */ - pthread_cond_t *rt_queue_cond; /** pthread cond */ -} resthread_t; - - -/** - * Resource thread queue head. - */ -static resthread_t *resthread_list = NULL; -static pthread_mutex_t reslist_mutex = PTHREAD_MUTEX_INITIALIZER; - - -static resthread_t *find_resthread_byname(const char *resgroupname); -static int spawn_if_needed(const char *resgroupname); -int rt_enqueue_request(const char *resgroupname, int request, - int response_fd, int max, uint64_t target, - int arg0, int arg1); - - -/** - SIGUSR1 output - */ -void -dump_threads(void) -{ - resthread_t *rt; - - printf("+++ BEGIN Thread dump\n"); - pthread_mutex_lock(&reslist_mutex); - list_do(&resthread_list, rt) { - printf("TID %d group %s (@ %p) request %d\n", - (int)rt->rt_thread, - rt->rt_name, rt, rt->rt_request); - } while (!list_done(&resthread_list, rt)); - pthread_mutex_unlock(&reslist_mutex); - printf("--- END Thread dump\n"); -} - - -static int -wait_initialize(const char *name) -{ - resthread_t *t; - - while (1) { - pthread_mutex_lock(&reslist_mutex); - t = find_resthread_byname(name); - - if (!t) { - pthread_mutex_unlock(&reslist_mutex); - return -1; - } - - if (t->rt_status != RG_STATE_UNINITIALIZED) { - pthread_mutex_unlock(&reslist_mutex); - return 0; - } - - pthread_mutex_unlock(&reslist_mutex); - usleep(50000); - } - - assert(0); -} - - -static void -rg_sighandler_setup(void) -{ - block_all_signals(); - unblock_signal(SIGCHLD); -} - - -static void -purge_status_checks(request_t **list) -{ - request_t *curr; - int found; - - if (!list) - return; - - do { - found = 0; - list_do(list, curr) { - if (curr->rr_request == RG_STATUS) { - list_remove(list, curr); - rq_free(curr); - found = 1; - break; - } - } while (!list_done(list, curr)); - } while (found); -} - - -static void -purge_all(request_t **list) -{ - request_t *curr; - - if (!list) - return; - - if (!*list) - return; - - while((curr = *list)) { - - list_remove(list, curr); - dprintf("Removed request %d\n", curr->rr_request); - if (curr->rr_resp_fd != -1) { - send_response(RG_EABORT, NODE_ID_NONE, curr); - } - rq_free(curr); - } -} - - -static void * -resgroup_thread_main(void *arg) -{ - pthread_mutex_t my_queue_mutex; - pthread_cond_t my_queue_cond; - request_t *my_queue = NULL; - uint64_t newowner = NODE_ID_NONE; - char myname[256]; - resthread_t *myself; - request_t *req; - uint32_t ret = RG_FAIL, error = 0; - - rg_inc_threads(); - - strncpy(myname, arg, 256); - dprintf("Thread %s (tid %d) starting\n",myname,gettid()); - - pthread_mutex_init(&my_queue_mutex, NULL); - pthread_mutex_lock(&my_queue_mutex); - pthread_cond_init(&my_queue_cond, NULL); - - /* - * Wait until we're inserted. The code herein should never be - * reached. - */ - while (1) { - pthread_mutex_lock(&reslist_mutex); - - myself = find_resthread_byname(myname); - if (myself) - break; - - pthread_mutex_unlock(&reslist_mutex); - usleep(250000); - } - - myself->rt_queue = &my_queue; - myself->rt_queue_mutex = &my_queue_mutex; - myself->rt_queue_cond = &my_queue_cond; - myself->rt_status = RG_STATE_STARTED; /* Ok, we're ready to go */ - rg_sighandler_setup(); - - /* Wait for first event */ - pthread_mutex_unlock(&reslist_mutex); - - /* My mutex is still held */ - pthread_cond_wait(&my_queue_cond, &my_queue_mutex); - pthread_mutex_unlock(&my_queue_mutex); - - while(1) { - pthread_mutex_lock(&reslist_mutex); - pthread_mutex_lock(&my_queue_mutex); - if ((req = rq_next_request(&my_queue)) == NULL) { - /* We're done. No more requests. - We're about to kill our thread, so exit the - loop with the lock held. */ - break; - } - pthread_mutex_unlock(&my_queue_mutex); - pthread_mutex_unlock(&reslist_mutex); - - ret = RG_FAIL; - error = 0; - - dprintf("Processing request %s, resource group %s\n", - rg_req_str(req->rr_request), myname); - - /* find ourselves. */ - pthread_mutex_lock(&reslist_mutex); - myself = find_resthread_byname(myname); - assert(myself); - myself->rt_request = req->rr_request; - if (req->rr_request == RG_STOP_EXITING) - myself->rt_status = RG_STATE_STOPPING; - pthread_mutex_unlock(&reslist_mutex); - - switch(req->rr_request) { - case RG_START_REMOTE: - case RG_START_RECOVER: - error = handle_start_remote_req(myname, - req->rr_request); - break; - - case RG_START: - case RG_ENABLE: - if (req->rr_arg0) { - error = handle_fd_start_req(myname, - req->rr_request, - &newowner); - } else { - error = handle_start_req(myname, - req->rr_request, - &newowner); - } - break; - - case RG_RELOCATE: - /* Relocate requests are user requests and must be - forwarded */ - error = handle_relocate_req(myname, RG_START_REMOTE, - req->rr_target, - &newowner); - if (error == RG_EFORWARD) - ret = RG_NONE; - break; - - case RG_INIT: - /* Stop without changing shared state of it */ - error = group_op(myname, RG_STOP); - - pthread_mutex_lock(&my_queue_mutex); - purge_all(&my_queue); - pthread_mutex_unlock(&my_queue_mutex); - - if (error == 0) - ret = RG_SUCCESS; - else - ret = RG_FAIL; - break; - - case RG_CONDSTOP: - /* CONDSTOP doesn't change RG state by itself */ - group_op(myname, RG_CONDSTOP); - break; - - case RG_CONDSTART: - /* CONDSTART doesn't change RG state by itself */ - group_op(myname, RG_CONDSTART); - break; - - case RG_STOP: - case RG_STOP_USER: - /* Disable and user stop requests need to be - forwarded; they're user requests */ - error = svc_stop(myname, req->rr_request); - - if (error == 0) { - ret = RG_SUCCESS; - - pthread_mutex_lock(&my_queue_mutex); - purge_status_checks(&my_queue); - pthread_mutex_unlock(&my_queue_mutex); - } else if (error == RG_EFORWARD) { - ret = RG_NONE; - break; - } else { - /* - * Bad news. - */ - ret = RG_FAIL; - } - - break; - - case RG_STOP_EXITING: - /* We're out of here. Don't allow starts anymore */ - error = svc_stop(myname, RG_STOP); - - if (error == 0) { - ret = RG_SUCCESS; - - } else if (error == RG_EFORWARD) { - ret = RG_NONE; - break; - } else { - /* - * Bad news. - */ - ret = RG_FAIL; - } - - pthread_mutex_lock(&my_queue_mutex); - purge_all(&my_queue); - pthread_mutex_unlock(&my_queue_mutex); - - break; - - - case RG_DISABLE: - /* Disable and user stop requests need to be - forwarded; they're user requests */ - error = svc_disable(myname); - - if (error == 0) { - ret = RG_SUCCESS; - - pthread_mutex_lock(&my_queue_mutex); - purge_status_checks(&my_queue); - pthread_mutex_unlock(&my_queue_mutex); - } else if (error == RG_EFORWARD) { - ret = RG_NONE; - break; - } else { - /* - * Bad news. - */ - ret = RG_FAIL; - } - - break; - - case RG_RESTART: - error = svc_stop(myname, RG_STOP_USER); - - if (error == 0) { - pthread_mutex_lock(&my_queue_mutex); - purge_status_checks(&my_queue); - pthread_mutex_unlock(&my_queue_mutex); - - error = handle_start_req(myname, - req->rr_request, - &newowner); - break; - - } else if (error == RG_EFORWARD) { - ret = RG_NONE; - break; - } else { - /* - * Bad news. - */ - ret = RG_FAIL; - } - - break; - - case RG_STATUS: - /* Need to make sure we don't check status of - resource groups we don't own */ - error = svc_status(myname); - - /* Recover dead service */ - if (error == 0) { - ret = RG_SUCCESS; - break; - } - - error = svc_stop(myname, RG_STOP_RECOVER); - if (error == 0) { - if (central_events_enabled()) { - ret = RG_SUCCESS; - break; - } - - error = handle_recover_req(myname, &newowner); - if (error == 0) - ret = RG_SUCCESS; - } - - break; - - default: - printf("Unhandled request %d\n", req->rr_request); - ret = RG_NONE; - break; - } - - pthread_mutex_lock(&reslist_mutex); - myself = find_resthread_byname(myname); - myself->rt_request = RG_NONE; - pthread_mutex_unlock(&reslist_mutex); - - if (error == RG_EFORWARD) { - /* Forward_request frees this and closes the - file descriptor, so we can just move on - with life. */ - forward_request(req); - continue; - } - - if (ret != RG_NONE && rg_initialized() && - (req->rr_resp_fd >= 0)) { - send_response(error, newowner, req); - } - - rq_free(req); - } - - /* reslist_mutex and my_queue_mutex held */ - myself = find_resthread_byname(myname); - - if (!myself) { - dprintf("I don't exist...\n"); - raise(SIGSEGV); - } - - pthread_mutex_destroy(&my_queue_mutex); - list_remove(&resthread_list, myself); - free(myself); - - pthread_mutex_unlock(&reslist_mutex); - - dprintf("RGth %s (tid %d): No more requests" - "; exiting.\n", myname, gettid()); - - /* Thread's outta here */ - rg_dec_threads(); - pthread_exit((void *)NULL); -} - - -/** - * Start a resgroup thread. - */ -static int -spawn_resgroup_thread(const char *name) -{ - pthread_attr_t attrs; - resthread_t *newthread = NULL; - int ret = 0; - - pthread_attr_init(&attrs); - pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); - - newthread = malloc(sizeof(*newthread)); - if (!newthread) - return -1; - memset(newthread, 0, sizeof(*newthread)); - - newthread->rt_status = RG_STATE_UNINITIALIZED; - strncpy(newthread->rt_name, name, sizeof(newthread->rt_name)); - - ret = pthread_create(&newthread->rt_thread, &attrs, - resgroup_thread_main, (void *)name); - pthread_attr_destroy(&attrs); - - if (ret != 0) { - free(newthread); - return ret; - } - - list_insert(&resthread_list, newthread); - - return 0; -} - - -/** - Spawn a resource group thread if necessary - */ -int -spawn_if_needed(const char *resgroupname) -{ - int ret; - resthread_t *resgroup = NULL; - -retry: - resgroup = NULL; - pthread_mutex_lock(&reslist_mutex); - while (resgroup == NULL) { - resgroup = find_resthread_byname(resgroupname); - if (resgroup != NULL) - break; - - ret = spawn_resgroup_thread(resgroupname); - if (ret == 0) - continue; - pthread_mutex_unlock(&reslist_mutex); - - return ret; - } - - ret = (resgroup->rt_status == RG_STATE_STOPPING); - - pthread_mutex_unlock(&reslist_mutex); - if (wait_initialize(resgroupname) < 0) { - goto retry; - } - - return ret; -} - - -/** - * Call with mutex locked. - */ -static resthread_t * -find_resthread_byname(const char *resgroupname) -{ - resthread_t *curr = NULL; - - if (!resthread_list) - return NULL; - - list_do(&resthread_list, curr) { - if (!strncmp(resgroupname, curr->rt_name, - sizeof(curr->rt_name))) - return curr; - } while (!list_done(&resthread_list, curr)); - - return NULL; -} - - -/** - * queues a request for a resgroup. - * - * @param resgroupname Service name to perform operations on - * @param request Request to perform - * @param response_fd Send response to this file descriptor when - * this request completes. - * @param max Don't insert this request if there already - * are this many requests of this type in the - * queue. - * @param arg Argument to the decoder. - * @param arglen Length of argument. - * @return -1 on failure, 0 on success, or 1 if - * the request was dropped. - * @see rq_queue_request - */ -int -rt_enqueue_request(const char *resgroupname, int request, int response_fd, - int max, uint64_t target, int arg0, int arg1) -{ - request_t *curr; - int count = 0, ret; - resthread_t *resgroup; - - if (spawn_if_needed(resgroupname) != 0) { - /* Usually, we get here if the thread is killing - stuff. This prevents us from queueing START requests - while we're exiting */ - return -1; - } - - pthread_mutex_lock(&reslist_mutex); - resgroup = find_resthread_byname(resgroupname); - if (resgroup == NULL) { - /* DOOOOM */ - pthread_mutex_unlock(&reslist_mutex); - return -1; - } - - /* Main mutex held */ - if (resgroup->rt_request == request) - count++; - - pthread_mutex_lock(resgroup->rt_queue_mutex); - - if (request == RG_INIT) { - /* If we're initializing it, zap the queue if there - is one */ - purge_all(resgroup->rt_queue); - } else { - if (max) { - list_do(resgroup->rt_queue, curr) { - if (curr->rr_request == request) - count++; - } while (!list_done(resgroup->rt_queue, curr)); - - if (count >= max) { - pthread_mutex_unlock(resgroup->rt_queue_mutex); - pthread_mutex_unlock(&reslist_mutex); - /* - * Maximum reached. - */ - return 1; - } - } - } - - if (resgroup->rt_request == RG_RELOCATE) { - switch(request) { - case RG_RELOCATE: - case RG_START_REMOTE: - case RG_START_RECOVER: - case RG_START: - case RG_ENABLE: - send_ret(response_fd, resgroup->rt_name, RG_EDEADLCK, - request, NODE_ID_NONE); - break; - } - fprintf(stderr, "Failed to queue request: Would block\n"); - /* EWOULDBLOCK */ - pthread_mutex_unlock(resgroup->rt_queue_mutex); - pthread_mutex_unlock(&reslist_mutex); - return -1; - } - - ret = rq_queue_request(resgroup->rt_queue, resgroup->rt_name, - request, 0, 0, response_fd, 0, target, - arg0, arg1); - pthread_cond_broadcast(resgroup->rt_queue_cond); - pthread_mutex_unlock(resgroup->rt_queue_mutex); - pthread_mutex_unlock(&reslist_mutex); - - if (ret < 0) - return ret; - - dprintf("Queued request for %d for %s\n", request, resgroupname); - - return 0; -} diff --git a/rgmanager/src/daemons/service_op.c b/rgmanager/src/daemons/service_op.c deleted file mode 100644 index 48fbd2d..0000000 --- a/rgmanager/src/daemons/service_op.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <assert.h> -#include <platform.h> -#include <magma.h> -#include <magmamsg.h> -#include <stdio.h> -#include <string.h> -#include <sets.h> -#include <resgroup.h> -#include <clulog.h> -#include <rg_locks.h> -#include <ccs.h> -#include <rg_queue.h> -#include <msgsimple.h> -#include <res-ocf.h> -#include <event.h> - - -/* - * Send a message to the target node to start the service. - */ -int svc_start_remote(char *svcName, int request, uint64_t target); -void svc_report_failure(char *); -int get_service_state_internal(char *svcName, rg_state_t *svcStatus); - - -/** - * - */ -int -service_op_start(char *svcName, - uint64_t *target_list, - int target_list_len, - uint64_t *new_owner) -{ - int target; - int ret, x; - int excl = 0, dep = 0, fail = 0; - rg_state_t svcStatus; - - if (get_service_state_internal(svcName, &svcStatus) < 0) { - return RG_EFAIL; - } - - if (svcStatus.rs_state == RG_STATE_FAILED || - svcStatus.rs_state == RG_STATE_UNINITIALIZED) - return RG_EINVAL; - - if (svcStatus.rs_state == RG_STATE_RECOVER) - add_restart(svcName); - - for (x = 0; x < target_list_len; x++) { - - target = target_list[x]; - ret = svc_start_remote(svcName, RG_START_REMOTE, - target); - switch (ret) { - case RG_ERUN: - /* Someone stole the service while we were - trying to start it */ - get_rg_state_local(svcName, &svcStatus); - if (new_owner) - *new_owner = svcStatus.rs_owner; - return 0; - case RG_EEXCL: - ++excl; - continue; - case RG_EDEPEND: - case RG_ERELO: - ++dep; - continue; - case RG_EFAIL: - ++fail; - continue; - case RG_EABORT: - svc_report_failure(svcName); - return RG_EFAIL; - default: - /* deliberate fallthrough */ - clulog(LOG_ERR, - "#61: Invalid reply from member %d during" - " start operation!\n", target); - case RG_NO: - /* state uncertain */ - clulog(LOG_CRIT, "State Uncertain: svc:%s " - "nid:%d req:%s ret:%s\n", svcName, - target, rg_req_str(RG_START_REMOTE), rg_strerror(ret)); - return 0; - case 0: - if (new_owner) - *new_owner = target; - clulog(LOG_NOTICE, "Service %s is now running " - "on member %d\n", svcName, (int)target); - return 0; - } - } - - ret = RG_EFAIL; - if (excl == target_list_len) - ret = RG_EEXCL; - else if (dep == target_list_len) - ret = RG_EDEPEND; - - clulog(LOG_INFO, "Start failed; node reports: %d failures, " - "%d exclusive, %d dependency errors\n", fail, excl, dep); - return ret; -} - - -int -service_op_stop(char *svcName, int do_disable, int event_type) -{ - SmMessageSt msg; - int msg_ret; - int fd; - rg_state_t svcStatus; - uint64_t msgtarget = my_id(); - - /* Build the message header */ - msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msg.sm_hdr.gh_command = RG_ACTION_REQUEST; - msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER; - msg.sm_hdr.gh_length = sizeof (SmMessageSt); - - msg.sm_data.d_action = ((!do_disable) ? RG_STOP:RG_DISABLE); - - if (msg.sm_data.d_action == RG_STOP && event_type == EVENT_USER) - msg.sm_data.d_action = RG_STOP_USER; - - strncpy(msg.sm_data.d_svcName, svcName, - sizeof(msg.sm_data.d_svcName)); - msg.sm_data.d_ret = 0; - msg.sm_data.d_svcOwner = 0; - - /* Open a connection to the local node - it will decide what to - do in this case. XXX inefficient; should queue requests - locally and immediately forward requests otherwise */ - - if (get_service_state_internal(svcName, &svcStatus) < 0) - return RG_EFAIL; - - if (svcStatus.rs_owner != NODE_ID_NONE) { - if (member_online(svcStatus.rs_owner)) { - msgtarget = svcStatus.rs_owner; - } else { - /* If the owner is not online, - mark the service as 'stopped' but - otherwise, do nothing. - */ - return svc_stop(svcName, RG_STOP); - } - } - - if ((fd = msg_open(msgtarget, RG_PORT, RG_PURPOSE, 2)) < 0) { - clulog(LOG_ERR, - "#58: Failed opening connection to member #0x%x\n", - (unsigned)msgtarget); - return -1; - } - - /* Encode */ - swab_SmMessageSt(&msg); - - /* Send stop message to the other node */ - if (msg_send(fd, &msg, sizeof (SmMessageSt)) < - (int)sizeof (SmMessageSt)) { - clulog(LOG_ERR, "Failed to send complete message\n"); - msg_close(fd); - return -1; - } - - /* Check the response */ - do { - msg_ret = msg_receive_timeout(fd, &msg, - sizeof (SmMessageSt), 10); - if ((msg_ret == -1 && errno != ETIMEDOUT) || - (msg_ret > 0)) { - break; - } - } while(1); - - if (msg_ret != sizeof (SmMessageSt)) { - clulog(LOG_WARNING, "Strange response size: %d vs %d\n", - msg_ret, (int)sizeof(SmMessageSt)); - return 0; /* XXX really UNKNOWN */ - } - - /* Got a valid response from other node. */ - msg_close(fd); - - /* Decode */ - swab_SmMessageSt(&msg); - - return msg.sm_data.d_ret; -} - - -/* - TODO - service_op_migrate() - */ - diff --git a/rgmanager/src/daemons/slang_event.c b/rgmanager/src/daemons/slang_event.c deleted file mode 100644 index 859fa3b..0000000 --- a/rgmanager/src/daemons/slang_event.c +++ /dev/null @@ -1,1290 +0,0 @@ -/* - Copyright Red Hat, Inc. 2007 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 as published - by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** - @file S/Lang event handling & intrinsic functions + vars - */ -#include <platform.h> -#include <sets.h> -#include <resgroup.h> -#include <list.h> -#include <restart_counter.h> -#include <reslist.h> -#include <resgroup.h> -#include <clulog.h> -#include <magma.h> -#include <magmamsg.h> -#include <assert.h> -#include <event.h> - -#include <stdio.h> -#include <string.h> -#include <slang.h> -#include <sys/syslog.h> -#include <malloc.h> -#include <clulog.h> -#include <signal.h> - -static int __sl_initialized = 0; - -static char **_service_list = NULL; -static int _service_list_len = 0; - -char **get_service_names(int *len); /* from groups.c */ -int get_service_property(char *rg_name, char *prop, char *buf, size_t buflen); -void push_int_array(set_type_t *stuff, int len); -int member_online_set(set_type_t **nodes, int *nodecount); - - - -/* ================================================================ - * Node states - * ================================================================ */ -static const int - _ns_online = 1, - _ns_offline = 0; - -/* ================================================================ - * Event information - * ================================================================ */ -static const int - _ev_none = EVENT_NONE, - _ev_node = EVENT_NODE, - _ev_service = EVENT_RG, - _ev_config = EVENT_CONFIG, - _ev_user = EVENT_USER; - -static const int - _rg_fail = RG_EFAIL, - _rg_success = RG_ESUCCESS, - _rg_edomain = RG_EDOMAIN, - _rg_edepend = RG_EDEPEND, - _rg_eabort = RG_EABORT, - _rg_einval = RG_EINVAL, - _rg_erun = RG_ERUN; - -static int - _stop_processing = 0, - _my_node_id = 0, - _node_state = 0, - _node_id = 0, - _node_clean = 0, - _service_owner = 0, - _service_last_owner = 0, - _service_restarts_exceeded = 0, - _user_request = 0, - _user_arg1 = 0, - _user_arg2 = 0, - _user_return = 0, - _rg_err = 0, - _event_type = 0; - -static char - *_node_name = NULL, - *_service_name = NULL, - *_service_state = NULL, - *_rg_err_str = "No Error"; - -static int - _user_enable = RG_ENABLE, - _user_disable = RG_DISABLE, - _user_stop = RG_STOP_USER, /* From clusvcadm */ - _user_relo = RG_RELOCATE, - _user_restart = RG_RESTART; - - -SLang_Intrin_Var_Type rgmanager_vars[] = -{ - /* Log levels (constants) */ - - /* Node state information */ - MAKE_VARIABLE("NODE_ONLINE", &_ns_online, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("NODE_OFFLINE", &_ns_offline, SLANG_INT_TYPE, 1), - - /* Node event information */ - MAKE_VARIABLE("node_self", &_my_node_id, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("node_state", &_node_state, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("node_id", &_node_id, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("node_name", &_node_name, SLANG_STRING_TYPE,1), - MAKE_VARIABLE("node_clean", &_node_clean, SLANG_INT_TYPE, 1), - - /* Service event information */ - MAKE_VARIABLE("service_name", &_service_name, SLANG_STRING_TYPE,1), - MAKE_VARIABLE("service_state", &_service_state,SLANG_STRING_TYPE,1), - MAKE_VARIABLE("service_owner", &_service_owner,SLANG_INT_TYPE, 1), - MAKE_VARIABLE("service_last_owner", &_service_last_owner, - SLANG_INT_TYPE, 1), - MAKE_VARIABLE("service_restarts_exceeded", &_service_restarts_exceeded, - SLANG_INT_TYPE, 1), - - /* User event information */ - MAKE_VARIABLE("user_request", &_user_request, SLANG_INT_TYPE,1), - MAKE_VARIABLE("user_arg1", &_user_arg1, SLANG_INT_TYPE,1), - MAKE_VARIABLE("user_arg2", &_user_arg2, SLANG_INT_TYPE,1), - MAKE_VARIABLE("user_service", &_service_name, SLANG_STRING_TYPE,1), - MAKE_VARIABLE("user_target", &_service_owner,SLANG_INT_TYPE, 1), - /* Return code to user requests; i.e. clusvcadm */ - MAKE_VARIABLE("user_return", &_user_return, SLANG_INT_TYPE, 0), - - /* General event information */ - MAKE_VARIABLE("event_type", &_event_type, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("EVENT_NONE", &_ev_none, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("EVENT_NODE", &_ev_node, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("EVENT_CONFIG", &_ev_config, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("EVENT_SERVICE", &_ev_service, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("EVENT_USER", &_ev_user, SLANG_INT_TYPE, 1), - - /* User request constants */ - MAKE_VARIABLE("USER_ENABLE", &_user_enable, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("USER_DISABLE", &_user_disable, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("USER_STOP", &_user_stop, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("USER_RELOCATE", &_user_relo, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("USER_RESTART", &_user_restart, SLANG_INT_TYPE, 1), - - /* Errors */ - MAKE_VARIABLE("rg_error", &_rg_err, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("rg_error_string",&_rg_err_str, SLANG_STRING_TYPE,1), - - /* From constants.c */ - MAKE_VARIABLE("FAIL", &_rg_fail, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("SUCCESS", &_rg_success, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("ERR_ABORT", &_rg_eabort, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("ERR_INVALID", &_rg_einval, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("ERR_DEPEND", &_rg_edepend, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("ERR_DOMAIN", &_rg_edomain, SLANG_INT_TYPE, 1), - MAKE_VARIABLE("ERR_RUNNING", &_rg_erun, SLANG_INT_TYPE, 1), - - SLANG_END_INTRIN_VAR_TABLE -}; - - -#define rg_error(errortype) \ -do { \ - _rg_err = errortype; \ - _rg_err_str = ##errortype; \ -} while(0) - - -int -get_service_state_internal(char *svcName, rg_state_t *svcStatus) -{ - void *lock; - char buf[32]; - - get_rg_state_local(svcName, svcStatus); - if (svcStatus->rs_state == RG_STATE_UNINITIALIZED) { - if (rg_lock(svcName, &lock) < 0) { - errno = ENOLCK; - return -1; - } - - if (get_rg_state(svcName, svcStatus) < 0) { - errno = ENOENT; - rg_unlock(svcName, lock); - return -1; - } - - /* We got a copy from another node - don't flip the state */ - if (svcStatus->rs_transition) { - rg_unlock(svcName, lock); - return 0; - } - - /* Finish initializing the service state */ - svcStatus->rs_transition = (uint64_t)time(NULL); - - if (get_service_property(svcName, "autostart", - buf, sizeof(buf)) == 0) { - if (buf[0] == '0' || !strcasecmp(buf, "no")) { - svcStatus->rs_state = RG_STATE_DISABLED; - } else { - svcStatus->rs_state = RG_STATE_STOPPED; - } - } - - set_rg_state(svcName, svcStatus); - - rg_unlock(svcName, lock); - } - - return 0; -} - - -/* - (restarts, last_owner, owner, state) = get_service_status(servicename) - */ -void -sl_service_status(char *svcName) -{ - rg_state_t svcStatus; - int restarts_exceeded = 0; - char *state_str; - - if (get_service_state_internal(svcName, &svcStatus) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to get status for %s", - __FUNCTION__, - svcName); - return; - } - - restarts_exceeded = check_restart(svcName); - if (SLang_push_integer(restarts_exceeded) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to push restarts_exceeded %s", - __FUNCTION__, - svcName); - return; - } - - if (SLang_push_integer(svcStatus.rs_restarts) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to push restarts for %s", - __FUNCTION__, - svcName); - return; - } - - if (SLang_push_integer((int)(svcStatus.rs_last_owner)) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to push last owner of %s", - __FUNCTION__, - svcName); - return; - } - - switch(svcStatus.rs_state) { - case RG_STATE_DISABLED: - case RG_STATE_STOPPED: - case RG_STATE_FAILED: - case RG_STATE_RECOVER: - case RG_STATE_ERROR: - /* There is no owner for these states. Ever. */ - svcStatus.rs_owner = -1; - } - - if (SLang_push_integer((int)(svcStatus.rs_owner)) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to push owner of %s", - __FUNCTION__, - svcName); - return; - } - - state_str = strdup(rg_state_str(svcStatus.rs_state)); - if (!state_str) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to duplicate state of %s", - __FUNCTION__, - svcName); - return; - } - - if (SLang_push_malloced_string(state_str) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - "%s: Failed to push state of %s", - __FUNCTION__, - svcName); - //free(state_str); - } -} - - -/** - (nofailback, restricted, ordered, nodelist) = service_domain_info(svcName); - */ -void -sl_domain_info(char *svcName) -{ - set_type_t *nodelist = NULL; - int listlen; - char buf[64]; - int flags = 0; - - if (get_service_property(svcName, "domain", buf, sizeof(buf)) < 0) { - /* no nodes */ - SLang_push_integer(0); - - /* no domain? */ -/* - str = strdup("none"); - if (SLang_push_malloced_string(str) < 0) { - free(state_str); - return; - } -*/ - - /* not ordered */ - SLang_push_integer(0); - /* not restricted */ - SLang_push_integer(0); - /* nofailback not set */ - SLang_push_integer(0); - } - - if (node_domain_set_safe(buf, &nodelist, &listlen, &flags) < 0) { - SLang_push_integer(0); - SLang_push_integer(0); - SLang_push_integer(0); - SLang_push_integer(0); - return; - } - - SLang_push_integer(!!(flags & FOD_NOFAILBACK)); - SLang_push_integer(!!(flags & FOD_RESTRICTED)); - SLang_push_integer(!!(flags & FOD_ORDERED)); - - push_int_array(nodelist, listlen); - free(nodelist); - -/* - str = strdup(buf); - if (SLang_push_malloced_string(str) < 0) { - free(state_str); - return; - } -*/ -} - - -static int -get_int_array(set_type_t **nodelist, int *len) -{ - SLang_Array_Type *a = NULL; - set_type_t *nodes = NULL; - int i; - int t, ret = -1, tmp; - - if (!nodelist || !len) - return -1; - - t = SLang_peek_at_stack(); - if (t == SLANG_INT_TYPE) { - - nodes = malloc(sizeof(set_type_t) * 1); - if (!nodes) - goto out; - if (SLang_pop_integer(&tmp) < 0) - goto out; - - /* XXX gulm? */ - nodes[0] = (uint64_t)tmp; - *len = 1; - ret = 0; - - } else if (t == SLANG_ARRAY_TYPE) { - if (SLang_pop_array_of_type(&a, SLANG_INT_TYPE) < 0) - goto out; - if (a->num_dims > 1) - goto out; - if (a->dims[0] < 0) - goto out; - nodes = malloc(sizeof(set_type_t) * a->dims[0]); - if (!nodes) - goto out; - for (i = 0; i < a->dims[0]; i++) { - SLang_get_array_element(a, &i, &tmp); - /* XXX gulm? */ - nodes[i] = (uint64_t)tmp; - } - - *len = a->dims[0]; - ret = 0; - } - -out: - if (a) - SLang_free_array(a); - if (ret == 0) { - *nodelist = nodes; - } else { - if (nodes) - free(nodes); - } - - return ret; -} - - -/** - get_service_property(service_name, property) - */ -static void -sl_service_property(char *svcName, char *prop) -{ - char buf[96]; - char *ret; - - if (get_service_property(svcName, prop, buf, sizeof(buf)) < 0) - return; - - ret = strdup(buf); - if (!ret) { - SLang_verror(SL_INTRINSIC_ERROR, - (char *)"%s: Failed to duplicate %s property of %s", - __FUNCTION__, prop, svcName); - return; - } - - if (SLang_push_malloced_string(ret) < 0) { - SLang_verror(SL_INTRINSIC_ERROR, - (char *)"%s: Failed to push %s property of %s", - __FUNCTION__, prop, svcName); - free(ret); - } -} - - -/** - usage: - - stop_service(name, disable_flag); - */ -int -sl_stop_service(void) -{ - char *svcname = NULL; - int nargs, t, ret = -1; - int do_disable = 0; - - nargs = SLang_Num_Function_Args; - - /* Takes one or two args */ - if (nargs <= 0 || nargs > 2) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: Wrong # of args (%d), must be 1 or 2\n", - __FUNCTION__, - nargs); - return -1; - } - - if (nargs == 2) { - t = SLang_peek_at_stack(); - if (t != SLANG_INT_TYPE) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: expected type %d got %d\n", - __FUNCTION__, SLANG_INT_TYPE, t); - goto out; - } - - if (SLang_pop_integer(&do_disable) < 0) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: Failed to pop integer from stack!\n", - __FUNCTION__); - goto out; - } - - --nargs; - } - - if (nargs == 1) { - t = SLang_peek_at_stack(); - if (t != SLANG_STRING_TYPE) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: expected type %d got %d\n", - __FUNCTION__, - SLANG_STRING_TYPE, t); - goto out; - } - - if (SLpop_string(&svcname) < 0) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: Failed to pop string from stack!\n", - __FUNCTION__); - goto out; - } - } - - /* TODO: Meat of function goes here */ - ret = service_op_stop(svcname, do_disable, _event_type); -out: - if (svcname) - free(svcname); - _user_return = ret; - return ret; -} - - -/** - usage: - - start_service(name, <array>ordered_node_list_allowed, - <array>node_list_illegal) - */ -int -sl_start_service(void) -{ - char *svcname = NULL; - set_type_t *pref_list = NULL, *illegal_list = NULL; - int pref_list_len = 0, illegal_list_len = 0; - int nargs, t, ret = -1; - uint64_t newowner; - - nargs = SLang_Num_Function_Args; - - /* Takes one, two, or three */ - if (nargs <= 0 || nargs > 3) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: Wrong # of args (%d), must be 1 or 2\n", - __FUNCTION__, nargs); - return -1; - } - - if (nargs == 3) { - if (get_int_array(&illegal_list, &illegal_list_len) < 0) - goto out; - --nargs; - } - - if (nargs == 2) { - if (get_int_array(&pref_list, &pref_list_len) < 0) - goto out; - --nargs; - } - - if (nargs == 1) { - /* Just get the service name */ - t = SLang_peek_at_stack(); - if (t != SLANG_STRING_TYPE) { - SLang_verror(SL_SYNTAX_ERROR, - "%s: expected type %d got %d\n", - __FUNCTION__, - SLANG_STRING_TYPE, t); - goto out; - } - - if (SLpop_string(&svcname) < 0) - goto out; - } - - /* TODO: Meat of function goes here */ - ret = service_op_start(svcname, pref_list, - pref_list_len, &newowner); - - if (ret == 0 && newowner > 0) - ret = newowner; -out: - if (svcname) - free(svcname); - if (illegal_list) - free(illegal_list); - if (pref_list) - free(pref_list); - _user_return = ret; - return ret; -} - - -/* Take an array of integers given its length and - push it on to the S/Lang stack */ -void -push_int_array(set_type_t *stuff, int len) -{ - int arrlen, x; - SLang_Array_Type *arr; - int i; - - arrlen = len; - arr = SLang_create_array(SLANG_INT_TYPE, 0, NULL, &arrlen, 1); - if (!arr) - return; - - x = 0; - for (x = 0; x < len; x++) { - /* XXX gulm? */ - i = (int) (stuff[x]); - SLang_set_array_element(arr, &x, &i); - } - SLang_push_array(arr, 1); -} - - -/* - Returns an array of rgmanager-visible nodes online. How cool is that? - */ -void -sl_nodes_online(void) -{ - set_type_t *nodes; - int nodecount = 0, x = 0; - - x = member_online_set(&nodes, &nodecount); - if (x < 0 || !nodes || !nodecount) - return; - - push_int_array(nodes, nodecount); - free(nodes); -} - - -/* - Returns an array of rgmanager-defined services, in type:name format - We allocate/kill this list *once* per event to ensure we don't leak - memory - */ -void -sl_service_list(void) -{ - int svccount = _service_list_len, x = 0; - SLang_Array_Type *svcarray; - - svcarray = SLang_create_array(SLANG_STRING_TYPE, 0, NULL, &svccount, 1); - if (!svcarray) - return; - - for (; x < _service_list_len; x++) - SLang_set_array_element(svcarray, &x, &_service_list[x]); - - SLang_push_array(svcarray, 1); -} - - -/* s_union hook (see sets.c) */ -void -sl_union(void) -{ - set_type_t *arr1 = NULL, *arr2 = NULL, *ret = NULL; - int a1len = 0, a2len = 0, retlen = 0; - int nargs = SLang_Num_Function_Args; - - if (nargs != 2) - return; - - /* Remember: args on the stack are reversed */ - get_int_array(&arr2, &a2len); - get_int_array(&arr1, &a1len); - s_union(arr1, a1len, arr2, a2len, &ret, &retlen); - push_int_array(ret, retlen); - if (arr1) - free(arr1); - if (arr2) - free(arr2); - if (ret) - free(ret); - return; -} - - -/* s_intersection hook (see sets.c) */ -void -sl_intersection(void) -{ - set_type_t *arr1 = NULL, *arr2 = NULL, *ret = NULL; - int a1len = 0, a2len = 0, retlen = 0; - int nargs = SLang_Num_Function_Args; - - if (nargs != 2) - return; - - /* Remember: args on the stack are reversed */ - get_int_array(&arr2, &a2len); - get_int_array(&arr1, &a1len); - s_intersection(arr1, a1len, arr2, a2len, &ret, &retlen); - push_int_array(ret, retlen); - if (arr1) - free(arr1); - if (arr2) - free(arr2); - if (ret) - free(ret); - return; -} - - -/* s_delta hook (see sets.c) */ -void -sl_delta(void) -{ - set_type_t *arr1 = NULL, *arr2 = NULL, *ret = NULL; - int a1len = 0, a2len = 0, retlen = 0; - int nargs = SLang_Num_Function_Args; - - if (nargs != 2) - return; - - /* Remember: args on the stack are reversed */ - get_int_array(&arr2, &a2len); - get_int_array(&arr1, &a1len); - s_delta(arr1, a1len, arr2, a2len, &ret, &retlen); - push_int_array(ret, retlen); - if (arr1) - free(arr1); - if (arr2) - free(arr2); - if (ret) - free(ret); - return; -} - - -/* s_subtract hook (see sets.c) */ -void -sl_subtract(void) -{ - set_type_t *arr1 = NULL, *arr2 = NULL, *ret = NULL; - int a1len = 0, a2len = 0, retlen = 0; - int nargs = SLang_Num_Function_Args; - - if (nargs != 2) - return; - - /* Remember: args on the stack are reversed */ - get_int_array(&arr2, &a2len); - get_int_array(&arr1, &a1len); - s_subtract(arr1, a1len, arr2, a2len, &ret, &retlen); - push_int_array(ret, retlen); - if (arr1) - free(arr1); - if (arr2) - free(arr2); - if (ret) - free(ret); - return; -} - - -/* Shuffle array (see sets.c) */ -void -sl_shuffle(void) -{ - set_type_t *arr1 = NULL; - int a1len = 0; - int nargs = SLang_Num_Function_Args; - - if (nargs != 1) - return; - - /* Remember: args on the stack are reversed */ - get_int_array(&arr1, &a1len); - s_shuffle(arr1, a1len); - push_int_array(arr1, a1len); - if (arr1) - free(arr1); - return; -} - - -/* Converts an int array to a string so we can log it in one shot */ -static int -array_to_string(char *buf, int buflen, set_type_t *array, int arraylen) -{ - char intbuf[16]; - int x, len, remain = buflen; - - memset(intbuf, 0, sizeof(intbuf)); - memset(buf, 0, buflen); - len = snprintf(buf, buflen - 1, "[ "); - if (len == buflen) - return -1; - - remain -= len; - for (x = 0; x < arraylen; x++) { - len = snprintf(intbuf, sizeof(intbuf) - 1, "%d ", (int)array[x]); - remain -= len; - if (remain > 0) { - strncat(buf, intbuf, len); - } else { - return -1; - } - } - - len = snprintf(intbuf, sizeof(intbuf) - 1 , "]"); - remain -= len; - if (remain > 0) { - strncat(buf, intbuf, len); - } else { - return -1; - } - return (buflen - remain); -} - - -/** - Start at the end of the arg list and work backwards, prepending a string. - This does not support standard clulog / printf formattting; rather, we - just allow integers / strings to be mixed on the stack, figure out the - type, convert it to the right type, and prepend it on to our log message - - The last must be a log level, as specified above: - LOG_DEBUG - ... - LOG_EMERG - - This matches up with clulog / syslog mappings in the var table; the above - are constants in the S/Lang interpreter. Any number of arguments may - be provided. Examples are: - - log(LOG_INFO, "String", 1, "string2"); - - Result: String1string2 - - log(LOG_INFO, "String ", 1, " string2"); - - Result: String 1 string2 - - */ -void -sl_clulog(int level) -{ - int t, nargs, len; - //int level; - int s_intval; - char *s_strval; - set_type_t *nodes = NULL; - int nlen = 0; - char logbuf[512]; - char tmp[256]; - int need_free; - int remain = sizeof(logbuf)-2; - - nargs = SLang_Num_Function_Args; - if (nargs < 1) - return; - - memset(logbuf, 0, sizeof(logbuf)); - memset(tmp, 0, sizeof(tmp)); - logbuf[sizeof(logbuf)-1] = 0; - logbuf[sizeof(logbuf)-2] = '\n'; - - while (nargs && (t = SLang_peek_at_stack()) >= 0 && remain) { - switch(t) { - case SLANG_ARRAY_TYPE: - if (get_int_array(&nodes, &nlen) < 0) - return; - len = array_to_string(tmp, sizeof(tmp), - nodes, nlen); - if (len < 0) { - free(nodes); - return; - } - free(nodes); - break; - case SLANG_INT_TYPE: - if (SLang_pop_integer(&s_intval) < 0) - return; - len=snprintf(tmp, sizeof(tmp) - 1, "%d", s_intval); - break; - case SLANG_STRING_TYPE: - need_free = 0; - if (SLpop_string(&s_strval) < 0) - return; - len=snprintf(tmp, sizeof(tmp) - 1, "%s", s_strval); - SLfree(s_strval); - break; - default: - need_free = 0; - len=snprintf(tmp, sizeof(tmp) - 1, - "{UnknownType %d}", t); - break; - } - - --nargs; - - if (len > remain) - return; - remain -= len; - - memcpy(&logbuf[remain], tmp, len); - } - -#if 0 - printf("<%d> %s\n", level, &logbuf[remain]); -#endif - clulog(level, &logbuf[remain]); - return; -} - - -/* Logging functions */ -void -sl_log_debug(void) -{ - sl_clulog(LOG_DEBUG); -} - - -void -sl_log_info(void) -{ - sl_clulog(LOG_INFO); -} - - -void -sl_log_notice(void) -{ - sl_clulog(LOG_NOTICE); -} - - -void -sl_log_warning(void) -{ - sl_clulog(LOG_WARNING); -} - - -void -sl_log_err(void) -{ - sl_clulog(LOG_ERR); -} - - -void -sl_log_crit(void) -{ - sl_clulog(LOG_CRIT); -} - - -void -sl_log_alert(void) -{ - sl_clulog(LOG_ALERT); -} - - -void -sl_log_emerg(void) -{ - sl_clulog(LOG_EMERG); -} - - -void -sl_die(void) -{ - _stop_processing = 1; - return; -} - - -SLang_Intrin_Fun_Type rgmanager_slang[] = -{ - MAKE_INTRINSIC_0("nodes_online", sl_nodes_online, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("service_list", sl_service_list, SLANG_VOID_TYPE), - - MAKE_INTRINSIC_SS("service_property", sl_service_property, - SLANG_STRING_TYPE), - MAKE_INTRINSIC_S("service_domain_info", sl_domain_info, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("service_stop", sl_stop_service, SLANG_INT_TYPE), - MAKE_INTRINSIC_0("service_start", sl_start_service, SLANG_INT_TYPE), - MAKE_INTRINSIC_S("service_status", sl_service_status, - SLANG_VOID_TYPE), - - /* Node list manipulation */ - MAKE_INTRINSIC_0("union", sl_union, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("intersection", sl_intersection, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("delta", sl_delta, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("subtract", sl_subtract, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("shuffle", sl_shuffle, SLANG_VOID_TYPE), - - /* Logging */ - MAKE_INTRINSIC_0("debug", sl_log_debug, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("info", sl_log_info, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("notice", sl_log_notice, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("warning", sl_log_warning, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("err", sl_log_err, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("crit", sl_log_crit, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("alert", sl_log_alert, SLANG_VOID_TYPE), - MAKE_INTRINSIC_0("emerg", sl_log_emerg, SLANG_VOID_TYPE), - - MAKE_INTRINSIC_0("stop_processing", sl_die, SLANG_VOID_TYPE), - - SLANG_END_INTRIN_FUN_TABLE -}; - - -/* Hook for when we generate a script error */ -void -rgmanager_slang_error_hook(char *errstr) -{ - /* Don't just send errstr, because it might contain - "%s" for example which would result in a crash! - plus, we like the newline :) */ - clulog(LOG_ERR, "[S/Lang] %s\n", errstr); - //raise(SIGSTOP); -} - - - -/* ================================================================ - * S/Lang initialization - * ================================================================ */ -int -do_init_slang(void) -{ - SLang_init_slang(); - SLang_init_slfile(); - - if (SLadd_intrin_fun_table(rgmanager_slang, NULL) < 0) - return 1; - if (SLadd_intrin_var_table (rgmanager_vars, NULL) < 0) - return 1; - - /* TODO: Make rgmanager S/Lang conformant. Though, it - might be a poor idea to provide access to all the - S/Lang libs */ - SLpath_set_load_path(RESOURCE_ROOTDIR); - - _my_node_id = my_id(); - __sl_initialized = 1; - - SLang_Error_Hook = rgmanager_slang_error_hook; - - return 0; -} - - -/* - Execute a script / file and return the result to the caller - Log an error if we receive one. - */ -int -do_slang_run(const char *file, const char *script) -{ - int ret = 0; - int tries = 0; - - for (tries = 0; tries < 2; tries++) { - /* XXX This is here because there's a stack leak - that I have not been able to track down */ - SLang_restart(1); - SLang_Error = 0; - - if (file) - ret = SLang_load_file((char *)file); - else - ret = SLang_load_string((char *)script); - - if (ret == 0) - break; - } - - if (ret < 0) - clulog(LOG_ERR, "[S/Lang] Script Execution Failure\n"); - - return ret; -} - - -int -S_node_event(const char *file, const char *script, int nodeid, - int state, int clean) -{ - int ret; - cluster_member_list_t *membership = member_list(); - char *nodename; - - nodename = memb_id_to_name(membership, nodeid); - if (nodename) - _node_name = strdup(nodename); - else - _node_name = strdup("unknown"); - _node_state = state; - _node_clean = clean; - _node_id = nodeid; - cml_free(membership); - - ret = do_slang_run(file, script); - - _node_state = 0; - _node_clean = 0; - _node_id = 0; - if (_node_name) - free(_node_name); - _node_name = NULL; - - return ret; -} - - -int -S_service_event(const char *file, const char *script, char *name, - int state, int owner, int last_owner) -{ - int ret; - - _service_name = name; - _service_state = (char *)rg_state_str(state); - _service_owner = owner; - _service_last_owner = last_owner; - _service_restarts_exceeded = check_restart(name); - - switch(state) { - case RG_STATE_DISABLED: - case RG_STATE_STOPPED: - case RG_STATE_FAILED: - case RG_STATE_RECOVER: - case RG_STATE_ERROR: - /* There is no owner for these states. Ever. */ - _service_owner = -1; - } - - ret = do_slang_run(file, script); - - _service_name = NULL; - _service_state = 0; - _service_owner = 0; - _service_last_owner = 0; - _service_restarts_exceeded = 0; - - return ret; -} - - -int -S_user_event(const char *file, const char *script, char *name, - int request, int arg1, int arg2, int target, int fd) -{ - int ret = RG_SUCCESS; - - _service_name = name; - _service_owner = target; - _user_request = request; - _user_arg1 = arg1; - _user_arg2 = arg2; - _user_return = 0; - - ret = do_slang_run(file, script); - if (ret < 0) { - _user_return = RG_ESCRIPT; - } - - _service_name = NULL; - _service_owner = 0; - _user_request = 0; - _user_arg1 = 0; - _user_arg2 = 0; - - /* XXX Send response code to caller - that 0 should be the - new service owner, if there is one */ - if (fd >= 0) { - if (_user_return > 0) { - /* sl_start_service() squashes return code and - node ID into one value. <0 = error, >0 = - success, return-value == node id running - service */ - send_ret(fd, name, 0, request, _user_return); - } else { - /* return value < 0 ... pass directly back; - don't transpose */ - send_ret(fd, name, _user_return, request, 0); - } - msg_close(fd); - } - _user_return = 0; - return ret; -} - - -int -slang_do_script(event_t *pattern, event_t *ev) -{ - _event_type = ev->ev_type; - int ret = 0; - - switch(ev->ev_type) { - case EVENT_NODE: - ret = S_node_event( - pattern->ev_script_file, - pattern->ev_script, - ev->ev.node.ne_nodeid, - ev->ev.node.ne_state, - ev->ev.node.ne_clean); - break; - case EVENT_RG: - ret = S_service_event( - pattern->ev_script_file, - pattern->ev_script, - ev->ev.group.rg_name, - ev->ev.group.rg_state, - ev->ev.group.rg_owner, - ev->ev.group.rg_last_owner); - break; - case EVENT_USER: - ret = S_user_event( - pattern->ev_script_file, - pattern->ev_script, - ev->ev.user.u_name, - ev->ev.user.u_request, - ev->ev.user.u_arg1, - ev->ev.user.u_arg2, - ev->ev.user.u_target, - ev->ev.user.u_fd); - break; - default: - break; - } - - _event_type = EVENT_NONE; - return ret; -} - - - -/** - Process an event given our event table and the event that - occurred. Note that the caller is responsible for freeing the - event - do not free (ev) ... - */ -int -slang_process_event(event_table_t *event_table, event_t *ev) -{ - int x, y; - event_t *pattern; - - if (!__sl_initialized) - do_init_slang(); - - /* Get the service list once before processing events */ - if (!_service_list || !_service_list_len) - _service_list = get_service_names(&_service_list_len); - - _stop_processing = 0; - for (x = 1; x <= event_table->max_prio; x++) { - list_for(&event_table->entries[x], pattern, y) { - if (event_match(pattern, ev)) - slang_do_script(pattern, ev); - if (_stop_processing) - goto out; - } - } - - /* Default level = 0 */ - list_for(&event_table->entries[0], pattern, y) { - if (event_match(pattern, ev)) - slang_do_script(pattern, ev); - if (_stop_processing) - goto out; - } - -out: - /* Free the service list */ - if (_service_list) { - for(x = 0; x < _service_list_len; x++) { - free(_service_list[x]); - } - free(_service_list); - _service_list = NULL; - _service_list_len = 0; - } - - return 0; -} diff --git a/rgmanager/src/daemons/test.c b/rgmanager/src/daemons/test.c deleted file mode 100644 index 1a6862c..0000000 --- a/rgmanager/src/daemons/test.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - Copyright Red Hat, Inc. 2004-2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include <libxml/xpath.h> -#include <stdlib.h> -#include <stdio.h> -#include <resgroup.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <list.h> -#include <restart_counter.h> -#include <reslist.h> -#include <event.h> -#include <pthread.h> - -#ifndef NO_CCS -#error "Can not be built with CCS support." -#endif - -#define shift() {++argv; --argc;} - -#define USAGE_TEST \ - "\ttest <configfile> [args..]\n" \ - "\t\tstart <type> <resource>\n" \ - "\t\tstatus <type> <resource>\n" \ - "\t\tstop <type> <resource>\n" \ - "\n" - -#define USAGE_DELTA \ - "\tdelta <configfile1> <configfile2>\n\n" - -#define USAGE_RULES \ - "\trules\n\n" - - -void _no_op_mode(int); -void malloc_dump_table(void); -char *agentpath = RESOURCE_ROOTDIR; - - -int -rules_func(int argc, char **argv) -{ - resource_rule_t *rulelist = NULL, *currule; - int rules = 0; - - fprintf(stderr,"Running in rules mode.\n"); - - load_resource_rules(agentpath, &rulelist); - list_do(&rulelist, currule) { - ++rules; - } while (!list_done(&rulelist, currule)); - fprintf(stderr, "Loaded %d resource rules\n", - rules); - list_do(&rulelist, currule) { - print_resource_rule(currule); - } while (!list_done(&rulelist, currule)); - - destroy_resource_rules(&rulelist); - - return 0; -} - - - -int -test_func(int argc, char **argv) -{ - fod_t *domains = NULL; - resource_rule_t *rulelist = NULL, *currule; - resource_t *reslist = NULL, *curres; - resource_node_t *tree = NULL, *tmp, *rn = NULL; - int ccsfd, ret = 0, rules = 0; - event_table_t *events = NULL; - - fprintf(stderr,"Running in test mode.\n"); - - conf_setconfig(argv[1]); - ccsfd = ccs_lock(); - if (ccsfd < 0) { - printf("Error parsing %s\n", argv[1]); - goto out; - } - - load_resource_rules(agentpath, &rulelist); - construct_domains(ccsfd, &domains); - construct_events(ccsfd, &events); - load_resources(ccsfd, &reslist, &rulelist); - build_resource_tree(ccsfd, &tree, &rulelist, &reslist); - - shift(); - - if (argc == 1) { - /* - printf("=== Resource XML Rules ===\n"); - list_do(&rulelist, currule) { - print_resource_rule(currule); - } while (!list_done(&rulelist, currule)); - */ - list_do(&rulelist, currule) { - ++rules; - } while (!list_done(&rulelist, currule)); - fprintf(stderr, "Loaded %d resource rules\n", - rules); - - if (reslist) { - printf("=== Resources List ===\n"); - list_do(&reslist, curres) { - print_resource(curres); - } while (!list_done(&reslist, curres)); - } - - if (tree) { - printf("=== Resource Tree ===\n"); - print_resource_tree(&tree); - } - - if (domains) { - printf("=== Failover Domains ===\n"); - print_domains(&domains); - } - - if (events) { - printf("=== Event Triggers ===\n"); - print_events(events); - } - } - - ccs_unlock(ccsfd); - - if (argc < 4) - goto out; - - curres = find_resource_by_ref(&reslist, argv[2], argv[3]); - if (!curres) { - printf("No resource %s of type %s found\n", - argv[3], argv[2]); - goto out; - } - - list_do(&tree, tmp) { - if (tmp->rn_resource == curres) { - rn = tmp; - break; - } - } while (!list_done(&tree, tmp)); - - if (!strcmp(argv[1], "start")) { - printf("Starting %s...\n", argv[3]); - - if (res_start(&tree, curres, NULL)) { - printf("Failed to start %s\n", argv[3]); - ret = -1; - goto out; - } - printf("Start of %s complete\n", argv[3]); - goto out; - } else if (!strcmp(argv[1], "stop")) { - printf("Stopping %s...\n", argv[3]); - - if (res_stop(&tree, curres, NULL)) { - ret = -1; - goto out; - } - printf("Stop of %s complete\n", argv[3]); - goto out; - } else if (!strcmp(argv[1], "migrate")) { - printf("Migrating %s to %s...\n", argv[3], argv[4]); - - #if 0 - if (!group_migratory(curres)) { - printf("No can do\n"); - ret = -1; - goto out; - } - #endif - - if (res_exec(rn, RS_MIGRATE, argv[4], 0)) { - ret = -1; - goto out; - } - printf("Migration of %s complete\n", argv[3]); - goto out; - } else if (!strcmp(argv[1], "status")) { - printf("Checking status of %s...\n", argv[3]); - - ret = res_status(&tree, curres, NULL); - if (ret) { - printf("Status check of %s failed\n", argv[3]); - goto out; - } - printf("Status of %s is good\n", argv[3]); - goto out; - } - -out: - deconstruct_events(&events); - deconstruct_domains(&domains); - destroy_resource_tree(&tree); - destroy_resources(&reslist); - destroy_resource_rules(&rulelist); - - return ret; -} - - -int -tree_delta_test(int argc, char **argv) -{ - resource_rule_t *rulelist = NULL, *currule, *rulelist2 = NULL; - resource_t *reslist = NULL, *curres, *reslist2 = NULL; - resource_node_t *tree = NULL, *tree2 = NULL; - resource_node_t *tn; - int ccsfd, ret = 0, need_init, need_kill; - char rg[64]; - - if (argc < 2) { - printf("Operation requires two arguments\n"); - printf(USAGE_DELTA); - return -1; - } - - currule = NULL; - curres = NULL; - - fprintf(stderr,"Running in resource tree delta test mode.\n"); - - conf_setconfig(argv[1]); - - ccsfd = ccs_lock(); - if (ccsfd < 0) { - printf("Error parsing %s\n", argv[1]); - ret = 1; - goto out; - } - - load_resource_rules(agentpath, &rulelist); - load_resources(ccsfd, &reslist, &rulelist); - build_resource_tree(ccsfd, &tree, &rulelist, &reslist); - ccs_unlock(ccsfd); - - conf_setconfig(argv[2]); - - ccsfd = ccs_lock(); - if (ccsfd < 0) { - printf("Error parsing %s\n", argv[2]); - ret = 1; - goto out; - } - - load_resource_rules(agentpath, &rulelist2); - load_resources(ccsfd, &reslist2, &rulelist2); - build_resource_tree(ccsfd, &tree2, &rulelist2, &reslist2); - ccs_unlock(ccsfd); - - resource_delta(&reslist, &reslist2); - - printf("=== Old Resource List ===\n"); - list_do(&reslist, curres) { - print_resource(curres); - } while (!list_done(&reslist, curres)); - printf("=== New Resource List ===\n"); - list_do(&reslist2, curres) { - print_resource(curres); - } while (!list_done(&reslist2, curres)); - - curres = find_root_by_ref(&reslist, "oracle"); - - resource_tree_delta(&tree, &tree2); - printf("=== Old Resource Tree ===\n"); - print_resource_tree(&tree); - printf("=== New Resource Tree ===\n"); - print_resource_tree(&tree2); - printf("=== Operations (down-phase) ===\n"); - list_do(&tree, tn) { - res_build_name(rg, sizeof(rg), tn->rn_resource); - /* Set state to uninitialized if we're killing a RG */ - need_init = 0; - - /* Set state to uninitialized if we're killing a RG */ - need_kill = 0; - if (tn->rn_resource->r_flags & RF_NEEDSTOP) { - need_kill = 1; - printf("[kill] "); - } - - res_condstop(&tn, tn->rn_resource, NULL); - } while (!list_done(&tree, tn)); - printf("=== Operations (up-phase) ===\n"); - list_do(&tree2, tn) { - res_build_name(rg, sizeof(rg), tn->rn_resource); - /* New RG. We'll need to initialize it. */ - need_init = 0; - if (!(tn->rn_resource->r_flags & RF_RECONFIG) && - (tn->rn_resource->r_flags & RF_NEEDSTART)) - need_init = 1; - - if (need_init) { - printf("[init] "); - } - - if (need_init) { - res_stop(&tn, tn->rn_resource, NULL); - } else { - res_condstart(&tn, tn->rn_resource, NULL); - } - } while (!list_done(&tree2, tn)); - -out: - destroy_resource_tree(&tree2); - destroy_resources(&reslist2); - destroy_resource_rules(&rulelist2); - - destroy_resource_tree(&tree); - destroy_resources(&reslist); - destroy_resource_rules(&rulelist); - - return ret; -} - - -int -usage(char *arg0) -{ - printf("usage: %s [agent_path] <args..>\n\n", arg0); - printf(USAGE_TEST); - printf(USAGE_DELTA); - printf(USAGE_RULES); - - exit(1); -} - - -int -main(int argc, char **argv) -{ - char *arg0 = basename(argv[0]); - int ret; - struct stat st; - - if (argc < 2) { - usage(arg0); - return 1; - } - - xmlInitParser(); - while (argc > 1) { - if (!strcmp(argv[1], "test")) { - shift(); - ret = test_func(argc, argv); - goto out; - } else if (!strcmp(argv[1], "noop")) { - shift(); - _no_op_mode(1); - ret = test_func(argc, argv); - goto out; - } else if (!strcmp(argv[1], "rules")) { - shift(); - ret = rules_func(argc, argv); - goto out; - } else if (!strcmp(argv[1], "delta")) { - shift(); - _no_op_mode(1); - ret = tree_delta_test(argc, argv); - goto out; - } else { - ret = stat(argv[1], &st); - if (ret == -1 || !S_ISDIR(st.st_mode)) { - break; - } - fprintf(stderr, - "Using %s as resource agent path\n", - argv[1]); - agentpath = argv[1]; - shift(); - } - } - - usage(arg0); - xmlCleanupParser(); - malloc_dump_table(); - return 1; - -out: - xmlCleanupParser(); - malloc_dump_table(); - return ret; -} diff --git a/rgmanager/src/daemons/tests/delta-test001-test002.expected b/rgmanager/src/daemons/tests/delta-test001-test002.expected deleted file mode 100644 index 34eaf37..0000000 --- a/rgmanager/src/daemons/tests/delta-test001-test002.expected +++ /dev/null @@ -1,56 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] [INLINE] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; -} -=== Operations (down-phase) === -=== Operations (up-phase) === diff --git a/rgmanager/src/daemons/tests/delta-test002-test003.expected b/rgmanager/src/daemons/tests/delta-test002-test003.expected deleted file mode 100644 index 043b74c..0000000 --- a/rgmanager/src/daemons/tests/delta-test002-test003.expected +++ /dev/null @@ -1,70 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: script [NEEDSTART] -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/httpd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script [ NEEDSTART ] { - name = "initscript"; - file = "/etc/init.d/httpd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -Node script:initscript - CONDSTART -[start] script:initscript diff --git a/rgmanager/src/daemons/tests/delta-test003-test004.expected b/rgmanager/src/daemons/tests/delta-test003-test004.expected deleted file mode 100644 index 4bdd9ad..0000000 --- a/rgmanager/src/daemons/tests/delta-test003-test004.expected +++ /dev/null @@ -1,84 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: script [NEEDSTOP] -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/httpd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: script [NEEDSTART] -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script [ NEEDSTOP ] { - name = "initscript"; - file = "/etc/init.d/httpd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script [ NEEDSTART ] { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -Node script:initscript - CONDSTOP -[stop] script:initscript -=== Operations (up-phase) === -Node script:initscript - CONDSTART -[start] script:initscript diff --git a/rgmanager/src/daemons/tests/delta-test004-test005.expected b/rgmanager/src/daemons/tests/delta-test004-test005.expected deleted file mode 100644 index a3b8b55..0000000 --- a/rgmanager/src/daemons/tests/delta-test004-test005.expected +++ /dev/null @@ -1,95 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip [NEEDSTART] -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.2 [ primary unique ] - monitor_link = 1 - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip [ NEEDSTART ] { - address = "192.168.1.2"; - monitor_link = "1"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -Node ip:192.168.1.2 - CONDSTART -[start] ip:192.168.1.2 diff --git a/rgmanager/src/daemons/tests/delta-test005-test006.expected b/rgmanager/src/daemons/tests/delta-test005-test006.expected deleted file mode 100644 index 4e0310c..0000000 --- a/rgmanager/src/daemons/tests/delta-test005-test006.expected +++ /dev/null @@ -1,110 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip [NEEDSTOP] -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.2 [ primary unique ] - monitor_link = 1 - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip [NEEDSTART] -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.2 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip [ NEEDSTOP ] { - address = "192.168.1.2"; - monitor_link = "1"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip [ NEEDSTART ] { - address = "192.168.1.2"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -Node ip:192.168.1.2 - CONDSTOP -[stop] ip:192.168.1.2 -=== Operations (up-phase) === -Node ip:192.168.1.2 - CONDSTART -[start] ip:192.168.1.2 diff --git a/rgmanager/src/daemons/tests/delta-test006-test007.expected b/rgmanager/src/daemons/tests/delta-test006-test007.expected deleted file mode 100644 index bd4db79..0000000 --- a/rgmanager/src/daemons/tests/delta-test006-test007.expected +++ /dev/null @@ -1,110 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip [NEEDSTOP] -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.2 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip [NEEDSTART] -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip [ NEEDSTOP ] { - address = "192.168.1.2"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip [ NEEDSTART ] { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -Node ip:192.168.1.2 - CONDSTOP -[stop] ip:192.168.1.2 -=== Operations (up-phase) === -Node ip:192.168.1.3 - CONDSTART -[start] ip:192.168.1.3 diff --git a/rgmanager/src/daemons/tests/delta-test007-test008.expected b/rgmanager/src/daemons/tests/delta-test007-test008.expected deleted file mode 100644 index 19fe209..0000000 --- a/rgmanager/src/daemons/tests/delta-test007-test008.expected +++ /dev/null @@ -1,116 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: fs [NEEDSTART] -Instances: 0/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === diff --git a/rgmanager/src/daemons/tests/delta-test008-test009.expected b/rgmanager/src/daemons/tests/delta-test008-test009.expected deleted file mode 100644 index 5168931..0000000 --- a/rgmanager/src/daemons/tests/delta-test008-test009.expected +++ /dev/null @@ -1,135 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: fs -Instances: 0/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs [ NEEDSTART ] { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -Node fs:mount1 - CONDSTART -[start] fs:mount1 diff --git a/rgmanager/src/daemons/tests/delta-test009-test010.expected b/rgmanager/src/daemons/tests/delta-test009-test010.expected deleted file mode 100644 index ef379fd..0000000 --- a/rgmanager/src/daemons/tests/delta-test009-test010.expected +++ /dev/null @@ -1,149 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport [NEEDSTART] -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === diff --git a/rgmanager/src/daemons/tests/delta-test010-test011.expected b/rgmanager/src/daemons/tests/delta-test010-test011.expected deleted file mode 100644 index 38d7fb2..0000000 --- a/rgmanager/src/daemons/tests/delta-test010-test011.expected +++ /dev/null @@ -1,232 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport [ NEEDSTART ] { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -Node nfsexport:Dummy Export - CONDSTART -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group diff --git a/rgmanager/src/daemons/tests/delta-test011-test012.expected b/rgmanager/src/daemons/tests/delta-test011-test012.expected deleted file mode 100644 index 8b9803d..0000000 --- a/rgmanager/src/daemons/tests/delta-test011-test012.expected +++ /dev/null @@ -1,307 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient [NEEDSTOP] -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient [ NEEDSTART ] { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -Node nfsclient:red - CONDSTART -[start] nfsclient:red diff --git a/rgmanager/src/daemons/tests/delta-test012-test013.expected b/rgmanager/src/daemons/tests/delta-test012-test013.expected deleted file mode 100644 index c45223d..0000000 --- a/rgmanager/src/daemons/tests/delta-test012-test013.expected +++ /dev/null @@ -1,316 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient [NEEDSTOP] -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient [ NEEDSTOP ] { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient [ NEEDSTART ] { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Operations (down-phase) === -Node nfsclient:red - CONDSTOP -[stop] nfsclient:red -=== Operations (up-phase) === -Node nfsclient:red - CONDSTART -[start] nfsclient:red diff --git a/rgmanager/src/daemons/tests/delta-test013-test014.expected b/rgmanager/src/daemons/tests/delta-test013-test014.expected deleted file mode 100644 index d779448..0000000 --- a/rgmanager/src/daemons/tests/delta-test013-test014.expected +++ /dev/null @@ -1,407 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] [NEEDSTART] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs [NEEDSTART] -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip [NEEDSTART] -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service [ NEEDSTART ] { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -[init] [stop] script:initscript -[stop] ip:192.168.1.4 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -[stop] service:test2 diff --git a/rgmanager/src/daemons/tests/delta-test014-test015.expected b/rgmanager/src/daemons/tests/delta-test014-test015.expected deleted file mode 100644 index 6cf0310..0000000 --- a/rgmanager/src/daemons/tests/delta-test014-test015.expected +++ /dev/null @@ -1,494 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient [NEEDSTOP] -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient [NEEDSTART] -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient [ NEEDSTOP ] { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient [ NEEDSTOP ] { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient [ NEEDSTART ] { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient [ NEEDSTART ] { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== Operations (down-phase) === -Node nfsclient:User group - CONDSTOP -[stop] nfsclient:User group -Node nfsclient:User group - CONDSTOP -[stop] nfsclient:User group -=== Operations (up-phase) === -Node nfsclient:User group - CONDSTART -[start] nfsclient:User group -Node nfsclient:User group - CONDSTART -[start] nfsclient:User group diff --git a/rgmanager/src/daemons/tests/delta-test015-test016.expected b/rgmanager/src/daemons/tests/delta-test015-test016.expected deleted file mode 100644 index 7139041..0000000 --- a/rgmanager/src/daemons/tests/delta-test015-test016.expected +++ /dev/null @@ -1,487 +0,0 @@ -Warning: Max references exceeded for resource address (type ip) -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === diff --git a/rgmanager/src/daemons/tests/delta-test016-test017.expected b/rgmanager/src/daemons/tests/delta-test016-test017.expected deleted file mode 100644 index 0b5723b..0000000 --- a/rgmanager/src/daemons/tests/delta-test016-test017.expected +++ /dev/null @@ -1,535 +0,0 @@ -Warning: Max references exceeded for resource address (type ip) -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script [NEEDSTART] -Agent: script.sh -Attributes: - name = script2 [ primary unique ] - file = /etc/init.d/script2 [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script [NEEDSTART] -Agent: script.sh -Attributes: - name = script3 [ primary unique ] - file = /etc/init.d/script3 [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip [ NEEDSTOP ] { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs [ NEEDSTOP ] { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip [ NEEDSTOP ] { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - ip [ NEEDSTART ] { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - fs [ NEEDSTART ] { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - script [ NEEDSTART ] { - name = "script2"; - file = "/etc/init.d/script2"; - service_name = "test2"; - } - ip [ NEEDSTART ] { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - } - script [ NEEDSTART ] { - name = "script3"; - file = "/etc/init.d/script3"; - service_name = "test2"; - } -} -=== Operations (down-phase) === -Node ip:192.168.1.3 - CONDSTOP -[stop] ip:192.168.1.3 -Node fs:mount2 - CONDSTOP -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -Node ip:192.168.1.4 - CONDSTOP -[stop] ip:192.168.1.4 -=== Operations (up-phase) === -Node ip:192.168.1.3 - CONDSTART -[start] ip:192.168.1.3 -Node fs:mount2 - CONDSTART -[start] fs:mount2 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -Node script:script2 - CONDSTART -[start] script:script2 -Node ip:192.168.1.4 - CONDSTART -[start] ip:192.168.1.4 -Node script:script3 - CONDSTART -[start] script:script3 diff --git a/rgmanager/src/daemons/tests/delta-test017-test018.expected b/rgmanager/src/daemons/tests/delta-test017-test018.expected deleted file mode 100644 index 6670d36..0000000 --- a/rgmanager/src/daemons/tests/delta-test017-test018.expected +++ /dev/null @@ -1,558 +0,0 @@ -=== Old Resource List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script2 [ primary unique ] - file = /etc/init.d/script2 [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script3 [ primary unique ] - file = /etc/init.d/script3 [ unique required ] - service_name [ inherit("service%name") ] - -=== New Resource List === -Resource type: clusterfs [NEEDSTART] -Agent: clusterfs.sh -Attributes: - name = argle [ primary ] - mountpoint = /mnt/cluster3 [ unique required ] - device = /dev/sdb10 [ unique required ] - nfslock [ inherit("service%nfslock") ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script2 [ primary unique ] - file = /etc/init.d/script2 [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script3 [ primary unique ] - file = /etc/init.d/script3 [ unique required ] - service_name [ inherit("service%name") ] - -=== Old Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "script2"; - file = "/etc/init.d/script2"; - service_name = "test2"; - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - } - script { - name = "script3"; - file = "/etc/init.d/script3"; - service_name = "test2"; - } -} -=== New Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - clusterfs [ NEEDSTART ] { - name = "argle"; - mountpoint = "/mnt/cluster3"; - device = "/dev/sdb10"; - nfslock = "0"; - } - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - clusterfs [ NEEDSTART ] { - name = "argle"; - mountpoint = "/mnt/cluster3"; - device = "/dev/sdb10"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "script2"; - file = "/etc/init.d/script2"; - service_name = "test2"; - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - } - script { - name = "script3"; - file = "/etc/init.d/script3"; - service_name = "test2"; - } -} -=== Operations (down-phase) === -=== Operations (up-phase) === -Node clusterfs:argle - CONDSTART -[start] clusterfs:argle -Node clusterfs:argle - CONDSTART -[start] clusterfs:argle diff --git a/rgmanager/src/daemons/tests/gentests.sh b/rgmanager/src/daemons/tests/gentests.sh deleted file mode 100755 index e55bbbc..0000000 --- a/rgmanager/src/daemons/tests/gentests.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh - -LANG=C -LC_ALL=C -LOCALE=C -export LANG LC_ALL LOCALE - -. testlist - -echo "WARNING:" -echo " You will need to MANUALLY verify these test cases after generation!" -echo " Do NOT commit them to CVS without first hand-checking each and" -echo " every one! These are meant to help determine possible regressions" -echo " in the tree handling code and the resource code." -echo "" - -echo -n "Are you sure [y/N] ?" -read foo -if [ "$foo" != "y" ]; then - echo "Ok, aborting..." - exit 0 -fi - -# -# Basic config tests. -# -for t in $TESTS; do - echo -n "Generating $t..." - ../rg_test ../../resources test $t.conf > $t.expected 2> /dev/null - if grep "Error" $t.expected; then - echo "FAILED" - exit 1 - fi - echo OK -done - - -# -# Start/stop tests (noop) -# -for t in $TESTS; do - declare SERVICES=$(echo "xpath /cluster/rm/service" | xmllint $t.conf --shell | grep content | cut -f2 -d'=') - declare phase svc - echo -n "Generating $t exec..." - for phase in start stop; do - echo -n "$phase..." - rm -f $t.$phase.expected - for svc in $SERVICES; do - ../rg_test ../../resources noop $t.conf $phase service $svc >> $t.$phase.expected 2> /dev/null - done - done - echo "OK" -done - - -# -# Delta tests -# -prev= -for t in $TESTS; do - if [ -z "$prev" ]; then - prev=$t - continue - fi - echo -n "Generating delta between $prev and $t..." - ../rg_test ../../resources delta \ - $prev.conf $t.conf > delta-$prev-$t.expected 2> /dev/null - if grep "Error" delta-$prev-$t.expected; then - echo "FAILED" - exit 1 - fi - prev=$t - echo OK -done diff --git a/rgmanager/src/daemons/tests/runtests.sh b/rgmanager/src/daemons/tests/runtests.sh deleted file mode 100755 index 76b548b..0000000 --- a/rgmanager/src/daemons/tests/runtests.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/sh -# -# Super primitive sanity check test program. If the output format of -# any of the trees/lists changes, the tests will need to be regenerated -# and manually checked. -# -# Poor design, but it does effectively detect memory leaks. (when linked -# against the alloc.c in ../../clulib) -# - -LANG=C -LC_ALL=C -LOCALE=C -export LANG LC_ALL LOCALE - -. ./testlist - -echo "Running sanity+memory leak checks on rgmanager tree operations..." - -# -# Basic config tests. -# -for t in $TESTS; do - echo -n " Checking $t.conf..." - ../rg_test ../../resources test $t.conf > $t.out 2> $t.out.stderr - diff -uw $t.expected $t.out - if [ $? -ne 0 ]; then - echo "FAILED" - echo "*** Basic Test $t failed" - exit 1 - fi - if grep -q "allocation trace" $t.out.stderr; then - echo "FAILED - memory leak" - echo "*** Memory Test $t failed" - echo - echo Output: - echo - cat $t.out.stderr - exit 1 - fi - rm -f $t.out $t.out.stderr - echo OK -done - - -# -# Start/stop tests (noop) -# -for t in $TESTS; do - declare SERVICES=$(echo "xpath /cluster/rm/service" | xmllint $t.conf --shell | grep content | cut -f2 -d'=') - declare phase svc - echo -n " Checking $t.conf..." - for phase in start stop; do - echo -n "$phase..." - rm -f $t.$phase.out - for svc in $SERVICES; do - ../rg_test ../../resources noop $t.conf $phase service $svc >> $t.$phase.out 2> $t.$phase.out.stderr - done - diff -uw $t.$phase.expected $t.$phase.out - if [ $? -ne 0 ]; then - echo "FAILED" - echo "*** Start Test $t failed" - exit 1 - fi - if grep -q "allocation trace" $t.$phase.out.stderr; then - echo "FAILED - memory leak" - echo "*** Memory Test $t failed" - echo - echo Output: - echo - cat $t.$phase.out.stderr - exit 1 - fi - rm -f $t.$phase.out $t.$phase.out.stderr - done - echo "OK" -done - - -# -# Delta tests -# -prev= -for t in $TESTS; do - if [ -z "$prev" ]; then - prev=$t - continue - fi - echo -n " Checking delta between $prev and $t..." - ../rg_test ../../resources delta \ - $prev.conf $t.conf > delta-$prev-$t.out 2> delta-$prev-$t.out.stderr - diff -uw delta-$prev-$t.expected delta-$prev-$t.out - if [ $? -ne 0 ]; then - echo "FAILED" - echo "*** Differential test between $prev and $t failed" - exit 1 - fi - if grep -q "allocation trace" delta-$prev-$t.out.stderr; then - echo "FAILED - memory leak" - echo "*** Memory Test $t failed" - echo - echo Output: - echo - cat delta-$prev-$t.out.stderr - exit 1 - fi - rm -f delta-$prev-$t.out delta-$prev-$t.out.stderr - prev=$t - echo OK -done diff --git a/rgmanager/src/daemons/tests/test001.conf b/rgmanager/src/daemons/tests/test001.conf deleted file mode 100644 index b95ba86..0000000 --- a/rgmanager/src/daemons/tests/test001.conf +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0"?> -<!-- inline resource group --> -<cluster> -<rm> - <service name="test1"/> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test001.expected b/rgmanager/src/daemons/tests/test001.expected deleted file mode 100644 index 43d90e8..0000000 --- a/rgmanager/src/daemons/tests/test001.expected +++ /dev/null @@ -1,32 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] [INLINE] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test001.start.expected b/rgmanager/src/daemons/tests/test001.start.expected deleted file mode 100644 index 9b991d7..0000000 --- a/rgmanager/src/daemons/tests/test001.start.expected +++ /dev/null @@ -1,3 +0,0 @@ -Starting test1... -[start] service:test1 -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test001.stop.expected b/rgmanager/src/daemons/tests/test001.stop.expected deleted file mode 100644 index 993cf06..0000000 --- a/rgmanager/src/daemons/tests/test001.stop.expected +++ /dev/null @@ -1,3 +0,0 @@ -Stopping test1... -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test002.conf b/rgmanager/src/daemons/tests/test002.conf deleted file mode 100644 index 2782312..0000000 --- a/rgmanager/src/daemons/tests/test002.conf +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0"?> -<!-- normal resource group --> -<!-- If compared with the inline resource group in test1, - this should not make this resource group restart since no - attributes have changed. --> -<cluster> -<rm> - <resources> - <service name="test1"/> - </resources> - <service ref="test1"/> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test002.expected b/rgmanager/src/daemons/tests/test002.expected deleted file mode 100644 index 09b160f..0000000 --- a/rgmanager/src/daemons/tests/test002.expected +++ /dev/null @@ -1,32 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test002.start.expected b/rgmanager/src/daemons/tests/test002.start.expected deleted file mode 100644 index 9b991d7..0000000 --- a/rgmanager/src/daemons/tests/test002.start.expected +++ /dev/null @@ -1,3 +0,0 @@ -Starting test1... -[start] service:test1 -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test002.stop.expected b/rgmanager/src/daemons/tests/test002.stop.expected deleted file mode 100644 index 993cf06..0000000 --- a/rgmanager/src/daemons/tests/test002.stop.expected +++ /dev/null @@ -1,3 +0,0 @@ -Stopping test1... -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test003.conf b/rgmanager/src/daemons/tests/test003.conf deleted file mode 100644 index 9514516..0000000 --- a/rgmanager/src/daemons/tests/test003.conf +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0"?> -<!-- Add an initscript to our regular resource group. - The initscript should get a 'NEEDSTART' flag. --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/httpd"/> - </resources> - <service ref="test1"> - <script ref="initscript"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test003.expected b/rgmanager/src/daemons/tests/test003.expected deleted file mode 100644 index b39a24e..0000000 --- a/rgmanager/src/daemons/tests/test003.expected +++ /dev/null @@ -1,44 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/httpd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/httpd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test003.start.expected b/rgmanager/src/daemons/tests/test003.start.expected deleted file mode 100644 index fd37d3a..0000000 --- a/rgmanager/src/daemons/tests/test003.start.expected +++ /dev/null @@ -1,4 +0,0 @@ -Starting test1... -[start] service:test1 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test003.stop.expected b/rgmanager/src/daemons/tests/test003.stop.expected deleted file mode 100644 index bdbee27..0000000 --- a/rgmanager/src/daemons/tests/test003.stop.expected +++ /dev/null @@ -1,4 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test004.conf b/rgmanager/src/daemons/tests/test004.conf deleted file mode 100644 index c71fe0b..0000000 --- a/rgmanager/src/daemons/tests/test004.conf +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!-- Change the script, keeping the reference the same. - the test3 (old) tree should note NEEDSTOP while the new - tree should note NEEDSTART for the script resource --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - </resources> - <service ref="test1"> - <script ref="initscript"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test004.expected b/rgmanager/src/daemons/tests/test004.expected deleted file mode 100644 index bc2a264..0000000 --- a/rgmanager/src/daemons/tests/test004.expected +++ /dev/null @@ -1,44 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test004.start.expected b/rgmanager/src/daemons/tests/test004.start.expected deleted file mode 100644 index fd37d3a..0000000 --- a/rgmanager/src/daemons/tests/test004.start.expected +++ /dev/null @@ -1,4 +0,0 @@ -Starting test1... -[start] service:test1 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test004.stop.expected b/rgmanager/src/daemons/tests/test004.stop.expected deleted file mode 100644 index bdbee27..0000000 --- a/rgmanager/src/daemons/tests/test004.stop.expected +++ /dev/null @@ -1,4 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test005.conf b/rgmanager/src/daemons/tests/test005.conf deleted file mode 100644 index bce3070..0000000 --- a/rgmanager/src/daemons/tests/test005.conf +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<!-- Add an IP address. The new tree should note NEEDSTART for this - new IP address, but nothing else. --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.2"/> - </resources> - <service ref="test1"> - <ip ref="192.168.1.2"/> - <script ref="initscript"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test005.expected b/rgmanager/src/daemons/tests/test005.expected deleted file mode 100644 index b05749a..0000000 --- a/rgmanager/src/daemons/tests/test005.expected +++ /dev/null @@ -1,57 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.2 [ primary unique ] - monitor_link = 1 - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.2"; - monitor_link = "1"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test005.start.expected b/rgmanager/src/daemons/tests/test005.start.expected deleted file mode 100644 index 8d18f77..0000000 --- a/rgmanager/src/daemons/tests/test005.start.expected +++ /dev/null @@ -1,5 +0,0 @@ -Starting test1... -[start] service:test1 -[start] ip:192.168.1.2 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test005.stop.expected b/rgmanager/src/daemons/tests/test005.stop.expected deleted file mode 100644 index 7f6cabc..0000000 --- a/rgmanager/src/daemons/tests/test005.stop.expected +++ /dev/null @@ -1,5 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.2 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test006.conf b/rgmanager/src/daemons/tests/test006.conf deleted file mode 100644 index 1383a9a..0000000 --- a/rgmanager/src/daemons/tests/test006.conf +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<!-- The IP address should have a NEEDSTOP in the old tree and NEEDSTART - in the new tree, --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.2" monitor_link="yes"/> - </resources> - <service ref="test1"> - <ip ref="192.168.1.2"/> - <script ref="initscript"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test006.expected b/rgmanager/src/daemons/tests/test006.expected deleted file mode 100644 index 2b77f91..0000000 --- a/rgmanager/src/daemons/tests/test006.expected +++ /dev/null @@ -1,57 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.2 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.2"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test006.start.expected b/rgmanager/src/daemons/tests/test006.start.expected deleted file mode 100644 index 8d18f77..0000000 --- a/rgmanager/src/daemons/tests/test006.start.expected +++ /dev/null @@ -1,5 +0,0 @@ -Starting test1... -[start] service:test1 -[start] ip:192.168.1.2 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test006.stop.expected b/rgmanager/src/daemons/tests/test006.stop.expected deleted file mode 100644 index 7f6cabc..0000000 --- a/rgmanager/src/daemons/tests/test006.stop.expected +++ /dev/null @@ -1,5 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.2 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test007.conf b/rgmanager/src/daemons/tests/test007.conf deleted file mode 100644 index 6122c2f..0000000 --- a/rgmanager/src/daemons/tests/test007.conf +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0"?> -<!-- When comapred with test6, the old IP address (192.168.1.2) should - have a NEEDSTOP while the new IP address should have a NEEDSTART - flag --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test007.expected b/rgmanager/src/daemons/tests/test007.expected deleted file mode 100644 index ea4bcf1..0000000 --- a/rgmanager/src/daemons/tests/test007.expected +++ /dev/null @@ -1,57 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test007.start.expected b/rgmanager/src/daemons/tests/test007.start.expected deleted file mode 100644 index c30c7c2..0000000 --- a/rgmanager/src/daemons/tests/test007.start.expected +++ /dev/null @@ -1,5 +0,0 @@ -Starting test1... -[start] service:test1 -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test007.stop.expected b/rgmanager/src/daemons/tests/test007.stop.expected deleted file mode 100644 index 238fab5..0000000 --- a/rgmanager/src/daemons/tests/test007.stop.expected +++ /dev/null @@ -1,5 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test008.conf b/rgmanager/src/daemons/tests/test008.conf deleted file mode 100644 index ebedd3e..0000000 --- a/rgmanager/src/daemons/tests/test008.conf +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0"?> -<!-- When comapred with test7, - there should be no NEEDSTART flags in any of the output trees, because - although we have now defined "mount1", we have not assigned it - to any resource groups. There SHOULD be a NEEDSTART in the resource - list, just not any of the trees. --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test008.expected b/rgmanager/src/daemons/tests/test008.expected deleted file mode 100644 index 82877fe..0000000 --- a/rgmanager/src/daemons/tests/test008.expected +++ /dev/null @@ -1,67 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: fs -Instances: 0/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test008.start.expected b/rgmanager/src/daemons/tests/test008.start.expected deleted file mode 100644 index c30c7c2..0000000 --- a/rgmanager/src/daemons/tests/test008.start.expected +++ /dev/null @@ -1,5 +0,0 @@ -Starting test1... -[start] service:test1 -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test008.stop.expected b/rgmanager/src/daemons/tests/test008.stop.expected deleted file mode 100644 index 238fab5..0000000 --- a/rgmanager/src/daemons/tests/test008.stop.expected +++ /dev/null @@ -1,5 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test009.conf b/rgmanager/src/daemons/tests/test009.conf deleted file mode 100644 index 00fbacd..0000000 --- a/rgmanager/src/daemons/tests/test009.conf +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- When comapred with test8, - We've now bound the fs "mount1" to "test1". There should be a - NEEDSTART flag in the output of the "new" tree. --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test009.expected b/rgmanager/src/daemons/tests/test009.expected deleted file mode 100644 index 0c4c274..0000000 --- a/rgmanager/src/daemons/tests/test009.expected +++ /dev/null @@ -1,74 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test009.start.expected b/rgmanager/src/daemons/tests/test009.start.expected deleted file mode 100644 index 93d3e1a..0000000 --- a/rgmanager/src/daemons/tests/test009.start.expected +++ /dev/null @@ -1,6 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test009.stop.expected b/rgmanager/src/daemons/tests/test009.stop.expected deleted file mode 100644 index b30788f..0000000 --- a/rgmanager/src/daemons/tests/test009.stop.expected +++ /dev/null @@ -1,6 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test010.conf b/rgmanager/src/daemons/tests/test010.conf deleted file mode 100644 index c375bb4..0000000 --- a/rgmanager/src/daemons/tests/test010.conf +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- Add NFS export to the mix. Should have no NEEDSTOPS/NEEDSTARTS - in the resource tree outputs. --> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <nfsexport name="Dummy Export"/> - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test010.expected b/rgmanager/src/daemons/tests/test010.expected deleted file mode 100644 index bd89cb3..0000000 --- a/rgmanager/src/daemons/tests/test010.expected +++ /dev/null @@ -1,83 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test010.start.expected b/rgmanager/src/daemons/tests/test010.start.expected deleted file mode 100644 index 93d3e1a..0000000 --- a/rgmanager/src/daemons/tests/test010.start.expected +++ /dev/null @@ -1,6 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test010.stop.expected b/rgmanager/src/daemons/tests/test010.stop.expected deleted file mode 100644 index b30788f..0000000 --- a/rgmanager/src/daemons/tests/test010.stop.expected +++ /dev/null @@ -1,6 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test011.conf b/rgmanager/src/daemons/tests/test011.conf deleted file mode 100644 index ac158ca..0000000 --- a/rgmanager/src/daemons/tests/test011.conf +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0"?> -<!-- Add NFS clients to the mix. - Between test 10 and this one, there should be NEEDSTARTS in the - new resource tree for Dummy Export. - - Because everything below an element is started if there's a NEEDSTART - flag (and everything below an element is stopped if there's a - NEEDSTOP, too), Admin group and User group will not need NEEDSTART - flags in the resource trees, but their output in the resource list - should show that they do have NEEDSTART flags. ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="ro"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw,no_root_squash"/> - - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - </nfsexport> - </fs> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test011.expected b/rgmanager/src/daemons/tests/test011.expected deleted file mode 100644 index 6ce15c4..0000000 --- a/rgmanager/src/daemons/tests/test011.expected +++ /dev/null @@ -1,153 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test011.start.expected b/rgmanager/src/daemons/tests/test011.start.expected deleted file mode 100644 index c75b535..0000000 --- a/rgmanager/src/daemons/tests/test011.start.expected +++ /dev/null @@ -1,9 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test011.stop.expected b/rgmanager/src/daemons/tests/test011.stop.expected deleted file mode 100644 index 2962100..0000000 --- a/rgmanager/src/daemons/tests/test011.stop.expected +++ /dev/null @@ -1,9 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test012.conf b/rgmanager/src/daemons/tests/test012.conf deleted file mode 100644 index 939b455..0000000 --- a/rgmanager/src/daemons/tests/test012.conf +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> -<!-- - NEEDSTOP in the resource list for client "red". NEEDSTART in the - new resource TREE for client "red" ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="ro"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="ro"/> - - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test012.expected b/rgmanager/src/daemons/tests/test012.expected deleted file mode 100644 index 97b07cc..0000000 --- a/rgmanager/src/daemons/tests/test012.expected +++ /dev/null @@ -1,160 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test012.start.expected b/rgmanager/src/daemons/tests/test012.start.expected deleted file mode 100644 index e7fd06f..0000000 --- a/rgmanager/src/daemons/tests/test012.start.expected +++ /dev/null @@ -1,10 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test012.stop.expected b/rgmanager/src/daemons/tests/test012.stop.expected deleted file mode 100644 index 5218b3a..0000000 --- a/rgmanager/src/daemons/tests/test012.stop.expected +++ /dev/null @@ -1,10 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test013.conf b/rgmanager/src/daemons/tests/test013.conf deleted file mode 100644 index fd62271..0000000 --- a/rgmanager/src/daemons/tests/test013.conf +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0"?> -<!-- - NEEDSTOP in the old resource _tree_ for client red. - NEEDSTART in the new resource _tree_ for client red. We have - changed the options to "rw". ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="ro"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw"/> - - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test013.expected b/rgmanager/src/daemons/tests/test013.expected deleted file mode 100644 index 07564ff..0000000 --- a/rgmanager/src/daemons/tests/test013.expected +++ /dev/null @@ -1,160 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test013.start.expected b/rgmanager/src/daemons/tests/test013.start.expected deleted file mode 100644 index e7fd06f..0000000 --- a/rgmanager/src/daemons/tests/test013.start.expected +++ /dev/null @@ -1,10 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete diff --git a/rgmanager/src/daemons/tests/test013.stop.expected b/rgmanager/src/daemons/tests/test013.stop.expected deleted file mode 100644 index 5218b3a..0000000 --- a/rgmanager/src/daemons/tests/test013.stop.expected +++ /dev/null @@ -1,10 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete diff --git a/rgmanager/src/daemons/tests/test014.conf b/rgmanager/src/daemons/tests/test014.conf deleted file mode 100644 index ced4848..0000000 --- a/rgmanager/src/daemons/tests/test014.conf +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0"?> -<!-- - NEEDSTART for resource group "test2". ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <service name="test2"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <ip address="192.168.1.4" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="ro"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw"/> - - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> - <service ref="test2"> - <ip ref="192.168.1.4"/> - <script ref="initscript"/> - <fs ref="mount2"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test014.expected b/rgmanager/src/daemons/tests/test014.expected deleted file mode 100644 index c7db038..0000000 --- a/rgmanager/src/daemons/tests/test014.expected +++ /dev/null @@ -1,247 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = ro - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "ro"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test014.start.expected b/rgmanager/src/daemons/tests/test014.start.expected deleted file mode 100644 index 562e1a5..0000000 --- a/rgmanager/src/daemons/tests/test014.start.expected +++ /dev/null @@ -1,20 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete -Starting test2... -[start] service:test2 -[start] fs:mount2 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.4 -[start] script:initscript -Start of test2 complete diff --git a/rgmanager/src/daemons/tests/test014.stop.expected b/rgmanager/src/daemons/tests/test014.stop.expected deleted file mode 100644 index c3eb880..0000000 --- a/rgmanager/src/daemons/tests/test014.stop.expected +++ /dev/null @@ -1,20 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete -Stopping test2... -[stop] script:initscript -[stop] ip:192.168.1.4 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -[stop] service:test2 -Stop of test2 complete diff --git a/rgmanager/src/daemons/tests/test015.conf b/rgmanager/src/daemons/tests/test015.conf deleted file mode 100644 index e1f76bf..0000000 --- a/rgmanager/src/daemons/tests/test015.conf +++ /dev/null @@ -1,51 +0,0 @@ -<?xml version="1.0"?> -<!-- - NEEDSTOP in old tree for "User group" - NEEDSTART in new tree for "User group". - - We have changed the options again. Please make sure that BOTH - tree nodes (the one in "test1" AND in "Test2") have NEEDSTOP/NEEDSTART - flags! ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <service name="test2"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <ip address="192.168.1.4" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="rw,sync"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw"/> - - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> - <service ref="test2"> - <ip ref="192.168.1.4"/> - <script ref="initscript"/> - <fs ref="mount2"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test015.expected b/rgmanager/src/daemons/tests/test015.expected deleted file mode 100644 index 6ac189b..0000000 --- a/rgmanager/src/daemons/tests/test015.expected +++ /dev/null @@ -1,247 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test015.start.expected b/rgmanager/src/daemons/tests/test015.start.expected deleted file mode 100644 index 562e1a5..0000000 --- a/rgmanager/src/daemons/tests/test015.start.expected +++ /dev/null @@ -1,20 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete -Starting test2... -[start] service:test2 -[start] fs:mount2 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.4 -[start] script:initscript -Start of test2 complete diff --git a/rgmanager/src/daemons/tests/test015.stop.expected b/rgmanager/src/daemons/tests/test015.stop.expected deleted file mode 100644 index c3eb880..0000000 --- a/rgmanager/src/daemons/tests/test015.stop.expected +++ /dev/null @@ -1,20 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete -Stopping test2... -[stop] script:initscript -[stop] ip:192.168.1.4 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -[stop] service:test2 -Stop of test2 complete diff --git a/rgmanager/src/daemons/tests/test016.conf b/rgmanager/src/daemons/tests/test016.conf deleted file mode 100644 index ed3501f..0000000 --- a/rgmanager/src/daemons/tests/test016.conf +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0"?> -<!-- - Negative test: Attempting to assign an IP address to multiple resource - groups. Only ONE copy of "192.168.1.3" should appear in the tree. - - There should be _no_ NEEDSTOPs/NEEDSTARTs anywhere. ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <service name="test2"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <ip address="192.168.1.4" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="rw,sync"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw"/> - - </resources> - <service ref="test1"> - <ip ref="192.168.1.3"/> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> - <service ref="test2"> - <ip ref="192.168.1.3"/> - <ip ref="192.168.1.4"/> - <script ref="initscript"/> - <fs ref="mount2"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test016.expected b/rgmanager/src/daemons/tests/test016.expected deleted file mode 100644 index 1ce2579..0000000 --- a/rgmanager/src/daemons/tests/test016.expected +++ /dev/null @@ -1,248 +0,0 @@ -Warning: Max references exceeded for resource address (type ip) -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test016.start.expected b/rgmanager/src/daemons/tests/test016.start.expected deleted file mode 100644 index 3f49953..0000000 --- a/rgmanager/src/daemons/tests/test016.start.expected +++ /dev/null @@ -1,22 +0,0 @@ -Warning: Max references exceeded for resource address (type ip) -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.3 -[start] script:initscript -Start of test1 complete -Warning: Max references exceeded for resource address (type ip) -Starting test2... -[start] service:test2 -[start] fs:mount2 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] ip:192.168.1.4 -[start] script:initscript -Start of test2 complete diff --git a/rgmanager/src/daemons/tests/test016.stop.expected b/rgmanager/src/daemons/tests/test016.stop.expected deleted file mode 100644 index dfc1cc1..0000000 --- a/rgmanager/src/daemons/tests/test016.stop.expected +++ /dev/null @@ -1,22 +0,0 @@ -Warning: Max references exceeded for resource address (type ip) -Stopping test1... -[stop] script:initscript -[stop] ip:192.168.1.3 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete -Warning: Max references exceeded for resource address (type ip) -Stopping test2... -[stop] script:initscript -[stop] ip:192.168.1.4 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -[stop] service:test2 -Stop of test2 complete diff --git a/rgmanager/src/daemons/tests/test017.conf b/rgmanager/src/daemons/tests/test017.conf deleted file mode 100644 index c300e47..0000000 --- a/rgmanager/src/daemons/tests/test017.conf +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0"?> -<!-- - Lots of needstarts/needstops; this one is meant to test the ordering - of untyped resources. In the test 2 service, the start/stop ordering - should be: - - start test2 - start initscript - start ip .1.3 - start mount2 - start dummy export - start admin group - start user group - start red - start script2 - start .1.4 - start script3 - - - ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <service name="test2"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <script name="script2" file="/etc/init.d/script2"/> - <script name="script3" file="/etc/init.d/script3"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <ip address="192.168.1.4" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="rw,sync"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw"/> - - </resources> - <service ref="test1"> - <script ref="initscript"/> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> - <service ref="test2"> - <script ref="initscript"> - <ip ref="192.168.1.3"/> - <fs ref="mount2"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - <script ref="script2"/> - <ip ref="192.168.1.4"/> - </script> - <script ref="script3"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test017.expected b/rgmanager/src/daemons/tests/test017.expected deleted file mode 100644 index 4727803..0000000 --- a/rgmanager/src/daemons/tests/test017.expected +++ /dev/null @@ -1,271 +0,0 @@ -=== Resources List === -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script2 [ primary unique ] - file = /etc/init.d/script2 [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script3 [ primary unique ] - file = /etc/init.d/script3 [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "script2"; - file = "/etc/init.d/script2"; - service_name = "test2"; - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - } - script { - name = "script3"; - file = "/etc/init.d/script3"; - service_name = "test2"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test017.start.expected b/rgmanager/src/daemons/tests/test017.start.expected deleted file mode 100644 index 054809f..0000000 --- a/rgmanager/src/daemons/tests/test017.start.expected +++ /dev/null @@ -1,22 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] script:initscript -Start of test1 complete -Starting test2... -[start] service:test2 -[start] script:initscript -[start] ip:192.168.1.3 -[start] fs:mount2 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] script:script2 -[start] ip:192.168.1.4 -[start] script:script3 -Start of test2 complete diff --git a/rgmanager/src/daemons/tests/test017.stop.expected b/rgmanager/src/daemons/tests/test017.stop.expected deleted file mode 100644 index ccc056c..0000000 --- a/rgmanager/src/daemons/tests/test017.stop.expected +++ /dev/null @@ -1,22 +0,0 @@ -Stopping test1... -[stop] script:initscript -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete -Stopping test2... -[stop] script:script3 -[stop] ip:192.168.1.4 -[stop] script:script2 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -[stop] ip:192.168.1.3 -[stop] script:initscript -[stop] service:test2 -Stop of test2 complete diff --git a/rgmanager/src/daemons/tests/test018.conf b/rgmanager/src/daemons/tests/test018.conf deleted file mode 100644 index da7ed6e..0000000 --- a/rgmanager/src/daemons/tests/test018.conf +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0"?> -<!-- - while testing for #212121, I found that if you had multiple - instances of untyped children where the untyped children were - multi-instance resources, you could end up with resource duplication - the second time around. - - For example: - - start test2 - start initscript - start clusterfs - this should not happen twice - start clusterfs - start ip .1.3 - start mount2 - start dummy export - start admin group - start user group - start red - start script2 - start .1.4 - start script3 - - ... would occur without the change to restree.c which removes - the addition of newchild to the known-children. - ---> -<cluster> -<rm> - <resources> - <service name="test1"/> - <service name="test2"/> - <script name="initscript" file="/etc/init.d/sshd"/> - <script name="script2" file="/etc/init.d/script2"/> - <script name="script3" file="/etc/init.d/script3"/> - <ip address="192.168.1.3" monitor_link="yes"/> - <ip address="192.168.1.4" monitor_link="yes"/> - <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/> - <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/> - <nfsexport name="Dummy Export"/> - <nfsclient name="User group" target="@users" options="rw,sync"/> - <nfsclient name="Admin group" target="@admin" options="rw"/> - <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/> - <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/> - <nfsclient name="red" target="red" options="rw"/> - <clusterfs name="argle" mountpoint="/mnt/cluster3" device="/dev/sdb10"/> - - </resources> - <service ref="test1"> - <script ref="initscript"> - <clusterfs ref="argle"/> - </script> - <fs ref="mount1"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - </service> - <service ref="test2"> - <script ref="initscript"> - <clusterfs ref="argle"/> - <ip ref="192.168.1.3"/> - <fs ref="mount2"> - <nfsexport ref="Dummy Export"> - <nfsclient ref="Admin group"/> - <nfsclient ref="User group"/> - <nfsclient ref="red"/> - </nfsexport> - </fs> - <script ref="script2"/> - <ip ref="192.168.1.4"/> - </script> - <script ref="script3"/> - </service> -</rm> -</cluster> diff --git a/rgmanager/src/daemons/tests/test018.expected b/rgmanager/src/daemons/tests/test018.expected deleted file mode 100644 index 225b150..0000000 --- a/rgmanager/src/daemons/tests/test018.expected +++ /dev/null @@ -1,291 +0,0 @@ -=== Resources List === -Resource type: clusterfs -Agent: clusterfs.sh -Attributes: - name = argle [ primary ] - mountpoint = /mnt/cluster3 [ unique required ] - device = /dev/sdb10 [ unique required ] - nfslock [ inherit("service%nfslock") ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test1 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: service [ROOT] -Instances: 1/1 -Agent: service.sh -Attributes: - name = test2 [ primary unique required ] - autostart = 1 [ reconfig ] - hardrecovery = 0 [ reconfig ] - exclusive = 0 [ reconfig ] - nfslock = 0 - recovery = restart [ reconfig ] - depend_mode = hard - max_restarts = 0 [ reconfig ] - restart_expire_time = 0 [ reconfig ] - -Resource type: nfsexport -Agent: nfsexport.sh -Attributes: - name = Dummy Export [ primary ] - device [ inherit("device") ] - path [ inherit("mountpoint") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = User group [ primary unique ] - target = @users [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,sync - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = Admin group [ primary unique ] - target = @admin [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = yellow [ primary unique ] - target = yellow [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = magenta [ primary unique ] - target = magenta [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw,no_root_squash - -Resource type: nfsclient -Agent: nfsclient.sh -Attributes: - name = red [ primary unique ] - target = red [ required ] - path [ inherit("path") ] - fsid [ inherit("fsid") ] - nfslock [ inherit("service%nfslock") ] - options = rw - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount1 [ primary ] - mountpoint = /mnt/cluster [ unique required ] - device = /dev/sdb8 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: fs -Instances: 1/1 -Agent: fs.sh -Attributes: - name = mount2 [ primary ] - mountpoint = /mnt/cluster2 [ unique required ] - device = /dev/sdb9 [ unique required ] - fstype = ext3 - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.3 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: ip -Instances: 1/1 -Agent: ip.sh -Attributes: - address = 192.168.1.4 [ primary unique ] - monitor_link = yes - nfslock [ inherit("service%nfslock") ] - -Resource type: script -Agent: script.sh -Attributes: - name = initscript [ primary unique ] - file = /etc/init.d/sshd [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script2 [ primary unique ] - file = /etc/init.d/script2 [ unique required ] - service_name [ inherit("service%name") ] - -Resource type: script -Agent: script.sh -Attributes: - name = script3 [ primary unique ] - file = /etc/init.d/script3 [ unique required ] - service_name [ inherit("service%name") ] - -=== Resource Tree === -service { - name = "test1"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - fs { - name = "mount1"; - mountpoint = "/mnt/cluster"; - device = "/dev/sdb8"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb8"; - path = "/mnt/cluster"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test1"; - clusterfs { - name = "argle"; - mountpoint = "/mnt/cluster3"; - device = "/dev/sdb10"; - nfslock = "0"; - } - } -} -service { - name = "test2"; - autostart = "1"; - hardrecovery = "0"; - exclusive = "0"; - nfslock = "0"; - recovery = "restart"; - depend_mode = "hard"; - max_restarts = "0"; - restart_expire_time = "0"; - script { - name = "initscript"; - file = "/etc/init.d/sshd"; - service_name = "test2"; - clusterfs { - name = "argle"; - mountpoint = "/mnt/cluster3"; - device = "/dev/sdb10"; - nfslock = "0"; - } - ip { - address = "192.168.1.3"; - monitor_link = "yes"; - nfslock = "0"; - } - fs { - name = "mount2"; - mountpoint = "/mnt/cluster2"; - device = "/dev/sdb9"; - fstype = "ext3"; - nfslock = "0"; - nfsexport { - name = "Dummy Export"; - device = "/dev/sdb9"; - path = "/mnt/cluster2"; - nfslock = "0"; - nfsclient { - name = "Admin group"; - target = "@admin"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - nfsclient { - name = "User group"; - target = "@users"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw,sync"; - } - nfsclient { - name = "red"; - target = "red"; - path = "/mnt/cluster2"; - nfslock = "0"; - options = "rw"; - } - } - } - script { - name = "script2"; - file = "/etc/init.d/script2"; - service_name = "test2"; - } - ip { - address = "192.168.1.4"; - monitor_link = "yes"; - nfslock = "0"; - } - } - script { - name = "script3"; - file = "/etc/init.d/script3"; - service_name = "test2"; - } -} -=== Event Triggers === -Event Priority Level 100: - Name: Default - (Any event) - File: /usr/share/cluster/default_event_script.sl diff --git a/rgmanager/src/daemons/tests/test018.start.expected b/rgmanager/src/daemons/tests/test018.start.expected deleted file mode 100644 index b633297..0000000 --- a/rgmanager/src/daemons/tests/test018.start.expected +++ /dev/null @@ -1,24 +0,0 @@ -Starting test1... -[start] service:test1 -[start] fs:mount1 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] script:initscript -[start] clusterfs:argle -Start of test1 complete -Starting test2... -[start] service:test2 -[start] script:initscript -[start] clusterfs:argle -[start] ip:192.168.1.3 -[start] fs:mount2 -[start] nfsexport:Dummy Export -[start] nfsclient:Admin group -[start] nfsclient:User group -[start] nfsclient:red -[start] script:script2 -[start] ip:192.168.1.4 -[start] script:script3 -Start of test2 complete diff --git a/rgmanager/src/daemons/tests/test018.stop.expected b/rgmanager/src/daemons/tests/test018.stop.expected deleted file mode 100644 index 5df827b..0000000 --- a/rgmanager/src/daemons/tests/test018.stop.expected +++ /dev/null @@ -1,24 +0,0 @@ -Stopping test1... -[stop] clusterfs:argle -[stop] script:initscript -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount1 -[stop] service:test1 -Stop of test1 complete -Stopping test2... -[stop] script:script3 -[stop] ip:192.168.1.4 -[stop] script:script2 -[stop] nfsclient:red -[stop] nfsclient:User group -[stop] nfsclient:Admin group -[stop] nfsexport:Dummy Export -[stop] fs:mount2 -[stop] ip:192.168.1.3 -[stop] clusterfs:argle -[stop] script:initscript -[stop] service:test2 -Stop of test2 complete diff --git a/rgmanager/src/daemons/tests/testlist b/rgmanager/src/daemons/tests/testlist deleted file mode 100755 index 045a3e1..0000000 --- a/rgmanager/src/daemons/tests/testlist +++ /dev/null @@ -1,4 +0,0 @@ -# -# Tests to run. -# -TESTS=$(/bin/ls -1 test*.conf | cut -f1 -d.) diff --git a/rgmanager/src/daemons/watchdog.c b/rgmanager/src/daemons/watchdog.c deleted file mode 100644 index c748382..0000000 --- a/rgmanager/src/daemons/watchdog.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright Red Hat, Inc. 2005-2006 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/reboot.h> -#include <stdlib.h> - -#include <signals.h> -#include <clulog.h> - -static pid_t child = 0; - -static void -signal_handler(int signum) -{ - kill(child, signum); -} -static void -redirect_signals(void) -{ - int i; - for (i = 0; i < _NSIG; i++) { - switch (i) { - case SIGCHLD: - case SIGILL: - case SIGFPE: - case SIGSEGV: - case SIGBUS: - setup_signal(i, SIG_DFL); - break; - default: - setup_signal(i, signal_handler); - } - } -} - -/** - return watchdog's pid, or 0 on failure -*/ -int -watchdog_init(void) -{ - int status; - pid_t parent; - - parent = getpid(); - child = fork(); - if (child < 0) - return 0; - else if (!child) - return parent; - - redirect_signals(); - - while (1) { - if (waitpid(child, &status, 0) <= 0) - continue; - - if (WIFEXITED(status)) - exit(WEXITSTATUS(status)); - - if (WIFSIGNALED(status)) { - if (WTERMSIG(status) == SIGKILL) { - clulog(LOG_CRIT, "Watchdog: Daemon killed, exiting\n"); - raise(SIGKILL); - while(1) ; - } - else { -#ifdef DEBUG - clulog(LOG_CRIT, "Watchdog: Daemon died, but not rebooting because DEBUG is set\n"); -#else - clulog(LOG_CRIT, "Watchdog: Daemon died, rebooting...\n"); - sync(); - reboot(RB_AUTOBOOT); -#endif - exit(255); - } - } - } -} diff --git a/rgmanager/src/resources/Makefile b/rgmanager/src/resources/Makefile deleted file mode 100644 index c1f4a71..0000000 --- a/rgmanager/src/resources/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. - -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk -INCLUDE += -I $(top_srcdir)/include - -RESOURCES=fs.sh service.sh ip.sh nfsclient.sh nfsexport.sh \ - script.sh netfs.sh clusterfs.sh smb.sh \ - apache.sh openldap.sh samba.sh mysql.sh \ - postgres-8.sh tomcat-5.sh lvm.sh lvm_by_lv.sh lvm_by_vg.sh \ - SAPInstance SAPDatabase named.sh \ - oracledb.sh - -METADATA=apache.metadata openldap.metadata samba.metadata \ - mysql.metadata postgres-8.metadata tomcat-5.metadata \ - named.metadata lvm.metadata - -TARGETS=${RESOURCES} ocf-shellfuncs svclib_nfslock - -UTIL_TARGETS= \ - utils/config-utils.sh utils/ra-skelet.sh utils/messages.sh \ - utils/httpd-parse-config.pl utils/tomcat-parse-config.pl \ - utils/member_util.sh - -EVENT_TARGETS= \ - default_event_script.sl - -all: - -install: all - echo ${sharedir} - echo ${sbindir} - install -d ${sharedir} - install -d ${sharedir}/utils - install $(TARGETS) ${sharedir} - install $(UTIL_TARGETS) ${sharedir}/utils - install -m 644 $(METADATA) ${sharedir} - install -m 644 $(EVENT_TARGETS) ${sharedir} - -uninstall: - ${UNINSTALL} ${UTIL_TARGETS} ${sharedir}/utils - ${UNINSTALL} ${TARGETS} ${sharedir} - -clean: - -check: $(RESOURCES) ra-api-1-modified.dtd - @echo Validating resource agent meta-data - @for f in $(RESOURCES); do \ - echo " ./$$f "; \ - ./$$f meta-data | xmllint --dtdvalid \ - ./ra-api-1-modified.dtd --noout -; \ - if [ $$? -ne 0 ]; then exit 1; fi \ - done diff --git a/rgmanager/src/resources/SAPDatabase b/rgmanager/src/resources/SAPDatabase deleted file mode 100755 index c06f227..0000000 --- a/rgmanager/src/resources/SAPDatabase +++ /dev/null @@ -1,698 +0,0 @@ -#!/bin/sh -# -# SAPDatabase -# -# Description: Manages any type of SAP supported database instance -# as a High-Availability OCF compliant resource. -# -# Author: Alexander Krauth, October 2006 -# Support: liunx@sap.com -# License: GNU General Public License (GPL) -# Copyright: (c) 2006 Alexander Krauth -# -# An example usage: -# See usage() function below for more details... -# -# OCF instance parameters: -# OCF_RESKEY_SID -# OCF_RESKEY_DIR_EXECUTABLE (optional, well known directories will be searched by default) -# OCF_RESKEY_DBTYPE -# OCF_RESKEY_NETSERVICENAME (optional, non standard name of Oracle Listener) -# OCF_RESKEY_DBJ2EE_ONLY (optional, default is false) -# OCF_RESKEY_DIR_BOOTSTRAP (optional, if non standard J2EE server directory) -# OCF_RESKEY_DIR_SECSTORE (optional, if non standard J2EE secure store directory) -# -# ToDo: -# Remove all the database dependend stuff from the agent and use -# saphostcontrol daemon as soon as SAP will release it. -# -####################################################################### -# Initialization: - -if [ -f /usr/lib/heartbeat/ocf-shellfuncs ]; then - . /usr/lib/heartbeat/ocf-shellfuncs -elif [ -f /usr/share/cluster/ocf-shellfuncs ]; then - . /usr/share/cluster/ocf-shellfuncs -else - echo Could not find ocf-shellfuncs! - exit 1 -fi - -####################################################################### - -SH=/bin/sh - -usage() { - methods=`sapdatabase_methods` - methods=`echo $methods | tr ' ' '|'` - cat <<-! - usage: $0 ($methods) - - $0 manages a SAP database of any type as an HA resource. - Currently Oracle, MaxDB and DB/2 UDB are supported. - ABAP databases as well as JAVA only databases are supported. - - The 'start' operation starts the instance. - The 'stop' operation stops the instance. - The 'status' operation reports whether the instance is running - The 'monitor' operation reports whether the instance seems to be working - The 'validate-all' operation reports whether the parameters are valid - The 'methods' operation reports on the methods $0 supports - - ! -} - -meta_data() { - cat <<END -<?xml version="1.0"?> -<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> -<resource-agent name="SAPDatabase"> -<version>1.2</version> - -<longdesc lang="en"> -Resource script for SAP databases. It manages a SAP database of any type as an HA resource. -</longdesc> -<shortdesc lang="en">SAP database resource agent</shortdesc> - -<parameters> - <parameter name="SID" unique="1" required="1" primary="1"> - <longdesc lang="en">The unique SAP system identifier. e.g. P01</longdesc> - <shortdesc lang="en">SAP system ID</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="DIR_EXECUTABLE" unique="1" required="0"> - <longdesc lang="en">The full qualified path where to find sapstartsrv and sapcontrol.</longdesc> - <shortdesc lang="en">path of sapstartsrv and sapcontrol</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="DBTYPE" unique="1" required="1"> - <longdesc lang="en">The name of the database vendor you use. Set either: ORA,DB6,ADA</longdesc> - <shortdesc lang="en">database vendor</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="NETSERVICENAME" unique="1" required="0"> - <longdesc lang="en">The Oracle TNS listener name.</longdesc> - <shortdesc lang="en">listener name</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="DBJ2EE_ONLY" unique="1" required="0"> - <longdesc lang="en">If you do not have a ABAP stack installed in the SAP database, set this to TRUE</longdesc> - <shortdesc lang="en">only JAVA stack installed</shortdesc> - <content type="boolean" default="false"/> - </parameter> - <parameter name="DIR_BOOTSTRAP" unique="1" required="0"> - <longdesc lang="en">The full qualified path where to find the J2EE instance bootstrap directory. e.g. /usr/sap/P01/J00/j2ee/cluster/bootstrap</longdesc> - <shortdesc lang="en">path to j2ee bootstrap directory</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="DIR_SECSTORE" unique="1" required="0"> - <longdesc lang="en">The full qualified path where to find the J2EE security store directory. e.g. /usr/sap/P01/SYS/global/security/lib/tools</longdesc> - <shortdesc lang="en">path to j2ee secure store directory</shortdesc> - <content type="string" default="" /> - </parameter> -</parameters> - -<actions> -<action name="start" timeout="1800" /> -<action name="stop" timeout="1800" /> -<action name="status" timeout="60" /> -<action name="monitor" depth="0" timeout="60" interval="120" start-delay="180" /> -<action name="validate-all" timeout="5" /> -<action name="meta-data" timeout="5" /> -<action name="methods" timeout="5" /> -</actions> -</resource-agent> -END -} - -trap_handler() { - rm -f $TEMPFILE - exit $OCF_ERR_GENERIC -} - - -# -# listener_start: Start the given listener -# -listener_start() { - orasid="ora`echo $SID | tr [:upper:] [:lower:]`" - rc=$OCF_SUCCESS - output=`echo "lsnrctl start $NETSERVICENAME" | su - $orasid 2>&1` - if [ $? -eq 0 ] - then - ocf_log info "Oracle Listener $NETSERVICENAME started: $output" - rc=$OCF_SUCCESS - else - ocf_log err "Oracle Listener $NETSERVICENAME start failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# listener_stop: Stop the given listener -# -listener_stop() { - orasid="ora`echo $SID | tr [:upper:] [:lower:]`" - rc=$OCF_SUCCESS - if - listener_status - then - : listener is running, trying to stop it later... - else - return $OCF_SUCCESS - fi - output=`echo "lsnrctl stop $NETSERVICENAME" | su - $orasid 2>&1` - if [ $? -eq 0 ] - then - ocf_log info "Oracle Listener $NETSERVICENAME stopped: $output" - else - ocf_log err "Oracle Listener $NETSERVICENAME stop failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# listener_status: is the given listener running? -# -listener_status() { - orasid="ora`echo $SID | tr [:upper:] [:lower:]`" - # Note: ps cuts off it's output at column $COLUMNS, so "ps -ef" can not be used here - # as the output might be to long. - cnt=`ps efo args --user $orasid | grep $NETSERVICENAME | grep -c tnslsnr` - if [ $cnt -eq 1 ] - then - rc=$OCF_SUCCESS - else - ocf_log info "listener process not running for $NETSERVICENAME for $SID" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# x_server_start: Start the given x_server -# -x_server_start() { - rc=$OCF_SUCCESS - output=`echo "x_server start" | su - $sidadm 2>&1` - if [ $? -eq 0 ] - then - ocf_log info "MaxDB x_server start: $output" - rc=$OCF_SUCCESS - else - ocf_log err "MaxDB x_server start failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# x_server_stop: Stop the x_server -# -x_server_stop() { - rc=$OCF_SUCCESS - output=`echo "x_server stop" | su - $sidadm 2>&1` - if [ $? -eq 0 ] - then - ocf_log info "MaxDB x_server stop: $output" - else - ocf_log err "MaxDB x_server stop failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# x_server_status: is the x_server running? -# -x_server_status() { - sdbuser=`ls -ld /sapdb/$SID | awk '{print $3}'` - # Note: ps cuts off it's output at column $COLUMNS, so "ps -ef" can not be used here - # as the output might be to long. - cnt=`ps efo args --user $sdbuser | grep -c vserver` - if [ $cnt -eq 1 ] - then - rc=$OCF_SUCCESS - else - ocf_log info "x_server process not running" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# oracle_stop: Stop the Oracle database without any condition -# -oracle_stop() { -echo '#!/bin/sh -LOG=$HOME/stopdb.log -date > $LOG - -if [ -x "${ORACLE_HOME}/bin/sqlplus" ] -then - SRVMGRDBA_EXE="${ORACLE_HOME}/bin/sqlplus" -else - echo "Can not find executable sqlplus" >> $LOG - exit 1 -fi - -$SRVMGRDBA_EXE /NOLOG >> $LOG << ! -connect / as sysdba -shutdown immediate -exit -! -rc=$? -cat $LOG -exit $rc' > $TEMPFILE - -chmod 700 $TEMPFILE -chown $sidadm $TEMPFILE - -su - $sidadm -c $TEMPFILE -retcode=$? -rm -f $TEMPFILE - -if [ $retcode -eq 0 ]; then - sapdatabase_status - if [ $? -ne $OCF_NOT_RUNNING ]; then - retcode=1 - fi -fi - -return $retcode -} - -# -# maxdb_stop: Stop the MaxDB database without any condition -# -maxdb_stop() { -if [ $DBJ2EE_ONLY -eq 1 ]; then - userkey=c_J2EE -else - userkey=c -fi - -echo "#!/bin/sh -LOG=$HOME/stopdb.log -date > $LOG -echo "Stop database with xuserkey >$userkey<" >> $LOG -dbmcli -U ${userkey} db_offline >> $LOG 2>&1 -exit $?" > $TEMPFILE - -chmod 700 $TEMPFILE -chown $sidadm $TEMPFILE - -su - $sidadm -c $TEMPFILE -retcode=$? -rm -f $TEMPFILE - -if [ $retcode -eq 0 ]; then - sapdatabase_status - if [ $? -ne $OCF_NOT_RUNNING ]; then - retcode=1 - fi -fi - -return $retcode -} - -# -# db6udb_stop: Stop the DB2/UDB database without any condition -# -db6udb_stop() { -echo '#!/bin/sh -LOG=$HOME/stopdb.log -date > $LOG -echo "Shut down the database" >> $LOG -$INSTHOME/sqllib/bin/db2 deactivate database $DB2DBDFT |tee -a $LOG 2>&1 -$INSTHOME/sqllib/adm/db2stop force |tee -a $LOG 2>&1 -exit $?' > $TEMPFILE - -chmod 700 $TEMPFILE -chown $sidadm $TEMPFILE - -su - $sidadm -c $TEMPFILE -retcode=$? -rm -f $TEMPFILE - -if [ $retcode -eq 0 ]; then - sapdatabase_status - if [ $? -ne $OCF_NOT_RUNNING ]; then - retcode=1 - fi -fi - -return $retcode -} - -# -# methods: What methods/operations do we support? -# -sapdatabase_methods() { - cat <<-! - start - stop - status - monitor - validate-all - methods - meta-data - usage - ! -} - - -# -# sapdatabase_start : Start the SAP database -# -sapdatabase_start() { - case $DBTYPE in - ADA) x_server_start - ;; - ORA) listener_start - ;; - esac - - output=`su - $sidadm -c $SAPSTARTDB` - if [ $? -eq 0 ] - then - ocf_log info "SAP database $SID started: $output" - rc=$OCF_SUCCESS - else - ocf_log err "SAP database $SID start failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# sapdatabase_stop: Stop the SAP database -# -sapdatabase_stop() { - - # use of the stopdb kernel script is not possible, because there are to may checks in that - # script. We want to stop the database regardless of anything. - #output=`su - $sidadm -c $SAPSTOPDB` - - case $DBTYPE in - ORA) output=`oracle_stop` - ;; - ADA) output=`maxdb_stop` - ;; - DB6) output=`db6udb_stop` - ;; - esac - - if [ $? -eq 0 ] - then - ocf_log info "SAP database $SID stopped: $output" - rc=$OCF_SUCCESS - else - ocf_log err "SAP database $SID stop failed: $output" - rc=$OCF_ERR_GENERIC - fi - - case $DBTYPE in - ORA) listener_stop - ;; - ADA) x_server_stop - ;; - esac - return $rc -} - - -# -# sapdatabase_monitor: Can the given database instance do anything useful? -# -sapdatabase_monitor() { - rc=$OCF_SUCCESS - - case $DBTYPE in - ADA) x_server_status - if [ $? -ne $OCF_SUCCESS ]; then x_server_start; fi - ;; - ORA) listener_status - if [ $? -ne $OCF_SUCCESS ]; then listener_start; fi - ;; - esac - - if [ $DBJ2EE_ONLY -eq 0 ] - then - output=`echo "$SAPDBCONNECT -d -w /dev/null" | su $sidadm 2>&1` - if [ $? -le 4 ] - then - rc=$OCF_SUCCESS - else - rc=$OCF_NOT_RUNNING - fi - else - DB_JARS="" - if [ -f "$BOOTSTRAP"/bootstrap.properties ]; then - DB_JARS=`cat $BOOTSTRAP/bootstrap.properties | grep -i rdbms.driverLocation | sed -e 's/\:/:/g' | awk -F= '{print $2}'` - fi - IAIK_JCE="$SECSTORE"/iaik_jce.jar - IAIK_JCE_EXPORT="$SECSTORE"/iaik_jce_export.jar - EXCEPTION="$BOOTSTRAP"/exception.jar - LOGGING="$BOOTSTRAP"/logging.jar - OPENSQLSTA="$BOOTSTRAP"/opensqlsta.jar - TC_SEC_SECSTOREFS="$BOOTSTRAP"/tc_sec_secstorefs.jar - JDDI="$BOOTSTRAP"/../server0/bin/ext/jdbdictionary/jddi.jar - ANTLR="$BOOTSTRAP"/../server0/bin/ext/antlr/antlr.jar - FRAME="$BOOTSTRAP"/../server0/bin/system/frame.jar - - # only start jdbcconnect when all jars available - if [ -f "$EXCEPTION" -a -f "$LOGGING" -a -f "$OPENSQLSTA" -a -f "$TC_SEC_SECSTOREFS" -a -f "$JDDI" -a -f "$ANTLR" -a -f "$FRAME" -a -f "$SAPDBCONNECT" ] - then - output=`eval java -cp ".:$FRAME:$ANTLR:$JDDI:$IAIK_JCE_EXPORT:$IAIK_JCE:$EXCEPTION:$LOGGING:$OPENSQLSTA:$TC_SEC_SECSTOREFS:$DB_JARS:$SAPDBCONNECT" com.sap.inst.jdbc.connect.JdbcCon -sec $SID:$SID` - if [ $? -le 0 ] - then - rc=$OCF_SUCCESS - else - rc=$OCF_NOT_RUNNING - fi - else - output="Cannot find all jar files needed for database monitoring." - rc=$OCF_ERR_GENERIC - fi - fi - - if [ $rc -ne $OCF_SUCCESS ] - then - ocf_log err "The SAP database $SID ist not running: $output" - fi - return $rc -} - - -# -# sapdatabase_status: Are there any database processes on this host ? -# -sapdatabase_status() { - case $DBTYPE in - ADA) SEARCH="$SID/db/pgm/kernel" - SUSER=`ls -ld /sapdb/$SID | awk '{print $3}'` - SNUM=2 - ;; - ORA) SEARCH="ora_[a-z][a-z][a-z][a-z]_" - SUSER="ora`echo $SID | tr [:upper:] [:lower:]`" - SNUM=4 - ;; - DB6) SEARCH="db2[a-z][a-z][a-z][a-z][a-z]" - SUSER="db2`echo $SID | tr [:upper:] [:lower:]`" - SNUM=5 - ;; - esac - - # Note: ps cuts off it's output at column $COLUMNS, so "ps -ef" can not be used here - # as the output might be to long. - cnt=`ps efo args --user $SUSER | grep -c "$SEARCH"` - if [ $cnt -ge $SNUM ] - then - rc=$OCF_SUCCESS - else - # ocf_log info "Database Instance $SID is not running on `hostname`" - rc=$OCF_NOT_RUNNING - fi - return $rc -} - - -# -# sapdatabase_vaildate: Check the symantic of the input parameters -# -sapdatabase_vaildate() { - rc=$OCF_SUCCESS - if [ `echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$'` -ne 1 ] - then - ocf_log err "Parsing parameter SID: '$SID' is not a valid system ID!" - rc=$OCF_ERR_ARGS - fi - - case "$DBTYPE" in - ORA|ADA|DB6) ;; - *) ocf_log err "Parsing parameter DBTYPE: '$DBTYPE' is not a supported database type!" - rc=$OCF_ERR_ARGS ;; - esac - - return $rc -} - - -# -# 'main' starts here... -# - -if - ( [ $# -ne 1 ] ) -then - usage - exit $OCF_ERR_ARGS -fi - -# Set a tempfile and make sure to clean it up again -TEMPFILE="$(mktemp -t /tmp/SAPDatabase.tmp.XXXXXX)" -trap trap_handler INT TERM - -# These operations don't require OCF instance parameters to be set -case "$1" in - meta-data) meta_data - exit $OCF_SUCCESS;; - - usage) usage - exit $OCF_SUCCESS;; - - methods) sapdatabase_methods - exit $?;; - - *);; -esac - -US=`id -u -n` -US=`echo $US` -if - [ $US != root ] -then - ocf_log err "$0 must be run as root" - exit $OCF_ERR_PERM -fi - -# mandatory parameter check -if [ -z "$OCF_RESKEY_SID" ]; then - ocf_log err "Please set OCF_RESKEY_SID to the SAP system id!" - exit $OCF_ERR_ARGS -fi -SID=`echo "$OCF_RESKEY_SID"` - -if [ -z "$OCF_RESKEY_DBTYPE" ]; then - ocf_log err "Please set OCF_RESKEY_DBTYPE to the database vendor specific tag (ORA,ADA,DB6)!" - exit $OCF_ERR_ARGS -fi -DBTYPE="$OCF_RESKEY_DBTYPE" - -# optional OCF parameters, we try to guess which directories are correct -EXESTARTDB="startdb" -EXESTOPDB="stopdb" -EXEDBCONNECT="R3trans" -if [ -z "$OCF_RESKEY_DBJ2EE_ONLY" ]; then - DBJ2EE_ONLY=0 -else - case "$OCF_RESKEY_DBJ2EE_ONLY" in - 1|true|TRUE|yes|YES) DBJ2EE_ONLY=1 - EXESTARTDB="startj2eedb" - EXESTOPDB="stopj2eedb" - EXEDBCONNECT="jdbcconnect.jar" - ;; - 0|false|FALSE|no|NO) DBJ2EE_ONLY=0;; - *) ocf_log err "Parsing parameter DBJ2EE_ONLY: '$DBJ2EE_ONLY' is not a boolean value!" - exit $OCF_ERR_ARGS ;; - esac -fi - -if [ -z "$OCF_RESKEY_NETSERVICENAME" ]; then - case "$DBTYPE" in - ORA|ora) NETSERVICENAME="LISTENER";; - *) NETSERVICENAME="";; - esac -else - NETSERVICENAME="$OCF_RESKEY_NETSERVICENAME" -fi - -PATHLIST=" -$OCF_RESKEY_DIR_EXECUTABLE -/usr/sap/$SID/*/exe -/usr/sap/$SID/SYS/exe/run -/sapmnt/$SID/exe -" -DIR_EXECUTABLE="" -for EXEPATH in $PATHLIST -do - SAPSTARTDB=`which $EXEPATH/$EXESTARTDB 2> /dev/null` - if [ $? -eq 0 ] - then - MYPATH=`echo "$SAPSTARTDB" | head -1` - MYPATH=`dirname "$MYPATH"` - if [ -x $MYPATH/$EXESTARTDB -a -x $MYPATH/$EXESTOPDB -a -x $MYPATH/$EXEDBCONNECT ] - then - DIR_EXECUTABLE=$MYPATH - SAPSTARTDB=$MYPATH/$EXESTARTDB - SAPSTOPDB=$MYPATH/$EXESTOPDB - SAPDBCONNECT=$MYPATH/$EXEDBCONNECT - break - fi - fi -done -if [ -z "$DIR_EXECUTABLE" ] -then - ocf_log err "Cannot find $EXESTARTDB,$EXESTOPDB and $EXEDBCONNECT executable, please set DIR_EXECUTABLE parameter!" - exit $OCF_ERR_GENERIC -fi - -if [ $DBJ2EE_ONLY -eq 1 ] -then - if [ -n "$OCF_RESKEY_DIR_BOOTSTRAP" ] - then - BOOTSTRAP="$OCF_RESKEY_DIR_BOOTSTRAP" - else - BOOTSTRAP=`echo /usr/sap/$SID/*/j2ee/cluster/bootstrap | head -1` - fi - - if [ -n "$OCF_RESKEY_DIR_SECSTORE" ] - then - SECSTORE="$OCF_RESKEY_DIR_SECSTORE" - else - SECSTORE=/usr/sap/$SID/SYS/global/security/lib/tools - fi -fi - -# as root user we need the library path to the SAP kernel to be able to call executables -if [ `echo $LD_LIBRARY_PATH | grep -c "^$DIR_EXECUTABLE>"` -eq 0 ]; then - LD_LIBRARY_PATH=$DIR_EXECUTABLE:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH -fi -sidadm="`echo $SID | tr [:upper:] [:lower:]`adm" - -# What kind of method was invoked? -case "$1" in - - start) sapdatabase_start - exit $?;; - - stop) sapdatabase_stop - exit $?;; - - monitor) - sapdatabase_monitor - exit $?;; - - status) - sapdatabase_status - exit $?;; - - validate-all) sapdatabase_vaildate - exit $?;; - - *) sapdatabase_methods - exit $OCF_ERR_UNIMPLEMENTED;; -esac diff --git a/rgmanager/src/resources/SAPInstance b/rgmanager/src/resources/SAPInstance deleted file mode 100755 index b84a967..0000000 --- a/rgmanager/src/resources/SAPInstance +++ /dev/null @@ -1,406 +0,0 @@ -#!/bin/sh -# -# SAPInstance -# -# Description: Manages a single SAP Instance as a High-Availability -# resource. One SAP Instance is defined by one -# SAP Instance-Profile. start/stop handels all services -# of the START-Profile, status and monitor care only -# about essential services. -# -# Author: Alexander Krauth, June 2006 -# Support: liunx@sap.com -# License: GNU General Public License (GPL) -# Copyright: (c) 2006 Alexander Krauth -# -# An example usage: -# See usage() function below for more details... -# -# OCF instance parameters: -# OCF_RESKEY_InstanceName -# OCF_RESKEY_DIR_EXECUTABLE (optional, well known directories will be searched by default) -# OCF_RESKEY_DIR_PROFILE (optional, well known directories will be searched by default) -# OCF_RESKEY_START_PROFILE (optional, well known directories will be searched by default) -# -####################################################################### -# Initialization: - -if [ -f /usr/lib/heartbeat/ocf-shellfuncs ]; then - . /usr/lib/heartbeat/ocf-shellfuncs -elif [ -f /usr/share/cluster/ocf-shellfuncs ]; then - . /usr/share/cluster/ocf-shellfuncs -else - echo Could not find ocf-shellfuncs! - exit 1 -fi - -####################################################################### - -SH=/bin/sh - -usage() { - methods=`sapinstance_methods` - methods=`echo $methods | tr ' ' '|'` - cat <<-! - usage: $0 ($methods) - - $0 manages a SAP Instance as an HA resource. - - The 'start' operation starts the instance. - The 'stop' operation stops the instance. - The 'status' operation reports whether the instance is running - The 'monitor' operation reports whether the instance seems to be working - The 'validate-all' operation reports whether the parameters are valid - The 'methods' operation reports on the methods $0 supports - - ! -} - -meta_data() { - cat <<END -<?xml version="1.0"?> -<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> -<resource-agent name="SAPInstance"> -<version>1.6</version> - -<longdesc lang="en"> -Resource script for SAP. It manages a SAP Instance as an HA resource. -</longdesc> -<shortdesc lang="en">SAP instance resource agent</shortdesc> - -<parameters> - <parameter name="InstanceName" unique="1" required="1" primary="1"> - <longdesc lang="en">The full qualified SAP instance name. e.g. P01_DVEBMGS00_sapp01ci</longdesc> - <shortdesc lang="en">instance name: SID_INSTANCE_VIR-HOSTNAME</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="DIR_EXECUTABLE" unique="1" required="0"> - <longdesc lang="en">The full qualified path where to find sapstartsrv and sapcontrol.</longdesc> - <shortdesc lang="en">path of sapstartsrv and sapcontrol</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="DIR_PROFILE" unique="1" required="0"> - <longdesc lang="en">The full qualified path where to find the SAP START profile.</longdesc> - <shortdesc lang="en">path of start profile</shortdesc> - <content type="string" default="" /> - </parameter> - <parameter name="START_PROFILE" unique="1" required="0"> - <longdesc lang="en">The name of the SAP START profile.</longdesc> - <shortdesc lang="en">start profile name</shortdesc> - <content type="string" default="" /> - </parameter> -</parameters> - -<actions> -<action name="start" timeout="180" /> -<action name="stop" timeout="240" /> -<action name="status" timeout="60" /> -<action name="monitor" depth="0" timeout="60" interval="120" start-delay="240" /> -<action name="validate-all" timeout="5" /> -<action name="meta-data" timeout="5" /> -<action name="methods" timeout="5" /> -</actions> -</resource-agent> -END -} - - -# -# methods: What methods/operations do we support? -# -sapinstance_methods() { - cat <<-! - start - stop - status - monitor - validate-all - methods - meta-data - usage - ! -} - - -# -# check_sapstartsrv : Before using sapcontrol we make sure that the sapstartsrv is running for the correct instance. -# We cannot use sapinit and the /usr/sap/sapservices file in case of an enquerep instance, -# because then we have two instances with the same instance number. -# -check_sapstartsrv() { - restart=0 - output=`$SAPCONTROL -nr $InstanceNr -function ParameterValue INSTANCE_NAME -format script` - if [ $? -eq 0 ] - then - runninginst=`echo "$output" | grep '^0 : ' | cut -d' ' -f3` - if [ "$runninginst" != "$InstanceName" ] - then - ocf_log warn "sapstartsrv is running for instance $runninginst, that service will be killed" - restart=1 - fi - else - ocf_log warn "sapstartsrv is not running for instance $SID-$InstanceName, it will be started now" - restart=1 - fi - - if [ -z "$runninginst" ]; then runninginst=$InstanceName; fi - - if [ $restart -eq 1 ] - then - pkill -9 -f "sapstartsrv.*$runninginst" - $SAPSTARTSRV pf=$SAPSTARTPROFILE -D -u $sidadm - - ocf_log info "sapstartsrv for instance $SID-$InstanceName was restarted !" - fi - - return 0 -} - - -# -# sapinstance_start : Start the SAP instance -# -sapinstance_start() { - check_sapstartsrv - - output=`$SAPCONTROL -nr $InstanceNr -function Start` - if [ $? -eq 0 ] - then - output=`$SAPCONTROL -nr $InstanceNr -function WaitforStarted 3600 1` - if [ $? -eq 0 ] - then - ocf_log info "SAP Instance $SID-$InstanceName started: $output" - rc=$OCF_SUCCESS - else - ocf_log err "SAP Instance $SID-$InstanceName start failed: $output" - rc=$OCF_ERR_GENERIC - fi - else - ocf_log err "SAP Instance $SID-$InstanceName start failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - -# -# sapinstance_stop: Stop the SAP instance -# -sapinstance_stop() { - check_sapstartsrv - - output=`$SAPCONTROL -nr $InstanceNr -function Stop` - if [ $? -eq 0 ] - then - output=`$SAPCONTROL -nr $InstanceNr -function WaitforStopped 3600 1` - if [ $? -eq 0 ] - then - ocf_log info "SAP Instance $SID-$InstanceName stopped: $output" - rc=$OCF_SUCCESS - else - ocf_log err "SAP Instance $SID-$InstanceName stop failed: $output" - rc=$OCF_ERR_GENERIC - fi - else - ocf_log err "SAP Instance $SID-$InstanceName stop failed: $output" - rc=$OCF_ERR_GENERIC - fi - return $rc -} - - -# -# sapinstance_monitor: Can the given SAP instance do anything useful? -# -sapinstance_monitor() { - check_sapstartsrv - - rc=$OCF_SUCCESS - count=0 - LOCALHOST=`hostname` - output=`$SAPCONTROL -nr $InstanceNr -host $LOCALHOST -function GetProcessList -format script` - - # we have to parse the output, because the returncode doesn't tell anything about the instance status - for SERVNO in `echo "$output" | grep '^[0-9] ' | cut -d' ' -f1 | sort -u` - do - COLOR=`echo "$output" | grep "^$SERVNO dispstatus: " | cut -d' ' -f3` - SERVICE=`echo "$output" | grep "^$SERVNO name: " | cut -d' ' -f3` - STATE=0 - - case $COLOR in - GREEN|YELLOW) STATE=$OCF_SUCCESS;; - *) STATE=$OCF_NOT_RUNNING;; - esac - - case $SERVICE in - disp+work|msg_server|enserver|enrepserver) - if [ $STATE -eq $OCF_NOT_RUNNING ] - then - ocf_log err "SAP instance service $SERVICE is not running with status $COLOR !" - rc=$STATE - fi - count=1;; - *);; - esac - done - - if [ $count -eq 0 -a $rc -eq $OCF_SUCCESS ] - then - ocf_log err "The SAP instance does not run any services which this RA could monitor!" - rc=$OCF_ERR_ARGS - fi - - return $rc -} - -# -# sapinstance_vaildate: Check the symantic of the input parameters -# -sapinstance_vaildate() { - rc=$OCF_SUCCESS - if [ `echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$'` -ne 1 ] - then - ocf_log err "Parsing instance profile name: '$SID' is not a valid system ID!" - rc=$OCF_ERR_ARGS - fi - - if [ `echo "$InstanceName" | grep -c '^[A-Z].*[0-9][0-9]$'` -ne 1 ] - then - ocf_log err "Parsing instance profile name: '$InstanceName' is not a valid instance name!" - rc=$OCF_ERR_ARGS - fi - - if [ `echo "$InstanceNr" | grep -c '^[0-9][0-9]$'` -ne 1 ] - then - ocf_log err "Parsing instance profile name: '$InstanceNr' is not a valid instance number!" - rc=$OCF_ERR_ARGS - fi - - if [ `echo "$SAPVIRHOST" | grep -c '^[A-Za-z][A-Za-z0-9_-]*$'` -ne 1 ] - then - ocf_log err "Parsing instance profile name: '$SAPVIRHOST' is not a valid hostname!" - rc=$OCF_ERR_ARGS - fi - - return $rc -} - - -# -# 'main' starts here... -# - -if - ( [ $# -ne 1 ] ) -then - usage - exit $OCF_ERR_ARGS -fi - -# These operations don't require OCF instance parameters to be set -case "$1" in - meta-data) meta_data - exit $OCF_SUCCESS;; - - usage) usage - exit $OCF_SUCCESS;; - - methods) sapinstance_methods - exit $?;; - - *);; -esac - -US=`id -u -n` -US=`echo $US` -if - [ $US != root ] -then - ocf_log err "$0 must be run as root" - exit $OCF_ERR_PERM -fi - -# parameter check -if [ -z "$OCF_RESKEY_InstanceName" ] -then - ocf_log err "Please set OCF_RESKEY_InstanceName to the name to the SAP instance profile!" - exit $OCF_ERR_ARGS -fi - -SID=`echo "$OCF_RESKEY_InstanceName" | cut -d_ -f1` -InstanceName=`echo "$OCF_RESKEY_InstanceName" | cut -d_ -f2` -InstanceNr=`echo "$InstanceName" | sed 's/.*([0-9][0-9])$/\1/'` -SAPVIRHOST=`echo "$OCF_RESKEY_InstanceName" | cut -d_ -f3` - -# optional OCF parameters, we try to guess which directories are correct -if [ -z "$OCF_RESKEY_DIR_EXECUTABLE" ] -then - if [ -x /usr/sap/$SID/$InstanceName/exe/sapstartsrv -a -x /usr/sap/$SID/$InstanceName/exe/sapcontrol ] - then - DIR_EXECUTABLE="/usr/sap/$SID/$InstanceName/exe" - SAPSTARTSRV="/usr/sap/$SID/$InstanceName/exe/sapstartsrv" - SAPCONTROL="/usr/sap/$SID/$InstanceName/exe/sapcontrol" - elif [ -x /usr/sap/$SID/SYS/exe/run/sapstartsrv -a -x /usr/sap/$SID/SYS/exe/run/sapcontrol ] - then - DIR_EXECUTABLE="/usr/sap/$SID/SYS/exe/run" - SAPSTARTSRV="/usr/sap/$SID/SYS/exe/run/sapstartsrv" - SAPCONTROL="/usr/sap/$SID/SYS/exe/run/sapcontrol" - else - ocf_log err "Cannot find sapstartsrv and sapcontrol executable, please set DIR_EXECUTABLE parameter!" - exit $OCF_ERR_GENERIC - fi -else - DIR_EXECUTABLE="$OCF_RESKEY_DIR_EXECUTABLE" - SAPSTARTSRV="$OCF_RESKEY_DIR_EXECUTABLE/sapstartsrv" - SAPCONTROL="$OCF_RESKEY_DIR_EXECUTABLE/sapcontrol" -fi - -if [ -z "$OCF_RESKEY_DIR_PROFILE" ] -then - if [ -d /usr/sap/$SID/SYS/profile/ ] - then - DIR_PROFILE="/usr/sap/$SID/SYS/profile" - else - ocf_log err "Expected /usr/sap/$SID/SYS/profile/ to be a directory, please set DIR_PROFILE parameter!" - exit $OCF_ERR_GENERIC - fi -else - DIR_PROFILE="$OCF_RESKEY_DIR_PROFILE" -fi - -if [ -z "$OCF_RESKEY_START_PROFILE" ] -then - SAPSTARTPROFILE="$DIR_PROFILE/START_${InstanceName}_${SAPVIRHOST}" - if [ ! -r $SAPSTARTPROFILE ] - then - ocf_log err "Expected $SAPSTARTPROFILE to be the instance START profile, please set START_PROFILE parameter!" - exit $OCF_ERR_GENERIC - fi -else - SAPSTARTPROFILE="$OCF_RESKEY_START_PROFILE" -fi - -# as root user we need the library path to the SAP kernel to be able to call sapcontrol -if [ `echo $LD_LIBRARY_PATH | grep -c "^$DIR_EXECUTABLE>"` -eq 0 ]; then - LD_LIBRARY_PATH=$DIR_EXECUTABLE:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH -fi -sidadm="`echo $SID | tr [:upper:] [:lower:]`adm" - -# What kind of method was invoked? -case "$1" in - - start) sapinstance_start - exit $?;; - - stop) sapinstance_stop - exit $?;; - - status|monitor) - sapinstance_monitor - exit $?;; - - validate-all) sapinstance_vaildate - exit $?;; - - *) sapinstance_methods - exit $OCF_ERR_UNIMPLEMENTED;; -esac diff --git a/rgmanager/src/resources/apache.metadata b/rgmanager/src/resources/apache.metadata deleted file mode 100644 index 1c7374c..0000000 --- a/rgmanager/src/resources/apache.metadata +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="apache"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an instance of Apache web server - </longdesc> - <shortdesc lang="en"> - Defines an Apache web server - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Define a name for use in <IfDefine name> directive. - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="server_root"> - <longdesc lang="en"> - Define an alternate initial ServerRoot - </longdesc> - <shortdesc lang="en"> - Initial ServerRoot - </shortdesc> - <content type="string" default="/etc/httpd"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define an alternate ServerConfigFile - </longdesc> - <shortdesc lang="en"> - Initial ServerConfigFile - </shortdesc> - <content type="string" default="conf/httpd.conf"/> - </parameter> - - <parameter name="httpd_options"> - <longdesc lang="en"> - Other command-line options for httpd - </longdesc> - <shortdesc lang="en"> - Other command-line options for httpd - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- Checks to see if it''s mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> - - <special tag="rgmanager"> - </special> -</resource-agent> diff --git a/rgmanager/src/resources/apache.sh b/rgmanager/src/resources/apache.sh deleted file mode 100755 index 5132ff2..0000000 --- a/rgmanager/src/resources/apache.sh +++ /dev/null @@ -1,277 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare APACHE_HTTPD=/usr/sbin/httpd -declare APACHE_serverConfigFile -declare APACHE_pid_file="`generate_name_for_pid_file`" -declare APACHE_conf_dir="`generate_name_for_conf_dir`" -declare APACHE_genConfig="$APACHE_conf_dir/httpd.conf" - -declare APACHE_parseConfig=$(dirname $0)/utils/httpd-parse-config.pl - -apache_serverConfigFile() -{ - if [[ "$OCF_RESKEY_config_file" =~ '^/' ]]; then - APACHE_serverConfigFile="$OCF_RESKEY_config_file" - else - APACHE_serverConfigFile="$OCF_RESKEY_server_root/$OCF_RESKEY_config_file" - fi - - return; -} - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_server_root" ]; then - clog_service_verify $CLOG_FAILED "Invalid ServerRoot" - return $OCF_ERR_ARGS - fi - - if [ ! -d "$OCF_RESKEY_server_root" ]; then - clog_service_verify $CLOG_FAILED "ServerRoot Directory Is Missing" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - return $OCF_ERR_ARGS - fi - - if [ ! -r "$APACHE_serverConfigFile" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE "$APACHE_config_file" - return $OCF_ERR_ARGS - fi - - if [ -z "$APACHE_pid_file" ]; then - clog_service_verify $CLOG_FAILED "Invalid name of PID file" - return $OCF_ERR_ARGS - fi - - clog_check_syntax $CLOG_INIT "$APACHE_serverConfigFile" - - "$APACHE_HTTPD" -t \ - -D"$OCF_RESKEY_name" \ - -d "$OCF_RESKEY_server_root" \ - -f "$APACHE_serverConfigFile" \ - $OCF_RESKEY_httpd_options &> /dev/null - - if [ $? -ne 0 ]; then - clog_check_syntax $CLOG_FAILED "$APACHE_config_file" - return $OCF_ERR_GENERIC - fi - - clog_check_syntax $CLOG_SUCCEED "$APACHE_config_file" - - return 0 -} - -generate_configFile() -{ - declare originalConfigFile=$1; - declare generatedConfigFile=$2; - declare ip_addresses=$3; - - if [ -f "$generatedConfigFile" ]; then - sha1_verify "$generatedConfigFile" - if [ $? -ne 0 ]; then - clog_check_sha1 $CLOG_FAILED - return 0 - fi - fi - - clog_generate_config $CLOG_INIT "$originalConfigFile" "$generatedConfigFile" - - generate_configTemplate "$generatedConfigFile" "$1" - cat >> "$generatedConfigFile" << EOT -# From a cluster perspective, the key fields are: -# Listen - must be set to service floating IP address. -# ServerRoot - path to the ServerRoot (initial value is set in service conf) -# - -EOT - - IFS_old="$IFS" - IFS=$'\n' - for i in `"$APACHE_parseConfig" -D"$OCF_RESKEY_name" < "$originalConfigFile" | grep -P '(^Listen)|(^Port)' | grep -v ':'`; do - port=`echo $i | sed 's/^Listen (.*)/\1/;s/^Port (.*)/\1/'`; - IFS=$' '; - for z in $ip_addresses; do - echo "Listen $z:$port" >> "$generatedConfigFile"; - done - IFS=$'\n'; - done; - IFS="$IFS_old" - - echo "PidFile "$APACHE_pid_file"" >> "$generatedConfigFile"; - echo >> "$generatedConfigFile" - - cat "$originalConfigFile" | sed 's/^Listen/### Listen/;s/^Port/### Port/;s/^PidFile/### PidFile/' | \ - "$APACHE_parseConfig" -D"$OCF_RESKEY_name" >> "$generatedConfigFile" - - sha1_addToFile "$generatedConfigFile" - clog_generate_config $CLOG_SUCCEED "$originalConfigFile" "$generatedConfigFile" -} - -start() -{ - declare ccs_fd - declare ip_addresses - - clog_service_start $CLOG_INIT - - create_pid_directory - create_conf_directory "$APACHE_conf_dir" - check_pid_file "$APACHE_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$APACHE_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_INIT "IP Addresses" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -z "$ip_addresses" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_SUCCEED "IP Addresses" - - generate_configFile "$APACHE_serverConfigFile" "$APACHE_genConfig" "$ip_addresses" - - "$APACHE_HTTPD" \ - "-D$OCF_RESKEY_name" \ - -d "$OCF_RESKEY_server_root" \ - -f "$APACHE_genConfig" \ - $OCF_RESKEY_httpd_options \ - -k start - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - else - clog_service_start $CLOG_SUCCEED - fi - - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$APACHE_pid_file" "$OCF_RESKEY_shutdown_wait" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$APACHE_pid_file" - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$APACHE_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -if [ "$1" != "meta-data" ]; then - apache_serverConfigFile -fi; - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - verify-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac diff --git a/rgmanager/src/resources/clusterfs.sh b/rgmanager/src/resources/clusterfs.sh deleted file mode 100755 index fa2994d..0000000 --- a/rgmanager/src/resources/clusterfs.sh +++ /dev/null @@ -1,876 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2002-2004 -# Copyright Mission Critical Linux, Inc. 2000 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# File system (normal) mount/umount/fsck/etc. agent -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -# -# XXX todo - search and replace on these -# -SUCCESS=0 -FAIL=2 -YES=0 -NO=1 -YES_STR="yes" - -# Grab nfs lock tricks if available -export NFS_TRICKS=1 -if [ -f "$(dirname $0)/svclib_nfslock" ]; then - . $(dirname $0)/svclib_nfslock - NFS_TRICKS=0 -else - unset OCF_RESKEY_nfslock -fi - - -. $(dirname $0)/ocf-shellfuncs - - -meta_data() -{ - cat <<EOT -<?xml version="1.0" ?> -<resource-agent name="clusterfs" version="rgmanager 2.0"> - <version>1.0</version> - - <longdesc lang="en"> - This defines a cluster file system mount (i.e. GFS) - </longdesc> - <shortdesc lang="en"> - Defines a cluster file system mount. - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Symbolic name for this file system. - </longdesc> - <shortdesc lang="en"> - File System Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="mountpoint" unique="1" required="1"> - <longdesc lang="en"> - Path in file system heirarchy to mount this file system. - </longdesc> - <shortdesc lang="en"> - Mount Point - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="device" unique="1" required="1"> - <longdesc lang="en"> - Block device, file system label, or UUID of file system. - </longdesc> - <shortdesc lang="en"> - Device or Label - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="fstype"> - <longdesc lang="en"> - File system type. If not specified, mount(8) will attempt to - determine the file system type. - </longdesc> - <shortdesc lang="en"> - File system type - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="force_unmount"> - <longdesc lang="en"> - If set, the cluster will kill all processes using - this file system when the resource group is - stopped. Otherwise, the unmount will fail, and - the resource group will be restarted. - </longdesc> - <shortdesc lang="en"> - Force Unmount - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="options"> - <longdesc lang="en"> - If set, the file system will be checked (even if - it is a journalled file system). This option is - ignored for non-journalled file systems such as - ext2. - </longdesc> - <shortdesc lang="en"> - Mount Options - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="self_fence"> - <longdesc lang="en"> - If set and unmounting the file system fails, the node will - immediately reboot. Generally, this is used in conjunction - with force-unmount support, but it is not required. - </longdesc> - <shortdesc lang="en"> - Seppuku Unmount - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="fsid"> - <longdesc lang="en"> - File system ID for NFS exports. This can be overridden - in individual nfsclient entries. - </longdesc> - <shortdesc lang="en"> - NFS File system ID - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="nfslock" inherit="service%nfslock"> - <longdesc lang="en"> - If set, the node will try to kill lockd and issue - reclaims across all remaining network interface cards. - This happens always, regardless of unmounting failed. - </longdesc> - <shortdesc lang="en"> - Enable NFS lock workarounds - </shortdesc> - <content type="boolean"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="900"/> - <action name="stop" timeout="30"/> - <!-- Recovery isn't possible; we don't know if resources are using - the file system. --> - - <!-- Checks to see if it's mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <!-- Checks to see if we can write to the mountpoint (if !ROFS) --> - <action name="status" depth="20" timeout="30" interval="10m"/> - <action name="monitor" depth="20" timeout="30" interval="10m"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="5"/> - </actions> - - <special tag="rgmanager"> - <child type="fs" start="1" stop="3"/> - <child type="clusterfs" start="1" stop="3"/> - <child type="nfsexport" start="3" stop="1"/> - </special> -</resource-agent> -EOT -} - - -verify_name() -{ - [ -n "$OCF_RESKEY_name" ] || exit $OCF_ERR_ARGS -} - - -verify_mountpoint() -{ - if [ -z "$OCF_RESKEY_mountpoint" ]; then - ocf_log err "No mount point specified." - return $OCF_ERR_ARGS - fi - - if ! [ -e "$OCF_RESKEY_mountpoint" ]; then - ocf_log info "Mount point $OCF_RESKEY_mountpoint will be " - "created at mount time." - return 0 - fi - - [ -d "$OCF_RESKEY_mountpoint" ] && return 0 - - ocf_log err "$OCF_RESKEY_mountpoint is not a directory" - return $OCF_ERR_ARGS -} - - -real_device() -{ - declare dev=$1 - declare realdev - - [ -z "$dev" ] && return 1 - - if [ -h "$dev" ]; then - realdev=$(readlink -f $dev) - if [ $? -ne 0 ]; then - return 1 - fi - echo $realdev - return 0 - fi - - if [ -b "$dev" ]; then - echo $dev - return 0 - fi - - realdev=$(findfs $dev 2> /dev/null) - if [ -n "$realdev" ] && [ -b "$realdev" ]; then - echo $realdev - return 0 - fi - - return 1 -} - - -verify_device() -{ - declare realdev - - if [ -z "$OCF_RESKEY_device" ]; then - ocf_log err "No device or label specified." - return $OCF_ERR_ARGS - fi - - realdev=$(real_device $OCF_RESKEY_device) - if [ -n "$realdev" ]; then - if [ "$realdev" != "$OCF_RESKEY_device" ]; then - echo "Specified $OCF_RESKEY_device maps to $realdev" - fi - return $OCF_SUCCESS - fi - - ocf_log "Device or label "$OCF_RESKEY_device" not valid" - - return $OCF_ERR_ARGS -} - - -verify_fstype() -{ - # Auto detect? - [ -z "$OCF_RESKEY_fstype" ] && return $OCF_SUCCESS - - case $OCF_RESKEY_fstype in - gfs) - return $OCF_SUCCESS - ;; - *) - ocf_log err "File system type $OCF_RESKEY_fstype not supported" - return $OCF_ERR_ARGS - ;; - esac -} - - -verify_options() -{ - declare -i ret=$OCF_SUCCESS - - # - # From mount(8) - # - for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do - case $o in - async|atime|auto|defaults|dev|exec|_netdev|noatime) - continue - ;; - noauto|nodev|noexec|nosuid|nouser|ro|rw|suid|sync) - continue - ;; - dirsync|user|users) - continue - ;; - esac - - case $OCF_RESKEY_fstype in - gfs) - case $o in - lockproto=*|locktable=*|hostdata=*) - continue; - ;; - localcaching|localflocks|ignore_local_fs) - continue; - ;; - num_glockd|acl|suiddir) - continue - ;; - esac - ;; - esac - - ocf_log err "Option $o not supported for $OCF_RESKEY_fstype" - ret=$OCF_ERR_ARGS - done - - return $ret -} - - -verify_all() -{ - verify_name || return $OCF_ERR_ARGS - verify_fstype || return $OCF_ERR_ARGS - verify_device || return $OCF_ERR_ARGS - verify_mountpoint || return $OCF_ERR_ARGS - verify_options || return $OCF_ERR_ARGS -} - - -# -# mountInUse device mount_point -# -# Check to see if either the device or mount point are in use anywhere on -# the system. It is not required that the device be mounted on the named -# moint point, just if either are in use. -# -mountInUse () { - typeset mp tmp_mp - typeset dev tmp_dev - typeset junk - - if [ $# -ne 2 ]; then - ocf_log err "Usage: mountInUse device mount_point". - return $FAIL - fi - - dev=$1 - mp=$2 - - while read tmp_dev tmp_mp junk; do - if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then - return $YES - fi - - if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then - return $YES - fi - done < <(mount | awk '{print $1,$3}') - - return $NO -} - - -# -# isMounted device mount_point -# -# Check to see if the device is mounted. Print a warning if its not -# mounted on the directory we expect it to be mounted on. -# -isMounted () { - - typeset mp tmp_mp - typeset dev tmp_dev - - if [ $# -ne 2 ]; then - ocf_log err "Usage: isMounted device mount_point" - return $FAIL - fi - - dev=$(real_device $1) - if [ -z "$dev" ]; then - ocf_log err "isMounted: Could not match $1 with a real device" - return $FAIL - fi - mp=$(readlink -f $2) - - while read tmp_dev tmp_mp - do - #echo "spec=$1 dev=$dev tmp_dev=$tmp_dev" - tmp_dev=$(real_device $tmp_dev) - - if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then - # - # Check to see if its mounted in the right - # place - # - if [ -n "$tmp_mp" -a "$tmp_mp" != "$mp" ]; then - ocf_log warn "\ -Device $dev is mounted on $tmp_mp instead of $mp" - fi - return $YES - fi - done < <(mount | awk '{print $1,$3}') - - return $NO -} - - -# -# isAlive mount_point -# -# Check to see if mount_point is alive (testing read/write) -# -isAlive() -{ - declare errcode - declare mount_point - declare file=".writable_test.$(hostname)" - declare rw - - if [ $# -ne 1 ]; then - ocf_log err "Usage: isAlive mount_point" - return $FAIL - fi - mount_point=$1 - - test -d $mount_point - if [ $? -ne 0 ]; then - ocf_log err "$mount_point is not a directory" - return $FAIL - fi - - [ $OCF_CHECK_LEVEL -lt 10 ] && return $YES - - # depth 10 test (read test) - ls $mount_point > /dev/null 2> /dev/null - errcode=$? - if [ $errcode -ne 0 ]; then - ocf_log err "clusterfs:${OCF_RESKEY_name}: isAlive failed read test on [$mount_point]. Return code: $errcode" - return $NO - fi - - [ $OCF_CHECK_LEVEL -lt 20 ] && return $YES - - # depth 20 check (write test) - rw=$YES - for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do - if [ "$o" = "ro" ]; then - rw=$NO - fi - done - if [ $rw -eq $YES ]; then - file=$mount_point/$file - while true; do - if [ -e "$file" ]; then - file=${file}_tmp - continue - else - break - fi - done - touch $file > /dev/null 2> /dev/null - errcode=$? - if [ $errcode -ne 0 ]; then - ocf_log err "clusterfs:${OCF_RESKEY_name}: isAlive failed write test on [$mount_point]. Return code: $errcode" - return $NO - fi - rm -f $file > /dev/null 2> /dev/null - fi - - return $YES -} - - -# -# startFilesystem -# -startFilesystem() { - typeset -i ret_val=$SUCCESS - typeset mp="" # mount point - typeset dev="" # device - typeset fstype="" - typeset opts="" - typeset device_in_use="" - typeset mount_options="" - - # - # Get the mount point, if it exists. If not, no need to continue. - # - mp=${OCF_RESKEY_mountpoint} - case "$mp" in - ""|"[ ]*") # nothing to mount - return $SUCCESS - ;; - /*) # found it - ;; - *) # invalid format - ocf_log err \ -"startFilesystem: Invalid mount point format (must begin with a '/'): '$mp'" - return $FAIL - ;; - esac - - # - # Get the device - # - dev=$(real_device $OCF_RESKEY_device) - if [ -z "$dev" ]; then - ocf_log err "\ -startFilesystem: Could not match $OCF_RESKEY_device with a real device" - return $FAIL - fi - - # - # Ensure we've got a valid directory - # - if [ -e "$mp" ]; then - if ! [ -d "$mp" ]; then - ocf_log err "\ -startFilesystem: Mount point $mp exists but is not a directory" - return $FAIL - fi - else - ocf_log info "\ -startFilesystem: Creating mount point $mp for device $dev" - mkdir -p $mp - fi - - # - # Get the filesystem type, if specified. - # - fstype_option="" - fstype=${OCF_RESKEY_fstype} - case "$fstype" in - ""|"[ ]*") - fstype="" - ;; - *) # found it - fstype_option="-t $fstype" - ;; - esac - - # - # See if the device is already mounted. - # - isMounted $dev $mp - case $? in - $YES) # already mounted - ocf_log debug "$dev already mounted" - return $SUCCESS - ;; - $NO) # not mounted, continue - ;; - $FAIL) - return $FAIL - ;; - esac - - - # - # Make sure that neither the device nor the mount point are mounted - # (i.e. they may be mounted in a different location). The'mountInUse' - # function checks to see if either the device or mount point are in - # use somewhere else on the system. - # - mountInUse $dev $mp - case $? in - $YES) # uh oh, someone is using the device or mount point - ocf_log err "\ -Cannot mount $dev on $mp, the device or mount point is already in use!" - return $FAIL - ;; - $NO) # good, no one else is using it - ;; - $FAIL) - return $FAIL - ;; - *) - ocf_log err "Unknown return from mountInUse" - return $FAIL - ;; - esac - - # - # Make sure the mount point exists. - # - if [ ! -d $mp ]; then - rm -f $mp # rm in case its a plain file - mkdir -p $mp # create the mount point - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err \ - "'mkdir -p $mp' failed, error=$ret_val" - return $FAIL - fi - fi - - # - # Get the mount options, if they exist. - # - mount_options="" - opts=${OCF_RESKEY_options} - case "$opts" in - ""|"[ ]*") - opts="" - ;; - *) # found it - mount_options="-o $opts" - ;; - esac - - # - # Mount the device - # - ocf_log debug "mount $fstype_option $mount_options $dev $mp" - mount $fstype_option $mount_options $dev $mp - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err "\ -'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val" - return $FAIL - fi - - return $SUCCESS -} - - -# -# stopFilesystem serviceID deviceID -# -# Run the stop actions -# -stopFilesystem() { - typeset -i ret_val=0 - typeset -i try=1 - typeset -i max_tries=3 # how many times to try umount - typeset -i sleep_time=2 # time between each umount failure - typeset -i refs=0 - typeset done="" - typeset umount_failed="" - typeset force_umount="" - typeset self_fence="" - typeset fstype="" - - - # - # Get the mount point, if it exists. If not, no need to continue. - # - mp=${OCF_RESKEY_mountpoint} - case "$mp" in - ""|"[ ]*") # nothing to mount - return $SUCCESS - ;; - /*) # found it - ;; - *) # invalid format - ocf_log err \ -"stopFilesystem: Invalid mount point format (must begin with a '/'): '$mp'" - return $FAIL - ;; - esac - - # - # Get the device - # - dev=$(real_device $OCF_RESKEY_device) - if [ -z "$dev" ]; then - ocf_log err "\ -stop: Could not match $OCF_RESKEY_device with a real device" - return $FAIL - fi - - - # - # Get the force unmount setting if there is a mount point. - # - if [ -n "$mp" ]; then - case ${OCF_RESKEY_force_unmount} in - $YES_STR) force_umount=$YES ;; - 1) force_umount=$YES ;; - *) force_umount="" ;; - esac - fi - - if [ -n "$mp" ]; then - case ${OCF_RESKEY_self_fence} in - $YES_STR) self_fence=$YES ;; - 1) self_fence=$YES ;; - *) self_fence="" ;; - esac - fi - - # - # Check the rgmanager-supplied reference count if one exists. - # If the reference count is <= 1, we can safely proceed - # - if [ -n "$OCF_RESKEY_RGMANAGER_meta_refcnt" ]; then - refs=$OCF_RESKEY_RGMANAGER_meta_refcnt - if [ $refs -gt 1 ]; then - ((refs--)) - ocf_log debug "Not unmounting $OCF_RESOURCE_INSTANCE - still in use by $refs other service(s)" - return $OCF_SUCCESS - fi - fi - - # - # Always do this hackery on clustered file systems. - # - if [ "$OCF_RESKEY_nfslock" = "yes" ] || \ - [ "$OCF_RESKEY_nfslock" = "1" ]; then - ocf_log warning "Dropping node-wide NFS locks" - mkdir -p $mp/.clumanager/statd - pkill -KILL -x lockd - # Copy out the notify list; our - # IPs are already torn down - if notify_list_store $mp/.clumanager/statd; then - notify_list_broadcast $mp/.clumanager/statd - fi - fi - - # Always invalidate buffers on clusterfs resources - clubufflush -f $dev - - if [ -z "$force_umount" ]; then - ocf_log debug "Not umounting $dev (clustered file system)" - return $SUCCESS - fi - - # - # Unmount the device. - # - while [ ! "$done" ]; do - isMounted $dev $mp - case $? in - $NO) - ocf_log info "$dev is not mounted" - umount_failed= - done=$YES - ;; - $FAIL) - return $FAIL - ;; - $YES) - sync; sync; sync - ocf_log info "unmounting $dev ($mp)" - - umount $mp - ret_val=$? - if [ $ret_val -eq 0 ]; then - umount_failed= - done=$YES - continue - fi - - umount_failed=yes - - if [ "$force_umount" ]; then - if [ $try -eq 1 ]; then - fuser -TERM -kvm "$mp" - else - fuser -kvm "$mp" - fi - fi - - ;; - *) - return $FAIL - ;; - esac - - if [ $try -ge $max_tries ]; then - done=$YES - else - sleep $sleep_time - let try=try+1 - fi - done # while - - if [ -n "$umount_failed" ]; then - ocf_log err "'umount $mp' failed, error=$ret_val" - - if [ "$self_fence" ]; then - ocf_log alert "umount failed - REBOOTING" - sync - reboot -fn - fi - return $FAIL - fi - - return $SUCCESS -} - - -case $1 in -start) - declare tries=0 - declare rv - - while [ $tries -lt 3 ]; do - startFilesystem - rv=$? - if [ $rv -eq 0 ]; then - exit 0 - fi - - ((tries++)) - sleep 3 - done - exit $rv - ;; -stop) - stopFilesystem - exit $? - ;; -status|monitor) - isMounted ${OCF_RESKEY_device} ${OCF_RESKEY_mountpoint} - [ $? -ne $YES ] && exit $OCF_ERR_GENERIC - - isAlive ${OCF_RESKEY_mountpoint} - [ $? -ne $YES ] && exit $OCF_ERR_GENERIC - - exit 0 - ;; -restart) - stopFilesystem - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - startFilesystem - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - exit 0 - ;; -meta-data) - meta_data - exit 0 - ;; -verify-all) - verify_all - ;; -*) - echo "usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac - -exit 0 diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl deleted file mode 100644 index 35e0964..0000000 --- a/rgmanager/src/resources/default_event_script.sl +++ /dev/null @@ -1,316 +0,0 @@ -define node_in_set(node_list, node) -{ - variable x, len; - - len = length(node_list); - for (x = 0; x < len; x++) { - if (node_list[x] == node) - return 1; - } - - return 0; -} - - -define move_or_start(service, node_list) -{ - variable len; - variable state, owner; - variable depends; - - depends = service_property(service, "depend"); - if (depends != "") { - (,,, owner, state) = service_status(depends); - if (owner < 0) { - debug(service, " is not runnable; dependency not met"); - return ERR_DEPEND; - } - } - - (,,, owner, state) = service_status(service); - debug("Evaluating ", service, " state=", state, " owner=", owner); - - len = length(node_list); - if (len == 0) { - notice(service, " is not runnable - restricted domain offline"); - ()=service_stop(service); - return ERR_DOMAIN; - } - - if (((event_type != EVENT_USER) and (state == "disabled")) or (state == "failed")) { - % - % Commenting out this block will -not- allow you to - % recover failed services from event scripts. Sorry. - % All it will get you is a false log message about - % starting this service. - % - % You may enable disabled services, but I recommend - % against it. - % - debug(service, " is not runnable"); - return -1; - } - - if (node_list[0] == owner) { - debug(service, " is already running on best node"); - return ERR_RUNNING; - } - - if ((owner >= 0) and (node_in_set(node_list, owner) == 1)) { - notice("Moving ", service, " from ", owner, - " to ", node_list); - if (service_stop(service) < 0) { - return ERR_ABORT; - } - } else { - notice("Starting ", service, " on ", node_list); - } - - return service_start(service, node_list); -} - - -% -% Returns the set of online nodes in preferred/shuffled order which -% are allowed to run this service. Gives highest preference to current -% owner if nofailback is specified. -% -define allowed_nodes(service) -{ - variable anodes; - variable online; - variable nodes_domain; - variable ordered, restricted, nofailback; - variable state, owner; - variable depends; - - (nofailback, restricted, ordered, nodes_domain) = - service_domain_info(service); - - (,,, owner, state) = service_status(service); - - anodes = nodes_online(); - - % Shuffle the array so we don't start all services on the same - % node. TODO - add RR, Least-services, placement policies... - online = shuffle(anodes); - - if (restricted == 1) { - anodes = intersection(nodes_domain, online); - } else { - % Ordered failover domains (nodes_domain) unioned with the - % online nodes basically just reorders the online node list - % according to failover domain priority rules. - anodes = union(intersection(nodes_domain, online), - online); - } - - if ((nofailback == 1) or (ordered == 0)) { - - if ((owner < 0) or (node_in_set(anodes, owner) == 0)) { - return anodes; - } - - % Because union takes left as priority, we can - % return the union of the current owner with the - % allowed node list. This means the service will - % remain on the same node it's currently on. - return union(owner, anodes); - } - - return anodes; -} - - -define default_node_event_handler() -{ - variable services = service_list(); - variable x; - variable nodes; - - % debug("Executing default node event handler"); - for (x = 0; x < length(services); x++) { - nodes = allowed_nodes(services[x]); - ()=move_or_start(services[x], nodes); - } -} - - -define default_service_event_handler() -{ - variable services = service_list(); - variable x; - variable depends; - variable depend_mode; - variable policy; - variable nodes; - variable tmp; - variable owner; - variable state; - - % debug("Executing default service event handler"); - - if (service_state == "recovering") { - - policy = service_property(service_name, "recovery"); - debug("Recovering", - " Service: ", service_name, - " Last owner: ", service_last_owner, - " Policy: ", policy, - " RTE: ", service_restarts_exceeded); - - if (policy == "disable") { - () = service_stop(service_name, 1); - return; - } - - nodes = allowed_nodes(service_name); - if (policy == "restart" and service_restarts_exceeded == 0) { - nodes = union(service_last_owner, nodes); - } else { - % relocate - tmp = subtract(nodes, service_last_owner); - if (length(tmp) == 0) { - () = service_stop(service_name,0); - return; - } - - nodes = union(tmp, service_last_owner); - } - - ()=move_or_start(service_name, nodes); - - return; - } - - for (x = 0; x < length(services); x++) { - if (service_name == services[x]) { - % don't do anything to ourself! - continue; - } - - % - % Simplistic dependency handling - % - depends = service_property(services[x], "depend"); - depend_mode = service_property(services[x], "depend_mode"); - - % No dependency; do nothing - if (depends != service_name) { - continue; - } - - (,,, owner, state) = service_status(services[x]); - if ((service_state == "started") and (owner < 0) and - (state == "stopped")) { - info("Dependency met; starting ", services[x]); - nodes = allowed_nodes(services[x]); - ()=move_or_start(services[x], nodes); - } - - % service died - stop service(s) that depend on the dead - if ((service_owner < 0) and (owner >= 0) and - (depend_mode != "soft")) { - info("Dependency lost; stopping ", services[x]); - ()=service_stop(services[x]); - } - } -} - -define default_config_event_handler() -{ - % debug("Executing default config event handler"); -} - -define default_user_event_handler() -{ - variable ret; - variable nodes; - variable reordered; - variable x; - variable target = user_target; - variable found = 0; - variable owner, state; - - nodes = allowed_nodes(service_name); - (,,, owner, state) = service_status(service_name); - - if (user_request == USER_RESTART) { - - if (owner >= 0) { - reordered = union(owner, nodes); - nodes = reordered; - } - - notice("Stopping ", service_name, " for relocate to ", nodes); - - found = service_stop(service_name); - if (found < 0) { - return ERR_ABORT; - } - - ret = move_or_start(service_name, nodes); - - } else if ((user_request == USER_RELOCATE) or - (user_request == USER_ENABLE)) { - - if (user_target > 0) { - for (x = 0; x < length(nodes); x++) { - % - % Put the preferred node at the front of the - % list for a user-relocate operation - % - if (nodes[x] == user_target) { - reordered = union(user_target, nodes); - nodes = reordered; - found = 1; - } - } - - if (found == 0) { - warning("User specified node ", user_target, - " is offline"); - } - } - - if ((owner >= 0) and (user_request == USER_RELOCATE)) { - if (service_stop(service_name) < 0) { - return ERR_ABORT; - } - - % - % The current owner shouldn't be the default - % for a relocate operation - % - reordered = subtract(nodes, owner); - nodes = union(reordered, owner); - } - - ret = move_or_start(service_name, nodes); - - } else if (user_request == USER_DISABLE) { - - ret = service_stop(service_name, 1); - - } else if (user_request == USER_STOP) { - - ret = service_stop(service_name); - - } - - % - % todo - migrate - % - - return ret; -} - -if (event_type == EVENT_NODE) - default_node_event_handler(); -if (event_type == EVENT_SERVICE) - default_service_event_handler(); -if (event_type == EVENT_CONFIG) - default_config_event_handler(); -if (event_type == EVENT_USER) - user_return=default_user_event_handler(); - diff --git a/rgmanager/src/resources/fs.sh b/rgmanager/src/resources/fs.sh deleted file mode 100755 index 046aa65..0000000 --- a/rgmanager/src/resources/fs.sh +++ /dev/null @@ -1,1203 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2002-2004, 2009 -# Copyright Mission Critical Linux, Inc. 2000 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# File system (normal) mount/umount/fsck/etc. agent -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -# -# XXX todo - search and replace on these -# -SUCCESS=0 -FAIL=2 -YES=0 -NO=1 -YES_STR="yes" -INVALIDATEBUFFERS="/bin/true" - -# -# Using a global to contain the return value saves -# clone() operations. This is important to reduce -# resource consumption during status checks. -# -# There is no way to return a string from a function -# in bash without cloning the process, which is exactly -# what we are trying to avoid. So, we have to resort -# to using a dedicated global variable. This one is -# for the real_device() function below. -# -declare REAL_DEVICE - -# -# Stub ocf_log function for when we are using -# quick_status, since ocf_log generally forks (and -# sourcing ocf-shellfuncs forks -a lot-). -# -ocf_log() -{ - echo $* -} - -# -# Assume NFS_TRICKS are not available until we are -# proved otherwise. -# -export NFS_TRICKS=1 - -# -# Quick status doesn't fork() or clone() when using -# device files directly. (i.e. not symlinks, LABEL= or -# UUID= -# -if [ "$1" = "status" -o "$1" = "monitor" ] && - [ "$OCF_RESKEY_quick_status" = "1" ]; then - echo Using Quick Status - - # XXX maybe we can make ocf-shellfuncs have a 'quick' mode too? - export OCF_SUCCESS=0 - export OCF_ERR_GENERIC=1 -else - # - # Grab nfs lock tricks if available - # - if [ -f "$(dirname $0)/svclib_nfslock" ]; then - . $(dirname $0)/svclib_nfslock - NFS_TRICKS=0 - fi - - . $(dirname $0)/ocf-shellfuncs -fi - -meta_data() -{ - cat <<EOT -<?xml version="1.0" encoding="ISO-8859-1" ?> -<resource-agent name="fs" version="rgmanager 2.0"> - <version>1.0</version> - - <longdesc lang="en"> - This defines a standard file system mount (= not a clustered - or otherwise shared file system). - </longdesc> - <shortdesc lang="en"> - Defines a file system mount. - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Symbolic name for this file system. - </longdesc> - <shortdesc lang="en"> - File System Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="mountpoint" unique="1" required="1"> - <longdesc lang="en"> - Path in file system heirarchy to mount this file system. - </longdesc> - <shortdesc lang="en"> - Mount Point - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="device" unique="1" required="1"> - <longdesc lang="en"> - Block device, file system label, or UUID of file system. - </longdesc> - <shortdesc lang="en"> - Device or Label - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="fstype"> - <longdesc lang="en"> - File system type. If not specified, mount(8) will attempt to - determine the file system type. - </longdesc> - <shortdesc lang="en"> - File system type - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="force_unmount"> - <longdesc lang="en"> - If set, the cluster will kill all processes using - this file system when the resource group is - stopped. Otherwise, the unmount will fail, and - the resource group will be restarted. - </longdesc> - <shortdesc lang="en"> - Force Unmount - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="quick_status"> - <longdesc lang="en"> - Use quick status checks. When set to 0 (the default), this - agent behaves normally. When set to 1, this agent will not - log errors incurred or perform the file system accessibility - check (e.g. it will not try to read from/write to the file - system). You should only set this to 1 if you have lots of - file systems on your cluster or you are seeing very high load - spikes as a direct result of this agent. - </longdesc> - <shortdesc lang="en"> - Quick/brief status checks. - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="self_fence"> - <longdesc lang="en"> - If set and unmounting the file system fails, the node will - immediately reboot. Generally, this is used in conjunction - with force-unmount support, but it is not required. - </longdesc> - <shortdesc lang="en"> - Seppuku Unmount - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="nfslock" inherit="service%nfslock"> - <longdesc lang="en"> - If set and unmounting the file system fails, the node will - try to kill lockd and issue reclaims across all remaining - network interface cards. - </longdesc> - <shortdesc lang="en"> - Enable NFS lock workarounds - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="fsid"> - <longdesc lang="en"> - File system ID for NFS exports. This can be overridden - in individual nfsclient entries. - </longdesc> - <shortdesc lang="en"> - NFS File system ID - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="force_fsck"> - <longdesc lang="en"> - If set, the file system will be checked (even if - it is a journalled file system). This option is - ignored for non-journalled file systems such as - ext2. - </longdesc> - <shortdesc lang="en"> - Force fsck support - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="options"> - <longdesc lang="en"> - Options used when the file system is mounted. These - are often file-system specific. See mount(8) for supported - mount options. - </longdesc> - <shortdesc lang="en"> - Mount Options - </shortdesc> - <content type="string"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="900"/> - <action name="stop" timeout="30"/> - <!-- Recovery isn't possible; we don't know if resources are using - the file system. --> - - <!-- Checks to see if it's mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Note: active monitoring is constant and supplants all - check depths --> - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="30"/> - <action name="monitor" depth="10" timeout="30" interval="30"/> - - <!-- Checks to see if we can write to the mountpoint (if !ROFS) --> - <action name="status" depth="20" timeout="30" interval="1m"/> - <action name="monitor" depth="20" timeout="30" interval="1m"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="5"/> - </actions> - - <special tag="rgmanager"> - <attributes maxinstances="1"/> - <child type="fs" start="1" stop="3"/> - <child type="clusterfs" start="1" stop="3"/> - <child type="nfsexport" start="3" stop="1"/> - </special> -</resource-agent> -EOT -} - -verify_name() -{ - if [ -z "$OCF_RESKEY_name" ]; then - ocf_log err "No file system name specified." - return $OCF_ERR_ARGS - fi - return $OCF_SUCCESS -} - - -verify_mountpoint() -{ - if [ -z "$OCF_RESKEY_mountpoint" ]; then - ocf_log err "No mount point specified." - return $OCF_ERR_ARGS - fi - - if ! [ -e "$OCF_RESKEY_mountpoint" ]; then - ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "\ - "created at mount time." - return $OCF_SUCCESS - fi - - [ -d "$OCF_RESKEY_mountpoint" ] && return $OCF_SUCCESS - - ocf_log err "$OCF_RESKEY_mountpoint exists but is not a directory." - - return $OCF_ERR_ARGS -} - - -# -# This used to be called using $(...), but doing this causes bash -# to set up a pipe and clone(). So, the output of this function is -# stored in the global variable REAL_DEVICE, declared previously. -# -real_device() -{ - declare dev=$1 - declare realdev - - REAL_DEVICE="" - - [ -z "$dev" ] && return $OCF_ERR_ARGS - - # If our provided blockdev is a device, we are done - if [ -b "$dev" ]; then - REAL_DEVICE="$dev" - return $OCF_SUCCESS - fi - - # Oops, we have a link. Sorry, this is going to fork. - if [ -h "$dev" ]; then - realdev=$(readlink -f $dev) - if [ $? -ne 0 ]; then - return $OCF_ERR_ARGS - fi - REAL_DEVICE="$realdev" - return $OCF_SUCCESS - fi - - # It's not a link, it's not a block device. If it also - # does not match UUID= or LABEL=, then findfs is not - # going to find anything useful, so we should quit now. - if [ "${dev/UUID=/}" = "$dev" ] && - [ "${dev/LABEL=/}" = "$dev" ]; then - return $OCF_ERR_GENERIC - fi - - # When using LABEL= or UUID=, we can't save a fork. - realdev=$(findfs $dev 2> /dev/null) - if [ -n "$realdev" ] && [ -b "$realdev" ]; then - REAL_DEVICE="$realdev" - return $OCF_SUCCESS - fi - - return $OCF_ERR_GENERIC -} - - -verify_device() -{ - declare realdev - - if [ -z "$OCF_RESKEY_device" ]; then - ocf_log err "No device or label specified." - return $OCF_ERR_ARGS - fi - - real_device $OCF_RESKEY_device - realdev=$REAL_DEVICE - if [ -n "$realdev" ]; then - if [ "$realdev" != "$OCF_RESKEY_device" ]; then - ocf_log info "Specified $OCF_RESKEY_device maps to $realdev" - fi - return $OCF_SUCCESS - fi - - ocf_log err "Device or label "$OCF_RESKEY_device" not valid" - - return $OCF_ERR_ARGS -} - - -verify_fstype() -{ - # Auto detect? - [ -z "$OCF_RESKEY_fstype" ] && return 0 - - case $OCF_RESKEY_fstype in - ext2|ext3|jfs|xfs|reiserfs|vfat|tmpfs|vxfs) - return 0 - ;; - *) - echo "File system type $OCF_RESKEY_fstype not supported" - return $OCF_ERR_ARGS - ;; - esac -} - - -verify_options() -{ - declare -i ret=$OCF_SUCCESS - declare o - - # - # From mount(8) - # - for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do - case $o in - async|atime|auto|defaults|dev|exec|_netdev|noatime) - continue - ;; - noauto|nodev|noexec|nosuid|nouser|ro|rw|suid|sync) - continue - ;; - dirsync|user|users) - continue - ;; - esac - - case $OCF_RESKEY_fstype in - ext2|ext3) - case $o in - bsddf|minixdf|check|check=*|nocheck|debug) - continue - ;; - errors=*|grpid|bsdgroups|nogrpid|sysvgroups) - continue - ;; - resgid=*|resuid=*|sb=*|grpquota|noquota) - continue - ;; - quota|usrquota|nouid32) - continue - ;; - esac - - if [ "$OCF_RESKEY_fstype" = "ext3" ]; then - case $0 in - noload|data=*) - continue - ;; - esac - fi - ;; - vfat) - case $o in - blocksize=512|blocksize=1024|blocksize=2048) - continue - ;; - uid=*|gid=*|umask=*|dmask=*|fmask=*) - continue - ;; - check=r*|check=n*|check=s*|codepage=*) - continue - ;; - conv=b*|conv=t*|conv=a*|cvf_format=*) - continue - ;; - cvf_option=*|debug|fat=12|fat=16|fat=32) - continue - ;; - iocharset=*|quiet) - continue - ;; - esac - ;; - - jfs) - case $o in - conv|hash=rupasov|hash=tea|hash=r5|hash=detect) - continue - ;; - hashed_relocation|no_unhashed_relocation) - continue - ;; - noborder|nolog|notail|resize=*) - continue - ;; - esac - ;; - - xfs) - case $o in - biosize=*|dmapi|xdsm|logbufs=*|logbsize=*) - continue - ;; - logdev=*|rtdev=*|noalign|noatime) - continue - ;; - norecovery|osyncisdsync|quota|userquota) - continue - ;; - uqnoenforce|grpquota|gqnoenforce) - continue - ;; - sunit=*|swidth=*) - continue - ;; - esac - ;; - - tmpfs) - case $o in - size=*|nr_blocks=*|mode=*) - continue - ;; - esac - ;; - esac - - echo Option $o not supported for $OCF_RESKEY_fstype - ret=$OCF_ERR_ARGS - done - - return $ret -} - - -verify_all() -{ - verify_name || return $OCF_ERR_ARGS - verify_fstype || return $OCF_ERR_ARGS - verify_device || return $OCF_ERR_ARGS - verify_mountpoint || return $OCF_ERR_ARGS - verify_options || return $OCF_ERR_ARGS -} - - -# -# mountInUse device mount_point -# -# Check to see if either the device or mount point are in use anywhere on -# the system. It is not required that the device be mounted on the named -# moint point, just if either are in use. -# -mountInUse () { - typeset mp tmp_mp - typeset dev tmp_dev - typeset junka junkb junkc junkd - - if [ $# -ne 2 ]; then - ocf_log err "Usage: mountInUse device mount_point". - return $FAIL - fi - - dev=$1 - mp=$2 - - while read tmp_dev tmp_mp junka junkb junkc junkd; do - if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then - return $YES - fi - - if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then - return $YES - fi - done < /proc/mounts - - return $NO -} - - -# -# isMounted device mount_point -# -# Check to see if the device is mounted. Print a warning if its not -# mounted on the directory we expect it to be mounted on. -# -isMounted () { - - typeset mp tmp_mp - typeset dev tmp_dev - typeset ret=$FAIL - typeset found=1 - typeset poss_mp - - if [ $# -ne 2 ]; then - ocf_log err "Usage: isMounted device mount_point" - return $FAIL - fi - - real_device $1 - dev=$REAL_DEVICE - if [ -z "$dev" ]; then - ocf_log err \ - "fs (isMounted): Could not match $1 with a real device" - return $OCF_ERR_ARGS - fi - - if [ -h "$2" ]; then - mp=$(readlink -f $2) - else - mp=$2 - fi - - ret=$NO - - while read tmp_dev tmp_mp junk_a junk_b junk_c junk_d - do - real_device $tmp_dev - tmp_dev=$REAL_DEVICE - - # This bash glyph simply removes a trailing slash - # if one exists. /a/b/ -> /a/b; /a/b -> /a/b. - tmp_mp=${tmp_mp%/} - mp=${mp%/} - - if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then - # - # Check to see if its mounted in the right - # place - # - if [ -n "$tmp_mp" ]; then - if [ "$tmp_mp" != "$mp" ]; then - poss_mp=$tmp_mp - else - found=0 - fi - fi - ret=$YES - fi - done < /proc/mounts - - if [ $ret -eq $YES ] && [ $found -ne 0 ]; then - ocf_log warn "Device $dev is mounted on $poss_mp instead of $mp" - fi - - return $ret -} - - -# -# isAlive mount_point -# -# Check to see if mount_point is alive (testing read/write) -# -isAlive() -{ - declare errcode - declare mount_point - declare file=".writable_test" - declare rw - - if [ $# -ne 1 ]; then - ocf_log err "Usage: isAlive mount_point" - return $FAIL - fi - mount_point=$1 - - test -d $mount_point - if [ $? -ne 0 ]; then - ocf_log err "fs (isAlive): $mount_point is not a directory" - return $FAIL - fi - - [ $OCF_CHECK_LEVEL -lt 10 ] && return $YES - - # depth 10 test (read test) - ls $mount_point > /dev/null 2> /dev/null - errcode=$? - if [ $errcode -ne 0 ]; then - ocf_log err "fs:${OCF_RESKEY_name}: isAlive failed read test on [$mount_point]. Return code: $errcode" - return $NO - fi - - [ $OCF_CHECK_LEVEL -lt 20 ] && return $YES - - # depth 20 check (write test) - rw=$YES - for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do - if [ "$o" = "ro" ]; then - rw=$NO - fi - done - if [ $rw -eq $YES ]; then - file=$mount_point/$file - while true; do - if [ -e "$file" ]; then - file=${file}_tmp - continue - else - break - fi - done - touch $file > /dev/null 2> /dev/null - errcode=$? - if [ $errcode -ne 0 ]; then - ocf_log err "fs:${OCF_RESKEY_name}: isAlive failed write test on [$mount_point]. Return code: $errcode" - return $NO - fi - rm -f $file > /dev/null 2> /dev/null - fi - - return $YES -} - - -# -# Decide which quota options are enabled and return a string -# which we can pass to quotaon -# -quota_opts() -{ - declare quotaopts="" - declare opts=$1 - declare mopt - - for mopt in `echo $opts | sed -e s/,/\ /g`; do - case $mopt in - usrquota) - quotaopts="u$quotaopts" - continue - ;; - grpquota) - quotaopts="g$quotaopts" - continue - ;; - noquota) - quotaopts="" - return 0 - ;; - esac - done - - echo $quotaopts - return 0 -} - - - -# -# Enable quotas on the mount point if the user requested them -# -enable_fs_quotas() -{ - declare -i need_check=0 - declare -i rv - declare quotaopts="" - declare mopt - declare opts=$1 - declare mp=$2 - - if [ -z "`which quotaon`" ]; then - ocf_log err "quotaon not found in $PATH" - return $OCF_ERR_GENERIC - fi - - quotaopts=$(quota_opts $opts) - - ocf_log info "quotaopts = $quotaopts" - - [ -z "$quotaopts" ] && return 0 - - # Ok, create quota files if they don't exist - for f in quota.user aquota.user quota.group aquota.group; do - if ! [ -f "$mp/$f" ]; then - ocf_log info "$mp/$f was missing - creating" - touch "$mp/$f" - chmod 600 "$mp/$f" - need_check=1 - fi - done - - if [ $need_check -eq 1 ]; then - ocf_log info "Checking quota info in $mp" - quotacheck -$quotaopts $mp - fi - - ocf_log info "Enabling Quotas on $mp" - ocf_log debug "quotaon -$quotaopts $mp" - quotaon -$quotaopts $mp - rv=$? - if [ $rv -ne 0 ]; then - # Just a warning - ocf_log warn "Unable to turn on quotas for $mp; return = $rv" - fi - - return $rv -} - - -# -# startFilesystem -# -startFilesystem() { - typeset -i ret_val=$SUCCESS - typeset mp="" # mount point - typeset dev="" # device - typeset fstype="" - typeset opts="" - typeset device_in_use="" - typeset mount_options="" - - # - # Get the mount point, if it exists. If not, no need to continue. - # - mp=${OCF_RESKEY_mountpoint} - case "$mp" in - ""|"[ ]*") # nothing to mount - return $OCF_SUCCESS - ;; - /*) # found it - ;; - *) # invalid format - ocf_log err \ -"startFilesystem: Invalid mount point format (must begin with a '/'): '$mp'" - return $OCF_ERR_ARGS - ;; - esac - - # - # Get the device - # - real_device $OCF_RESKEY_device - dev=$REAL_DEVICE - if [ -z "$dev" ]; then - ocf_log err "\ -startFilesystem: Could not match $OCF_RESKEY_device with a real device" - return $OCF_ERR_ARGS - fi - - # - # Ensure we've got a valid directory - # - if [ -e "$mp" ]; then - if ! [ -d "$mp" ]; then - ocf_log err"\ -startFilesystem: Mount point $mp exists but is not a directory" - return $OCF_ERR_ARGS - fi - else - ocf_log err "\ -startFilesystem: Creating mount point $mp for device $dev" - mkdir -p $mp - fi - - # - # Get the filesystem type, if specified. - # - fstype_option="" - fstype=${OCF_RESKEY_fstype} - case "$fstype" in - ""|"[ ]*") - fstype="" - ;; - *) # found it - fstype_option="-t $fstype" - ;; - esac - - # - # See if the device is already mounted. - # - isMounted $dev $mp - case $? in - $YES) # already mounted - ocf_log debug "$dev already mounted" - return $OCF_SUCCESS - ;; - $NO) # not mounted, continue - ;; - *) - return $FAIL - ;; - esac - - - # - # Make sure that neither the device nor the mount point are mounted - # (i.e. they may be mounted in a different location). The'mountInUse' - # function checks to see if either the device or mount point are in - # use somewhere else on the system. - # - mountInUse $dev $mp - case $? in - $YES) # uh oh, someone is using the device or mount point - ocf_log err "\ -Cannot mount $dev on $mp, the device or mount point is already in use!" - return $FAIL - ;; - $NO) # good, no one else is using it - ;; - $FAIL) - return $FAIL - ;; - *) - ocf_log err "Unknown return from mountInUse" - return $FAIL - ;; - esac - - # - # Make sure the mount point exists. - # - if [ ! -d $mp ]; then - rm -f $mp # rm in case its a plain file - mkdir -p $mp # create the mount point - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err \ - "'mkdir -p $mp' failed, error=$ret_val" - return $FAIL - fi - fi - - # - # Get the mount options, if they exist. - # - mount_options="" - opts=${OCF_RESKEY_options} - case "$opts" in - ""|"[ ]*") - opts="" - ;; - *) # found it - mount_options="-o $opts" - ;; - esac - - - # - # Check to determine if we need to fsck the filesystem. - # - # Note: this code should not indicate in any manner suggested - # file systems to use in the cluster. Known filesystems are - # listed here for correct operation. - # - case "$fstype" in - reiserfs) typeset fsck_needed="" ;; - ext3) typeset fsck_needed="" ;; - jfs) typeset fsck_needed="" ;; - xfs) typeset fsck_needed="" ;; - ext2) typeset fsck_needed=yes ;; - minix) typeset fsck_needed=yes ;; - vfat) typeset fsck_needed=yes ;; - msdos) typeset fsck_needed=yes ;; - "") typeset fsck_needed=yes ;; # assume fsck - *) - typeset fsck_needed=yes # assume fsck - ocf_log warn "\ -Unknown file system type '$fstype' for device $dev. Assuming fsck is required." - ;; - esac - - - # - # Fsck the device, if needed. - # - if [ -n "$fsck_needed" ] || [ "${OCF_RESKEY_force_fsck}" = "yes" ] ||\ - [ "${OCF_RESKEY_force_fsck}" = "1" ]; then - typeset fsck_log=$(mktemp /tmp/fs-$OCF_RESKEY_name.fsck.log.XXXXXX) - ocf_log debug "Running fsck on $dev" - fsck -p $dev >> $fsck_log 2>&1 - ret_val=$? - if [ $ret_val -gt 1 ]; then - ocf_log err "\ -'fsck -p $dev' failed, error=$ret_val; check $fsck_log for errors" - ocf_log debug "Invalidating buffers for $dev" - $INVALIDATEBUFFERS -f $dev - return $FAIL - fi - rm -f $fsck_log - fi - - # - # Mount the device - # - ocf_log info "mounting $dev on $mp" - ocf_log debug "mount $fstype_option $mount_options $dev $mp" - mount $fstype_option $mount_options $dev $mp - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err "\ -'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val" - return $FAIL - fi - - # - # Create this for the NFS NLM broadcast bit - # - if [ $NFS_TRICKS -eq 0 ]; then - if [ "$OCF_RESKEY_nfslock" = "yes" ] || \ - [ "$OCF_RESKEY_nfslock" = "1" ]; then - mkdir -p $mp/.clumanager/statd - notify_list_merge $mp/.clumanager/statd - fi - fi - - enable_fs_quotas $opts $mp - - return $SUCCESS -} - - -# -# stopFilesystem serviceID deviceID -# -# Run the stop actions -# -stopFilesystem() { - typeset -i ret_val=0 - typeset -i try=1 - typeset -i max_tries=3 # how many times to try umount - typeset -i sleep_time=5 # time between each umount failure - typeset -i nfslock_reclaim=0 - typeset done="" - typeset umount_failed="" - typeset force_umount="" - typeset self_fence="" - typeset fstype="" - typeset quotaopts="" - - - # - # Get the mount point, if it exists. If not, no need to continue. - # - mp=${OCF_RESKEY_mountpoint} - case "$mp" in - ""|"[ ]*") # nothing to mount - return $SUCCESS - ;; - /*) # found it - ;; - *) # invalid format - ocf_log err \ -"stopFilesystem: Invalid mount point format (must begin with a '/'): '$mp'" - return $FAIL - ;; - esac - - - # - # Get the device - # - real_device $OCF_RESKEY_device - dev=$REAL_DEVICE - if [ -z "$dev" ]; then - ocf_log err "\ -stop: Could not match $OCF_RESKEY_device with a real device" - return $FAIL - fi - - # - # Get the force unmount setting if there is a mount point. - # - if [ -n "$mp" ]; then - case ${OCF_RESKEY_force_unmount} in - $YES_STR) force_umount=$YES ;; - 1) force_umount=$YES ;; - *) force_umount="" ;; - esac - fi - - if [ -n "$mp" ]; then - case ${OCF_RESKEY_self_fence} in - $YES_STR) self_fence=$YES ;; - 1) self_fence=$YES ;; - *) self_fence="" ;; - esac - fi - - # - # Unmount the device. - # - while [ ! "$done" ]; do - isMounted $dev $mp - case $? in - $NO) - ocf_log info "$dev is not mounted" - umount_failed= - done=$YES - ;; - $FAIL) - return $FAIL - ;; - $YES) - sync; sync; sync - quotaopts=$(quota_opts $OCF_RESKEY_options) - if [ -n "$quotaopts" ]; then - ocf_log debug "Turning off quotas for $mp" - quotaoff -$quotaopts $mp &> /dev/null - fi - - - ocf_log info "unmounting $mp" - umount $mp - ret_val=$? - if [ $ret_val -eq 0 ]; then - umount_failed= - done=$YES - continue - fi - - umount_failed=yes - - if [ "$force_umount" ]; then - if [ $try -eq 1 ]; then - fuser -TERM -kvm "$mp" - - if [ "$OCF_RESKEY_nfslock" = "yes" ] || \ - [ "$OCF_RESKEY_nfslock" = "1" ]; then - ocf_log warning \ - "Dropping node-wide NFS locks" - pkill -KILL -x lockd - mkdir -p $mp/.clumanager/statd - # Copy out the notify list; our - # IPs are already torn down - notify_list_store $mp/.clumanager/statd - nfslock_reclaim=1 - fi - else - fuser -kvm "$mp" - fi - fi - - ;; - *) - return $FAIL - ;; - esac - - if [ $try -ge $max_tries ]; then - done=$YES - elif [ "$done" != "$YES" ]; then - sleep $sleep_time - let try=try+1 - fi - done # while - - if [ $nfslock_reclaim -eq 1 ]; then - # If we have this flag set, do a full reclaim broadcast - notify_list_broadcast $mp/.clumanager/statd - fi - - if [ -n "$umount_failed" ]; then - ocf_log err "'umount $mp' failed, error=$ret_val" - - if [ "$self_fence" ]; then - ocf_log alert "umount failed - REBOOTING" - sync - reboot -fn - fi - return $FAIL - else - return $SUCCESS - fi -} - - -case $1 in -start) - startFilesystem - exit $? - ;; -stop) - stopFilesystem - exit $? - ;; -status|monitor) - isMounted ${OCF_RESKEY_device} ${OCF_RESKEY_mountpoint} - - if [ $? -ne $YES ]; then - ocf_log err "fs:${OCF_RESKEY_name}: ${OCF_RESKEY_device} is not mounted on ${OCF_RESKEY_mountpoint}" - exit $OCF_ERR_GENERIC - fi - - if [ "$OCF_RESKEY_quick_status" = "1" ]; then - exit 0 - fi - - isAlive ${OCF_RESKEY_mountpoint} - [ $? -eq $YES ] && exit 0 - - ocf_log err "fs:${OCF_RESKEY_name}: Mount point is not accessible!" - exit $OCF_ERR_GENERIC - ;; -restart) - stopFilesystem - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - startFilesystem - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - exit 0 - ;; -meta-data) - meta_data - exit 0 - ;; -verify-all) - verify_all - exit $? - ;; -*) - echo "usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac - -exit 0 diff --git a/rgmanager/src/resources/ip.sh b/rgmanager/src/resources/ip.sh deleted file mode 100755 index 083738b..0000000 --- a/rgmanager/src/resources/ip.sh +++ /dev/null @@ -1,967 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2004 -# Copyright Mission Critical Linux, Inc. 2000 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# IPv4/IPv6 address management using new /sbin/ifcfg instead of -# ifconfig utility. -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -# Grab nfs lock tricks if available -export NFS_TRICKS=1 -if [ -f "$(dirname $0)/svclib_nfslock" ]; then - . $(dirname $0)/svclib_nfslock - NFS_TRICKS=0 -fi - -. $(dirname $0)/ocf-shellfuncs - - -meta_data() -{ - cat <<EOT -<?xml version="1.0" ?> -<resource-agent version="rgmanager 2.0" name="ip"> - <version>1.0</version> - - <longdesc lang="en"> - This is an IP address. Both IPv4 and IPv6 addresses are supported, - as well as NIC link monitoring for each IP address. - </longdesc> - <shortdesc lang="en"> - This is an IP address. - </shortdesc> - - <parameters> - <parameter name="address" unique="1" primary="1"> - <longdesc lang="en"> - IPv4 or IPv6 address to use as a virtual IP - resource. - </longdesc> - - <shortdesc lang="en"> - IP Address - </shortdesc> - - <content type="string"/> - </parameter> - - <parameter name="family"> - <longdesc lang="en"> - IPv4 or IPv6 address protocol family. - </longdesc> - - <shortdesc lang="en"> - Family - </shortdesc> - - <!-- - <val>auto</val> - <val>inet</val> - <val>inet6</val> - --> - <content type="string"/> - </parameter> - - <parameter name="monitor_link"> - <longdesc lang="en"> - Enabling this causes the status check to fail if - the link on the NIC to which this IP address is - bound is not present. - </longdesc> - <shortdesc lang="en"> - Monitor NIC Link - </shortdesc> - <content type="boolean" default="1"/> - </parameter> - - <parameter name="nfslock" inherit="service%nfslock"> - <longdesc lang="en"> - If set and unmounting the file system fails, the node will - try to kill lockd and issue reclaims across all remaining - network interface cards. - </longdesc> - <shortdesc lang="en"> - Enable NFS lock workarounds - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="sleeptime"> - <longdesc lang="en"> - Amount of time to sleep after removing an IP address. - Value is specified in seconds. Default value is 10. - </longdesc> - <shortdesc lang="en"> - Amount of time (seconds) to sleep. - </shortdesc> - <content type="string"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="20"/> - <action name="stop" timeout="20"/> - <!-- No recover action. If the IP address is not useable, then - resources may or may not depend on it. If it's been - deconfigured, resources using it are in a bad state. --> - - <!-- Checks to see if the IP is up and (optionally) the link is - working --> - <action name="status" interval="20" timeout="10"/> - <action name="monitor" interval="20" timeout="10"/> - - <!-- Checks to see if we can ping the IP address locally --> - <action name="status" depth="10" interval="60" timeout="20"/> - <action name="monitor" depth="10" interval="60" timeout="20"/> - - <action name="meta-data" timeout="20"/> - <action name="verify-all" timeout="20"/> - </actions> - - <special tag="rgmanager"> - <attributes maxinstances="1"/> - <child type="nfsclient" forbid="1"/> - <child type="nfsexport" forbid="1"/> - </special> -</resource-agent> -EOT -} - - -verify_address() -{ - # XXX TBD - return 0 -} - - -verify_all() -{ - # XXX TBD - return 0 -} - - -# -# Expand an IPv6 address. -# -ipv6_expand() -{ - typeset addr=$1 - typeset maskbits - typeset -i x - - maskbits=${addr/*//} - if [ "$maskbits" = "$addr" ]; then - maskbits="" - else - # chop off mask bits - addr=${addr//*/} - fi - - # use space as placeholder - addr=${addr/::/\ } - - # get rid of colons - addr=${addr//:/} - - # add in zeroes where the doublecolon was - len=$((${#addr}-1)) - zeroes= - while [ $len -lt 32 ]; do - zeroes="0$zeroes" - ((len++)) - done - addr=${addr/\ /$zeroes} - - # probably a better way to do this - for (( x=0; x < ${#addr} ; x++)); do - naddr=$naddr${addr:x:1} - - if (( x < (${#addr} - 1) && x%4 == 3)); then - naddr=$naddr: - fi - done - - if [ -n "$maskbits" ]; then - echo "$naddr/$maskbits" - return 0 - fi - - echo "$naddr" - return 0 -} - - -# -# see if two ipv6 addrs are in the same subnet -# -ipv6_same_subnet() -{ - declare addrl=$1 - declare addrr=$2 - declare m=$3 - declare r x llsb rlsb - - if [ $# -lt 2 ]; then - ocf_log err "usage: ipv6_same_subnet addr1 addr2 [mask]" - return 255 - fi - - if [ -z "$m" ]; then - m=${addrl/*//} - - [ -n "$m" ] || return 1 - - fi - - if [ "${addrr}" != "${addrr/*//}" ] && - [ "$m" != "${addrr/*//}" ]; then - return 1 - fi - - addrl=${addrl//*/} - if [ ${#addrl} -lt 39 ]; then - addrl=$(ipv6_expand $addrl) - fi - - addrr=${addrr//*/} - if [ ${#addrr} -lt 39 ]; then - addrr=$(ipv6_expand $addrr) - fi - - # Calculate the amount to compare directly - x=$(($m/4+$m/16-(($m%4)==0))) - - # and the remaining number of bits - r=$(($m%4)) - - if [ $r -ne 0 ]; then - # If we have any remaining bits, we will need to compare - # them later. Get them now. - llsb=`printf "%d" 0x${addrl:$x:1}` - rlsb=`printf "%d" 0x${addrr:$x:1}` - - # One less byte to compare directly, please - ((--x)) - fi - - # direct (string comparison) to see if they are equal - if [ "${addrl:0:$x}" != "${addrr:0:$x}" ]; then - return 1 - fi - - case $r in - 0) - return 0 - ;; - 1) - [ $(($llsb & 8)) -eq $(($rlsb & 8)) ] - return $? - ;; - 2) - [ $(($llsb & 12)) -eq $(($rlsb & 12)) ] - return $? - ;; - 3) - [ $(($llsb & 14)) -eq $(($rlsb & 14)) ] - return $? - ;; - esac - - return 1 -} - - -ipv4_same_subnet() -{ - declare addrl=$1 - declare addrr=$2 - declare m=$3 - declare r x llsb rlsb - - if [ $# -lt 2 ]; then - ocf_log err "usage: ipv4_same_subnet current_addr new_addr [maskbits]" - return 255 - fi - - - # - # Chop the netmask off of the ipaddr: - # e.g. 1.2.3.4/22 -> 22 - # - if [ -z "$m" ]; then - m=${addrl/*//} - [ -n "$m" ] || return 1 - fi - - # - # Check to see if there was a subnet mask provided on the - # new IP address. If there was one and it does not match - # our expected subnet mask, we are done. - # - if [ "${addrr}" != "${addrr//*/}" ] && - [ "$m" != "${addrr/*//}" ]; then - return 1 - fi - - # - # Chop off subnet bits for good. - # - addrl=${addrl//*/} - addrr=${addrr//*/} - - # - # Remove '.' characters from dotted decimal notation and save - # in arrays. i.e. - # - # 192.168.1.163 -> array[0] = 192 - # array[1] = 168 - # array[2] = 1 - # array[3] = 163 - # - - let x=0 - for quad in ${addrl//./\ }; do - ip1[((x++))]=$quad - done - - x=0 - for quad in ${addrr//./\ }; do - ip2[((x++))]=$quad - done - - x=0 - - while [ $m -ge 8 ]; do - ((m-=8)) - if [ ${ip1[x]} -ne ${ip2[x]} ]; then - return 1 - fi - ((x++)) - done - - case $m in - 0) - return 0 - ;; - 1) - [ $((${ip1[x]} & 128)) -eq $((${ip2[x]} & 128)) ] - return $? - ;; - 2) - [ $((${ip1[x]} & 192)) -eq $((${ip2[x]} & 192)) ] - return $? - ;; - 3) - [ $((${ip1[x]} & 224)) -eq $((${ip2[x]} & 224)) ] - return $? - ;; - 4) - [ $((${ip1[x]} & 240)) -eq $((${ip2[x]} & 240)) ] - return $? - ;; - 5) - [ $((${ip1[x]} & 248)) -eq $((${ip2[x]} & 248)) ] - return $? - ;; - 6) - [ $((${ip1[x]} & 252)) -eq $((${ip2[x]} & 252)) ] - return $? - ;; - 7) - [ $((${ip1[x]} & 254)) -eq $((${ip2[x]} & 254)) ] - return $? - ;; - esac - - return 1 -} - - -ipv6_list_interfaces() -{ - declare idx dev ifaddr - declare ifaddr_exp - - while read idx dev ifaddr; do - - isSlave $dev - if [ $? -ne 2 ]; then - continue - fi - - idx=${idx/:/} - - ifaddr_exp=$(ipv6_expand $ifaddr) - - echo $dev ${ifaddr_exp//*/} ${ifaddr_exp/*//} - - done < <(/sbin/ip -o -f inet6 addr | awk '{print $1,$2,$4}') - - return 0 -} - - -# -# Find slaves for a bonded interface -# -findSlaves() -{ - declare mastif=$1 - declare line - declare intf - declare interfaces - - if [ -z "$mastif" ]; then - ocf_log err "usage: findSlaves <master I/F>" - return $OCF_ERR_ARGS - fi - - line=$(/sbin/ip link list dev $mastif | grep "<.*MASTER.*>") - if [ $? -ne 0 ]; then - ocf_log err "Error determining status of $mastif" - return $OCF_ERR_GENERIC - fi - - if [ -z "`/sbin/ip link list dev $mastif | grep "<.*MASTER.*>"`" ] - then - ocf_log err "$mastif is not a master device" - return $OCF_ERR_GENERIC - fi - - ## Strip possible VLAN (802.1q) suffixes - ## - Roland Gadinger roland.gadinger@beko.at - mastif=${mastif%%.*} - - while read line; do - set - $line - interfaces="${2/:/} $interfaces" - done < <( /sbin/ip -o link list | grep "master $mastif" ) - - echo $interfaces -} - - -isSlave() -{ - declare intf=$1 - declare line - - if [ -z "$intf" ]; then - ocf_log err "usage: isSlave <I/F>" - return $OCF_ERR_ARGS - fi - - line=$(/sbin/ip link list dev $intf) - if [ $? -ne 0 ]; then - ocf_log err "$intf not found" - return $OCF_ERR_GENERIC - fi - - if [ "$line" = "${line/<*SLAVE*>/}" ]; then - return 2 - fi - - # Yes, it is a slave device. Ignore. - return 0 -} - - -# -# Check if interface is in UP state -# -interface_up() -{ - declare intf=$1 - - if [ -z "$intf" ]; then - ocf_log err "usage: interface_up <I/F>" - return 1 - fi - - line=$(/sbin/ip -o link show up dev $intf 2> /dev/null) - [ -z "$line" ] && return 2 - - return 0 -} - - -ethernet_link_up() -{ - declare linkstate=$(ethtool $1 | grep "Link detected:" |\ - awk '{print $3}') - - [ -n "$linkstate" ] || return 0 - - case $linkstate in - yes) - return 0 - ;; - *) - return 1 - ;; - esac - - return 1 -} - - -# -# Checks the physical link status of an ethernet or bonded interface. -# -network_link_up() -{ - declare slaves - declare intf_arg=$1 - declare link_up=1 # Assume link down - declare intf_test - - if [ -z "$intf_arg" ]; then - ocf_log err "usage: network_link_up <intf>" - return 1 - fi - - # - # XXX assumes bond* interfaces are the bonding driver. (Fair - # assumption on Linux, I think) - # - if [ "${intf_arg/bond/}" != "$intf_arg" ]; then - - # - # Bonded driver. Check link of all slaves for this interface. - # If any link is up, the bonding driver is expected to route - # traffic through that link. Thus, the entire bonded link - # is declared up. - # - slaves=$(findSlaves $intf_arg) - if [ $? -ne 0 ]; then - ocf_log err "Error finding slaves of $intf_arg" - return 1 - fi - for intf_test in $slaves; do - ethernet_link_up $intf_test && link_up=0 - done - else - ethernet_link_up $intf_arg - link_up=$? - fi - - if [ $link_up -eq 0 ]; then - ocf_log debug "Link for $intf_arg: Detected" - else - ocf_log warn "Link for $intf_arg: Not detected" - fi - - return $link_up -} - - -ipv4_list_interfaces() -{ - declare idx dev ifaddr - - while read idx dev ifaddr; do - - isSlave $dev - if [ $? -ne 2 ]; then - continue - fi - - idx=${idx/:/} - - echo $dev ${ifaddr//*/} ${ifaddr/*//} - - done < <(/sbin/ip -o -f inet addr | awk '{print $1,$2,$4}') - - return 0 -} - - -# -# Add an IP address to our interface. -# -ipv6() -{ - declare dev maskbits - declare addr=$2 - declare addr_exp=$(ipv6_expand $addr) - - while read dev ifaddr_exp maskbits; do - if [ -z "$dev" ]; then - continue - fi - - if [ "$1" = "add" ]; then - ipv6_same_subnet $ifaddr_exp/$maskbits $addr_exp - if [ $? -ne 0 ]; then - continue - fi - interface_up $dev - if [ $? -ne 0 ]; then - continue - fi - if [ "$OCF_RESKEY_monitor_link" = "yes" ]; then - network_link_up $dev - if [ $? -ne 0 ]; then - continue - fi - fi - - if [ "${addr//*/}" = "${addr}" ]; then - addr="$addr/$maskbits" - fi - ocf_log info "Adding IPv6 address $addr to $dev" - fi - if [ "$1" = "del" ]; then - if [ "${addr_exp//*/}" != "$ifaddr_exp" ]; then - continue - fi - ocf_log info "Removing IPv6 address $addr from $dev" - fi - - /sbin/ip -f inet6 addr $1 dev $dev $addr - [ $? -ne 0 ] && return 1 - - # - # NDP should take of figuring out our new address. Plus, - # we do not have something (like arping) to do this for ipv6 - # anyway. - # - # RFC 2461, section 7.2.6 states thusly: - # - # Note that because unsolicited Neighbor Advertisements do not - # reliably update caches in all nodes (the advertisements might - # not be received by all nodes), they should only be viewed as - # a performance optimization to quickly update the caches in - # most neighbors. - # - - # Not sure if this is necessary for ipv6 either. - file=$(which rdisc 2>/dev/null) - if [ -f "$file" ]; then - killall -HUP rdisc || rdisc -fs - fi - - return 0 - done < <(ipv6_list_interfaces) - - return 1 -} - - -# -# Add an IP address to our interface. -# -ipv4() -{ - declare dev ifaddr maskbits - declare addr=$2 - - while read dev ifaddr maskbits; do - if [ -z "$dev" ]; then - continue - fi - - if [ "$1" = "add" ]; then - ipv4_same_subnet $ifaddr/$maskbits $addr - if [ $? -ne 0 ]; then - continue - fi - interface_up $dev - if [ $? -ne 0 ]; then - continue - fi - if [ "$OCF_RESKEY_monitor_link" = "yes" ]; then - network_link_up $dev - if [ $? -ne 0 ]; then - continue - fi - fi - - if [ "${addr//*/}" = "${addr}" ]; then - addr="$addr/$maskbits" - fi - ocf_log info "Adding IPv4 address $addr to $dev" - fi - if [ "$1" = "del" ]; then - if [ "${addr//*/}" != "$ifaddr" ]; then - continue - fi - ocf_log info "Removing IPv4 address $addr from $dev" - fi - - /sbin/ip -f inet addr $1 dev $dev $addr - [ $? -ne 0 ] && return 1 - - # - # The following is needed only with ifconfig; ifcfg does it for us - # - if [ "$1" = "add" ]; then - # do that freak arp thing - - hwaddr=$(/sbin/ip -o link show $dev) - hwaddr=${hwaddr/*link/ether\ /} - hwaddr=${hwaddr/\ */} - - addr=${addr//*/} - ocf_log debug "Sending gratuitous ARP: $addr $hwaddr" - arping -q -c 2 -U -I $dev $addr - fi - - file=$(which rdisc 2>/dev/null) - if [ -f "$file" ]; then - killall -HUP rdisc || rdisc -fs - fi - - return 0 - done < <(ipv4_list_interfaces) - - return 1 -} - - -# -# Usage: -# ping_check <family> <address> [interface] -# -ping_check() -{ - declare ops="-c 1 -w 2" - declare pingcmd="" - - if [ "$1" = "inet6" ]; then - pingcmd="ping6" - else - pingcmd="ping" - fi - - if [ -n "$3" ]; then - ops="$ops -I $3" - fi - - return $($pingcmd $ops $2 &> /dev/null) -} - - -# -# Usage: -# check_interface_up <family> <address> -# -check_interface_up() -{ - declare dev - declare addr=${2//*/} - - dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}') - if [ -z "$dev" ]; then - return 1 - fi - - interface_up $dev - return $? -} - - -# -# Usage: -# address_configured <family> <address> -# -address_configured() -{ - declare line - declare addr - - # Chop off maxk bits - addr=${2//*/} - line=$(/sbin/ip -f $1 -o addr | grep " $addr/") - - if [ -z "$line" ]; then - return 1 - fi - return 0 -} - - -# -# Usage: -# ip_op <family> <operation> <address> [quiet] -# -ip_op() -{ - declare dev - declare rtr - declare addr=${3//*/} - - - if [ "$2" = "status" ]; then - - ocf_log debug "Checking $3, Level $OCF_CHECK_LEVEL" - - dev=$(/sbin/ip -f $1 -o addr | grep " $addr/" | awk '{print $2}') - if [ -z "$dev" ]; then - ocf_log warn "$3 is not configured" - return 1 - fi - ocf_log debug "$3 present on $dev" - - if [ "$OCF_RESKEY_monitor_link" = "yes" ]; then - if ! network_link_up $dev; then - ocf_log warn "No link on $dev..." - return 1 - fi - ocf_log debug "Link detected on $dev" - fi - - [ $OCF_CHECK_LEVEL -lt 10 ] && return 0 - if ! ping_check $1 $addr $dev; then - ocf_log warn "Failed to ping $addr" - return 1 - fi - ocf_log debug "Local ping to $addr succeeded" - - return 0 - fi - - case $1 in - inet) - ipv4 $2 $3 - return $? - ;; - inet6) - ipv6 $2 $3 - return $? - ;; - esac - return 1 -} - - -case ${OCF_RESKEY_family} in -inet) - ;; -inet6) - ;; -*) - if [ "${OCF_RESKEY_address//:/}" != "${OCF_RESKEY_address}" ]; then - export OCF_RESKEY_family=inet6 - else - export OCF_RESKEY_family=inet - fi - ;; -esac - - -if [ -z "$OCF_CHECK_LEVEL" ]; then - OCF_CHECK_LEVEL=0 -fi - -if [ "${OCF_RESKEY_monitor_link}" = "no" ] || - [ "${OCF_RESKEY_monitor_link}" = "0" ]; then - OCF_RESKEY_monitor_link="no" -else - OCF_RESKEY_monitor_link="yes" -fi - -case $1 in -start) - if address_configured ${OCF_RESKEY_family} ${OCF_RESKEY_address}; then - ocf_log debug "${OCF_RESKEY_address} already configured" - exit 0 - fi - ip_op ${OCF_RESKEY_family} add ${OCF_RESKEY_address} - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - export OCF_CHECK_LEVEL=10 - ip_op ${OCF_RESKEY_family} status ${OCF_RESKEY_address} - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - if [ $NFS_TRICKS -eq 0 ]; then - if [ "$OCF_RESKEY_nfslock" = "yes" ] || \ - [ "$OCF_RESKEY_nfslock" = "1" ]; then - notify_list_broadcast /var/lib/nfs/statd - fi - fi - - exit $? - ;; -stop) - if address_configured ${OCF_RESKEY_family} ${OCF_RESKEY_address}; then - - ip_op ${OCF_RESKEY_family} del ${OCF_RESKEY_address} - - # Make sure it's down - if address_configured ${OCF_RESKEY_family} ${OCF_RESKEY_address}; then - ocf_log err "Failed to remove ${OCF_RESKEY_address}" - exit 1 - fi - - # XXX Let nfsd/lockd clear their queues; we hope to have a - # way to enforce this in the future - if [ -z "$OCF_RESKEY_sleeptime" ]; then - sleep 10 - else - if [ "$OCF_RESKEY_sleeptime" -gt "0" ]; then - sleep $OCF_RESKEY_sleeptime - fi - fi - else - ocf_log debug "${OCF_RESKEY_address} is not configured" - fi - exit 0 - ;; -status|monitor) - ip_op ${OCF_RESKEY_family} status ${OCF_RESKEY_address} - [ $? -ne 0 ] && exit $OCF_ERR_GENERIC - - check_interface_up ${OCF_RESKEY_family} ${OCF_RESKEY_address} - exit $? - ;; -restart) - $0 stop || exit $OCF_ERR_GENERIC - $0 start || exit $OCF_ERR_GENERIC - exit 0 - ;; -meta-data) - meta_data - exit 0 - ;; -verify-all) - verify_all - exit $? - ;; -*) - echo "usage: $0 {start|stop|status|monitor|restart|meta-data|verify-alll}" - exit $OCF_ERR_GENERIC - ;; -esac - - diff --git a/rgmanager/src/resources/lvm.metadata b/rgmanager/src/resources/lvm.metadata deleted file mode 100755 index fdf2621..0000000 --- a/rgmanager/src/resources/lvm.metadata +++ /dev/null @@ -1,86 +0,0 @@ -<?xml version="1.0" ?> -<resource-agent name="lvm" version="rgmanager 2.0"> - <version>1.0</version> - - <longdesc lang="en"> - This defines a LVM volume group that is ... - </longdesc> - - <shortdesc lang="en"> - LVM Failover script - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Unique name for this LVM resource - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="vg_name" required="1"> - <longdesc lang="en"> - Name of the volume group being managed - </longdesc> - <shortdesc lang="en"> - Volume group name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="lv_name"> - <longdesc lang="en"> - Name of the logical volume being managed. This - parameter is optional if there are more than one - logical volumes in the volume group to be managed. - </longdesc> - <shortdesc lang="en"> - Logical Volume name (optional). - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="self_fence"> - <longdesc lang="en"> - If set and the clean up of the tags fails, the node will - immediately reboot. - </longdesc> - <shortdesc lang="en"> - Fence the node if it is not able to clean up LVM tags - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="nfslock" inherit="service%nfslock"> - <longdesc lang="en"> - If set and unmounting the file system fails, the node will - try to kill lockd and issue reclaims across all remaining - network interface cards. - </longdesc> - <shortdesc lang="en"> - Enable NFS lock workarounds - </shortdesc> - <content type="boolean"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="5"/> - <action name="stop" timeout="5"/> - - <action name="status" timeout="5" interval="1h"/> - <action name="monitor" timeout="5" interval="1h"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="30"/> - </actions> - - <special tag="rgmanager"> - <attributes maxinstances="1"/> - </special> - -</resource-agent> diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh deleted file mode 100755 index 70355c6..0000000 --- a/rgmanager/src/resources/lvm.sh +++ /dev/null @@ -1,193 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2007 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# LVM Failover Script. -# NOTE: Changes to /etc/lvm/lvm.conf are required for proper operation. - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/member_util.sh -. $(dirname $0)/lvm_by_lv.sh -. $(dirname $0)/lvm_by_vg.sh - -rv=0 - -################################################################################ -# clvm_check -# -################################################################################ -function clvm_check -{ - if [[ $(vgs -o attr --noheadings $1) =~ .....c ]]; then - return 1 - fi - - return 0 -} - -################################################################################ -# ha_lvm_proper_setup_check -# -################################################################################ -function ha_lvm_proper_setup_check -{ - ## - # The default for lvm.conf:activation/volume_list is empty, - # this must be changed for HA LVM. - ## - if ! lvm dumpconfig activation/volume_list >& /dev/null; then - ocf_log err "HA LVM: Improper setup detected" - ocf_log err "- "volume_list" not specified in lvm.conf." - return $OCF_ERR_GENERIC - fi - - ## - # Machine's cluster node name must be present as - # a tag in lvm.conf:activation/volume_list - ## - if ! lvm dumpconfig activation/volume_list | grep $(local_node_name); then - ocf_log err "HA LVM: Improper setup detected" - ocf_log err "- @$(local_node_name) missing from "volume_list" in lvm.conf" - return $OCF_ERR_GENERIC - fi - - ## - # The volume group to be failed over must NOT be in - # lvm.conf:activation/volume_list; otherwise, machines - # will be able to activate the VG regardless of the tags - ## - if lvm dumpconfig activation/volume_list | grep $OCF_RESKEY_vg_name; then - ocf_log err "HA LVM: Improper setup detected" - ocf_log err "- $OCF_RESKEY_vg_name found in "volume_list" in lvm.conf" - return $OCF_ERR_GENERIC - fi - - ## - # Next, we need to ensure that their initrd has been updated - # If not, the machine could boot and activate the VG outside - # the control of rgmanager - ## - # Fixme: we might be able to perform a better check... - if [ "$(find /boot -name *.img -newer /etc/lvm/lvm.conf)" == "" ]; then - ocf_log err "HA LVM: Improper setup detected" - ocf_log err "- initrd image needs to be newer than lvm.conf" - return $OCF_ERR_GENERIC - fi - - return $OCF_SUCCESS -} - -################################################################################ -# MAIN -################################################################################ - -case $1 in -start) - ## - # We can safely ignore clustered volume groups (VGs handled by CLVM) - ## - if ! clvm_check $OCF_RESKEY_vg_name; then - ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..." - exit 0 - fi - - ha_lvm_proper_setup_check || exit 1 - - rv=0 - - if [ -z $OCF_RESKEY_lv_name ]; then - vg_start || exit 1 - else - lv_start || exit 1 - fi - ;; - -status|monitor) - ocf_log notice "Getting status" - - if [ -z $OCF_RESKEY_lv_name ]; then - vg_status || exit 1 - else - lv_status || exit 1 - fi - rv=0 - ;; - -stop) - ## - # We can safely ignore clustered volume groups (VGs handled by CLVM) - ## - if ! clvm_check $OCF_RESKEY_vg_name; then - ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..." - exit 0 - fi - - if ! ha_lvm_proper_setup_check; then - ocf_log err "WARNING: An improper setup can cause data corruption!" - fi - - if [ -z $OCF_RESKEY_lv_name ]; then - vg_stop || exit 1 - else - lv_stop || exit 1 - fi - rv=0 - ;; - -recover|restart) - $0 stop || exit $OCF_ERR_GENERIC - $0 start || exit $OCF_ERR_GENERIC - rv=0 - ;; - -meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - rv=0 - ;; - -verify-all) - ## - # We can safely ignore clustered volume groups (VGs handled by CLVM) - ## - if ! clvm_check $OCF_RESKEY_vg_name; then - ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..." - exit 0 - fi - - if [ -z $OCF_RESKEY_lv_name ]; then - vg_verify || exit 1 - else - lv_verify || exit 1 - fi - rv=0 - ;; -*) - echo "usage: $0 {start|status|monitor|stop|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac - -exit $rv diff --git a/rgmanager/src/resources/lvm_by_lv.sh b/rgmanager/src/resources/lvm_by_lv.sh deleted file mode 100644 index 1937b9f..0000000 --- a/rgmanager/src/resources/lvm_by_lv.sh +++ /dev/null @@ -1,365 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2007 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# lv_verify -# -# Verify the parameters passed in -# -lv_verify() -{ - # Anything to verify? Perhaps the names? - return $OCF_SUCCESS -} - -# lv_exec_resilient -# -# Sometimes, devices can come back. Their metadata will conflict -# with the good devices that remain. This function filters out those -# failed devices when executing the given command -# -# Finishing with vgscan resets the cache/filter -lv_exec_resilient() -{ - declare command=$1 - declare all_pvs - - ocf_log notice "Making resilient : $command" - - if [ -z $command ]; then - ocf_log err "lv_exec_resilient: Arguments not supplied" - return $OCF_ERR_ARGS - fi - - # pvs will print out only those devices that are valid - # If a device dies and comes back, it will not appear - # in pvs output (but you will get a Warning). - all_pvs=(`pvs --noheadings -o pv_name | grep -v Warning`) - - # Now we use those valid devices in a filter which we set up. - # The device will then be activated because there are no - # metadata conflicts. - command=$command" --config devices{filter=[" - for i in ${all_pvs[*]}; do - command=$command'"a|'$i'|",' - done - command=$command""r|.*|"]}" - - ocf_log notice "Resilient command: $command" - if ! $command ; then - ocf_log err "lv_exec_resilient failed" - vgscan - return $OCF_ERR_GENERIC - else - vgscan - return $OCF_SUCCESS - fi -} - -# lv_activate_resilient -# -# Sometimes, devices can come back. Their metadata will conflict -# with the good devices that remain. We must filter out those -# failed devices when trying to reactivate -lv_activate_resilient() -{ - declare action=$1 - declare lv_path=$2 - declare op="-ay" - - if [ -z $action ] || [ -z $lv_path ]; then - ocf_log err "lv_activate_resilient: Arguments not supplied" - return $OCF_ERR_ARGS - fi - - if [ $action != "start" ]; then - op="-an" - fi - - if ! lv_exec_resilient "lvchange $op $lv_path" ; then - ocf_log err "lv_activate_resilient $action failed on $lv_path" - return $OCF_ERR_GENERIC - else - return $OCF_SUCCESS - fi -} - -# lv_status -# -# Is the LV active? -lv_status() -{ - declare lv_path="$OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name" - declare dev="/dev/$lv_path" - declare realdev - declare owner - declare my_name - - # - # Check if device is active - # - if [[ ! $(lvs -o attr --noheadings $lv_path) =~ ....a. ]]; then - return $OCF_ERR_GENERIC - fi - - if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then - ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..." - return $OCF_SUCCESS - fi - - # - # Check if all links/device nodes are present - # - if [ -h "$dev" ]; then - realdev=$(readlink -f $dev) - if [ $? -ne 0 ]; then - ocf_log err "Failed to follow link, $dev" - return $OCF_ERR_ARGS - fi - - if [ ! -b $realdev ]; then - ocf_log err "Device node for $lv_path is not present" - return $OCF_ERR_GENERIC - fi - else - ocf_log err "Symbolic link for $lv_path is not present" - return $OCF_ERR_GENERIC - fi - - # - # Verify that we are the correct owner - # - owner=`lvs -o tags --noheadings $lv_path` - my_name=$(local_node_name) - if [ -z $my_name ]; then - ocf_log err "Unable to determine local machine name" - - # FIXME: I don't really want to fail on 1st offense - return $OCF_SUCCESS - fi - - if [ -z $owner ] || [ $my_name != $owner ]; then - ocf_log err "WARNING: $lv_path should not be active" - ocf_log err "WARNING: $my_name does not own $lv_path" - ocf_log err "WARNING: Attempting shutdown of $lv_path" - - lv_activate_resilient "stop" $lv_path - return $OCF_ERR_GENERIC - fi - - return $OCF_SUCCESS -} - -# lv_activate_and_tag -lv_activate_and_tag() -{ - declare action=$1 - declare tag=$2 - declare lv_path=$3 - typeset self_fence="" - - case ${OCF_RESKEY_self_fence} in - "yes") self_fence=1 ;; - 1) self_fence=1 ;; - *) self_fence="" ;; - esac - - if [ -z $action ] || [ -z $tag ] || [ -z $lv_path ]; then - ocf_log err "Supplied args: 1) $action, 2) $tag, 3) $lv_path" - return $OCF_ERR_ARGS - fi - - if [ $action == "start" ]; then - ocf_log notice "Activating $lv_path" - lvchange --addtag $tag $lv_path - if [ $? -ne 0 ]; then - ocf_log err "Unable to add tag to $lv_path" - return $OCF_ERR_GENERIC - fi - - if ! lv_activate_resilient $action $lv_path; then - ocf_log err "Unable to activate $lv_path" - return $OCF_ERR_GENERIC - fi - else - ocf_log notice "Deactivating $lv_path" - if ! lv_activate_resilient $action $lv_path; then - if [ "$self_fence" ]; then - ocf_log err "Unable to deactivate $lv_path: REBOOTING" - sync - reboot -fn - else - ocf_log err "Unable to deactivate $lv_path" - fi - return $OCF_ERR_GENERIC - fi - - ocf_log notice "Removing ownership tag ($tag) from $lv_path" - - lvchange --deltag $tag $lv_path - if [ $? -ne 0 ]; then - ocf_log err "Unable to delete tag from $lv_path" - return $OCF_ERR_GENERIC - fi - - if [ `lvs --noheadings -o lv_tags $lv_path` == $tag ]; then - ocf_log notice "Removing ownership tag ($tag) from $lv_path" - lvchange --deltag $tag $lv_path - if [ $? -ne 0 ]; then - ocf_log err "Unable to delete tag from $lv_path" - return $OCF_ERR_GENERIC - fi - fi - fi - - return $OCF_SUCCESS -} - -# lv_activate -# $1: start/stop only -# -# Basically, if we want to [de]activate an LVM volume, -# we must own it. That means that our tag must be on it. -# This requires a change to /etc/lvm/lvm.conf: -# volume_list = [ "root_volume", "@my_hostname" ] -# where "root_volume" is your root volume group and -# "my_hostname" is $(local_node_name) -# -# If there is a node failure, we may wish to "steal" the -# LV. For that, we need to check if the node that owns -# it is still part of the cluster. We use the tag to -# determine who owns the volume then query for their -# liveness. If they are dead, we can steal. -lv_activate() -{ - declare lv_path="$OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name" - declare owner=`lvs -o tags --noheadings $lv_path` - declare my_name=$(local_node_name) - - if [ -z $my_name ]; then - ocf_log err "Unable to determine cluster node name" - return $OCF_ERR_GENERIC - fi - - # - # FIXME: This code block is repeated below... might be - # nice to put it in a function - # - if [ ! -z $owner ] && [ $owner != $my_name ]; then - if is_node_member_clustat $owner ; then - ocf_log err "$owner owns $lv_path unable to $1" - return $OCF_ERR_GENERIC - fi - ocf_log notice "Owner of $lv_path is not in the cluster" - ocf_log notice "Stealing $lv_path" - - lvchange --deltag $owner $lv_path - if [ $? -ne 0 ]; then - ocf_log err "Failed to steal $lv_path from $owner" - return $OCF_ERR_GENERIC - fi - - # Warning --deltag doesn't always result in failure - if [ ! -z `lvs -o tags --noheadings $lv_path` ]; then - ocf_log err "Failed to steal $lv_path from $owner." - return $OCF_ERR_GENERIC - fi - fi - - if ! lv_activate_and_tag $1 $my_name $lv_path; then - ocf_log err "Failed to $1 $lv_path" - - if [ "$1" == "start" ]; then - ocf_log notice "Attempting cleanup of $OCF_RESKEY_vg_name" - - if vgreduce --removemissing --config \ - "activation { volume_list = "$OCF_RESKEY_vg_name" }" \ - $OCF_RESKEY_vg_name; then - ocf_log notice "$OCF_RESKEY_vg_name now consistent" - owner=`lvs -o tags --noheadings $lv_path` - if [ ! -z $owner ] && [ $owner != $my_name ]; then - if is_node_member_clustat $owner ; then - ocf_log err "$owner owns $lv_path unable to $1" - return $OCF_ERR_GENERIC - fi - ocf_log notice "Owner of $lv_path is not in the cluster" - ocf_log notice "Stealing $lv_path" - - lvchange --deltag $owner $lv_path - if [ $? -ne 0 ]; then - ocf_log err "Failed to steal $lv_path from $owner" - return $OCF_ERR_GENERIC - fi - - # Warning --deltag doesn't always result in failure - if [ ! -z `lvs -o tags --noheadings $lv_path` ]; then - ocf_log err "Failed to steal $lv_path from $owner." - return $OCF_ERR_GENERIC - fi - fi - - if ! lv_activate_and_tag $1 $my_name $lv_path; then - ocf_log err "Failed second attempt to $1 $lv_path" - return $OCF_ERR_GENERIC - else - ocf_log notice "Second attempt to $1 $lv_path successful" - return $OCF_SUCCESS - fi - else - ocf_log err "Failed to make $OCF_RESKEY_vg_name consistent" - return $OCF_ERR_GENERIC - fi - else - ocf_log err "Failed to $1 $lv_path" - return $OCF_ERR_GENERIC - fi - fi - return $OCF_SUCCESS -} - -function lv_start -{ - if ! lvs $OCF_RESKEY_vg_name >& /dev/null; then - lv_count=0 - else - lv_count=`lvs --noheadings -o name $OCF_RESKEY_vg_name | grep -v _mlog | grep -v _mimage | grep -v nconsistent | wc -l` - fi - if [ $lv_count -gt 1 ]; then - ocf_log err "HA LVM requires Only one logical volume per volume group." - ocf_log err "There are currently $lv_count logical volumes in $OCF_RESKEY_vg_name" - ocf_log err "Failing HA LVM start of $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name" - exit $OCF_ERR_GENERIC - fi - - if ! lv_activate start; then - return 1 - fi - - return 0 -} - -function lv_stop -{ - if ! lv_activate stop; then - return 1 - fi - - return 0 -} diff --git a/rgmanager/src/resources/lvm_by_vg.sh b/rgmanager/src/resources/lvm_by_vg.sh deleted file mode 100755 index 8fa36d6..0000000 --- a/rgmanager/src/resources/lvm_by_vg.sh +++ /dev/null @@ -1,281 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2007 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# vg_owner -# -# Returns: -# 1 == We are the owner -# 2 == We can claim it -# 0 == Owned by someone else -function vg_owner -{ - local owner=`vgs -o tags --noheadings $OCF_RESKEY_vg_name` - local my_name=$(local_node_name) - - if [ -z $my_name ]; then - ocf_log err "Unable to determine cluster node name" - return 0 - fi - - if [ -z $owner ]; then - # No-one owns this VG yet, so we can claim it - return 2 - fi - - if [ $owner != $my_name ]; then - if is_node_member_clustat $owner ; then - return 0 - fi - return 2 - fi - - return 1 -} - -function strip_tags -{ - local i - - for i in `vgs --noheadings -o tags $OCF_RESKEY_vg_name | sed s/","/" "/g`; do - ocf_log info "Stripping tag, $i" - vgchange --deltag $i $OCF_RESKEY_vg_name - done - - if [ ! -z `vgs -o tags --noheadings $OCF_RESKEY_vg_name` ]; then - ocf_log err "Failed to remove ownership tags from $OCF_RESKEY_vg_name" - return $OCF_ERR_GENERIC - fi - - return $OCF_SUCCESS -} - -function strip_and_add_tag -{ - if ! strip_tags; then - ocf_log err "Failed to remove tags from volume group, $OCF_RESKEY_vg_name" - return $OCF_ERR_GENERIC - fi - - vgchange --addtag $(local_node_name) $OCF_RESKEY_vg_name - if [ $? -ne 0 ]; then - ocf_log err "Failed to add ownership tag to $OCF_RESKEY_vg_name" - return $OCF_ERR_GENERIC - fi - - ocf_log info "New tag "$(local_node_name)" added to $OCF_RESKEY_vg_name" - - return $OCF_SUCCESS -} - -# vg_status -# -# Are all the LVs active? -function vg_status -{ - local i - local dev - local readdev - local my_name=$(local_node_name) - - # - # Check that all LVs are active - # - for i in `lvs $OCF_RESKEY_vg_name --noheadings -o attr`; do - if [[ ! $i =~ ....a. ]]; then - return $OCF_ERR_GENERIC - fi - done - - # - # Check if all links/device nodes are present - # - for i in `lvs $OCF_RESKEY_vg_name --noheadings -o name`; do - dev="/dev/$OCF_RESKEY_vg_name/$i" - - if [ -h $dev ]; then - realdev=$(readlink -f $dev) - if [ $? -ne 0 ]; then - ocf_log err "Failed to follow link, $dev" - return $OCF_ERR_GENERIC - fi - - if [ ! -b $realdev ]; then - ocf_log err "Device node for $dev is not present" - return $OCF_ERR_GENERIC - fi - else - ocf_log err "Symbolic link for $lv_path is not present" - return $OCF_ERR_GENERIC - fi - done - - # - # Verify that we are the correct owner - # - vg_owner - if [ $? -ne 1 ]; then - ocf_log err "WARNING: $OCF_RESKEY_vg_name should not be active" - ocf_log err "WARNING: $my_name does not own $OCF_RESKEY_vg_name" - ocf_log err "WARNING: Attempting shutdown of $OCF_RESKEY_vg_name" - - # FIXME: may need more force to shut this down - vgchange -an $OCF_RESKEY_vg_name - return $OCF_ERR_GENERIC - fi - - return $OCF_SUCCESS -} - -function vg_verify -{ - # Anything to verify? - return $OCF_SUCCESS -} - -function vg_start -{ - local a - local results - local all_pvs - local resilience - - ocf_log info "Starting volume group, $OCF_RESKEY_vg_name" - - vg_owner - case $? in - 0) - ocf_log info "Someone else owns this volume group" - return $OCF_ERR_GENERIC - ;; - 1) - ocf_log info "I own this volume group" - ;; - 2) - ocf_log info "I can claim this volume group" - ;; - esac - - if ! strip_and_add_tag || - ! vgchange -ay $OCF_RESKEY_vg_name -vvvv >& /tmp/butt; then - ocf_log err "Failed to activate volume group, $OCF_RESKEY_vg_name" - ocf_log notice "Attempting cleanup of $OCF_RESKEY_vg_name" - - if ! vgreduce --removemissing --config \ - "activation { volume_list = "$OCF_RESKEY_vg_name" }" \ - $OCF_RESKEY_vg_name; then - - ocf_log err "Failed to make $OCF_RESKEY_vg_name consistent" - return $OCF_ERR_GENERIC - fi - - vg_owner - if [ $? -eq 0 ]; then - ocf_log err "Unable to claim ownership of $OCF_RESKEY_vg_name" - return $OCF_ERR_GENERIC - fi - - if ! strip_and_add_tag || - ! vgchange -ay $OCF_RESKEY_vg_name; then - ocf_log err "Failed second attempt to activate $OCF_RESKEY_vg_name" - return $OCF_ERR_GENERIC - fi - - ocf_log notice "Second attempt to activate $OCF_RESKEY_vg_name successful" - return $OCF_SUCCESS - else - # The activation commands succeeded, but did they do anything? - # Make sure all the logical volumes are active - results=(`lvs -o name,attr --noheadings 2> /dev/null $OCF_RESKEY_vg_name`) - a=0 - while [ ! -z ${results[$a]} ]; do - if [[ ! ${results[$(($a + 1))]} =~ ....a. ]]; then - all_pvs=(`pvs --noheadings -o name 2> /dev/null`) - resilience=" --config devices{filter=[" - for i in ${all_pvs[*]}; do - resilience=$resilience'"a|'$i'|",' - done - resilience=$resilience""r|.*|"]}" - - vgchange -ay $OCF_RESKEY_vg_name $resilience - break - fi - a=$(($a + 2)) - done - - # We need to check the LVs again if we made the command resilient - if [ ! -z $resilience ]; then - results=(`lvs -o name,attr --noheadings $OCF_RESKEY_vg_name $resilience 2> /dev/null`) - a=0 - while [ ! -z ${results[$a]} ]; do - if [[ ! ${results[$(($a + 1))]} =~ ....a. ]]; then - ocf_log err "Failed to activate $OCF_RESKEY_vg_name" - return $OCF_ERR_GENERIC - fi - a=$(($a + 2)) - done - ocf_log err "Orphan storage device in $OCF_RESKEY_vg_name slowing operations" - fi - fi - - return $OCF_SUCCESS -} - -function vg_stop -{ - local a - local results - typeset self_fence="" - - case ${OCF_RESKEY_self_fence} in - "yes") self_fence=1 ;; - 1) self_fence=1 ;; - *) self_fence="" ;; - esac - - # Shut down the volume group - # Do we need to make this resilient? - vgchange -an $OCF_RESKEY_vg_name - - # Make sure all the logical volumes are inactive - results=(`lvs -o name,attr --noheadings $OCF_RESKEY_vg_name 2> /dev/null`) - a=0 - while [ ! -z ${results[$a]} ]; do - if [[ ${results[$(($a + 1))]} =~ ....a. ]]; then - if [ "$self_fence" ]; then - ocf_log err "Unable to deactivate $lv_path REBOOT" - sync - reboot -fn - else - ocf_log err "Logical volume $OCF_RESKEY_vg_name/${results[$a]} failed to shutdown" - fi - return $OCF_ERR_GENERIC - fi - a=$(($a + 2)) - done - - # Make sure we are the owner before we strip the tags - vg_owner - if [ $? -ne 0 ]; then - strip_tags - fi - - return $OCF_SUCCESS -} diff --git a/rgmanager/src/resources/mysql.metadata b/rgmanager/src/resources/mysql.metadata deleted file mode 100644 index 29784e2..0000000 --- a/rgmanager/src/resources/mysql.metadata +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="mysql"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an instance of MySQL database server - </longdesc> - <shortdesc lang="en"> - Defines a MySQL database server - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Define a name - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define configuration file - </longdesc> - <shortdesc lang="en"> - Define configuration file - </shortdesc> - <content type="string" default="/etc/my.cnf"/> - </parameter> - - <parameter name="listen_address"> - <longdesc lang="en"> - Define an IP address for MySQL - </longdesc> - <shortdesc lang="en"> - Define an IP address for MySQL server. If the address - is not given then first IP address from the service is taken. - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="mysqld_options"> - <longdesc lang="en"> - Other command-line options for httpd - </longdesc> - <shortdesc lang="en"> - Other command-line options for httpd - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- Checks to see if it''s mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> - - <special tag="rgmanager"> - </special> -</resource-agent> diff --git a/rgmanager/src/resources/mysql.sh b/rgmanager/src/resources/mysql.sh deleted file mode 100755 index 6d7ea18..0000000 --- a/rgmanager/src/resources/mysql.sh +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare MYSQL_MYSQLD=/usr/bin/mysqld_safe -declare MYSQL_ipAddress -declare MYSQL_pid_file="`generate_name_for_pid_file`" -declare MYSQL_timeout=30 - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ ! -r "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE $OCF_RESKEY_config_file - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ -z "$MYSQL_pid_file" ]; then - clog_service_verify $CLOG_FAILED "Invalid name of PID file" - return $OCF_ERR_ARGS - fi - - clog_service_verify $CLOG_SUCCEED - return 0 -} - -start() -{ - declare ccs_fd; - - clog_service_start $CLOG_INIT - - create_pid_directory - check_pid_file "$MYSQL_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$MYSQL_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - if [ -n "$OCF_RESKEY_listen_address" ]; then - MYSQL_ipAddress="$OCF_RESKEY_listen_address" - else - clog_looking_for $CLOG_INIT "IP Address" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -n "$ip_addresses" ]; then - for i in $ip_addresses; do - MYSQL_ipAddress="$i" - break; - done - else - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Address" - fi - fi - - clog_looking_for $CLOG_SUCCEED "IP Address" - - $MYSQL_MYSQLD --defaults-file="$OCF_RESKEY_config_file" \ - --pid-file="$MYSQL_pid_file" \ - --bind-address="$MYSQL_ipAddress" \ - $OCF_RESKEY_mysqld_options > /dev/null 2>&1 & - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - while [ "$MYSQL_timeout" -gt 0 ]; do - if [ -f "$MYSQL_pid_file" ]; then - break; - fi - sleep 1 - let MYSQL_timeout=${MYSQL_timeout}-1 - done - - if [ "$MYSQL_timeout" -eq 0 ]; then - clog_service_start $CLOG_FAILED_TIMEOUT - return $OCF_ERR_GENERIC - fi - - clog_service_start $CLOG_SUCCEED - - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$MYSQL_pid_file" "$OCF_RESKEY_shutdown_wait" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$MYSQL_pid_file" - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$MYSQL_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - verify-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac diff --git a/rgmanager/src/resources/named.metadata b/rgmanager/src/resources/named.metadata deleted file mode 100644 index 3cd96fa..0000000 --- a/rgmanager/src/resources/named.metadata +++ /dev/null @@ -1,104 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="named"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an instance of DNS named server - </longdesc> - <shortdesc lang="en"> - Defines an instance of named server - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Specifies a service name for logging and other purposes - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define absolute path to configuration file - </longdesc> - <shortdesc lang="en"> - Config File - </shortdesc> - <content type="string" default="/etc/named.conf"/> - </parameter> - - <parameter name="named_sdb"> - <longdesc lang="en"> - Simplified Database Backend - </longdesc> - <shortdesc lang="en"> - Simplified Database Backend - </shortdesc> - <content type="boolean" default="0"/> - </parameter> - - <parameter name="named_working_dir"> - <longdesc lang="en"> - Other command-line options for named - </longdesc> - <shortdesc lang="en"> - Other command-line options for named - </shortdesc> - <content type="string" default="/var/named" /> - </parameter> - - <parameter name="named_options"> - <longdesc lang="en"> - Other command-line options for named - </longdesc> - <shortdesc lang="en"> - Other command-line options for named - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" default="5" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- Checks to see if it''s mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <action name="meta-data" timeout="0"/> - <action name="validate-all" timeout="0"/> - </actions> - - <special tag="rgmanager"> - </special> -</resource-agent> diff --git a/rgmanager/src/resources/named.sh b/rgmanager/src/resources/named.sh deleted file mode 100755 index 8a8c2f4..0000000 --- a/rgmanager/src/resources/named.sh +++ /dev/null @@ -1,223 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare NAMED_NAMED=/usr/sbin/named -declare NAMED_pid_file="`generate_name_for_pid_file`" -declare NAMED_conf_dir="`generate_name_for_conf_dir`" -declare NAMED_gen_config_file="$NAMED_conf_dir/named.conf" -declare NAMED_url_list -declare NAMED_parse_config=$(dirname $0)/utils/named-parse-config.pl - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ ! -r "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE $OCF_RESKEY_config_file - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - clog_service_verify $CLOG_SUCCEED - - return 0 -} - -generate_config_file() -{ - declare original_file="$1" - declare generated_file="$2" - declare ip_address="$3" - - if [ -f "$generated_file" ]; then - sha1_verify "$generated_file" - if [ $? -ne 0 ]; then - clog_check_sha1 $CLOG_FAILED - return 0 - fi - fi - - clog_generate_config $CLOG_INIT "$original_file" "$generated_file" - - generate_configTemplate "$generated_file" "$1" - cat "$original_file" | grep -v "^[[:space:]]*listen-on" | \ - grep -v "^[[:space:]]*pid-file" | \ - grep -v "^[[:space:]]*directory" >> "$generated_file" - - declare tmp_file=`mktemp -t cluster.XXXXXXXXXX` - mv "$generated_file" "$tmp_file" - - "$NAMED_parse_config" "$OCF_RESKEY_named_working_dir" "$NAMED_pid_file" "$ip_address" \ - < "$tmp_file" > "$generated_file" - - rm "$tmp_file" - sha1_addToFile "$generated_file" - clog_generate_config $CLOG_SUCCEED "$original_file" "$generated_file" - - return 0; -} - -start() -{ - declare ccs_fd; - declare ip_list; - - clog_service_start $CLOG_INIT - - create_pid_directory - create_conf_directory "$NAMED_conf_dir" - check_pid_file "$NAMED_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$NAMED_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - clog_looking_for $CLOG_INIT "IP Addresses" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -z "$ip_addresses" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_SUCCEED "IP Addresses" - - ip_list=`echo $ip_addresses | sed 's/ /;/;s/([[:digit:]])$/\1;/' ` - - if [ -z "$ip_list" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - generate_config_file "$OCF_RESKEY_config_file" "$NAMED_gen_config_file" "$ip_list" - - $NAMED_NAMED -c "$NAMED_gen_config_file" $OCF_RESKEY_named_options - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_start $CLOG_SUCCEED - - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$NAMED_pid_file" "$OCF_RESKEY_shutdown_wait" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$NAMED_pid_file" - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$NAMED_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - validate-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}" - exit $OCF_ERR_UNIMPLEMENTED - ;; -esac diff --git a/rgmanager/src/resources/netfs.sh b/rgmanager/src/resources/netfs.sh deleted file mode 100755 index a144eeb..0000000 --- a/rgmanager/src/resources/netfs.sh +++ /dev/null @@ -1,625 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2002-2004 -# Copyright Mission Critical Linux, Inc. 2000 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# NFS/CIFS file system mount/umount/etc. agent -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -# -# XXX todo - search and replace on these -# -SUCCESS=0 -FAIL=2 -YES=0 -NO=1 -YES_STR="yes" - - -. $(dirname $0)/ocf-shellfuncs - - -meta_data() -{ - cat <<EOT -<?xml version="1.0" ?> -<resource-agent name="netfs" version="rgmanager 2.0"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an NFS/CIFS mount for use by cluster services. - </longdesc> - <shortdesc lang="en"> - Defines an NFS/CIFS file system mount. - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Symbolic name for this file system. - </longdesc> - <shortdesc lang="en"> - File System Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="mountpoint" unique="1" required="1"> - <longdesc lang="en"> - Path in file system heirarchy to mount this file system. - </longdesc> - <shortdesc lang="en"> - Mount Point - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="host" required="1"> - <longdesc lang="en"> - Server IP address or hostname - </longdesc> - <shortdesc lang="en"> - IP or Host - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="export" required="1"> - <longdesc lang="en"> - NFS Export directory name or CIFS share - </longdesc> - <shortdesc lang="en"> - Export - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="fstype" required="0"> - <longdesc lang="en"> - File System type (nfs, nfs4 or cifs) - </longdesc> - <shortdesc lang="en"> - File System Type - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="force_unmount"> - <longdesc lang="en"> - If set, the cluster will kill all processes using - this file system when the resource group is - stopped. Otherwise, the unmount will fail, and - the resource group will be restarted. - </longdesc> - <shortdesc lang="en"> - Force Unmount - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="options"> - <longdesc lang="en"> - Provides a list of mount options. If none are specified, - the NFS file system is mounted -o sync. - </longdesc> - <shortdesc lang="en"> - Mount Options - </shortdesc> - <content type="string"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="900"/> - <action name="stop" timeout="30"/> - <!-- Recovery isn't possible; we don't know if resources are using - the file system. --> - - <!-- Checks to see if it's mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <!-- Checks to see if we can write to the mountpoint (if !ROFS) --> - <action name="status" depth="20" timeout="30" interval="10m"/> - <action name="monitor" depth="20" timeout="30" interval="10m"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="5"/> - </actions> - - <special tag="rgmanager"> - <child type="nfsexport" forbid="1"/> - <child type="nfsclient" forbid="1"/> - </special> -</resource-agent> -EOT -} - - -verify_name() -{ - [ -n "$OCF_RESKEY_name" ] || exit $OCF_ERR_ARGS -} - - -verify_mountpoint() -{ - if [ -z "$OCF_RESKEY_mountpoint" ]; then - ocf_log err "No mount point specified." - return $OCF_ERR_ARGS - fi - - if ! [ -e "$OCF_RESKEY_mountpoint" ]; then - ocf_log info "Mount point $OCF_RESKEY_mountpoint will be created "\ - "at mount time." - return 0 - fi - - [ -d "$OCF_RESKEY_mountpoint" ] && return 0 - - ocf_log err "$OCF_RESKEY_mountpoint is not a directory" - - return 1 -} - - -verify_host() -{ - if [ -z "$OCF_RESKEY_host" ]; then - ocf_log err "No server hostname or IP address specified." - return 1 - fi - - host $OCF_RESKEY_host 2>&1 | grep -vq "not found" - if [ $? -eq 0 ]; then - return 0 - fi - - ocf_log err "Hostname or IP address "$OCF_RESKEY_host" not valid" - - return $OCF_ERR_ARGS -} - - -verify_fstype() -{ - # Auto detect? - [ -z "$OCF_RESKEY_fstype" ] && return 0 - - case $OCF_RESKEY_fstype in - nfs|nfs4|cifs) - return 0 - ;; - *) - ocf_log err "File system type $OCF_RESKEY_fstype not supported" - return $OCF_ERR_ARGS - ;; - esac -} - - -verify_options() -{ - declare -i ret=0 - - # - # From mount(1) - # - for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do - case $o in - async|atime|auto|defaults|dev|exec|_netdev|noatime) - continue - ;; - noauto|nodev|noexec|nosuid|nouser|ro|rw|suid|sync) - continue - ;; - dirsync|user|users) - continue - ;; - esac - - case $OCF_RESKEY_fstype in - cifs) - continue - ;; - nfs|nfs4) - case $o in - # - # NFS / NFS4 common - # - rsize=*|wsize=*|timeo=*|retrans=*|acregmin=*) - continue - ;; - acregmax=*|acdirmin=*|acdirmax=*|actimeo=*) - continue - ;; - retry=*|port=*|bg|fg|soft|hard|intr|cto|ac|noac) - continue - ;; - esac - - # - # NFS v2/v3 only - # - if [ "$OCF_RESKEY_fstype" = "nfs" ]; then - case $o in - mountport=*|mounthost=*) - continue - ;; - mountprog=*|mountvers=*|nfsprog=*|nfsvers=*) - continue - ;; - namelen=*) - continue - ;; - tcp|udp|lock|nolock) - continue - ;; - esac - fi - - # - # NFS4 only - # - if [ "$OCF_RESKEY_fstype" = "nfs4" ]; then - case $o in - proto=*|clientaddr=*|sec=*) - continue - ;; - esac - fi - - ;; - esac - - ocf_log err "Option $o not supported for $OCF_RESKEY_fstype" - ret=$OCF_ERR_ARGS - done - - return $ret -} - - -verify_all() -{ - verify_name || return $OCF_ERR_ARGS - verify_fstype|| return $OCF_ERR_ARGS - verify_host || return $OCF_ERR_ARGS - verify_mountpoint || return $OCF_ERR_ARGS - verify_options || return $OCF_ERR_ARGS -} - - - -# -# isMounted fullpath mount_point -# -# Check to see if the full path is mounted where we need it. -# -isMounted () { - - typeset mp tmp_mp - typeset fullpath tmp_fullpath - - if [ $# -ne 2 ]; then - ocf_log err "Usage: isMounted host:/export mount_point" - return $FAIL - fi - - fullpath=$1 - mp=$(readlink -f $2) - - while read tmp_fullpath tmp_mp - do - if [ "$tmp_fullpath" = "$fullpath" -a \ - "$tmp_mp" = "$mp" ]; then - return $YES - fi - done < <(mount | awk '{print $1,$3}') - - return $NO -} - -# -# startNFSFilesystem -# -startNFSFilesystem() { - typeset -i ret_val=$SUCCESS - typeset mp="" # mount point - typeset host="" - typeset fullpath="" - typeset exp="" - typeset opts="" - typeset mount_options="" - - # - # Get the mount point, if it exists. If not, no need to continue. - # - mp=${OCF_RESKEY_mountpoint} - case "$mp" in - ""|"[ ]*") # nothing to mount - return $SUCCESS - ;; - /*) # found it - ;; - *) # invalid format - ocf_log err \ -"startFilesystem: Invalid mount point format (must begin with a '/'): '$mp'" - return $FAIL - ;; - esac - # - # Get the device - # - host=${OCF_RESKEY_host} - exp=${OCF_RESKEY_export} - - fullpath=$host:$exp - - # - # Ensure we've got a valid directory - # - if [ -e "$mp" ]; then - if ! [ -d "$mp" ]; then - ocf_log err "\ -startFilesystem: Mount point $mp exists but is not a directory" - return $FAIL - fi - else - ocf_log info "\ -startFilesystem: Creating mount point $mp for $fullpath" - mkdir -p $mp - fi - - # - # See if the mount path is already mounted. - # - isMounted $fullpath $mp - case $? in - $YES) # already mounted - ocf_log debug "$fullpath already mounted on $mp" - return $SUCCESS - ;; - $NO) # not mounted, continue - ;; - $FAIL) - return $FAIL - ;; - esac - - # - # Get the mount options, if they exist. - # - mount_options="" - opts=${OCF_RESKEY_options} - case "$opts" in - ""|"[ ]*") - opts="" - ;; - *) # found it - mount_options="-o $opts" - ;; - esac - - # - # Mount the NFS export - # - ocf_log debug "mount $fstype_option $mount_options $fullpath $mp" - - case $OCF_RESKEY_fstype in - nfs|nfs4) - mount -t $OCF_RESKEY_fstype $mount_options $host:$exp $mp - ;; - cifs) - mount -t $OCF_RESKEY_fstype $mount_options //$host/$exp $mp - ;; - esac - - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err "\ -'mount $fstype_option $mount_options $fullpath $mp' failed, error=$ret_val" - return $FAIL - fi - - return $SUCCESS -} - - -# -# stopFilesystem serviceID deviceID -# -# Run the stop actions -# -stopNFSFilesystem() { - typeset -i ret_val=0 - typeset -i try=1 - typeset -i max_tries=3 # how many times to try umount - typeset -i sleep_time=2 # time between each umount failure - typeset done="" - typeset umount_failed="" - typeset force_umount="" - typeset fstype="" - - - # - # Get the mount point, if it exists. If not, no need to continue. - # - mp=${OCF_RESKEY_mountpoint} - case "$mp" in - ""|"[ ]*") # nothing to mount - return $SUCCESS - ;; - /*) # found it - ;; - *) # invalid format - ocf_log err \ -"stopNFSFilesystem: Invalid mount point format (must begin with a '/'): '$mp'" - return $FAIL - ;; - esac - - # - # Get the host/path - # - fullpath="${OCF_RESKEY_host}:${OCF_RESKEY_export}" - - # - # Get the force unmount setting if there is a mount point. - # - if [ -n "$mp" ]; then - case ${OCF_RESKEY_force_unmount} in - $YES_STR) force_umount="$YES" ;; - 1) force_umount="$YES" ;; - *) force_umount="" ;; - esac - fi - - # - # Unmount - # - while [ ! "$done" ]; do - isMounted $fullpath $mp - case $? in - $NO) - ocf_log debug "$fullpath is not mounted" - umount_failed= - done=$YES - ;; - $FAIL) - return $FAIL - ;; - $YES) - sync; sync; sync - ocf_log info "unmounting $mp" - - umount $mp - ret_val=$? - if [ $ret_val -eq 0 ]; then - umount_failed= - done=$YES - continue - fi - - umount_failed=yes - - if [ "$force_umount" ]; then - if [ $try -eq 1 ]; then - fuser -TERM -kvm "$mp" - else - fuser -kvm "$mp" - fi - fi - - ;; - *) - return $FAIL - ;; - esac - - if [ $try -ge $max_tries ]; then - done=$YES - else - sleep $sleep_time - let try=try+1 - fi - done # while - - if [ -n "$umount_failed" ]; then - ocf_log err "'umount $fullpath' failed ($mp), error=$ret_val" - - return $FAIL - else - return $SUCCESS - fi -} - - -populate_defaults() -{ - if [ -z "$OCF_RESKEY_fstype" ]; then - export OCF_RESKEY_fstype=nfs - fi - - if [ -z "$OCF_RESKEY_options" ]; then - export OCF_RESKEY_options=sync,soft,noac - fi -} - - -# -# Main... -# - -populate_defaults - -case $1 in -start) - startNFSFilesystem - exit $? - ;; -stop) - stopNFSFilesystem - exit $? - ;; -status|monitor) - isMounted ${OCF_RESKEY_host}:${OCF_RESKEY_export} \ - ${OCF_RESKEY_mountpoint} - exit $? - ;; -restart) - stopNFSFilesystem - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - startNFSFilesystem - if [ $? -ne 0 ]; then - exit $OCF_ERR_GENERIC - fi - - exit 0 - ;; -meta-data) - meta_data - exit 0 - ;; -verify-all) - verify_all - exit $? - ;; -*) - echo "usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac - -exit 0 diff --git a/rgmanager/src/resources/nfsclient.sh b/rgmanager/src/resources/nfsclient.sh deleted file mode 100755 index a579bb1..0000000 --- a/rgmanager/src/resources/nfsclient.sh +++ /dev/null @@ -1,478 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2004 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. - - -# -# NFS Export Client handler agent script -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -. $(dirname $0)/ocf-shellfuncs - -meta_data() -{ - cat <<EOT -<?xml version="1.0" ?> -<resource-agent version="rgmanager 2.0" name="nfsclient"> - <version>1.0</version> - - <longdesc lang="en"> - This defines how a machine or group of machines may access - an NFS export on the cluster. IP addresses, IP wildcards, - hostnames, hostname wildcards, and netgroups are supported. - </longdesc> - <shortdesc lang="en"> - Defines an NFS client. - </shortdesc> - - <parameters> - <parameter name="name" unique="1" primary="1"> - <longdesc lang="en"> - This is a symbolic name of a client used to reference - it in the resource tree. This is NOT the same thing - as the target option. - </longdesc> - <shortdesc lang="en"> - Client Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="target" required="1"> - <longdesc lang="en"> - This is either a hostname, a wildcard (IP address or - hostname based), or a netgroup to which defining a - host or hosts to export to. - </longdesc> - <shortdesc lang="en"> - Target Hostname, Wildcard, or Netgroup - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="path" inherit="path"> - <longdesc lang="en"> - This is the path to export to the target. This - field is generally left blank, as it inherits the - path from the parent export. - </longdesc> - <shortdesc lang="en"> - Path to Export - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="fsid" inherit="fsid"> - <longdesc lang="en"> - File system ID inherited from the parent nfsexport/ - clusterfs/fs resource. Putting fsid in the options - field will override this. - </longdesc> - <shortdesc lang="en"> - File system ID - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="nfslock" inherit="service%nfslock"> - <longdesc lang="en"> - This tells us whether the service in question has the - NFS lock workarounds enabled. If so, we always unexport - * rather than the specified client. - </longdesc> - <shortdesc lang="en"> - NFS Lock workaround flag - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="options"> - <longdesc lang="en">Defines a list of options for this - particular client. See 'man 5 exports' for a list - of available options. - </longdesc> - <shortdesc lang="en"> - Export Options - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="allow_recover"> - <longdesc lang="en"> - Allows recovery of this NFS client (default = 1) if it - disappears from the export list. If set to 0, the service - will be restarted. This is useful to help preserve export - ordering. - </longdesc> - <shortdesc lang="en"> - Allow recovery - </shortdesc> - <content type="boolean"/> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Service this NFS export belongs to. Used for caching - exports on a per-service basis. - </longdesc> - <shortdesc lang="en"> - Service Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="use_cache" inherit="service%nfs_client_cache"> - <longdesc lang="en"> - On systems with large numbers of exports, a performance - problem in the exportfs command can cause inordinately long - status check times for services with lots of mounted - NFS clients. This occurs because exportfs does DNS queries - on all clients in the export list. - - Setting this option to '1' will enable caching of the export - list returned from the exportfs command on a per-service - basis. The cache will last for 30 seconds before expiring - instead of being generated each time an nfsclient resource - is called. - </longdesc> - <shortdesc lang="en"> - Enable exportfs list caching - </shortdesc> - <content type="integer"/> - </parameter> - - - </parameters> - - <actions> - <action name="start" timeout="90"/> - <action name="stop" timeout="5"/> - <action name="recover" timeout="90"/> - - <!-- Checks to see if the export exists in /var/lib/nfs/etab --> - <action name="status" timeout="5" interval="1m"/> - <action name="monitor" timeout="5" interval="1m"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="30"/> - </actions> - -</resource-agent> -EOT -} - - -verify_options() -{ - declare o - declare -i ret=0 - - [ -z "$OCF_RESKEY_options" ] && return 0 - - # - # From exports(5) - # - for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do - case $o in - fsid=*) - ocf_log debug "Using designated $o instead of fsid=$OCF_RESKEY_fsid" - unset OCF_RESKEY_fsid - ;; - secure) - ;; - insecure) - ;; - - rw) - ;; - ro) - ;; - async) - ;; - sync) - ;; - wdelay) - ;; - no_wdelay) - ;; - hide) - ;; - nohide) - ;; - subtree_check) - ;; - no_subtree_check) - ;; - secure_locks) - ;; - insecure_locks) - ;; - auth_nlm) - ;; - no_auth_nlm) - ;; - mountpoint=*) - ;; - mp=*) - ;; - root_squash) - ;; - no_root_squash) - ;; - all_squash) - ;; - no_all_squash) - ;; - anonuid=*) - ;; - anongid=*) - ;; - *) - ocf_log err "Export Option $o invalid" - ret=$OCF_ERR_ARGS - ;; - esac - done - - return $ret -} - - -verify_target() -{ - # XXX need to add wildcards, hostname, ip, etc. - [ -n "$OCF_RESKEY_target" ] && return 0 - - return $OCF_ERR_ARGS -} - - -verify_path() -{ - if [ -z "$OCF_RESKEY_path" ]; then - ocf_log err "No export path specified." - return $OCF_ERR_ARGS - fi - - [ -d "$OCF_RESKEY_path" ] && return 0 - - ocf_log err "$OCF_RESKEY_path is not a directory" - - return $OCF_ERR_ARGS -} - - -verify_type() -{ - [ -z "$OCF_RESKEY_type" ] && return 0 - [ "$OCF_RESKEY_type" = "nfs" ] && return 0 - - ocf_log err "Export type $OCF_RESKEY_type not supported yet" - return $OCF_ERR_ARGS -} - - -verify_all() -{ - declare -i ret=0 - - verify_type || ret=$OCF_ERR_ARGS - verify_options || ret=$OCF_ERR_ARGS - verify_target || ret=$OCF_ERR_ARGS - verify_path || ret=$OCF_ERR_ARGS - - return $ret -} - - -case $1 in -start) - declare option_str - - verify_all || exit $OCF_ERR_ARGS - - # - # XXX - # Bad: Side-effect of verify_options: unset OCF_RESKEY_fsid if - # fsid is specified in the options string. - # - if [ -z "$OCF_RESKEY_options" ] && [ -n "$OCF_RESKEY_fsid" ]; then - option_str="fsid=$OCF_RESKEY_fsid" - elif [ -n "$OCF_RESKEY_options" ] && [ -z "$OCF_RESKEY_fsid" ]; then - option_str="$OCF_RESKEY_options" - elif [ -n "$OCF_RESKEY_fsid" ] && [ -n "$OCF_RESKEY_options" ]; then - option_str="fsid=$OCF_RESKEY_fsid,$OCF_RESKEY_options" - fi - - if [ -z "$option_str" ]; then - ocf_log info "Adding export: ${OCF_RESKEY_target}:${OCF_RESKEY_path}" - exportfs -i "${OCF_RESKEY_target}:${OCF_RESKEY_path}" - rv=$? - else - ocf_log info "Adding export: ${OCF_RESKEY_target}:${OCF_RESKEY_path} ($option_str)" - exportfs -i -o $option_str "${OCF_RESKEY_target}:${OCF_RESKEY_path}" - rv=$? - fi - ;; - -stop) - verify_all || exit $OCF_ERR_ARGS - - #if [ "$OCF_RESKEY_nfslock" = "1" ]; then - # - # If the NFS lock workarounds were enabled, unexport from - # the world - # - # Per https://bugzilla.redhat.com/show_bug.cgi?id=292861 - # This breaks unexport! - # - #export OCF_RESKEY_target="*" - #fi - - ocf_log info "Removing export: ${OCF_RESKEY_target}:${OCF_RESKEY_path}" - exportfs -u "${OCF_RESKEY_target}:${OCF_RESKEY_path}" - rv=$? - ;; - -status|monitor) - verify_all || exit $OCF_ERR_ARGS - - if [ "${OCF_RESKEY_target}" = "*" ]; then - export OCF_RESKEY_target="<world>" - fi - - # - # Status check fix from Birger Wathne: - # * Exports longer than 14 chars have line breaks inserted, which - # broke the way the status check worked. - # - # Status check fix from Craig Lewis: - # * Exports with RegExp metacharacters need to be escaped. - # These metacharacters are: * ? . - # - export OCF_RESKEY_target_regexp=$(echo $OCF_RESKEY_target | \ - sed -e 's/*/[*]/g' -e 's/?/[?]/g' -e 's/./\./g') - - declare tmpfn - declare time_created time_now - declare -i delta=0 - - # - # Don't let anyone read the cache files. - # - umask 066 - - mkdir -p /var/cache/cluster - - if [ -n "$OCF_RESKEY_service_name" ] && [ "$OCF_RESKEY_use_cache" = "1" ]; then - - # - # For large #s of exports, we need to cache the information - # - tmpfn=/var/cache/cluster/nfsclient-status-cache-$OCF_RESKEY_service_name - - if [ -f "$tmpfn" ]; then - time_created=$(stat -c "%Y" $tmpfn) - time_now=$(date +"%s") - delta=$((time_now-time_created)) - fi - #echo "Cache age = $delta seconds" - else - delta=100 - # - # Create a different file if this is a separate instance - # - tmpfn=/var/cache/cluster/nfsclient-status-cache-$$ - fi - - if ! [ -f "$tmpfn" ] || [ $delta -gt 30 ]; then - #echo "Create $tmpfn. Nonexistent / expired / no service name" - exportfs -v > $tmpfn - fi - - cat $tmpfn | tr -d "\n" | sed -e 's/([^)]*)/\n/g' | grep -iq \ - "^${OCF_RESKEY_path}[\t ]*.*${OCF_RESKEY_target_regexp}" - rv=$? - - if [ $rv -eq 0 ]; then - [ "$OCF_RESKEY_use_cache" = "1" ] || rm -f $tmpfn - exit 0 - fi - - declare OCF_RESKEY_target_tmp=$(clufindhostname -i "$OCF_RESKEY_target") - if [ $? -ne 0 ]; then - [ "$OCF_RESKEY_use_cache" = "1" ] || rm -f $tmpfn - ocf_log err "nfsclient:$OCF_RESKEY_name is missing!" - exit 1 - fi - - cat $tmpfn | tr -d "\n" | sed -e 's/([^)]*)/\n/g' | grep -q \ - "^${OCF_RESKEY_path}[\t ]*.*${OCF_RESKEY_target_tmp}" - rv=$? - - [ "$OCF_RESKEY_use_cache" = "1" ] || rm -f $tmpfn - if [ $rv -eq 0 ]; then - exit 0 - fi - - ocf_log err "nfsclient:$OCF_RESKEY_name is missing!" - exit 1 - ;; - -recover) - if [ "$OCF_RESKEY_allow_recover" = "0" ] || \ - [ "$OCF_RESKEY_allow_recover" = "no" ] || \ - [ "$OCF_RESKEY_allow_recover" = "false" ]; then - exit 1 - fi - - $0 stop || exit 1 - $0 start || exit 1 - ;; - -restart) - # - # Recover might better be "exportfs -r" - reexport - # - $0 stop || exit 1 - $0 start || exit 1 - ;; - -meta-data) - meta_data - exit 0 - ;; - -verify-all) - verify_all - rv=$? - ;; - -*) - echo "usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - rv=$OCF_ERR_GENERIC - ;; -esac - -exit $rv diff --git a/rgmanager/src/resources/nfsexport.sh b/rgmanager/src/resources/nfsexport.sh deleted file mode 100755 index e5afa85..0000000 --- a/rgmanager/src/resources/nfsexport.sh +++ /dev/null @@ -1,278 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2002-2004 -# Copyright Mission Critical Linux, 2000 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# NFS Export Script. Handles starting/stopping clurmtabd and doing -# the strange NFS stuff to get it to fail over properly. -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -. $(dirname $0)/ocf-shellfuncs - - -rmtabpid="" -nfsop_arg="" -rv=0 - -meta_data() -{ - cat <<EOT -<?xml version="1.0" ?> -<resource-agent name="nfsexport" version="rgmanager 2.0"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an NFS export path. Generally, these are - defined inline and implicitly; you should not have to - configure one of these. All of the relevant information - is inherited from the parent. - </longdesc> - - <shortdesc lang="en"> - This defines an NFS export. - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Descriptive name for this export. Generally, only - one export is ever defined, and it's called "generic - nfs export". - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="device" inherit="device"> - <longdesc lang="en"> - If you can see this, your GUI is broken. - </longdesc> - <shortdesc lang="en"> - If you can see this, your GUI is broken. - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="path" inherit="mountpoint"> - <longdesc lang="en"> - If you can see this, your GUI is broken. - </longdesc> - <shortdesc lang="en"> - If you can see this, your GUI is broken. - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="fsid" inherit="fsid"> - <longdesc lang="en"> - If you can see this, your GUI is broken. - </longdesc> - <shortdesc lang="en"> - If you can see this, your GUI is broken. - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="nfslock" inherit="service%nfslock"> - <longdesc lang="en"> - If you can see this, your GUI is broken. - This inherits an unspecified nfslock parameter so that - it works with fs or clusterfs resources. - </longdesc> - <shortdesc lang="en"> - If you can see this, your GUI is broken. - </shortdesc> - <content type="boolean"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="5"/> - <action name="stop" timeout="5"/> - <action name="recover" timeout="5"/> - - <!-- NFS Exports really don't do anything except provide a path - for nfs clients. So, status and monitor are no-ops --> - <action name="status" timeout="5" interval="1h"/> - <action name="monitor" timeout="5" interval="1h"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="30"/> - </actions> - - <special tag="rgmanager"> - <child type="nfsexport" forbid="1"/> - <child type="nfsclient"/> - </special> - -</resource-agent> -EOT -} - - -verify_device() -{ - if [ -z "$OCF_RESKEY_device" ]; then - ocf_log err "No device or label specified." - return $OCF_ERR_ARGS - fi - - [ -b "$OCF_RESKEY_device" ] && return 0 - [ -b "`findfs $OCF_RESKEY_device`" ] && return 0 - - ocf_log err "Device or label "$OCF_RESKEY_device" not valid" - - return $OCF_ERR_ARGS -} - - -verify_path() -{ - if [ -z "$OCF_RESKEY_path" ]; then - ocf_log err "No export path specified." - return $OCF_ERR_ARGS - fi - - [ -d "$OCF_RESKEY_path" ] && return 0 - - ocf_log err "$OCF_RESKEY_path is not a directory" - - return $OCF_ERR_ARGS -} - - -verify_all() -{ - declare -i ret=0 - - verify_device || ret=$OCF_ERR_ARGS - verify_path || ret=$OCF_ERR_ARGS - - return $ret -} - - -# -# Check if the NFS daemons are running. -# -nfs_daemons_running() -{ - declare NFS_DAEMONS="nfsd rpc.mountd rpc.statd" - - for daemon in $NFS_DAEMONS; do - ps -ef | grep "$daemon" | grep -v grep >/dev/null 2>&1 - if [ $? -ne 0 ]; then - ocf_log err \ - "NFS daemon $daemon is not running." - ocf_log err \ - "Verify that the NFS service run level script is enabled." - return 1 - fi - done - - return 0 -} - - -nfs_check() -{ - declare junk - - if nfs_daemons_running; then - return 0 - fi - - # - # Don't restart daemons during status check. - # - if [ "$1" = "status" ]; then - return 1; - fi - - ocf_log err "Restarting NFS daemons" - # Note restart does less than stop/start - junk=$(/sbin/service nfslock stop) - junk=$(/sbin/service nfslock start) - junk=$(/sbin/service nfs stop) - junk=$(/sbin/service nfs start) - sleep 2 - - if ! nfs_daemons_running; then - ocf_log err "Failed restarting NFS daemons" - return 1 - fi - ocf_log notice "Successfully restarted NFS daemons" -} - - -case $1 in -start) - nfs_check start || exit 1 - rv=0 - ;; - -status|monitor) - nfs_check status || exit 1 - rv=0 - ;; - -stop) - nfs_check restart || exit 1 - rv=0 - ;; - -recover|restart) - $0 stop || exit $OCF_ERR_GENERIC - $0 start || exit $OCF_ERR_GENERIC - rv=0 - ;; - -meta-data) - meta_data - rv=0 - ;; - -verify-all) - verify_all - rv=$? - ;; -*) - echo "usage: $0 {start|status|monitor|stop|recover|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac - -# -# Flush NFS request queue. This might be done in the ip resource in the -# future, but keep this around for now. -# -# clunfsops $nfsop_arg -d ${OCF_RESKEY_device} -# - -exit $rv diff --git a/rgmanager/src/resources/ocf-shellfuncs b/rgmanager/src/resources/ocf-shellfuncs deleted file mode 100755 index 98156c0..0000000 --- a/rgmanager/src/resources/ocf-shellfuncs +++ /dev/null @@ -1,185 +0,0 @@ -# -# $Id$ -# -# Common helper functions for the OCF Resource Agents supplied by -# heartbeat. -# -# Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Br���e -# All Rights Reserved. -# -# Modified for linux-cluster 2005 by Lon Hohberger -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - - -# TODO: Some of this should probably split out into a generic OCF -# library for shell scripts, but for the time being, we'll just use it -# ourselves... -# - -# TODO wish-list: -# - Generic function for evaluating version numbers -# - Generic function(s) to extract stuff from our own meta-data -# - Logging function which automatically adds resource identifier etc -# prefixes -# TODO: Move more common functionality for OCF RAs here. -# -__SCRIPT_NAME=`basename $0` - -# lhh - determine if we're a dumb terminal -consoletype &> /dev/null -if [ $? -eq 1 ]; then - __SERIAL="yes" -fi - -__LOG_PID=$PPID -__LOG_NAME=$(basename $(readlink /proc/$PPID/exe)) - -pretty_echo() { - declare pretty - declare n="[0m" - declare __OCF_PRIO="$1" - shift - declare __OCF_MSG="$*" - - if [ -n "$__SERIAL" ]; then - echo "<$__OCF_PRIO> $__OCF_MSG" - return 0 - fi - - case $__OCF_PRIO in - emerg) pretty="[34;1;5m";; - alert) pretty="[34;1m";; - crit|critical) pretty="[34;1m";; - err|error) pretty="[0;34m";; - warn|warning) pretty="[35;1m";; - note|notice) pretty="[37;1m";; - info) pretty="[37;1m";; - debug|dbg) pretty="[0m";; - *) pretty="[37;1m";; - esac - - echo "$n<$pretty$__OCF_PRIO$n> [10G$__OCF_MSG" - return 0 -} - -__ocf_set_defaults() { - __OCF_ACTION="$1" - - # Return to sanity for the agents... - unset LANG - LC_ALL=C - export LC_ALL - - # TODO: Review whether we really should source this. Or rewrite - # to match some emerging helper function syntax...? This imports - # things which no OCF RA should be using... - - OCF_SUCCESS=0 - OCF_ERR_GENERIC=1 - OCF_ERR_ARGS=2 - OCF_ERR_UNIMPLEMENTED=3 - OCF_ERR_PERM=4 - OCF_ERR_INSTALLED=5 - OCF_ERR_CONFIGURED=6 - OCF_NOT_RUNNING=7 - - if [ -z "$OCF_RESOURCE_TYPE" ]; then - : ${OCF_RESOURCE_TYPE:=$__SCRIPT_NAME} - fi - - if [ -z "$OCF_RA_VERSION_MAJOR" ]; then - : We are being invoked as an init script. - : Fill in some things with reasonable values. - : ${OCF_RESOURCE_INSTANCE:="default"} - return 0 - fi - - if [ -z "$OCF_ROOT" ]; then - OCF_ROOT=$(dirname $0) - fi - if [ ! -d "$OCF_ROOT" ]; then - ocf_log err "OCF_ROOT points to non-directory $OCF_ROOT." - exit $OCF_ERR_GENERIC - fi - - # TODO: Anything else we should be setting and thus checking? - # There is nothing in this script which depends on the version - # of the API. TESTING THIS HERE IS A BUG. THIS SHOULD BE - # tested by the script that's invoked us. FIXME!! - if [ "x$OCF_RA_VERSION_MAJOR" != "x1" ]; then - ocf_log err "This script is OCF RA API 1.x compliant only!" - exit $OCF_ERR_UNIMPLEMENTED - fi - # TODO: Should the minor level really be a number and not rather - # a list of flags...? - # AlanR says -- absolutely not -- a list of flags is good for a list - # of implemented features, not a version compiliance - # perhaps some future version might have such a list of - # flags, but that would be _in addition to_ the minor version number - if [ -z "$OCF_RA_VERSION_MINOR" ]; then - ocf_log err "No OCF RA minor version set." - exit $OCF_ERR_UNIMPLEMENTED - fi - - if [ "x$__OCF_ACTION" = "xmeta-data" ]; then - OCF_RESOURCE_INSTANCE="undef" - fi - - if [ -z "$OCF_RESOURCE_INSTANCE" ]; then - ocf_log err "Need to tell us our resource instance name." - exit $OCF_ERR_ARGS - fi -} - - -ocf_log() { - # TODO: Revisit and implement internally. - if - [ $# -lt 2 ] - then - ocf_log err "Not enough arguments [$#] to ocf_log." - fi - - declare __OCF_PRIO="$1" - declare -i __OCF_PRIO_N - - shift - - declare __OCF_MSG="$*" - - case "${__OCF_PRIO}" in - emerg) __OCF_PRIO_N=0;; # Not in original ocf-shellfuncs - alert) __OCF_PRIO_N=1;; # Not in original ocf-shellfuncs - crit|critical) __OCF_PRIO_N=2;; - err|error) __OCF_PRIO_N=3;; - warn|warning) __OCF_PRIO_N=4;; - note|notice) __OCF_PRIO_N=5;; # Not in original ocf-shellfuncs - info) __OCF_PRIO_N=6;; - debug|dbg) __OCF_PRIO_N=7;; - *) __OCF_PRIO_N=5;; # Defaults to INFO - esac - - pretty_echo $__OCF_PRIO "$__OCF_MSG" - - if [ -z "`which clulog 2> /dev/null`" ]; then - return 0 - fi - clulog -p $__LOG_PID -n $__LOG_NAME \ - -s $__OCF_PRIO_N "$__OCF_MSG" -} - -__ocf_set_defaults "$@" diff --git a/rgmanager/src/resources/openldap.metadata b/rgmanager/src/resources/openldap.metadata deleted file mode 100644 index 07d2e84..0000000 --- a/rgmanager/src/resources/openldap.metadata +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="openldap"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an instance of Open LDAP - </longdesc> - <shortdesc lang="en"> - Defines an Open LDAP server - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Specifies a service name for logging and other purposes - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define absolute path to configuration file - </longdesc> - <shortdesc lang="en"> - Config File - </shortdesc> - <content type="string" default="/etc/openldap/slapd.conf"/> - </parameter> - - <parameter name="url_list"> - <longdesc lang="en"> - Serve URL list. Default behaviour of URL list is changed and - enhanced. eg. ldap:/// won't bind all IP address on the - computer but to all IP addresses in service. Using - ldap://0:port/ will bind to all IP addresses for service on - given port. - </longdesc> - <shortdesc lang="en"> - URL list - </shortdesc> - <content type="string" default="ldap:///"/> - </parameter> - - <parameter name="slapd_options"> - <longdesc lang="en"> - Other command-line options for slapd - </longdesc> - <shortdesc lang="en"> - Other command-line options for slapd - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- Checks to see if it''s mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> - - <special tag="rgmanager"> - </special> -</resource-agent> diff --git a/rgmanager/src/resources/openldap.sh b/rgmanager/src/resources/openldap.sh deleted file mode 100755 index 5b9c893..0000000 --- a/rgmanager/src/resources/openldap.sh +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare LDAP_SLAPD=/usr/sbin/slapd -declare LDAP_pid_file="`generate_name_for_pid_file`" -declare LDAP_conf_dir="`generate_name_for_conf_dir`" -declare LDAP_gen_config_file="$LDAP_conf_dir/slapd.conf" -declare LDAP_url_list - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ ! -r "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE $OCF_RESKEY_config_file - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - clog_service_verify $CLOG_SUCCEED - - return 0 -} - -generate_url_list() -{ - declare ldap_url_source=$1 - declare ip_addresses=$2 - declare url_list - declare tmp; - - for u in $ldap_url_source; do - if [[ "$u" =~ ':///' ]]; then - for z in $ip_addresses; do - tmp=`echo $u | sed "s,://,://$z,"` - url_list="$url_list $tmp" - done - elif [[ "$u" =~ '://0:' ]]; then - for z in $ip_addresses; do - tmp=`echo $u | sed "s,://0:,://$z:,"` - url_list="$url_list $tmp" - done - else - url_list="$url_list $u" - fi - done - - echo $url_list -} - -generate_config_file() -{ - declare original_file="$1" - declare generated_file="$2" - - if [ -f "$generated_file" ]; then - sha1_verify "$generated_file" - if [ $? -ne 0 ]; then - clog_check_sha1 $CLOG_FAILED - return 0 - fi - fi - - clog_generate_config $CLOG_INIT "$original_file" "$generated_file" - - generate_configTemplate "$generated_file" "$1" - echo "pidfile "$LDAP_pid_file"" >> $generated_file - echo >> $generated_file - sed 's/^[[:space:]]*pidfile/### pidfile/i' < "$original_file" >> "$generated_file" - - sha1_addToFile "$generated_file" - clog_generate_config $CLOG_SUCCEED "$original_file" "$generated_file" - - return 0; -} - -start() -{ - declare ccs_fd; - - clog_service_start $CLOG_INIT - - create_pid_directory - create_conf_directory "$LDAP_conf_dir" - check_pid_file "$LDAP_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$LDAP_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - clog_looking_for $CLOG_INIT "IP Addresses" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -z "$ip_addresses" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_SUCCEED "IP Addresses" - - LDAP_url_list=`generate_url_list "$OCF_RESKEY_url_list" "$ip_addresses"` - - if [ -z "$LDAP_url_list" ]; then - ocf_log error "Generating URL List for $OCF_RESOURCE_INSTANCE > Failed" - return $OCF_ERR_GENERIC - fi - - generate_config_file "$OCF_RESKEY_config_file" "$LDAP_gen_config_file" - - $LDAP_SLAPD -f "$LDAP_gen_config_file" -n "$OCF_RESOURCE_INSTANCE" \ - -h "$LDAP_url_list" $OCF_RESKEY_slapd_options - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_start $CLOG_SUCCEED - - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$LDAP_pid_file" "$OCF_RESKEY_shutdown_wait" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$LDAP_pid_file" - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$LDAP_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - verify-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac diff --git a/rgmanager/src/resources/oracledb.sh b/rgmanager/src/resources/oracledb.sh deleted file mode 100755 index a415dc0..0000000 --- a/rgmanager/src/resources/oracledb.sh +++ /dev/null @@ -1,869 +0,0 @@ -#!/bin/bash -# -# Copyright 2003-2004, 2006-2007 Red Hat, Inc. -# -# Author(s): -# Hardy Merrill <hmerrill at redhat.com> -# Lon Hohberger <lhh at redhat.com> -# Michael Moon <Michael dot Moon at oracle.com> -# -# This program is Open Source software. You may modify and/or redistribute -# it persuant to the terms of the Open Software License version 2.1, which -# is available from the following URL and is included herein by reference: -# -# http://opensource.org/licenses/osl-2.1.php -# -# chkconfig: 345 99 01 -# description: Service script for starting/stopping \ -# Oracle(R) Database 10g on \ -# Red Hat Enterprise Linux 5 -# -# NOTES: -# -# (1) You can comment out the LOCKFILE declaration below. This will prevent -# the need for this script to access anything outside of the ORACLE_HOME -# path. -# -# (2) You MUST customize ORACLE_USER, ORACLE_HOME, ORACLE_SID, and -# ORACLE_HOSTNAME to match your installation if not running from within -# rgmanager. -# -# (3) Do NOT place this script in shared storage; place it in ORACLE_USER's -# home directory in non-clustered environments and /usr/share/cluster -# in rgmanager/Red Hat cluster environments. -# -# Oracle is a registered trademark of Oracle Corporation. -# Oracle9i is a trademark of Oracle Corporation. -# Oracle10g is a trademark of Oracle Corporation. -# All other trademarks are property of their respective owners. -# - -. /etc/init.d/functions - -# -# Source stuff from /etc/sysconfig, but this may be overridden if -# this is being called as a cluster resource agent instead. -#. /etc/sysconfig/oracledb - -declare SCRIPT="`basename $0`" -declare SCRIPTDIR="`dirname $0`" - -[ -n "$OCF_RESKEY_user" ] && ORACLE_USER=$OCF_RESKEY_user -[ -n "$OCF_RESKEY_home" ] && ORACLE_HOME=$OCF_RESKEY_home -[ -n "$OCF_RESKEY_name" ] && ORACLE_SID=$OCF_RESKEY_name -[ -n "$OCF_RESKEY_lockfile" ] && LOCKFILE=$OCF_RESKEY_lockfile -[ -n "$OCF_RESKEY_type" ] && ORACLE_TYPE=$OCF_RESKEY_type -[ -n "$OCF_RESKEY_vhost" ] && ORACLE_HOSTNAME=$OCF_RESKEY_vhost - -###################################################### -# Customize these to match your Oracle installation. # -###################################################### -# -# 1. Oracle user. Must be the same across all cluster members. In the event -# that this script is run by the super-user, it will automatically switch -# to the Oracle user and restart. Oracle needs to run as the Oracle -# user, not as root. -# -#[ -n "$ORACLE_USER" ] || ORACLE_USER=oracle - -# -# 2. Oracle home. This is set up during the installation phase of Oracle. -# From the perspective of the cluster, this is generally the mount point -# you intend to use as the mount point for your Oracle Infrastructure -# service. -# -#[ -n "$ORACLE_HOME" ] || ORACLE_HOME=/mnt/oracle/home - -# -# 3. This is your SID. This is set up during oracle installation as well. -# -#[ -n "$ORACLE_SID" ] || ORACLE_SID=orcl - -# -# 4. The oracle user probably doesn't have the permission to write to -# /var/lock/subsys, so use the user's home directory. -# -#[ -n "$LOCKFILE" ] || LOCKFILE="/home/$ORACLE_USER/.oracle-ias.lock" -[ -n "$LOCKFILE" ] || LOCKFILE="$ORACLE_HOME/.oracle-ias.lock" -#[ -n "$LOCKFILE" ] || LOCKFILE="/var/lock/subsys/oracle-ias" # Watch privileges - -# -# 5. Type of Oracle Database. Currently supported: 10g 10g-iAS(untested!) -# -[ -n "$ORACLE_TYPE" ] || ORACLE_TYPE=10g - -# -# 6. Oracle virtual hostname. This is the hostname you gave Oracle during -# installation. -# -#[ -n "$ORACLE_HOSTNAME" ] || ORACLE_HOSTNAME=svc0.foo.test.com - - - -########################################################################### -ORACLE_TYPE=`echo $ORACLE_TYPE | tr A-Z a-z` -export ORACLE_USER ORACLE_HOME ORACLE_SID LOCKFILE ORACLE_TYPE -export ORACLE_HOSTNAME - - -########################## -# Set up paths we'll use. Not all are used by all the different types of -# Oracle installations -# -export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/opmn/lib -export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/opmn/bin:$ORACLE_HOME/dcm/bin:$PATH - -declare -i RESTART_RETRIES=3 -declare -r DB_PROCNAMES="pmon" -#declare -r DB_PROCNAMES="pmonXX" # testing -#declare -r DB_PROCNAMES="pmon smon dbw0 lgwr" - -declare -r LSNR_PROCNAME="tnslsnr" -#declare -r LSNR_PROCNAME="tnslsnrXX" # testing - - -########################################################## -# (Hopefully) No user-serviceable parts below this line. # -########################################################## -meta_data() -{ - cat <<EOT -<?xml version="1.0" ?> -<resource-agent name="oracledb" version="rgmanager 2.0"> - <version>1.0</version> - - <longdesc lang="en"> - Oracle 10g Failover Instance - </longdesc> - <shortdesc lang="en"> - Oracle 10g Failover Instance - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Instance name (SID) of oracle instance - </longdesc> - <shortdesc lang="en"> - Oracle SID - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="user" unique="1" required="1"> - <longdesc lang="en"> - Oracle user name. This is the user name of the Oracle - user which the Oracle AS instance runs as. - </longdesc> - <shortdesc lang="en"> - Oracle User Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="home" unique="1" required="1"> - <longdesc lang="en"> - This is the Oracle (application, not user) home directory. - This is configured when you install Oracle. - </longdesc> - <shortdesc lang="en"> - Oracle Home Directory - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="type" required="1"> - <longdesc lang="en"> - This is the Oracle installation type. - Only "10g" and "10g-ias" are supported, and 10g-ias is - untested. - </longdesc> - <shortdesc lang="en"> - Oracle Installation Type - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="vhost" required="0" unique="1"> - <longdesc lang="en"> - Virtual Hostname matching the installation hostname of - Oracle 10g. Note that during the start/stop of an oracledb - resource, your hostname will temporarily be changed to - this hostname. As such, it is recommended that oracledb - resources be instanced as part of an exclusive service only. - </longdesc> - <shortdesc lang="en"> - Virtual Hostname - </shortdesc> - <content type="string"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="900"/> - <action name="stop" timeout="90"/> - <action name="recover" timeout="990"/> - - <!-- Checks to see if it's mounted in the right place --> - <action name="status" timeout="10"/> - <action name="monitor" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <!-- Checks to see if we can write to the mountpoint (if !ROFS) --> - <action name="status" depth="20" timeout="90" interval="10m"/> - <action name="monitor" depth="20" timeout="90" interval="10m"/> - - <action name="meta-data" timeout="5"/> - <action name="verify-all" timeout="5"/> - </actions> - - <special tag="rgmanager"> - <attributes maxinstances="1"/> - </special> -</resource-agent> -EOT -} - - -# -# "action"-like macro supporting functions -# -faction() -{ - echo -n "$1" - shift - $* - if [ $? -eq 0 ]; then - echo_success - echo - return 0 - fi - - echo_failure - echo - return 1 -} - - -# -# Start Oracle9i (database portion) -# -start_db() -{ - declare tmpfile - declare logfile - declare -i rv - - tmpfile=$(mktemp /tmp/$SCRIPT-start.tmp.XXXXXX) - logfile=$(mktemp /tmp/$SCRIPT-start.log.XXXXXX) - - # - # Set up our sqlplus script. Basically, we're trying to - # capture output in the hopes that it's useful in the case - # that something doesn't work properly. - # - echo "startup" > $tmpfile - echo "quit" >> $tmpfile - - sqlplus "/ as sysdba" < $tmpfile &> $logfile - rv=$? - - # Dump logfile to /var/log/messages - initlog -q -c "cat $logfile" - - if [ $rv -ne 0 ]; then - echo "ORACLE_HOME Incorrectly set?" - echo "See $logfile for more information." - return 1 - fi - - # - # If we see: - # ORA-.....: failure, we failed - # - - rm -f $tmpfile - grep -q "failure" $logfile - if [ $? -eq 0 ]; then - rm -f $tmpfile - echo "ORACLE_SID Incorrectly set?" - echo "See $logfile for more information." - return 1 - fi - - return 0 -} - - -# -# Stop Oracle9i (database portion) -# -stop_db() -{ - declare tmpfile - declare logfile - declare -i rv - - tmpfile=$(mktemp /tmp/$SCRIPT-stop.tmp.XXXXXX) - logfile=$(mktemp /tmp/$SCRIPT-stop.log.XXXXXX) - - # Setup for Stop ... - echo "shutdown abort" > $tmpfile - echo "quit" >> $tmpfile - - sqlplus "/ as sysdba" < $tmpfile &> $logfile - rv=$? - - # Dump logfile to /var/log/messages - initlog -q -c "cat $logfile" - - if [ $rv -ne 0 ]; then - echo "ORACLE_HOME Incorrectly set?" - echo "See $logfile for more information." - return 1 - fi - - # - # If we see 'failure' in the log, we're done. - # - rm -f $tmpfile - grep -q failure $logfile - if [ $? -eq 0 ]; then - echo_failure - echo - echo "Possible reason: ORACLE_SID Incorrectly set." - echo "See $logfile for more information." - return 1 - fi - - return 0 -} - - -# -# Destroy any remaining processes with refs to $ORACLE_HOME -# -force_cleanup() -{ - declare pids - declare pid - - pids=`ps ax | grep $ORACLE_HOME | grep -v grep | awk '{print $1}'` - - initlog -n $SCRIPT -s "<err> Not all Oracle processes exited cleanly, killing" - - for pid in $pids; do - kill -9 $pid - if [ $? -eq 0 ]; then - initlog -n $SCRIPT -s "Killed $pid" - fi - done - - return 0 -} - - - -# -# Wait for oracle processes to exit. Time out after 60 seconds -# -exit_idle() -{ - declare -i n=0 - while ps ax | grep $ORACLE_HOME | grep -q -v grep; do - if [ $n -ge 90 ]; then - force_cleanup - return 0 - fi - sleep 1 - ((n++)) - done - return 0 -} - - -# -# Get database background process status. Restart it if it failed and -# we have seen the lock file. -# -get_db_status() -{ - declare -i subsys_lock=$1 - declare -i i=0 - declare -i rv=0 - declare ora_procname - - for procname in $DB_PROCNAMES ; do - - ora_procname="ora_${procname}_${ORACLE_SID}" - - status $ora_procname - if [ $? -eq 0 ] ; then - # This one's okay; go to the next one. - continue - fi - - # - # We're not supposed to be running, and we are, - # in fact, not running... - # XXX only works when monitoring one db process; consider - # extending in future. - # - if [ $subsys_lock -ne 0 ]; then - return 3 - fi - - for (( i=$RESTART_RETRIES ; i; i-- )) ; do - # this db process is down - stop and - # (re)start all ora_XXXX_$ORACLE_SID processes - initlog -q -n $SCRIPT -s "Restarting Oracle Database..." - stop_db - if [ $? != 0 ] ; then - # stop failed - return 1 - return 1 - fi - - start_db - if [ $? == 0 ] ; then - # ora_XXXX_$ORACLE_SID processes started - # successfully, so break out of the - # stop/start # 'for' loop - break - fi - done - - if [ $i -eq 0 ]; then - # stop/start's failed - return 1 (failure) - return 1 - fi - done - return 0 -} - - -# -# Get the status of the Oracle listener process -# -get_lsnr_status() -{ - declare -i subsys_lock=$1 - declare -i rv - - status $LSNR_PROCNAME - rv=$? - if [ $rv == 0 ] ; then - return 0 # Listener is running fine - fi - - # - # We're not supposed to be running, and we are, - # in fact, not running. Return 3 - # - if [ $subsys_lock -ne 0 ]; then - return 3 - fi - - # - # Listener is NOT running (but should be) - try to restart - # - for (( i=$RESTART_RETRIES ; i; i-- )) ; do - - action "Restarting Oracle listener:" lsnrctl start - lsnrctl status >& /dev/null - if [ $? == 0 ] ; then - break # Listener was (re)started and is running fine - fi - done - - if [ $i -eq 0 ]; then - # stop/start's failed - return 1 (failure) - return 1 - fi - - status $LSNR_PROCNAME - if [ $? != 0 ] ; then - return 1 # Problem restarting the Listener - fi - return 0 # Success restarting the Listener -} - - -# -# usage: get_opmn_proc_status <ias-component> [process-type] -# -# Get the status of a specific OPMN-managed process. If process-type -# is not specified, assume the process-type is the same as the ias-component. -# If the lock-file exists (or no lock file is specified), try to restart -# the given process-type if it is not running. -# -get_opmn_proc_status() -{ - declare comp=$1 - declare opmntype=$2 - declare type_pretty - declare _pid _status - - [ -n "$comp" ] || return 1 - if [ -z "$opmntype" ]; then - opmntype=$comp - else - type_pretty=" [$opmntype]" - fi - - for (( i=$RESTART_RETRIES ; i; i-- )) ; do - - _status=`opmnctl status | grep "^$comp " | grep " $opmntype " | cut -d '|' -f3,4 | sed -e 's/ //g' -e 's/|/ /g'` - - _pid=`echo $_status | cut -f1 -d' '` - _status=`echo $_status | cut -f2 -d' '` - if [ "${_status}" == "Alive" ] || [ "${_status}" == "Init" ]; then - if [ $i -lt $RESTART_RETRIES ] ; then - echo " $comp$type_pretty restarted" - fi - echo " $comp$type_pretty (pid $_pid) is running..." - break - else - echo " $comp$type_pretty is stopped" - - # - # Try to restart it, but don't worry if we fail. OPMN - # is supposed to handle restarting these anyway. - # - # If it's running and you tell OPMN to "start" it, - # you will get an error. - # - # If it's NOT running and you tell OPMN to "restart" - # it, you will also get an error. - # - opmnctl startproc process-type=$opmntype &> /dev/null - fi - done - - if [ $i -eq 0 ]; then - # restarts failed - return 1 (failure) - return 1 - fi - - return 0 -} - - -# -# Get the status of the OPMN-managed processes. -# -get_opmn_status() -{ - declare -i subsys_lock=$1 - declare -i ct_errors=0 - - opmnctl status &> /dev/null - if [ $? -eq 2 ]; then - # - # OPMN not running?? - # - echo "opmn is stopped" - - if [ $subsys_lock -eq 0 ]; then - # - # Don't handle full opmn-restart. XXX - # - return 1 - fi - - # That's okay, it's not supposed to be! - return 3 - fi - - # - # Print out the PIDs for everyone. - # - echo "opmn is running..." - echo "opmn components:" - - # - # Check the OPMN-managed processes - # - get_opmn_proc_status OID || ((ct_errors++)) - get_opmn_proc_status HTTP_Server || ((ct_errors++)) - get_opmn_proc_status OC4J OC4J_SECURITY || ((ct_errors++)) - - # - # One or more OPMN-managed processes failed and could not be - # restarted. - # - if [ $ct_errors -ne 0 ]; then - return 1 - fi - return 0 -} - - -# -# Helps us keep a running status so we know what our ultimate return -# code will be. Returns 1 if the $1 and $2 are not equivalent, otherwise -# returns $1. The return code is meant to be the next $1 when this is -# called, so, for example: -# -# update_status 0 <-- returns 0 -# update_status $? 0 <-- returns 0 -# update_status $? 3 <-- returns 1 (values different - error condition) -# update_status $? 1 <-- returns 1 (same, but happen to be error state!) -# -# update_status 3 -# update_status $? 3 <-- returns 3 -# -# (and so forth...) -# -update_status() -{ - declare -i old_status=$1 - declare -i new_status=$2 - - if [ -z "$2" ]; then - return $old_status - fi - - if [ $old_status -ne $new_status ]; then - return 1 - fi - - return $old_status -} - - -# -# Print an error message to the user and exit. -# -oops() -{ - echo "Please configure this script ($0) to" - echo "match your installation." - echo - echo " $1 failed validation checks." - exit 1 -} - - -# -# Do some validation on the user-configurable stuff at the beginning of the -# script. -# -validation_checks() -{ - # - # If the oracle user doesn't exist, we're done. - # - [ -n "$ORACLE_USER" ] || oops "ORACLE_USER" - id -u $ORACLE_USER > /dev/null || oops "ORACLE_USER" - id -g $ORACLE_USER > /dev/null || oops "ORACLE_USER" - - # - # If the oracle home isn't a directory, we're done - # - [ -n "$ORACLE_HOME" ] || oops ORACLE_HOME - #[ -d "$ORACLE_HOME" ] || oops ORACLE_HOME - - # - # If the oracle SID is NULL, we're done - # - [ -n "$ORACLE_SID" ] || oops ORACLE_SID - - # - # If we don't know the type, we're done - # - [ "$ORACLE_TYPE" = "10g" ] || [ "$ORACLE_TYPE" = "10g-ias" ] || oops ORACLE_TYPE - - # - # If the hostname is zero-length, fix it - # - [ -n "$ORACLE_HOSTNAME" ] || ORACLE_HOSTNAME=`hostname` - - # - # Super user? Automatically change UID and exec as oracle user. - # Oracle needs to be run as the Oracle user, not root! - # - if [ "`id -u`" = "0" ]; then - echo "Restarting $0 as $ORACLE_USER." - # - # Breaks on RHEL5 - # exec sudo -u $ORACLE_USER $0 $* - # - su $ORACLE_USER -c "$0 $*" - exit $? - fi - - # - # If we're not root and not the Oracle user, we're done. - # - [ "`id -u`" = "`id -u $ORACLE_USER`" ] || exit 1 - [ "`id -g`" = "`id -g $ORACLE_USER`" ] || exit 1 - - # - # Go home. - # - cd $ORACLE_HOME - - return 0 -} - - -# -# Start Oracle9i Application Server Infrastructure -# -start_oracle() -{ - faction "Starting Oracle Database:" start_db || return 1 - action "Starting Oracle Listener:" lsnrctl start || return 1 - - if [ "$ORACLE_TYPE" = "10g" ]; then - action "Starting iSQL*Plus:" isqlplusctl start || return 1 - action "Starting Oracle EM DB Console:" emctl start dbconsole || return 1 - elif [ "$ORACLE_TYPE" = "10g-ias" ]; then - action "Starting Oracle EM:" emctl start em || return 1 - action "Starting iAS Infrastructure:" opmnctl startall || return 1 - fi - - if [ -n "$LOCKFILE" ]; then - touch $LOCKFILE - fi - return 0 -} - - -# -# Stop Oracle9i Application Server Infrastructure -# -stop_oracle() -{ - if ! [ -e "$ORACLE_HOME/bin/lsnrctl" ]; then - echo "Oracle Listener Control is not available" - echo " ($ORACLE_HOME not mounted?)" - return 0 - fi - - if [ "$ORACLE_TYPE" = "10g" ]; then - action "Stopping Oracle EM DB Console:" emctl stop dbconsole || return 1 - action "Stopping iSQL*Plus:" isqlplusctl stop || return 1 - elif [ "$ORACLE_TYPE" = "10g-ias" ]; then - action "Stopping iAS Infrastructure:" opmnctl stopall || return 1 - action "Stopping Oracle EM:" emctl stop em || return 1 - fi - - faction "Stopping Oracle Database:" stop_db || return 1 - action "Stopping Oracle Listener:" lsnrctl stop - faction "Waiting for all Oracle processes to exit:" exit_idle - - if [ $? -ne 0 ]; then - echo "WARNING: Not all Oracle processes exited cleanly" - fi - - if [ -n "$LOCKFILE" ]; then - rm -f $LOCKFILE - fi - return 0 -} - - -# -# Find and display the status of iAS infrastructure. -# -# This has three parts: -# (1) Oracle database itself -# (2) Oracle listener process -# (3) OPMN and OPMN-managed processes -# -# - If all are (cleanly) down, we return 3. In order for this to happen, -# $LOCKFILE must not exist. In this case, we try and restart certain parts -# of the service - as this may be running in a clustered environment. -# -# - If some but not all are running (and, if $LOCKFILE exists, we could not -# restart the failed portions), we return 1 (ERROR) -# -# - If all are running, return 0. In the "all-running" case, we recreate -# $LOCKFILE if it does not exist. -# -status_oracle() -{ - declare -i subsys_lock=1 - declare -i last - declare -i depth=$1 - - # - # Check for lock file. Crude and rudimentary, but it works - # - if [ -z "$LOCKFILE" ] || [ -f $LOCKFILE ]; then - subsys_lock=0 - fi - - # Check database status - get_db_status $subsys_lock $depth - update_status $? # Start - last=$? - - # Check & report listener status - get_lsnr_status $subsys_lock $depth - update_status $? $last - last=$? - - if [ "$ORACLE_TYPE" = "10g" ]; then - # XXX Add isqlplus status check?! - emctl status dbconsole 2>&1 | grep "is running" - update_status $? $last - last=$? - elif [ "$ORACLE_TYPE" = "10g-ias" ]; then - # Check & report opmn / opmn-managed process status - get_opmn_status $subsys_lock $depth - update_status $? $last - last=$? - fi - - # - # No lock file, but everything's running. Put the lock - # file back. XXX - this kosher? - # - if [ $last -eq 0 ] && [ $subsys_lock -ne 0 ]; then - touch $LOCKFILE - fi - - return $last -} - - -######################## -# Do some real work... # -######################## -if [ "$1" = "meta-data" ]; then - meta_data - exit 0 -fi - -validation_checks $* - -case $1 in - start) - start_oracle - exit $? - ;; - stop) - stop_oracle - exit $? - ;; - status|monitor) - status_oracle $OCF_CHECK_LEVEL - exit $? - ;; - restart) - $0 stop || exit $? - $0 start || exit $? - exit 0 - ;; - *) - echo "usage: $SCRIPT {start|stop|status|restart|meta-data}" - exit 1 - ;; -esac -exit 0 diff --git a/rgmanager/src/resources/perlscript.pl b/rgmanager/src/resources/perlscript.pl deleted file mode 100755 index 2d4154e..0000000 --- a/rgmanager/src/resources/perlscript.pl +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/perl - -# -# Copyright Red Hat Inc., 2004 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# Test case for a perl script -# - -print "=== Env dump $0 ===\n"; -while (($key,$value) = each %ENV) { - print "$key=$value\n"; -} -print "=== End env dump @ARGV[0] ===\n"; - -if ($ENV{"OCF_RESKEY_file"} = "") { - exit 1 -} - -# Don't need to catch return codes; this one will work. -exec $ENV{"OCF_RESKEY_file"}, @ARGV[0]; diff --git a/rgmanager/src/resources/postgres-8.metadata b/rgmanager/src/resources/postgres-8.metadata deleted file mode 100644 index 760e865..0000000 --- a/rgmanager/src/resources/postgres-8.metadata +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="postgres-8"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an instance of PostgreSQL server - </longdesc> - <shortdesc lang="en"> - Defines a PostgreSQL server - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Specifies a service name for logging and other purposes - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define absolute path to configuration file - </longdesc> - <shortdesc lang="en"> - Config File - </shortdesc> - <content type="string" default="/var/lib/pgsql/data/postgresql.conf"/> - </parameter> - - <parameter name="postmaster_user"> - <longdesc lang="en"> - User who runs the database server because it can't be - run by root. - </longdesc> - <shortdesc lang="en"> - User who runs the database server - </shortdesc> - <content type="string" default="postgres" /> - </parameter> - - <parameter name="postmaster_options"> - <longdesc lang="en"> - Other command-line options for postmaster - </longdesc> - <shortdesc lang="en"> - Other command-line options for postmaster - </shortdesc> - <content type="string" default="-D /var/lib/pgsql/data"/> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- Checks to see if it''s mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> - - <special tag="rgmanager"> - </special> -</resource-agent> diff --git a/rgmanager/src/resources/postgres-8.sh b/rgmanager/src/resources/postgres-8.sh deleted file mode 100755 index 766646f..0000000 --- a/rgmanager/src/resources/postgres-8.sh +++ /dev/null @@ -1,235 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare PSQL_POSTMASTER="/usr/bin/postmaster" -declare PSQL_pid_file="`generate_name_for_pid_file`" -declare PSQL_conf_dir="`generate_name_for_conf_dir`" -declare PSQL_gen_config_file="$PSQL_conf_dir/postgresql.conf" - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ ! -r "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE $OCF_RESKEY_config_file - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_postmaster_user" ]; then - clog_servicer_verify $CLOG_FAILED "Invalid User" - return $OCF_ERR_ARGS - fi - - clog_service_verify $CLOG_SUCCEED - - return 0 -} - -generate_config_file() -{ - declare original_file="$1" - declare generated_file="$2" - declare ip_addressess="$3" - - declare ip_comma=""; - - if [ -f "$generated_file" ]; then - sha1_verify "$generated_file" - if [ $? -ne 0 ]; then - clog_check_sha1 $CLOG_FAILED - return 0 - fi - fi - - clog_generate_config $CLOG_INIT "$original_file" "$generated_file" - - declare x=1 - for i in $ip_addressess; do - if [ $x -eq 1 ]; then - x=0 - ip_comma=$i - else - ip_comma=$ip_comma,$i - fi - done - - generate_configTemplate "$generated_file" "$1" - echo "external_pid_file = '$PSQL_pid_file'" >> "$generated_file" - echo "listen_addresses = '$ip_comma'" >> "$generated_file" - - echo >> "$generated_file" - sed 's/^[[:space:]]*external_pid_file/### external_pid_file/i;s/^[[:space:]]*listen_addresses/### listen_addresses/i' < "$original_file" >> "$generated_file" - - sha1_addToFile "$generated_file" - clog_generate_config $CLOG_SUCCEED "$original_file" "$generated_file" - - return 0; -} - -start() -{ - declare ccs_fd; - declare pguser_group - - clog_service_start $CLOG_INIT - - create_pid_directory - create_conf_directory "$PSQL_conf_dir" - check_pid_file "$PSQL_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$PSQL_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - # - # Create an empty PID file for the postgres user and - # change it to be owned by the postgres user so that - # postmaster doesn't complain. - # - pguser_group=`groups $OCF_RESKEY_postmaster_user | cut -f1 -d ' '` - touch $PSQL_pid_file - chown $OCF_RESKEY_postmaster_user.$pguser_group $PSQL_pid_file - - clog_looking_for $CLOG_INIT "IP Addresses" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -z "$ip_addresses" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_SUCCEED "IP Addresses" - - generate_config_file "$OCF_RESKEY_config_file" "$PSQL_gen_config_file" "$ip_addresses" - - sudo -u "$OCF_RESKEY_postmaster_user" $PSQL_POSTMASTER -c config_file="$PSQL_gen_config_file" \ - $OCF_RESKEY_postmaster_options &> /dev/null & - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_start $CLOG_SUCCEED - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$PSQL_pid_file" "$OCF_RESKEY_shutdown_wait" - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$PSQL_pid_file" - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$PSQL_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - verify-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac diff --git a/rgmanager/src/resources/ra-api-1-modified.dtd b/rgmanager/src/resources/ra-api-1-modified.dtd deleted file mode 100644 index 539b8c7..0000000 --- a/rgmanager/src/resources/ra-api-1-modified.dtd +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> - -<!-- This is based on the RA-API-1.0 DTD from: - http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/ra-api-1.dtd - - There are additions for rgmanager. These additions should be - ignored by other RMs. - --> - -<!ELEMENT resource-agent (version,longdesc,shortdesc,parameters,actions,special*) > -<!ATTLIST resource-agent - name CDATA #REQUIRED - version CDATA #IMPLIED> - -<!ELEMENT version (#PCDATA)> - -<!ELEMENT parameters (parameter*)> - -<!ELEMENT actions (action*)> - -<!-- Primary and required are for rgmanager use. --> -<!ELEMENT parameter (longdesc+,shortdesc+,content)> -<!ATTLIST parameter - name CDATA #REQUIRED - primary (1|0) "0" - required (1|0) "0" - inherit CDATA "" - unique (1|0) "0"> - -<!ELEMENT longdesc ANY> -<!ATTLIST longdesc - lang NMTOKEN #IMPLIED> - -<!ELEMENT shortdesc ANY> -<!ATTLIST shortdesc - lang NMTOKEN #IMPLIED> - -<!ELEMENT content EMPTY> -<!ATTLIST content - type (string|integer|boolean) #REQUIRED - default CDATA #IMPLIED> - -<!ELEMENT action EMPTY> -<!ATTLIST action - name (start|stop|recover|status|monitor|reload|meta-data|verify-all) #REQUIRED - timeout CDATA #REQUIRED - interval CDATA #IMPLIED - start-delay CDATA #IMPLIED - depth CDATA #IMPLIED> - -<!-- Special tag list for rgmanager --> -<!ELEMENT special (attributes*, child*)> -<!ATTLIST special - tag CDATA #REQUIRED> - -<!ELEMENT attributes EMPTY> -<!ATTLIST attributes - root (1|0) "0" - maxinstances CDATA "0"> - -<!ELEMENT child EMPTY> -<!ATTLIST child - type CDATA #REQUIRED - forbid (1|0) "0" - start CDATA "100" - stop CDATA "0"> diff --git a/rgmanager/src/resources/samba.metadata b/rgmanager/src/resources/samba.metadata deleted file mode 100644 index ad56197..0000000 --- a/rgmanager/src/resources/samba.metadata +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="samba"> - <version>1.0</version> - - <longdesc lang="en"> - Dynamic smbd/nmbd resource agent - </longdesc> - <shortdesc lang="en"> - Dynamic smbd/nmbd resource agent - </shortdesc> - - <parameters> - <parameter name="name" unique="1" primary="1"> - <longdesc lang="en"> - Samba Symbolic Name. - </longdesc> - <shortdesc lang="en"> - Samba Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define absolute path to configuration file - </longdesc> - <shortdesc lang="en"> - Config File - </shortdesc> - <content type="string" default="/etc/samba/smb.conf"/> - </parameter> - - <parameter name="smbd_options"> - <longdesc lang="en"> - Other command-line options for smbd - </longdesc> - <shortdesc lang="en"> - Other command-line options for smbd - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="nmbd_options"> - <longdesc lang="en"> - Other command-line options for nmbd - </longdesc> - <shortdesc lang="en"> - Other command-line options for nmbd - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this smb service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- This is just a wrapper for LSB init scripts, so monitor - and status can't have a timeout, nor do they do any extra - work regardless of the depth --> - <action name="status" interval="30s" timeout="0"/> - <action name="monitor" interval="30s" timeout="0"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> -</resource-agent> diff --git a/rgmanager/src/resources/samba.sh b/rgmanager/src/resources/samba.sh deleted file mode 100755 index 70ea17f..0000000 --- a/rgmanager/src/resources/samba.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare SAMBA_SMBD=/usr/sbin/smbd -declare SAMBA_NMBD=/usr/sbin/nmbd -declare SAMBA_pid_dir="`generate_name_for_pid_dir`" -declare SAMBA_conf_dir="`generate_name_for_conf_dir`" -declare SAMBA_smbd_pid_file="$SAMBA_pid_dir/smbd.pid" -declare SAMBA_nmbd_pid_file="$SAMBA_pid_dir/nmbd.pid" -declare SAMBA_gen_config_file="$SAMBA_conf_dir/smb.conf" - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ ! -r "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE $OCF_RESKEY_config_file - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - clog_service_verify $CLOG_SUCCEED - - return 0 -} - -generate_config_file() -{ - declare original_file="$1" - declare generated_file="$2" - declare ip_addresses="$3" - - if [ -f "$generated_file" ]; then - sha1_verify "$generated_file" - if [ $? -ne 0 ]; then - clog_check_sha1 $CLOG_FAILED - return 0 - fi - fi - - clog_generate_config $CLOG_INIT "$original_file" "$generated_file" - - generate_configTemplate "$generated_file" "$1" - - echo "pid directory = "$SAMBA_pid_dir"" >> "$generated_file" - echo "interfaces = $ip_addresses" >> "$generated_file" - echo "bind interfaces only = Yes" >> "$generated_file" - echo "netbios name = "$OCF_RESKEY_name"" >> "$generated_file" - echo >> "$generated_file" - sed 's/^[[:space:]]*pid directory/### pid directory/i;s/^[[:space:]]*interfaces/### interfaces/i;s/^[[:space:]]*bind interfaces only/### bind interfaces only/i;s/^[[:space:]]*netbios name/### netbios name/i' \ - < "$original_file" >> "$generated_file" - - sha1_addToFile "$generated_file" - clog_generate_config $CLOG_SUCCEED "$original_file" "$generated_file" - - return 0; -} - -start() -{ - declare ccs_fd; - - clog_service_start $CLOG_INIT - - create_pid_directory - mkdir -p "$SAMBA_pid_dir" - create_conf_directory "$SAMBA_conf_dir" - check_pid_file "$SAMBA_smbd_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$SAMBA_smbd_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - check_pid_file "$SAMBA_nmbd_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$SAMBA_nmbd_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_INIT "IP Addresses" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -z "$ip_addresses" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_SUCCEED "IP Addresses" - - generate_config_file "$OCF_RESKEY_config_file" "$SAMBA_gen_config_file" "$ip_addresses" - - $SAMBA_SMBD -D -s "$SAMBA_gen_config_file" $OCF_RESKEY_smbd_options - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - $SAMBA_NMBD -D -s "$SAMBA_gen_config_file" $OCF_RESKEY_nmbd_options - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - clog_service_start $CLOG_SUCCEED - - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$SAMBA_smbd_pid_file" "$OCF_RESKEY_shutdown_wait" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - stop_generic "$SAMBA_nmbd_pid_file" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - if [ -e "$SAMBA_smbd_pid_file" ]; then - rm -f "$SAMBA_smbd_pid_file" - fi - - if [ -e "$SAMBA_nmbd_pid_file" ]; then - rm -f "$SAMBA_nmbd_pid_file" - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$SAMBA_smbd_pid_file" - - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$SAMBA_smbd_pid_file" - return $OCF_ERR_GENERIC - fi - - status_check_pid "$SAMBA_nmbd_pid_file" - - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$SAMBA_nmbd_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - verify-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac diff --git a/rgmanager/src/resources/script.sh b/rgmanager/src/resources/script.sh deleted file mode 100755 index 0141c80..0000000 --- a/rgmanager/src/resources/script.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2004 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# Script to handle a non-OCF script (e.g. a normal init-script) -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -. $(dirname $0)/ocf-shellfuncs - -meta_data() -{ - cat <<EOT -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="script"> - <version>1.0</version> - - <longdesc lang="en"> - The script resource allows a standard LSB-compliant init script - to be used to start a clustered service. - </longdesc> - <shortdesc lang="en"> - LSB-compliant init script as a clustered resource. - </shortdesc> - - <parameters> - <parameter name="name" unique="1" primary="1"> - <longdesc lang="en"> - Name - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="file" unique="1" required="1"> - <longdesc lang="en"> - Path to script - </longdesc> - <shortdesc lang="en"> - Path to script - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name, in case the - script wants to know this information. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- This is just a wrapper for LSB init scripts, so monitor - and status can't have a timeout, nor do they do any extra - work regardless of the depth --> - <action name="status" interval="30s" timeout="0"/> - <action name="monitor" interval="30s" timeout="0"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> -</resource-agent> -EOT -} - -case $1 in - meta-data) - meta_data - exit 0 - ;; - *) - ;; -esac - -[ -n "${OCF_RESKEY_file}" ] || exit $OCF_ERR_ARGS # Invalid Argument -[ -f "${OCF_RESKEY_file}" ] || exit $OCF_ERR_INSTALLED # Program not installed -[ -x "${OCF_RESKEY_file}" ] || exit $OCF_ERR_GENERIC # Generic error - -# Don't need to catch return codes; this one will work. -ocf_log info "Executing ${OCF_RESKEY_file} $1" -${OCF_RESKEY_file} $1 - -declare -i rv=$? -if [ $rv -ne 0 ]; then - ocf_log err "script:$OCF_RESKEY_name: $1 of $OCF_RESKEY_file failed (returned $rv)" - exit $OCF_ERR_GENERIC -fi diff --git a/rgmanager/src/resources/service.sh b/rgmanager/src/resources/service.sh deleted file mode 100755 index a21a66b..0000000 --- a/rgmanager/src/resources/service.sh +++ /dev/null @@ -1,302 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2004-2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -# -# Dummy OCF script for resource group -# - -# Grab nfs lock tricks if available -export NFS_TRICKS=1 -if [ -f "$(dirname $0)/svclib_nfslock" ]; then - . $(dirname $0)/svclib_nfslock - NFS_TRICKS=0 -fi - -meta_data() -{ - cat <<EOT -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="service"> - <version>1.0</version> - - <longdesc lang="en"> - This defines a collection of resources, known as a resource - group or cluster service. - </longdesc> - <shortdesc lang="en"> - Defines a services. - </shortdesc> - - <parameters> - <parameter name="name" unique="1" required="1" primary="1"> - <longdesc lang="en"> - This is the name of the resource group. - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="domain" reconfig="1"> - <longdesc lang="en"> - Fail over domains define lists of cluster members - to try in the event that a resource group fails. - </longdesc> - <shortdesc lang="en"> - Fail over Domain - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="autostart" reconfig="1"> - <longdesc lang="en"> - If set to yes, this resource group will automatically be started - after the cluster forms a quorum. If set to no, this resource - group will start in the 'disabled' state after the cluster forms - a quorum. - </longdesc> - <shortdesc lang="en"> - Automatic start after quorum formation - </shortdesc> - <content type="boolean" default="1"/> - </parameter> - - <parameter name="hardrecovery" reconfig="1"> - <longdesc lang="en"> - If set to yes, the last owner will reboot if this resource - group fails to stop cleanly, thus allowing the resource - group to fail over to another node. Use with caution; a - badly-behaved resource could cause the entire cluster to - reboot. This should never be enabled if the automatic - start feature is used. - </longdesc> - <shortdesc lang="en"> - Reboot if stop phase fails - </shortdesc> - <content type="boolean" default="0"/> - </parameter> - - <parameter name="exclusive" reconfig="1"> - <longdesc lang="en"> - If set, this resource group will only relocate to - nodes which have no other resource groups running in the - event of a failure. If no empty nodes are available, - this resource group will not be restarted after a failure. - Additionally, resource groups will not automatically - relocate to the node running this resource group. This - option can be overridden by manual start and/or relocate - operations. - </longdesc> - <shortdesc lang="en"> - Exclusive resource group - </shortdesc> - <content type="boolean" default="0"/> - </parameter> - - <parameter name="nfslock"> - <longdesc lang="en"> - Enable NFS lock workarounds. When used with a compatible - HA-callout program like clunfslock, this could be used - to provide NFS lock failover, but at significant cost to - other services on the machine. This requires a compatible - version of nfs-utils and manual configuration of rpc.statd; - see 'man rpc.statd' to see if your version supports - the -H parameter. - </longdesc> - <shortdesc lang="en"> - Enable NFS lock workarounds - </shortdesc> - <content type="boolean" default="0"/> - </parameter> - - <parameter name="nfs_client_cache"> - <longdesc lang="en"> - On systems with large numbers of exports, a performance - problem in the exportfs command can cause inordinately long - status check times for services with lots of mounted - NFS clients. This occurs because exportfs does DNS queries - on all clients in the export list. - - Setting this option to '1' will enable caching of the export - list returned from the exportfs command on a per-service - basis. The cache will last for 30 seconds before expiring - instead of being generated each time an nfsclient resource - is called. - </longdesc> - <shortdesc lang="en"> - Enable exportfs list caching - </shortdesc> - <content type="integer" default="0"/> - </parameter> - - - <parameter name="recovery" reconfig="1"> - <longdesc lang="en"> - This currently has three possible options: "restart" tries - to restart failed parts of this resource group locally before - attempting to relocate (default); "relocate" does not bother - trying to restart the service locally; "disable" disables - the resource group if any component fails. Note that - any resource with a valid "recover" operation which can be - recovered without a restart will be. - </longdesc> - <shortdesc lang="en"> - Failure recovery policy - </shortdesc> - <content type="string" default="restart"/> - </parameter> - - <parameter name="depend"> - <longdesc lang="en"> - Top-level service this depends on, in "service:name" format. - </longdesc> - <shortdesc lang="en"> - Service dependency; will not start without the specified - service running. - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="depend_mode"> - <longdesc lang="en"> - Dependency mode - </longdesc> - <shortdesc lang="en"> - Service dependency mode. - hard - This service is stopped/started if its dependency - is stopped/started - soft - This service only depends on the other service for - initial startip. If the other service stops, this - service is not stopped. - </shortdesc> - <content type="string" default="hard"/> - </parameter> - - <parameter name="max_restarts"> - <longdesc lang="en"> - Maximum restarts for this service. - </longdesc> - <shortdesc lang="en"> - Maximum restarts for this service. - </shortdesc> - <content type="string" default="0"/> - </parameter> - - <parameter name="restart_expire_time"> - <longdesc lang="en"> - Restart expiration time - </longdesc> - <shortdesc lang="en"> - Restart expiration time. A restart is forgotten - after this time. When combined with the max_restarts - option, this lets administrators specify a threshold - for when to fail over services. If max_restarts - is exceeded in this given expiration time, the service - is relocated instead of restarted again. - </shortdesc> - <content type="string" default="0"/> - </parameter> - - </parameters> - - <actions> - <action name="start" timeout="5"/> - <action name="stop" timeout="5"/> - - <!-- No-ops. Groups are abstract resource types. - <action name="status" timeout="5" interval="1h"/> - <action name="monitor" timeout="5" interval="1h"/> - --> - - <action name="reconfig" timeout="5"/> - <action name="recover" timeout="5"/> - <action name="reload" timeout="5"/> - <action name="meta-data" timeout="5"/> - <action name="validate-all" timeout="5"/> - </actions> - - <special tag="rgmanager"> - <attributes root="1" maxinstances="1"/> - <child type="lvm" start="1" stop="9"/> - <child type="fs" start="2" stop="8"/> - <child type="clusterfs" start="3" stop="7"/> - <child type="netfs" start="4" stop="6"/> - <child type="nfsexport" start="5" stop="5"/> - - <child type="nfsclient" start="6" stop="4"/> - - <child type="ip" start="7" stop="2"/> - <child type="smb" start="8" stop="3"/> - <child type="script" start="9" stop="1"/> - </special> -</resource-agent> -EOT -} - - -# -# A Resource group is abstract, but the OCF RA API doesn't allow for abstract -# resources, so here it is. -# -case $1 in - start) - [ -d "/var/run/cluster/rgmanager" ] && touch "/var/run/cluster/rgmanager/$OCF_RESOURCE_INSTANCE" - # - # XXX If this is set, we kill lockd. If there is no - # child IP address, then clients will NOT get the reclaim - # notification. - # - if [ $NFS_TRICKS -eq 0 ]; then - if [ "$OCF_RESKEY_nfslock" = "yes" ] || \ - [ "$OCF_RESKEY_nfslock" = "1" ]; then - pkill -KILL -x lockd - fi - fi - exit 0 - ;; - stop) - [ -d "/var/run/cluster/rgmanager" ] && rm -f "/var/run/cluster/rgmanager/$OCF_RESOURCE_INSTANCE" - exit 0 - ;; - recover|restart) - exit 0 - ;; - status|monitor) - exit 0 - ;; - reload) - exit 0 - ;; - meta-data) - meta_data - exit 0 - ;; - validate-all) - exit 0 - ;; - reconfig) - exit 0 - ;; - *) - exit 0 - ;; -esac diff --git a/rgmanager/src/resources/smb.sh b/rgmanager/src/resources/smb.sh deleted file mode 100755 index 71ff4fd..0000000 --- a/rgmanager/src/resources/smb.sh +++ /dev/null @@ -1,768 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat Inc., 2002, 2004 -# Copyright Mission Critical Linux, 2000 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# Author(s): -# Lon Hohberger (lhh at redhat.com) -# Tim Burke (tburke at redhat.com) -# - -# -# Script to manage a Samba file-sharing service component. -# Unline NFS, this should be placed at the top level of a service -# because it will try to gather information necessary to run the -# smbd/nmbd daemons at run-time from the service structure. -# - -LC_ALL=C -LANG=C -PATH=/bin:/sbin:/usr/bin:/usr/sbin -export LC_ALL LANG PATH - -# -# Definitions! -# -declare SAMBA_CONFIG_DIR=/etc/samba -declare SMBD_COMMAND=/usr/sbin/smbd -declare NMBD_COMMAND=/usr/sbin/nmbd -declare KILLALL_COMMAND=/usr/bin/killall -declare SAMBA_PID_DIR=/var/run/samba -declare SAMBA_LOCK_DIR=/var/cache/samba - -# -# gross globals -# -declare -a ipkeys -declare -a fskeys - -# Don't change please :) -_FAIL=255 - -. $(dirname $0)/ocf-shellfuncs - -meta_data() -{ - cat <<EOT -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="smb"> - <version>1.0</version> - - <longdesc lang="en"> - Dynamic smbd/nmbd resource agent - </longdesc> - <shortdesc lang="en"> - Dynamic smbd/nmbd resource agent - </shortdesc> - - <parameters> - <parameter name="name" unique="1" primary="1"> - <longdesc lang="en"> - Samba Symbolic Name. This name will - correspond to /etc/samba/smb.conf.NAME - </longdesc> - <shortdesc lang="en"> - Samba Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="workgroup"> - <longdesc lang="en"> - Workgroup name - </longdesc> - <shortdesc lang="en"> - Workgroup name - </shortdesc> - <content type="string" default="LINUXCLUSTER"/> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this smb service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- This is just a wrapper for LSB init scripts, so monitor - and status can't have a timeout, nor do they do any extra - work regardless of the depth --> - <action name="status" interval="30s" timeout="0"/> - <action name="monitor" interval="30s" timeout="0"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> -</resource-agent> -EOT -} - - -# -# Usage: ccs_connect -# Returns: $_FAIL on failure, or a connection descriptor on success -# -ccs_connect() -{ - declare outp - - outp=$(ccs_test connect 2>&1) - if [ $? -ne 0 ]; then - ocf_log err "$outp" - return $_FAIL - fi - - outp=${outp/*= /} - if [ -n "$outp" ]; then - echo $outp - return 0 - fi - - return 1 -} - - -# -# Usage: ccs_disconnect desc -# -ccs_disconnect() -{ - declare outp - - [ -n "$1" ] || return $_FAIL - outp=$(ccs_test disconnect $1 2>&1) - if [ $? -ne 0 ]; then - ocf_log warn "Disconnect CCS desc $1 failed: $outp" - return 1 - fi - return 0 -} - - -# -# Usage: ccs_get desc key -# -ccs_get() -{ - declare outp - declare ccsfd=$1 - declare key - - [ -n "$1" ] || return $_FAIL - [ -n "$2" ] || return $_FAIL - - shift - key="$*" - - outp=$(ccs_test get $ccsfd "$key" 2>&1) - if [ $? -ne 0 ]; then - if [ "$outp" = "${outp/No data available/}" ]; then - ocf_log err "$outp ($key)" - return $_FAIL - fi - - # no real error, just no data available - return 0 - fi - - outp=${outp/*</} - outp=${outp/>*/} - - echo $outp - - return 0 -} - - -# -# Build a list of service IP keys; traverse refs if necessary -# -get_service_ip_keys() -{ - declare -i ccsfd=$1 - declare svc=$2 - declare -i x y=0 - declare outp - declare key - - if [ $ccsfd -eq $_FAIL ]; then - ocf_log err "Can not talk to ccsd: invalid descriptor $ccsfd" - return 1 - fi - - # - # Find service-local IP keys - # - x=1 - while : ; do - key="/cluster/rm/service[@name="$svc"]/ip[$x]" - - # - # Try direct method - # - outp=$(ccs_get $ccsfd "$key/@address") - if [ $? -ne 0 ]; then - return 1 - fi - - # - # Try by reference - # - if [ -z "$outp" ]; then - outp=$(ccs_get $ccsfd "$key/@ref") - if [ $? -ne 0 ]; then - return 1 - fi - key="/cluster/rm/resources/ip[@address="$outp"]" - fi - - if [ -z "$outp" ]; then - break - fi - - #ocf_log debug "IP $outp found @ $key" - - ipkeys[$y]="$key" - - ((y++)) - ((x++)) - done - - ocf_log debug "$y IP addresses found for $svc/$OCF_RESKEY_name" - - return 0 -} - - -# -# Build a list of service fs keys, traverse refs if necessary -# -get_service_fs_keys() -{ - declare -i ccsfd=$1 - declare svc=$2 - declare -i x y=0 - declare outp - declare key - - if [ $ccsfd -eq $_FAIL ]; then - ocf_log err "Can not talk to ccsd: invalid descriptor $ccsfd" - return 1 - fi - - # - # Find service-local IP keys - # - x=1 - while : ; do - key="/cluster/rm/service[@name="$svc"]/fs[$x]" - - # - # Try direct method - # - outp=$(ccs_get $ccsfd "$key/@name") - if [ $? -ne 0 ]; then - return 1 - fi - - # - # Try by reference - # - if [ -z "$outp" ]; then - outp=$(ccs_get $ccsfd "$key/@ref") - if [ $? -ne 0 ]; then - return 1 - fi - key="/cluster/rm/resources/fs[@name="$outp"]" - fi - - if [ -z "$outp" ]; then - break - fi - - #ocf_log debug "filesystem $outp found @ $key" - - fskeys[$y]="$key" - - ((y++)) - ((x++)) - done - - ocf_log debug "$y filesystems found for $svc/$OCF_RESKEY_name" - - return 0 -} - - -build_ip_list() -{ - declare -i ccsfd=$1 - declare ipaddrs ipaddr - declare -i x=0 - - while [ -n "${ipkeys[$x]}" ]; do - ipaddr=$(ccs_get $ccsfd "${ipkeys[$x]}/@address") - if [ -z "$ipaddr" ]; then - break - fi - - ipaddrs="$ipaddrs $ipaddr" - - ((x++)) - done - - echo $ipaddrs -} - - -add_sha1() -{ - declare sha1line="# rgmanager-sha1 $(sha1sum "$1")" - echo $sha1line >> "$1" -} - - -verify_sha1() -{ - declare tmpfile="$(mktemp /tmp/smb-${OCF_RESKEY}_name.tmp.XXXXXX)" - declare current exp - - exp=$(grep "^# rgmanager-sha1.*$1" "$1" | head -1) - if [ -z "$exp" ]; then - # No sha1 line. We're done. - ocf_log debug "No SHA1 info in $1" - return 1 - fi - - # - # Find expected sha1 and expected file name - # - exp=${exp/*sha1 /} - exp=${exp/ */} - - grep -v "^# rgmanager-sha1" "$1" > "$tmpfile" - current=$(sha1sum "$tmpfile") - current=${current/ */} - - rm -f "$tmpfile" - - if [ "$current" = "$exp" ]; then - ocf_log debug "SHA1 sum matches for $1" - return 0 - fi - ocf_log debug "SHA1 sum does not match for $1" - return 1 -} - - -add_fs_entries() -{ - declare -i ccsfd=$1 - declare conf="$2" - declare sharename - declare sharepath key - - declare -i x=0 - - while [ -n "${fskeys[$x]}" ]; do - key="${fskeys[$x]}/@name" - - sharename=$(ccs_get $ccsfd "$key") - if [ -z "$sharename" ]; then - break - fi - - key="${fskeys[$x]}/@mountpoint" - sharepath=$(ccs_get $ccsfd "$key") - if [ -z "$sharepath" ]; then - break - fi - - cat >> "$conf" <<EODEV -[$sharename] - comment = Auto-generated $sharename share - # Hide the secret cluster files - veto files = /.clumanager/.rgmanager/ - browsable = yes - writable = no - public = yes - path = $sharepath - -EODEV - - ((x++)) - done -} - - -# -# Generate the samba configuration if neede for this service. -# -gen_smb_conf() -{ - declare -i ccsfd=$_FAIL - declare conf="$1" - declare lvl="debug" - - if [ -f "$conf" ]; then - verify_sha1 "$conf" - if [ $? -ne 0 ]; then - ocf_log debug "Config file changed; skipping" - return 0 - fi - else - lvl="info" - fi - - ocf_log $lvl "Creating $conf" - - ccsfd=$(ccs_connect) - if [ $? -eq $_FAIL ]; then - return $OCF_ERR_GENERIC - fi - - ocf_log debug "Acquired CCS descriptor $ccsfd" - - get_service_ip_keys $ccsfd "$OCF_RESKEY_service_name" - get_service_fs_keys $ccsfd "$OCF_RESKEY_service_name" - - cat > "$conf" <<EOT -# -# "$conf" -# -# This template configuration wass automatically generated, and will -# be automatically regenerated if removed. Please modify this file to -# speficy subdirectories and/or client access permissions. -# -# Once this file has been altered, automatic re-generation will stop. -# Remember to copy this file to all other cluster members after making -# changes, or your SMB service will not operate correctly. -# -# From a cluster perspective, the key fields are: -# lock directory - must be unique per samba service. -# bind interfaces only - must be present set to yes. -# interfaces - must be set to service floating IP address. -# path - must be the service mountpoint or subdirectory thereof. -# - -[global] - workgroup = $OCF_RESKEY_workgroup - pid directory = /var/run/samba/$OCF_RESKEY_name - lock directory = /var/cache/samba/$OCF_RESKEY_name - log file = /var/log/samba/%m.log - #private dir = /var/ - encrypt passwords = yes - bind interfaces only = yes - netbios name = ${OCF_RESKEY_name/ /_} - - # - # Interfaces are based on ip resources at the top level of - # "$OCF_RESKEY_service_name"; IPv6 addresses may or may not - # work correctly. - # - interfaces = $(build_ip_list $ccsfd) - -# -# Shares based on fs resources at the top level of "$OCF_RESKEY_service_name" -# -EOT - add_fs_entries $ccsfd "$conf" - ccs_disconnect $ccsfd - add_sha1 "$conf" - - return 0 -} - - -# -# Kill off the specified PID -# (from clumanager 1.0.x/1.2.x) -# -# Killing off the samba daemons was miserable to implement, merely -# because killall doesn't distinguish by program commandline. -# Consequently I had to implement these routines to selectively pick 'em off. -# -# Kills of either the {smbd|nmbd} which is running and was started with -# the specified argument. Can't use `killall` to do this because it -# doesn't allow you to distinguish which process to kill based on any -# of the program arguments. -# -# This routine is also called on "status" checks. In this case it doesn't -# actually kill anything. -# -# Parameters: -# daemonName - daemon name, can be either smbd or nmbd -# command - [stop|start|status] -# arg - argument passed to daemon. In this case its not the -# full set of program args, rather its really just the -# samba config file. -# -# Returns: 0 - success (or the daemon isn't currently running) -# 1 - failure -# -kill_daemon_by_arg() -{ - declare daemonName=$1 - declare action=$2 - declare arg=$3 - # Create a unique temporary file to stash off intermediate results - declare tmpfile_str=/tmp/sambapids.XXXXXX - declare tmpfile - declare ret - - tmpfile=$(mktemp $tmpfile_str); ret_val=$? - - if [ -z "$tmpfile" ]; then - ocf_log err "kill_daemon_by_arg: Can't create tmp file" - return $_FAIL - fi - - # Mumble, need to strip off the /etc/samba portion, otherwise the - # grep pattern matching will fail. - declare confFile="$(basename $arg)" - - # First generate a list of candidate pids. - pidof $daemonName > $tmpfile - if [ $? -ne 0 ]; then - ocf_log debug "kill_daemon_by_arg: no pids for $daemonName" - rm -f $tmpfile - case "$action" in - 'stop') - return 0 - ;; - 'status') - return $_FAIL - ;; - esac - return 0 - fi - - # If you don't find any matching daemons for a "stop" operation, thats - # considered success; whereas for "status" inquiries its a failure. - case "$action" in - 'stop') - ret=0 - ;; - 'status') - ret=$_FAIL - ;; - esac - # - # At this point tmpfile contains a set of pids for the corresponding - # {smbd|nmbd}. Now look though this candidate set of pids and compare - # the program arguments (samba config file name). This distinguishes - # which ones should be killed off. - # - declare daemonPid="" - for daemonPid in $(cat $tmpfile); do - declare commandLine=$(cat /proc/$daemonPid/cmdline) - declare confBase="$(basename $commandLine)" - if [ "$confBase" = "$confFile" ]; then - case "$action" in - 'status') - rm -f $tmpfile - return 0 - ;; - esac - kill_daemon_pid $daemonPid - if [ $? -ne 0 ]; then - ret=$_FAIL - ocf_log err \ - "kill_daemon_by_arg: kill_daemon_pid $daemonPid failed" - else - ocf_log debug \ - "kill_daemon_by_arg: kill_daemon_pid $daemonPid success" - fi - fi - done - rm -f $tmpfile - return $ret -} - - -# -# Kill off the specified PID -# (from clumanager 1.0.x/1.2.x) -# -kill_daemon_pid() -{ - declare pid=$1 - declare retval=0 - - - kill -TERM $pid - if [ $? -eq 0 ]; then - ocf_log debug "Samba: successfully killed $pid" - else - ocf_log debug "Samba: failed to kill $pid" - retval=$_FAIL - fi - return $retval -} - - -share_start_stop() -{ - declare command=$1 - declare conf="$SAMBA_CONFIG_DIR/smb.conf.$OCF_RESKEY_name" - declare smbd_command - declare nmbd_command - declare netbios_name - - # - # Specify daemon options - # -D = spawn off as separate daemon - # -s = the following arg specifies the config file - # - declare smbd_options="-D -s" - declare nmbd_options="-D -s" - - if [ "$command" = "start" ]; then - gen_smb_conf "$conf" - else - if ! [ -f "$conf" ]; then - ocf_log warn ""$conf" missing during $command" - fi - fi - - # - # On clusters with multiple samba shares, we need to ensure (as much - # as possible) that each service is advertised as a separate netbios - # name. - # - # Generally, the admin sets this in smb.conf.NAME - but since - # it is not required, we need another option. Consequently, we use - # smb instance name (which must be unique) - # - if [ -f "$conf" ]; then - grep -qe "^([[:space:]]+n|n)etbios[[:space:]]+name[[:space:]]*=[[:space:]]*[[:alnum:]]+" "$conf" - if [ $? -ne 0 ]; then - - netbios_name=$OCF_RESKEY_name - - ocf_log notice "Using $netbios_name as NetBIOS name (service $OCF_RESKEY_service_name)" - nmbd_options=" -n $netbios_name $nmbd_options" - fi - fi - - case $command in - start) - ocf_log info "Starting Samba instance "$OCF_RESKEY_name"" - mkdir -p "$SAMBA_PID_DIR/$OCF_RESKEY_name" - mkdir -p "$SAMBA_LOCK_DIR/$OCF_RESKEY_name" - - # Kick off the per-service smbd - $SMBD_COMMAND $smbd_options "$conf" - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err "Samba service failed: $SMBD_COMMAND $smbd_options "$conf"" - return $_FAIL - fi - ocf_log debug "Samba service succeeded: $SMBD_COMMAND $smbd_options "$conf"" - - # Kick off the per-service nmbd - $NMBD_COMMAND $nmbd_options "$conf" - ret_val=$? - if [ $ret_val -ne 0 ]; then - ocf_log err "Samba service failed: $NMBD_COMMAND $nmbd_options "$conf"" - return $_FAIL - fi - ocf_log debug "Samba service succeeded: $NMBD_COMMAND $nmbd_options "$conf"" - ;; - stop) - ocf_log info "Stopping Samba instance "$OCF_RESKEY_name"" - - kill_daemon_by_arg "nmbd" $command "$conf" - kill_daemon_by_arg "smbd" $command "$conf" - if [ "$SAMBA_PID_DIR/$OCF_RESKEY_name" != "/" ]; then - pushd "$SAMBA_PID_DIR" &> /dev/null - rm -rf "$OCF_RESKEY_name" - popd &> /dev/null - fi - if [ "$SAMBA_LOCK_DIR/$OCF_RESKEY_name" != "/" ]; then - pushd "$SAMBA_LOCK_DIR" &> /dev/null - rm -rf "$OCF_RESKEY_name" - popd &> /dev/null - fi - ;; - status) - ocf_log debug "Checking Samba instance "$OCF_RESKEY_name"" - kill_daemon_by_arg "nmbd" $command "$conf" - if [ $? -ne 0 ]; then - ocf_log err \ - "share_start_stop: nmbd for service $svc_name died!" - return $_FAIL - fi - kill_daemon_by_arg "smbd" $command "$conf" - if [ $? -ne 0 ]; then - ocf_log err \ - "share_start_stop: nmbd for service $svc_name died!" - return $_FAIL - fi - ;; - esac -} - - -verify_all() -{ - [ -z "$OCF_RESKEY_workgroup" ] && export OCF_RESKEY_workgroup="LINUXCLUSTER" - [ -n "${OCF_RESKEY_name}" ] || exit $OCF_ERR_ARGS # Invalid Argument - if [ -z "${OCF_RESKEY_service_name}" ]; then - ocf_log ERR "Samba service ${OCF_RESKEY_name} is not the child of a service" - exit $OCF_ERR_ARGS - fi -} - -case $1 in - meta-data) - meta_data - exit 0 - ;; - start|stop) - verify_all - share_start_stop $1 - exit $? - ;; - status|monitor) - verify_all - share_start_stop status - exit $? - ;; - verify-all) - verify_all - echo "Yer radio's workin', driver!" - exit 0 - ;; - *) - echo "usage: $0 {start|stop|status|monitor|meta-data|verify-all}" - exit $OCF_ERR_ARGS - ;; -esac - diff --git a/rgmanager/src/resources/svclib_nfslock b/rgmanager/src/resources/svclib_nfslock deleted file mode 100644 index a0250b2..0000000 --- a/rgmanager/src/resources/svclib_nfslock +++ /dev/null @@ -1,278 +0,0 @@ -#!/bin/bash -# -# Copyright Red Hat Inc., 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# Do reclaim-broadcasts when we kill lockd during shutdown/startup -# of a cluster service. -# -# Exported functions: -# -# notify_list_store -# notify_list_merge -# notify_list_broadcast -# - -# -# Usage: -# statd_notify <directory> <hostname|ip> -# -# Copy out a list from <directory>, merge them with the system nfs lock -# list, and send them out as <hostname|ip> after generating a random -# state (needed so clients will reclaim their locks) -# -nfslock_statd_notify() -{ - declare tmpdir=$(mktemp -d /tmp/statd-$2.XXXXXX) - declare nl_dir=$1 - declare nl_ip=$2 - declare command # Work around bugs in rpc.statd - declare pid_xxx # Work around bugs in rpc.statd - declare owner - - [ -z "$lockd_pid" ] && return 0 - if ! [ -d $nl_dir ]; then - return 0 - fi - - if [ -z "`ls $nl_dir/sm/* 2> /dev/null`" ]; then - ocf_log debug "No hosts to notify" - return 0 - fi - - # Ok, copy the HA directory to something we can use. - mkdir -p $tmpdir/sm - - # Copy in our specified entries - cp -f $nl_dir/sm/* $tmpdir/sm - - # Copy in our global entries - # XXX This might be what we just copied. - - if [ -d "/var/lib/nfs/statd/sm" ]; then - owner=$(ls -dl /var/lib/nfs/statd/sm | awk '{print $3"."$4}') - cp -f /var/lib/nfs/statd/sm/* $tmpdir/sm - elif [ -d "/var/lib/nfs/sm" ]; then - owner=$(ls -dl /var/lib/nfs/statd/sm | awk '{print $3"."$4}') - cp -f /var/lib/nfs/sm/* $tmpdir/sm - fi - - # - # Generate a random state file. If this ends up being what a client - # already has in its list, that's bad, but the chances of this - # are small - and relocations should be rare. - # - dd if=/dev/urandom of=$tmpdir/state bs=1 count=4 &> /dev/null - - # - # Make sure we set permissions, or statd will not like it. - # - chown -R $owner $tmpdir - - # - # Tell rpc.statd to notify clients. Don't go into background, - # because statd is buggy and won't exit like it's supposed to after - # sending the notifications out. - # - ocf_log info "Sending reclaim notifications via $nl_ip" - command="rpc.statd -NFP $tmpdir -n $nl_ip" - eval $command 2>&1 & - sleep 3 # XXX - the instance of rpc.statd we just spawned is supposed - # to exit after it finishes notifying clients. - # rpc.statd spawned which is still running handles the actual - # new SM_MON requests... we hope 3 seconds is enough time - # to get all the SM_NOTIFY messages out. rpc.statd = bugged - # - # clean up - # - pid_xxx=`ps auwwx | grep "$command" | grep -v grep | awk '{print $2}'` - kill $pid_xxx - rm -rf $tmpdir - - return 0 -} - - -# -# Copy of isSlave from svclib_ip and/or ip.sh -# -nfslock_isSlave() -{ - declare intf=$1 - declare line - - if [ -z "$intf" ]; then - ocf_log err "usage: isSlave <I/F>" - return 1 - fi - - line=$(/sbin/ip link list dev $intf) - if [ $? -ne 0 ]; then - ocf_log err "$intf not found" - return 1 - fi - - if [ "$line" = "${line/<*SLAVE*>/}" ]; then - return 2 - fi - - # Yes, it is a slave device. Ignore. - return 0 -} - - -# -# Get all the IPs on the system except loopback IPs -# -nfslock_ip_address_list() -{ - declare idx dev family ifaddr - - while read idx dev family ifaddr; do - - if [ "$family" != "inet" ] && [ "$family" != "inet6" ]; then - continue - fi - - if [ "$dev" = "lo" ]; then - # Ignore loopback - continue - fi - - nfslock_isSlave $dev - if [ $? -ne 2 ]; then - continue - fi - - idx=${idx/:/} - - echo $dev $family ${ifaddr//*/} ${ifaddr/*//} - - done < <(/sbin/ip -o addr list | awk '{print $1,$2,$3,$4}') - - return 0 -} - - -# -# Usage: broadcast_notify <state_directory> -# -# Send the contents of <state_directory> out via all IPs on the system. -# -notify_list_broadcast() -{ - declare dev family addr maskbits ip_name - declare lockd_pid=$(pidof lockd) - declare nl_dir=$1 - - # First of all, send lockd a SIGKILL. We hope nfsd is running. - # If it is, this will cause lockd to reset the grace period for - # lock reclaiming. - if [ -n "$lockd_pid" ]; then - ocf_log info "Asking lockd to drop locks (pid $lockd_pid)" - kill -9 $lockd_pid - else - ocf_log warning "lockd not running; cannot notify clients" - return 1 - fi - - while read dev family addr maskbits; do - if [ "$family" != "inet" ]; then - continue - fi - - ip_name=$(clufindhostname -i $addr) - if [ -z "$ip_name" ]; then - nfslock_statd_notify $nl_dir $addr - else - nfslock_statd_notify $nl_dir $ip_name - fi - - done < <(nfslock_ip_address_list) -} - - -# -# Store the lock monitor list from rpc.statd - do this during a teardown -# after the IP addresses of a service have been taken offline. Note that -# this should be done by HA-callout programs, but this feature is not in -# RHEL3. -# -notify_list_store() -{ - declare nl_dir=$1 - declare owner - - mkdir -p $nl_dir/sm - - if [ -d "/var/lib/nfs/statd/sm" ]; then - if [ -z "`ls /var/lib/nfs/statd/sm/* 2> /dev/null`" ]; then - return 1 - # nothing to do! - fi - - owner=$(ls -dl /var/lib/nfs/statd/sm | awk '{print $3"."$4}') - cp -af /var/lib/nfs/statd/sm/* $nl_dir/sm - chown -R $owner $nl_dir - return 0 - elif [ -d "/var/lib/nfs/sm" ]; then - if [ -z "`ls /var/lib/nfs/sm/* 2> /dev/null`" ]; then - return 1 - # nothing to do! - fi - - owner=$(ls -dl /var/lib/nfs/sm | awk '{print $3"."$4}') - cp -af /var/lib/nfs/sm/* $nl_dir/sm - chown -R $owner $nl_dir - return 0 - fi - - return 1 -} - - -# -# Merge the contents of <nl_dir>/sm with the system-wide list -# Make sure ownership is right, or statd will hiccup. This should not -# actually ever be needed because statd will, upon getting a SM_MON -# request, create all the entries in this list. It's mostly for -# housekeeping for next time we relocate the service. -# -notify_list_merge() -{ - declare nl_dir=$1 - declare owner - - if [ -z "`ls $nl_dir/* 2> /dev/null`" ]; then - return 1 - fi - - if [ -d "/var/lib/nfs/statd/sm" ]; then - owner=$(ls -dl /var/lib/nfs/statd/sm | awk '{print $3"."$4}') - cp -af $nl_dir/sm/* /var/lib/nfs/statd/sm - chown -R $owner $nl_dir - return 0 - elif [ -d "/var/lib/nfs/sm" ]; then - owner=$(ls -dl /var/lib/nfs/sm | awk '{print $3"."$4}') - cp -af $nl_dir/sm/* /var/lib/nfs/sm - chown -R $owner $nl_dir - return 0 - fi - - return 1 -} - diff --git a/rgmanager/src/resources/tomcat-5.metadata b/rgmanager/src/resources/tomcat-5.metadata deleted file mode 100644 index a6fb8d8..0000000 --- a/rgmanager/src/resources/tomcat-5.metadata +++ /dev/null @@ -1,104 +0,0 @@ -<?xml version="1.0"?> -<resource-agent version="rgmanager 2.0" name="tomcat-5"> - <version>1.0</version> - - <longdesc lang="en"> - This defines an instance of Tomcat server - </longdesc> - <shortdesc lang="en"> - Defines a Tomcat server - </shortdesc> - - <parameters> - <parameter name="name" primary="1"> - <longdesc lang="en"> - Specifies a service name for logging and other purposes - </longdesc> - <shortdesc lang="en"> - Name - </shortdesc> - <content type="string"/> - </parameter> - - <parameter name="config_file"> - <longdesc lang="en"> - Define absolute path to configuration file - </longdesc> - <shortdesc lang="en"> - Config File - </shortdesc> - <content type="string" default="/etc/tomcat5/tomcat5.conf"/> - </parameter> - - <parameter name="tomcat_user"> - <longdesc lang="en"> - User who runs the Tomcat server - </longdesc> - <shortdesc lang="en"> - User who runs the Tomcat server - </shortdesc> - <content type="string" default="tomcat" /> - </parameter> - - <parameter name="catalina_options"> - <longdesc lang="en"> - Other command-line options for Catalina - </longdesc> - <shortdesc lang="en"> - Other command-line options for Catalina - </shortdesc> - <content type="string" /> - </parameter> - - <parameter name="catalina_base"> - <longdesc lang="en"> - Cataliny base directory - </longdesc> - <shortdesc lang="en"> - Catalina base directory (differs for each service) - </shortdesc> - <content type="string" default="/usr/share/tomcat5" /> - </parameter> - - <parameter name="shutdown_wait"> - <longdesc lang="en"> - Wait X seconds for correct end of service shutdown - </longdesc> - <shortdesc lang="en"> - Wait X seconds for correct end of service shutdown - </shortdesc> - <content type="number" default="30" /> - </parameter> - - <parameter name="service_name" inherit="service%name"> - <longdesc lang="en"> - Inherit the service name. We need to know - the service name in order to determine file - systems and IPs for this service. - </longdesc> - <shortdesc lang="en"> - Inherit the service name. - </shortdesc> - <content type="string"/> - </parameter> - </parameters> - - <actions> - <action name="start" timeout="0"/> - <action name="stop" timeout="0"/> - - <!-- Checks to see if it''s mounted in the right place --> - <action name="status" interval="1m" timeout="10"/> - <action name="monitor" interval="1m" timeout="10"/> - - <!-- Checks to see if we can read from the mountpoint --> - <action name="status" depth="10" timeout="30" interval="5m"/> - <action name="monitor" depth="10" timeout="30" interval="5m"/> - - <action name="meta-data" timeout="0"/> - <action name="verify-all" timeout="0"/> - </actions> - - <special tag="rgmanager"> - </special> -</resource-agent> diff --git a/rgmanager/src/resources/tomcat-5.sh b/rgmanager/src/resources/tomcat-5.sh deleted file mode 100755 index d085535..0000000 --- a/rgmanager/src/resources/tomcat-5.sh +++ /dev/null @@ -1,287 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Gener5~al Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -export LC_ALL=C -export LANG=C -export PATH=/bin:/sbin:/usr/bin:/usr/sbin - -. $(dirname $0)/ocf-shellfuncs -. $(dirname $0)/utils/config-utils.sh -. $(dirname $0)/utils/messages.sh -. $(dirname $0)/utils/ra-skelet.sh - -declare TOMCAT_TOMCAT=/usr/bin/dtomcat5 -declare TOMCAT_RELINK=/usr/share/tomcat5/bin/relink -declare TOMCAT_pid_file="`generate_name_for_pid_file`" -declare TOMCAT_conf_dir="`generate_name_for_conf_dir`/conf" -declare TOMCAT_gen_config_file="$TOMCAT_conf_dir/server.xml" -declare TOMCAT_gen_catalina_base="`generate_name_for_conf_dir`" - -declare JAVA_HOME -declare CATALINA_HOME -declare CATALINA_BASE -declare CATALINA_TMPDIR -declare CLASSPATH -declare TOMCAT_USER -## - -verify_all() -{ - clog_service_verify $CLOG_INIT - - if [ -z "$OCF_RESKEY_name" ]; then - clog_service_verify $CLOG_FAILED "Invalid Name Of Service" - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_service_name" ]; then - clog_service_verify $CLOG_FAILED_NOT_CHILD - return $OCF_ERR_ARGS - fi - - if [ -z "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$OCF_RESKEY_config_file" - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - if [ ! -r "$OCF_RESKEY_config_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_READABLE $OCF_RESKEY_config_file - clog_service_verify $CLOG_FAILED - return $OCF_ERR_ARGS - fi - - . "$OCF_RESKEY_config_file" - - if [ $? -ne 0 ]; then - clog_service_verify $CLOG_FAILED "Error In The File "$OCF_RESKEY_config_file"" - return $OCF_ERR_ARGS - fi - - if [ -z "$JAVA_HOME" ]; then - clog_service_verify $CLOG_FAILED "JAVA_HOME Not Specified In ${OCF_RESKEY_config_file}" - return $OCF_ERR_ARGS; - fi - - if [ ! -d "$JAVA_HOME" ]; then - clog_service_verify $CLOG_FAILED "JAVA_HOME Does Not Exist" - return $OCF_ERR_ARGS; - fi - - if [ -z "$JAVA_ENDORSED_DIRS" ]; then - clog_service_verify $CLOG_FAILED "JAVA_ENDORSED_DIRS Not Specified In ${OCF_RESKEY_config_file}" - return $OCF_ERR_ARGS; - fi - - if [ ! -d "$JAVA_ENDORSED_DIRS" ]; then - clog_service_verify $CLOG_FAILED "JAVA_ENDORSED_DIRS Does Not Exist" - return $OCF_ERR_ARGS; - fi - - if [ -z "$CATALINA_HOME" ]; then - clog_service_verify $CLOG_FAILED "CATALINA_HOME Not Specified In ${OCF_RESKEY_config_file}" - return $OCF_ERR_ARGS; - fi - - if [ ! -d "$CATALINA_HOME" ]; then - clog_service_verify $CLOG_FAILED "CATALINA_HOME Does Not Exist" - return $OCF_ERR_ARGS; - fi - - if [ -z "$CATALINA_TMPDIR" ]; then - clog_service_verify $CLOG_FAILED "CATALINA_TMPDIR Not Specified In ${OCF_RESKEY_config_file}" - return $OCF_ERR_ARGS; - fi - - if [ ! -d "$CATALINA_TMPDIR" ]; then - clog_service_verify $CLOG_FAILED "CATALINA_TMPDIR Does Not Exist" - return $OCF_ERR_ARGS; - fi - - if [ -z "$TOMCAT_USER" ]; then - clog_service_verify $CLOG_FAILED "TOMCAT_USER Does Not Exist" - return $OCF_ERR_ARGS; - fi - - clog_service_verify $CLOG_SUCCEED - - return 0 -} - -generate_config_file() -{ - declare original_file="$1" - declare generated_file="$2" - declare ip_addresses="$3" - - if [ -f "$generated_file" ]; then - sha1_verify "$generated_file" - if [ $? -ne 0 ]; then - clog_check_sha1 $CLOG_FAILED - return 0 - fi - fi - - clog_generate_config $CLOG_INIT "$original_file" "$generated_file" - -# generate_configTemplate "$generated_file" "$original_file" - $(dirname $0)/utils/tomcat-parse-config.pl $ip_addresses < "$original_file" >> "$generated_file" - - sha1_addToFile "$generated_file" - clog_generate_config $CLOG_SUCCEED "$original_file" "$generated_file" - - return 0; -} - -start() -{ - declare ccs_fd; - - clog_service_start $CLOG_INIT - - create_pid_directory - create_conf_directory "$TOMCAT_conf_dir" - check_pid_file "$TOMCAT_pid_file" - - if [ $? -ne 0 ]; then - clog_check_pid $CLOG_FAILED "$TOMCAT_pid_file" - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - clog_looking_for $CLOG_INIT "IP Addresses" - - ccs_fd=$(ccs_connect); - if [ $? -ne 0 ]; then - clog_looking_for $CLOG_FAILED_CCS - return $OCF_ERR_GENERIC - fi - - get_service_ip_keys "$ccs_fd" "$OCF_RESKEY_service_name" - ip_addresses=`build_ip_list "$ccs_fd"` - - if [ -z "$ip_addresses" ]; then - clog_looking_for $CLOG_FAILED_NOT_FOUND "IP Addresses" - return $OCF_ERR_GENERIC - fi - - clog_looking_for $CLOG_SUCCEED "IP Addresses" - generate_config_file "$OCF_RESKEY_catalina_base/conf/server.xml" "$TOMCAT_gen_config_file" "$ip_addresses" - ln -s "$OCF_RESKEY_catalina_base"/* "$TOMCAT_gen_catalina_base" &> /dev/null - ln -s "$OCF_RESKEY_catalina_base"/conf/* "$TOMCAT_gen_catalina_base"/conf &> /dev/null - - CLASSPATH="$JAVA_HOME"/lib/tools.jar:"$CATALINA_HOME"/bin/bootstrap.jar:"$CATALINA_HOME"/bin/commons-logging-api.jar:`/usr/bin/build-classpath mx4j/mx4j-impl`:`/usr/bin/build-classpath mx4j/mx4j-jmx` - - sudo -u "$TOMCAT_USER" "$JAVA_HOME/bin/java" $JAVA_OPTS $OCF_RESKEY_catalina_options \ - -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \ - -Dcatalina.base="$TOMCAT_gen_catalina_base" \ - -Dcatalina.home="$CATALINA_HOME" \ - -Djava.io.tmpdir="$CATALINA_TMPDIR" \ - org.apache.catalina.startup.Bootstrap "$@" start \ - >> "$TOMCAT_gen_catalina_base"/logs/catalina.out 2>&1 & - - - if [ $? -ne 0 ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - if [ -z "$!" ]; then - clog_service_start $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - echo $! > "$TOMCAT_pid_file" - - clog_service_start $CLOG_SUCCEED - - return 0; -} - -stop() -{ - clog_service_stop $CLOG_INIT - - stop_generic "$TOMCAT_pid_file" "$OCF_RESKEY_shutdown_wait" - - if [ $? -ne 0 ]; then - clog_service_stop $CLOG_FAILED - return $OCF_ERR_GENERIC - fi - - if [ -e "$TOMCAT_pid_file" ]; then - rm -f "$TOMCAT_pid_file" - fi - - clog_service_stop $CLOG_SUCCEED - return 0; -} - -status() -{ - clog_service_status $CLOG_INIT - - status_check_pid "$TOMCAT_pid_file" - if [ $? -ne 0 ]; then - clog_service_status $CLOG_FAILED "$TOMCAT_pid_file" - return $OCF_ERR_GENERIC - fi - - clog_service_status $CLOG_SUCCEED - return 0 -} - -case $1 in - meta-data) - cat `echo $0 | sed 's/^(.*).sh$/\1.metadata/'` - exit 0 - ;; - verify-all) - verify_all - exit $? - ;; - start) - verify_all && start - exit $? - ;; - stop) - verify_all && stop - exit $? - ;; - status|monitor) - verify_all - status - exit $? - ;; - restart) - verify_all - stop - start - exit $? - ;; - *) - echo "Usage: $0 {start|stop|status|monitor|restart|meta-data|verify-all}" - exit $OCF_ERR_GENERIC - ;; -esac diff --git a/rgmanager/src/resources/utils/config-utils.sh b/rgmanager/src/resources/utils/config-utils.sh deleted file mode 100644 index 67049c7..0000000 --- a/rgmanager/src/resources/utils/config-utils.sh +++ /dev/null @@ -1,307 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# - -declare RA_COMMON_pid_dir=/var/run/cluster -declare RA_COMMON_conf_dir=/etc/cluster - -declare -i FAIL=-1 -declare -a ip_keys - -generate_configTemplate() -{ - cat > $1 << EOT -# -# "$1" was created from the "$2" -# -# This template configuration was automatically generated, and will be -# automatically regenerated if removed. Once this file has been altered, -# automatic re-generation will stop. Remember to copy this file to all -# other cluster members after making changes, or your service will not -# operate correctly. -# -EOT -} - -sha1_addToFile() -{ - declare sha1line="# rgmanager-sha1 $(sha1sum "$1")" - echo $sha1line >> "$1" -} - -sha1_verify() -{ - declare sha1_new sha1_old - declare oldFile=$1 - - ocf_log debug "Checking: SHA1 checksum of config file $oldFile" - - sha1_new=`cat $oldFile | grep -v "# rgmanager-sha1" | sha1sum | sed 's/^([a-z0-9]+) .*$/\1/'` - sha1_old=`tail -n 1 $oldFile | sed 's/^# rgmanager-sha1 (.*)$/\1/' | sed 's/^([a-z0-9]+) .*$/\1/'` - - if [ $sha1_new = $sha1_old ]; then - ocf_log debug "Checking: SHA1 checksum > succeed" - return 0; - else - ocf_log debug "Checking: SHA1 checksum > failed - file changed" - return 1; - fi -} - -# -# Usage: ccs_connect -# Returns: $FAIL on failure, or a connection descriptor on success -# -ccs_connect() -{ - declare outp - - outp=$(ccs_test connect 2>&1) - if [ $? -ne 0 ]; then - ocf_log err "$outp" - return $FAIL - fi - - outp=${outp/*= /} - if [ -n "$outp" ]; then - echo $outp - return 0 - fi - - return 1 -} - -# -# Usage: ccs_disconnect descriptor -# -ccs_disconnect() -{ - declare outp - - [ -n "$1" ] || return $FAIL - outp=$(ccs_test disconnect $1 2>&1) - if [ $? -ne 0 ]; then - ocf_log warn "Disconnect CCS desc $1 failed: $outp" - return 1 - fi - return 0 -} - -# -# Usage: ccs_get desc key -# -ccs_get() -{ - declare outp - declare ccsfd=$1 - declare key - - [ -n "$1" ] || return $FAIL - [ -n "$2" ] || return $FAIL - - shift - key="$*" - - outp=$(ccs_test get $ccsfd "$key" 2>&1) - if [ $? -ne 0 ]; then - if [ "$outp" = "${outp/No data available/}" ]; then - ocf_log err "$outp ($key)" - return $FAIL - fi - - # no real error, just no data available - return 0 - fi - - outp=${outp/*</} - outp=${outp/>*/} - - echo $outp - - return 0 -} - -# -# Build a list of service IP keys; traverse refs if necessary -# Usage: get_service_ip_keys desc serviceName -# -get_service_ip_keys() -{ - declare ccsfd=$1 - declare svc=$2 - declare -i x y=0 - declare outp - declare key - - if [ $ccsfd -eq $FAIL ]; then - ocf_log err "Can not talk to ccsd: invalid descriptor $ccsfd" - return 1 - fi - - # - # Find service-local IP keys - # - x=1 - while : ; do - key="/cluster/rm/service[@name="$svc"]/ip[$x]" - - # - # Try direct method - # - outp=$(ccs_get $ccsfd "$key/@address") - if [ $? -ne 0 ]; then - return 1 - fi - - # - # Try by reference - # - if [ -z "$outp" ]; then - outp=$(ccs_get $ccsfd "$key/@ref") - if [ $? -ne 0 ]; then - return 1 - fi - key="/cluster/rm/resources/ip[@address="$outp"]" - fi - - if [ -z "$outp" ]; then - break - fi - - #ocf_log debug "IP $outp found @ $key" - - ip_keys[$y]="$key" - - ((y++)) - ((x++)) - done - - ocf_log debug "$y IP addresses found for $svc/$OCF_RESKEY_name" - - return 0 -} - -build_ip_list() -{ - declare -i ccsfd=$1 - declare ipaddrs ipaddr - declare -i x=0 - - while [ -n "${ip_keys[$x]}" ]; do - ipaddr=$(ccs_get $ccsfd "${ip_keys[$x]}/@address") - if [ -z "$ipaddr" ]; then - break - fi - - ipaddrs="$ipaddrs $ipaddr" - ((x++)) - done - - echo $ipaddrs -} - -generate_name_for_pid_file() -{ - declare filename=$(basename $0) - - echo "$RA_COMMON_pid_dir/$(basename $0 | sed 's/^(.*)..*/\1/')/$OCF_RESOURCE_INSTANCE.pid" - - return 0; -} - -generate_name_for_pid_dir() -{ - declare filename=$(basename $0) - - echo "$RA_COMMON_pid_dir/$(basename $0 | sed 's/^(.*)..*/\1/')/$OCF_RESOURCE_INSTANCE" - - return 0; -} - -generate_name_for_conf_dir() -{ - declare filename=$(basename $0) - - echo "$RA_COMMON_conf_dir/$(basename $0 | sed 's/^(.*)..*/\1/')/$OCF_RESOURCE_INSTANCE" - - return 0; -} - -create_pid_directory() -{ - declare program_name="$(basename $0 | sed 's/^(.*)..*/\1/')" - declare dirname="$RA_COMMON_pid_dir/$program_name" - - if [ -d "$dirname" ]; then - return 0; - fi - - chmod 711 "$RA_COMMON_pid_dir" - mkdir -p "$dirname" - - if [ "$program_name" = "mysql" ]; then - chown mysql.root "$dirname" - elif [ "$program_name" = "tomcat-5" ]; then - chown tomcat.root "$dirname" - fi - - return 0; -} - -create_conf_directory() -{ - declare dirname="$1" - - if [ -d "$dirname" ]; then - return 0; - fi - - mkdir -p "$dirname" - - return 0; -} - -check_pid_file() { - declare pid_file="$1" - - if [ -z "$pid_file" ]; then - return 1; - fi - - if [ ! -e "$pid_file" ]; then - return 0; - fi - - ## if PID file is empty then it should be safe to remove it - read pid < "$pid_file" - if [ -z "$pid" ]; then - rm $pid_file - ocf_log debug "PID File "$pid_file" Was Removed - Zero length"; - return 0; - fi - - if [ ! -d /proc/`cat "$pid_file"` ]; then - rm "$pid_file" - ocf_log debug "PID File "$pid_file" Was Removed - PID Does Not Exist"; - return 0; - fi - - return 1; -} \ No newline at end of file diff --git a/rgmanager/src/resources/utils/httpd-parse-config.pl b/rgmanager/src/resources/utils/httpd-parse-config.pl deleted file mode 100755 index 26ef378..0000000 --- a/rgmanager/src/resources/utils/httpd-parse-config.pl +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/perl -w - -## -## This script removes <IfDefine foo> sections from the -## Apache httpd.conf file. This is quite useful because we -## don't have any direct access to the parsed configuration -## file of the httpd server. -## -## Usage: ./httpd-parse-config.pl -Dfoo1 -Dfoo2 < httpd.conf -## where fooX are defines as passed to the httpd server -## -## Note: All whitespace characters at the beginning and end -## of lines are removed. -## -use strict; - -my @defines = (); -## Default behaviour is to show all lines when we are not -## in the <IfDefine foo> sections. -my @show = (1); - -sub testIfDefine($) { - my $param = $1; - my $positiveTest = 1; - if ($param =~ /^!(.*)$/) { - $param = $1; - $positiveTest = 0; - } - - foreach my $def (@defines) { - if ($def eq $param) { - return $positiveTest; - } - } - - return (1-$positiveTest); -} - -foreach my $arg (@ARGV) { - if ($arg =~ /^-D(.*)$/) { - push(@defines, $1); - } -} - -## Parse config file and remove IfDefine sections -while (my $line = <STDIN>) { - chomp($line); - $line =~ s/^\s*(.*?)\s*$/$1/; - if ($line =~ /<IfDefine (.*)>/) { - if (testIfDefine($1) == 1) { - if ($show[$#show] == 1) { - push (@show, 1); - } else { - push (@show, 0); - } - } else { - push (@show, 0); - } - } elsif ($line =~ /</IfDefine>/) { - pop(@show); - } elsif ($show[$#show] == 1) { - print $line, "\n"; - } -} - diff --git a/rgmanager/src/resources/utils/member_util.sh b/rgmanager/src/resources/utils/member_util.sh deleted file mode 100644 index 4026e59..0000000 --- a/rgmanager/src/resources/utils/member_util.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2007 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# Description: -# Utility functions to get membership information. -# -# Author(s): -# Lon Hohberger (lhh at redhat.com) -# - -# -# Use clustat to figure out if the specified node is a member -# of the cluster. Returns 2 if not found, 1 if not a member, and -# 0 if the node is happily running. -# Tested on RHEL4 and RHEL5; requires RHCS 5.1 or 4.5 to operate -# properly in all cases. -# -is_node_member_clustat() -{ - declare line=$(clustat -xm $1 | grep "name="$1"") - declare tmp - - # Done if there's no node in the list with that name: not a - # cluster member, and not in the configuration. - [ -n "$line" ] || return 2 - - # Clear out xml tag seps. - line=${line/*</} - line=${line//>/} - - # Make vars out of XML attributes. - for tmp in $line; do - eval declare __$tmp - done - - # Flip the value. clustat reports 1 for member, 0 for not; - # Exactly the opposite of what a shell script expects. - ((__state = !__state)) - return $__state -} - - -# -# Print the local node name to stdout -# Returns 0 if could be found, 1 if not -# Tested on RHEL4 (magma) and RHEL5 (cman) -# -local_node_name() -{ - declare node state line - - if which magma_tool &> /dev/null; then - # Use magma_tool, if available. - line=$(magma_tool localname | grep "^Local") - res=$? - - if [ $res -ne 0 ]; then - # magma_tool failed. - return 2 - fi - - if [ -n "$line" ]; then - echo ${line/* = /} - return 0 - fi - fi - - if ! which cman_tool &> /dev/null; then - # No cman tool? :( - return 2 - fi - - # Use cman_tool - - line=$(cman_tool status | grep -i "Node name: $1") - [ -n "$line" ] || return 1 - echo ${line/*name: /} - return 0 -} - diff --git a/rgmanager/src/resources/utils/messages.sh b/rgmanager/src/resources/utils/messages.sh deleted file mode 100644 index 533c58a..0000000 --- a/rgmanager/src/resources/utils/messages.sh +++ /dev/null @@ -1,272 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# Description: -# Catalog of log messages for resources agents -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# - -declare CLOG_INIT=100 -declare CLOG_SUCCEED=200 - -declare CLOG_FAILED=400 -declare CLOG_FAILED_TIMEOUT=401 -declare CLOG_FAILED_CCS=402 -declare CLOG_FAILED_NOT_FOUND=403 -declare CLOG_FAILED_INVALID=404 -declare CLOG_FAILED_NOT_READABLE=405 - -## -## Usage: -## clog_service_start %operation% -## -clog_service_start() -{ - case $1 in - $CLOG_INIT) - ocf_log info "Starting Service $OCF_RESOURCE_INSTANCE" - ;; - $CLOG_SUCCEED) - ocf_log debug "Starting Service $OCF_RESOURCE_INSTANCE > Succeed" - ;; - $CLOG_FAILED) - ocf_log error "Starting Service $OCF_RESOURCE_INSTANCE > Failed" - ;; - $CLOG_FAILED_TIMEOUT) - ocf_log error "Starting Service $OCF_RESOURCE_INSTANCE > Failed - Timeout Error" - ;; - esac - return 0 -} - -## -## Usage: -## clog_service_stop %operation% -## -clog_service_stop() -{ - case $1 in - $CLOG_INIT) - ocf_log info "Stopping Service $OCF_RESOURCE_INSTANCE" - ;; - $CLOG_SUCCEED) - ocf_log info "Stopping Service $OCF_RESOURCE_INSTANCE > Succeed" - ;; - $CLOG_FAILED) - ocf_log error "Stopping Service $OCF_RESOURCE_INSTANCE > Failed" - ;; - $CLOG_FAILED_NOT_STOPPED) - ocf_log error "Stopping Service $OCF_RESOURCE_INSTANCE > Failed - Application Is Still Running" - ;; - esac - return 0 -} - -## -## Usage: -## clog_service_status %operation% -## -clog_service_status() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Monitoring Service $OCF_RESOURCE_INSTANCE" - ;; - $CLOG_SUCCEED) - ocf_log debug "Monitoring Service $OCF_RESOURCE_INSTANCE > Service Is Running" - ;; - $CLOG_FAILED) - ocf_log error "Monitoring Service $OCF_RESOURCE_INSTANCE > Service Is Not Running" - ;; - $CLOG_FAILED_NOT_FOUND) - ocf_log error "Monitoring Service $OCF_RESOURCE_INSTANCE > Service Is Not Running - PID File Not Found" - ;; - esac - return 0 -} - -## -## Usage: -## clog_service_verify %operation% -## clog_service_verify $CLOG_FAILED %reason% -## -clog_service_verify() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Verifying Configuration Of $OCF_RESOURCE_INSTANCE" - ;; - $CLOG_SUCCEED) - ocf_log debug "Verifying Configuration Of $OCF_RESOURCE_INSTANCE > Succeed" - ;; - $CLOG_FAILED_NOT_CHILD) - ocf_log error "Service $OCF_RESOURCE_INSTANCE Is Not A Child Of A Service" - ;; - $CLOG_FAILED) - if [ "x$2" = "x" ]; then - ocf_log error "Verifying Configuration Of $OCF_RESOURCE_INSTANCE > Failed" - else - ocf_log error "Verifying Configuration Of $OCF_RESOURCE_INSTANCE > Failed - $2" - fi - ;; - esac - return 0 -} - - -## -## Usage: -## clog_check_sha1 %operation% %filename% -## -clog_check_sha1() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Checking SHA1 Checksum Of File $1" - ;; - $CLOG_SUCCEED) - ocf_log debug "Checking SHA1 Checksum Of File > Succeed" - ;; - $CLOG_FAILED) - ocf_log debug "Checking SHA1 Checksum Of File > Failed - File Changed" - ;; - esac - return 0; -} - -## -## Usage: -## clog_check_file_exist %operation% %filename% -## -clog_check_file_exist() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Checking Existence Of File $2" - ;; - $CLOG_SUCCEED) - ocf_log debug "Checking Existence Of File $2 > Succeed" - ;; - $CLOG_FAILED) - ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed" - ;; - $CLOG_FAILED_INVALID) - ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed - Invalid Argument" - ;; - $CLOG_FAILED_NOT_FOUND) - ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed - File Doesn't Exist" - ;; - $CLOG_FAILED_NOT_READABLE) - ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed - File Is Not Readable" - ;; - esac - return 0; -} - -## -## Usage: -## clog_check_pid %operation% %filename% -## -clog_check_pid() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Checking Non-Existence Of PID File $2" - return 0 - ;; - $CLOG_SUCCEED) - ocf_log debug "Checking Non-Existence of PID File $2 > Succeed" - ;; - $CLOG_FAILED) - ocf_log error "Checking Non-Existence of PID File $2 [$OCF_RESOURCE_INSTANCE] > Failed - PID File Exists For $OCF_RESOURCE_INSTANCE" - ;; - esac - return 0; -} - -## -## Usage: -## clog_check_syntax %operation% %filename% -## -clog_check_syntax() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Checking Syntax Of The File $2" - ;; - $CLOG_SUCCEED) - ocf_log debug "Checking Syntax Of The File $2 > Succeed" - ;; - $CLOG_FAILED) - ocf_log error "Checking Syntax Of The File $2 [$OCF_RESOURCE_INSTANCE] > Failed" - ;; - esac - return 0; -} - -## -## Usage: -## clog_generate_config %operation% %old filename% %new filename% -## -clog_generate_config() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Generating New Config File $3 From $2" - ;; - $CLOG_SUCCEED) - ocf_log debug "Generating New Config File $3 From $2 > Succeed" - ;; - $CLOG_FAILED) - ocf_log error "Generating New Config File $3 From $2 [$OCF_RESOURCE_INSTANCE] > Failed" - ;; - esac - return 0; -} - -## -## Usage: -## clog_looking_for %operation% %resource% -## clog_looking_for %operation% "IP Addresses" -## clog_looking_for %operation% "Filesystems" -## -clog_looking_for() -{ - case $1 in - $CLOG_INIT) - ocf_log debug "Looking For $2" - ;; - $CLOG_SUCCEED) - ocf_log debug "Looking For $2 > Succeed - $3 $2 Found" - ;; - $CLOG_FAILED) - ocf_log error "Looking For $2 [$OCF_RESOURCE_INSTANCE] > Failed" - ;; - $CLOG_FAILED_CCS) - ocf_log error "Looking For $2 [$OCF_RESOURCE_INSTANCE] > Failed - Unable To Connect To "ccs"" - ;; - $CLOG_FAILED_NOT_FOUND) - ocf_log error "Looking For $2 [$OCF_RESOURCE_INSTANCE] > Failed - No $2 Found" - ;; - esac - return 0; -} diff --git a/rgmanager/src/resources/utils/named-parse-config.pl b/rgmanager/src/resources/utils/named-parse-config.pl deleted file mode 100644 index 4ac39c3..0000000 --- a/rgmanager/src/resources/utils/named-parse-config.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl -w - -## -## parse named.conf (from stdin) and add options from cluster.conf -## -## ./named-parse-config.pl "directory" "pid-file" "listen-on" -## -use strict; - -if ($#argv < 2) { - die ("Not enough arguments"); -} - -while (my $line = <STDIN>) { - chomp($line); - $line =~ s/(.*?)\s*$/$1/; - if ($line =~ /^\s*options\s+{/) { - print $line, "\n"; - print "\tdirectory "$ARGV[0]";\n"; - print "\tpid-file "$ARGV[1]";\n"; - print "\tlisten-on { $ARGV[2] };\n"; - } else { - print $line, "\n"; - } -} - diff --git a/rgmanager/src/resources/utils/ra-skelet.sh b/rgmanager/src/resources/utils/ra-skelet.sh deleted file mode 100644 index 37cd942..0000000 --- a/rgmanager/src/resources/utils/ra-skelet.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash - -# -# Copyright Red Hat, Inc. 2006 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, -# MA 02139, USA. -# -# -# Author(s): -# Marek Grac (mgrac at redhat.com) -# -status_check_pid() -{ - declare pid_file="$1" - - if [ -z "$pid_file" ]; then - clog_check_file_exist $CLOG_FAILED_INVALID "$pid_file" - return $OCF_ERR_GENERIC - fi - - if [ ! -e "$pid_file" ]; then - clog_check_file_exist $CLOG_FAILED "$pid_file" - return $OCF_ERR_GENERIC - fi - - if [ ! -d /proc/`cat "$pid_file"` ]; then - return $OCF_ERR_GENERIC - fi - - return 0 -} - -stop_generic() -{ - declare pid_file="$1" - declare kill_timeout="$2" - declare pid; - declare count=0; - - if [ ! -e "$pid_file" ]; then - clog_check_file_exist $CLOG_FAILED_NOT_FOUND "$pid_file" - # In stop-after-stop situation there is no PID file but - # it will be nice to check for it in stop-after-start - # look at bug #449394 - return 0 - fi - - if [ -z "$kill_timeout" ]; then - kill_timeout=20 - fi - - read pid < "$pid_file" - - # @todo: PID file empty -> error? - if [ -z "$pid" ]; then - return 0; - fi - - # @todo: PID is not running -> error? - if [ ! -d "/proc/$pid" ]; then - return 0; - fi - - kill -TERM "$pid" - - if [ $? -ne 0 ]; then - return $OCF_ERR_GENERIC - fi - - until [ `ps --pid "$pid" &> /dev/null; echo $?` = '1' ] || [ $count -gt $kill_timeout ] - do - sleep 1 - let count=$count+1 - done - - if [ $count -gt $kill_timeout ]; then - clog_service_stop $CLOG_FAILED_NOT_STOPPED - return $OCF_ERR_GENERIC - fi - - return 0; -} diff --git a/rgmanager/src/resources/utils/tomcat-parse-config.pl b/rgmanager/src/resources/utils/tomcat-parse-config.pl deleted file mode 100755 index 109ecae..0000000 --- a/rgmanager/src/resources/utils/tomcat-parse-config.pl +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl -w - -## -## This script replace IP addresses on which tomcat server -## should listen. Tomcat can't listen on every IP because that -## way we can run only on instance. -## -## Usage: ./tomcat-parse-config.pl ip1 ip2 < /etc/tomcat/server.xml -## where ipXX defines an IP address [eg. 127.0.0.1 134.45.11.1] -## -## -use strict; - -while (my $line = <STDIN>) { - chomp ($line); - - if ($line =~ /(.*?)<Connector (.*)/) { - my $tmp = $2; - my $content = "<Connector "; - my $start = $1; - my $rest = ""; - - while (($tmp =~ />/) == 0) { - $content .= $tmp . "\n"; - $tmp = <STDIN>; - chomp($tmp); - } - - if ($tmp =~ /(.*?)>(.*)/) { - $content .= $1 . ">\n"; - $rest = $2; - chomp($rest); - } - - print $start; - foreach my $arg (@ARGV) { - $content =~ s/\s+address=".*?"/ /; - $content =~ s/Connector /Connector address="$arg" /; - print $content; - } - print $rest; - } else { - print $line,"\n"; - } -} diff --git a/rgmanager/src/utils/Makefile b/rgmanager/src/utils/Makefile deleted file mode 100644 index a8de53c..0000000 --- a/rgmanager/src/utils/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -############################################################################### -## -## Copyright (C) 2004 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -top_srcdir=../.. -UNINSTALL=${top_srcdir}/scripts/uninstall.pl - -include ${top_srcdir}/make/defines.mk -INCLUDE += -I $(top_srcdir)/include - -CFLAGS+= -g -I${incdir} - -CFLAGS+= -g -Wstrict-prototypes -Wshadow -fPIC -D_GNU_SOURCE - -CFLAGS+= -L${libdir} -DPACKAGE_VERSION="${RELEASE}" - -LDFLAGS+= -lmagmamsg -lmagma -lpthread -ldl -lncurses -L../clulib -lclulib -lccs -TARGETS=clubufflush clufindhostname clustat clusvcadm clulog clunfslock - -all: ${TARGETS} - -install: all - install -d ${sbindir} - install $(TARGETS) ${sbindir} - -uninstall: - ${UNINSTALL} $(TARGETS) ${sbindir} - -cluarp: cluarp.o - $(CC) -o $@ $^ $(INLUDE) $(CFLAGS) $(LDFLAGS) - -clulog: clulog.o - $(CC) -o $@ $^ $(INLUDE) $(CFLAGS) $(LDFLAGS) - -clubufflush: clubufflush.o - $(CC) -o $@ $^ $(INLUDE) $(CFLAGS) $(LDFLAGS) - -clufindhostname: clufindhostname.o - $(CC) -o $@ $^ $(INLUDE) $(CFLAGS) $(LDFLAGS) - -clustat: clustat.o - $(CC) -o $@ $^ $(INLUDE) $(CFLAGS) $(LDFLAGS) - -clusvcadm: clusvcadm.o - $(CC) -o $@ $^ $(INLUDE) $(CFLAGS) $(LDFLAGS) - -clunfslock: clunfslock.sh - cp clunfslock.sh clunfslock - chmod 755 clunfslock - -clean: - rm -f *.o $(TARGETS) - -%.o: %.c - $(CC) -c -o $@ $^ $(INCLUDE) $(CFLAGS) diff --git a/rgmanager/src/utils/cluarp.c b/rgmanager/src/utils/cluarp.c deleted file mode 100644 index 9434a39..0000000 --- a/rgmanager/src/utils/cluarp.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Utility to generate a gratuitous ARP request on a given interface. - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/socket.h> -#include <netinet/if_ether.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#define IP_ADDR_LEN 4 -#define DEFAULT_DEVICE "eth0" -#define SA_DATA_LEN 14 /* Taken from include/linux/socket.h */ - -/** - * ARP frame structure. - */ -struct arp_frame { - u_char ether_dest_hw_addr[ETH_ALEN]; - u_char ether_src_hw_addr[ETH_ALEN]; - u_short ether_packet_type; - u_short arp_hw_type; - u_short arp_proto_type; - u_char arp_hlen; - u_char arp_plen; - u_short op; - u_char arp_sender_ha[ETH_ALEN]; - u_char arp_sender_ip[IP_ADDR_LEN]; - u_char arp_target_ha[ETH_ALEN]; - u_char arp_target_ip[IP_ADDR_LEN]; - u_char padding[18]; -}; - - -/** - * Display usage information. - */ -void usage(void) -{ - fprintf(stdout, - "myarp <src_ip> <src_hw> <targ_ip> <targ_hw> [device]\n"); -} - - -/** - * Change a hardware ethernet address into an array of characters. - * Warning: Unchecked bounds in copy_to. - * - * @param addr_string NULL-terminated string in the format: - * "aa:bb:cc:dd:ee:ff" - * @param copy_to Pre-allocated array of at least 6 bytes, - * preferrably set to 0. - */ -void -parse_hw_addr(char *addr_string, u_char *copy_to) -{ - char *c = addr_string, p, result=' '; - int i; - - for (i = 0; i < ETH_ALEN; i++) { - /* first digit */ - if (*c == ':') - c++; - p = tolower(*c++); - if (isdigit(p)) - result = p - '0'; - else if (p >= 'a' && p <= 'z') - result = p - 'a' + 10; - *copy_to = result << 4; - /* second digit */ - if (*c == ':') - c++; - p = tolower(*c++); - if (isdigit(p)) - result = p - '0'; - else if (p >= 'a' && p <= 'z') - result = p - 'a' + 10; - *copy_to++ |= result; - } - return; -} - - -/** - * Change an IP address into an array of characters. - * Warning: Unchecked bounds in copy_to. - * - * @param addr_string NULL-terminated string in the format: - * "10.1.2.3" (standard IPv4 dotted-quad). - * @param copy_to Pre-allocated array of at least 4 bytes, - * preferrably set to 0. - */ -void -parse_ip_addr(char *addr_string, u_char *copy_to) -{ - unsigned long inaddr; - - inaddr = inet_addr(addr_string); - memcpy(copy_to, &inaddr, IP_ADDR_LEN); - -} - - -/** - * Driver for cluarp. - * - * @return 0 on success, 1 on any failure. - */ -int -main(int argc, char **argv) -{ - - int s; - struct arp_frame arp_packet; - struct sockaddr sockaddr; -/* unsigned long inaddr; */ - - if ((argc != 5) && (argc != 6)) { - usage(); - exit(1); - } - - bzero(&arp_packet, sizeof(struct arp_frame)); - - parse_ip_addr(argv[1], arp_packet.arp_sender_ip); - parse_hw_addr(argv[2], arp_packet.ether_src_hw_addr); - parse_hw_addr(argv[2], arp_packet.arp_sender_ha); - parse_ip_addr(argv[3], arp_packet.arp_target_ip); - parse_hw_addr(argv[4], arp_packet.ether_dest_hw_addr); - parse_hw_addr(argv[4], arp_packet.arp_target_ha); - - arp_packet.ether_packet_type = htons(ETH_P_ARP); - arp_packet.arp_hw_type = htons(ETH_P_802_3); - arp_packet.arp_proto_type = htons(ETH_P_IP); - arp_packet.arp_hlen = ETH_ALEN; - arp_packet.arp_plen = IP_ADDR_LEN; - arp_packet.op = htons(ARPOP_REPLY); - - s = socket(AF_PACKET,SOCK_PACKET,htons(ETH_P_RARP)); - - if (argc == 5) - strncpy(sockaddr.sa_data, DEFAULT_DEVICE, SA_DATA_LEN); - else - strncpy(sockaddr.sa_data, argv[5], SA_DATA_LEN); - - if (sendto(s, &arp_packet, sizeof(struct arp_frame), 0, - &sockaddr, sizeof(struct sockaddr)) < 0) { - perror("sendto"); - exit(1); - } - exit(0); -} - - diff --git a/rgmanager/src/utils/clubufflush.c b/rgmanager/src/utils/clubufflush.c deleted file mode 100644 index 0359808..0000000 --- a/rgmanager/src/utils/clubufflush.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Calls ioctl to invalidate/flush buffers on a given device. - * - * Author: Gregory P. Myrdal Myrdal@MissionCriticalLinux.Com - * - * invalidatebuffers.c - */ - -/* - * Version string that is filled in by CVS - */ -static const char *version __attribute__ ((unused)) = "$Revision$"; - -/* - * System includes - */ -#include <unistd.h> -#include <stdio.h> -#include <syslog.h> -#include <linux/fs.h> -#include <string.h> -#include <sys/stat.h> -#include <errno.h> - -#ifdef __NFDBITS -#undef __NFDBITS -#endif - -#ifdef __FDMASK -#undef __FDMASK -#endif - -#include <sys/types.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <stdlib.h> -/* - * Cluster includes - */ -#include <clulog.h> - -/*************************************************************************** - * - * Functions - * - ***************************************************************************/ - -/** - * printUsage - * - * Print out usage string to stdout. - */ -static void -printUsage(char *progName) -{ - clulog_and_print(LOG_ERR, "Usage: %s [-h] [-f device]\n", progName); -} - -/*************************************************************************** - * - * Main - * - ***************************************************************************/ -int -main(int argc, char **argv) -{ - int opt; - uid_t uid; - char *devicename = (char *)NULL; - int fd; - - uid=getuid(); - if (uid) - { - clulog_and_print(LOG_ERR, "%s should only be run as user root\n", - argv[0]); - exit(1); - } - - while ((opt = getopt(argc, argv, "f:h")) != -1) - { - switch (opt) - { - case 'f': // stop services - devicename = strdup(optarg); - break; - - case 'h': // command line help - printUsage(argv[0]); - exit(0); - - default: // unknown option - printUsage(argv[0]); - exit(0); - } - } - - if (devicename == (char *)NULL) - { - printUsage(argv[0]); - exit(1); - } - - fd = open(devicename, O_RDONLY, 0); - - if (fd < 0) - { - clulog_and_print(LOG_ERR, "Cannot open %s for flushing: %s\n", - devicename, strerror(errno)); - exit(1); - } - - if (ioctl(fd, BLKFLSBUF, 0) < 0) - { - clulog_and_print(LOG_ERR, "Cannot flush %s: %s\n", - devicename, strerror(errno)); - exit(1); - } - free(devicename); - close(fd); - - exit(0); -} diff --git a/rgmanager/src/utils/clufindhostname.c b/rgmanager/src/utils/clufindhostname.c deleted file mode 100644 index 490acce..0000000 --- a/rgmanager/src/utils/clufindhostname.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Utility/command to return name found by gethostbyname and gethostbyaddr. - * - * Author: Richard Rabbat rabbat@missioncriticallinux.com - */ -#include <netdb.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <arpa/inet.h> - -void usage(char* progname) -{ - fprintf (stderr, "Usage: %s [-i ip_addr] [-n ip_name]\n", progname); -} - -int main (int argc, char** argv) -{ - struct hostent* hp; - unsigned long int address; - int opt; - - if (argc != 3) - { - usage(argv[0]); - exit(1); - } - - while ((opt = getopt(argc, argv, "i:n:")) != EOF) { - switch (opt) { - case 'i': - address = inet_addr (optarg); - - if ( !( hp = gethostbyaddr ((char*)&address, 4, AF_INET ))) - { - exit (2); - } - else - { - fprintf (stdout, "%s\n", hp->h_name); - exit (0); - } - break; - case 'n': - if ( !( hp = gethostbyname (argv[2]))) - { - exit (2); - } - else - { - fprintf (stdout, "%s\n", hp->h_name); - exit (0); - } - break; - default: - break; - } - } - exit (0); -} - - diff --git a/rgmanager/src/utils/clulog.c b/rgmanager/src/utils/clulog.c deleted file mode 100644 index 324210c..0000000 --- a/rgmanager/src/utils/clulog.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - Copyright Mission Critical Linux, 2000 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * Utility for logging arbitrary strings to the cluster log file via syslog. - * - * Author: Jeff Moyer <jmoyer at redhat.com> - */ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <getopt.h> -#include <string.h> -#include <sys/syslog.h> -#include <clulog.h> -#include <ccs.h> - -int configure_logging(int); - -#define MAX_TOKENLEN 64 - -void -usage(char *progname) -{ - fprintf(stdout, "%s -s severity [-f facility] [-l priority_filter] [-n program name] \n" - "\t\t [-p pid] "message text"\n", progname); - exit(0); -} - - -/* - * Configure logging based on data in cluster.conf - */ -int -configure_logging(int ccsfd) -{ - char *v; - char internal = 0; - - if (ccsfd < 0) { - internal = 1; - ccsfd = ccs_connect(); - if (ccsfd < 0) - return -1; - } - - if (ccs_get(ccsfd, "/cluster/rm/@log_facility", &v) == 0) { - clu_set_facility(v); - free(v); - } - - if (ccs_get(ccsfd, "/cluster/rm/@log_level", &v) == 0) { - clu_set_loglevel(atoi(v)); - free(v); - } - - if (internal) - ccs_disconnect(ccsfd); - - return 0; -} - - -int -main(int argc, char **argv) -{ - int opt; - int severity = 7, - cmdline_loglevel = 0;/* set if we should not use the config file val*/ - char *logmsg, *msg_ptr = argv[argc-1]; - int pid = 0; - char *progname = NULL; - int result; - size_t len; - - if (argc < 4) - usage(argv[0]); - - --argc; /* don't parse last value in getopt */ - - while ((opt = getopt(argc, argv, "f:l:s:hp:n:")) != -1) { - switch (opt) { - case 'l': - clu_set_loglevel(atoi(optarg)); - cmdline_loglevel = 1; - case 'f': - clu_set_facility(optarg); - break; - case 's': - severity = atoi(optarg); - break; - case 'p': - pid = atoi(optarg); - break; - case 'n': - progname = strdup(optarg); - break; - case 'h': - usage(argv[0]); - default: - usage(argv[0]); - } - } - - /* Add two bytes for linefeed and NULL terminator */ - len = strlen(msg_ptr) + 2; - logmsg = (char*)malloc(len); - if (logmsg == NULL) { - fprintf(stderr, - "clulog: malloc fail err=%d\n", errno); - exit(0); - } - - snprintf(logmsg, len, "%s\n", msg_ptr); - - if (!cmdline_loglevel) { - /* - * Let's see what loglevel the SM is running at. - * If ccsd's not available, use default. - */ - if (configure_logging(-1) < 0) - clu_set_loglevel(LOGLEVEL_DFLT); - } - result = clulog_pid(severity, pid, progname, logmsg); - free(progname); - return(result); -} diff --git a/rgmanager/src/utils/clunfslock.sh b/rgmanager/src/utils/clunfslock.sh deleted file mode 100644 index 9b6d6da..0000000 --- a/rgmanager/src/utils/clunfslock.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# -# (C) 2006 Red Hat, Inc. -# -# Licensed under the GNU General Public License, Version 2. -# -# rpc.statd -H $0 to enable. This provides the HA-callout capability -# for RHCS-managed NFS services. Note that you must edit -# /etc/sysconfig/nfs in order to make this work; clumanager/rgmanager -# will not interfere with a running nfs statd. -# -# Arg 3 (server as known to client) does not work; it's always 127.0.0.1 -# so we traverse all cluster mount points. -# - -clustered_mounts() -{ - declare dev mp - - while read dev mp; do - if [ "${dev:0:4}" != "/dev" ]; then - continue - fi - - # XXX Need clumanager to create this on mount - if [ -d "$mp/.clumanager" ]; then - echo $dev $mp - fi - done < <(cat /proc/mounts | awk '{print $1,$2}') -} - - -add-client() -{ - declare dev mp - - while read dev mp; do - [ -d "$mp/.clumanager/statd/sm" ] || \ - mkdir -p $mp/.clumanager/statd/sm - touch $mp/.clumanager/statd/sm/$1 - done < <(clustered_mounts) -} - - -del-client() -{ - while read $dev $mp; do - [ -d "$mp/.clumanager/statd/sm" ] || \ - mkdir -p $mp/.clumanager/statd/sm - rm -f $mp/.clumanager/statd/sm/$1 - done < <(clustered_mounts) -} - -case "$1" in - add-client) - : - ;; - del-client) - : - ;; - *) - echo "Usage: $0 <add-client|del-client> <host> [server]" - exit 0 -esac - - -if [ -z "$2" ]; then - echo "Usage: $0 <add-client|del-client> <host> [server]" - exit 1 -fi - -$1 $2 $3 -exit 0 diff --git a/rgmanager/src/utils/clunfsops.c b/rgmanager/src/utils/clunfsops.c deleted file mode 100644 index ad92ccf..0000000 --- a/rgmanager/src/utils/clunfsops.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * This program simply parses command line args and then calls the - * corresponding system call. - * These operations are for NFS failover semantics in an attempt to - * shield clients from unnecessary stale file handle errors. - * - * File Origin - this command was reverse-engineered by starting with the - * GPL syscall interfaces defined in <linux/nfsd/syscall.h>. - */ - -#ifdef X86_64 -#define __ASM_SYSTEM_H -#define __ASM_X86_64_PROCESSOR_H -#endif - - -#define _LVM_H_INCLUDE /* XXX */ -#include <linux/list.h> -#include <linux/kdev_t.h> -#undef _LVM_H_INCLUDE -#include <linux/socket.h> -#include <linux/types.h> - -#ifdef S390 -#define __ssize_t_defined -#endif - -#include <linux/unistd.h> -/* - * lhh - someone thought it would be cute to remove the #ifdef __KERNEL__ - * around some of the system includes. Now we have to fudge the #inclusion - * of linux/types.h _AS_ sys/types.h just to compile. - */ -#define _SYS_TYPES_H -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/errno.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/param.h> -#include <signal.h> -#include <syslog.h> - -/* XXX - should be this file, -#include <linux/nfsd/syscall.h> - */ -/* - * But, temporarily include this file to simplify the build on - * systems which aren't yet installed and therefore don't have the - * header file w/ updated defines for new nfs syscalls. - */ -#include "syscall.h" - -/* - * Cluster include - */ -#include <clulog.h> - - -/* Forward routine declarations. */ -static void usage(const char * cmd); -int validateDevice(char *name); -int nfsctl(int cmd, struct nfsctl_arg * argp, void * resp); - -/* Program Globals */ -static int verbose = 0; -static char *cmdname; - -static void -usage(const char * cmd) -{ - fprintf(stderr, "\n"); - fprintf(stderr, "usage: %s [-ehsv] " - "[-d deviceName] " - "\n", cmd); - fprintf(stderr, "Options:\n"); - fprintf(stderr, "-e\t\tInitiate flush of pending requests.\n"); - fprintf(stderr, "-h\t\tPrints this help message.\n"); - fprintf(stderr, "-s\t\tCancel pending flush of pending requests.\n"); - fprintf(stderr, "-v\t\tIncreases verbose debugging level.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "NOTE: this command will only successfully run\n"); - fprintf(stderr, " if the correspoinding NFS kernel patches\n"); - fprintf(stderr, " are built into the kernel.\n"); - fprintf(stderr, "\n"); - exit(1); -} - -int -main(int argc, char** argv) -{ - extern char * optarg; - extern int optind, opterr, optopt; - int errors = 0; - int errno_save = 0; - int nfsSyscallNum = 0; - char *nfsSyscallString = "BOGUS"; - char *deviceName = NULL; - int c; - struct nfsctl_arg nfsctlarg; - int retval; - - if (geteuid() != (uid_t)0) { - clulog_and_print(LOG_ERR, "%s must be run as the root user.\n", - argv[0]); - exit(1); - } - if ((cmdname = strrchr(argv[0], '/')) == NULL) { - cmdname = argv[0]; - } - else{ - ++cmdname; - } - - while ((c = getopt(argc, argv, "d:ehsv")) != -1) { - switch(c) { - case 'd': deviceName = optarg; - break; - case 'e': - nfsSyscallNum = NFSCTL_FODROP; - nfsSyscallString = "NFSCTL_FODROP"; - break; - case 'h': usage(cmdname); - break; - case 's': - nfsSyscallNum = NFSCTL_STOPFODROP; - nfsSyscallString = "NFSCTL_STOPFODROP"; - break; - case 'v': ++verbose; - break; - default: ++errors; - break; - } - } - if (nfsSyscallNum == 0) { - clulog_and_print(LOG_ERR, "%s: No NFS syscall has been " - "specified.\n",cmdname); - ++errors; - } - if (deviceName == NULL) { - clulog_and_print(LOG_ERR, "%s: No device name has been " - "specified.\n", cmdname); - ++errors; - } - if (validateDevice(deviceName)) { - ++errors; - } - if (errors) { - usage(cmdname); - } - if (verbose) { - printf("Calling: nfsSyscall = %s, deviceName = %s.\n", - nfsSyscallString, deviceName); - } - /* - * Setup the data structure expected by the kernel. - */ - memset(&nfsctlarg, 0, sizeof(struct nfsctl_arg)); - nfsctlarg.ca_version = NFSCTL_VERSION; - strncpy(nfsctlarg.ca_fodrop.fo_dev, deviceName, - sizeof(nfsctlarg.ca_fodrop.fo_dev)); - nfsctlarg.ca_fodrop.fo_timeout = 1000; /* range 600-1200 */ - /* - * Jump into the kernel syscall. - */ - retval = nfsctl(nfsSyscallNum, &nfsctlarg, NULL); - if (retval != 0) { - /* clulog_and_print calls syslog(), which modifies errno */ - errno_save = errno; - clulog_and_print(LOG_WARNING, "#72: %s: NFS syscall %s failed: " - "%s.\n", cmdname, nfsSyscallString, - strerror(errno_save)); - if (errno_save == EINVAL) { - clulog_and_print(LOG_WARNING, - "#73: %s: Kernel may not " - "have NFS failover enhancements.\n", - cmdname); - } - exit(errno_save); - } - else { - if (verbose) { - printf("SUCCESS: nfsSyscall = %s, deviceName = %s.\n", - nfsSyscallString, deviceName); - } - } - exit(0); -} - -/* - * Validate the device parameter. Make sure it refers to a block - * device special file. - * Returns: 0=success, nonzero=error. - */ -int -validateDevice(char *name) { - struct stat stat_st, *stat_ptr; - stat_ptr = &stat_st; - - if (stat(name, stat_ptr) < 0) { - clulog_and_print(LOG_ERR, "%s: Unable to stat %s.\n", cmdname, name); - return(1); - } - /* - * Verify that its a block or character special file. - */ - if (S_ISBLK(stat_st.st_mode) == 0) { - clulog_and_print(LOG_ERR, "%s: %s is not a block special file.\n", cmdname, name); - return(1); - } - return(0); // success -} - -/* - * Routine to format make appropriate NFS syscall. - * Leveraged from nfs-utils. - */ -int -nfsctl(int cmd, struct nfsctl_arg * argp, void * resp) -{ - return syscall (__NR_nfsservctl, cmd, argp, resp); -} - diff --git a/rgmanager/src/utils/clushutdown b/rgmanager/src/utils/clushutdown deleted file mode 100755 index ef3eb72..0000000 --- a/rgmanager/src/utils/clushutdown +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -# -# Stop all services and prepare the cluster for a TCO. -# -. /etc/init.d/functions - -action $"Ensuring this member is in the Quorum:" clustat -Q -if [ $? -ne 0 ]; then - exit 1 -fi - -echo -echo "WARNING: About to stop ALL services managed by Red Hat Cluster Manager." -echo " This should only be done when maintainence is required on " -echo " enough members to dissolve the Cluster Quorum. This utility" -echo " generally does not need to be run when one cluster member" -echo " requires maintenance. This NEVER needs to be run in two" -echo " member clusters." -echo -echo -n "Continue [yes/NO]? " -read a -if [ "$a" != "YES" -a "$a" != "yes" ]; then - echo - echo Aborted. - exit 0 -fi - -action $"Preparing for global service shutdown:" clusvcadm -u -if [ $? -ne 0 ]; then - exit 1; -fi - -errors=0 -for s in `cludb -m services%service[0-9]+%name | cut -f2 -d=`; do - action "Stopping service $s: " clusvcadm -q -s $s - if [ $? -ne 0 ]; then - exit 1 - fi -done - -echo "All clustered services are stopped." - -action $"Locking service managers:" clusvcadm -l -if [ $? -ne 0 ]; then - exit 1 -fi - -echo -echo $"It is now safe to shut down all cluster members. Be advised that" -echo $"members not controlled by power switches may still reboot when " -echo $"when the cluster quorum is disbanded." -echo -exit 0 diff --git a/rgmanager/src/utils/clustat.c b/rgmanager/src/utils/clustat.c deleted file mode 100644 index 588958b..0000000 --- a/rgmanager/src/utils/clustat.c +++ /dev/null @@ -1,827 +0,0 @@ -#include <magma.h> -#include <magmamsg.h> -#include <msgsimple.h> -#include <resgroup.h> -#include <platform.h> -#include <libgen.h> -#include <ncurses.h> -#include <term.h> -#include <termios.h> -#include <ccs.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define FLAG_UP 0x1 -#define FLAG_LOCAL 0x2 -#define FLAG_RGMGR 0x4 -#define FLAG_NOCFG 0x8 /* Shouldn't happen */ - -#define RG_VERBOSE 0x1 - -#define QSTAT_ONLY 1 -#define VERSION_ONLY 2 -#define NODEID_ONLY 3 - - -int running = 1; - -void -term_handler(int sig) -{ - running = 0; -} - - -typedef struct { - int rgl_count; - rg_state_t rgl_states[0]; -} rg_state_list_t; - - -rg_state_list_t * -rg_state_list(uint64_t local_node_id, int fast) -{ - int fd, n, x; - rg_state_list_t *rsl = NULL; - generic_msg_hdr *msgp = NULL; - rg_state_msg_t *rsmp = NULL; - fd_set rfds; - struct timeval tv; - - fd = msg_open(local_node_id, RG_PORT, RG_PURPOSE, 10); - if (fd == -1) { - perror("msg_open"); - return NULL; - } - - msg_send_simple(fd, RG_STATUS, fast, 0); - - rsl = malloc(sizeof(rg_state_list_t)); - if (!rsl) { - printf("Try again, out of memory\n"); - exit(0); - } - memset(rsl, 0, sizeof(rg_state_list_t)); - - while (1) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = 10; - tv.tv_usec = 0; - - n = select(fd+1, &rfds, NULL, NULL, &tv); - if (n == 0) { - fprintf(stderr, "Timed out waiting for a response " - "from Resource Group Manager\n"); - break; - } - - if (n < 0) { - if (errno == EAGAIN || - errno == EINTR) - continue; - fprintf(stderr, "Failed to receive " - "service data: select: %s\n", - strerror(errno)); - break; - } - - n = msg_receive_simple(fd, &msgp, tv.tv_sec); - if (n < 0) { - if (errno == EAGAIN) - continue; - perror("msg_receive_simple"); - break; - } - if (n < sizeof(generic_msg_hdr)) { - printf("Error: Malformed message\n"); - break; - } - - if (!msgp) { - printf("Error: no message?!\n"); - break; - } - - swab_generic_msg_hdr(msgp); - if (msgp->gh_command == RG_SUCCESS) { - free(msgp); - break; - } - - if (n < sizeof(*rsmp)) { - msg_close(fd); - return NULL; - } - - - rsmp = (rg_state_msg_t *)msgp; - - swab_rg_state_t(&rsmp->rsm_state); - - rsl->rgl_count++; - x = sizeof(rg_state_list_t) + - (sizeof(rg_state_t) * rsl->rgl_count); - rsl = realloc(rsl, x); - if (!rsl) { - printf("Try again; out of RAM\n"); - exit(1); - } - - memcpy(&rsl->rgl_states[(rsl->rgl_count-1)], - &rsmp->rsm_state, sizeof(rg_state_t)); - - free(msgp); - msgp = NULL; - } - - msg_send_simple(fd, RG_SUCCESS, 0, 0); - msg_close(fd); - - if (!rsl->rgl_count) { - free(rsl); - return NULL; - } - - return rsl; -} - - -cluster_member_list_t *ccs_member_list(void) -{ - int desc; - int x; - char buf[128]; - char *name; - cluster_member_list_t *ret = NULL; - - desc = ccs_connect(); - if (desc < 0) { - return NULL; - } - - x = 1; - - snprintf(buf, sizeof(buf), - "/cluster/clusternodes/clusternode[%d]/@name", x); - while (ccs_get(desc, buf, &name) == 0) { - if (!ret) { - ret = malloc(cml_size(x)); - if (!ret) { - perror("malloc"); - ccs_disconnect(desc); - exit(1); - } - memset(ret, 0, cml_size(x)); - } else { - ret = realloc(ret, cml_size(x)); - if (!ret) { - perror("realloc"); - ccs_disconnect(desc); - exit(1); - } - } - - memset(&ret->cml_members[x-1], 0, sizeof(cluster_member_t)); - strncpy(ret->cml_members[x-1].cm_name, name, - sizeof(ret->cml_members[x-1].cm_name)); - free(name); - - ret->cml_count = x; - ++x; - snprintf(buf, sizeof(buf), - "/cluster/clusternodes/clusternode[%d]/@name", x); - } - - ccs_disconnect(desc); - return ret; -} - - -void -flag_nodes(cluster_member_list_t *all, cluster_member_list_t *these, - uint8_t flag) -{ - int x; - cluster_member_t *m; - - for (x=0; x<all->cml_count; x++) { - - m = memb_name_to_p(these, all->cml_members[x].cm_name); - - if (m) { - all->cml_members[x].cm_id = m->cm_id; - all->cml_members[x].cm_state |= flag; - } - } -} - - -cluster_member_list_t * -add_missing(cluster_member_list_t *all, cluster_member_list_t *these) -{ - int x, y; - cluster_member_t *m, *new; - - for (x=0; x<these->cml_count; x++) { - - m = NULL; - for (y = 0; y < all->cml_count; y++) { - if (!strcmp(all->cml_members[y].cm_name, - these->cml_members[x].cm_name)) - m = &all->cml_members[y]; - } - - if (!m) { - all = realloc(all, cml_size((all->cml_count+1))); - if (!all) { - perror("realloc"); - exit(1); - } - - new = &all->cml_members[all->cml_count]; - - memcpy(new, &these->cml_members[x], - sizeof(cluster_member_t)); - - if (new->cm_state == STATE_UP) { - new->cm_state = FLAG_UP | FLAG_NOCFG; - } else { - new->cm_state = FLAG_NOCFG; - } - ++all->cml_count; - - } - } - - return all; -} - - -char * -my_memb_id_to_name(cluster_member_list_t *members, uint64_t memb_id) -{ - int x; - - if (memb_id == NODE_ID_NONE) - return "none"; - - for (x = 0; x < members->cml_count; x++) { - if (members->cml_members[x].cm_id == memb_id) - return members->cml_members[x].cm_name; - } - - return "unknown"; -} - - -void -_txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags) -{ - char owner[31]; - - - if (rs->rs_state == RG_STATE_STOPPED || - rs->rs_state == RG_STATE_DISABLED || - rs->rs_state == RG_STATE_ERROR || - rs->rs_state == RG_STATE_FAILED) { - - snprintf(owner, sizeof(owner), "(%-.28s)", - my_memb_id_to_name(members, rs->rs_last_owner)); - } else { - - snprintf(owner, sizeof(owner), "%-.30s", - my_memb_id_to_name(members, rs->rs_owner)); - } - printf(" %-20.20s %-30.30s %-16.16s\n", - rs->rs_name, - owner, - rg_state_str(rs->rs_state)); -} - - -void -_txt_rg_state_v(rg_state_t *rs, cluster_member_list_t *members, int flags) -{ - printf("Service Name : %s\n", rs->rs_name); - printf(" Current State : %s (%d)\n", - rg_state_str(rs->rs_state), rs->rs_state); - printf(" Owner : %s\n", - my_memb_id_to_name(members, rs->rs_owner)); - printf(" Last Owner : %s\n", - my_memb_id_to_name(members, rs->rs_last_owner)); - printf(" Last Transition : %s\n", - ctime((time_t *)(&rs->rs_transition))); -} - - -void -txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags) -{ - if (flags & RG_VERBOSE) - _txt_rg_state_v(rs, members, flags); - else - _txt_rg_state(rs, members, flags); -} - - -void -xml_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags) -{ - char time_str[32]; - int x; - - /* Chop off newlines */ - ctime_r((time_t *)&rs->rs_transition, time_str); - for (x = 0; time_str[x]; x++) { - if (time_str[x] < 32) { - time_str[x] = 0; - break; - } - } - - printf(" <group name="%s" state="%d" state_str="%s" " - " owner="%s" last_owner="%s" restarts="%d"" - " last_transition="%llu" last_transition_str="%s"/>\n", - rs->rs_name, - rs->rs_state, - rg_state_str(rs->rs_state), - my_memb_id_to_name(members, rs->rs_owner), - my_memb_id_to_name(members, rs->rs_last_owner), - rs->rs_restarts, - (long long unsigned)rs->rs_transition, - time_str); -} - - -int -txt_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members, - char *svcname, int flags) -{ - int x, ret = 0; - - if (!rgl || !members) - return -1; - - if (!(flags & RG_VERBOSE)) { - printf(" %-20.20s %-30.30s %-14.14s\n", - "Service Name", "Owner (Last)", "State"); - printf(" %-20.20s %-30.30s %-14.14s\n", - "------- ----", "----- ------", "-----"); - } else { - printf("Service Information\n" - "------- -----------\n\n"); - } - - for (x = 0; x < rgl->rgl_count; x++) { - if (svcname && - strcmp(rgl->rgl_states[x].rs_name, svcname)) - continue; - txt_rg_state(&rgl->rgl_states[x], members, flags); - if (svcname) { - switch (rgl->rgl_states[x].rs_state) { - case RG_STATE_STARTING: - case RG_STATE_STARTED: - case RG_STATE_STOPPING: - break; - default: - ret = rgl->rgl_states[x].rs_state; - } - } - } - - return ret; -} - - -int -xml_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members, - char *svcname, int flags) -{ - int x; - int ret = 0; - - if (!rgl || !members) - return -1; - - printf(" <groups>\n"); - - for (x = 0; x < rgl->rgl_count; x++) { - if (svcname && - strcmp(rgl->rgl_states[x].rs_name, svcname)) - continue; - xml_rg_state(&rgl->rgl_states[x], members, flags); - if (svcname) { - switch (rgl->rgl_states[x].rs_state) { - case RG_STATE_STARTING: - case RG_STATE_STARTED: - case RG_STATE_STOPPING: - break; - default: - ret = rgl->rgl_states[x].rs_state; - } - } - } - - printf(" </groups>\n"); - return ret; -} - - -void -txt_quorum_state(int qs) -{ - printf("Member Status: "); - - if (qs & QF_QUORATE) - printf("Quorate\n\n"); - else { - printf("Inquorate\n\n"); - } -} - - -void -xml_quorum_state(int qs) -{ - printf(" <quorum "); - - if (qs & QF_QUORATE) - printf("quorate="1""); - else { - printf("quorate="0" groupmember="0"/>\n"); - return; - } - - if (qs & QF_GROUPMEMBER) - printf(" groupmember="1""); - - printf("/>\n"); -} - - -void -txt_member_state(cluster_member_t *node) -{ - printf(" %-40.40s ", node->cm_name); - - if (node->cm_state & FLAG_UP) - printf("Online"); - else - printf("Offline"); - - if (node->cm_state & FLAG_LOCAL) - printf(", Local"); - - if (node->cm_state & FLAG_NOCFG) - printf(", Estranged"); - - if (node->cm_state & FLAG_RGMGR) - printf(", rgmanager"); - - printf("\n"); - - -} - - -void -xml_member_state(cluster_member_t *node) -{ - printf(" <node name="%s" state="%d" local="%d" " - "estranged="%d" rgmanager="%d" nodeid="0x%08x%08x"/>\n", - node->cm_name, - !!(node->cm_state & FLAG_UP), - !!(node->cm_state & FLAG_LOCAL), - !!(node->cm_state & FLAG_NOCFG), - !!(node->cm_state & FLAG_RGMGR), - (uint32_t)((node->cm_id >> 32)&0xffffffff), - (uint32_t)((node->cm_id )&0xffffffff)); -} - - -int -txt_member_states(cluster_member_list_t *membership, char *name) -{ - int x, ret = 0; - - if (!membership) { - printf("Membership information not available\n"); - return -1; - } - - printf(" %-40.40s %s\n", "Member Name", "Status"); - printf(" %-40.40s %s\n", "------ ----", "------"); - - for (x = 0; x < membership->cml_count; x++) { - if (name && strcmp(membership->cml_members[x].cm_name, name)) - continue; - txt_member_state(&membership->cml_members[x]); - ret = !(membership->cml_members[x].cm_state & FLAG_UP); - } - - printf("\n"); - return ret; -} - - -int -xml_member_states(cluster_member_list_t *membership, char *name) -{ - int x, ret = 0; - - if (!membership) { - printf(" <nodes/>\n"); - return -1; - } - - printf(" <nodes>\n"); - for (x = 0; x < membership->cml_count; x++) { - if (name && strcmp(membership->cml_members[x].cm_name, name)) - continue; - xml_member_state(&membership->cml_members[x]); - if (name) - ret = !(membership->cml_members[x].cm_state & FLAG_UP); - } - printf(" </nodes>\n"); - - return ret; -} - - -int -txt_cluster_status(int qs, cluster_member_list_t *membership, - rg_state_list_t *rgs, char *name, char *svcname, - int flags) -{ - int ret; - - if (!svcname && !name) { - txt_quorum_state(qs); - if (!membership || !(qs & QF_GROUPMEMBER)) { - printf("Resource Group Manager not running; " - "no service information available.\n\n"); - } - } - - if (!svcname || (name && svcname)) - ret = txt_member_states(membership, name); - if (name && !svcname) - return ret; - if (!name || (name && svcname)) - ret = txt_rg_states(rgs, membership, svcname, flags); - return ret; -} - - -int -xml_cluster_status(int qs, cluster_member_list_t *membership, - rg_state_list_t *rgs, char *name, char *svcname, - int flags) -{ - int ret1 = 0, ret2 = -1; - - printf("<?xml version=\"1.0\"?>\n"); - printf("<clustat version="4.1.1">\n"); - - if (!svcname && !name) - xml_quorum_state(qs); - if (!svcname || (name && svcname)) - ret1 = xml_member_states(membership, name); - - if (rgs && - (!name || (name && svcname))) - ret2 = xml_rg_states(rgs, membership, svcname, flags); - printf("</clustat>\n"); - - if (name && ret1) - return ret1; - if (svcname && ret2) - return ret2; - return 0; -} - - -cluster_member_list_t * -build_member_list(uint64_t *lid) -{ - cluster_member_list_t *all, *part; - cluster_member_t *m; - int root = 0; - int x; - - /* Get all members from ccs, and all members reported by the cluster - infrastructure */ - root = (getuid() == 0 || geteuid() == 0); - - part = clu_member_list(NULL); - msg_update(part); /* XXX magmamsg is awful. */ - - if (root && (all = ccs_member_list())) { - - /* See if our config has anyone missed. If so, flag - them as missing from the config file */ - all = add_missing(all, part); - - /* Flag online nodes */ - flag_nodes(all, part, FLAG_UP); - - cml_free(part); - } else { - /* not root - keep it simple for the next block */ - all = part; - } - - /* Grab the local node ID and flag it from the list of reported - online nodes */ - clu_local_nodeid(NULL, lid); - msg_set_nodeid(*lid); - - if (!all) - return NULL; - - for (x=0; x<all->cml_count; x++) { - if (all->cml_members[x].cm_id == *lid) { - m = &all->cml_members[x]; - m->cm_state |= FLAG_LOCAL; - break; - } - } - - /* Flag rgmanager nodes, if any */ - part = clu_member_list(RG_SERVICE_GROUP); - flag_nodes(all, part, FLAG_RGMGR); - cml_free(part); - - return all; -} - - -void -usage(char *arg0) -{ - printf( -"usage: %s <options>\n" -" -i <interval> Refresh every <interval> seconds. May not be used\n" -" with -x.\n" -" -I Display local node ID and exit\n" -" -m <member> Display status of <member> and exit\n" -" -s <service> Display status of <service> and exit\n" -" -v Display version & cluster plugin and exit\n" -" -x Dump information as XML\n" -" -Q Return 0 if quorate, 1 if not (no output)\n" -" -f Enable fast clustat reports\n" -" -l Use long format for services\n" -"\n", basename(arg0)); -} - - -int -main(int argc, char **argv) -{ - int fd, qs, ret = 0; - cluster_member_list_t *membership; - rg_state_list_t *rgs = NULL; - uint64_t local_node_id; - int fast = 0; - int runtype = 0; - - int refresh_sec = 0, errors = 0; - int opt, xml = 0, flags = 0; - char *member_name = NULL; - char *rg_name = NULL; - - while ((opt = getopt(argc, argv, "fIls:m:i:xvQh?")) != EOF) { - switch(opt) { - case 'v': - runtype = VERSION_ONLY; - break; - - case 'I': - runtype = NODEID_ONLY; - break; - - case 'i': - refresh_sec = atoi(optarg); - if (refresh_sec <= 0) - refresh_sec = 1; - break; - case 'l': - flags |= RG_VERBOSE; - break; - - case 'm': - member_name = optarg; - break; - - case 'Q': - /* Return to shell: 0 true, 1 false... */ - runtype = QSTAT_ONLY; - break; - - case 's': - rg_name = optarg; - break; - - case 'x': - if (refresh_sec) { - printf("Error: Options '-i' and '-x' are " - "mutually exclusive\n"); - ret = 1; - goto cleanup; - } - - xml = 1; - break; - case 'f': - ++fast; - break; - case '?': - case 'h': - usage(argv[0]); - return 0; - break; - default: - errors++; - break; - } - } - - if (errors) { - usage(argv[0]); - return 1; - } - - /* Connect & grab all our info */ - fd = clu_connect(RG_SERVICE_GROUP, 0); - - switch(runtype) { - case QSTAT_ONLY: - if (fd < 0) - break; - ret = !(clu_quorum_status(RG_SERVICE_GROUP) & - QF_QUORATE); - goto cleanup; - case VERSION_ONLY: - printf("%s version %s\n", basename(argv[0]), - PACKAGE_VERSION); - if (fd < 0) - break; - printf("Connected via: %s\n", clu_plugin_version()); - goto cleanup; - case NODEID_ONLY: - if (fd < 0) - break; - clu_local_nodeid(NULL, &local_node_id); - printf("0x%08x%08x\n",(uint32_t)(local_node_id>>32), - (uint32_t)(local_node_id&0xffffffff)); - goto cleanup; - } - - if (fd < 0) { - printf("Could not connect to cluster service\n"); - return 1; - } - - /* XXX add member/rg single-shot state */ - signal(SIGINT, term_handler); - signal(SIGTERM, term_handler); - - while (1) { - qs = clu_quorum_status(RG_SERVICE_GROUP); - membership = build_member_list(&local_node_id); - - if (!member_name) - rgs = rg_state_list(local_node_id, fast); - - if (refresh_sec) { - setupterm((char *) 0, STDOUT_FILENO, (int *) 0); - tputs(clear_screen, lines > 0 ? lines : 1, putchar); - } - - if (xml) - ret = xml_cluster_status(qs, membership, rgs, - member_name, rg_name, - flags); - else - ret = txt_cluster_status(qs, membership, rgs, - member_name, rg_name, - flags); - - if (membership) - cml_free(membership); - if (rgs) - free(rgs); - - if (!refresh_sec || !running) - break; - - sleep(refresh_sec); - } - -cleanup: - clu_disconnect(fd); - return ret; -} diff --git a/rgmanager/src/utils/clusvcadm.c b/rgmanager/src/utils/clusvcadm.c deleted file mode 100644 index 2e227d4..0000000 --- a/rgmanager/src/utils/clusvcadm.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - Copyright Red Hat, Inc. 2002-2003 - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - MA 02139, USA. -*/ -/** @file - * The New And Improved Cluster Service Admin Utility. - * TODO Clean up the code. - */ -#include <stdio.h> -#include <stdlib.h> -#include <sys/param.h> -#include <libgen.h> -#include <resgroup.h> -#include <platform.h> -#include <magma.h> -#include <magmamsg.h> -#include <resgroup.h> -#include <msgsimple.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -void -build_message(SmMessageSt *msgp, int action, char *svcName, uint64_t target, - uint32_t arg1, uint32_t arg2) -{ - msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC; - msgp->sm_hdr.gh_command = RG_ACTION_REQUEST; - msgp->sm_hdr.gh_length = sizeof(*msgp); - msgp->sm_hdr.gh_arg1 = arg1; - msgp->sm_hdr.gh_arg2 = arg2; - msgp->sm_data.d_action = action; - strncpy(msgp->sm_data.d_svcName, svcName, - sizeof(msgp->sm_data.d_svcName)); - msgp->sm_data.d_svcOwner = target; - msgp->sm_data.d_ret = 0; - - swab_SmMessageSt(msgp); -} - - -int -do_lock_req(int req) -{ - int cfd = -1; - int fd = -1; - int ret = RG_FAIL; - cluster_member_list_t *membership = NULL; - uint64_t me; - generic_msg_hdr hdr; - - fd = clu_connect(RG_SERVICE_GROUP, 0); - if (fd < 0) { - printf("Could not connect to cluster service\n"); - goto out; - } - - membership = clu_member_list(RG_SERVICE_GROUP); - msg_update(membership); - clu_local_nodeid(RG_SERVICE_GROUP, &me); - - fd = msg_open(me, RG_PORT, 0, 5); - if (fd < 0) { - printf("Could not connect to resource group manager\n"); - goto out; - } - - if (msg_send_simple(fd, req, 0, 0) < 0) { - printf("Communication failed\n"); - goto out; - } - - if (msg_receive_timeout(fd, &hdr, sizeof(hdr), 5) < sizeof(hdr)) { - printf("Receive failed\n"); - goto out; - } - - swab_generic_msg_hdr(&hdr); - ret = hdr.gh_command; - -out: - if (membership) - cml_free(membership); - - if (fd >= 0) - msg_close(fd); - - if (cfd >= 0) - clu_disconnect(cfd); - - return ret; -} - - -int -do_lock(void) -{ - if (do_lock_req(RG_LOCK) != RG_SUCCESS) { - printf("Lock operation failed\n"); - return 1; - } - printf("Resource groups locked\n"); - return 0; -} - - -int -do_unlock(void) -{ - if (do_lock_req(RG_UNLOCK) != RG_SUCCESS) { - printf("Unlock operation failed\n"); - return 1; - } - printf("Resource groups unlocked\n"); - return 0; -} - - -int -do_query_lock(void) -{ - switch(do_lock_req(RG_QUERY_LOCK)) { - case RG_LOCK: - printf("Resource groups locked\n"); - break; - case RG_UNLOCK: - printf("Resource groups unlocked\n"); - break; - default: - printf("Query operation failed\n"); - return 1; - } - return 0; -} - - -int -do_msg_receive(uint64_t msgtarget, int fd, void *buf, size_t len) -{ - int ret; - cluster_member_list_t *m = NULL; - - if ((int64_t)msgtarget < (int64_t)0) - return msg_receive(fd, buf, len); - - /* Make sure a node hasn't died while processing our request. */ - do { - ret = msg_receive_timeout(fd, buf, len, 20); - if (ret < (int)len) { - if (ret < 0 && errno == ETIMEDOUT) { - m = clu_member_list(RG_SERVICE_GROUP); - if (!memb_online(m, msgtarget)) { - ret = RG_ENODEDEATH; - break; - } - cml_free(m); - m = NULL; - continue; - } - - /* Make sure we don't overwrite ENODEDEATH */ - if (ret < 0) - ret = -1; - } - break; - } while(1); - - if (m) - cml_free(m); - return ret; -} - - -void -usage(char *name) -{ -printf("Resource Group Control Commands:\n"); -printf(" %s -v Display version and exit\n",name); -printf(" %s -d <group> Disable <group>\n", name); -printf(" %s -e <group> Enable <group> on the local node\n", - name); -printf(" %s -e <group> -F Enable <group> according to failover\n" - " domain rules\n", name); -printf(" %s -e <group> -m <member> Enable <group>" - " on <member>\n", name); -printf(" %s -r <group> -m <member> Relocate <group> [to <member>]\n", - name); -printf(" %s -q Quiet operation\n", name); -printf(" %s -R <group> Restart a group in place.\n", - name); -printf(" %s -s <group> Stop <group>\n", name); -printf("\n"); -printf("Resource Group Locking (for cluster Shutdown / Debugging):\n"); -printf(" %s -l Lock local resource group manager.\n" - " This prevents resource groups from\n" - " starting on the local node.\n", - name); -printf(" %s -S Show lock state\n", name); -printf(" %s -u Unlock local resource group manager.\n" - " This allows resource groups to start\n" - " on the local node.\n", name); -} - - -int -main(int argc, char **argv) -{ - extern char *optarg; - char *svcname=NULL, nodename[256], tmp[96]; - char *printname=NULL; - int opt; - int msgfd = -1, fd, fod = 0; - SmMessageSt msg; - int action = RG_STATUS; - int node_specified = 0; - uint64_t msgtarget, me, svctarget = NODE_ID_NONE; - char *actionstr = NULL; - cluster_member_list_t *membership; - - if (geteuid() != (uid_t) 0) { - fprintf(stderr, "%s must be run as the root user.\n", argv[0]); - return 1; - } - - while ((opt = getopt(argc, argv, "lSue:d:r:Fn:m:vR:s:qh?")) != EOF) { - switch (opt) { - case 'l': - return do_lock(); - - case 'S': - return do_query_lock(); - - case 'u': - return do_unlock(); - - case 'e': - /* ENABLE */ - actionstr = "trying to enable"; - action = RG_ENABLE; - svcname = optarg; - break; - case 'F': - if (node_specified) { - fprintf(stderr, - "Cannot use '-F' with '-n' or '-m'\n"); - return 1; - } - fod = 1; - break; - case 'd': - /* DISABLE */ - actionstr = "disabling"; - action = RG_DISABLE; - svcname = optarg; - break; - case 'r': - /* RELOCATE */ - actionstr = "trying to relocate"; - action = RG_RELOCATE; - svcname = optarg; - break; - case 's': - /* stop */ - actionstr = "stopping"; - action = RG_STOP_USER; - svcname = optarg; - break; - case 'R': - actionstr = "trying to restart"; - action = RG_RESTART; - svcname = optarg; - break; - case 'm': /* member ... */ - case 'n': /* node .. same thing */ - if (fod) { - fprintf(stderr, - "Cannot use '-F' with '-n' or '-m'\n"); - return 1; - } - strncpy(nodename,optarg,sizeof(nodename)); - node_specified = 1; - break; - case 'v': - printf("%s\n",PACKAGE_VERSION); - return 0; - case 'q': - close(STDOUT_FILENO); - break; - case 'h': - case '?': - default: - usage(basename(argv[0])); - return 1; - } - } - - if (!svcname) { - usage(basename(argv[0])); - return 1; - } - - if (strncmp(svcname, "service:", 8)) { - snprintf(tmp, sizeof(tmp), "service:%s", svcname); - printname = svcname; - svcname = tmp; - } - - /* No login */ - fd = clu_connect(RG_SERVICE_GROUP, 0); - if (fd < 0) { - printf("Could not connect to cluster service\n"); - return 1; - } - - membership = clu_member_list(RG_SERVICE_GROUP); - msg_update(membership); - clu_local_nodeid(RG_SERVICE_GROUP, &me); - msg_set_nodeid(me); - - if (node_specified) { - msgtarget = memb_name_to_id(membership, nodename); - if (msgtarget == NODE_ID_NONE) { - fprintf(stderr, "Member %s not in membership list\n", - nodename); - return 1; - } - svctarget = msgtarget; - } else { - clu_local_nodeid(RG_SERVICE_GROUP, &msgtarget); - clu_local_nodename(RG_SERVICE_GROUP, nodename, - sizeof(nodename)); - } - - build_message(&msg, action, svcname, svctarget, fod, 0); - - if (action != RG_RELOCATE) { - printf("Member %s %s %s", nodename, actionstr, - printname?printname:svcname); - printf("..."); - fflush(stdout); - msgfd = msg_open(msgtarget, RG_PORT, 0, 5); - } else { - if (node_specified) - printf("Trying to relocate %s to %s", - printname?printname:svcname, nodename); - else - printf("Trying to relocate %s", - printname?printname:svcname); - printf("..."); - fflush(stdout); - msgfd = msg_open(me, RG_PORT, 0, 5); - /* just do a normal receive from the local node */ - msgtarget = (uint64_t)-1; - } - - if (msgfd < 0) { - fprintf(stderr, - "Could not connect to resource group manager!\n"); - return 1; - } - - if (msg_send(msgfd, &msg, sizeof(msg)) != sizeof(msg)) { - perror("msg_send"); - fprintf(stderr, "Could not send entire message!\n"); - return 1; - } - - /* reusing opt */ - opt = do_msg_receive(msgtarget, msgfd, &msg, - sizeof(msg)); - if (opt < (int)sizeof(msg)) { - if (opt != RG_ENODEDEATH) { - perror("msg_receive"); - fprintf(stderr, "Error receiving reply!\n"); - return 1; - } - - /* - * XXX hack to enable node death processing along side - * all the rest of the possible responses. If an end-node - * died while processing, this will have been set by the - * rgmanager and a response with RG_ENODEDEATH as the d_ret - * would have been received. - */ - msg.sm_data.d_ret = RG_ENODEDEATH; - swab_SmMessageSt(&msg); - } - - /* Decode */ - swab_SmMessageSt(&msg); - switch (msg.sm_data.d_ret) { - case RG_SUCCESS: - printf("success\n"); - - /* Non-start/relo request: done */ - if (action != RG_RELOCATE && action != RG_ENABLE) - break; - - if (svctarget != NODE_ID_NONE && - msg.sm_data.d_svcOwner != svctarget) { - /* Service running somewhere besides where requested */ - printf("Warning: Service %s is running on %s " - "instead of %s\n", printname?printname:svcname, - memb_id_to_name(membership, - msg.sm_data.d_svcOwner), - memb_id_to_name(membership, svctarget)); - break; - } - - /* No node specified or service running where requested */ - printf("Service %s is now running on %s\n", printname?printname:svcname, - memb_id_to_name(membership, msg.sm_data.d_svcOwner)); - break; - default: - printf("%s\n", rg_strerror(msg.sm_data.d_ret)); - break; - } - - return msg.sm_data.d_ret; -} diff --git a/rgmanager/src/utils/syscall.h b/rgmanager/src/utils/syscall.h deleted file mode 100644 index c28a519..0000000 --- a/rgmanager/src/utils/syscall.h +++ /dev/null @@ -1,182 +0,0 @@ -/** @file - * Taken from: /usr/include/linux/nfsd/syscall.h (we hope). - * - * This file holds all declarations for the knfsd syscall interface. - * - * Copyright (C) 1995-1997 Olaf Kirch okir@monad.swb.de - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to the - * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - * MA 02139, USA. - */ - -#ifndef NFSD_SYSCALL_H -#define NFSD_SYSCALL_H - -#include <asm/types.h> -# include <linux/config.h> -# include <linux/types.h> -# include <linux/in.h> -#include <linux/posix_types.h> -#include <linux/nfsd/const.h> -#include <linux/nfsd/export.h> -// TIMXXX - took out to pacify user level compilation. -//#include <linux/nfsd/nfsfh.h> -#include <linux/nfsd/auth.h> - -/* - * Version of the syscall interface - */ -#define NFSCTL_VERSION 0x0201 - -/* - * These are the commands understood by nfsctl(). - */ -#define NFSCTL_SVC 0 /* This is a server process. */ -#define NFSCTL_ADDCLIENT 1 /* Add an NFS client. */ -#define NFSCTL_DELCLIENT 2 /* Remove an NFS client. */ -#define NFSCTL_EXPORT 3 /* export a file system. */ -#define NFSCTL_UNEXPORT 4 /* unexport a file system. */ -#define NFSCTL_UGIDUPDATE 5 /* update a client's uid/gid map. */ -#define NFSCTL_GETFH 6 /* get an fh by ino (used by mountd) */ -#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */ -#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */ -#define NFSCTL_FODROP 50 /* drop requests during failover */ -#define NFSCTL_STOPFODROP 51 /* stop dropping requests */ -#define NFSCTL_FOLOCKS 52 /* drop locks for failover */ -#define NFSCTL_FOGRACE 53 /* set grace period for failover */ -#define NFSCTL_FOSERV 54 /* remove service mon for failover */ -#define NFSCTL_FO_MIN NFSCTL_FODROP -#define NFSCTL_FO_MAX NFSCTL_FOSERV - -/* SVC */ -struct nfsctl_svc { - unsigned short svc_port; - int svc_nthreads; -}; - -/* ADDCLIENT/DELCLIENT */ -struct nfsctl_client { - char cl_ident[NFSCLNT_IDMAX+1]; - int cl_naddr; - struct in_addr cl_addrlist[NFSCLNT_ADDRMAX]; - int cl_fhkeytype; - int cl_fhkeylen; - unsigned char cl_fhkey[NFSCLNT_KEYMAX]; -}; - -/* EXPORT/UNEXPORT */ -struct nfsctl_export { - char ex_client[NFSCLNT_IDMAX+1]; - char ex_path[NFS_MAXPATHLEN+1]; - __kernel_dev_t ex_dev; - __kernel_ino_t ex_ino; - int ex_flags; - __kernel_uid_t ex_anon_uid; - __kernel_gid_t ex_anon_gid; -}; - -/* UGIDUPDATE */ -struct nfsctl_uidmap { - char * ug_ident; - __kernel_uid_t ug_uidbase; - int ug_uidlen; - __kernel_uid_t * ug_udimap; - __kernel_gid_t ug_gidbase; - int ug_gidlen; - __kernel_gid_t * ug_gdimap; -}; - -/* GETFH */ -struct nfsctl_fhparm { - struct sockaddr gf_addr; - __kernel_dev_t gf_dev; - __kernel_ino_t gf_ino; - int gf_version; -}; - -/* GETFD */ -struct nfsctl_fdparm { - struct sockaddr gd_addr; - char gd_path[NFS_MAXPATHLEN+1]; - int gd_version; -}; - -/* GETFS - GET Filehandle with Size */ -struct nfsctl_fsparm { - struct sockaddr gd_addr; - char gd_path[NFS_MAXPATHLEN+1]; - int gd_maxlen; -}; - -/* FODROP/STOPFODROP */ -struct nfsctl_fodrop { - char fo_dev[NFS_MAXPATHLEN+1]; - __u32 fo_timeout; -}; - -/* - * This is the argument union. - */ -struct nfsctl_arg { - int ca_version; /* safeguard */ - union { - struct nfsctl_svc u_svc; - struct nfsctl_client u_client; - struct nfsctl_export u_export; - struct nfsctl_uidmap u_umap; - struct nfsctl_fhparm u_getfh; - struct nfsctl_fdparm u_getfd; - struct nfsctl_fsparm u_getfs; - struct nfsctl_fodrop u_fodrop; - } u; -#define ca_svc u.u_svc -#define ca_client u.u_client -#define ca_export u.u_export -#define ca_umap u.u_umap -#define ca_getfh u.u_getfh -#define ca_getfd u.u_getfd -#define ca_getfs u.u_getfs -#define ca_authd u.u_authd -#define ca_fodrop u.u_fodrop -}; - -// TIMXXX - took out to pacify user level compilation. -//union nfsctl_res { - //__u8 cr_getfh[NFS_FHSIZE]; - //struct knfsd_fh cr_getfs; -//}; - -#ifdef __KERNEL__ -/* - * Kernel syscall implementation. - */ -#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE) -extern asmlinkage long sys_nfsservctl(int, void *, void *); -#else -#define sys_nfsservctl sys_ni_syscall -#endif -extern int exp_addclient(struct nfsctl_client *ncp); -extern int exp_delclient(struct nfsctl_client *ncp); -extern int exp_export(struct nfsctl_export *nxp); -extern int exp_unexport(struct nfsctl_export *nxp); -extern int exp_fodrop(struct nfsctl_fodrop *nfp); -extern int exp_stopfodrop(struct nfsctl_fodrop *nfp); -extern int nfsd_lockd_founlock(struct nfsctl_fodrop *nfp); -extern int nfsd_lockd_fograce(struct nfsctl_fodrop *nfp); -extern int nfsd_lockd_foservice(struct nfsctl_fodrop *nfp); - -#endif /* __KERNEL__ */ - -#endif /* NFSD_SYSCALL_H */ diff --git a/rgmanager/tests/nfs-tests b/rgmanager/tests/nfs-tests deleted file mode 100755 index 95aefdd..0000000 --- a/rgmanager/tests/nfs-tests +++ /dev/null @@ -1,343 +0,0 @@ -#!/bin/bash -# -# Cluster NFS failover test script. -# - -[ -z "$MP" ] && MP=/mnt/tmp # Mount point for our tests -[ -z "$NFSOPS" ] && NFSOPS="nfsvers=3,noac" # Any default NFS options -[ -z "$NODE1" ] && NODE1="magenta" # First node in cluster -[ -z "$NODE2" ] && NODE2="yellow" # Second node in cluster -[ -z "$SERVICE" ] && SERVICE="nfs_service" # Name of NFS service -[ -z "$EXPORT" ] && EXPORT="192.168.1.30:/mnt/nfs_test" # NFS export -[ -z "$TESTS" ] && TESTS="t_mount t_basic t_restart t_relo t_failover" # tests to run - - -# -# I/O loop -# -if [ "$1" = "iochild" ]; then - while : ; do - if ! dd if=/dev/urandom of=$MP/big-file bs=1k count=512 &> /tmp/$0-child.log; then - echo "Child I/O Failure" - kill -USR2 $PPID - exit 1 - fi - - # - # Notify parent we're still okay. - # - kill -USR1 $PPID - - # - # Wait for OK to continue from parent - # suspend -f doesn't work. Heh. - # If we spawn another dd, the umount will get - # EBUSY ;( - # - kill -STOP $$ - done - - exit 1 -fi - - -die() -{ - declare P - - echo $* - - child_kill - umount $MP - echo "Output:" - cat /tmp/$0.log - exit 1 -} - - -killed_by_child() -{ - echo "Killed by child!" - echo "Output from child:" - cat /tmp/$0-child.log - exit 1 -} - - -child_woke() -{ - echo "Received wakeup signal from child" -} - - -child_stopped() -{ - declare P - - echo "Sending continue to child..." - - for P in `jobs -l 2>/dev/null | grep iochild | awk '{print $2}'`; do - kill -CONT $P &> /dev/null - done -} - - -enable_service() -{ - echo -n " Enabling $2 on $1..." - ssh $1 "clusvcadm -e $2" &> /tmp/$0.log || die "Couldn't disable $1" - echo "Done" -} - - -disable_service() -{ - echo -n " Disabling $2..." - ssh $1 "clusvcadm -d $2" &> /tmp/$0.log || die "Couldn't disable $1" - echo "Done" -} - - -sigint_handler() -{ - echo - echo - echo "Term signal received!" - child_kill - exit 1 -} - -mount_mp() -{ - declare opts="" - - if [ -z "$NFSOPS" ] && [ -n "$1" ]; then - opts="-o $1" - elif [ -z "$1" ] && [ -n "$NFSOPS" ]; then - opts="-o $NFSOPS" - elif [ -n "$1" ] && [ -n "$NFSOPS" ]; then - opts="-o $NFSOPS,$1" - fi - - echo -n " Mounting $opts..." - mount $opts $EXPORT $MP || die "Failed to mount." - echo "Done" -} - - -umount_mp() -{ - echo -n " Umounting..." - umount $MP || die "Failed to umount $MP" - echo "Done" -} - - -child_spawn() -{ - echo -n " Spawning I/O child task..." - trap child_stopped SIGUSR1 - $0 iochild &> /dev/null & - echo "Done" -} - -child_wait() -{ - trap child_woke SIGUSR1 - echo -n " Waiting for child task respond: " - wait -} - - -# -# Arg 1 - child name -# -child_kill() -{ - declare P - declare J - declare c - - # Kill all children if none are specified. - c=$1 - [ -z "$c" ] && c="." - - # - # Kill the child - # - [ -z "$1" ] && echo -n " Killing all children: " - [ -n "$1" ] && echo -n " Killing $1 children: " - while read J P; do - J=${J/*[/} - J=${J/]*/} - - disown %$J &> /dev/null - kill -KILL $P &> /dev/null - kill -CONT $P &> /dev/null - done < <(jobs -l 2>/dev/null | grep $c | awk '{print $1,$2}') - echo "Done" -} - - -send_service_home() -{ - echo -n " Sending $SERVICE to $NODE1..." - ssh $NODE2 "clusvcadm -d $SERVICE" &> /tmp/$0.log || die "Couldn't disable $SERVICE" - ssh $NODE1 "clusvcadm -e $SERVICE" &> /tmp/$0.log || die "Couldn't enable $SERVICE on $NODE1" - echo "Done" -} - - -reboot_node() -{ - declare P - declare J - - echo " Warning: Rebooting $1!" - ssh $1 "reboot -fn" & - sleep 1 - - child_kill ssh -} - - - -t_mount() -{ - # - # Test 1 -- Mount/unmount - # - echo "Test: Basic NFS mount/umount test" - for proto in tcp udp; do - mount_mp $proto - umount_mp - done - echo "Test: Success" - echo -} - - -t_basic() -{ - # - # Test 2 -- NFS mount + io (e.g. ls) - # - echo "Test: Basic NFS mount/io/umount test" - for proto in tcp udp; do - mount_mp $proto - - child_spawn - child_wait - child_kill iochild - - umount_mp - done - echo "Test: Success" - echo -} - - -t_restart() -{ - # - # Test 3 -- Restart NFS service during metadata I/O - # - echo "Test: NFS I/O during restart on same cluster node" - for proto in tcp udp; do - mount_mp $proto - child_spawn - - disable_service $NODE1 $SERVICE - echo -n " Sleeping 3 seconds..." - sleep 3 - echo Done - enable_service $NODE1 $SERVICE - - child_wait - child_kill iochild - umount_mp - done - echo "Test: Success" - echo -} - - -t_relo() -{ - # - # Test 4 - NFS Mount/io/umount during relocation to different node - # - echo "Test: NFS I/O during relocation" - for proto in tcp udp; do - mount_mp $proto - child_spawn - - disable_service $NODE1 $SERVICE - echo -n " Sleeping 3 seconds..." - sleep 3 - echo Done - enable_service $NODE2 $SERVICE - - child_wait - child_kill iochild - umount_mp - send_service_home - done - echo "Test: Success" - echo -} - - -t_failover() -{ - # - # Test 5 - NFS Mount/io/FAILOVER - # - echo "Test: NFS I/O during failover [ TCP ONLY ]" - for proto in tcp; do - disable_service $NODE1 $SERVICE - enable_service $NODE2 $SERVICE - - mount_mp $proto - child_spawn - - reboot_node $NODE2 - - child_wait - child_kill iochild - umount_mp - done - echo "Test: Success" - echo -} - - -# -# Setup -# -echo "Setting up..." -trap sigint_handler SIGINT -trap sigint_handler SIGTERM -trap sigint_handler SIGQUIT -trap killed_by_child SIGUSR2 - -echo " Node 1: $NODE1" -echo " Node 2: $NODE2" -echo " Service Name: $SERVICE" -echo " Mount point: $MP" -echo " NFS Export: $EXPORT" -echo " NFS Mount Options: $NFSOPS" -echo " Tests: $TESTS" - -send_service_home -mkdir -p $MP -umount $MP &> /dev/null -rm -f /tmp/$0.log /tmp/$0-child.log - -echo - -for t in $TESTS; do - $t -done - -exit 0 diff --git a/scripts/latest_tag.pl b/scripts/latest_tag.pl deleted file mode 100755 index 21a2d32..0000000 --- a/scripts/latest_tag.pl +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/perl -w - -if(scalar(@ARGV) != 1){ - print STDERR "Wrong number of arguments.\n"; - exit(1); -} - -$component = $ARGV[0]; - -unless(-d $component){ - print STDERR "${component}:: No such directory. Skipping...\n"; - exit(0); -} - -$output = `cvs log $component/configure`; - -if($output =~ /symbolic names:\n\s+(.*):\s/){ - print "${component}:: Syncing with latest tag ($1)\n"; - `cvs update -r $1 $component`; -} else { - print STDERR "${component}:: Untagged, can not sync.\n"; - exit(1); -}
cluster-commits@lists.fedorahosted.org